Browse Source

update zod translations

pull/1661/head
Bernd Storath 6 months ago
parent
commit
840fe0dbd6
  1. 138
      src/i18n/locales/en.json
  2. 22
      src/server/database/repositories/client/types.ts
  3. 10
      src/server/database/repositories/general/types.ts
  4. 2
      src/server/database/repositories/hooks/types.ts
  5. 8
      src/server/database/repositories/interface/types.ts
  6. 4
      src/server/database/repositories/oneTimeLink/types.ts
  7. 2
      src/server/database/repositories/user/types.ts
  8. 4
      src/server/database/repositories/userConfig/types.ts
  9. 53
      src/server/utils/types.ts

138
src/i18n/locales/en.json

@ -38,79 +38,6 @@
"portPlaceholder": "443", "portPlaceholder": "443",
"migration": "Restore the backup" "migration": "Restore the backup"
}, },
"zod": {
"generic": {
"required": "{0} is required",
"validNumber": "{0} must be a valid number",
"validString": "{0} must be a valid string",
"validBoolean": "{0} must be a valid boolean",
"validStringArray": "{0} must be a valid array of strings",
"stringMin": "{0} must be at least {1} Character",
"numberMin": "{0} must be at least {1}"
},
"client": {
"id": "Client ID must be a valid number",
"name": "Name must be a valid string",
"nameMin": "Name must be at least 1 Character",
"expireDate": "expiredDate must be a valid string",
"expireDateMin": "expiredDate must be at least 1 Character",
"address4": "IPv4 Address must be a valid string",
"address4Min": "IPv4 Address must be a be at least 1 Character",
"address6": "IPv6 Address must be a valid string",
"address6Min": "IPv6 Address must be a be at least 1 Character",
"serverAllowedIps": "Allowed IPs must be a valid array of strings"
},
"user": {
"username": "Username",
"password": "Password",
"passwordUppercase": "Password must have at least 1 uppercase letter",
"passwordLowercase": "Password must have at least 1 lowercase letter",
"passwordNumber": "Password must have at least 1 number",
"passwordSpecial": "Password must have at least 1 special character",
"remember": "Remember",
"accept": "Accept",
"acceptTrue": "Accept Conditions to continue",
"name": "Name",
"email": "Email",
"emailInvalid": "Email must be a valid email",
"passwordMatch": "Passwords must match"
},
"userConfig": {
"host": "Host must be a valid string",
"hostMin": "Host must contain at least 1 character"
},
"general": {
"sessionTimeout": "Session Timeout must be a valid number"
},
"interface": {
"cidr": "CIDR must be a valid string",
"cidrMin": "CIDR must be at least 1 Character",
"device": "Device must be a valid string",
"deviceMin": "Device must be at least 1 Character"
},
"otl": {
"otl": "oneTimeLink must be a valid string",
"otlMin": "oneTimeLink must be at least 1 Character"
},
"stringMalformed": "String is malformed",
"body": "Body must be a valid object",
"hook": "Hook must be a valid string",
"mtu": "MTU must be a valid number",
"mtuMin": "MTU must be at least 1280",
"mtuMax": "MTU must be at most 9000",
"port": "Port must be a valid number",
"portMin": "Port must be at least 1",
"portMax": "Port must be at most 65535",
"persistentKeepalive": "Persistent Keepalive must be a valid number",
"persistentKeepaliveMin": "Persistent Keepalive must be at least 0",
"persistentKeepaliveMax": "Persistent Keepalive must be at most 65535",
"address": "IP Address must be a valid string",
"addressMin": "IP Address must be a be at least 1 Character",
"dns": "DNS must be a valid array of strings",
"dnsMin": "DNS must have at least 1 item",
"allowedIps": "Allowed IPs must be a valid array of strings",
"allowedIpsMin": "Allowed IPs must have at least 1 item"
},
"name": "Name", "name": "Name",
"username": "Username", "username": "Username",
"signIn": "Sign In", "signIn": "Sign In",
@ -157,16 +84,67 @@
"clear": "Clear", "clear": "Clear",
"login": "Log in error" "login": "Log in error"
}, },
"general": {
"sessionTimeout": "Session Timeout",
"metrics": "Metrics",
"prometheus": "Prometheus",
"json": "JSON"
},
"form": { "form": {
"actions": "Actions", "actions": "Actions",
"save": "Save", "save": "Save",
"revert": "Revert" "revert": "Revert"
}, },
"password": "Password" "password": "Password",
"zod": {
"generic": {
"required": "{0} is required",
"validNumber": "{0} must be a valid number",
"validString": "{0} must be a valid string",
"validBoolean": "{0} must be a valid boolean",
"validArray": "{0} must be a valid array",
"stringMin": "{0} must be at least {1} Character",
"numberMin": "{0} must be at least {1}"
},
"client": {
"id": "Client ID",
"name": "Name",
"expiresAt": "Expires At",
"address4": "IPv4 Address",
"address6": "IPv6 Address",
"serverAllowedIps": "Server Allowed IPs"
},
"user": {
"username": "Username",
"password": "Password",
"passwordUppercase": "Password must have at least 1 uppercase letter",
"passwordLowercase": "Password must have at least 1 lowercase letter",
"passwordNumber": "Password must have at least 1 number",
"passwordSpecial": "Password must have at least 1 special character",
"remember": "Remember",
"accept": "Accept",
"acceptTrue": "Accept Conditions to continue",
"name": "Name",
"email": "Email",
"emailInvalid": "Email must be a valid email",
"passwordMatch": "Passwords must match"
},
"userConfig": {
"host": "Host"
},
"general": {
"sessionTimeout": "Session Timeout",
"metricsEnabled": "Metrics",
"metricsPassword": "Metrics Password"
},
"interface": {
"cidr": "CIDR",
"device": "Device"
},
"otl": "One Time link",
"stringMalformed": "String is malformed",
"body": "Body must be a valid object",
"hook": "Hook",
"enabled": "Enabled",
"mtu": "MTU",
"port": "Port",
"persistentKeepalive": "Persistent Keepalive",
"address": "IP Address",
"dns": "DNS",
"allowedIps": "Allowed IPs"
}
} }

