mirror of
https://github.com/p-stream/p-stream.git
synced 2026-03-11 17:55:33 +00:00
passkey translations
This commit is contained in:
parent
b7e08b505f
commit
4a8c756eb0
5 changed files with 51 additions and 42 deletions
|
|
@ -158,7 +158,8 @@
|
||||||
"customPassphrasePlaceholder": "Enter your custom passphrase",
|
"customPassphrasePlaceholder": "Enter your custom passphrase",
|
||||||
"useCustomPassphrase": "Use Custom Passphrase",
|
"useCustomPassphrase": "Use Custom Passphrase",
|
||||||
"invalidPassphraseCharacters": "Invalid passphrase characters. Only English letters, numbers 1-10, and normal symbols are allowed.",
|
"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.</0>",
|
"hasAccount": "Already have an account? <0>Login here.</0>",
|
||||||
"login": {
|
"login": {
|
||||||
|
|
@ -168,7 +169,10 @@
|
||||||
"passphrasePlaceholder": "Passphrase",
|
"passphrasePlaceholder": "Passphrase",
|
||||||
"submit": "Login",
|
"submit": "Login",
|
||||||
"title": "Login to your account",
|
"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": {
|
"register": {
|
||||||
"information": {
|
"information": {
|
||||||
|
|
@ -209,7 +213,9 @@
|
||||||
"passphraseLabel": "Your 12-word passphrase",
|
"passphraseLabel": "Your 12-word passphrase",
|
||||||
"recaptchaFailed": "ReCaptcha validation failed",
|
"recaptchaFailed": "ReCaptcha validation failed",
|
||||||
"register": "Create account",
|
"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": {
|
"errors": {
|
||||||
|
|
|
||||||
|
|
@ -156,7 +156,12 @@ export function decryptData(data: string, secret: Uint8Array) {
|
||||||
// Passkey/WebAuthn utilities
|
// Passkey/WebAuthn utilities
|
||||||
|
|
||||||
export function isPasskeySupported(): boolean {
|
export function isPasskeySupported(): boolean {
|
||||||
|
// Passkeys require HTTPS
|
||||||
|
const isSecureContext =
|
||||||
|
typeof window !== "undefined" && window.location.protocol === "https:";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
isSecureContext &&
|
||||||
typeof navigator !== "undefined" &&
|
typeof navigator !== "undefined" &&
|
||||||
"credentials" in navigator &&
|
"credentials" in navigator &&
|
||||||
"create" in navigator.credentials &&
|
"create" in navigator.credentials &&
|
||||||
|
|
|
||||||
|
|
@ -117,8 +117,40 @@ export function LoginFormPart(props: LoginFormPartProps) {
|
||||||
{t("auth.login.description")}
|
{t("auth.login.description")}
|
||||||
</LargeCardText>
|
</LargeCardText>
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
|
<AuthInputBox
|
||||||
|
label={t("auth.deviceNameLabel") ?? undefined}
|
||||||
|
value={device}
|
||||||
|
onChange={setDevice}
|
||||||
|
placeholder={t("auth.deviceNamePlaceholder") ?? undefined}
|
||||||
|
/>
|
||||||
|
<AuthInputBox
|
||||||
|
label={t("auth.login.passphraseLabel") ?? undefined}
|
||||||
|
value={mnemonic}
|
||||||
|
autoComplete="username"
|
||||||
|
name="username"
|
||||||
|
onChange={setMnemonic}
|
||||||
|
placeholder={t("auth.login.passphrasePlaceholder") ?? undefined}
|
||||||
|
passwordToggleable
|
||||||
|
/>
|
||||||
|
{(result.error || passkeyResult.error) &&
|
||||||
|
!result.loading &&
|
||||||
|
!passkeyResult.loading ? (
|
||||||
|
<p className="text-authentication-errorText">
|
||||||
|
{result.error?.message || passkeyResult.error?.message}
|
||||||
|
</p>
|
||||||
|
) : null}
|
||||||
{isPasskeySupported() && (
|
{isPasskeySupported() && (
|
||||||
<div>
|
<div className="relative mb-4">
|
||||||
|
<div className="relative my-4">
|
||||||
|
<div className="absolute inset-0 flex items-center">
|
||||||
|
<div className="w-full border-t border-authentication-border/50" />
|
||||||
|
</div>
|
||||||
|
<div className="relative flex justify-center text-sm">
|
||||||
|
<span className="px-2 bg-authentication-bg text-authentication-text">
|
||||||
|
{t("auth.login.or")}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<Button
|
<Button
|
||||||
theme="secondary"
|
theme="secondary"
|
||||||
onClick={() => executePasskey(device)}
|
onClick={() => executePasskey(device)}
|
||||||
|
|
@ -131,42 +163,10 @@ export function LoginFormPart(props: LoginFormPartProps) {
|
||||||
className="w-full"
|
className="w-full"
|
||||||
>
|
>
|
||||||
<Icon icon={Icons.LOCK} className="mr-2" />
|
<Icon icon={Icons.LOCK} className="mr-2" />
|
||||||
{t("auth.login.usePasskey") ?? "Use passkey"}
|
{t("auth.login.usePasskey")}
|
||||||
</Button>
|
</Button>
|
||||||
<div className="relative my-4">
|
|
||||||
<div className="absolute inset-0 flex items-center">
|
|
||||||
<div className="w-full border-t border-authentication-border/50" />
|
|
||||||
</div>
|
|
||||||
<div className="relative flex justify-center text-sm">
|
|
||||||
<span className="px-2 bg-authentication-bg text-authentication-text">
|
|
||||||
{t("auth.login.or") ?? "or"}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<AuthInputBox
|
|
||||||
label={t("auth.login.passphraseLabel") ?? undefined}
|
|
||||||
value={mnemonic}
|
|
||||||
autoComplete="username"
|
|
||||||
name="username"
|
|
||||||
onChange={setMnemonic}
|
|
||||||
placeholder={t("auth.login.passphrasePlaceholder") ?? undefined}
|
|
||||||
passwordToggleable
|
|
||||||
/>
|
|
||||||
<AuthInputBox
|
|
||||||
label={t("auth.deviceNameLabel") ?? undefined}
|
|
||||||
value={device}
|
|
||||||
onChange={setDevice}
|
|
||||||
placeholder={t("auth.deviceNamePlaceholder") ?? undefined}
|
|
||||||
/>
|
|
||||||
{(result.error || passkeyResult.error) &&
|
|
||||||
!result.loading &&
|
|
||||||
!passkeyResult.loading ? (
|
|
||||||
<p className="text-authentication-errorText">
|
|
||||||
{result.error?.message || passkeyResult.error?.message}
|
|
||||||
</p>
|
|
||||||
) : null}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<LargeCardButtons>
|
<LargeCardButtons>
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,7 @@ export function PassphraseGeneratePart(props: PassphraseGeneratePartProps) {
|
||||||
className="w-full"
|
className="w-full"
|
||||||
>
|
>
|
||||||
<Icon icon={Icons.LOCK} className="mr-2" />
|
<Icon icon={Icons.LOCK} className="mr-2" />
|
||||||
{t("auth.generate.usePasskeyInstead") ?? "Use passkey instead"}
|
{t("auth.generate.usePasskeyInstead")}
|
||||||
</Button>
|
</Button>
|
||||||
{passkeyResult.error && (
|
{passkeyResult.error && (
|
||||||
<p className="mt-2 text-authentication-errorText text-sm text-center">
|
<p className="mt-2 text-authentication-errorText text-sm text-center">
|
||||||
|
|
|
||||||
|
|
@ -188,8 +188,7 @@ export function VerifyPassphrase(props: VerifyPassphraseProps) {
|
||||||
icon={<Icon icon={Icons.CIRCLE_CHECK} />}
|
icon={<Icon icon={Icons.CIRCLE_CHECK} />}
|
||||||
title={t("auth.verify.title")}
|
title={t("auth.verify.title")}
|
||||||
>
|
>
|
||||||
{t("auth.verify.passkeyDescription") ??
|
{t("auth.verify.passkeyDescription")}
|
||||||
"Please authenticate with your passkey to complete registration."}
|
|
||||||
</LargeCardText>
|
</LargeCardText>
|
||||||
{passkeyResult.error ? (
|
{passkeyResult.error ? (
|
||||||
<p className="mt-3 text-authentication-errorText">
|
<p className="mt-3 text-authentication-errorText">
|
||||||
|
|
@ -203,8 +202,7 @@ export function VerifyPassphrase(props: VerifyPassphraseProps) {
|
||||||
onClick={() => authenticatePasskeyFn()}
|
onClick={() => authenticatePasskeyFn()}
|
||||||
>
|
>
|
||||||
<Icon icon={Icons.LOCK} className="mr-2" />
|
<Icon icon={Icons.LOCK} className="mr-2" />
|
||||||
{t("auth.verify.authenticatePasskey") ??
|
{t("auth.verify.authenticatePasskey")}
|
||||||
"Authenticate with Passkey"}
|
|
||||||
</Button>
|
</Button>
|
||||||
</LargeCardButtons>
|
</LargeCardButtons>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue