modifica login e inserimento creazione nuovo utente
This commit is contained in:
parent
79cfa791d2
commit
03835bf426
6 changed files with 304 additions and 112 deletions
|
|
@ -1,10 +1,6 @@
|
||||||
import type { ExpressAuthConfig } from "@auth/express";
|
import type { ExpressAuthConfig } from "@auth/express";
|
||||||
import Credentials from "@auth/express/providers/credentials";
|
import Credentials from "@auth/express/providers/credentials";
|
||||||
import bcrypt from "bcryptjs";
|
import { authenticateUser } from "./credentials.js";
|
||||||
import type { RowDataPacket } from "mysql2";
|
|
||||||
import pool from "../db/pool.js";
|
|
||||||
import type { Utente } from "../types/index.js";
|
|
||||||
import { validateLoginInput } from "../validation/utente.js";
|
|
||||||
|
|
||||||
const isProduction = process.env.NODE_ENV === "production";
|
const isProduction = process.env.NODE_ENV === "production";
|
||||||
|
|
||||||
|
|
@ -36,28 +32,18 @@ export const authConfig: ExpressAuthConfig = {
|
||||||
password: { label: "Password", type: "password" },
|
password: { label: "Password", type: "password" },
|
||||||
},
|
},
|
||||||
async authorize(credentials) {
|
async authorize(credentials) {
|
||||||
const validation = validateLoginInput(credentials ?? {});
|
const email = credentials?.email?.toString().trim().toLowerCase() ?? "";
|
||||||
|
const password = credentials?.password?.toString() ?? "";
|
||||||
|
if (!email || !password) return null;
|
||||||
|
|
||||||
if (!validation.success) return null;
|
const user = await authenticateUser(email, password);
|
||||||
|
if (!user) return null;
|
||||||
const { email, password } = validation.data;
|
|
||||||
|
|
||||||
const [rows] = await pool.execute<RowDataPacket[]>(
|
|
||||||
"SELECT UtenteID, Nome, Cognome, Email, PasswordHash, Ruolo FROM utente WHERE Email = ?",
|
|
||||||
[email]
|
|
||||||
);
|
|
||||||
|
|
||||||
const utente = rows[0] as Utente | undefined;
|
|
||||||
if (!utente) return null;
|
|
||||||
|
|
||||||
const valid = await bcrypt.compare(password, utente.PasswordHash);
|
|
||||||
if (!valid) return null;
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: String(utente.UtenteID),
|
id: String(user.id),
|
||||||
email: utente.Email,
|
email: user.email,
|
||||||
name: `${utente.Nome} ${utente.Cognome}`,
|
name: `${user.nome} ${user.cognome}`,
|
||||||
ruolo: utente.Ruolo,
|
ruolo: user.ruolo,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
|
|
||||||
45
src/auth/credentials.ts
Normal file
45
src/auth/credentials.ts
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
import bcrypt from "bcryptjs";
|
||||||
|
import type { RowDataPacket } from "mysql2";
|
||||||
|
import pool from "../db/pool.js";
|
||||||
|
import type { Ruolo } from "../types/index.js";
|
||||||
|
|
||||||
|
interface UtenteAuthRow extends RowDataPacket {
|
||||||
|
UtenteID: number;
|
||||||
|
Nome: string;
|
||||||
|
Cognome: string;
|
||||||
|
Email: string;
|
||||||
|
PasswordHash: string;
|
||||||
|
Ruolo: Ruolo;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AuthenticatedUser {
|
||||||
|
id: number;
|
||||||
|
nome: string;
|
||||||
|
cognome: string;
|
||||||
|
email: string;
|
||||||
|
ruolo: Ruolo;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function authenticateUser(
|
||||||
|
email: string,
|
||||||
|
password: string
|
||||||
|
): Promise<AuthenticatedUser | null> {
|
||||||
|
const [rows] = await pool.execute<UtenteAuthRow[]>(
|
||||||
|
"SELECT UtenteID, Nome, Cognome, Email, PasswordHash, Ruolo FROM utente WHERE Email = ?",
|
||||||
|
[email]
|
||||||
|
);
|
||||||
|
|
||||||
|
const utente = rows[0];
|
||||||
|
if (!utente) return null;
|
||||||
|
|
||||||
|
const valid = await bcrypt.compare(password, utente.PasswordHash);
|
||||||
|
if (!valid) return null;
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: utente.UtenteID,
|
||||||
|
nome: utente.Nome,
|
||||||
|
cognome: utente.Cognome,
|
||||||
|
email: utente.Email,
|
||||||
|
ruolo: utente.Ruolo,
|
||||||
|
};
|
||||||
|
}
|
||||||
37
src/auth/session.ts
Normal file
37
src/auth/session.ts
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
import { encode } from "@auth/core/jwt";
|
||||||
|
import type { Response } from "express";
|
||||||
|
import type { AuthenticatedUser } from "./credentials.js";
|
||||||
|
|
||||||
|
function getSessionCookieName(): string {
|
||||||
|
return process.env.NODE_ENV === "production"
|
||||||
|
? "__Secure-authjs.session-token"
|
||||||
|
: "authjs.session-token";
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function setAuthSession(
|
||||||
|
res: Response,
|
||||||
|
user: AuthenticatedUser
|
||||||
|
): Promise<void> {
|
||||||
|
const cookieName = getSessionCookieName();
|
||||||
|
const isProduction = process.env.NODE_ENV === "production";
|
||||||
|
|
||||||
|
const token = await encode({
|
||||||
|
token: {
|
||||||
|
name: `${user.nome} ${user.cognome}`,
|
||||||
|
email: user.email,
|
||||||
|
sub: String(user.id),
|
||||||
|
id: String(user.id),
|
||||||
|
ruolo: user.ruolo,
|
||||||
|
},
|
||||||
|
secret: process.env.AUTH_SECRET!,
|
||||||
|
salt: cookieName,
|
||||||
|
maxAge: 30 * 24 * 60 * 60,
|
||||||
|
});
|
||||||
|
|
||||||
|
res.cookie(cookieName, token, {
|
||||||
|
httpOnly: true,
|
||||||
|
secure: isProduction,
|
||||||
|
sameSite: isProduction ? "none" : "lax",
|
||||||
|
path: "/",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
@ -343,6 +343,63 @@ export const openApiSpec = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"/api/utenti/login": {
|
||||||
|
post: {
|
||||||
|
tags: ["Utenti"],
|
||||||
|
summary: "Login utente",
|
||||||
|
description:
|
||||||
|
"Autentica l'utente con email e password. Imposta il cookie di sessione.",
|
||||||
|
requestBody: {
|
||||||
|
required: true,
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
schema: {
|
||||||
|
type: "object",
|
||||||
|
required: ["email", "password"],
|
||||||
|
properties: {
|
||||||
|
email: { type: "string", format: "email" },
|
||||||
|
password: { type: "string" },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
responses: {
|
||||||
|
200: {
|
||||||
|
description: "Login riuscito",
|
||||||
|
content: { "application/json": { schema: utenteSchema } },
|
||||||
|
},
|
||||||
|
400: responses.validationError,
|
||||||
|
401: { description: "Credenziali non valide" },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"/api/utenti/register": {
|
||||||
|
post: {
|
||||||
|
tags: ["Utenti"],
|
||||||
|
summary: "Registra utente",
|
||||||
|
description:
|
||||||
|
"Crea un nuovo utente (Dipendente o Referente Academy). Richiede autenticazione Referente Academy.",
|
||||||
|
security: [{ cookieAuth: [] }],
|
||||||
|
requestBody: {
|
||||||
|
required: true,
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
schema: { $ref: "#/components/schemas/UtenteCreate" },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
responses: {
|
||||||
|
201: {
|
||||||
|
description: "Utente registrato",
|
||||||
|
content: { "application/json": { schema: utenteSchema } },
|
||||||
|
},
|
||||||
|
400: responses.validationError,
|
||||||
|
403: responses.forbidden,
|
||||||
|
409: { description: "Email già registrata" },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
"/api/utenti/{id}": {
|
"/api/utenti/{id}": {
|
||||||
get: {
|
get: {
|
||||||
tags: ["Utenti"],
|
tags: ["Utenti"],
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@
|
||||||
import bcrypt from "bcryptjs";
|
import bcrypt from "bcryptjs";
|
||||||
import { Router } from "express";
|
import { Router } from "express";
|
||||||
import type { ResultSetHeader, RowDataPacket } from "mysql2";
|
import type { ResultSetHeader, RowDataPacket } from "mysql2";
|
||||||
|
import { authenticateUser } from "../auth/credentials.js";
|
||||||
|
import { setAuthSession } from "../auth/session.js";
|
||||||
import pool from "../db/pool.js";
|
import pool from "../db/pool.js";
|
||||||
import { mapDbError } from "../errors/db.js";
|
import { mapDbError } from "../errors/db.js";
|
||||||
import { requireAuth, requireReferenteAcademy } from "../middleware/auth.js";
|
import { requireAuth, requireReferenteAcademy } from "../middleware/auth.js";
|
||||||
|
|
@ -14,8 +16,10 @@ import type { Ruolo } from "../types/index.js";
|
||||||
import { UTENTE_CONSTRAINTS } from "../validation/constraints.js";
|
import { UTENTE_CONSTRAINTS } from "../validation/constraints.js";
|
||||||
import { validateBody } from "../validation/middleware.js";
|
import { validateBody } from "../validation/middleware.js";
|
||||||
import {
|
import {
|
||||||
|
validateLoginInput,
|
||||||
validateUtenteCreate,
|
validateUtenteCreate,
|
||||||
validateUtenteUpdate,
|
validateUtenteUpdate,
|
||||||
|
type LoginInput,
|
||||||
type UtenteCreateInput,
|
type UtenteCreateInput,
|
||||||
type UtenteUpdateInput,
|
type UtenteUpdateInput,
|
||||||
} from "../validation/utente.js";
|
} from "../validation/utente.js";
|
||||||
|
|
@ -48,6 +52,127 @@ async function findUtenteById(id: number): Promise<UtenteRow | undefined> {
|
||||||
return rows[0];
|
return rows[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function insertUtente(body: UtenteCreateInput): Promise<UtenteRow> {
|
||||||
|
const passwordHash = await bcrypt.hash(body.password, 10);
|
||||||
|
const [result] = await pool.execute<ResultSetHeader>(
|
||||||
|
"INSERT INTO utente (Nome, Cognome, Email, PasswordHash, Ruolo) VALUES (?, ?, ?, ?, ?)",
|
||||||
|
[body.nome, body.cognome, body.email, passwordHash, body.ruolo]
|
||||||
|
);
|
||||||
|
|
||||||
|
const created = await findUtenteById(result.insertId);
|
||||||
|
if (!created) {
|
||||||
|
throw new Error("Errore durante la creazione dell'utente");
|
||||||
|
}
|
||||||
|
|
||||||
|
return created;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function applyUtenteUpdate(
|
||||||
|
id: number,
|
||||||
|
updates: UtenteUpdateInput
|
||||||
|
): Promise<UtenteRow> {
|
||||||
|
const setClauses: string[] = [];
|
||||||
|
const values: (string | number)[] = [];
|
||||||
|
|
||||||
|
if (updates.nome !== undefined) {
|
||||||
|
setClauses.push("Nome = ?");
|
||||||
|
values.push(updates.nome);
|
||||||
|
}
|
||||||
|
if (updates.cognome !== undefined) {
|
||||||
|
setClauses.push("Cognome = ?");
|
||||||
|
values.push(updates.cognome);
|
||||||
|
}
|
||||||
|
if (updates.email !== undefined) {
|
||||||
|
setClauses.push("Email = ?");
|
||||||
|
values.push(updates.email);
|
||||||
|
}
|
||||||
|
if (updates.ruolo !== undefined) {
|
||||||
|
setClauses.push("Ruolo = ?");
|
||||||
|
values.push(updates.ruolo);
|
||||||
|
}
|
||||||
|
if (updates.password) {
|
||||||
|
const passwordHash = await bcrypt.hash(updates.password, 10);
|
||||||
|
setClauses.push("PasswordHash = ?");
|
||||||
|
values.push(passwordHash);
|
||||||
|
}
|
||||||
|
|
||||||
|
await pool.execute<ResultSetHeader>(
|
||||||
|
`UPDATE utente SET ${setClauses.join(", ")} WHERE UtenteID = ?`,
|
||||||
|
[...values, id]
|
||||||
|
);
|
||||||
|
|
||||||
|
const updated = await findUtenteById(id);
|
||||||
|
if (!updated) {
|
||||||
|
throw new Error("Errore durante l'aggiornamento dell'utente");
|
||||||
|
}
|
||||||
|
|
||||||
|
return updated;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleUtenteDbError(
|
||||||
|
res: import("express").Response,
|
||||||
|
error: unknown
|
||||||
|
): boolean {
|
||||||
|
const mapped = mapDbError(error);
|
||||||
|
if (mapped) {
|
||||||
|
res.status(mapped.status).json({
|
||||||
|
error: mapped.error,
|
||||||
|
fields: mapped.fields,
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function createUtenteHandler(
|
||||||
|
body: UtenteCreateInput,
|
||||||
|
res: import("express").Response
|
||||||
|
): Promise<void> {
|
||||||
|
try {
|
||||||
|
const created = await insertUtente(body);
|
||||||
|
res.status(201).json(toUtenteResponse(created));
|
||||||
|
} catch (error) {
|
||||||
|
if (handleUtenteDbError(res, error)) return;
|
||||||
|
if (error instanceof Error && error.message.includes("creazione")) {
|
||||||
|
res.status(500).json({ error: error.message });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
router.post("/login", validateBody(validateLoginInput), async (_req, res) => {
|
||||||
|
const { email, password } = res.locals.validatedBody as LoginInput;
|
||||||
|
|
||||||
|
const user = await authenticateUser(email, password);
|
||||||
|
if (!user) {
|
||||||
|
res.status(401).json({ error: "Credenziali non valide" });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await setAuthSession(res, user);
|
||||||
|
res.json({
|
||||||
|
id: user.id,
|
||||||
|
nome: user.nome,
|
||||||
|
cognome: user.cognome,
|
||||||
|
email: user.email,
|
||||||
|
ruolo: user.ruolo,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
router.post(
|
||||||
|
"/register",
|
||||||
|
requireAuth,
|
||||||
|
requireReferenteAcademy,
|
||||||
|
validateBody(validateUtenteCreate),
|
||||||
|
async (_req, res) => {
|
||||||
|
await createUtenteHandler(
|
||||||
|
res.locals.validatedBody as UtenteCreateInput,
|
||||||
|
res
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
router.use(requireAuth, requireReferenteAcademy);
|
router.use(requireAuth, requireReferenteAcademy);
|
||||||
|
|
||||||
router.get("/", async (req, res) => {
|
router.get("/", async (req, res) => {
|
||||||
|
|
@ -90,33 +215,10 @@ router.get("/:id", async (req, res) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
router.post("/", validateBody(validateUtenteCreate), async (_req, res) => {
|
router.post("/", validateBody(validateUtenteCreate), async (_req, res) => {
|
||||||
const body = res.locals.validatedBody as UtenteCreateInput;
|
await createUtenteHandler(
|
||||||
|
res.locals.validatedBody as UtenteCreateInput,
|
||||||
try {
|
res
|
||||||
const passwordHash = await bcrypt.hash(body.password, 10);
|
);
|
||||||
const [result] = await pool.execute<ResultSetHeader>(
|
|
||||||
"INSERT INTO utente (Nome, Cognome, Email, PasswordHash, Ruolo) VALUES (?, ?, ?, ?, ?)",
|
|
||||||
[body.nome, body.cognome, body.email, passwordHash, body.ruolo]
|
|
||||||
);
|
|
||||||
|
|
||||||
const created = await findUtenteById(result.insertId);
|
|
||||||
if (!created) {
|
|
||||||
res.status(500).json({ error: "Errore durante la creazione dell'utente" });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
res.status(201).json(toUtenteResponse(created));
|
|
||||||
} catch (error) {
|
|
||||||
const mapped = mapDbError(error);
|
|
||||||
if (mapped) {
|
|
||||||
res.status(mapped.status).json({
|
|
||||||
error: mapped.error,
|
|
||||||
fields: mapped.fields,
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
router.put("/:id", validateBody(validateUtenteUpdate), async (req, res) => {
|
router.put("/:id", validateBody(validateUtenteUpdate), async (req, res) => {
|
||||||
|
|
@ -133,51 +235,14 @@ router.put("/:id", validateBody(validateUtenteUpdate), async (req, res) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const updates = res.locals.validatedBody as UtenteUpdateInput;
|
const updates = res.locals.validatedBody as UtenteUpdateInput;
|
||||||
const setClauses: string[] = [];
|
|
||||||
const values: (string | number)[] = [];
|
|
||||||
|
|
||||||
if (updates.nome !== undefined) {
|
|
||||||
setClauses.push("Nome = ?");
|
|
||||||
values.push(updates.nome);
|
|
||||||
}
|
|
||||||
if (updates.cognome !== undefined) {
|
|
||||||
setClauses.push("Cognome = ?");
|
|
||||||
values.push(updates.cognome);
|
|
||||||
}
|
|
||||||
if (updates.email !== undefined) {
|
|
||||||
setClauses.push("Email = ?");
|
|
||||||
values.push(updates.email);
|
|
||||||
}
|
|
||||||
if (updates.ruolo !== undefined) {
|
|
||||||
setClauses.push("Ruolo = ?");
|
|
||||||
values.push(updates.ruolo);
|
|
||||||
}
|
|
||||||
if (updates.password) {
|
|
||||||
const passwordHash = await bcrypt.hash(updates.password, 10);
|
|
||||||
setClauses.push("PasswordHash = ?");
|
|
||||||
values.push(passwordHash);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await pool.execute<ResultSetHeader>(
|
const updated = await applyUtenteUpdate(id, updates);
|
||||||
`UPDATE utente SET ${setClauses.join(", ")} WHERE UtenteID = ?`,
|
|
||||||
[...values, id]
|
|
||||||
);
|
|
||||||
|
|
||||||
const updated = await findUtenteById(id);
|
|
||||||
if (!updated) {
|
|
||||||
res.status(500).json({ error: "Errore durante l'aggiornamento dell'utente" });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
res.json(toUtenteResponse(updated));
|
res.json(toUtenteResponse(updated));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const mapped = mapDbError(error);
|
if (handleUtenteDbError(res, error)) return;
|
||||||
if (mapped) {
|
if (error instanceof Error && error.message.includes("aggiornamento")) {
|
||||||
res.status(mapped.status).json({
|
res.status(500).json({ error: error.message });
|
||||||
error: mapped.error,
|
|
||||||
fields: mapped.fields,
|
|
||||||
});
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
throw error;
|
throw error;
|
||||||
|
|
|
||||||
|
|
@ -62,8 +62,8 @@ export function validateLoginInput(
|
||||||
return buildResult(data, errors);
|
return buildResult(data, errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
function validateUtenteProfileFields(
|
function validateNomeCognomeEmail(
|
||||||
data: UtenteCreateInput,
|
data: Pick<UtenteCreateInput, "nome" | "cognome" | "email">,
|
||||||
errors: FieldErrors
|
errors: FieldErrors
|
||||||
): void {
|
): void {
|
||||||
validateRequired(errors, "nome", data.nome, "Nome obbligatorio");
|
validateRequired(errors, "nome", data.nome, "Nome obbligatorio");
|
||||||
|
|
@ -91,23 +91,39 @@ function validateUtenteProfileFields(
|
||||||
"Email"
|
"Email"
|
||||||
);
|
);
|
||||||
validateEmailFormat(errors, "email", data.email);
|
validateEmailFormat(errors, "email", data.email);
|
||||||
|
}
|
||||||
|
|
||||||
validateRequired(errors, "password", data.password, "Password obbligatoria");
|
function validatePasswordField(
|
||||||
|
errors: FieldErrors,
|
||||||
|
password: string,
|
||||||
|
options: { required: boolean }
|
||||||
|
): void {
|
||||||
|
if (options.required) {
|
||||||
|
validateRequired(errors, "password", password, "Password obbligatoria");
|
||||||
|
}
|
||||||
|
if (!password) return;
|
||||||
validateMinLength(
|
validateMinLength(
|
||||||
errors,
|
errors,
|
||||||
"password",
|
"password",
|
||||||
data.password,
|
password,
|
||||||
UTENTE_CONSTRAINTS.password.minLength,
|
UTENTE_CONSTRAINTS.password.minLength,
|
||||||
"Password"
|
"Password"
|
||||||
);
|
);
|
||||||
validateMaxLength(
|
validateMaxLength(
|
||||||
errors,
|
errors,
|
||||||
"password",
|
"password",
|
||||||
data.password,
|
password,
|
||||||
UTENTE_CONSTRAINTS.password.maxLength,
|
UTENTE_CONSTRAINTS.password.maxLength,
|
||||||
"Password"
|
"Password"
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function validateUtenteProfileFields(
|
||||||
|
data: UtenteCreateInput,
|
||||||
|
errors: FieldErrors
|
||||||
|
): void {
|
||||||
|
validateNomeCognomeEmail(data, errors);
|
||||||
|
validatePasswordField(errors, data.password, { required: true });
|
||||||
validateRequired(errors, "ruolo", data.ruolo, "Ruolo obbligatorio");
|
validateRequired(errors, "ruolo", data.ruolo, "Ruolo obbligatorio");
|
||||||
validateEnum(
|
validateEnum(
|
||||||
errors,
|
errors,
|
||||||
|
|
@ -135,7 +151,6 @@ export function validateUtenteCreate(
|
||||||
return buildResult(data, errors);
|
return buildResult(data, errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export function validateUtenteUpdate(
|
export function validateUtenteUpdate(
|
||||||
raw: Record<string, unknown>
|
raw: Record<string, unknown>
|
||||||
): ValidationResult<UtenteUpdateInput> {
|
): ValidationResult<UtenteUpdateInput> {
|
||||||
|
|
@ -183,20 +198,7 @@ export function validateUtenteUpdate(
|
||||||
const password = raw.password?.toString() ?? "";
|
const password = raw.password?.toString() ?? "";
|
||||||
if (password) {
|
if (password) {
|
||||||
data.password = password;
|
data.password = password;
|
||||||
validateMinLength(
|
validatePasswordField(errors, password, { required: false });
|
||||||
errors,
|
|
||||||
"password",
|
|
||||||
password,
|
|
||||||
UTENTE_CONSTRAINTS.password.minLength,
|
|
||||||
"Password"
|
|
||||||
);
|
|
||||||
validateMaxLength(
|
|
||||||
errors,
|
|
||||||
"password",
|
|
||||||
password,
|
|
||||||
UTENTE_CONSTRAINTS.password.maxLength,
|
|
||||||
"Password"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue