mirror of
https://github.com/zitadel/zitadel.git
synced 2025-12-12 15:03:52 +00:00
initial param for password set page, fix cookie overflow
This commit is contained in:
@@ -19,7 +19,7 @@ export default async function Page({
|
||||
const t = await getTranslations({ locale, namespace: "password" });
|
||||
const tError = await getTranslations({ locale, namespace: "error" });
|
||||
|
||||
const { loginName, organization, authRequestId, code } = searchParams;
|
||||
const { loginName, organization, authRequestId } = searchParams;
|
||||
|
||||
// also allow no session to be found (ignoreUnkownUsername)
|
||||
const sessionFactors = await loadMostRecentSession({
|
||||
|
||||
@@ -22,7 +22,8 @@ export default async function Page({
|
||||
const t = await getTranslations({ locale, namespace: "password" });
|
||||
const tError = await getTranslations({ locale, namespace: "error" });
|
||||
|
||||
const { userId, loginName, organization, authRequestId, code } = searchParams;
|
||||
const { userId, loginName, organization, authRequestId, code, initial } =
|
||||
searchParams;
|
||||
|
||||
// also allow no session to be found (ignoreUnkownUsername)
|
||||
let session: Session | undefined;
|
||||
@@ -81,7 +82,7 @@ export default async function Page({
|
||||
></UserAvatar>
|
||||
) : null}
|
||||
|
||||
<Alert type={AlertType.INFO}>{t("set.codeSent")}</Alert>
|
||||
{!initial && <Alert type={AlertType.INFO}>{t("set.codeSent")}</Alert>}
|
||||
|
||||
{passwordComplexity &&
|
||||
(loginName ?? user?.preferredLoginName) &&
|
||||
@@ -93,6 +94,7 @@ export default async function Page({
|
||||
authRequestId={authRequestId}
|
||||
organization={organization}
|
||||
passwordComplexitySettings={passwordComplexity}
|
||||
codeRequired={!(initial === "true")}
|
||||
/>
|
||||
) : (
|
||||
<div className="py-4">
|
||||
|
||||
@@ -104,13 +104,13 @@ export const U2F = (alreadyAdded: boolean, link: string) => {
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
strokeWidth="1.5"
|
||||
stroke="currentColor"
|
||||
className="w-8 h-8 mr-4"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
d="M7.864 4.243A7.5 7.5 0 0119.5 10.5c0 2.92-.556 5.709-1.568 8.268M5.742 6.364A7.465 7.465 0 004.5 10.5a7.464 7.464 0 01-1.15 3.993m1.989 3.559A11.209 11.209 0 008.25 10.5a3.75 3.75 0 117.5 0c0 .527-.021 1.049-.064 1.565M12 10.5a14.94 14.94 0 01-3.6 9.75m6.633-4.596a18.666 18.666 0 01-2.485 5.33"
|
||||
/>
|
||||
</svg>
|
||||
@@ -143,8 +143,8 @@ export const EMAIL = (alreadyAdded: boolean, link: string) => {
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
d="M21.75 6.75v10.5a2.25 2.25 0 01-2.25 2.25h-15a2.25 2.25 0 01-2.25-2.25V6.75m19.5 0A2.25 2.25 0 0019.5 4.5h-15a2.25 2.25 0 00-2.25 2.25m19.5 0v.243a2.25 2.25 0 01-1.07 1.916l-7.5 4.615a2.25 2.25 0 01-2.36 0L3.32 8.91a2.25 2.25 0 01-1.07-1.916V6.75"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -12,7 +12,6 @@ import { create } from "@zitadel/client";
|
||||
import { ChecksSchema } from "@zitadel/proto/zitadel/session/v2/session_service_pb";
|
||||
import { PasswordComplexitySettings } from "@zitadel/proto/zitadel/settings/v2/password_settings_pb";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import { FieldValues, useForm } from "react-hook-form";
|
||||
import { Alert } from "./alert";
|
||||
@@ -57,8 +56,6 @@ export function ChangePasswordForm({
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
const [error, setError] = useState<string>("");
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
async function submitChange(values: Inputs) {
|
||||
setLoading(true);
|
||||
const changeResponse = await setMyPassword({
|
||||
|
||||
@@ -35,6 +35,7 @@ type Props = {
|
||||
userId: string;
|
||||
organization?: string;
|
||||
authRequestId?: string;
|
||||
codeRequired: boolean;
|
||||
};
|
||||
|
||||
export function SetPasswordForm({
|
||||
@@ -44,6 +45,7 @@ export function SetPasswordForm({
|
||||
loginName,
|
||||
userId,
|
||||
code,
|
||||
codeRequired,
|
||||
}: Props) {
|
||||
const t = useTranslations("password");
|
||||
|
||||
@@ -59,11 +61,17 @@ export function SetPasswordForm({
|
||||
|
||||
async function submitRegister(values: Inputs) {
|
||||
setLoading(true);
|
||||
const changeResponse = await changePassword({
|
||||
let payload: { userId: string; password: string; code?: string } = {
|
||||
userId: userId,
|
||||
password: values.password,
|
||||
code: values.code,
|
||||
}).catch(() => {
|
||||
};
|
||||
|
||||
// this is not required for initial password setup
|
||||
if (codeRequired) {
|
||||
payload = { ...payload, code: values.code };
|
||||
}
|
||||
|
||||
const changeResponse = await changePassword(payload).catch(() => {
|
||||
setError("Could not register user");
|
||||
});
|
||||
|
||||
@@ -94,7 +102,8 @@ export function SetPasswordForm({
|
||||
password: { password: values.password },
|
||||
}),
|
||||
authRequestId,
|
||||
}).catch(() => {
|
||||
}).catch((error) => {
|
||||
console.error("verifyerror", error);
|
||||
setLoading(false);
|
||||
setError("Could not verify password");
|
||||
return;
|
||||
@@ -109,23 +118,6 @@ export function SetPasswordForm({
|
||||
) {
|
||||
setError(passwordResponse.error);
|
||||
}
|
||||
|
||||
// // skip verification for now as it is an app based flow
|
||||
// // return router.push(`/verify?` + params);
|
||||
|
||||
// // check for mfa force to continue with mfa setup
|
||||
|
||||
// if (authRequestId && changeResponse.sessionId) {
|
||||
// if (authRequestId) {
|
||||
// params.append("authRequest", authRequestId);
|
||||
// }
|
||||
// return router.push(`/login?` + params);
|
||||
// } else {
|
||||
// if (authRequestId) {
|
||||
// params.append("authRequestId", authRequestId);
|
||||
// }
|
||||
// return router.push(`/signedin?` + params);
|
||||
// }
|
||||
}
|
||||
|
||||
const { errors } = formState;
|
||||
@@ -152,25 +144,28 @@ export function SetPasswordForm({
|
||||
return (
|
||||
<form className="w-full">
|
||||
<div className="pt-4 grid grid-cols-1 gap-4 mb-4">
|
||||
<div className="flex flex-row items-end">
|
||||
<div className="flex-1">
|
||||
<TextInput
|
||||
type="text"
|
||||
required
|
||||
{...register("code", {
|
||||
required: "This field is required",
|
||||
})}
|
||||
label="Code"
|
||||
autoComplete="one-time-code"
|
||||
error={errors.code?.message as string}
|
||||
/>
|
||||
{codeRequired && (
|
||||
<div className="flex flex-row items-end">
|
||||
<div className="flex-1">
|
||||
<TextInput
|
||||
type="text"
|
||||
required
|
||||
{...register("code", {
|
||||
required: "This field is required",
|
||||
})}
|
||||
label="Code"
|
||||
autoComplete="one-time-code"
|
||||
error={errors.code?.message as string}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="ml-4 mb-1">
|
||||
<Button variant={ButtonVariants.Secondary}>
|
||||
{t("set.resend")}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="ml-4 mb-1">
|
||||
<Button variant={ButtonVariants.Secondary}>
|
||||
{t("set.resend")}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="">
|
||||
<TextInput
|
||||
type="password"
|
||||
|
||||
@@ -65,7 +65,13 @@ export function VerifyEmailForm({
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const params = new URLSearchParams({});
|
||||
const params = new URLSearchParams({
|
||||
userId: userId,
|
||||
});
|
||||
|
||||
if (isInvite) {
|
||||
params.append("initial", "true");
|
||||
}
|
||||
|
||||
if (loginName) {
|
||||
params.append("loginName", loginName);
|
||||
@@ -121,7 +127,10 @@ export function VerifyEmailForm({
|
||||
}
|
||||
|
||||
// if auth methods fall trough, we complete to login
|
||||
const params = new URLSearchParams({});
|
||||
const params = new URLSearchParams({
|
||||
userId: userId,
|
||||
initial: "true", // defines that a code is not required and is therefore not shown in the UI
|
||||
});
|
||||
|
||||
if (organization) {
|
||||
params.set("organization", organization);
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
import { cookies } from "next/headers";
|
||||
import { LANGUAGE_COOKIE_NAME } from "./i18n";
|
||||
|
||||
// TODO: improve this to handle overflow
|
||||
export const MAX_COOKIE_SIZE = 4096;
|
||||
|
||||
export type Cookie = {
|
||||
id: string;
|
||||
token: string;
|
||||
@@ -56,7 +59,13 @@ export async function addSessionToCookie<T>(
|
||||
if (index > -1) {
|
||||
currentSessions[index] = session;
|
||||
} else {
|
||||
currentSessions = [...currentSessions, session];
|
||||
const temp = [...currentSessions, session];
|
||||
|
||||
if (temp.length > MAX_COOKIE_SIZE) {
|
||||
// TODO: improve cookie handling
|
||||
// this replaces the first session (oldest) with the new one
|
||||
currentSessions = [session].concat(currentSessions.slice(1));
|
||||
}
|
||||
}
|
||||
|
||||
if (cleanup) {
|
||||
|
||||
@@ -169,7 +169,6 @@ export const PROVIDER_MAPPING: {
|
||||
} = {
|
||||
[IdentityProviderType.GOOGLE]: (idp: IDPInformation) => {
|
||||
const rawInfo = idp.rawInformation as OIDC_USER;
|
||||
console.log(rawInfo);
|
||||
|
||||
return create(AddHumanUserRequestSchema, {
|
||||
username: idp.userName,
|
||||
|
||||
@@ -71,8 +71,6 @@ export async function sendPassword(command: UpdateSessionCommand) {
|
||||
organizationId: command.organization,
|
||||
});
|
||||
|
||||
console.log(users);
|
||||
|
||||
if (users.details?.totalResult == BigInt(1) && users.result[0].userId) {
|
||||
user = users.result[0];
|
||||
|
||||
@@ -89,7 +87,7 @@ export async function sendPassword(command: UpdateSessionCommand) {
|
||||
}
|
||||
|
||||
// this is a fake error message to hide that the user does not even exist
|
||||
return { error: "Could not verify password!" };
|
||||
return { error: "Could not verify password" };
|
||||
} else {
|
||||
session = await setSessionAndUpdateCookie(
|
||||
sessionCookie,
|
||||
@@ -274,7 +272,7 @@ export async function sendPassword(command: UpdateSessionCommand) {
|
||||
}
|
||||
|
||||
export async function changePassword(command: {
|
||||
code: string;
|
||||
code?: string;
|
||||
userId: string;
|
||||
password: string;
|
||||
}) {
|
||||
|
||||
@@ -13,6 +13,7 @@ import { Checks } from "@zitadel/proto/zitadel/session/v2/session_service_pb";
|
||||
import { IDPInformation } from "@zitadel/proto/zitadel/user/v2/idp_pb";
|
||||
import {
|
||||
RetrieveIdentityProviderIntentRequest,
|
||||
SetPasswordRequestSchema,
|
||||
VerifyPasskeyRegistrationRequest,
|
||||
VerifyU2FRegistrationRequest,
|
||||
} from "@zitadel/proto/zitadel/user/v2/user_service_pb";
|
||||
@@ -315,7 +316,6 @@ export async function verifyInviteCode(
|
||||
}
|
||||
|
||||
export async function resendInviteCode(userId: string) {
|
||||
console.log("resetInit");
|
||||
return userService.resendInviteCode({ userId }, {});
|
||||
}
|
||||
|
||||
@@ -580,24 +580,50 @@ export async function passwordReset(userId: string, host: string | null) {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param userId userId of the user to set the password for
|
||||
* @param password the new password
|
||||
* @param code optional if the password should be set with a code (reset), no code for initial setup of password
|
||||
* @returns
|
||||
*/
|
||||
export async function setPassword(
|
||||
userId: string,
|
||||
password: string,
|
||||
code: string,
|
||||
code?: string,
|
||||
) {
|
||||
return userService.setPassword(
|
||||
{
|
||||
userId,
|
||||
newPassword: {
|
||||
password,
|
||||
},
|
||||
let payload = create(SetPasswordRequestSchema, {
|
||||
userId,
|
||||
newPassword: {
|
||||
password,
|
||||
},
|
||||
});
|
||||
|
||||
// check if the user has no password set in order to set a password
|
||||
if (!code) {
|
||||
const authmethods = await listAuthenticationMethodTypes(userId);
|
||||
|
||||
// if the user has no authmethods set, we can set a password otherwise we need a code
|
||||
if (
|
||||
!authmethods ||
|
||||
!authmethods.authMethodTypes ||
|
||||
authmethods.authMethodTypes.length === 0
|
||||
) {
|
||||
return { error: "Provide a code to set a password" };
|
||||
}
|
||||
}
|
||||
|
||||
if (code) {
|
||||
payload = {
|
||||
...payload,
|
||||
verification: {
|
||||
case: "verificationCode",
|
||||
value: code,
|
||||
},
|
||||
},
|
||||
{},
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
return userService.setPassword(payload, {});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user