22
src/server/database/repositories/client/types.ts

@ -3,8 +3,6 @@ import z from 'zod';
import type { client } from './schema'; import type { client } from './schema';
export type ID = string;
export type ClientType = InferSelectModel<typeof client>; export type ClientType = InferSelectModel<typeof client>;
export type CreateClientType = Omit< export type CreateClientType = Omit<
@ -18,28 +16,28 @@ export type UpdateClientType = Omit<
>; >;
const name = z const name = z
.string({ message: '!zod.generic.validString:zod.client.name' }) .string({ message: t('zod.client.name') })
.min(1, '!zod.generic.stringMinOne:zod.client.nameMin') .min(1, t('zod.client.name'))
.pipe(safeStringRefine); .pipe(safeStringRefine);
const expiresAt = z const expiresAt = z
.string({ message: '!zod.generic.validString:zod.client.expireDate' }) .string({ message: t('zod.client.expiresAt') })
.min(1, '!zod.generic.stringMinOne:zod.client.expireDateMin') .min(1, t('zod.client.expiresAt'))
.pipe(safeStringRefine) .pipe(safeStringRefine)
.nullable(); .nullable();
const address4 = z const address4 = z
.string({ message: 'zod.client.address4' }) .string({ message: t('zod.client.address4') })
.min(1, { message: 'zod.client.address4Min' }) .min(1, { message: t('zod.client.address4') })
.pipe(safeStringRefine); .pipe(safeStringRefine);
const address6 = z const address6 = z
.string({ message: 'zod.client.address6' }) .string({ message: t('zod.client.address6') })
.min(1, { message: 'zod.client.address6Min' }) .min(1, { message: t('zod.client.address6') })
.pipe(safeStringRefine); .pipe(safeStringRefine);
const serverAllowedIps = z.array(AddressSchema, { const serverAllowedIps = z.array(AddressSchema, {
message: 'zod.serverAllowedIps', message: t('zod.client.serverAllowedIps'),
}); });
export const ClientCreateSchema = z.object({ export const ClientCreateSchema = z.object({
@ -65,7 +63,7 @@ export const ClientUpdateSchema = schemaForType<UpdateClientType>()(
); );
// TODO: investigate if coerce is bad // TODO: investigate if coerce is bad
const clientId = z.number({ message: 'zod.client.id', coerce: true }); const clientId = z.number({ message: t('zod.client.id'), coerce: true });
export const ClientGetSchema = z.object({ export const ClientGetSchema = z.object({
clientId: clientId, clientId: clientId,

10
src/server/database/repositories/general/types.ts

@ -4,11 +4,13 @@ import z from 'zod';
export type GeneralType = InferSelectModel<typeof general>; export type GeneralType = InferSelectModel<typeof general>;
const sessionTimeout = z.number({ message: 'zod.general.sessionTimeout' }); const sessionTimeout = z.number({ message: t('zod.general.sessionTimeout') });
const metricsEnabled = z.boolean({ message: 'zod.general.metricsEnabled' });
const metricsEnabled = z.boolean({ message: t('zod.general.metricsEnabled') });
const metricsPassword = z const metricsPassword = z
.string({ message: 'zod.general.metricsPassword' }) .string({ message: t('zod.general.metricsPassword') })
.min(1, { message: 'zod.general.metricsPasswordMin' }) .min(1, { message: t('zod.general.metricsPassword') })
// TODO: validate argon2 regex? // TODO: validate argon2 regex?
.nullable(); .nullable();

2
src/server/database/repositories/hooks/types.ts

@ -6,7 +6,7 @@ export type HooksType = InferSelectModel<typeof hooks>;
export type HooksUpdateType = Omit<HooksType, 'id' | 'createdAt' | 'updatedAt'>; export type HooksUpdateType = Omit<HooksType, 'id' | 'createdAt' | 'updatedAt'>;
const hook = z.string({ message: 'zod.hook' }).pipe(safeStringRefine); const hook = z.string({ message: t('zod.hook') }).pipe(safeStringRefine);
export const HooksUpdateSchema = schemaForType<HooksUpdateType>()( export const HooksUpdateSchema = schemaForType<HooksUpdateType>()(
z.object({ z.object({

8
src/server/database/repositories/interface/types.ts

@ -15,13 +15,13 @@ export type InterfaceUpdateType = Omit<
>; >;
const device = z const device = z
.string({ message: 'zod.interface.device' }) .string({ message: t('zod.interface.device') })
.min(1, 'zod.interface.deviceMin') .min(1, t('zod.interface.device'))
.pipe(safeStringRefine); .pipe(safeStringRefine);
const cidr = z const cidr = z
.string({ message: 'zod.interface.cidr' }) .string({ message: t('zod.interface.cidr') })
.min(1, { message: 'zod.interface.cidrMin' }) .min(1, { message: t('zod.interface.cidr') })
.pipe(safeStringRefine); .pipe(safeStringRefine);
export const InterfaceUpdateSchema = schemaForType<InterfaceUpdateType>()( export const InterfaceUpdateSchema = schemaForType<InterfaceUpdateType>()(

4
src/server/database/repositories/oneTimeLink/types.ts

@ -5,8 +5,8 @@ import { z } from 'zod';
export type OneTimeLinkType = InferSelectModel<typeof oneTimeLink>; export type OneTimeLinkType = InferSelectModel<typeof oneTimeLink>;
const oneTimeLinkType = z const oneTimeLinkType = z
.string({ message: 'zod.otl.otl' }) .string({ message: t('zod.otl.otl') })
.min(1, 'zod.otl.otlMin') .min(1, t('zod.otl.otl'))
.pipe(safeStringRefine); .pipe(safeStringRefine);
export const OneTimeLinkGetSchema = z.object( export const OneTimeLinkGetSchema = z.object(

2
src/server/database/repositories/user/types.ts

@ -4,8 +4,6 @@ import z from 'zod';
export type UserType = InferSelectModel<typeof user>; export type UserType = InferSelectModel<typeof user>;
const t = (v: string) => v;
const username = z const username = z
.string({ message: t('zod.user.username') }) .string({ message: t('zod.user.username') })
.min(8, t('zod.user.username')) .min(8, t('zod.user.username'))

4
src/server/database/repositories/userConfig/types.ts

@ -5,8 +5,8 @@ import z from 'zod';
export type UserConfigType = InferSelectModel<typeof userConfig>; export type UserConfigType = InferSelectModel<typeof userConfig>;
const host = z const host = z
.string({ message: 'zod.userConfig.host' }) .string({ message: t('zod.userConfig.host') })
.min(1, 'zod.userConfig.hostMin') .min(1, t('zod.userConfig.host'))
.pipe(safeStringRefine); .pipe(safeStringRefine);
export const UserConfigSetupSchema = z.object({ export const UserConfigSetupSchema = z.object({

53
src/server/utils/types.ts

@ -2,46 +2,53 @@ import type { ZodSchema } from 'zod';
import z from 'zod'; import z from 'zod';
import type { H3Event, EventHandlerRequest } from 'h3'; import type { H3Event, EventHandlerRequest } from 'h3';
export const objectMessage = 'zod.body'; /**
* return the string as is
*
* used for i18n ally
*/
export const t = (v: string) => v;
export const objectMessage = t('zod.body');
export const safeStringRefine = z export const safeStringRefine = z
.string() .string()
.refine( .refine(
(v) => v !== '__proto__' && v !== 'constructor' && v !== 'prototype', (v) => v !== '__proto__' && v !== 'constructor' && v !== 'prototype',
{ message: 'zod.stringMalformed' } { message: t('zod.stringMalformed') }
); );
// TODO: create custom getValidatedRouterParams and readValidatedBody wrapper // TODO: create custom getValidatedRouterParams and readValidatedBody wrapper
export const EnabledSchema = z.boolean({ message: 'zod.enabled' }); export const EnabledSchema = z.boolean({ message: t('zod.enabled') });
export const MtuSchema = z export const MtuSchema = z
.number({ message: 'zod.mtu' }) .number({ message: t('zod.mtu') })
.min(1280, { message: 'zod.mtuMin' }) .min(1280, { message: t('zod.mtu') })
.max(9000, { message: 'zod.mtuMax' }); .max(9000, { message: t('zod.mtu') });
export const PortSchema = z export const PortSchema = z
.number({ message: 'zod.port' }) .number({ message: t('zod.port') })
.min(1, { message: 'zod.portMin' }) .min(1, { message: t('zod.port') })
.max(65535, { message: 'zod.portMax' }); .max(65535, { message: t('zod.port') });
export const PersistentKeepaliveSchema = z export const PersistentKeepaliveSchema = z
.number({ message: 'zod.persistentKeepalive' }) .number({ message: t('zod.persistentKeepalive') })
.min(0, 'zod.persistentKeepaliveMin') .min(0, t('zod.persistentKeepalive'))
.max(65535, 'zod.persistentKeepaliveMax'); .max(65535, t('zod.persistentKeepalive'));
export const AddressSchema = z export const AddressSchema = z
.string({ message: 'zod.address' }) .string({ message: t('zod.address') })
.min(1, { message: 'zod.addressMin' }) .min(1, { message: t('zod.address') })
.pipe(safeStringRefine); .pipe(safeStringRefine);
export const DnsSchema = z export const DnsSchema = z
.array(AddressSchema, { message: 'zod.dns' }) .array(AddressSchema, { message: t('zod.dns') })
.min(1, 'zod.dnsMin'); .min(1, t('zod.dns'));
export const AllowedIpsSchema = z export const AllowedIpsSchema = z
.array(AddressSchema, { message: 'zod.allowedIps' }) .array(AddressSchema, { message: t('zod.allowedIps') })
.min(1, { message: 'zod.allowedIpsMin' }); .min(1, { message: t('zod.allowedIps') });
export const schemaForType = export const schemaForType =
<T>() => <T>() =>
@ -103,6 +110,16 @@ export function validateZod<T>(
t(v.message), t(v.message),
]); ]);
break; break;
case 'number':
newMessage = t('zod.generic.validNumber', [
t(v.message),
]);
break;
case 'array':
newMessage = t('zod.generic.validArray', [
t(v.message),
]);
break;
} }
} }
break; break;

Loading…
Cancel
Save