diff --git a/.config/example.yml b/.config/example.yml index 7817578d9a..9d071c1cc3 100644 --- a/.config/example.yml +++ b/.config/example.yml @@ -144,3 +144,6 @@ id: 'aid' # Upload or download file size limits (bytes) #maxFileSize: 262144000 + +# Maxium users, should be used for hosting management services +#maxUserSignups: 100 diff --git a/packages/backend/src/config/load.ts b/packages/backend/src/config/load.ts index 8e73059855..c479ccc40a 100644 --- a/packages/backend/src/config/load.ts +++ b/packages/backend/src/config/load.ts @@ -6,7 +6,7 @@ import * as fs from 'node:fs'; import { fileURLToPath } from 'node:url'; import { dirname } from 'node:path'; import * as yaml from 'js-yaml'; -import { Source, Mixin } from './types.js'; +import type { Source, Mixin } from './types.js'; const _filename = fileURLToPath(import.meta.url); const _dirname = dirname(_filename); diff --git a/packages/backend/src/config/types.ts b/packages/backend/src/config/types.ts index 2f182e1aeb..ccd7b13323 100644 --- a/packages/backend/src/config/types.ts +++ b/packages/backend/src/config/types.ts @@ -63,6 +63,8 @@ export type Source = { mediaProxy?: string; proxyRemoteFiles?: boolean; + + maxUserSignups?: number; }; /** diff --git a/packages/backend/src/server/api/common/signup.ts b/packages/backend/src/server/api/common/signup.ts index abc142472a..22a1f25e35 100644 --- a/packages/backend/src/server/api/common/signup.ts +++ b/packages/backend/src/server/api/common/signup.ts @@ -11,6 +11,7 @@ import { UserKeypair } from '@/models/entities/user-keypair.js'; import { usersChart } from '@/services/chart/index.js'; import { UsedUsername } from '@/models/entities/used-username.js'; import { db } from '@/db/postgre.js'; +import config from '@/config/index.js'; export async function signup(opts: { username: User['username']; @@ -21,6 +22,14 @@ export async function signup(opts: { const { username, password, passwordHash, host } = opts; let hash = passwordHash; + const userCount = await Users.countBy({ + host: IsNull(), + }); + + if (config.maxUserSignups != null && config.maxUserSignups > userCount) { + throw new Error('MAX_USERS_REACHED'); + } + // Validate username if (!Users.validateLocalUsername(username)) { throw new Error('INVALID_USERNAME');