fix(login): update LDAP flow (#11788)

Closes #11096 

# Which Problems Are Solved

This pull request resolves a 404 error that occurred at the end of the
LDAP login flow.

Previously, when a user submitted their LDAP credentials in the
apps/login application, the form initiated the session creation process
but incorrectly redirected the user to /idp/ldap/success, a route that
does not exist. In addition, the redirect failed to preserve necessary
IDP context parameters (such as requestId, organization, and linking
fingerprint info) that are required to fully complete the authentication
intent.

# How the Problems Are Solved

- Fixed redirect path: Updated `createNewSessionForLDAP` to redirect to
`/idp/ldap/process` instead of success, aligning it with the standard
IDP intent processing pipeline which dynamically resolves
`[provider]/process`.
- Preserved context parameters: Extracted `requestId`, `organization`,
`postErrorRedirectUrl`, `linkToSessionId`, and `linkFingerprint` from
the URL parameters on the LDAP page and passed them through
LDAPUsernamePasswordForm down to the server action so the ongoing auth
request is successfully tied to the user's intent.
This commit is contained in:
Max Peintner
2026-03-10 13:26:42 +01:00
committed by GitHub
parent 62cb5bbb83
commit defa7b5d0e
3 changed files with 48 additions and 4 deletions
+18 -2
View File
@@ -11,7 +11,15 @@ export default async function Page(props: {
params: Promise<{ provider: string }>;
}) {
const searchParams = await props.searchParams;
const { idpId, organization, link } = searchParams;
const {
idpId,
organization,
link,
requestId,
postErrorRedirectUrl,
linkToSessionId,
linkFingerprint,
} = searchParams;
if (!idpId) {
throw new Error("No idpId provided in searchParams");
@@ -44,7 +52,15 @@ export default async function Page(props: {
</div>
<div className="w-full">
<LDAPUsernamePasswordForm idpId={idpId} link={link === "true"}></LDAPUsernamePasswordForm>
<LDAPUsernamePasswordForm
idpId={idpId}
link={link === "true"}
requestId={requestId}
organization={organization}
postErrorRedirectUrl={postErrorRedirectUrl}
linkToSessionId={linkToSessionId}
linkFingerprint={linkFingerprint}
/>
</div>
</DynamicTheme>
);
@@ -20,9 +20,22 @@ type Inputs = {
type Props = {
idpId: string;
link: boolean;
requestId?: string;
organization?: string;
postErrorRedirectUrl?: string;
linkToSessionId?: string;
linkFingerprint?: string;
};
export function LDAPUsernamePasswordForm({ idpId, link }: Props) {
export function LDAPUsernamePasswordForm({
idpId,
link,
requestId,
organization,
postErrorRedirectUrl,
linkToSessionId,
linkFingerprint,
}: Props) {
const { register, handleSubmit, formState } = useForm<Inputs>({
mode: "onChange",
});
@@ -44,6 +57,11 @@ export function LDAPUsernamePasswordForm({ idpId, link }: Props) {
username: values.loginName,
password: values.password,
link: link,
requestId,
organization,
postErrorRedirectUrl,
linkToSessionId,
linkFingerprint,
})
.catch(() => {
setError("Could not start LDAP flow");
+11 -1
View File
@@ -216,6 +216,11 @@ type createNewSessionForLDAPCommand = {
password: string;
idpId: string;
link: boolean;
requestId?: string;
organization?: string;
postErrorRedirectUrl?: string;
linkToSessionId?: string;
linkFingerprint?: string;
};
export async function createNewSessionForLDAP(command: createNewSessionForLDAPCommand) {
@@ -249,8 +254,13 @@ export async function createNewSessionForLDAP(command: createNewSessionForLDAPCo
if (command.link) {
params.set("link", "true");
}
if (command.requestId) params.set("requestId", command.requestId);
if (command.organization) params.set("organization", command.organization);
if (command.postErrorRedirectUrl) params.set("postErrorRedirectUrl", command.postErrorRedirectUrl);
if (command.linkToSessionId) params.set("linkToSessionId", command.linkToSessionId);
if (command.linkFingerprint) params.set("linkFingerprint", command.linkFingerprint);
return {
redirect: `/idp/ldap/success?` + params.toString(),
redirect: `/idp/ldap/process?` + params.toString(),
};
}