mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-14 04:27:34 +00:00
implement mfa init prompt
This commit is contained in:
@@ -71,7 +71,8 @@
|
||||
},
|
||||
"set": {
|
||||
"title": "2-Faktor einrichten",
|
||||
"description": "Wählen Sie einen der folgenden zweiten Faktoren."
|
||||
"description": "Wählen Sie einen der folgenden zweiten Faktoren.",
|
||||
"skip": "Überspringen"
|
||||
}
|
||||
},
|
||||
"otp": {
|
||||
|
@@ -71,7 +71,8 @@
|
||||
},
|
||||
"set": {
|
||||
"title": "Set up 2-Factor",
|
||||
"description": "Choose one of the following second factors."
|
||||
"description": "Choose one of the following second factors.",
|
||||
"skip": "Skip"
|
||||
}
|
||||
},
|
||||
"otp": {
|
||||
|
@@ -71,7 +71,8 @@
|
||||
},
|
||||
"set": {
|
||||
"title": "Configurar autenticación de 2 factores",
|
||||
"description": "Elige uno de los siguientes factores secundarios."
|
||||
"description": "Elige uno de los siguientes factores secundarios.",
|
||||
"skip": "Omitir"
|
||||
}
|
||||
},
|
||||
"otp": {
|
||||
|
@@ -71,7 +71,8 @@
|
||||
},
|
||||
"set": {
|
||||
"title": "Configura l'autenticazione a 2 fattori",
|
||||
"description": "Scegli uno dei seguenti secondi fattori."
|
||||
"description": "Scegli uno dei seguenti secondi fattori.",
|
||||
"skip": "Salta"
|
||||
}
|
||||
},
|
||||
"otp": {
|
||||
|
@@ -71,7 +71,8 @@
|
||||
},
|
||||
"set": {
|
||||
"title": "设置双因素认证",
|
||||
"description": "选择以下的一个第二因素。"
|
||||
"description": "选择以下的一个第二因素。",
|
||||
"skip": "跳过"
|
||||
}
|
||||
},
|
||||
"otp": {
|
||||
|
@@ -161,6 +161,12 @@ export default async function Page(props: {
|
||||
></ChooseSecondFactorToSetup>
|
||||
)}
|
||||
|
||||
{force !== "true" && (
|
||||
<div>
|
||||
<p>{t("set.skip")}</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="mt-8 flex w-full flex-row items-center">
|
||||
<BackButton />
|
||||
<span className="flex-grow"></span>
|
||||
|
@@ -16,7 +16,7 @@ import {
|
||||
setPassword,
|
||||
setUserPassword,
|
||||
} from "@/lib/zitadel";
|
||||
import { create } from "@zitadel/client";
|
||||
import { ConnectError, create } from "@zitadel/client";
|
||||
import { createServerTransport } from "@zitadel/client/node";
|
||||
import { createUserServiceClient } from "@zitadel/client/v2";
|
||||
import {
|
||||
@@ -267,7 +267,8 @@ export async function sendPassword(command: UpdateSessionCommand) {
|
||||
return { error: "Could not verify password!" };
|
||||
}
|
||||
|
||||
const mfaFactorCheck = checkMFAFactors(
|
||||
const mfaFactorCheck = await checkMFAFactors(
|
||||
serviceUrl,
|
||||
session,
|
||||
loginSettings,
|
||||
authMethods,
|
||||
@@ -433,7 +434,7 @@ export async function checkSessionAndSetPassword({
|
||||
},
|
||||
{},
|
||||
)
|
||||
.catch((error) => {
|
||||
.catch((error: ConnectError) => {
|
||||
console.log(error);
|
||||
if (error.code === 7) {
|
||||
return { error: "Session is not valid." };
|
||||
|
@@ -203,7 +203,8 @@ export async function sendVerification(command: VerifyUserByEmailCommand) {
|
||||
}
|
||||
|
||||
// redirect to mfa factor if user has one, or redirect to set one up
|
||||
const mfaFactorCheck = checkMFAFactors(
|
||||
const mfaFactorCheck = await checkMFAFactors(
|
||||
serviceUrl,
|
||||
session,
|
||||
loginSettings,
|
||||
authMethodResponse.authMethodTypes,
|
||||
@@ -407,12 +408,12 @@ export async function sendVerificationRedirectWithoutCheck(
|
||||
|
||||
const loginSettings = await getLoginSettings({
|
||||
serviceUrl,
|
||||
|
||||
organization: user.details?.resourceOwner,
|
||||
});
|
||||
|
||||
// redirect to mfa factor if user has one, or redirect to set one up
|
||||
const mfaFactorCheck = checkMFAFactors(
|
||||
const mfaFactorCheck = await checkMFAFactors(
|
||||
serviceUrl,
|
||||
session,
|
||||
loginSettings,
|
||||
authMethodResponse.authMethodTypes,
|
||||
|
@@ -5,6 +5,7 @@ import { PasswordExpirySettings } from "@zitadel/proto/zitadel/settings/v2/passw
|
||||
import { HumanUser } from "@zitadel/proto/zitadel/user/v2/user_pb";
|
||||
import { AuthenticationMethodType } from "@zitadel/proto/zitadel/user/v2/user_service_pb";
|
||||
import moment from "moment";
|
||||
import { getUserByID } from "./zitadel";
|
||||
|
||||
export function checkPasswordChangeRequired(
|
||||
expirySettings: PasswordExpirySettings | undefined,
|
||||
@@ -100,7 +101,8 @@ export function checkEmailVerification(
|
||||
}
|
||||
}
|
||||
|
||||
export function checkMFAFactors(
|
||||
export async function checkMFAFactors(
|
||||
serviceUrl: string,
|
||||
session: Session,
|
||||
loginSettings: LoginSettings | undefined,
|
||||
authMethods: AuthenticationMethodType[],
|
||||
@@ -188,31 +190,42 @@ export function checkMFAFactors(
|
||||
);
|
||||
}
|
||||
|
||||
// TODO: provide a way to setup passkeys on mfa page?
|
||||
return { redirect: `/mfa/set?` + params };
|
||||
} else if (
|
||||
loginSettings?.mfaInitSkipLifetime &&
|
||||
(loginSettings.mfaInitSkipLifetime.nanos > 0 ||
|
||||
loginSettings.mfaInitSkipLifetime.seconds > 0) &&
|
||||
!availableMultiFactors.length &&
|
||||
session?.factors?.user?.id
|
||||
) {
|
||||
const user = await getUserByID({
|
||||
serviceUrl,
|
||||
userId: session.factors?.user?.id,
|
||||
});
|
||||
if (
|
||||
user.user?.type?.case === "human" &&
|
||||
user.user?.type?.value.mfaInitSkipped
|
||||
) {
|
||||
}
|
||||
const params = new URLSearchParams({
|
||||
loginName: session.factors?.user?.loginName as string,
|
||||
force: "false", // this defines if the mfa is not forced in the settings and can be skipped
|
||||
checkAfter: "true", // this defines if the check is directly made after the setup
|
||||
});
|
||||
|
||||
if (requestId) {
|
||||
params.append("requestId", requestId);
|
||||
}
|
||||
|
||||
if (organization || session.factors?.user?.organizationId) {
|
||||
params.append(
|
||||
"organization",
|
||||
organization ?? (session.factors?.user?.organizationId as string),
|
||||
);
|
||||
}
|
||||
|
||||
// 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 (requestId) {
|
||||
// params.append("requestId", requestId);
|
||||
// }
|
||||
|
||||
// if (organization) {
|
||||
// params.append("organization", organization);
|
||||
// }
|
||||
|
||||
// return router.push(`/passkey/set?` + params);
|
||||
// }
|
||||
}
|
||||
|
Reference in New Issue
Block a user