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": { "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.", "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": { "error": {
"unknownContext": "Could not get the context of the user. Make sure to enter the username first or provide a loginName as searchParam.", "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": { "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.", "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": { "error": {
"unknownContext": "Impossibile ottenere il contesto dell'utente. Assicurati di inserire prima il nome utente o di fornire un loginName come parametro di ricerca.", "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 { SetPasswordForm } from "@/components/set-password-form";
import { UserAvatar } from "@/components/user-avatar"; import { UserAvatar } from "@/components/user-avatar";
import { loadMostRecentSession } from "@/lib/session"; 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"; import { getLocale, getTranslations } from "next-intl/server";
export default async function Page({ export default async function Page({
@@ -14,24 +18,21 @@ export default async function Page({
const locale = getLocale(); const locale = getLocale();
const t = await getTranslations({ locale, namespace: "password" }); 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) // also allow no session to be found (ignoreUnkownUsername)
let sessionFactors; const sessionFactors = await loadMostRecentSession({
try { loginName,
sessionFactors = await loadMostRecentSession({ organization,
loginName, });
organization,
});
} catch (error) {
// ignore error to continue to show the password form
console.warn(error);
}
const branding = await getBrandingSettings(organization); 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 ( return (
<DynamicTheme branding={branding}> <DynamicTheme branding={branding}>
@@ -56,13 +57,18 @@ export default async function Page({
></UserAvatar> ></UserAvatar>
)} )}
{loginName && ( {passwordComplexity && loginName ? (
<SetPasswordForm <SetPasswordForm
code={code}
loginName={loginName} loginName={loginName}
authRequestId={authRequestId} authRequestId={authRequestId}
organization={organization} organization={organization}
loginSettings={loginSettings} passwordComplexitySettings={passwordComplexity}
/> />
) : (
<div className="py-4">
<Alert>{t("error:failedLoading")}</Alert>
</div>
)} )}
</div> </div>
</DynamicTheme> </DynamicTheme>

View File

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

View File

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