mirror of
https://github.com/andwati/zitadel.git
synced 2026-10-28 18:12:16 +00:00
Closes #11006 # Which Problems Are Solved This PR addresses an issue where the ignoreUnknownUsernames setting was not being respected in certain scenarios during the login flow. Specifically: - When a user was found but rejected due to login settings (e.g., disableLoginWithEmail), the system would return a "User not found" error instead of redirecting to the password page as dictated by ignoreUnknownUsernames. - When a user was not found, and the flow fell through the registration checks (e.g., IDP redirect failed), it would also return "User not found" without checking ignoreUnknownUsernames. # How the Problems Are Solved - Introduced a helper function `handleUserNotFound` in `apps/login/src/lib/server/loginname.ts` to centralize the logic for checking ignoreUnknownUsernames and redirecting to the password page. - Updated the user validation logic to call handleUserNotFound when a user is found but rejected by policy. - Updated the registration fallback logic to call handleUserNotFound instead of directly returning an error. - Added new test cases in `apps/login/src/lib/server/loginname.test.ts` to verify the fix and ensure no regressions. # Additional Changes - Fixed inconsistency in translation files --------- Co-authored-by: Livio Spring <[email protected]>
91 lines
2.6 KiB
TypeScript
91 lines
2.6 KiB
TypeScript
"use server";
|
|
|
|
import { getSession, registerU2F, verifyU2FRegistration } from "@/lib/zitadel";
|
|
import { create } from "@zitadel/client";
|
|
import { VerifyU2FRegistrationRequestSchema } from "@zitadel/proto/zitadel/user/v2/user_service_pb";
|
|
import { headers } from "next/headers";
|
|
import { userAgent } from "next/server";
|
|
import { getSessionCookieById } from "../cookies";
|
|
import { getServiceConfig } from "../service-url";
|
|
import { getPublicHost } from "./host";
|
|
|
|
type RegisterU2FCommand = {
|
|
sessionId: string;
|
|
};
|
|
|
|
type VerifyU2FCommand = {
|
|
u2fId: string;
|
|
passkeyName?: string;
|
|
publicKeyCredential: any;
|
|
sessionId: string;
|
|
};
|
|
|
|
export async function addU2F(command: RegisterU2FCommand) {
|
|
const _headers = await headers();
|
|
const { serviceConfig } = getServiceConfig(_headers);
|
|
const host = getPublicHost(_headers);
|
|
|
|
const sessionCookie = await getSessionCookieById({
|
|
sessionId: command.sessionId,
|
|
});
|
|
|
|
if (!sessionCookie) {
|
|
return { error: "Could not get session" };
|
|
}
|
|
|
|
const session = await getSession({ serviceConfig, sessionId: sessionCookie.id, sessionToken: sessionCookie.token });
|
|
|
|
const [hostname] = host.split(":");
|
|
|
|
if (!hostname) {
|
|
throw new Error("Could not get hostname");
|
|
}
|
|
|
|
const userId = session?.session?.factors?.user?.id;
|
|
|
|
if (!session || !userId) {
|
|
return { error: "Could not get session" };
|
|
}
|
|
|
|
return registerU2F({ serviceConfig, userId, domain: hostname });
|
|
}
|
|
|
|
export async function verifyU2F(command: VerifyU2FCommand) {
|
|
const _headers = await headers();
|
|
const { serviceConfig } = getServiceConfig(_headers);
|
|
let passkeyName = command.passkeyName;
|
|
if (!passkeyName) {
|
|
const headersList = await headers();
|
|
const userAgentStructure = { headers: headersList };
|
|
const { browser, device, os } = userAgent(userAgentStructure);
|
|
|
|
passkeyName = `${device.vendor ?? ""} ${device.model ?? ""}${
|
|
device.vendor || device.model ? ", " : ""
|
|
}${os.name}${os.name ? ", " : ""}${browser.name}`;
|
|
}
|
|
const sessionCookie = await getSessionCookieById({
|
|
sessionId: command.sessionId,
|
|
});
|
|
|
|
if (!sessionCookie) {
|
|
return { error: "Could not get session cookie" };
|
|
}
|
|
|
|
const session = await getSession({ serviceConfig, sessionId: sessionCookie.id, sessionToken: sessionCookie.token });
|
|
|
|
const userId = session?.session?.factors?.user?.id;
|
|
|
|
if (!userId) {
|
|
return { error: "Could not get session" };
|
|
}
|
|
|
|
const request = create(VerifyU2FRegistrationRequestSchema, {
|
|
u2fId: command.u2fId,
|
|
publicKeyCredential: command.publicKeyCredential,
|
|
tokenName: passkeyName,
|
|
userId,
|
|
});
|
|
|
|
return verifyU2FRegistration({ serviceConfig, request });
|
|
}
|