{
- setLoading(true);
-
- let command = {
- organization,
- requestId,
- } as SendVerificationRedirectWithoutCheckCommand;
-
- if (userId) {
- command = {
- ...command,
- userId,
- } as SendVerificationRedirectWithoutCheckCommand;
- } else if (loginName) {
- command = {
- ...command,
- loginName,
- } as SendVerificationRedirectWithoutCheckCommand;
- }
-
- const response = await sendVerificationRedirectWithoutCheck(command)
- .catch(() => {
- setError("Could not verify");
- return;
- })
- .finally(() => {
- setLoading(false);
- });
-
- if (response && "error" in response && response.error) {
- setError(response.error);
- return;
- }
-
- if (response && "redirect" in response && response.redirect) {
- router.push(response.redirect);
- return true;
- }
- }
-
- return (
- <>
- {t("success")}
-
- {error && (
-
- )}
-
-
-
-
- {authMethods?.length === 0 && (
-
- )}
-
- >
- );
-}
diff --git a/apps/login/src/lib/server/verify.ts b/apps/login/src/lib/server/verify.ts
index 5591da7290..cf60f739b3 100644
--- a/apps/login/src/lib/server/verify.ts
+++ b/apps/login/src/lib/server/verify.ts
@@ -6,7 +6,6 @@ import {
getSession,
getUserByID,
listAuthenticationMethodTypes,
- resendInviteCode,
verifyEmail,
verifyInviteCode,
verifyTOTPRegistration,
@@ -17,7 +16,6 @@ import crypto from "crypto";
import { create } from "@zitadel/client";
import { Session } from "@zitadel/proto/zitadel/session/v2/session_pb";
import { ChecksSchema } from "@zitadel/proto/zitadel/session/v2/session_service_pb";
-import { User } from "@zitadel/proto/zitadel/user/v2/user_pb";
import { cookies, headers } from "next/headers";
import { getNextUrl } from "../client";
import { getSessionCookieByLoginName } from "../cookies";
@@ -282,16 +280,19 @@ export async function resendVerification(command: resendVerifyEmailCommand) {
const basePath = process.env.NEXT_PUBLIC_BASE_PATH ?? "";
return command.isInvite
- ? resendInviteCode({
+ ? createInviteCode({
serviceUrl,
userId: command.userId,
+ urlTemplate:
+ `${host.includes("localhost") ? "http://" : "https://"}${host}${basePath}/verify?code={{.Code}}&userId={{.UserID}}&organization={{.OrgID}}&invite=true` +
+ (command.requestId ? `&requestId=${command.requestId}` : ""),
}).catch((error) => {
if (error.code === 9) {
return { error: "User is already verified!" };
}
return { error: "Could not resend invite" };
})
- : sendEmailCode({
+ : zitadelSendEmailCode({
userId: command.userId,
serviceUrl,
urlTemplate:
@@ -300,191 +301,29 @@ export async function resendVerification(command: resendVerifyEmailCommand) {
});
}
-type sendEmailCommand = {
- serviceUrl: string;
+type SendEmailCommand = {
userId: string;
urlTemplate: string;
};
-export async function sendEmailCode(command: sendEmailCommand) {
- return zitadelSendEmailCode({
- serviceUrl: command.serviceUrl,
- userId: command.userId,
- urlTemplate: command.urlTemplate,
- });
-}
-
-export async function sendInviteEmailCode(command: sendEmailCommand) {
- // TODO: change this to sendInvite
- return createInviteCode({
- serviceUrl: command.serviceUrl,
- userId: command.userId,
- urlTemplate: command.urlTemplate,
- });
-}
-
-export type SendVerificationRedirectWithoutCheckCommand = {
- organization?: string;
- requestId?: string;
-} & (
- | { userId: string; loginName?: never }
- | { userId?: never; loginName: string }
-);
-
-export async function sendVerificationRedirectWithoutCheck(
- command: SendVerificationRedirectWithoutCheckCommand,
-) {
+export async function sendEmailCode(command: SendEmailCommand) {
const _headers = await headers();
const { serviceUrl } = getServiceUrlFromHeaders(_headers);
- if (!("loginName" in command || "userId" in command)) {
- return { error: "No userId, nor loginname provided" };
- }
-
- let session: Session | undefined;
- let user: User | undefined;
-
- if ("loginName" in command) {
- const sessionCookie = await getSessionCookieByLoginName({
- loginName: command.loginName,
- organization: command.organization,
- }).catch((error) => {
- console.warn("Ignored error:", error);
- });
-
- if (!sessionCookie) {
- return { error: "Could not load session cookie" };
- }
-
- session = await getSession({
- serviceUrl,
- sessionId: sessionCookie.id,
- sessionToken: sessionCookie.token,
- }).then((response) => {
- if (response?.session) {
- return response.session;
- }
- });
-
- if (!session?.factors?.user?.id) {
- return { error: "Could not create session for user" };
- }
-
- const userResponse = await getUserByID({
- serviceUrl,
- userId: session?.factors?.user?.id,
- });
-
- if (!userResponse?.user) {
- return { error: "Could not load user" };
- }
-
- user = userResponse.user;
- } else if ("userId" in command) {
- const userResponse = await getUserByID({
- serviceUrl,
- userId: command.userId,
- });
-
- if (!userResponse?.user) {
- return { error: "Could not load user" };
- }
-
- user = userResponse.user;
-
- const checks = create(ChecksSchema, {
- user: {
- search: {
- case: "loginName",
- value: userResponse.user.preferredLoginName,
- },
- },
- });
-
- session = await createSessionAndUpdateCookie({
- checks,
- requestId: command.requestId,
- });
- }
-
- if (!session?.factors?.user?.id) {
- return { error: "Could not create session for user" };
- }
-
- if (!session?.factors?.user?.id) {
- return { error: "Could not create session for user" };
- }
-
- if (!user) {
- return { error: "Could not load user" };
- }
-
- const authMethodResponse = await listAuthenticationMethodTypes({
+ return zitadelSendEmailCode({
serviceUrl,
- userId: user.userId,
+ userId: command.userId,
+ urlTemplate: command.urlTemplate,
+ });
+}
+
+export async function sendInviteEmailCode(command: SendEmailCommand) {
+ const _headers = await headers();
+ const { serviceUrl } = getServiceUrlFromHeaders(_headers);
+
+ return createInviteCode({
+ serviceUrl,
+ userId: command.userId,
+ urlTemplate: command.urlTemplate,
});
-
- if (!authMethodResponse || !authMethodResponse.authMethodTypes) {
- return { error: "Could not load possible authenticators" };
- }
-
- // if no authmethods are found on the user, redirect to set one up
- if (
- authMethodResponse &&
- authMethodResponse.authMethodTypes &&
- authMethodResponse.authMethodTypes.length == 0
- ) {
- const params = new URLSearchParams({
- sessionId: session.id,
- });
-
- if (session.factors?.user?.loginName) {
- params.set("loginName", session.factors?.user?.loginName);
- }
- return { redirect: `/authenticator/set?${params}` };
- }
-
- const loginSettings = await getLoginSettings({
- serviceUrl,
- organization: user.details?.resourceOwner,
- });
-
- // redirect to mfa factor if user has one, or redirect to set one up
- const mfaFactorCheck = await checkMFAFactors(
- serviceUrl,
- session,
- loginSettings,
- authMethodResponse.authMethodTypes,
- command.organization,
- command.requestId,
- );
-
- if (mfaFactorCheck?.redirect) {
- return mfaFactorCheck;
- }
-
- // login user if no additional steps are required
- if (command.requestId && session.id) {
- const nextUrl = await getNextUrl(
- {
- sessionId: session.id,
- requestId: command.requestId,
- organization:
- command.organization ?? session.factors?.user?.organizationId,
- },
- loginSettings?.defaultRedirectUri,
- );
-
- return { redirect: nextUrl };
- }
-
- const url = await getNextUrl(
- {
- loginName: session.factors.user.loginName,
- organization: session.factors?.user?.organizationId,
- },
- loginSettings?.defaultRedirectUri,
- );
-
- return { redirect: url };
}
diff --git a/apps/login/src/lib/zitadel.ts b/apps/login/src/lib/zitadel.ts
index b7f0f9a059..bdf46a5905 100644
--- a/apps/login/src/lib/zitadel.ts
+++ b/apps/login/src/lib/zitadel.ts
@@ -502,21 +502,6 @@ export async function verifyInviteCode({
return userService.verifyInviteCode({ userId, verificationCode }, {});
}
-export async function resendInviteCode({
- serviceUrl,
- userId,
-}: {
- serviceUrl: string;
- userId: string;
-}) {
- const userService: Client = await createServiceForHost(
- UserService,
- serviceUrl,
- );
-
- return userService.resendInviteCode({ userId }, {});
-}
-
export async function sendEmailCode({
serviceUrl,
userId,