From e10a54d4ae6898205dc92040cfcc05b6093ba017 Mon Sep 17 00:00:00 2001 From: peintnermax Date: Thu, 17 Oct 2024 16:35:30 +0200 Subject: [PATCH] use urlTemplate for emails, fix error i18n --- apps/login/src/app/(login)/mfa/page.tsx | 5 ++--- apps/login/src/app/(login)/mfa/set/page.tsx | 7 +++--- .../src/app/(login)/otp/[method]/page.tsx | 3 ++- .../src/app/(login)/otp/[method]/set/page.tsx | 3 ++- apps/login/src/app/(login)/passkey/page.tsx | 5 ++--- .../src/app/(login)/passkey/set/page.tsx | 3 ++- .../src/app/(login)/password/change/page.tsx | 5 +++-- apps/login/src/app/(login)/password/page.tsx | 3 ++- .../src/app/(login)/password/set/page.tsx | 5 +++-- apps/login/src/app/(login)/u2f/page.tsx | 5 ++--- apps/login/src/app/(login)/u2f/set/page.tsx | 3 ++- apps/login/src/app/(login)/verify/page.tsx | 3 ++- apps/login/src/components/password-form.tsx | 2 +- apps/login/src/lib/server/password.ts | 5 ++++- apps/login/src/lib/zitadel.ts | 22 +++++++++++++------ 15 files changed, 47 insertions(+), 32 deletions(-) diff --git a/apps/login/src/app/(login)/mfa/page.tsx b/apps/login/src/app/(login)/mfa/page.tsx index 38b3e57cf9b..f61aa4d988f 100644 --- a/apps/login/src/app/(login)/mfa/page.tsx +++ b/apps/login/src/app/(login)/mfa/page.tsx @@ -19,6 +19,7 @@ export default async function Page({ }) { const locale = getLocale(); const t = await getTranslations({ locale, namespace: "mfa" }); + const tError = await getTranslations({ locale, namespace: "error" }); const { loginName, authRequestId, organization, sessionId } = searchParams; @@ -84,9 +85,7 @@ export default async function Page({ > )} - {!(loginName || sessionId) && ( - {t("error:unknownContext")} - )} + {!(loginName || sessionId) && {tError("unknownContext")}} {sessionFactors ? ( )} - {!(loginName || sessionId) && ( - {t("error:unknownContext")} - )} + {!(loginName || sessionId) && {tError("unknownContext")}} - {!valid && {t("error.sessionExpired")}} + {!valid && {tError("sessionExpired")}} {isSessionValid(sessionWithData).valid && loginSettings && diff --git a/apps/login/src/app/(login)/otp/[method]/page.tsx b/apps/login/src/app/(login)/otp/[method]/page.tsx index d1071dbcad5..7109d58f115 100644 --- a/apps/login/src/app/(login)/otp/[method]/page.tsx +++ b/apps/login/src/app/(login)/otp/[method]/page.tsx @@ -15,6 +15,7 @@ export default async function Page({ }) { const locale = getLocale(); const t = await getTranslations({ locale, namespace: "otp" }); + const tError = await getTranslations({ locale, namespace: "error" }); const { loginName, authRequestId, sessionId, organization, code, submit } = searchParams; @@ -44,7 +45,7 @@ export default async function Page({ {!session && (
- {t("error:unknownContext")} + {tError("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 7a9c28cbbde..b08a1facdee 100644 --- a/apps/login/src/app/(login)/otp/[method]/set/page.tsx +++ b/apps/login/src/app/(login)/otp/[method]/set/page.tsx @@ -25,6 +25,7 @@ export default async function Page({ }) { const locale = getLocale(); const t = await getTranslations({ locale, namespace: "otp" }); + const tError = await getTranslations({ locale, namespace: "error" }); const { loginName, organization, sessionId, authRequestId, checkAfter } = searchParams; @@ -105,7 +106,7 @@ export default async function Page({

{t("set.title")}

{!session && (
- {t("error:unknownContext")} + {tError("unknownContext")}
)} diff --git a/apps/login/src/app/(login)/passkey/page.tsx b/apps/login/src/app/(login)/passkey/page.tsx index 22a195673b7..fc0f701e805 100644 --- a/apps/login/src/app/(login)/passkey/page.tsx +++ b/apps/login/src/app/(login)/passkey/page.tsx @@ -14,6 +14,7 @@ export default async function Page({ }) { const locale = getLocale(); const t = await getTranslations({ locale, namespace: "passkey" }); + const tError = await getTranslations({ locale, namespace: "error" }); const { loginName, altPassword, authRequestId, organization, sessionId } = searchParams; @@ -51,9 +52,7 @@ export default async function Page({ )}

{t("verify.description")}

- {!(loginName || sessionId) && ( - {t("error:unknownContext")} - )} + {!(loginName || sessionId) && {tError("unknownContext")}} {(loginName || sessionId) && ( - {t("error:unknownContext")} + {tError("unknownContext")} )} diff --git a/apps/login/src/app/(login)/password/change/page.tsx b/apps/login/src/app/(login)/password/change/page.tsx index cf8a970cda4..006d2a15b5c 100644 --- a/apps/login/src/app/(login)/password/change/page.tsx +++ b/apps/login/src/app/(login)/password/change/page.tsx @@ -17,6 +17,7 @@ export default async function Page({ }) { const locale = getLocale(); const t = await getTranslations({ locale, namespace: "password" }); + const tError = await getTranslations({ locale, namespace: "error" }); const { loginName, organization, authRequestId, code } = searchParams; @@ -46,7 +47,7 @@ export default async function Page({ {(!sessionFactors || !loginName) && !loginSettings?.ignoreUnknownUsernames && (
- {t("error:unknownContext")} + {tError("unknownContext")}
)} @@ -71,7 +72,7 @@ export default async function Page({ /> ) : (
- {t("error:failedLoading")} + {tError("failedLoading")}
)} diff --git a/apps/login/src/app/(login)/password/page.tsx b/apps/login/src/app/(login)/password/page.tsx index 43cb969dc35..1f752850e63 100644 --- a/apps/login/src/app/(login)/password/page.tsx +++ b/apps/login/src/app/(login)/password/page.tsx @@ -14,6 +14,7 @@ export default async function Page({ }) { const locale = getLocale(); const t = await getTranslations({ locale, namespace: "password" }); + const tError = await getTranslations({ locale, namespace: "error" }); const { loginName, organization, authRequestId, alt } = searchParams; @@ -44,7 +45,7 @@ export default async function Page({ {(!sessionFactors || !loginName) && !loginSettings?.ignoreUnknownUsernames && (
- {t("error:unknownContext")} + {tError("unknownContext")}
)} diff --git a/apps/login/src/app/(login)/password/set/page.tsx b/apps/login/src/app/(login)/password/set/page.tsx index e99f79ef923..ac61442b3b7 100644 --- a/apps/login/src/app/(login)/password/set/page.tsx +++ b/apps/login/src/app/(login)/password/set/page.tsx @@ -17,6 +17,7 @@ export default async function Page({ }) { const locale = getLocale(); const t = await getTranslations({ locale, namespace: "password" }); + const tError = await getTranslations({ locale, namespace: "error" }); const { loginName, organization, authRequestId, code } = searchParams; @@ -44,7 +45,7 @@ export default async function Page({ {(!sessionFactors || !loginName) && !loginSettings?.ignoreUnknownUsernames && (
- {t("error:unknownContext")} + {tError("unknownContext")}
)} @@ -72,7 +73,7 @@ export default async function Page({ /> ) : (
- {t("error:failedLoading")} + {tError("failedLoading")}
)} diff --git a/apps/login/src/app/(login)/u2f/page.tsx b/apps/login/src/app/(login)/u2f/page.tsx index 60a661f60c1..36fef6d7869 100644 --- a/apps/login/src/app/(login)/u2f/page.tsx +++ b/apps/login/src/app/(login)/u2f/page.tsx @@ -14,6 +14,7 @@ export default async function Page({ }) { const locale = getLocale(); const t = await getTranslations({ locale, namespace: "u2f" }); + const tError = await getTranslations({ locale, namespace: "error" }); const { loginName, authRequestId, sessionId, organization } = searchParams; @@ -50,9 +51,7 @@ export default async function Page({ )}

{t("verify.description")}

- {!(loginName || sessionId) && ( - {t("error:unknownContext")} - )} + {!(loginName || sessionId) && {tError("unknownContext")}} {(loginName || sessionId) && ( - {t("error:unknownContext")} + {tError("unknownContext")} )} diff --git a/apps/login/src/app/(login)/verify/page.tsx b/apps/login/src/app/(login)/verify/page.tsx index 6ee00a30f84..07e00e7a080 100644 --- a/apps/login/src/app/(login)/verify/page.tsx +++ b/apps/login/src/app/(login)/verify/page.tsx @@ -8,6 +8,7 @@ import { getLocale, getTranslations } from "next-intl/server"; export default async function Page({ searchParams }: { searchParams: any }) { const locale = getLocale(); const t = await getTranslations({ locale, namespace: "verify" }); + const tError = await getTranslations({ locale, namespace: "error" }); const { userId, @@ -31,7 +32,7 @@ export default async function Page({ searchParams }: { searchParams: any }) { {!userId && (
- {t("error:unknownContext")} + {tError("unknownContext")}
)} diff --git a/apps/login/src/components/password-form.tsx b/apps/login/src/components/password-form.tsx index bca61bcd954..98b0ec853ff 100644 --- a/apps/login/src/components/password-form.tsx +++ b/apps/login/src/components/password-form.tsx @@ -85,13 +85,13 @@ export function PasswordForm({ organization, }).catch(() => { setError("Could not reset password"); + return; }); setLoading(false); if (response && "error" in response) { setError(response.error); - return; } diff --git a/apps/login/src/lib/server/password.ts b/apps/login/src/lib/server/password.ts index 3db467b0f30..c1467e6b39d 100644 --- a/apps/login/src/lib/server/password.ts +++ b/apps/login/src/lib/server/password.ts @@ -18,6 +18,7 @@ import { } from "@zitadel/proto/zitadel/session/v2/session_service_pb"; import { User, UserState } from "@zitadel/proto/zitadel/user/v2/user_pb"; import { AuthenticationMethodType } from "@zitadel/proto/zitadel/user/v2/user_service_pb"; +import { headers } from "next/headers"; import { redirect } from "next/navigation"; import { getSessionCookieByLoginName } from "../cookies"; @@ -27,6 +28,8 @@ type ResetPasswordCommand = { }; export async function resetPassword(command: ResetPasswordCommand) { + const host = headers().get("host"); + const users = await listUsers({ loginName: command.loginName, organizationId: command.organization, @@ -41,7 +44,7 @@ export async function resetPassword(command: ResetPasswordCommand) { } const userId = users.result[0].userId; - return passwordReset(userId); + return passwordReset(userId, host); } export type UpdateSessionCommand = { diff --git a/apps/login/src/lib/zitadel.ts b/apps/login/src/lib/zitadel.ts index 846552ddda2..9d815d7b405 100644 --- a/apps/login/src/lib/zitadel.ts +++ b/apps/login/src/lib/zitadel.ts @@ -492,16 +492,24 @@ export function createUser( * @param userId the id of the user where the email should be set * @returns the newly set email */ -export async function passwordReset(userId: string) { +export async function passwordReset(userId: string, host: string | null) { return userService.passwordReset( { userId, - medium: { - case: "sendLink", - value: { - notificationType: NotificationType.Email, - }, - }, + medium: host + ? { + case: "sendLink", + value: { + notificationType: NotificationType.Email, + urlTemplate: `https://${host}/password/set?code={{.Code}}&userId={{.UserID}}&organization={{.OrgID}}`, + }, + } + : { + case: "sendLink", + value: { + notificationType: NotificationType.Email, + }, + }, }, {}, );