mirror of
https://github.com/zitadel/zitadel.git
synced 2025-12-12 05:06:55 +00:00
checkafter redirect, continue after setup
This commit is contained in:
@@ -20,7 +20,7 @@ export default async function Page({
|
|||||||
}: {
|
}: {
|
||||||
searchParams: Record<string | number | symbol, string | undefined>;
|
searchParams: Record<string | number | symbol, string | undefined>;
|
||||||
}) {
|
}) {
|
||||||
const { loginName, altPassword, authRequestId, organization, sessionId } =
|
const { loginName, checkAfter, authRequestId, organization, sessionId } =
|
||||||
searchParams;
|
searchParams;
|
||||||
|
|
||||||
const sessionFactors = sessionId
|
const sessionFactors = sessionId
|
||||||
@@ -95,6 +95,7 @@ export default async function Page({
|
|||||||
organization={organization}
|
organization={organization}
|
||||||
loginSettings={loginSettings}
|
loginSettings={loginSettings}
|
||||||
userMethods={sessionFactors.authMethods ?? []}
|
userMethods={sessionFactors.authMethods ?? []}
|
||||||
|
checkAfter={checkAfter === "true"}
|
||||||
></ChooseSecondFactorToSetup>
|
></ChooseSecondFactorToSetup>
|
||||||
) : (
|
) : (
|
||||||
<Alert>No second factors available to setup.</Alert>
|
<Alert>No second factors available to setup.</Alert>
|
||||||
|
|||||||
@@ -7,11 +7,14 @@ import {
|
|||||||
server,
|
server,
|
||||||
} from "#/lib/zitadel";
|
} from "#/lib/zitadel";
|
||||||
import Alert from "#/ui/Alert";
|
import Alert from "#/ui/Alert";
|
||||||
|
import { Button, ButtonVariants } from "#/ui/Button";
|
||||||
import DynamicTheme from "#/ui/DynamicTheme";
|
import DynamicTheme from "#/ui/DynamicTheme";
|
||||||
|
import { Spinner } from "#/ui/Spinner";
|
||||||
import TOTPRegister from "#/ui/TOTPRegister";
|
import TOTPRegister from "#/ui/TOTPRegister";
|
||||||
import UserAvatar from "#/ui/UserAvatar";
|
import UserAvatar from "#/ui/UserAvatar";
|
||||||
import { getMostRecentCookieWithLoginname } from "#/utils/cookies";
|
import { getMostRecentCookieWithLoginname } from "#/utils/cookies";
|
||||||
import { RegisterTOTPResponse } from "@zitadel/server";
|
import { RegisterTOTPResponse } from "@zitadel/server";
|
||||||
|
import Link from "next/link";
|
||||||
import { ClientError } from "nice-grpc";
|
import { ClientError } from "nice-grpc";
|
||||||
|
|
||||||
export default async function Page({
|
export default async function Page({
|
||||||
@@ -21,7 +24,8 @@ export default async function Page({
|
|||||||
searchParams: Record<string | number | symbol, string | undefined>;
|
searchParams: Record<string | number | symbol, string | undefined>;
|
||||||
params: Record<string | number | symbol, string | undefined>;
|
params: Record<string | number | symbol, string | undefined>;
|
||||||
}) {
|
}) {
|
||||||
const { loginName, organization, sessionId, authRequestId } = searchParams;
|
const { loginName, organization, sessionId, authRequestId, checkAfter } =
|
||||||
|
searchParams;
|
||||||
const { method } = params;
|
const { method } = params;
|
||||||
|
|
||||||
const branding = await getBrandingSettings(server, organization);
|
const branding = await getBrandingSettings(server, organization);
|
||||||
@@ -65,6 +69,34 @@ export default async function Page({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const paramsToContinue = new URLSearchParams({});
|
||||||
|
let urlToContinue = "/accounts";
|
||||||
|
|
||||||
|
if (authRequestId && sessionId) {
|
||||||
|
if (sessionId) {
|
||||||
|
paramsToContinue.append("sessionId", sessionId);
|
||||||
|
}
|
||||||
|
if (authRequestId) {
|
||||||
|
paramsToContinue.append("authRequestId", authRequestId);
|
||||||
|
}
|
||||||
|
if (organization) {
|
||||||
|
paramsToContinue.append("organization", organization);
|
||||||
|
}
|
||||||
|
urlToContinue = `/login?` + paramsToContinue;
|
||||||
|
} else if (loginName) {
|
||||||
|
if (loginName) {
|
||||||
|
paramsToContinue.append("loginName", loginName);
|
||||||
|
}
|
||||||
|
if (authRequestId) {
|
||||||
|
paramsToContinue.append("authRequestId", authRequestId);
|
||||||
|
}
|
||||||
|
if (organization) {
|
||||||
|
paramsToContinue.append("organization", organization);
|
||||||
|
}
|
||||||
|
|
||||||
|
urlToContinue = `/signedin?` + paramsToContinue;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DynamicTheme branding={branding}>
|
<DynamicTheme branding={branding}>
|
||||||
<div className="flex flex-col items-center space-y-4">
|
<div className="flex flex-col items-center space-y-4">
|
||||||
@@ -107,17 +139,39 @@ export default async function Page({
|
|||||||
sessionId={sessionId}
|
sessionId={sessionId}
|
||||||
authRequestId={authRequestId}
|
authRequestId={authRequestId}
|
||||||
organization={organization}
|
organization={organization}
|
||||||
|
checkAfter={checkAfter === "true"}
|
||||||
></TOTPRegister>
|
></TOTPRegister>
|
||||||
</div>{" "}
|
</div>{" "}
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<p className="ztdl-p">
|
<>
|
||||||
{method === "email"
|
<p className="ztdl-p">
|
||||||
? "Code via email was successfully added."
|
{method === "email"
|
||||||
: method === "sms"
|
? "Code via email was successfully added."
|
||||||
? "Code via SMS was successfully added."
|
: method === "sms"
|
||||||
: ""}
|
? "Code via SMS was successfully added."
|
||||||
</p>
|
: ""}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div className="mt-8 flex w-full flex-row items-center">
|
||||||
|
<span className="flex-grow"></span>
|
||||||
|
<Link
|
||||||
|
href={
|
||||||
|
checkAfter
|
||||||
|
? `/otp/${method}?` + new URLSearchParams()
|
||||||
|
: urlToContinue
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
type="submit"
|
||||||
|
className="self-end"
|
||||||
|
variant={ButtonVariants.Primary}
|
||||||
|
>
|
||||||
|
continue
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</DynamicTheme>
|
</DynamicTheme>
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ type Props = {
|
|||||||
organization?: string;
|
organization?: string;
|
||||||
loginSettings: LoginSettings;
|
loginSettings: LoginSettings;
|
||||||
userMethods: AuthenticationMethodType[];
|
userMethods: AuthenticationMethodType[];
|
||||||
|
checkAfter: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function ChooseSecondFactorToSetup({
|
export default function ChooseSecondFactorToSetup({
|
||||||
@@ -26,6 +27,7 @@ export default function ChooseSecondFactorToSetup({
|
|||||||
organization,
|
organization,
|
||||||
loginSettings,
|
loginSettings,
|
||||||
userMethods,
|
userMethods,
|
||||||
|
checkAfter,
|
||||||
}: Props) {
|
}: Props) {
|
||||||
const cardClasses = (alreadyAdded: boolean) =>
|
const cardClasses = (alreadyAdded: boolean) =>
|
||||||
clsx(
|
clsx(
|
||||||
@@ -47,6 +49,9 @@ export default function ChooseSecondFactorToSetup({
|
|||||||
if (organization) {
|
if (organization) {
|
||||||
params.append("organization", organization);
|
params.append("organization", organization);
|
||||||
}
|
}
|
||||||
|
if (checkAfter) {
|
||||||
|
params.append("checkAfter", "true");
|
||||||
|
}
|
||||||
|
|
||||||
const TOTP = (alreadyAdded: boolean) => {
|
const TOTP = (alreadyAdded: boolean) => {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -120,6 +120,7 @@ export default function PasswordForm({
|
|||||||
} else if (loginSettings?.forceMfa && !resp.authFactors?.length) {
|
} else if (loginSettings?.forceMfa && !resp.authFactors?.length) {
|
||||||
const params = new URLSearchParams({
|
const params = new URLSearchParams({
|
||||||
loginName: resp.factors.user.loginName,
|
loginName: resp.factors.user.loginName,
|
||||||
|
checkAfter: "true", // this defines if the check is directly made after the setup
|
||||||
});
|
});
|
||||||
|
|
||||||
if (authRequestId) {
|
if (authRequestId) {
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ type Props = {
|
|||||||
sessionId?: string;
|
sessionId?: string;
|
||||||
authRequestId?: string;
|
authRequestId?: string;
|
||||||
organization?: string;
|
organization?: string;
|
||||||
|
checkAfter?: boolean;
|
||||||
};
|
};
|
||||||
export default function TOTPRegister({
|
export default function TOTPRegister({
|
||||||
uri,
|
uri,
|
||||||
@@ -31,6 +32,7 @@ export default function TOTPRegister({
|
|||||||
sessionId,
|
sessionId,
|
||||||
authRequestId,
|
authRequestId,
|
||||||
organization,
|
organization,
|
||||||
|
checkAfter,
|
||||||
}: Props) {
|
}: Props) {
|
||||||
const [error, setError] = useState<string>("");
|
const [error, setError] = useState<string>("");
|
||||||
const [loading, setLoading] = useState<boolean>(false);
|
const [loading, setLoading] = useState<boolean>(false);
|
||||||
@@ -48,22 +50,13 @@ export default function TOTPRegister({
|
|||||||
return verifyTOTP(values.code, loginName, organization)
|
return verifyTOTP(values.code, loginName, organization)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
if (authRequestId && sessionId) {
|
// if attribute is set, validate MFA after it is setup, otherwise proceed as usual (when mfa is enforced to login)
|
||||||
const params = new URLSearchParams({
|
if (checkAfter) {
|
||||||
sessionId: sessionId,
|
const params = new URLSearchParams({});
|
||||||
authRequest: authRequestId,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (organization) {
|
if (loginName) {
|
||||||
params.append("organization", organization);
|
params.append("loginName", loginName);
|
||||||
}
|
}
|
||||||
|
|
||||||
return router.push(`/login?` + params);
|
|
||||||
} else if (loginName) {
|
|
||||||
const params = new URLSearchParams({
|
|
||||||
loginName,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (authRequestId) {
|
if (authRequestId) {
|
||||||
params.append("authRequestId", authRequestId);
|
params.append("authRequestId", authRequestId);
|
||||||
}
|
}
|
||||||
@@ -71,7 +64,33 @@ export default function TOTPRegister({
|
|||||||
params.append("organization", organization);
|
params.append("organization", organization);
|
||||||
}
|
}
|
||||||
|
|
||||||
return router.push(`/signedin?` + params);
|
return router.push(`/otp/time-based?` + params);
|
||||||
|
} else {
|
||||||
|
if (authRequestId && sessionId) {
|
||||||
|
const params = new URLSearchParams({
|
||||||
|
sessionId: sessionId,
|
||||||
|
authRequest: authRequestId,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (organization) {
|
||||||
|
params.append("organization", organization);
|
||||||
|
}
|
||||||
|
|
||||||
|
return router.push(`/login?` + params);
|
||||||
|
} else if (loginName) {
|
||||||
|
const params = new URLSearchParams({
|
||||||
|
loginName,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (authRequestId) {
|
||||||
|
params.append("authRequestId", authRequestId);
|
||||||
|
}
|
||||||
|
if (organization) {
|
||||||
|
params.append("organization", organization);
|
||||||
|
}
|
||||||
|
|
||||||
|
return router.push(`/signedin?` + params);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user