| | const { z } = require('zod'); |
| |
|
| | const MIN_PASSWORD_LENGTH = parseInt(process.env.MIN_PASSWORD_LENGTH, 10) || 8; |
| |
|
| | const allowedCharactersRegex = new RegExp( |
| | '^[' + |
| | 'a-zA-Z0-9_.@#$%&*()' + |
| | '\\p{Script=Latin}' + |
| | '\\p{Script=Common}' + |
| | '\\p{Script=Cyrillic}' + |
| | '\\p{Script=Devanagari}' + |
| | '\\p{Script=Han}' + |
| | '\\p{Script=Arabic}' + |
| | '\\p{Script=Hiragana}' + |
| | '\\p{Script=Katakana}' + |
| | '\\p{Script=Hangul}' + |
| | ']+$', |
| | 'u', |
| | ); |
| | const injectionPatternsRegex = /('|--|\$ne|\$gt|\$lt|\$or|\{|\}|\*|;|<|>|\/|=)/i; |
| |
|
| | const usernameSchema = z |
| | .string() |
| | .min(2) |
| | .max(80) |
| | .refine((value) => allowedCharactersRegex.test(value), { |
| | message: 'Invalid characters in username', |
| | }) |
| | .refine((value) => !injectionPatternsRegex.test(value), { |
| | message: 'Potential injection attack detected', |
| | }); |
| |
|
| | const loginSchema = z.object({ |
| | email: z.string().email(), |
| | password: z |
| | .string() |
| | .min(MIN_PASSWORD_LENGTH) |
| | .max(128) |
| | .refine((value) => value.trim().length > 0, { |
| | message: 'Password cannot be only spaces', |
| | }), |
| | }); |
| |
|
| | const registerSchema = z |
| | .object({ |
| | name: z.string().min(3).max(80), |
| | username: z |
| | .union([z.literal(''), usernameSchema]) |
| | .transform((value) => (value === '' ? null : value)) |
| | .optional() |
| | .nullable(), |
| | email: z.string().email(), |
| | password: z |
| | .string() |
| | .min(MIN_PASSWORD_LENGTH) |
| | .max(128) |
| | .refine((value) => value.trim().length > 0, { |
| | message: 'Password cannot be only spaces', |
| | }), |
| | confirm_password: z |
| | .string() |
| | .min(MIN_PASSWORD_LENGTH) |
| | .max(128) |
| | .refine((value) => value.trim().length > 0, { |
| | message: 'Password cannot be only spaces', |
| | }), |
| | }) |
| | .superRefine(({ confirm_password, password }, ctx) => { |
| | if (confirm_password !== password) { |
| | ctx.addIssue({ |
| | code: 'custom', |
| | message: 'The passwords did not match', |
| | }); |
| | } |
| | }); |
| |
|
| | module.exports = { |
| | loginSchema, |
| | registerSchema, |
| | }; |
| |
|