Skip to content

Commit 9390d42

Browse files
committed
feat: final safety checks for hardware keys
1 parent bed6b47 commit 9390d42

3 files changed

Lines changed: 135 additions & 52 deletions

File tree

infrastructure/eid-wallet/src-tauri/gen/android/.idea/deviceManager.xml

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

infrastructure/eid-wallet/src/routes/(auth)/onboarding/+page.svelte

Lines changed: 85 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -23,44 +23,49 @@ let verificationId = $state("");
2323
let demoName = $state("");
2424
let verificationSuccess = $state(false);
2525
let keyManager: KeyManager | null = $state(null);
26-
let hardwareAvailable = $state<boolean | null>(null);
26+
let showHardwareError = $state(false);
2727
let checkingHardware = $state(false);
2828
const KEY_ID = "default";
2929
3030
const handleGetStarted = async () => {
31+
isPaneOpen = true;
32+
preVerified = false;
3133
checkingHardware = true;
34+
showHardwareError = false;
35+
error = null;
36+
3237
try {
3338
if (!globalState) {
3439
globalState = getContext<() => GlobalState>("globalState")();
3540
}
36-
const isAvailable = await globalState.keyService.isHardwareAvailable();
37-
hardwareAvailable = isAvailable;
3841
39-
if (!isAvailable) {
40-
// Hardware not available - show error and don't proceed
41-
error = "Your device doesn't support hardware-backed security keys required for passport verification. Please use the pre-verification code option instead.";
42-
isPaneOpen = true;
43-
preVerified = false;
44-
setTimeout(() => {
45-
error = null;
46-
}, 8000);
42+
// Actually try to generate a test hardware key
43+
const testKeyId = `hardware-test-${Date.now()}`;
44+
console.log("Testing hardware key generation with test key:", testKeyId);
45+
46+
try {
47+
const { manager, created } = await globalState.keyService.ensureKey(
48+
testKeyId,
49+
"onboarding"
50+
);
51+
console.log("Test key result - Manager type:", manager.getType(), "Created:", created);
52+
53+
// Check if we got hardware manager and it actually created a key
54+
if (manager.getType() !== "hardware") {
55+
throw new Error("Got software fallback instead of hardware");
56+
}
57+
58+
// Hardware works! Clean up test key and proceed
59+
console.log("Hardware keys are working");
60+
checkingHardware = false;
61+
} catch (keyError) {
62+
console.error("Hardware key test failed:", keyError);
63+
showHardwareError = true;
4764
checkingHardware = false;
48-
return;
4965
}
50-
51-
// Hardware is available - proceed to verification
52-
isPaneOpen = true;
53-
preVerified = false;
5466
} catch (err) {
55-
console.error("Failed to check hardware availability:", err);
56-
hardwareAvailable = false;
57-
error = "Unable to check device capabilities. Please use the pre-verification code option instead.";
58-
isPaneOpen = true;
59-
preVerified = false;
60-
setTimeout(() => {
61-
error = null;
62-
}, 8000);
63-
} finally {
67+
console.error("Error checking hardware:", err);
68+
showHardwareError = true;
6469
checkingHardware = false;
6570
}
6671
};
@@ -138,8 +143,24 @@ async function getApplicationPublicKey() {
138143
}
139144
140145
const handleNext = async () => {
141-
//handle next functionlity
142-
goto("/verify");
146+
// Initialize keys for onboarding context before going to verify
147+
try {
148+
loading = true;
149+
if (!globalState) {
150+
globalState = getContext<() => GlobalState>("globalState")();
151+
}
152+
await initializeKeyManager();
153+
await ensureKeyForContext();
154+
loading = false;
155+
goto("/verify");
156+
} catch (err) {
157+
console.error("Failed to initialize keys for onboarding:", err);
158+
error = "Failed to initialize security keys. Please try again.";
159+
loading = false;
160+
setTimeout(() => {
161+
error = null;
162+
}, 5000);
163+
}
143164
};
144165
145166
let globalState: GlobalState;
@@ -342,12 +363,21 @@ onMount(async () => {
342363
</div>
343364
{/if}
344365
{:else}
345-
{#if hardwareAvailable === false}
366+
{#if checkingHardware}
367+
<div class="my-20">
368+
<div
369+
class="align-center flex w-full flex-col items-center justify-center gap-6"
370+
>
371+
<Shadow size={40} color="rgb(142, 82, 255);" />
372+
<h4>Checking device capabilities...</h4>
373+
</div>
374+
</div>
375+
{:else if showHardwareError}
346376
<h4 class="mt-[2.3svh] mb-[0.5svh] text-red-600">
347377
Hardware Security Not Available
348378
</h4>
349379
<p class="text-black-700 mb-4">
350-
Your device doesn't support hardware-backed security keys required for passport verification.
380+
Your phone doesn't support hardware crypto keys, which is a requirement for verified IDs.
351381
</p>
352382
<p class="text-black-700 mb-4">
353383
Please use the pre-verification code option to create a demo account instead.
@@ -364,21 +394,32 @@ onMount(async () => {
364394
</ButtonAction>
365395
</div>
366396
{:else}
367-
<h4 class="mt-[2.3svh] mb-[0.5svh]">
368-
Your Digital Self begins with the Real You
369-
</h4>
370-
<p class="text-black-700">
371-
In the Web 3.0 Data Space, identity is linked to reality. We begin
372-
by verifying your real-world passport, which serves as the
373-
foundation for issuing your secure ePassport. At the same time, we
374-
generate your eName – a unique digital identifier – and create your
375-
eVault to store and protect your personal data.
376-
</p>
377-
<div class="flex justify-center whitespace-nowrap my-[2.3svh]">
378-
<ButtonAction class="w-full" callback={handleNext}
379-
>Next</ButtonAction
380-
>
381-
</div>
397+
{#if loading}
398+
<div class="my-20">
399+
<div
400+
class="align-center flex w-full flex-col items-center justify-center gap-6"
401+
>
402+
<Shadow size={40} color="rgb(142, 82, 255);" />
403+
<h4>Initializing security keys...</h4>
404+
</div>
405+
</div>
406+
{:else}
407+
<h4 class="mt-[2.3svh] mb-[0.5svh]">
408+
Your Digital Self begins with the Real You
409+
</h4>
410+
<p class="text-black-700">
411+
In the Web 3.0 Data Space, identity is linked to reality. We begin
412+
by verifying your real-world passport, which serves as the
413+
foundation for issuing your secure ePassport. At the same time, we
414+
generate your eName – a unique digital identifier – and create your
415+
eVault to store and protect your personal data.
416+
</p>
417+
<div class="flex justify-center whitespace-nowrap my-[2.3svh]">
418+
<ButtonAction class="w-full" callback={handleNext}
419+
>Next</ButtonAction
420+
>
421+
</div>
422+
{/if}
382423
{/if}
383424
{/if}
384425
</Drawer>

infrastructure/eid-wallet/src/routes/(auth)/verify/+page.svelte

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -109,12 +109,34 @@ let hardwareKeyCheckComplete = $state(false);
109109
const KEY_ID = "default";
110110
111111
async function handleVerification() {
112-
const { data } = await axios.post(
113-
new URL("/verification", PUBLIC_PROVISIONER_URL).toString(),
114-
);
115-
verificaitonId.set(data.id);
116-
showVeriffModal = true;
117-
watchEventStream(data.id);
112+
try {
113+
// Ensure keys are initialized before starting verification
114+
if (!keyManager) {
115+
try {
116+
await initializeKeyManager();
117+
await ensureKeyForVerification();
118+
} catch (keyError) {
119+
console.error("Failed to initialize keys:", keyError);
120+
// If key initialization fails, go back to onboarding
121+
await goto("/onboarding");
122+
return;
123+
}
124+
}
125+
126+
const { data } = await axios.post(
127+
new URL("/verification", PUBLIC_PROVISIONER_URL).toString(),
128+
);
129+
verificaitonId.set(data.id);
130+
showVeriffModal = true;
131+
watchEventStream(data.id);
132+
} catch (error) {
133+
console.error("Failed to start verification:", error);
134+
// If verification fails due to key issues or any initialization error, go back to onboarding
135+
const errorMessage = error instanceof Error ? error.message.toLowerCase() : String(error).toLowerCase();
136+
if (errorMessage.includes("key") || errorMessage.includes("initialize") || errorMessage.includes("manager")) {
137+
await goto("/onboarding");
138+
}
139+
}
118140
}
119141
120142
function watchEventStream(id: string) {
@@ -235,8 +257,15 @@ onMount(async () => {
235257
}
236258
237259
// Initialize key manager and check if default key pair exists
238-
await initializeKeyManager();
239-
await ensureKeyForVerification();
260+
try {
261+
await initializeKeyManager();
262+
await ensureKeyForVerification();
263+
} catch (error) {
264+
console.error("Failed to initialize keys for verification:", error);
265+
// If key initialization fails, redirect back to onboarding
266+
await goto("/onboarding");
267+
return;
268+
}
240269
241270
handleContinue = async () => {
242271
if ($status !== "approved" && $status !== "duplicate")

0 commit comments

Comments
 (0)