set password

This commit is contained in:
peintnermax
2024-10-16 11:20:23 +02:00
parent 20b3c6bfc2
commit 94bd6bc3f6
8 changed files with 52 additions and 31 deletions

View File

@@ -134,6 +134,7 @@
},
"error": {
"unknownContext": "Der Kontext des Benutzers konnte nicht ermittelt werden. Stellen Sie sicher, dass Sie zuerst den Benutzernamen eingeben oder einen loginName als Suchparameter angeben.",
"sessionExpired": "Ihre aktuelle Sitzung ist abgelaufen. Bitte melden Sie sich erneut an."
"sessionExpired": "Ihre aktuelle Sitzung ist abgelaufen. Bitte melden Sie sich erneut an.",
"failedLoading": "Daten konnten nicht geladen werden. Bitte versuchen Sie es erneut."
}
}

View File

@@ -134,6 +134,7 @@
},
"error": {
"unknownContext": "Could not get the context of the user. Make sure to enter the username first or provide a loginName as searchParam.",
"sessionExpired": "Your current session has expired. Please login again."
"sessionExpired": "Your current session has expired. Please login again.",
"failedLoading": "Failed to load data. Please try again."
}
}

View File

@@ -134,6 +134,7 @@
},
"error": {
"unknownContext": "No se pudo obtener el contexto del usuario. Asegúrate de ingresar primero el nombre de usuario o proporcionar un loginName como parámetro de búsqueda.",
"sessionExpired": "Tu sesión actual ha expirado. Por favor, inicia sesión de nuevo."
"sessionExpired": "Tu sesión actual ha expirado. Por favor, inicia sesión de nuevo.",
"failedLoading": "No se pudieron cargar los datos. Por favor, inténtalo de nuevo."
}
}

View File

@@ -134,6 +134,7 @@
},
"error": {
"unknownContext": "Impossibile ottenere il contesto dell'utente. Assicurati di inserire prima il nome utente o di fornire un loginName come parametro di ricerca.",
"sessionExpired": "La tua sessione attuale è scaduta. Effettua nuovamente l'accesso."
"sessionExpired": "La tua sessione attuale è scaduta. Effettua nuovamente l'accesso.",
"failedLoading": "Impossibile caricare i dati. Riprova."
}
}

View File

@@ -3,7 +3,11 @@ import { DynamicTheme } from "@/components/dynamic-theme";
import { SetPasswordForm } from "@/components/set-password-form";
import { UserAvatar } from "@/components/user-avatar";
import { loadMostRecentSession } from "@/lib/session";
import { getBrandingSettings, getLoginSettings } from "@/lib/zitadel";
import {
getBrandingSettings,
getLoginSettings,
getPasswordComplexitySettings,
} from "@/lib/zitadel";
import { getLocale, getTranslations } from "next-intl/server";
export default async function Page({
@@ -14,24 +18,21 @@ export default async function Page({
const locale = getLocale();
const t = await getTranslations({ locale, namespace: "password" });
const { loginName, organization, authRequestId, alt } = searchParams;
const { loginName, organization, authRequestId, code } = searchParams;
// also allow no session to be found (ignoreUnkownUsername)
let sessionFactors;
try {
sessionFactors = await loadMostRecentSession({
const sessionFactors = await loadMostRecentSession({
loginName,
organization,
});
} catch (error) {
// ignore error to continue to show the password form
console.warn(error);
}
const branding = await getBrandingSettings(organization);
const loginSettings = await getLoginSettings(organization);
console.log(sessionFactors);
const passwordComplexity = await getPasswordComplexitySettings(
sessionFactors?.factors?.user?.organizationId,
);
const loginSettings = await getLoginSettings(organization);
return (
<DynamicTheme branding={branding}>
@@ -56,13 +57,18 @@ export default async function Page({
></UserAvatar>
)}
{loginName && (
{passwordComplexity && loginName ? (
<SetPasswordForm
code={code}
loginName={loginName}
authRequestId={authRequestId}
organization={organization}
loginSettings={loginSettings}
passwordComplexitySettings={passwordComplexity}
/>
) : (
<div className="py-4">
<Alert>{t("error:failedLoading")}</Alert>
</div>
)}
</div>
</DynamicTheme>

View File

@@ -6,6 +6,7 @@ import {
symbolValidator,
upperCaseValidator,
} from "@/helpers/validators";
import { changePassword } from "@/lib/server/password";
import { RegisterUserResponse } from "@/lib/server/register";
import { PasswordComplexitySettings } from "@zitadel/proto/zitadel/settings/v2/password_settings_pb";
import { useTranslations } from "next-intl";
@@ -27,7 +28,9 @@ type Inputs =
| FieldValues;
type Props = {
code?: string;
passwordComplexitySettings: PasswordComplexitySettings;
loginName: string;
organization?: string;
authRequestId?: string;
};

View File

@@ -5,9 +5,11 @@ import {
setSessionAndUpdateCookie,
} from "@/lib/server/cookie";
import {
getUserByID,
listAuthenticationMethodTypes,
listUsers,
passwordReset,
setPassword,
} from "@/lib/zitadel";
import { create } from "@zitadel/client";
import {
@@ -109,23 +111,17 @@ export async function sendPassword(command: UpdateSessionCommand) {
}
export async function changePassword(command: {
code?: string;
userId: string;
password: string;
}) {
// check for init state
const users = await listUsers({
loginName: command.loginName,
organizationId: command.organization,
});
const { user } = await getUserByID(command.userId);
if (
!users.details ||
users.details.totalResult !== BigInt(1) ||
!users.result[0].userId
) {
if (!user || user.userId !== command.userId) {
return { error: "Could not send Password Reset Link" };
}
const userId = users.result[0].userId;
const userId = user.userId;
return passwordReset(userId);
return setPassword(userId, command.password);
}

View File

@@ -500,6 +500,18 @@ export async function passwordReset(userId: string) {
);
}
export async function setPassword(userId: string, password: string) {
return userService.setPassword(
{
userId,
newPassword: {
password,
},
},
{},
);
}
/**
*
* @param server