mirror of
https://github.com/andwati/zitadel.git
synced 2026-10-30 02:52:16 +00:00
fix(login): check for primary auth methods on user discovery (#11689)
# Which Problems Are Solved - Currently, if a user has only secondary authentication methods (like TOTP) configured but no primary authentication method (Password, Passkey, or IDP), the login flow fails to handle them correctly, resulting in an unhelpful "user not found" error when they attempt to log in. - These users are not correctly prompted to set up a primary authentication factor, leaving them in a state where they cannot successfully authenticate. # How the Problems Are Solved - Updated `sendLoginname` to evaluate if a user has an active primary authentication method (`AuthenticationMethodType.PASSWORD`, `PASSKEY`, or `IDP`. If they lack a primary method, the flow now correctly redirects them into the verification/invite process rather than falling through the method checks and returning a generic error. - Updated `sendVerification` to replace the empty `authMethodTypes` array check with a specific check for primary authentication methods. Now, after completing email/invite verification, users who do not have a primary authentication method are explicitly redirected to `/authenticator/set` to set one up.
This commit is contained in:
@@ -100,6 +100,7 @@ export async function sendLoginname(command: SendLoginnameCommand) {
|
||||
|
||||
return { redirect: "/password?" + paramsPasswordDefault };
|
||||
}
|
||||
|
||||
return { error: t("errors.userNotFound") };
|
||||
};
|
||||
|
||||
@@ -320,8 +321,16 @@ export async function sendLoginname(command: SendLoginnameCommand) {
|
||||
userId: session?.factors?.user?.id ?? userId,
|
||||
});
|
||||
|
||||
// always resend invite if user has no auth method set
|
||||
if (!methods.authMethodTypes || !methods.authMethodTypes.length) {
|
||||
const hasPrimaryMethod =
|
||||
methods.authMethodTypes?.some(
|
||||
(m: AuthenticationMethodType) =>
|
||||
m === AuthenticationMethodType.PASSWORD ||
|
||||
m === AuthenticationMethodType.PASSKEY ||
|
||||
m === AuthenticationMethodType.IDP,
|
||||
) ?? false;
|
||||
|
||||
// always resend invite or setup email if user has no primary auth method set
|
||||
if (!hasPrimaryMethod) {
|
||||
console.log("humanUser.email?.isVerified", humanUser?.email?.isVerified);
|
||||
const params = new URLSearchParams({
|
||||
loginName: (session?.factors?.user?.loginName ?? user.preferredLoginName) as string,
|
||||
|
||||
@@ -16,6 +16,7 @@ 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 { AuthenticationMethodType } from "@zitadel/proto/zitadel/user/v2/user_service_pb";
|
||||
import { cookies, headers } from "next/headers";
|
||||
import { completeFlowOrGetUrl } from "../client";
|
||||
import { getSessionCookieByLoginName } from "../cookies";
|
||||
@@ -113,8 +114,16 @@ export async function sendVerification(command: VerifyUserByEmailCommand) {
|
||||
return { error: t("errors.couldNotLoadAuthenticators") };
|
||||
}
|
||||
|
||||
// if no authmethods are found on the user, redirect to set one up
|
||||
if (authMethodResponse && authMethodResponse.authMethodTypes && authMethodResponse.authMethodTypes.length == 0) {
|
||||
const hasPrimaryMethod =
|
||||
authMethodResponse?.authMethodTypes?.some(
|
||||
(m: AuthenticationMethodType) =>
|
||||
m === AuthenticationMethodType.PASSWORD ||
|
||||
m === AuthenticationMethodType.PASSKEY ||
|
||||
m === AuthenticationMethodType.IDP,
|
||||
) ?? false;
|
||||
|
||||
// if no primary auth methods are found on the user, redirect to set one up
|
||||
if (!hasPrimaryMethod) {
|
||||
if (!session) {
|
||||
const checks = create(ChecksSchema, {
|
||||
user: {
|
||||
|
||||
@@ -29,12 +29,6 @@ export function getServiceConfig(headers: ReadonlyHeaders): { serviceConfig: Ser
|
||||
const instanceHost = getInstanceHost(headers);
|
||||
const publicHost = getPublicHost(headers);
|
||||
|
||||
console.log("serviceConfig", {
|
||||
baseUrl: process.env.ZITADEL_API_URL,
|
||||
...(instanceHost && { instanceHost: stripProtocol(instanceHost) }),
|
||||
...(publicHost && { publicHost: stripProtocol(publicHost) }),
|
||||
});
|
||||
|
||||
return {
|
||||
serviceConfig: {
|
||||
baseUrl: process.env.ZITADEL_API_URL,
|
||||
|
||||
Reference in New Issue
Block a user