| 
247 | 247 |             try {  | 
248 | 248 |                 const decodedString = atob(base64Data);  | 
249 | 249 |                 signingData = JSON.parse(decodedString);  | 
 | 250 | +
  | 
 | 251 | +                // Debug logging  | 
 | 252 | +                console.log("🔍 DEBUG: Decoded signing data:", signingData);  | 
 | 253 | +                console.log(  | 
 | 254 | +                    "🔍 DEBUG: Data keys:",  | 
 | 255 | +                    Object.keys(signingData || {}),  | 
 | 256 | +                );  | 
 | 257 | +                console.log(  | 
 | 258 | +                    "🔍 DEBUG: Is poll request?",  | 
 | 259 | +                    !!(signingData?.pollId && signingData?.voteData),  | 
 | 260 | +                );  | 
250 | 261 |             } catch (error) {  | 
251 | 262 |                 console.error("Error decoding signing data:", error);  | 
252 | 263 |                 return;  | 
 | 
271 | 282 |                 throw new Error("No vault available for signing");  | 
272 | 283 |             }  | 
273 | 284 | 
  | 
274 |  | -            // Create the message to sign  | 
275 |  | -            const messageToSign = JSON.stringify({  | 
276 |  | -                pollId: signingData.pollId,  | 
277 |  | -                voteData: signingData.voteData,  | 
278 |  | -                userId: signingData.userId,  | 
279 |  | -                // Removed timestamp since backend doesn't verify it  | 
280 |  | -            });  | 
 | 285 | +            // Create the message to sign based on type  | 
 | 286 | +            let messageToSign: string;  | 
 | 287 | +
  | 
 | 288 | +            if (signingData.pollId && signingData.voteData) {  | 
 | 289 | +                // Poll-specific signing  | 
 | 290 | +                messageToSign = JSON.stringify({  | 
 | 291 | +                    pollId: signingData.pollId,  | 
 | 292 | +                    voteData: signingData.voteData,  | 
 | 293 | +                    userId: signingData.userId,  | 
 | 294 | +                    // Removed timestamp since backend doesn't verify it  | 
 | 295 | +                });  | 
 | 296 | +            } else {  | 
 | 297 | +                // Generic signature request  | 
 | 298 | +                messageToSign = JSON.stringify({  | 
 | 299 | +                    message: signingData.message,  | 
 | 300 | +                    sessionId: signingData.sessionId,  | 
 | 301 | +                    timestamp: Date.now(),  | 
 | 302 | +                });  | 
 | 303 | +            }  | 
281 | 304 | 
  | 
282 | 305 |             // In a real implementation, you would use the vault's signing capabilities  | 
283 | 306 |             // For now, we'll simulate the signing process  | 
 | 
312 | 335 |             signingDrawerOpen = false;  | 
313 | 336 |             signingSuccess = true;  | 
314 | 337 | 
  | 
315 |  | -            console.log("Vote signed successfully!");  | 
316 |  | -
  | 
 | 338 | +            console.log(  | 
 | 339 | +                signingData.pollId  | 
 | 340 | +                    ? "Vote signed successfully!"  | 
 | 341 | +                    : "Message signed successfully!",  | 
 | 342 | +            );  | 
