Files
26f8238499 fix(login): correctly redirect to /password when ignoreUnknownUsername is set (#11130)
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]>
2026-01-14 08:24:48 +00:00

52 lines
1.5 KiB
TypeScript

"use server";
import { createUserServiceClient } from "@zitadel/client/v2";
import { headers } from "next/headers";
import { getSessionCookieById } from "./cookies";
import { getServiceConfig } from "./service-url";
import { createServerTransport, getSession, ServiceConfig } from "./zitadel";
const myUserService = async (serviceConfig: ServiceConfig, sessionToken: string) => {
const transportPromise = await createServerTransport(sessionToken, serviceConfig);
return createUserServiceClient(transportPromise);
};
export async function setMyPassword({ sessionId, password }: { sessionId: string; password: string }) {
const _headers = await headers();
const { serviceConfig } = getServiceConfig(_headers);
const sessionCookie = await getSessionCookieById({ sessionId });
if (!sessionCookie) {
return { error: "Could not load session cookie" };
}
const { session } = await getSession({ serviceConfig, sessionId: sessionCookie.id, sessionToken: sessionCookie.token });
if (!session) {
return { error: "Could not load session" };
}
const service = await myUserService(serviceConfig, `${sessionCookie.token}`);
if (!session?.factors?.user?.id) {
return { error: "No user id found in session" };
}
return service
.setPassword(
{
userId: session.factors.user.id,
newPassword: { password, changeRequired: false },
},
{},
)
.catch((error) => {
console.log(error);
if (error.code === 7) {
return { error: "Session is not valid." };
}
throw error;
});
}