fix: add utf8 email validation support (#6239)
Co-authored-by: Thomas <thomas@ajnart.fr>
This commit is contained in:
1 parent
7c152cf4fe
commit
7d93df04dd
6 files changed
+43
-13
No files matched your search
@@ -0,0 +1,16 @@
|
||||
import { z } from "zod/v4";
|
||||
|
||||
export const utf8EmailSchema = z.email({ pattern: z.regexes.unicodeEmail });
|
||||
|
||||
export const optionalEmailSchema = utf8EmailSchema.or(z.string().length(0)).optional();
|
||||
|
||||
export const nullableEmailSchema = utf8EmailSchema
|
||||
.or(z.literal(""))
|
||||
.transform((value) => (value === "" ? null : value))
|
||||
.optional()
|
||||
.nullable();
|
||||
|
||||
export const requiredNullableEmailSchema = utf8EmailSchema
|
||||
.or(z.literal(""))
|
||||
.transform((value) => (value === "" ? null : value))
|
||||
.nullable();
|
||||
@@ -4,6 +4,7 @@ import { z } from "zod/v4";
|
||||
import type { TranslationFunction } from "@homarr/translation";
|
||||
|
||||
import { createCustomErrorParams, zodErrorMap } from "./i18n";
|
||||
import { utf8EmailSchema } from "../email";
|
||||
|
||||
const expectError = (error: z.core.$ZodIssue, key: string) => {
|
||||
expect(error.message).toContain(key);
|
||||
@@ -111,4 +112,19 @@ describe("i18n", () => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
expectError(result.error.issues[0]!, "boardAlreadyExists");
|
||||
});
|
||||
|
||||
test("should validate UTF8SMTP email with umlauts", () => {
|
||||
const result = utf8EmailSchema.safeParse("jörg@example.com");
|
||||
expect(result.success).toBe(true);
|
||||
});
|
||||
|
||||
test("should validate UTF8SMTP email with unicode domain", () => {
|
||||
const result = utf8EmailSchema.safeParse("user@münchen.de");
|
||||
expect(result.success).toBe(true);
|
||||
});
|
||||
|
||||
test("should validate standard ASCII emails", () => {
|
||||
const result = utf8EmailSchema.safeParse("user@example.com");
|
||||
expect(result.success).toBe(true);
|
||||
});
|
||||
});
|
||||
@@ -6,6 +6,7 @@ import type { TranslationObject } from "@homarr/translation";
|
||||
|
||||
import { zodEnumFromArray } from "./enums";
|
||||
import { createCustomErrorParams } from "./form/i18n";
|
||||
import { nullableEmailSchema, optionalEmailSchema } from "./email";
|
||||
|
||||
// We always want the lowercase version of the username to compare it in a case-insensitive way
|
||||
export const usernameSchema = z.string().trim().toLowerCase().min(3).max(255);
|
||||
@@ -42,7 +43,7 @@ export const userBaseCreateSchema = z.object({
|
||||
username: usernameSchema,
|
||||
password: userPasswordSchema,
|
||||
confirmPassword: z.string(),
|
||||
email: z.string().email().or(z.string().length(0)).optional(),
|
||||
email: optionalEmailSchema,
|
||||
});
|
||||
|
||||
export const userCreateSchema = addConfirmPasswordRefinement(userBaseCreateSchema).and(
|
||||
@@ -85,13 +86,7 @@ export const userRegistrationApiSchema = userRegistrationSchema.and(
|
||||
export const userEditProfileSchema = z.object({
|
||||
id: z.string(),
|
||||
name: usernameSchema,
|
||||
email: z
|
||||
.string()
|
||||
.email()
|
||||
.or(z.literal(""))
|
||||
.transform((value) => (value === "" ? null : value))
|
||||
.optional()
|
||||
.nullable(),
|
||||
email: nullableEmailSchema,
|
||||
});
|
||||
|
||||
const baseChangePasswordSchema = z.object({
|
||||
|
||||
Reference in new issue
Block a user