From 4a8c756eb0afd9984cc6f51f0f501a07fd5fa74b Mon Sep 17 00:00:00 2001 From: Pas <74743263+Pasithea0@users.noreply.github.com> Date: Mon, 29 Dec 2025 16:31:28 -0700 Subject: [PATCH] passkey translations --- src/assets/locales/en.json | 12 +++- src/backend/accounts/crypto.ts | 5 ++ src/pages/parts/auth/LoginFormPart.tsx | 68 +++++++++---------- .../parts/auth/PassphraseGeneratePart.tsx | 2 +- src/pages/parts/auth/VerifyPassphrasePart.tsx | 6 +- 5 files changed, 51 insertions(+), 42 deletions(-) diff --git a/src/assets/locales/en.json b/src/assets/locales/en.json index 8c15c234..76456bc6 100644 --- a/src/assets/locales/en.json +++ b/src/assets/locales/en.json @@ -158,7 +158,8 @@ "customPassphrasePlaceholder": "Enter your custom passphrase", "useCustomPassphrase": "Use Custom Passphrase", "invalidPassphraseCharacters": "Invalid passphrase characters. Only English letters, numbers 1-10, and normal symbols are allowed.", - "passphraseTooShort": "Passphrase must be at least 8 characters long." + "passphraseTooShort": "Passphrase must be at least 8 characters long.", + "usePasskeyInstead": "Use passkey instead" }, "hasAccount": "Already have an account? <0>Login here.", "login": { @@ -168,7 +169,10 @@ "passphrasePlaceholder": "Passphrase", "submit": "Login", "title": "Login to your account", - "validationError": "Incorrect or incomplete passphrase /ᐠ. .ᐟ\\" + "validationError": "Incorrect or incomplete passphrase /ᐠ. .ᐟ\\", + "usePasskey": "Use passkey", + "or": "or", + "noBackendUrl": "No backend URL" }, "register": { "information": { @@ -209,7 +213,9 @@ "passphraseLabel": "Your 12-word passphrase", "recaptchaFailed": "ReCaptcha validation failed", "register": "Create account", - "title": "Confirm your passphrase" + "title": "Confirm your passphrase", + "passkeyDescription": "Please authenticate with your passkey to complete registration.", + "authenticatePasskey": "Authenticate with Passkey" } }, "errors": { diff --git a/src/backend/accounts/crypto.ts b/src/backend/accounts/crypto.ts index fa7e045a..f98fc5da 100644 --- a/src/backend/accounts/crypto.ts +++ b/src/backend/accounts/crypto.ts @@ -156,7 +156,12 @@ export function decryptData(data: string, secret: Uint8Array) { // Passkey/WebAuthn utilities export function isPasskeySupported(): boolean { + // Passkeys require HTTPS + const isSecureContext = + typeof window !== "undefined" && window.location.protocol === "https:"; + return ( + isSecureContext && typeof navigator !== "undefined" && "credentials" in navigator && "create" in navigator.credentials && diff --git a/src/pages/parts/auth/LoginFormPart.tsx b/src/pages/parts/auth/LoginFormPart.tsx index ecb2d868..71f6f7d6 100644 --- a/src/pages/parts/auth/LoginFormPart.tsx +++ b/src/pages/parts/auth/LoginFormPart.tsx @@ -117,8 +117,40 @@ export function LoginFormPart(props: LoginFormPartProps) { {t("auth.login.description")}
+ + + {(result.error || passkeyResult.error) && + !result.loading && + !passkeyResult.loading ? ( +

+ {result.error?.message || passkeyResult.error?.message} +

+ ) : null} {isPasskeySupported() && ( -
+
+
+
+
+
+
+ + {t("auth.login.or")} + +
+
-
-
-
-
-
- - {t("auth.login.or") ?? "or"} - -
-
)} - - - {(result.error || passkeyResult.error) && - !result.loading && - !passkeyResult.loading ? ( -

- {result.error?.message || passkeyResult.error?.message} -

- ) : null}
diff --git a/src/pages/parts/auth/PassphraseGeneratePart.tsx b/src/pages/parts/auth/PassphraseGeneratePart.tsx index ff20b03a..bf2cbe8c 100644 --- a/src/pages/parts/auth/PassphraseGeneratePart.tsx +++ b/src/pages/parts/auth/PassphraseGeneratePart.tsx @@ -80,7 +80,7 @@ export function PassphraseGeneratePart(props: PassphraseGeneratePartProps) { className="w-full" > - {t("auth.generate.usePasskeyInstead") ?? "Use passkey instead"} + {t("auth.generate.usePasskeyInstead")} {passkeyResult.error && (

diff --git a/src/pages/parts/auth/VerifyPassphrasePart.tsx b/src/pages/parts/auth/VerifyPassphrasePart.tsx index f386d1b3..7b939e85 100644 --- a/src/pages/parts/auth/VerifyPassphrasePart.tsx +++ b/src/pages/parts/auth/VerifyPassphrasePart.tsx @@ -188,8 +188,7 @@ export function VerifyPassphrase(props: VerifyPassphraseProps) { icon={} title={t("auth.verify.title")} > - {t("auth.verify.passkeyDescription") ?? - "Please authenticate with your passkey to complete registration."} + {t("auth.verify.passkeyDescription")} {passkeyResult.error ? (

@@ -203,8 +202,7 @@ export function VerifyPassphrase(props: VerifyPassphraseProps) { onClick={() => authenticatePasskeyFn()} > - {t("auth.verify.authenticatePasskey") ?? - "Authenticate with Passkey"} + {t("auth.verify.authenticatePasskey")}