change logic

This commit is contained in:
Max Peintner
2025-05-26 08:57:13 +02:00
parent 0af7185a90
commit 8204312892
10 changed files with 71 additions and 65 deletions

View File

@@ -174,7 +174,8 @@
}, },
"verify": { "verify": {
"userIdMissing": "Keine Benutzer-ID angegeben!", "userIdMissing": "Keine Benutzer-ID angegeben!",
"success": "Erfolgreich verifiziert", "successTitle": "Benutzer verifiziert",
"successDescription": "Der Benutzer wurde erfolgreich verifiziert.",
"setupAuthenticator": "Authentifikator einrichten", "setupAuthenticator": "Authentifikator einrichten",
"verify": { "verify": {
"title": "Benutzer verifizieren", "title": "Benutzer verifizieren",

View File

@@ -174,7 +174,8 @@
}, },
"verify": { "verify": {
"userIdMissing": "No userId provided!", "userIdMissing": "No userId provided!",
"success": "The user has been verified successfully.", "successTitle": "User verified",
"successDescription": "The user has been verified successfully.",
"setupAuthenticator": "Setup authenticator", "setupAuthenticator": "Setup authenticator",
"verify": { "verify": {
"title": "Verify user", "title": "Verify user",

View File

@@ -174,7 +174,8 @@
}, },
"verify": { "verify": {
"userIdMissing": "¡No se proporcionó userId!", "userIdMissing": "¡No se proporcionó userId!",
"success": "¡Verificación exitosa!", "successTitle": "Usuario verificado",
"successDescription": "El usuario ha sido verificado con éxito.",
"setupAuthenticator": "Configurar autenticador", "setupAuthenticator": "Configurar autenticador",
"verify": { "verify": {
"title": "Verificar usuario", "title": "Verificar usuario",

View File

@@ -174,7 +174,8 @@
}, },
"verify": { "verify": {
"userIdMissing": "Nessun userId fornito!", "userIdMissing": "Nessun userId fornito!",
"success": "Verifica effettuata con successo!", "successTitle": "Utente verificato",
"successDescription": "L'utente è stato verificato con successo.",
"setupAuthenticator": "Configura autenticatore", "setupAuthenticator": "Configura autenticatore",
"verify": { "verify": {
"title": "Verifica utente", "title": "Verifica utente",

View File

@@ -174,7 +174,8 @@
}, },
"verify": { "verify": {
"userIdMissing": "Nie podano identyfikatora użytkownika!", "userIdMissing": "Nie podano identyfikatora użytkownika!",
"success": "Użytkownik został pomyślnie zweryfikowany.", "successTitle": "Weryfikacja zakończona",
"successDescription": "Użytkownik został pomyślnie zweryfikowany.",
"setupAuthenticator": "Skonfiguruj uwierzytelnianie", "setupAuthenticator": "Skonfiguruj uwierzytelnianie",
"verify": { "verify": {
"title": "Zweryfikuj użytkownika", "title": "Zweryfikuj użytkownika",

View File

@@ -174,7 +174,8 @@
}, },
"verify": { "verify": {
"userIdMissing": "Не указан userId!", "userIdMissing": "Не указан userId!",
"success": "Пользователь успешно подтверждён.", "successTitle": "Пользователь подтверждён",
"successDescription": "Пользователь успешно подтверждён.",
"setupAuthenticator": "Настроить аутентификатор", "setupAuthenticator": "Настроить аутентификатор",
"verify": { "verify": {
"title": "Подтверждение пользователя", "title": "Подтверждение пользователя",

View File

@@ -174,7 +174,8 @@
}, },
"verify": { "verify": {
"userIdMissing": "未提供用户 ID", "userIdMissing": "未提供用户 ID",
"success": "用户验证成功。", "successTitle": "用户验证",
"successDescription": "用户已成功验证。",
"setupAuthenticator": "设置认证器", "setupAuthenticator": "设置认证器",
"verify": { "verify": {
"title": "验证用户", "title": "验证用户",

View File

@@ -36,7 +36,7 @@ export default async function Page(props: { searchParams: Promise<any> }) {
const basePath = process.env.NEXT_PUBLIC_BASE_PATH ?? ""; const basePath = process.env.NEXT_PUBLIC_BASE_PATH ?? "";
async function sendEmail() { async function sendEmail(userId: string) {
const host = _headers.get("host"); const host = _headers.get("host");
if (!host || typeof host !== "string") { if (!host || typeof host !== "string") {
@@ -51,7 +51,7 @@ export default async function Page(props: { searchParams: Promise<any> }) {
`${host.includes("localhost") ? "http://" : "https://"}${host}${basePath}/verify?code={{.Code}}&userId={{.UserID}}&organization={{.OrgID}}&invite=true` + `${host.includes("localhost") ? "http://" : "https://"}${host}${basePath}/verify?code={{.Code}}&userId={{.UserID}}&organization={{.OrgID}}&invite=true` +
(requestId ? `&requestId=${requestId}` : ""), (requestId ? `&requestId=${requestId}` : ""),
}).catch((error) => { }).catch((error) => {
console.error("Could not resend verification email", error); console.error("Could not send invitation email", error);
throw Error("Failed to send verification email"); throw Error("Failed to send verification email");
}); });
} else { } else {
@@ -62,7 +62,7 @@ export default async function Page(props: { searchParams: Promise<any> }) {
`${host.includes("localhost") ? "http://" : "https://"}${host}${basePath}/verify?code={{.Code}}&userId={{.UserID}}&organization={{.OrgID}}` + `${host.includes("localhost") ? "http://" : "https://"}${host}${basePath}/verify?code={{.Code}}&userId={{.UserID}}&organization={{.OrgID}}` +
(requestId ? `&requestId=${requestId}` : ""), (requestId ? `&requestId=${requestId}` : ""),
}).catch((error) => { }).catch((error) => {
console.error("Could not resend verification email", error); console.error("Could not send verification email", error);
throw Error("Failed to send verification email"); throw Error("Failed to send verification email");
}); });
} }
@@ -78,11 +78,11 @@ export default async function Page(props: { searchParams: Promise<any> }) {
}); });
if (doSend && sessionFactors?.factors?.user?.id) { if (doSend && sessionFactors?.factors?.user?.id) {
await sendEmail(); await sendEmail(sessionFactors.factors.user.id);
} }
} else if ("userId" in searchParams && userId) { } else if ("userId" in searchParams && userId) {
if (doSend) { if (doSend) {
await sendEmail(); await sendEmail(userId);
} }
const userResponse = await getUserByID({ const userResponse = await getUserByID({

View File

@@ -33,7 +33,7 @@ async function loadSessionById(
export default async function Page(props: { searchParams: Promise<any> }) { export default async function Page(props: { searchParams: Promise<any> }) {
const searchParams = await props.searchParams; const searchParams = await props.searchParams;
const locale = getLocale(); const locale = getLocale();
const t = await getTranslations({ locale, namespace: "signedin" }); const t = await getTranslations({ locale, namespace: "verify" });
const _headers = await headers(); const _headers = await headers();
const { serviceUrl } = getServiceUrlFromHeaders(_headers); const { serviceUrl } = getServiceUrlFromHeaders(_headers);
@@ -84,10 +84,8 @@ export default async function Page(props: { searchParams: Promise<any> }) {
return ( return (
<DynamicTheme branding={branding}> <DynamicTheme branding={branding}>
<div className="flex flex-col items-center space-y-4"> <div className="flex flex-col items-center space-y-4">
<h1> <h1>{t("successTitle")}</h1>
{t("title", { user: sessionFactors?.factors?.user?.displayName })} <p className="ztdl-p mb-6 block">{t("successDescription")}</p>
</h1>
<p className="ztdl-p mb-6 block">{t("description")}</p>
{sessionFactors ? ( {sessionFactors ? (
<UserAvatar <UserAvatar

View File

@@ -113,6 +113,18 @@ export async function sendVerification(command: VerifyUserByEmailCommand) {
console.warn("Ignored error:", error); // checked later console.warn("Ignored error:", error); // checked later
}); });
if (sessionCookie) {
session = await getSession({
serviceUrl,
sessionId: sessionCookie.id,
sessionToken: sessionCookie.token,
}).then((response) => {
if (response?.session) {
return response.session;
}
});
}
// load auth methods for user // load auth methods for user
const authMethodResponse = await listAuthenticationMethodTypes({ const authMethodResponse = await listAuthenticationMethodTypes({
serviceUrl, serviceUrl,
@@ -143,16 +155,6 @@ export async function sendVerification(command: VerifyUserByEmailCommand) {
checks, checks,
requestId: command.requestId, requestId: command.requestId,
}); });
} else {
session = await getSession({
serviceUrl,
sessionId: sessionCookie.id,
sessionToken: sessionCookie.token,
}).then((response) => {
if (response?.session) {
return response.session;
}
});
} }
if (!session) { if (!session) {
@@ -187,10 +189,9 @@ export async function sendVerification(command: VerifyUserByEmailCommand) {
return { redirect: `/authenticator/set?${params}` }; return { redirect: `/authenticator/set?${params}` };
} }
// if no session found and user is not invited, only show success page, // if no session found only show success page,
// if user is invited, recreate invite flow to not depend on session // if user is invited, recreate invite flow to not depend on session
if (!session?.factors?.user?.id) {
if (!sessionCookie || !session?.factors?.user?.id) {
const verifySuccessParams = new URLSearchParams({}); const verifySuccessParams = new URLSearchParams({});
if (command.userId) { if (command.userId) {
@@ -216,51 +217,51 @@ export async function sendVerification(command: VerifyUserByEmailCommand) {
} }
return { redirect: `/verify/success?${verifySuccessParams}` }; return { redirect: `/verify/success?${verifySuccessParams}` };
} else { }
const loginSettings = await getLoginSettings({
serviceUrl,
organization: user.details?.resourceOwner,
});
// redirect to mfa factor if user has one, or redirect to set one up const loginSettings = await getLoginSettings({
const mfaFactorCheck = await checkMFAFactors( serviceUrl,
serviceUrl, organization: user.details?.resourceOwner,
session, });
loginSettings,
authMethodResponse.authMethodTypes,
command.organization,
command.requestId,
);
if (mfaFactorCheck?.redirect) { // redirect to mfa factor if user has one, or redirect to set one up
return mfaFactorCheck; const mfaFactorCheck = await checkMFAFactors(
} serviceUrl,
session,
loginSettings,
authMethodResponse.authMethodTypes,
command.organization,
command.requestId,
);
// login user if no additional steps are required if (mfaFactorCheck?.redirect) {
if (command.requestId && session.id) { return mfaFactorCheck;
const nextUrl = await getNextUrl( }
{
sessionId: session.id,
requestId: command.requestId,
organization:
command.organization ?? session.factors?.user?.organizationId,
},
loginSettings?.defaultRedirectUri,
);
return { redirect: nextUrl }; // login user if no additional steps are required
} if (command.requestId && session.id) {
const nextUrl = await getNextUrl(
const url = await getNextUrl(
{ {
loginName: session.factors.user.loginName, sessionId: session.id,
organization: session.factors?.user?.organizationId, requestId: command.requestId,
organization:
command.organization ?? session.factors?.user?.organizationId,
}, },
loginSettings?.defaultRedirectUri, loginSettings?.defaultRedirectUri,
); );
return { redirect: url }; return { redirect: nextUrl };
} }
const url = await getNextUrl(
{
loginName: session.factors.user.loginName,
organization: session.factors?.user?.organizationId,
},
loginSettings?.defaultRedirectUri,
);
return { redirect: url };
} }
type resendVerifyEmailCommand = { type resendVerifyEmailCommand = {