Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion infrastructure/control-panel/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,4 @@
"lucide-svelte": "^0.539.0",
"tailwind-merge": "^3.0.2"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ $effect(() => {
pin = calcPin(pins);
});

$effect(() => {
if (pin === "") {
Object.keys(pins).forEach((key) => (pins[+key] = ""));
}
});

const calcPin = (pins: { [key: number]: string }) => {
return Object.values(pins).join("") || "";
};
Expand Down
268 changes: 138 additions & 130 deletions infrastructure/eid-wallet/src/routes/(auth)/login/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,144 +1,152 @@
<script lang="ts">
import { goto } from "$app/navigation";
import { Hero } from "$lib/fragments";
import type { GlobalState } from "$lib/global";
import { InputPin } from "$lib/ui";
import * as Button from "$lib/ui/Button";
import {
type AuthOptions,
authenticate,
checkStatus,
} from "@tauri-apps/plugin-biometric";
import { getContext, onMount } from "svelte";

let pin = $state("");
let isError = $state(false);
let clearPin = $state(async () => {});
let handlePinInput = $state((pin: string) => {});
let globalState: GlobalState | undefined = $state(undefined);
let hasPendingDeepLink = $state(false);

const authOpts: AuthOptions = {
allowDeviceCredential: false,

cancelTitle: "Cancel",

// iOS
fallbackTitle: "Please enter your PIN",

// Android
title: "Login",
subtitle: "Please authenticate to continue",
confirmationRequired: true,
};

