2026-03-01 17:35:00 +00:00
import { z } from "zod" ;
2026-06-09 12:34:15 -07:00
import { type UserRole } from "@/domain/users/user.type.js" ;
2026-03-01 17:35:00 +00:00
export const passwordPattern =
/^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!?@#$%^&*()\-_=+[\]{};:'",.~`|\\/])[A-Za-z0-9!?@#$%^&*()\-_=+[\]{};:'",.~`|\\/]+$/ ;
2026-05-15 11:14:39 -07:00
export const passwordValidation = z
. string ()
. min ( 8 , "Password must be at least 8 characters" )
. regex ( passwordPattern , "Password must contain at least one lowercase letter, one uppercase letter, one number, and one special character" );
2026-03-01 17:35:00 +00:00
export const nameValidation = z
. string ()
. trim ()
. max ( 50 , "Name must be less than 50 characters" )
. regex (
/^(?=.*[\p{L}\p{Sc}])[\p{L}\p{Sc}\s'\-().]+$/u,
"Names must contain at least 1 letter and may only include letters, currency symbols, spaces, apostrophes, hyphens (-), periods (.), and parentheses ()."
);
2026-03-02 21:35:08 +00:00
export const lowercaseEmailValidation = z . email (). transform (( val ) => val . toLowerCase ());
2026-03-01 17:35:00 +00:00
2026-05-11 10:01:42 -07:00
export const dnsServerValidation = z
. string ()
. min ( 1 , "DNS server is required" )
. refine (( v ) => z . ipv4 (). safeParse ( v ). success || z . ipv6 (). safeParse ( v ). success , "Enter a valid IPv4 or IPv6 address (e.g. 8.8.8.8)" );
2026-05-11 10:12:27 -07:00
// Hostname (FQDN) — labels of 1-63 alphanumerics/hyphens separated by dots,
2026-05-11 10:27:41 -07:00
// optionally prefixed with `_` for service labels (e.g. _dmarc, _imaps._tcp).
// No scheme, port, path, or whitespace. Total length ≤ 253. Kept in sync with
2026-05-11 10:12:27 -07:00
// the client-side regex in client/src/Validation/monitor.ts.
2026-05-11 10:27:41 -07:00
export const dnsHostnameRegex = /^(?=.{1,253}$)([a-zA-Z0-9_](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,63}$/ ;
2026-05-11 10:12:27 -07:00
2026-03-02 19:25:34 +00:00
export const booleanCoercion = z . preprocess (( val ) => {
if ( val === "true" || val === true ) return true ;
if ( val === "false" || val === false ) return false ;
return val ; // Let Zod validation handle invalid values
}, z . boolean ());
2026-03-01 17:35:00 +00:00
export const roleValidator = ( allowedRoles : UserRole []) => {
return z . array ( z . custom < UserRole >()). refine (( userRoles ) => allowedRoles . some (( role ) => userRoles . includes ( role )), {
message : `You do not have the required authorization. Required roles: ${ allowedRoles . join ( ", " ) } ` ,
});
};