From eebfdf8559cfab06d238707e4506e0c699d98dcb Mon Sep 17 00:00:00 2001 From: Namekuji Date: Wed, 26 Apr 2023 20:06:18 +0000 Subject: [PATCH] feat: reserved usernames (#9917) This PR adds a feature to prevent users from creating a new account with a reserved username such as root, admin, system, proxy, info, etc... Reserved usernames can be configured via the config file. The administrator can create an account with a reserved username via the first setup screen or the control panel. The existing account of reserved usernames will not be affected. Co-authored-by: Namekuji Reviewed-on: https://codeberg.org/calckey/calckey/pulls/9917 Co-authored-by: Namekuji Co-committed-by: Namekuji --- .config/example.yml | 19 ++++++++++++++++--- packages/backend/src/config/types.ts | 2 ++ .../api/endpoints/username/available.ts | 7 ++++++- .../backend/src/server/api/private/signup.ts | 5 +++++ 4 files changed, 29 insertions(+), 4 deletions(-) diff --git a/.config/example.yml b/.config/example.yml index 3f0ce40311..8e881c1879 100644 --- a/.config/example.yml +++ b/.config/example.yml @@ -79,8 +79,8 @@ redis: # host: localhost # port: 9200 # ssl: false -# user: -# pass: +# user: +# pass: # ┌───────────────┐ #───┘ ID generation └─────────────────────────────────────────── @@ -109,6 +109,19 @@ id: 'aid' # Maximum lenght of an image caption or file comment (default 1500, max 8192) #maxCaptionLength: 1500 +# Reserved usernames that only the administrator can register with +reservedUsernames: + - root + - admin + - system + - test + - proxy + - relay + - mod + - moderator + - info + - information + # Whether disable HSTS #disableHsts: true @@ -211,4 +224,4 @@ id: 'aid' # !!!!!!!!!! # Seriously. Do NOT fill out the above settings if you're self-hosting. -# They're much better off being set from the control panel. +# They're much better off being set from the control panel. diff --git a/packages/backend/src/config/types.ts b/packages/backend/src/config/types.ts index a7cdc89cf2..4f367debe0 100644 --- a/packages/backend/src/config/types.ts +++ b/packages/backend/src/config/types.ts @@ -77,6 +77,8 @@ export type Source = { sha256CertFingerprints?: string[]; }; + reservedUsernames?: string[]; + // Managed hosting stuff maxUserSignups?: number; isManagedHosting?: boolean; diff --git a/packages/backend/src/server/api/endpoints/username/available.ts b/packages/backend/src/server/api/endpoints/username/available.ts index f5aa4ed1ea..6fa09ba369 100644 --- a/packages/backend/src/server/api/endpoints/username/available.ts +++ b/packages/backend/src/server/api/endpoints/username/available.ts @@ -1,5 +1,6 @@ import { IsNull } from "typeorm"; import { Users, UsedUsernames } from "@/models/index.js"; +import config from "@/config/index.js"; import define from "../../define.js"; export const meta = { @@ -40,7 +41,11 @@ export default define(meta, paramDef, async (ps) => { username: ps.username.toLowerCase(), }); + const reserved = config.reservedUsernames?.includes( + ps.username.toLowerCase(), + ); + return { - available: exist === 0 && exist2 === 0, + available: exist === 0 && exist2 === 0 && !reserved, }; }); diff --git a/packages/backend/src/server/api/private/signup.ts b/packages/backend/src/server/api/private/signup.ts index 754d86c3b8..d24a74c12a 100644 --- a/packages/backend/src/server/api/private/signup.ts +++ b/packages/backend/src/server/api/private/signup.ts @@ -44,6 +44,11 @@ export default async (ctx: Koa.Context) => { const invitationCode = body["invitationCode"]; const emailAddress = body["emailAddress"]; + if (config.reservedUsernames?.includes(username.toLowerCase())) { + ctx.status = 400; + return; + } + if (instance.emailRequiredForSignup) { if (emailAddress == null || typeof emailAddress !== "string") { ctx.status = 400;