mirror of
https://github.com/zitadel/zitadel.git
synced 2025-12-15 19:33:44 +00:00
document password pages, move redirects to sendPassword server action
This commit is contained in:
@@ -16,6 +16,9 @@ import {
|
||||
Checks,
|
||||
ChecksSchema,
|
||||
} from "@zitadel/proto/zitadel/session/v2/session_service_pb";
|
||||
import { User, UserState } from "@zitadel/proto/zitadel/user/v2/user_pb";
|
||||
import { AuthenticationMethodType } from "@zitadel/proto/zitadel/user/v2/user_service_pb";
|
||||
import { redirect } from "next/navigation";
|
||||
import { getSessionCookieByLoginName } from "../cookies";
|
||||
|
||||
type ResetPasswordCommand = {
|
||||
@@ -46,6 +49,7 @@ export type UpdateSessionCommand = {
|
||||
organization?: string;
|
||||
checks: Checks;
|
||||
authRequestId?: string;
|
||||
forceMfa?: boolean;
|
||||
};
|
||||
|
||||
export async function sendPassword(command: UpdateSessionCommand) {
|
||||
@@ -57,13 +61,18 @@ export async function sendPassword(command: UpdateSessionCommand) {
|
||||
});
|
||||
|
||||
let session;
|
||||
let user: User;
|
||||
if (!sessionCookie) {
|
||||
const users = await listUsers({
|
||||
loginName: command.loginName,
|
||||
organizationId: command.organization,
|
||||
});
|
||||
|
||||
console.log(users);
|
||||
|
||||
if (users.details?.totalResult == BigInt(1) && users.result[0].userId) {
|
||||
user = users.result[0];
|
||||
|
||||
const checks = create(ChecksSchema, {
|
||||
user: { search: { case: "userId", value: users.result[0].userId } },
|
||||
password: { password: command.checks.password?.password },
|
||||
@@ -85,6 +94,18 @@ export async function sendPassword(command: UpdateSessionCommand) {
|
||||
undefined,
|
||||
command.authRequestId,
|
||||
);
|
||||
|
||||
if (!session?.factors?.user?.id) {
|
||||
return { error: "Could not create session for user" };
|
||||
}
|
||||
|
||||
const userResponse = await getUserByID(session?.factors?.user?.id);
|
||||
|
||||
if (!userResponse.user) {
|
||||
return { error: "Could not find user" };
|
||||
}
|
||||
|
||||
user = userResponse.user;
|
||||
}
|
||||
|
||||
if (!session?.factors?.user?.id || !sessionCookie) {
|
||||
@@ -102,12 +123,151 @@ export async function sendPassword(command: UpdateSessionCommand) {
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
const submitted = {
|
||||
sessionId: session.id,
|
||||
factors: session.factors,
|
||||
challenges: session.challenges,
|
||||
authMethods,
|
||||
userState: user.state,
|
||||
};
|
||||
|
||||
if (
|
||||
!submitted ||
|
||||
!submitted.authMethods ||
|
||||
!submitted.factors?.user?.loginName
|
||||
) {
|
||||
return { error: "Could not verify password!" };
|
||||
}
|
||||
|
||||
const availableSecondFactors = submitted?.authMethods?.filter(
|
||||
(m: AuthenticationMethodType) =>
|
||||
m !== AuthenticationMethodType.PASSWORD &&
|
||||
m !== AuthenticationMethodType.PASSKEY,
|
||||
);
|
||||
|
||||
if (availableSecondFactors?.length == 1) {
|
||||
const params = new URLSearchParams({
|
||||
loginName: submitted.factors?.user.loginName,
|
||||
});
|
||||
|
||||
if (command.authRequestId) {
|
||||
params.append("authRequestId", command.authRequestId);
|
||||
}
|
||||
|
||||
if (command.organization) {
|
||||
params.append("organization", command.organization);
|
||||
}
|
||||
|
||||
const factor = availableSecondFactors[0];
|
||||
// if passwordless is other method, but user selected password as alternative, perform a login
|
||||
if (factor === AuthenticationMethodType.TOTP) {
|
||||
return redirect(`/otp/time-based?` + params);
|
||||
} else if (factor === AuthenticationMethodType.OTP_SMS) {
|
||||
return redirect(`/otp/sms?` + params);
|
||||
} else if (factor === AuthenticationMethodType.OTP_EMAIL) {
|
||||
return redirect(`/otp/email?` + params);
|
||||
} else if (factor === AuthenticationMethodType.U2F) {
|
||||
return redirect(`/u2f?` + params);
|
||||
}
|
||||
} else if (availableSecondFactors?.length >= 1) {
|
||||
const params = new URLSearchParams({
|
||||
loginName: submitted.factors.user.loginName,
|
||||
});
|
||||
|
||||
if (command.authRequestId) {
|
||||
params.append("authRequestId", command.authRequestId);
|
||||
}
|
||||
|
||||
if (command.organization) {
|
||||
params.append("organization", command.organization);
|
||||
}
|
||||
|
||||
return redirect(`/mfa?` + params);
|
||||
} else if (submitted.userState === UserState.INITIAL) {
|
||||
const params = new URLSearchParams({
|
||||
loginName: submitted.factors.user.loginName,
|
||||
});
|
||||
|
||||
if (command.authRequestId) {
|
||||
params.append("authRequestId", command.authRequestId);
|
||||
}
|
||||
|
||||
if (command.organization) {
|
||||
params.append("organization", command.organization);
|
||||
}
|
||||
|
||||
return redirect(`/password/change?` + params);
|
||||
} else if (command.forceMfa && !availableSecondFactors.length) {
|
||||
const params = new URLSearchParams({
|
||||
loginName: submitted.factors.user.loginName,
|
||||
force: "true", // this defines if the mfa is forced in the settings
|
||||
checkAfter: "true", // this defines if the check is directly made after the setup
|
||||
});
|
||||
|
||||
if (command.authRequestId) {
|
||||
params.append("authRequestId", command.authRequestId);
|
||||
}
|
||||
|
||||
if (command.organization) {
|
||||
params.append("organization", command.organization);
|
||||
}
|
||||
|
||||
// TODO: provide a way to setup passkeys on mfa page?
|
||||
return redirect(`/mfa/set?` + params);
|
||||
}
|
||||
// TODO: implement passkey setup
|
||||
|
||||
// else if (
|
||||
// submitted.factors &&
|
||||
// !submitted.factors.webAuthN && // if session was not verified with a passkey
|
||||
// promptPasswordless && // if explicitly prompted due policy
|
||||
// !isAlternative // escaped if password was used as an alternative method
|
||||
// ) {
|
||||
// const params = new URLSearchParams({
|
||||
// loginName: submitted.factors.user.loginName,
|
||||
// prompt: "true",
|
||||
// });
|
||||
|
||||
// if (authRequestId) {
|
||||
// params.append("authRequestId", authRequestId);
|
||||
// }
|
||||
|
||||
// if (organization) {
|
||||
// params.append("organization", organization);
|
||||
// }
|
||||
|
||||
// return router.push(`/passkey/set?` + params);
|
||||
// }
|
||||
else if (command.authRequestId && submitted.sessionId) {
|
||||
const params = new URLSearchParams({
|
||||
sessionId: submitted.sessionId,
|
||||
authRequest: command.authRequestId,
|
||||
});
|
||||
|
||||
if (command.organization) {
|
||||
params.append("organization", command.organization);
|
||||
}
|
||||
|
||||
return redirect(`/login?` + params);
|
||||
}
|
||||
|
||||
// without OIDC flow
|
||||
const params = new URLSearchParams(
|
||||
command.authRequestId
|
||||
? {
|
||||
loginName: submitted.factors.user.loginName,
|
||||
authRequestId: command.authRequestId,
|
||||
}
|
||||
: {
|
||||
loginName: submitted.factors.user.loginName,
|
||||
},
|
||||
);
|
||||
|
||||
if (command.organization) {
|
||||
params.append("organization", command.organization);
|
||||
}
|
||||
|
||||
return redirect(`/signedin?` + params);
|
||||
}
|
||||
|
||||
export async function changePassword(command: {
|
||||
|
||||
Reference in New Issue
Block a user