feat(auth): enhance validation rules for username and password
- Updated username validation to allow only lowercase letters, numbers, and underscores. - Strengthened password requirements to include at least 8 characters, one uppercase letter, one lowercase letter, one number, and one special character. - Adjusted frontend forms and backend DTOs to reflect new validation rules.
This commit is contained in:
@@ -148,7 +148,7 @@ describe("AuthService", () => {
|
||||
const dto = {
|
||||
username: "test",
|
||||
email: "test@example.com",
|
||||
password: "password",
|
||||
password: "Password1!",
|
||||
};
|
||||
mockHashingService.hashPassword.mockResolvedValue("hashed-password");
|
||||
mockHashingService.hashEmail.mockResolvedValue("hashed-email");
|
||||
@@ -165,7 +165,7 @@ describe("AuthService", () => {
|
||||
|
||||
describe("login", () => {
|
||||
it("should login a user", async () => {
|
||||
const dto = { email: "test@example.com", password: "password" };
|
||||
const dto = { email: "test@example.com", password: "Password1!" };
|
||||
const user = {
|
||||
uuid: "user-id",
|
||||
username: "test",
|
||||
|
||||
@@ -2,6 +2,7 @@ import {
|
||||
IsEmail,
|
||||
IsNotEmpty,
|
||||
IsString,
|
||||
Matches,
|
||||
MaxLength,
|
||||
MinLength,
|
||||
} from "class-validator";
|
||||
@@ -10,6 +11,9 @@ export class RegisterDto {
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
@MaxLength(32)
|
||||
@Matches(/^[a-z0-9_]+$/, {
|
||||
message: "username must contain only lowercase letters, numbers, and underscores",
|
||||
})
|
||||
username!: string;
|
||||
|
||||
@IsString()
|
||||
@@ -21,5 +25,15 @@ export class RegisterDto {
|
||||
|
||||
@IsString()
|
||||
@MinLength(8)
|
||||
@Matches(/[A-Z]/, {
|
||||
message: "password must contain at least one uppercase letter",
|
||||
})
|
||||
@Matches(/[a-z]/, {
|
||||
message: "password must contain at least one lowercase letter",
|
||||
})
|
||||
@Matches(/[0-9]/, { message: "password must contain at least one number" })
|
||||
@Matches(/[^A-Za-z0-9]/, {
|
||||
message: "password must contain at least one special character",
|
||||
})
|
||||
password!: string;
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ const loginSchema = z.object({
|
||||
email: z.string().email({ message: "Email invalide" }),
|
||||
password: z
|
||||
.string()
|
||||
.min(6, { message: "Le mot de passe doit faire au moins 6 caractères" }),
|
||||
.min(8, { message: "Le mot de passe doit faire au moins 8 caractères" }),
|
||||
});
|
||||
|
||||
type LoginFormValues = z.infer<typeof loginSchema>;
|
||||
|
||||
@@ -29,11 +29,24 @@ import { useAuth } from "@/providers/auth-provider";
|
||||
const registerSchema = z.object({
|
||||
username: z
|
||||
.string()
|
||||
.min(3, { message: "Le pseudo doit faire au moins 3 caractères" }),
|
||||
.min(3, { message: "Le pseudo doit faire au moins 3 caractères" })
|
||||
.regex(/^[a-z0-9_]+$/, {
|
||||
message: "Le pseudo ne doit contenir que des minuscules, chiffres et underscores",
|
||||
}),
|
||||
email: z.string().email({ message: "Email invalide" }),
|
||||
password: z
|
||||
.string()
|
||||
.min(6, { message: "Le mot de passe doit faire au moins 6 caractères" }),
|
||||
.min(8, { message: "Le mot de passe doit faire au moins 8 caractères" })
|
||||
.regex(/[A-Z]/, {
|
||||
message: "Le mot de passe doit contenir au moins une majuscule",
|
||||
})
|
||||
.regex(/[a-z]/, {
|
||||
message: "Le mot de passe doit contenir au moins une minuscule",
|
||||
})
|
||||
.regex(/[0-9]/, { message: "Le mot de passe doit contenir au moins un chiffre" })
|
||||
.regex(/[^A-Za-z0-9]/, {
|
||||
message: "Le mot de passe doit contenir au moins un caractère spécial",
|
||||
}),
|
||||
displayName: z.string().optional(),
|
||||
});
|
||||
|
||||
@@ -84,12 +97,25 @@ export default function RegisterPage() {
|
||||
<CardContent>
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="displayName"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Nom d'affichage (Optionnel)</FormLabel>
|
||||
<FormControl>
|
||||
<Input placeholder="Le Roi des Chèvres" {...field} />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="username"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Pseudo</FormLabel>
|
||||
<FormLabel>Pseudo (minuscule)</FormLabel>
|
||||
<FormControl>
|
||||
<Input placeholder="supergoat" {...field} />
|
||||
</FormControl>
|
||||
@@ -110,19 +136,6 @@ export default function RegisterPage() {
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="displayName"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Nom d'affichage (Optionnel)</FormLabel>
|
||||
<FormControl>
|
||||
<Input placeholder="Le Roi des Chèvres" {...field} />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="password"
|
||||
|
||||
Reference in New Issue
Block a user