mirror of
https://github.com/versia-pub/server.git
synced 2026-03-13 05:49:16 +01:00
refactor(config): ♻️ Redo config structure from scratch, simplify validation code, improve checks, add support for loading sensitive data from paths
This commit is contained in:
parent
d4afd84019
commit
54fd81f076
118 changed files with 3892 additions and 5291 deletions
|
|
@ -1,8 +1,8 @@
|
|||
import { userAddressValidator } from "@/api.ts";
|
||||
import { z } from "@hono/zod-openapi";
|
||||
import type { Account as ApiAccount } from "@versia/client/types";
|
||||
import { config } from "~/packages/config-manager";
|
||||
import { zBoolean } from "~/packages/config-manager/config.type";
|
||||
import { zBoolean } from "~/classes/schemas/common.ts";
|
||||
import { config } from "~/config.ts";
|
||||
import { iso631 } from "./common.ts";
|
||||
import { CustomEmoji } from "./emoji.ts";
|
||||
import { Role } from "./versia.ts";
|
||||
|
|
@ -12,7 +12,7 @@ export const Field = z.object({
|
|||
.string()
|
||||
.trim()
|
||||
.min(1)
|
||||
.max(config.validation.max_field_name_size)
|
||||
.max(config.validation.accounts.max_field_name_characters)
|
||||
.openapi({
|
||||
description: "The key of a given field’s key-value pair.",
|
||||
example: "Freak level",
|
||||
|
|
@ -24,7 +24,7 @@ export const Field = z.object({
|
|||
.string()
|
||||
.trim()
|
||||
.min(1)
|
||||
.max(config.validation.max_field_value_size)
|
||||
.max(config.validation.accounts.max_field_value_characters)
|
||||
.openapi({
|
||||
description: "The value associated with the name key.",
|
||||
example: "<p>High</p>",
|
||||
|
|
@ -87,9 +87,12 @@ export const Source = z
|
|||
.string()
|
||||
.trim()
|
||||
.min(0)
|
||||
.max(config.validation.max_bio_size)
|
||||
.max(config.validation.accounts.max_bio_characters)
|
||||
.refine(
|
||||
(s) => !config.filters.bio.some((filter) => s.match(filter)),
|
||||
(s) =>
|
||||
!config.validation.filters.bio.some((filter) =>
|
||||
filter.test(s),
|
||||
),
|
||||
"Bio contains blocked words",
|
||||
)
|
||||
.openapi({
|
||||
|
|
@ -99,9 +102,12 @@ export const Source = z
|
|||
url: "https://docs.joinmastodon.org/entities/Account/#source-note",
|
||||
},
|
||||
}),
|
||||
fields: z.array(Field).max(config.validation.max_field_count).openapi({
|
||||
description: "Metadata about the account.",
|
||||
}),
|
||||
fields: z
|
||||
.array(Field)
|
||||
.max(config.validation.accounts.max_field_count)
|
||||
.openapi({
|
||||
description: "Metadata about the account.",
|
||||
}),
|
||||
})
|
||||
.openapi({
|
||||
description:
|
||||
|
|
@ -126,15 +132,25 @@ export const Account = z.object({
|
|||
.string()
|
||||
.min(3)
|
||||
.trim()
|
||||
.max(config.validation.max_username_size)
|
||||
.max(config.validation.accounts.max_username_characters)
|
||||
.regex(
|
||||
/^[a-z0-9_-]+$/,
|
||||
"Username can only contain letters, numbers, underscores and hyphens",
|
||||
)
|
||||
.refine(
|
||||
(s) => !config.filters.username.some((filter) => s.match(filter)),
|
||||
(s) =>
|
||||
!config.validation.filters.username.some((filter) =>
|
||||
filter.test(s),
|
||||
),
|
||||
"Username contains blocked words",
|
||||
)
|
||||
.refine(
|
||||
(s) =>
|
||||
!config.validation.accounts.disallowed_usernames.some((u) =>
|
||||
u.test(s),
|
||||
),
|
||||
"Username is disallowed",
|
||||
)
|
||||
.openapi({
|
||||
description: "The username of the account, not including domain.",
|
||||
example: "lexi",
|
||||
|
|
@ -169,10 +185,12 @@ export const Account = z.object({
|
|||
.string()
|
||||
.min(3)
|
||||
.trim()
|
||||
.max(config.validation.max_displayname_size)
|
||||
.max(config.validation.accounts.max_displayname_characters)
|
||||
.refine(
|
||||
(s) =>
|
||||
!config.filters.displayname.some((filter) => s.match(filter)),
|
||||
!config.validation.filters.displayname.some((filter) =>
|
||||
filter.test(s),
|
||||
),
|
||||
"Display name contains blocked words",
|
||||
)
|
||||
.openapi({
|
||||
|
|
@ -185,10 +203,11 @@ export const Account = z.object({
|
|||
note: z
|
||||
.string()
|
||||
.min(0)
|
||||
.max(config.validation.max_bio_size)
|
||||
.max(config.validation.accounts.max_bio_characters)
|
||||
.trim()
|
||||
.refine(
|
||||
(s) => !config.filters.bio.some((filter) => s.match(filter)),
|
||||
(s) =>
|
||||
!config.validation.filters.bio.some((filter) => filter.test(s)),
|
||||
"Bio contains blocked words",
|
||||
)
|
||||
.openapi({
|
||||
|
|
@ -255,7 +274,7 @@ export const Account = z.object({
|
|||
}),
|
||||
fields: z
|
||||
.array(Field)
|
||||
.max(config.validation.max_field_count)
|
||||
.max(config.validation.accounts.max_field_count)
|
||||
.openapi({
|
||||
description:
|
||||
"Additional metadata attached to a profile as name-value pairs.",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { z } from "@hono/zod-openapi";
|
||||
import { config } from "~/packages/config-manager/index.ts";
|
||||
import { config } from "~/config.ts";
|
||||
import { Id } from "./common.ts";
|
||||
|
||||
export const Attachment = z
|
||||
|
|
@ -54,7 +54,7 @@ export const Attachment = z
|
|||
description: z
|
||||
.string()
|
||||
.trim()
|
||||
.max(config.validation.max_media_description_size)
|
||||
.max(config.validation.media.max_description_characters)
|
||||
.nullable()
|
||||
.openapi({
|
||||
description:
|
||||
|
|
|
|||
|
|
@ -4,3 +4,8 @@ import ISO6391 from "iso-639-1";
|
|||
export const Id = z.string().uuid();
|
||||
|
||||
export const iso631 = z.enum(ISO6391.getAllCodes() as [string, ...string[]]);
|
||||
|
||||
export const zBoolean = z
|
||||
.string()
|
||||
.transform((v) => ["true", "1", "on"].includes(v.toLowerCase()))
|
||||
.or(z.boolean());
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { emojiValidator } from "@/api.ts";
|
||||
import { z } from "@hono/zod-openapi";
|
||||
import { zBoolean } from "~/packages/config-manager/config.type";
|
||||
import { config } from "~/packages/config-manager/index.ts";
|
||||
import { zBoolean } from "~/classes/schemas/common.ts";
|
||||
import { config } from "~/config.ts";
|
||||
import { Id } from "./common.ts";
|
||||
|
||||
export const CustomEmoji = z
|
||||
|
|
@ -15,7 +15,7 @@ export const CustomEmoji = z
|
|||
.string()
|
||||
.trim()
|
||||
.min(1)
|
||||
.max(config.validation.max_emoji_shortcode_size)
|
||||
.max(config.validation.emojis.max_shortcode_characters)
|
||||
.regex(
|
||||
emojiValidator,
|
||||
"Shortcode must only contain letters (any case), numbers, dashes or underscores.",
|
||||
|
|
@ -77,7 +77,7 @@ export const CustomEmoji = z
|
|||
/* Versia Server API extension */
|
||||
description: z
|
||||
.string()
|
||||
.max(config.validation.max_emoji_description_size)
|
||||
.max(config.validation.emojis.max_description_characters)
|
||||
.nullable()
|
||||
.openapi({
|
||||
description:
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import { z } from "@hono/zod-openapi";
|
||||
import { zBoolean } from "~/packages/config-manager/config.type.ts";
|
||||
import { Id } from "./common.ts";
|
||||
import { Id, zBoolean } from "./common.ts";
|
||||
|
||||
export const FilterStatus = z
|
||||
.object({
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { z } from "@hono/zod-openapi";
|
||||
import { config } from "~/packages/config-manager/index.ts";
|
||||
import { config } from "~/config.ts";
|
||||
import { Id } from "./common.ts";
|
||||
import { CustomEmoji } from "./emoji.ts";
|
||||
|
||||
|
|
@ -9,7 +9,7 @@ export const PollOption = z
|
|||
.string()
|
||||
.trim()
|
||||
.min(1)
|
||||
.max(config.validation.max_poll_option_size)
|
||||
.max(config.validation.polls.max_option_characters)
|
||||
.openapi({
|
||||
description: "The text value of the poll option.",
|
||||
example: "yes",
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
import { z } from "@hono/zod-openapi";
|
||||
import type { Status as ApiNote } from "@versia/client/types";
|
||||
import { zBoolean } from "~/packages/config-manager/config.type.ts";
|
||||
import { config } from "~/packages/config-manager/index.ts";
|
||||
import { config } from "~/config.ts";
|
||||
import { Account } from "./account.ts";
|
||||
import { Attachment } from "./attachment.ts";
|
||||
import { PreviewCard } from "./card.ts";
|
||||
import { Id, iso631 } from "./common.ts";
|
||||
import { Id, iso631, zBoolean } from "./common.ts";
|
||||
import { CustomEmoji } from "./emoji.ts";
|
||||
import { FilterResult } from "./filters.ts";
|
||||
import { Poll } from "./poll.ts";
|
||||
|
|
@ -58,12 +57,12 @@ export const StatusSource = z
|
|||
}),
|
||||
text: z
|
||||
.string()
|
||||
.max(config.validation.max_note_size)
|
||||
.max(config.validation.notes.max_characters)
|
||||
.trim()
|
||||
.refine(
|
||||
(s) =>
|
||||
!config.filters.note_content.some((filter) =>
|
||||
s.match(filter),
|
||||
!config.validation.filters.note_content.some((filter) =>
|
||||
filter.test(s),
|
||||
),
|
||||
"Status contains blocked words",
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { z } from "@hono/zod-openapi";
|
||||
import { RolePermission } from "@versia/client/types";
|
||||
import { config } from "~/packages/config-manager/index.ts";
|
||||
import { config } from "~/config.ts";
|
||||
import { Id } from "./common.ts";
|
||||
|
||||
/* Versia Server API extension */
|
||||
|
|
@ -56,7 +56,7 @@ export const NoteReaction = z
|
|||
name: z
|
||||
.string()
|
||||
.min(1)
|
||||
.max(config.validation.max_emoji_shortcode_size)
|
||||
.max(config.validation.emojis.max_shortcode_characters)
|
||||
.trim()
|
||||
.openapi({
|
||||
description: "Custom Emoji shortcode or Unicode emoji.",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue