Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Overhaul config system #34

Merged
merged 5 commits into from
Feb 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
494 changes: 347 additions & 147 deletions .github/config.workflow.toml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion api/api/auth/login/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { afterAll, describe, expect, test } from "bun:test";
import { randomString } from "@/math";
import { Application } from "@versia/kit/db";
import { config } from "~/packages/config-manager";
import { config } from "~/config.ts";
import { fakeRequest, getTestUsers } from "~/tests/utils";

const { users, deleteUsers, passwords } = await getTestUsers(1);
Expand Down
2 changes: 1 addition & 1 deletion api/api/auth/login/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import type { Context } from "hono";
import { setCookie } from "hono/cookie";
import { SignJWT } from "jose";
import { ApiError } from "~/classes/errors/api-error";
import { config } from "~/packages/config-manager";
import { config } from "~/config.ts";

const schemas = {
form: z.object({
Expand Down
2 changes: 1 addition & 1 deletion api/api/auth/redirect/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { createRoute, z } from "@hono/zod-openapi";
import { db } from "@versia/kit/db";
import { Applications, Tokens } from "@versia/kit/tables";
import { and, eq } from "drizzle-orm";
import { config } from "~/packages/config-manager";
import { config } from "~/config.ts";

const schemas = {
query: z.object({
Expand Down
2 changes: 1 addition & 1 deletion api/api/auth/reset/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { afterAll, describe, expect, test } from "bun:test";
import { randomString } from "@/math";
import { Application } from "@versia/kit/db";
import { config } from "~/packages/config-manager";
import { config } from "~/config.ts";
import { fakeRequest, getTestUsers } from "~/tests/utils";

const { users, deleteUsers, passwords } = await getTestUsers(1);
Expand Down
2 changes: 1 addition & 1 deletion api/api/auth/reset/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { User } from "@versia/kit/db";
import { Users } from "@versia/kit/tables";
import { eq } from "drizzle-orm";
import type { Context } from "hono";
import { config } from "~/packages/config-manager";
import { config } from "~/config.ts";

const schemas = {
form: z.object({
Expand Down
2 changes: 1 addition & 1 deletion api/api/v1/accounts/:id/statuses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import { Timeline } from "@versia/kit/db";
import { Notes, RolePermissions } from "@versia/kit/tables";
import { and, eq, gt, gte, inArray, isNull, lt, or, sql } from "drizzle-orm";
import { Account as AccountSchema } from "~/classes/schemas/account";
import { zBoolean } from "~/classes/schemas/common.ts";
import { Status as StatusSchema } from "~/classes/schemas/status";
import { zBoolean } from "~/packages/config-manager/config.type";

const route = createRoute({
method: "get",
Expand Down
33 changes: 23 additions & 10 deletions api/api/v1/accounts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import { Users } from "@versia/kit/tables";
import { and, eq, isNull } from "drizzle-orm";
import ISO6391 from "iso-639-1";
import { ApiError } from "~/classes/errors/api-error";
import { config } from "~/packages/config-manager";
import { zBoolean } from "~/packages/config-manager/config.type";
import { zBoolean } from "~/classes/schemas/common";
import { config } from "~/config.ts";

const schema = z.object({
username: z.string().openapi({
Expand Down Expand Up @@ -157,7 +157,7 @@ export default apiRoute((app) =>
const { username, email, password, agreement, locale } =
context.req.valid("json");

if (!config.signups.registration) {
if (!config.registration.allow) {
throw new ApiError(422, "Registration is disabled");
}

Expand Down Expand Up @@ -217,18 +217,25 @@ export default apiRoute((app) =>
}

// Check if username doesnt match filters
if (config.filters.username.some((filter) => username?.match(filter))) {
if (
config.validation.filters.username.some((filter) =>
filter.test(username),
)
) {
errors.details.username.push({
error: "ERR_INVALID",
description: "contains blocked words",
});
}

// Check if username is too long
if ((username?.length ?? 0) > config.validation.max_username_size) {
if (
(username?.length ?? 0) >
config.validation.accounts.max_username_characters
) {
errors.details.username.push({
error: "ERR_TOO_LONG",
description: `is too long (maximum is ${config.validation.max_username_size} characters)`,
description: `is too long (maximum is ${config.validation.accounts.max_username_characters} characters)`,
});
}

Expand All @@ -241,7 +248,11 @@ export default apiRoute((app) =>
}

// Check if username is reserved
if (config.validation.username_blacklist.includes(username ?? "")) {
if (
config.validation.accounts.disallowed_usernames.some((filter) =>
filter.test(username),
)
) {
errors.details.username.push({
error: "ERR_RESERVED",
description: "is reserved",
Expand Down Expand Up @@ -274,9 +285,11 @@ export default apiRoute((app) =>

// Check if email is blocked
if (
config.validation.email_blacklist.includes(email) ||
(config.validation.blacklist_tempmail &&
tempmailDomains.domains.includes((email ?? "").split("@")[1]))
config.validation.emails.disallowed_domains.some((f) =>
f.test(email.split("@")[1]),
) ||
(config.validation.emails.disallow_tempmail &&
tempmailDomains.domains.includes(email.split("@")[1]))
) {
errors.details.email.push({
error: "ERR_BLOCKED",
Expand Down
2 changes: 1 addition & 1 deletion api/api/v1/accounts/lookup/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { and, eq, isNull } from "drizzle-orm";
import { ApiError } from "~/classes/errors/api-error";
import { Account } from "~/classes/schemas/account";
import { Account as AccountSchema } from "~/classes/schemas/account";
import { config } from "~/packages/config-manager";
import { config } from "~/config.ts";

const route = createRoute({
method: "get",
Expand Down
2 changes: 1 addition & 1 deletion api/api/v1/accounts/relationships/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { createRoute, z } from "@hono/zod-openapi";
import { Relationship } from "@versia/kit/db";
import { RolePermissions } from "@versia/kit/tables";
import { Account as AccountSchema } from "~/classes/schemas/account";
import { zBoolean } from "~/classes/schemas/common.ts";
import { Relationship as RelationshipSchema } from "~/classes/schemas/relationship";
import { zBoolean } from "~/packages/config-manager/config.type";

const route = createRoute({
method: "get",
Expand Down
2 changes: 1 addition & 1 deletion api/api/v1/accounts/search/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { eq, ilike, not, or, sql } from "drizzle-orm";
import stringComparison from "string-comparison";
import { ApiError } from "~/classes/errors/api-error";
import { Account as AccountSchema } from "~/classes/schemas/account";
import { zBoolean } from "~/packages/config-manager/config.type";
import { zBoolean } from "~/classes/schemas/common.ts";

export const route = createRoute({
method: "get",
Expand Down
2 changes: 1 addition & 1 deletion api/api/v1/accounts/update_credentials/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { afterAll, describe, expect, test } from "bun:test";
import type { Account as APIAccount } from "@versia/client/types";
import { config } from "~/packages/config-manager/index.ts";
import { config } from "~/config.ts";
import { fakeRequest, getTestUsers } from "~/tests/utils";

const { tokens, deleteUsers } = await getTestUsers(1);
Expand Down
20 changes: 11 additions & 9 deletions api/api/v1/accounts/update_credentials/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import { and, eq, isNull } from "drizzle-orm";
import { ApiError } from "~/classes/errors/api-error";
import { contentToHtml } from "~/classes/functions/status";
import { Account as AccountSchema } from "~/classes/schemas/account";
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";

const route = createRoute({
method: "patch",
Expand Down Expand Up @@ -62,9 +62,9 @@ const route = createRoute({
.refine(
(v) =>
v.size <=
config.validation
.max_avatar_size,
`Avatar must be less than ${config.validation.max_avatar_size} bytes`,
config.validation.accounts
.max_avatar_bytes,
`Avatar must be less than ${config.validation.accounts.max_avatar_bytes} bytes`,
)
.openapi({
description:
Expand All @@ -84,9 +84,9 @@ const route = createRoute({
.refine(
(v) =>
v.size <=
config.validation
.max_header_size,
`Header must be less than ${config.validation.max_header_size} bytes`,
config.validation.accounts
.max_header_bytes,
`Header must be less than ${config.validation.accounts.max_header_bytes} bytes`,
)
.openapi({
description:
Expand Down Expand Up @@ -144,7 +144,9 @@ const route = createRoute({
.element.shape.value,
}),
)
.max(config.validation.max_field_count),
.max(
config.validation.accounts.max_field_count,
),
})
.partial(),
},
Expand Down
4 changes: 2 additions & 2 deletions api/api/v1/challenges/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { apiRoute, auth } from "@/api";
import { generateChallenge } from "@/challenges";
import { createRoute, z } from "@hono/zod-openapi";
import { ApiError } from "~/classes/errors/api-error";
import { config } from "~/packages/config-manager";
import { config } from "~/config.ts";
import { ErrorSchema } from "~/types/api";

const route = createRoute({
Expand Down Expand Up @@ -45,7 +45,7 @@ const route = createRoute({

export default apiRoute((app) =>
app.openapi(route, async (context) => {
if (!config.validation.challenges.enabled) {
if (!config.validation.challenges) {
throw new ApiError(400, "Challenges are disabled in config");
}

Expand Down
6 changes: 3 additions & 3 deletions api/api/v1/emojis/:id/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { createRoute, z } from "@hono/zod-openapi";
import { RolePermissions } from "@versia/kit/tables";
import { ApiError } from "~/classes/errors/api-error";
import { CustomEmoji as CustomEmojiSchema } from "~/classes/schemas/emoji";
import { config } from "~/packages/config-manager";
import { config } from "~/config.ts";
import { ErrorSchema } from "~/types/api";

const schema = z
Expand All @@ -31,8 +31,8 @@ const schema = z
"Emoji image encoded using multipart/form-data",
})
.refine(
(v) => v.size <= config.validation.max_emoji_size,
`Emoji must be less than ${config.validation.max_emoji_size} bytes`,
(v) => v.size <= config.validation.emojis.max_bytes,
`Emoji must be less than ${config.validation.emojis.max_bytes} bytes`,
),
),
category: CustomEmojiSchema.shape.category.optional(),
Expand Down
6 changes: 3 additions & 3 deletions api/api/v1/emojis/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { Emojis, RolePermissions } from "@versia/kit/tables";
import { and, eq, isNull, or } from "drizzle-orm";
import { ApiError } from "~/classes/errors/api-error";
import { CustomEmoji as CustomEmojiSchema } from "~/classes/schemas/emoji";
import { config } from "~/packages/config-manager";
import { config } from "~/config.ts";

const schema = z.object({
shortcode: CustomEmojiSchema.shape.shortcode,
Expand All @@ -25,8 +25,8 @@ const schema = z.object({
"Emoji image encoded using multipart/form-data",
})
.refine(
(v) => v.size <= config.validation.max_emoji_size,
`Emoji must be less than ${config.validation.max_emoji_size} bytes`,
(v) => v.size <= config.validation.emojis.max_bytes,
`Emoji must be less than ${config.validation.emojis.max_bytes} bytes`,
),
),
category: CustomEmojiSchema.shape.category.optional(),
Expand Down
2 changes: 1 addition & 1 deletion api/api/v1/frontend/config/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { apiRoute } from "@/api";
import { createRoute, z } from "@hono/zod-openapi";
import { config } from "~/packages/config-manager";
import { config } from "~/config.ts";

const route = createRoute({
method: "get",
Expand Down
2 changes: 1 addition & 1 deletion api/api/v1/instance/extended_description.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ describe("/api/v1/instance/extended_description", () => {

const json = await response.json();
expect(json).toEqual({
updated_at: new Date(1970, 0, 0).toISOString(),
updated_at: new Date(0).toISOString(),
content:
'<p>This is a <a href="https://versia.pub">Versia</a> server with the default extended description.</p>\n',
});
Expand Down
15 changes: 9 additions & 6 deletions api/api/v1/instance/extended_description.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { apiRoute } from "@/api";
import { renderMarkdownInPath } from "@/markdown";
import { createRoute } from "@hono/zod-openapi";
import { markdownParse } from "~/classes/functions/status";
import { ExtendedDescription as ExtendedDescriptionSchema } from "~/classes/schemas/extended-description";
import { config } from "~/packages/config-manager";
import { config } from "~/config.ts";

const route = createRoute({
method: "get",
Expand All @@ -27,14 +27,17 @@ const route = createRoute({

export default apiRoute((app) =>
app.openapi(route, async (context) => {
const { content, lastModified } = await renderMarkdownInPath(
config.instance.extended_description_path ?? "",
"This is a [Versia](https://versia.pub) server with the default extended description.",
const content = await markdownParse(
config.instance.extended_description_path?.content ??
"This is a [Versia](https://versia.pub) server with the default extended description.",
);

return context.json(
{
updated_at: lastModified.toISOString(),
updated_at: new Date(
config.instance.extended_description_path?.file
.lastModified ?? 0,
).toISOString(),
content,
},
200,
Expand Down
Loading
Loading