mirror of
https://github.com/zitadel/zitadel.git
synced 2025-12-12 05:12:20 +00:00
hide mfa method from selection if phone or email is not verified
This commit is contained in:
@@ -14,6 +14,7 @@ import {
|
||||
getMostRecentCookieWithLoginname,
|
||||
getSessionCookieById,
|
||||
} from "#/utils/cookies";
|
||||
import { user } from "@zitadel/server";
|
||||
|
||||
export default async function Page({
|
||||
searchParams,
|
||||
@@ -23,7 +24,7 @@ export default async function Page({
|
||||
const { loginName, checkAfter, authRequestId, organization, sessionId } =
|
||||
searchParams;
|
||||
|
||||
const sessionFactors = sessionId
|
||||
const sessionWithData = sessionId
|
||||
? await loadSessionById(sessionId, organization)
|
||||
: await loadSessionByLoginname(loginName, organization);
|
||||
|
||||
@@ -37,13 +38,16 @@ export default async function Page({
|
||||
);
|
||||
return getSession(server, recent.id, recent.token).then((response) => {
|
||||
if (response?.session && response.session.factors?.user?.id) {
|
||||
return listAuthenticationMethodTypes(
|
||||
response.session.factors.user.id
|
||||
).then((methods) => {
|
||||
return {
|
||||
factors: response.session?.factors,
|
||||
authMethods: methods.authMethodTypes ?? [],
|
||||
};
|
||||
const userId = response.session.factors.user.id;
|
||||
return listAuthenticationMethodTypes(userId).then((methods) => {
|
||||
return getUserByID(userId).then((user) => {
|
||||
return {
|
||||
factors: response.session?.factors,
|
||||
authMethods: methods.authMethodTypes ?? [],
|
||||
phoneVerified: user.user?.human?.phone?.isVerified ?? false,
|
||||
emailVerified: user.user?.human?.email?.isVerified ?? false,
|
||||
};
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -53,13 +57,16 @@ export default async function Page({
|
||||
const recent = await getSessionCookieById(sessionId, organization);
|
||||
return getSession(server, recent.id, recent.token).then((response) => {
|
||||
if (response?.session && response.session.factors?.user?.id) {
|
||||
return listAuthenticationMethodTypes(
|
||||
response.session.factors.user.id
|
||||
).then((methods) => {
|
||||
return {
|
||||
factors: response.session?.factors,
|
||||
authMethods: methods.authMethodTypes ?? [],
|
||||
};
|
||||
const userId = response.session.factors.user.id;
|
||||
return listAuthenticationMethodTypes(userId).then((methods) => {
|
||||
return getUserByID(userId).then((user) => {
|
||||
return {
|
||||
factors: response.session?.factors,
|
||||
authMethods: methods.authMethodTypes ?? [],
|
||||
phoneVerified: user.user?.human?.phone?.isVerified ?? false,
|
||||
emailVerified: user.user?.human?.email?.isVerified ?? false,
|
||||
};
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -75,10 +82,10 @@ export default async function Page({
|
||||
|
||||
<p className="ztdl-p">Choose one of the following second factors.</p>
|
||||
|
||||
{sessionFactors && (
|
||||
{sessionWithData && (
|
||||
<UserAvatar
|
||||
loginName={loginName ?? sessionFactors.factors?.user?.loginName}
|
||||
displayName={sessionFactors.factors?.user?.displayName}
|
||||
loginName={loginName ?? sessionWithData.factors?.user?.loginName}
|
||||
displayName={sessionWithData.factors?.user?.displayName}
|
||||
showDropdown
|
||||
searchParams={searchParams}
|
||||
></UserAvatar>
|
||||
@@ -88,14 +95,16 @@ export default async function Page({
|
||||
<Alert>Provide your active session as loginName param</Alert>
|
||||
)}
|
||||
|
||||
{loginSettings && sessionFactors ? (
|
||||
{loginSettings && sessionWithData ? (
|
||||
<ChooseSecondFactorToSetup
|
||||
loginName={loginName}
|
||||
sessionId={sessionId}
|
||||
authRequestId={authRequestId}
|
||||
organization={organization}
|
||||
loginSettings={loginSettings}
|
||||
userMethods={sessionFactors.authMethods ?? []}
|
||||
userMethods={sessionWithData.authMethods ?? []}
|
||||
phoneVerified={sessionWithData.phoneVerified ?? false}
|
||||
emailVerified={sessionWithData.emailVerified ?? false}
|
||||
checkAfter={checkAfter === "true"}
|
||||
></ChooseSecondFactorToSetup>
|
||||
) : (
|
||||
|
||||
@@ -2,16 +2,37 @@ import clsx from "clsx";
|
||||
import Link from "next/link";
|
||||
import { BadgeState, StateBadge } from "./StateBadge";
|
||||
import { CheckIcon } from "@heroicons/react/24/solid";
|
||||
import { ReactNode } from "react";
|
||||
|
||||
const cardClasses = (alreadyAdded: boolean) =>
|
||||
clsx(
|
||||
"relative bg-background-light-400 dark:bg-background-dark-400 group block space-y-1.5 rounded-md px-5 py-3 border border-divider-light dark:border-divider-dark transition-all ",
|
||||
alreadyAdded ? "" : "hover:shadow-lg hover:dark:bg-white/10"
|
||||
alreadyAdded
|
||||
? "opacity-50 cursor-default"
|
||||
: "hover:shadow-lg hover:dark:bg-white/10"
|
||||
);
|
||||
|
||||
const LinkWrapper = ({
|
||||
alreadyAdded,
|
||||
children,
|
||||
link,
|
||||
}: {
|
||||
alreadyAdded: boolean;
|
||||
children: ReactNode;
|
||||
link: string;
|
||||
}) => {
|
||||
return !alreadyAdded ? (
|
||||
<Link href={link} className={cardClasses(alreadyAdded)}>
|
||||
{children}
|
||||
</Link>
|
||||
) : (
|
||||
<div className={cardClasses(alreadyAdded)}>{children}</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const TOTP = (alreadyAdded: boolean, link: string) => {
|
||||
return (
|
||||
<Link href={link} className={cardClasses(alreadyAdded)}>
|
||||
<LinkWrapper alreadyAdded={alreadyAdded} link={link}>
|
||||
<div
|
||||
className={clsx(
|
||||
"font-medium flex items-center",
|
||||
@@ -66,13 +87,13 @@ C72,238.87917,85.87916,225,102.99997,225H248z"
|
||||
<Setup />
|
||||
</>
|
||||
)}
|
||||
</Link>
|
||||
</LinkWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
export const U2F = (alreadyAdded: boolean, link: string) => {
|
||||
return (
|
||||
<Link href={link} className={cardClasses(alreadyAdded)}>
|
||||
<LinkWrapper alreadyAdded={alreadyAdded} link={link}>
|
||||
<div
|
||||
className={clsx(
|
||||
"font-medium flex items-center",
|
||||
@@ -100,13 +121,13 @@ export const U2F = (alreadyAdded: boolean, link: string) => {
|
||||
<Setup />
|
||||
</>
|
||||
)}
|
||||
</Link>
|
||||
</LinkWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
export const EMAIL = (alreadyAdded: boolean, link: string) => {
|
||||
return (
|
||||
<Link href={link} className={cardClasses(alreadyAdded)}>
|
||||
<LinkWrapper alreadyAdded={alreadyAdded} link={link}>
|
||||
<div
|
||||
className={clsx(
|
||||
"font-medium flex items-center",
|
||||
@@ -135,13 +156,13 @@ export const EMAIL = (alreadyAdded: boolean, link: string) => {
|
||||
<Setup />
|
||||
</>
|
||||
)}
|
||||
</Link>
|
||||
</LinkWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
export const SMS = (alreadyAdded: boolean, link: string) => {
|
||||
return (
|
||||
<Link href={link} className={cardClasses(alreadyAdded)}>
|
||||
<LinkWrapper alreadyAdded={alreadyAdded} link={link}>
|
||||
<div
|
||||
className={clsx(
|
||||
"font-medium flex items-center",
|
||||
@@ -169,7 +190,7 @@ export const SMS = (alreadyAdded: boolean, link: string) => {
|
||||
<Setup />
|
||||
</>
|
||||
)}
|
||||
</Link>
|
||||
</LinkWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -11,6 +11,8 @@ type Props = {
|
||||
loginSettings: LoginSettings;
|
||||
userMethods: AuthenticationMethodType[];
|
||||
checkAfter: boolean;
|
||||
phoneVerified: boolean;
|
||||
emailVerified: boolean;
|
||||
};
|
||||
|
||||
export default function ChooseSecondFactorToSetup({
|
||||
@@ -21,6 +23,8 @@ export default function ChooseSecondFactorToSetup({
|
||||
loginSettings,
|
||||
userMethods,
|
||||
checkAfter,
|
||||
phoneVerified,
|
||||
emailVerified,
|
||||
}: Props) {
|
||||
const params = new URLSearchParams({});
|
||||
|
||||
@@ -43,20 +47,15 @@ export default function ChooseSecondFactorToSetup({
|
||||
return (
|
||||
<div className="grid grid-cols-1 gap-5 w-full pt-4">
|
||||
{loginSettings.secondFactors.map((factor, i) => {
|
||||
return (
|
||||
<div key={"method-" + i}>
|
||||
{factor === 1 &&
|
||||
TOTP(
|
||||
userMethods.includes(4),
|
||||
userMethods.includes(4) ? "" : "/otp/time-based/set?" + params
|
||||
)}
|
||||
{factor === 2 && U2F(userMethods.includes(5), "/u2f/set?" + params)}
|
||||
{factor === 3 &&
|
||||
EMAIL(userMethods.includes(7), "/otp/email/set?" + params)}
|
||||
{factor === 4 &&
|
||||
SMS(userMethods.includes(6), "/otp/sms/set?" + params)}
|
||||
</div>
|
||||
);
|
||||
return factor === 1
|
||||
? TOTP(userMethods.includes(4), "/otp/time-based/set?" + params)
|
||||
: factor === 2
|
||||
? U2F(userMethods.includes(5), "/u2f/set?" + params)
|
||||
: factor === 3 && emailVerified
|
||||
? EMAIL(userMethods.includes(7), "/otp/email/set?" + params)
|
||||
: factor === 4 && phoneVerified
|
||||
? SMS(userMethods.includes(6), "/otp/sms/set?" + params)
|
||||
: null;
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user