From b5e81d426f998fa0a6dd2a16a8c9581a1ad5f38f Mon Sep 17 00:00:00 2001 From: peintnermax Date: Wed, 9 Oct 2024 17:03:03 +0200 Subject: [PATCH] mfa, otp i18n --- apps/login/locales/en.json | 19 +++++++++++++++++++ apps/login/src/app/(login)/mfa/page.tsx | 2 +- apps/login/src/app/(login)/mfa/set/page.tsx | 2 +- .../src/app/(login)/otp/[method]/page.tsx | 17 +++++++++-------- .../src/app/(login)/otp/[method]/set/page.tsx | 17 ++++++++--------- apps/login/src/components/login-otp.tsx | 9 ++++++--- apps/login/src/components/totp-register.tsx | 5 ++++- 7 files changed, 48 insertions(+), 23 deletions(-) diff --git a/apps/login/locales/en.json b/apps/login/locales/en.json index e4650e02ca9..b4a9162c714 100644 --- a/apps/login/locales/en.json +++ b/apps/login/locales/en.json @@ -59,6 +59,25 @@ "description": "Choose one of the following second factors." } }, + "otp": { + "verify": { + "title": "Verify 2-Factor", + "totpDescription": "Enter the code from your authenticator app.", + "smsDescription": "Enter the code you received via SMS.", + "emailDescription": "Enter the code you received via email.", + "noCodeReceived": "Didn't receive a code?", + "resendCode": "Resend code", + "submit": "Continue" + }, + "set": { + "title": "Set up 2-Factor", + "totpDescription": "Scan the QR code with your authenticator app.", + "smsDescription": "Enter your phone number to receive a code via SMS.", + "emailDescription": "Enter your email address to receive a code via email.", + "totpRegisterDescription": "Scan the QR Code or navigate to the URL manually.", + "submit": "Continue" + } + }, "error": { "unknownContext": "Could not get the context of the user. Make sure to enter the username first or provide a loginName as searchParam.", "sessionExpired": "You need to have a valid session in order to continue." diff --git a/apps/login/src/app/(login)/mfa/page.tsx b/apps/login/src/app/(login)/mfa/page.tsx index 1caad7b8fe9..38b3e57cf9b 100644 --- a/apps/login/src/app/(login)/mfa/page.tsx +++ b/apps/login/src/app/(login)/mfa/page.tsx @@ -85,7 +85,7 @@ export default async function Page({ )} {!(loginName || sessionId) && ( - {t("error.unknownContext")} + {t("error:unknownContext")} )} {sessionFactors ? ( diff --git a/apps/login/src/app/(login)/mfa/set/page.tsx b/apps/login/src/app/(login)/mfa/set/page.tsx index 5e2227b1a20..5af145350a7 100644 --- a/apps/login/src/app/(login)/mfa/set/page.tsx +++ b/apps/login/src/app/(login)/mfa/set/page.tsx @@ -122,7 +122,7 @@ export default async function Page({ )} {!(loginName || sessionId) && ( - {t("error.unknownContext")} + {t("error:unknownContext")} )} {!valid && {t("error.sessionExpired")}} diff --git a/apps/login/src/app/(login)/otp/[method]/page.tsx b/apps/login/src/app/(login)/otp/[method]/page.tsx index db1efa2a003..d1071dbcad5 100644 --- a/apps/login/src/app/(login)/otp/[method]/page.tsx +++ b/apps/login/src/app/(login)/otp/[method]/page.tsx @@ -4,6 +4,7 @@ import { LoginOTP } from "@/components/login-otp"; import { UserAvatar } from "@/components/user-avatar"; import { loadMostRecentSession } from "@/lib/session"; import { getBrandingSettings } from "@/lib/zitadel"; +import { getLocale, getTranslations } from "next-intl/server"; export default async function Page({ searchParams, @@ -12,6 +13,9 @@ export default async function Page({ searchParams: Record; params: Record; }) { + const locale = getLocale(); + const t = await getTranslations({ locale, namespace: "otp" }); + const { loginName, authRequestId, sessionId, organization, code, submit } = searchParams; @@ -27,23 +31,20 @@ export default async function Page({ return (
-

Verify 2-Factor

+

{t("verify.title")}

{method === "time-based" && ( -

Enter the code from your authenticator app.

+

{t("verify.totpDescription")}

)} {method === "sms" && ( -

Enter the code you got on your phone.

+

{t("verify.smsDescription")}

)} {method === "email" && ( -

Enter the code you got via your email.

+

{t("verify.emailDescription")}

)} {!session && (
- - Could not get the context of the user. Make sure to enter the - username first or provide a loginName as searchParam. - + {t("error:unknownContext")}
)} diff --git a/apps/login/src/app/(login)/otp/[method]/set/page.tsx b/apps/login/src/app/(login)/otp/[method]/set/page.tsx index 3e1b4dca8b4..7a9c28cbbde 100644 --- a/apps/login/src/app/(login)/otp/[method]/set/page.tsx +++ b/apps/login/src/app/(login)/otp/[method]/set/page.tsx @@ -12,6 +12,7 @@ import { registerTOTP, } from "@/lib/zitadel"; import { RegisterTOTPResponse } from "@zitadel/proto/zitadel/user/v2/user_service_pb"; +import { getLocale, getTranslations } from "next-intl/server"; import Link from "next/link"; import { redirect } from "next/navigation"; @@ -22,6 +23,9 @@ export default async function Page({ searchParams: Record; params: Record; }) { + const locale = getLocale(); + const t = await getTranslations({ locale, namespace: "otp" }); + const { loginName, organization, sessionId, authRequestId, checkAfter } = searchParams; const { method } = params; @@ -98,13 +102,10 @@ export default async function Page({ return (
-

Register 2-factor

+

{t("set.title")}

{!session && (
- - Could not get the context of the user. Make sure to enter the - username first or provide a loginName as searchParam. - + {t("error:unknownContext")}
)} @@ -125,9 +126,7 @@ export default async function Page({ {totpResponse && "uri" in totpResponse && "secret" in totpResponse ? ( <> -

- Scan the QR Code or navigate to the URL manually. -

+

{t("set.totpRegisterDescription")}

- continue + {t("set.submit")}
diff --git a/apps/login/src/components/login-otp.tsx b/apps/login/src/components/login-otp.tsx index 5f113907395..e131e2446b5 100644 --- a/apps/login/src/components/login-otp.tsx +++ b/apps/login/src/components/login-otp.tsx @@ -4,6 +4,7 @@ import { updateSession } from "@/lib/server/session"; import { create } from "@zitadel/client"; import { RequestChallengesSchema } from "@zitadel/proto/zitadel/session/v2/challenge_pb"; import { ChecksSchema } from "@zitadel/proto/zitadel/session/v2/session_service_pb"; +import { useTranslations } from "next-intl"; import { useRouter } from "next/navigation"; import { useEffect, useRef, useState } from "react"; import { useForm } from "react-hook-form"; @@ -35,6 +36,8 @@ export function LoginOTP({ method, code, }: Props) { + const t = useTranslations("otp"); + const [error, setError] = useState(""); const [loading, setLoading] = useState(false); @@ -191,7 +194,7 @@ export function LoginOTP({
- Did not get the Code? + {t("noCodeReceived")}
@@ -241,7 +244,7 @@ export function LoginOTP({ })} > {loading && } - continue + {t("submit")}
diff --git a/apps/login/src/components/totp-register.tsx b/apps/login/src/components/totp-register.tsx index 7bcb697b222..450cb5bfa76 100644 --- a/apps/login/src/components/totp-register.tsx +++ b/apps/login/src/components/totp-register.tsx @@ -1,5 +1,6 @@ "use client"; import { verifyTOTP } from "@/lib/server-actions"; +import { useTranslations } from "next-intl"; import Link from "next/link"; import { useRouter } from "next/navigation"; import { QRCodeSVG } from "qrcode.react"; @@ -33,6 +34,8 @@ export function TotpRegister({ organization, checkAfter, }: Props) { + const t = useTranslations("otp"); + const [error, setError] = useState(""); const [loading, setLoading] = useState(false); const router = useRouter(); @@ -138,7 +141,7 @@ export function TotpRegister({ onClick={handleSubmit(continueWithCode)} > {loading && } - continue + {t("set.submit")}