onMount(async () => {
globalState = getContext<() => GlobalState>("globalState")();
if (!globalState) {
console.error("Global state is not defined");
await goto("/"); // Redirect to home or error page
return;
}

// Check if there's a pending deep link
const pendingDeepLink = sessionStorage.getItem("pendingDeepLink");
hasPendingDeepLink = !!pendingDeepLink;
if (hasPendingDeepLink) {
console.log("Pending deep link detected on login page");
}

clearPin = async () => {
await globalState?.securityController.clearPin();
goto("/");
import { goto } from "$app/navigation";
import { Hero } from "$lib/fragments";
import type { GlobalState } from "$lib/global";
import { InputPin } from "$lib/ui";
import * as Button from "$lib/ui/Button";
import {
type AuthOptions,
authenticate,
checkStatus,
} from "@tauri-apps/plugin-biometric";
import { getContext, onMount } from "svelte";

let pin = $state("");
let isError = $state(false);
let clearPin = $state(async () => {});
let handlePinInput = $state((pin: string) => {});
let globalState: GlobalState | undefined = $state(undefined);
let hasPendingDeepLink = $state(false);

const authOpts: AuthOptions = {
allowDeviceCredential: false,

cancelTitle: "Cancel",

// iOS
fallbackTitle: "Please enter your PIN",

// Android
title: "Login",
subtitle: "Please authenticate to continue",
confirmationRequired: true,
};

handlePinInput = async (pin: string) => {
if (pin.length === 4) {
isError = false;
const check = globalState
? await globalState.securityController.verifyPin(pin)
: false;
if (!check) {
isError = true;
return;
}

// Check if there's a pending deep link to process
const pendingDeepLink = sessionStorage.getItem("pendingDeepLink");
if (pendingDeepLink) {
try {
const deepLinkData = JSON.parse(pendingDeepLink);
console.log(
"Processing pending deep link after login:",
deepLinkData,
);

// Store the deep link data for the scan page
sessionStorage.setItem("deepLinkData", pendingDeepLink);
// Clear the pending deep link
sessionStorage.removeItem("pendingDeepLink");

// Redirect to scan page to process the deep link
await goto("/scan-qr");
return;
} catch (error) {
console.error("Error processing pending deep link:", error);
sessionStorage.removeItem("pendingDeepLink");
}
}

// No pending deep link, go to main page
await goto("/main");
onMount(async () => {
globalState = getContext<() => GlobalState>("globalState")();
if (!globalState) {
console.error("Global state is not defined");
await goto("/"); // Redirect to home or error page
return;
}
Comment thread
grv-saini-20 marked this conversation as resolved.
Outdated
};

// for some reason it's important for this to be done before the biometric stuff
// otherwise pin doesn't work
$effect(() => {
handlePinInput(pin);
});
// Check if there's a pending deep link
const pendingDeepLink = sessionStorage.getItem("pendingDeepLink");
hasPendingDeepLink = !!pendingDeepLink;
if (hasPendingDeepLink) {
console.log("Pending deep link detected on login page");
}

if (
(await globalState.securityController.biometricSupport) &&
(await checkStatus()).isAvailable
) {
try {
await authenticate(
"You must authenticate with PIN first",
authOpts,
);

// Check if there's a pending deep link to process
const pendingDeepLink = sessionStorage.getItem("pendingDeepLink");
if (pendingDeepLink) {
try {
const deepLinkData = JSON.parse(pendingDeepLink);
console.log(
"Processing pending deep link after biometric login:",
deepLinkData,
);

// Store the deep link data for the scan page
sessionStorage.setItem("deepLinkData", pendingDeepLink);
// Clear the pending deep link
sessionStorage.removeItem("pendingDeepLink");

// Redirect to scan page to process the deep link
await goto("/scan-qr");
clearPin = async () => {
pin = "";
isError = false;
};

handlePinInput = async (pin: string) => {
if (pin.length === 4) {
isError = false;
const check = globalState
? await globalState.securityController.verifyPin(pin)
: false;
if (!check) {
isError = true;
return;
} catch (error) {
console.error("Error processing pending deep link:", error);
sessionStorage.removeItem("pendingDeepLink");
}

// Check if there's a pending deep link to process
const pendingDeepLink =
sessionStorage.getItem("pendingDeepLink");
if (pendingDeepLink) {
try {
const deepLinkData = JSON.parse(pendingDeepLink);
console.log(
"Processing pending deep link after login:",
deepLinkData,
);

// Store the deep link data for the scan page
sessionStorage.setItem("deepLinkData", pendingDeepLink);
// Clear the pending deep link
sessionStorage.removeItem("pendingDeepLink");

// Redirect to scan page to process the deep link
await goto("/scan-qr");
return;
} catch (error) {
console.error(
"Error processing pending deep link:",
error,
);
sessionStorage.removeItem("pendingDeepLink");
}
}

// No pending deep link, go to main page
await goto("/main");
}
};
Comment thread
grv-saini-20 marked this conversation as resolved.
Outdated

// for some reason it's important for this to be done before the biometric stuff
// otherwise pin doesn't work
$effect(() => {
handlePinInput(pin);
});

if (
(await globalState.securityController.biometricSupport) &&
(await checkStatus()).isAvailable
) {
try {
await authenticate(
"You must authenticate with PIN first",
authOpts,
);

// Check if there's a pending deep link to process
const pendingDeepLink =
sessionStorage.getItem("pendingDeepLink");
if (pendingDeepLink) {
try {
const deepLinkData = JSON.parse(pendingDeepLink);
console.log(
"Processing pending deep link after biometric login:",
deepLinkData,
);

// Store the deep link data for the scan page
sessionStorage.setItem("deepLinkData", pendingDeepLink);
// Clear the pending deep link
sessionStorage.removeItem("pendingDeepLink");

// Redirect to scan page to process the deep link
await goto("/scan-qr");
return;
} catch (error) {
console.error(
"Error processing pending deep link:",
error,
);
sessionStorage.removeItem("pendingDeepLink");
}
}

// No pending deep link, go to main page
await goto("/main");
} catch (e) {
console.error("Biometric authentication failed", e);
// No pending deep link, go to main page
await goto("/main");
} catch (e) {
console.error("Biometric authentication failed", e);
}
}
}
});
});
</script>

<main
Expand Down
Loading
Loading