move email verification

This commit is contained in:
Max Peintner
2024-12-19 15:12:50 +01:00
parent ab5bcb9eea
commit ed584c59e1
4 changed files with 53 additions and 37 deletions

View File

@@ -3,7 +3,7 @@
import { coerceToArrayBuffer, coerceToBase64Url } from "@/helpers/base64"; import { coerceToArrayBuffer, coerceToBase64Url } from "@/helpers/base64";
import { getNextUrl } from "@/lib/client"; import { getNextUrl } from "@/lib/client";
import { updateSession } from "@/lib/server/session"; import { updateSession } from "@/lib/server/session";
import { create } from "@zitadel/client"; import { create, JsonObject } from "@zitadel/client";
import { import {
RequestChallengesSchema, RequestChallengesSchema,
UserVerificationRequirement, UserVerificationRequirement,
@@ -118,7 +118,7 @@ export function LoginPasskey({
return session; return session;
} }
async function submitLogin(data: any) { async function submitLogin(data: JsonObject) {
setLoading(true); setLoading(true);
const response = await updateSession({ const response = await updateSession({
loginName, loginName,

View File

@@ -30,7 +30,7 @@ import {
import { headers } from "next/headers"; import { headers } from "next/headers";
import { getNextUrl } from "../client"; import { getNextUrl } from "../client";
import { getSessionCookieById, getSessionCookieByLoginName } from "../cookies"; import { getSessionCookieById, getSessionCookieByLoginName } from "../cookies";
import { checkMFAFactors } from "../verify-helper"; import { checkEmailVerification, checkMFAFactors } from "../verify-helper";
type ResetPasswordCommand = { type ResetPasswordCommand = {
loginName: string; loginName: string;
@@ -135,21 +135,6 @@ export async function sendPassword(command: UpdateSessionCommand) {
return { error: "Could not create session for user" }; return { error: "Could not create session for user" };
} }
// if password, check if user has MFA methods
let authMethods;
if (command.checks && command.checks.password && session.factors?.user?.id) {
const response = await listAuthenticationMethodTypes(
session.factors.user.id,
);
if (response.authMethodTypes && response.authMethodTypes.length) {
authMethods = response.authMethodTypes;
}
}
if (!authMethods || !session.factors?.user?.loginName) {
return { error: "Could not verify password!" };
}
const humanUser = user.type.case === "human" ? user.type.value : undefined; const humanUser = user.type.case === "human" ? user.type.value : undefined;
// check if the user has to change password first // check if the user has to change password first
@@ -175,28 +160,28 @@ export async function sendPassword(command: UpdateSessionCommand) {
return { error: "Initial User not supported" }; return { error: "Initial User not supported" };
} }
// add check to see if user was verified // check to see if user was verified
if (
!humanUser?.email?.isVerified &&
process.env.EMAIL_VERIFICATION === "true"
) {
const params = new URLSearchParams({
loginName: session.factors?.user?.loginName as string,
});
if (command.authRequestId) { checkEmailVerification(
params.append("authRequestId", command.authRequestId); session,
} humanUser,
command.organization,
if (command.organization || session.factors?.user?.organizationId) { command.authRequestId,
params.append(
"organization",
command.organization ??
(session.factors?.user?.organizationId as string),
); );
// if password, check if user has MFA methods
let authMethods;
if (command.checks && command.checks.password && session.factors?.user?.id) {
const response = await listAuthenticationMethodTypes(
session.factors.user.id,
);
if (response.authMethodTypes && response.authMethodTypes.length) {
authMethods = response.authMethodTypes;
}
} }
return { redirect: `/verify?` + params }; if (!authMethods) {
return { error: "Could not verify password!" };
} }
checkMFAFactors( checkMFAFactors(

View File

@@ -1,7 +1,37 @@
import { Session } from "@zitadel/proto/zitadel/session/v2/session_pb"; import { Session } from "@zitadel/proto/zitadel/session/v2/session_pb";
import { LoginSettings } from "@zitadel/proto/zitadel/settings/v2/login_settings_pb"; import { LoginSettings } from "@zitadel/proto/zitadel/settings/v2/login_settings_pb";
import { HumanUser } from "@zitadel/proto/zitadel/user/v2/user_pb";
import { AuthenticationMethodType } from "@zitadel/proto/zitadel/user/v2/user_service_pb"; import { AuthenticationMethodType } from "@zitadel/proto/zitadel/user/v2/user_service_pb";
export function checkEmailVerification(
session: Session,
humanUser?: HumanUser,
organization?: string,
authRequestId?: string,
) {
if (
!humanUser?.email?.isVerified &&
process.env.EMAIL_VERIFICATION === "true"
) {
const params = new URLSearchParams({
loginName: session.factors?.user?.loginName as string,
});
if (authRequestId) {
params.append("authRequestId", authRequestId);
}
if (organization || session.factors?.user?.organizationId) {
params.append(
"organization",
organization ?? (session.factors?.user?.organizationId as string),
);
}
return { redirect: `/verify?` + params };
}
}
export function checkMFAFactors( export function checkMFAFactors(
session: Session, session: Session,
loginSettings: LoginSettings | undefined, loginSettings: LoginSettings | undefined,

View File

@@ -3,5 +3,6 @@ export { NewAuthorizationBearerInterceptor } from "./interceptors";
// TODO: Move this to `./protobuf.ts` and export it from there // TODO: Move this to `./protobuf.ts` and export it from there
export { create, fromJson, toJson } from "@bufbuild/protobuf"; export { create, fromJson, toJson } from "@bufbuild/protobuf";
export type { JsonObject } from "@bufbuild/protobuf";
export { TimestampSchema, timestampDate, timestampFromDate, timestampFromMs, timestampMs } from "@bufbuild/protobuf/wkt"; export { TimestampSchema, timestampDate, timestampFromDate, timestampFromMs, timestampMs } from "@bufbuild/protobuf/wkt";
export type { Duration, Timestamp } from "@bufbuild/protobuf/wkt"; export type { Duration, Timestamp } from "@bufbuild/protobuf/wkt";