Files
zitadel/apps/login/src/app/(login)/verify/page.tsx

161 lines
4.7 KiB
TypeScript
Raw Normal View History

import { Alert } from "@/components/alert";
2024-09-26 22:50:55 -04:00
import { DynamicTheme } from "@/components/dynamic-theme";
import { UserAvatar } from "@/components/user-avatar";
2024-10-23 14:28:33 +02:00
import { VerifyForm } from "@/components/verify-form";
import { VerifyRedirectButton } from "@/components/verify-redirect-button";
2024-12-24 09:15:12 +01:00
import { resendVerification } from "@/lib/server/verify";
2024-12-19 08:59:39 +01:00
import { loadMostRecentSession } from "@/lib/session";
import {
getBrandingSettings,
getUserByID,
listAuthenticationMethodTypes,
} from "@/lib/zitadel";
2024-10-23 14:28:33 +02:00
import { HumanUser, User } from "@zitadel/proto/zitadel/user/v2/user_pb";
import { AuthenticationMethodType } from "@zitadel/proto/zitadel/user/v2/user_service_pb";
2024-10-10 16:15:10 +02:00
import { getLocale, getTranslations } from "next-intl/server";
2023-05-17 17:04:56 +02:00
2024-11-22 11:25:03 +01:00
export default async function Page(props: { searchParams: Promise<any> }) {
const searchParams = await props.searchParams;
2024-10-10 16:15:10 +02:00
const locale = getLocale();
const t = await getTranslations({ locale, namespace: "verify" });
const tError = await getTranslations({ locale, namespace: "error" });
2024-10-10 16:15:10 +02:00
2024-12-24 09:15:12 +01:00
const {
userId,
loginName,
code,
organization,
authRequestId,
invite,
skipsend,
} = searchParams;
2024-09-11 16:49:26 +02:00
const branding = await getBrandingSettings(organization);
2023-05-17 17:04:56 +02:00
2024-12-19 08:59:39 +01:00
let sessionFactors;
2024-10-23 14:28:33 +02:00
let user: User | undefined;
let human: HumanUser | undefined;
2024-12-19 08:59:39 +01:00
let id: string | undefined;
if ("loginName" in searchParams) {
sessionFactors = await loadMostRecentSession({
loginName,
organization,
});
2024-12-24 09:15:12 +01:00
if (!skipsend && sessionFactors?.factors?.user?.id) {
await resendVerification({
userId: sessionFactors?.factors?.user?.id,
isInvite: invite === "true",
2024-12-24 09:50:40 +01:00
}).catch((error) => {
console.error("Could not resend verification email", error);
throw Error("Could not request email");
2024-12-24 09:15:12 +01:00
});
}
2024-12-19 08:59:39 +01:00
} else if ("userId" in searchParams && userId) {
2024-12-24 09:15:12 +01:00
if (!skipsend) {
await resendVerification({
userId,
isInvite: invite === "true",
2024-12-24 09:50:40 +01:00
}).catch((error) => {
console.error("Could not resend verification email", error);
throw Error("Could not request email");
2024-12-24 09:15:12 +01:00
});
}
2024-10-23 14:28:33 +02:00
const userResponse = await getUserByID(userId);
if (userResponse) {
user = userResponse.user;
if (user?.type.case === "human") {
human = user.type.value as HumanUser;
}
}
}
2024-12-19 08:59:39 +01:00
id = userId ?? sessionFactors?.factors?.user?.id;
let authMethods: AuthenticationMethodType[] | null = null;
if (human?.email?.isVerified) {
const authMethodsResponse = await listAuthenticationMethodTypes(userId);
if (authMethodsResponse.authMethodTypes) {
authMethods = authMethodsResponse.authMethodTypes;
}
}
2024-10-23 14:28:33 +02:00
const params = new URLSearchParams({
userId: userId,
initial: "true", // defines that a code is not required and is therefore not shown in the UI
});
if (loginName) {
params.set("loginName", loginName);
}
2024-10-23 14:28:33 +02:00
if (organization) {
params.set("organization", organization);
}
if (authRequestId) {
params.set("authRequestId", authRequestId);
2024-10-23 14:28:33 +02:00
}
2024-09-11 16:49:26 +02:00
2023-05-17 17:04:56 +02:00
return (
2024-11-22 11:27:37 +01:00
<DynamicTheme branding={branding}>
<div className="flex flex-col items-center space-y-4">
<h1>{t("verify.title")}</h1>
<p className="ztdl-p mb-6 block">{t("verify.description")}</p>
2024-12-19 08:59:39 +01:00
{!id && (
2024-10-23 14:28:33 +02:00
<>
<h1>{t("verify.title")}</h1>
<p className="ztdl-p mb-6 block">{t("verify.description")}</p>
<div className="py-4">
<Alert>{tError("unknownContext")}</Alert>
</div>
</>
)}
2024-12-19 11:28:35 +01:00
{sessionFactors ? (
<UserAvatar
2024-12-19 11:28:35 +01:00
loginName={loginName ?? sessionFactors.factors?.user?.loginName}
displayName={sessionFactors.factors?.user?.displayName}
showDropdown
searchParams={searchParams}
></UserAvatar>
) : (
user && (
<UserAvatar
loginName={user.preferredLoginName}
displayName={human?.profile?.displayName}
showDropdown={false}
/>
)
)}
2024-12-19 08:59:39 +01:00
{id &&
(human?.email?.isVerified ? (
// show page for already verified users
<VerifyRedirectButton
userId={id}
loginName={loginName}
organization={organization}
authRequestId={authRequestId}
authMethods={authMethods}
/>
) : (
// check if auth methods are set
<VerifyForm
loginName={loginName}
2024-12-19 11:28:35 +01:00
organization={organization}
2024-12-19 08:59:39 +01:00
userId={id}
code={code}
isInvite={invite === "true"}
2024-12-19 11:28:35 +01:00
authRequestId={authRequestId}
2024-12-19 08:59:39 +01:00
/>
))}
</div>
2024-11-22 11:27:37 +01:00
</DynamicTheme>
2023-05-17 17:04:56 +02:00
);
}