317 | 343 |             // Check if this was from a deep link  | 
318 | 344 |             const deepLinkData = sessionStorage.getItem("deepLinkData");  | 
319 | 345 |             if (deepLinkData) {  | 
 | 
641 | 667 | 
 
  | 
642 | 668 | <!-- signing confirmation drawer -->  | 
643 | 669 | <Drawer  | 
644 |  | -    title="Sign Vote"  | 
 | 670 | +    title={signingData?.pollId ? "Sign Vote" : "Sign Message"}  | 
645 | 671 |     bind:isPaneOpen={signingDrawerOpen}  | 
646 | 672 |     class="flex flex-col gap-4 items-center justify-center"  | 
647 | 673 | >  | 
 | 
663 | 689 |         />  | 
664 | 690 |     </div>  | 
665 | 691 | 
 
  | 
666 |  | -    <h4>Sign Vote Request</h4>  | 
 | 692 | +    <h4>  | 
 | 693 | +        {signingData?.pollId ? "Sign Vote Request" : "Sign Message Request"}  | 
 | 694 | +    </h4>  | 
667 | 695 |     <p class="text-black-700">  | 
668 |  | -        You're being asked to sign a vote for the following poll  | 
 | 696 | +        {signingData?.pollId  | 
 | 697 | +            ? "You're being asked to sign a vote for the following poll"  | 
 | 698 | +            : "You're being asked to sign the following message"}  | 
669 | 699 |     </p>  | 
670 | 700 | 
 
  | 
671 |  | -    <div class="bg-gray rounded-2xl w-full p-4 mt-4">  | 
672 |  | -        <h4 class="text-base text-black-700">Poll ID</h4>  | 
673 |  | -        <p class="text-black-700 font-normal">  | 
674 |  | -            {signingData?.pollId ?? "Unknown"}  | 
675 |  | -        </p>  | 
676 |  | -    </div>  | 
 | 701 | +    {#if signingData?.pollId && signingData?.voteData}  | 
 | 702 | +        <!-- Poll Details -->  | 
 | 703 | +        <div class="bg-gray rounded-2xl w-full p-4 mt-4">  | 
 | 704 | +            <h4 class="text-base text-black-700">Poll ID</h4>  | 
 | 705 | +            <p class="text-black-700 font-normal">  | 
 | 706 | +                {signingData?.pollId ?? "Unknown"}  | 
 | 707 | +            </p>  | 
 | 708 | +        </div>  | 
677 | 709 | 
 
  | 
678 |  | -    <div class="bg-gray rounded-2xl w-full p-4">  | 
679 |  | -        <h4 class="text-base text-black-700">Your Vote</h4>  | 
680 |  | -        <div class="text-black-700 font-normal">  | 
681 |  | -            {#if signingData?.voteData?.optionId !== undefined}  | 
682 |  | -                <!-- Normal voting mode -->  | 
683 |  | -                <p>  | 
684 |  | -                    You selected: <strong  | 
685 |  | -                        >Option {parseInt(signingData.voteData.optionId) +  | 
686 |  | -                            1}</strong  | 
687 |  | -                    >  | 
688 |  | -                </p>  | 
689 |  | -                <p class="text-sm text-gray-600 mt-1">  | 
690 |  | -                    (This is the option number from the poll)  | 
691 |  | -                </p>  | 
692 |  | -            {:else if signingData?.voteData?.ranks}  | 
693 |  | -                <!-- Ranked voting mode -->  | 
694 |  | -                <p class="mb-2">Your ranking order:</p>  | 
695 |  | -                <div class="space-y-2">  | 
696 |  | -                    {#each Object.entries(signingData.voteData.ranks).sort(([a], [b]) => parseInt(a) - parseInt(b)) as [rank, optionIndex]}  | 
697 |  | -                        <div  | 
698 |  | -                            class="flex items-center space-x-3 p-2 bg-blue-50 rounded-lg"  | 
 | 710 | +        <div class="bg-gray rounded-2xl w-full p-4">  | 
 | 711 | +            <h4 class="text-base text-black-700">Your Vote</h4>  | 
 | 712 | +            <div class="text-black-700 font-normal">  | 
 | 713 | +                {#if signingData?.voteData?.optionId !== undefined}  | 
 | 714 | +                    <!-- Normal voting mode -->  | 
 | 715 | +                    <p>  | 
 | 716 | +                        You selected: <strong  | 
 | 717 | +                            >Option {parseInt(signingData.voteData.optionId) +  | 
 | 718 | +                                1}</strong  | 
699 | 719 |                         >  | 
700 |  | -                            <span  | 
701 |  | -                                class="text-sm bg-blue-500 text-white px-3 py-1 rounded-full font-medium"  | 
 | 720 | +                    </p>  | 
 | 721 | +                    <p class="text-sm text-gray-600 mt-1">  | 
 | 722 | +                        (This is the option number from the poll)  | 
 | 723 | +                    </p>  | 
 | 724 | +                {:else if signingData?.voteData?.ranks}  | 
 | 725 | +                    <!-- Ranked voting mode -->  | 
 | 726 | +                    <p class="mb-2">Your ranking order:</p>  | 
 | 727 | +                    <div class="space-y-2">  | 
 | 728 | +                        {#each Object.entries(signingData.voteData.ranks).sort(([a], [b]) => parseInt(a) - parseInt(b)) as [rank, optionIndex]}  | 
 | 729 | +                            <div  | 
 | 730 | +                                class="flex items-center space-x-3 p-2 bg-blue-50 rounded-lg"  | 
702 | 731 |                             >  | 
703 |  | -                                {rank === "1"  | 
704 |  | -                                    ? "1st"  | 
705 |  | -                                    : rank === "2"  | 
706 |  | -                                      ? "2nd"  | 
707 |  | -                                      : rank === "3"  | 
708 |  | -                                        ? "3rd"  | 
709 |  | -                                        : `${rank}th`}  | 
710 |  | -                            </span>  | 
711 |  | -                            <span class="font-medium"  | 
712 |  | -                                >Option {parseInt(String(optionIndex)) +  | 
713 |  | -                                    1}</span  | 
 | 732 | +                                <span  | 
 | 733 | +                                    class="text-sm bg-blue-500 text-white px-3 py-1 rounded-full font-medium"  | 
 | 734 | +                                >  | 
 | 735 | +                                    {rank === "1"  | 
 | 736 | +                                        ? "1st"  | 
 | 737 | +                                        : rank === "2"  | 
 | 738 | +                                          ? "2nd"  | 
 | 739 | +                                          : rank === "3"  | 
 | 740 | +                                            ? "3rd"  | 
 | 741 | +                                            : `${rank}th`}  | 
 | 742 | +                                </span>  | 
 | 743 | +                                <span class="font-medium"  | 
 | 744 | +                                    >Option {parseInt(String(optionIndex)) +  | 
 | 745 | +                                        1}</span  | 
 | 746 | +                                >  | 
 | 747 | +                            </div>  | 
 | 748 | +                        {/each}  | 
 | 749 | +                    </div>  | 
 | 750 | +                    <p class="text-sm text-gray-600 mt-2">  | 
 | 751 | +                        (1st = most preferred, 2nd = second choice, etc.)  | 
 | 752 | +                    </p>  | 
 | 753 | +                {:else if signingData?.voteData?.points}  | 
 | 754 | +                    <!-- Points voting mode -->  | 
 | 755 | +                    <p class="mb-2">Your point distribution:</p>  | 
 | 756 | +                    <div class="space-y-2">  | 
 | 757 | +                        {#each Object.entries(signingData.voteData.points)  | 
 | 758 | +                            .filter(([_, points]) => (points as number) > 0)  | 
 | 759 | +                            .sort(([a], [b]) => parseInt(a) - parseInt(b)) as [optionIndex, points]}  | 
 | 760 | +                            <div  | 
 | 761 | +                                class="flex items-center space-x-3 p-2 bg-purple-50 rounded-lg"  | 
714 | 762 |                             >  | 
715 |  | -                        </div>  | 
716 |  | -                    {/each}  | 
717 |  | -                </div>  | 
718 |  | -                <p class="text-sm text-gray-600 mt-2">  | 
719 |  | -                    (1st = most preferred, 2nd = second choice, etc.)  | 
720 |  | -                </p>  | 
721 |  | -            {:else if signingData?.voteData?.points}  | 
722 |  | -                <!-- Points voting mode -->  | 
723 |  | -                <p class="mb-2">Your point distribution:</p>  | 
724 |  | -                <div class="space-y-2">  | 
725 |  | -                    {#each Object.entries(signingData.voteData.points)  | 
726 |  | -                        .filter(([_, points]) => (points as number) > 0)  | 
727 |  | -                        .sort(([a], [b]) => parseInt(a) - parseInt(b)) as [optionIndex, points]}  | 
728 |  | -                        <div  | 
729 |  | -                            class="flex items-center space-x-3 p-2 bg-purple-50 rounded-lg"  | 
730 |  | -                        >  | 
731 |  | -                            <span  | 
732 |  | -                                class="text-sm bg-purple-500 text-white px-3 py-1 rounded-full font-medium"  | 
733 |  | -                            >  | 
734 |  | -                                {points} pts  | 
735 |  | -                            </span>  | 
736 |  | -                            <span class="font-medium"  | 
737 |  | -                                >Option {parseInt(String(optionIndex)) +  | 
738 |  | -                                    1}</span  | 
739 |  | -                            >  | 
740 |  | -                        </div>  | 
741 |  | -                    {/each}  | 
742 |  | -                </div>  | 
743 |  | -                <p class="text-sm text-gray-600 mt-2">  | 
744 |  | -                    (Total: {Object.values(signingData.voteData.points).reduce(  | 
745 |  | -                        (sum, points) =>  | 
746 |  | -                            (sum as number) + ((points as number) || 0),  | 
747 |  | -                        0,  | 
748 |  | -                    )}/100 points)  | 
749 |  | -                </p>  | 
750 |  | -            {:else}  | 
751 |  | -                <p>Vote data not available</p>  | 
752 |  | -            {/if}  | 
 | 763 | +                                <span  | 
 | 764 | +                                    class="text-sm bg-purple-500 text-white px-3 py-1 rounded-full font-medium"  | 
 | 765 | +                                >  | 
 | 766 | +                                    {points} pts  | 
 | 767 | +                                </span>  | 
 | 768 | +                                <span class="font-medium"  | 
 | 769 | +                                    >Option {parseInt(String(optionIndex)) +  | 
 | 770 | +                                        1}</span  | 
 | 771 | +                                >  | 
 | 772 | +                            </div>  | 
 | 773 | +                        {/each}  | 
 | 774 | +                    </div>  | 
 | 775 | +                    <p class="text-sm text-gray-600 mt-2">  | 
 | 776 | +                        (Total: {Object.values(  | 
 | 777 | +                            signingData.voteData.points,  | 
 | 778 | +                        ).reduce(  | 
 | 779 | +                            (sum, points) =>  | 
 | 780 | +                                (sum as number) + ((points as number) || 0),  | 
 | 781 | +                            0,  | 
 | 782 | +                        )}/100 points)  | 
 | 783 | +                    </p>  | 
 | 784 | +                {:else}  | 
 | 785 | +                    <p>Vote data not available</p>  | 
 | 786 | +                {/if}  | 
 | 787 | +            </div>  | 
753 | 788 |         </div>  | 
754 |  | -    </div>  | 
 | 789 | +    {:else}  | 
 | 790 | +        <!-- Generic Message Details -->  | 
 | 791 | +        <div class="bg-gray rounded-2xl w-full p-4 mt-4">  | 
 | 792 | +            <h4 class="text-base text-black-700">Message</h4>  | 
 | 793 | +            <p class="text-black-700 font-normal">  | 
 | 794 | +                {signingData?.message ?? "No message provided"}  | 
 | 795 | +            </p>  | 
 | 796 | +        </div>  | 
 | 797 | + | 
 | 798 | +        <div class="bg-gray rounded-2xl w-full p-4">  | 
 | 799 | +            <h4 class="text-base text-black-700">Session ID</h4>  | 
 | 800 | +            <p class="text-black-700 font-normal font-mono">  | 
 | 801 | +                {signingData?.sessionId?.slice(0, 8) ?? "Unknown"}...  | 
 | 802 | +            </p>  | 
 | 803 | +        </div>  | 
 | 804 | +    {/if}  | 
755 | 805 | 
 
  | 
756 | 806 |     <div class="flex justify-center gap-3 items-center mt-4">  | 
757 | 807 |         <Button.Action  | 
 | 
765 | 815 |             Decline  | 
766 | 816 |         </Button.Action>  | 
767 | 817 |         <Button.Action variant="solid" class="w-full" callback={handleSignVote}>  | 
768 |  | -            {loading ? "Signing..." : "Sign Vote"}  | 
 | 818 | +            {loading  | 
 | 819 | +                ? "Signing..."  | 
 | 820 | +                : signingData?.pollId  | 
 | 821 | +                  ? "Sign Vote"  | 
 | 822 | +                  : "Sign Message"}  | 
769 | 823 |         </Button.Action>  | 
770 | 824 |     </div>  | 
771 | 825 | 
 
  | 
 | 
792 | 846 |                 />  | 
793 | 847 |             </div>  | 
794 | 848 |             <h3 class="text-lg font-semibold text-gray-900 mb-2">  | 
795 |  | -                Vote Signed Successfully!  | 
 | 849 | +                {signingData?.pollId  | 
 | 850 | +                    ? "Vote Signed Successfully!"  | 
 | 851 | +                    : "Message Signed Successfully!"}  | 
796 | 852 |             </h3>  | 
797 |  | -            <p class="text-gray-600">You can return to the platform</p>  | 
 | 853 | +            <p class="text-gray-600">  | 
 | 854 | +                {signingData?.pollId  | 
 | 855 | +                    ? "Your vote has been signed and submitted to the voting system."  | 
 | 856 | +                    : "Your message has been signed and submitted successfully."}  | 
 | 857 | +            </p>  | 
798 | 858 | 
 
  | 
799 |  | -            {#if signingData?.redirect_uri}  | 
 | 859 | +            {#if redirect}  | 
800 | 860 |                 <div class="mt-4">  | 
801 | 861 |                     <Button.Action  | 
802 | 862 |                         variant="solid"  | 
803 | 863 |                         size="sm"  | 
804 | 864 |                         callback={() => {  | 
805 | 865 |                             try {  | 
806 |  | -                                window.location.href = signingData.redirect_uri;  | 
 | 866 | +                                if (redirect) {  | 
 | 867 | +                                    window.location.href = redirect;  | 
 | 868 | +                                }  | 
807 | 869 |                             } catch (error) {  | 
808 | 870 |                                 console.error("Manual redirect failed:", error);  | 
809 | 871 |                             }  | 
 | 
0 commit comments