Skip to content

Commit b4eb87b

Browse files
committed
feat: signing logic
1 parent d5c0224 commit b4eb87b

File tree

1 file changed

+137
-107
lines changed

1 file changed

+137
-107
lines changed

infrastructure/eid-wallet/src/routes/(app)/sign/+page.svelte

Lines changed: 137 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -1,119 +1,149 @@
11
<script lang="ts">
2-
import { goto } from "$app/navigation";
3-
import { onMount, getContext } from "svelte";
4-
import AppNav from "$lib/fragments/AppNav/AppNav.svelte";
5-
import type { GlobalState } from "$lib/global";
6-
import { Drawer } from "$lib/ui";
7-
import * as Button from "$lib/ui/Button";
8-
9-
const globalState = getContext<() => GlobalState>("globalState")();
10-
11-
interface SigningData {
12-
session: string;
13-
data: string;
14-
redirect_uri: string;
15-
}
16-
17-
let signingData: SigningData | null = $state(null);
18-
let decodedData: any = $state(null);
19-
let signingStatus: "pending" | "signing" | "success" | "error" =
20-
$state("pending");
21-
let errorMessage = $state("");
22-
23-
onMount(() => {
24-
// Get signing data from URL parameters
25-
const urlParams = new URLSearchParams(window.location.search);
26-
const session = urlParams.get("session");
27-
const data = urlParams.get("data");
28-
const redirect_uri = urlParams.get("redirect_uri");
29-
30-
if (!session || !data || !redirect_uri) {
31-
errorMessage = "Invalid signing request. Missing required parameters.";
32-
signingStatus = "error";
33-
return;
2+
import { goto } from "$app/navigation";
3+
import AppNav from "$lib/fragments/AppNav/AppNav.svelte";
4+
import type { GlobalState } from "$lib/global";
5+
import { Drawer } from "$lib/ui";
6+
import * as Button from "$lib/ui/Button";
7+
import { exists, signPayload } from "@auvo/tauri-plugin-crypto-hw-api";
8+
import { getContext, onMount } from "svelte";
9+
10+
const globalState = getContext<() => GlobalState>("globalState")();
11+
12+
interface SigningData {
13+
session: string;
14+
data: string;
15+
redirect_uri: string;
3416
}
3517
36-
try {
37-
// Decode base64 data
38-
const decodedString = atob(data);
39-
decodedData = JSON.parse(decodedString);
40-
41-
signingData = { session, data, redirect_uri };
42-
signingStatus = "pending";
43-
} catch (error) {
44-
console.error("Error decoding signing data:", error);
45-
errorMessage = "Invalid signing data format.";
46-
signingStatus = "error";
47-
}
48-
});
49-
50-
async function handleSign() {
51-
if (!signingData || !decodedData) return;
52-
53-
try {
54-
signingStatus = "signing";
55-
56-
// Get the vault for signing
57-
const vault = await globalState.vaultController.vault;
58-
if (!vault) {
59-
throw new Error("No vault available for signing");
60-
}
61-
62-
// Create the message to sign
63-
const messageToSign = JSON.stringify({
64-
pollId: decodedData.pollId,
65-
voteData: decodedData.voteData,
66-
userId: decodedData.userId,
67-
timestamp: Date.now(),
68-
});
69-
70-
// In a real implementation, you would use the vault's signing capabilities
71-
// For now, we'll simulate the signing process
72-
await new Promise((resolve) => setTimeout(resolve, 2000)); // Simulate signing delay
73-
74-
// Create the signed payload
75-
const signedPayload = {
76-
sessionId: signingData.session,
77-
signature: "simulated_signature_" + Date.now(), // In real implementation, this would be the actual signature
78-
publicKey: vault.ename, // Use eName as public key for now
79-
message: messageToSign,
18+
let signingData: SigningData | null = $state(null);
19+
let decodedData: {
20+
pollId: string;
21+
voteData: {
22+
optionId?: number;
23+
ranks?: Record<string, number>;
8024
};
81-
82-
// Send the signed payload to the redirect URI
83-
const response = await fetch(signingData.redirect_uri, {
84-
method: "POST",
85-
headers: {
86-
"Content-Type": "application/json",
87-
},
88-
body: JSON.stringify(signedPayload),
89-
});
90-
91-
if (!response.ok) {
92-
throw new Error("Failed to submit signed payload");
25+
userId: string;
26+
} | null = $state(null);
27+
let signingStatus: "pending" | "signing" | "success" | "error" =
28+
$state("pending");
29+
let errorMessage = $state("");
30+
31+
onMount(() => {
32+
// Get signing data from URL parameters
33+
const urlParams = new URLSearchParams(window.location.search);
34+
const session = urlParams.get("session");
35+
const data = urlParams.get("data");
36+
const redirect_uri = urlParams.get("redirect_uri");
37+
38+
if (!session || !data || !redirect_uri) {
39+
errorMessage =
40+
"Invalid signing request. Missing required parameters.";
41+
signingStatus = "error";
42+
return;
9343
}
9444
95-
signingStatus = "success";
96-
97-
// Redirect back to the main app after a short delay
98-
setTimeout(() => {
99-
goto("/main");
100-
}, 3000);
101-
} catch (error) {
102-
console.error("Error during signing:", error);
103-
errorMessage =
104-
error instanceof Error ? error.message : "Signing failed";
105-
signingStatus = "error";
45+
try {
46+
// Decode base64 data
47+
const decodedString = atob(data);
48+
decodedData = JSON.parse(decodedString);
49+
50+
signingData = { session, data, redirect_uri };
51+
signingStatus = "pending";
52+
} catch (error) {
53+
console.error("Error decoding signing data:", error);
54+
errorMessage = "Invalid signing data format.";
55+
signingStatus = "error";
56+
}
57+
});
58+
59+
async function handleSign() {
60+
if (!signingData || !decodedData) return;
61+
62+
try {
63+
signingStatus = "signing";
64+
65+
// Get the vault for signing
66+
const vault = await globalState.vaultController.vault;
67+
if (!vault) {
68+
throw new Error("No vault available for signing");
69+
}
70+
71+
// Create the message to sign
72+
const messageToSign = JSON.stringify({
73+
pollId: decodedData.pollId,
74+
voteData: decodedData.voteData,
75+
userId: decodedData.userId,
76+
timestamp: Date.now(),
77+
});
78+
79+
// In a real implementation, you would use the vault's signing capabilities
80+
// For now, we'll simulate the signing process
81+
await new Promise((resolve) => setTimeout(resolve, 2000)); // Simulate signing delay
82+
83+
// check if default key pair exists
84+
const keyExists = exists("default");
85+
86+
if (!keyExists) {
87+
// this would only indicate that it is an old evault/wallet
88+
// ask them to delete and make a new one maybe or some fallback
89+
// behaviour if we need it
90+
throw new Error("Default key pair does not exist");
91+
}
92+
93+
// Create the signed payload
94+
const signedPayload: {
95+
sessionId: string;
96+
publicKey: string; // Use eName as public key for now
97+
message: string;
98+
signature?: string;
99+
} = {
100+
sessionId: signingData.session,
101+
publicKey: vault.ename, // Use eName as public key for now
102+
message: messageToSign,
103+
};
104+
105+
const signature = await signPayload(
106+
"default",
107+
JSON.stringify(signedPayload),
108+
);
109+
110+
signedPayload.signature = signature;
111+
112+
// Send the signed payload to the redirect URI
113+
const response = await fetch(signingData.redirect_uri, {
114+
method: "POST",
115+
headers: {
116+
"Content-Type": "application/json",
117+
},
118+
body: JSON.stringify(signedPayload),
119+
});
120+
121+
if (!response.ok) {
122+
throw new Error("Failed to submit signed payload");
123+
}
124+
125+
signingStatus = "success";
126+
127+
// Redirect back to the main app after a short delay
128+
setTimeout(() => {
129+
goto("/main");
130+
}, 3000);
131+
} catch (error) {
132+
console.error("Error during signing:", error);
133+
errorMessage =
134+
error instanceof Error ? error.message : "Signing failed";
135+
signingStatus = "error";
136+
}
106137
}
107-
}
108138
109-
function handleCancel() {
110-
goto("/main");
111-
}
139+
function handleCancel() {
140+
goto("/main");
141+
}
112142
113-
function handleRetry() {
114-
signingStatus = "pending";
115-
errorMessage = "";
116-
}
143+
function handleRetry() {
144+
signingStatus = "pending";
145+
errorMessage = "";
146+
}
117147
</script>
118148

119149
<AppNav title="Sign Message" titleClasses="text-white" iconColor="white" />

0 commit comments

Comments
 (0)