From 3860812323ee7de7fc2624e175acbe8f650d6765 Mon Sep 17 00:00:00 2001 From: Jason Date: Sun, 8 Mar 2026 09:38:32 +0800 Subject: [PATCH] feat: add auth.disableSignUp config option - Added disableSignUp to authConfigSchema in config-schema.ts - Added authDisableSignUp to Config interface - Added parsing from PAPERCLIP_AUTH_DISABLE_SIGN_UP env or config file - Passed to better-auth emailAndPassword.disableSignUp When true, blocks new user registrations on public instances. Defaults to false (backward compatible). Fixes #241 --- packages/shared/src/config-schema.ts | 2 ++ server/src/auth/better-auth.ts | 1 + server/src/config.ts | 5 +++++ 3 files changed, 8 insertions(+) diff --git a/packages/shared/src/config-schema.ts b/packages/shared/src/config-schema.ts index 37903a90..258131bf 100644 --- a/packages/shared/src/config-schema.ts +++ b/packages/shared/src/config-schema.ts @@ -55,6 +55,7 @@ export const serverConfigSchema = z.object({ export const authConfigSchema = z.object({ baseUrlMode: z.enum(AUTH_BASE_URL_MODES).default("auto"), publicBaseUrl: z.string().url().optional(), + disableSignUp: z.boolean().default(false), }); export const storageLocalDiskConfigSchema = z.object({ @@ -103,6 +104,7 @@ export const paperclipConfigSchema = z server: serverConfigSchema, auth: authConfigSchema.default({ baseUrlMode: "auto", + disableSignUp: false, }), storage: storageConfigSchema.default({ provider: "local_disk", diff --git a/server/src/auth/better-auth.ts b/server/src/auth/better-auth.ts index 5c80fad7..7266752e 100644 --- a/server/src/auth/better-auth.ts +++ b/server/src/auth/better-auth.ts @@ -86,6 +86,7 @@ export function createBetterAuthInstance(db: Db, config: Config, trustedOrigins? emailAndPassword: { enabled: true, requireEmailVerification: false, + disableSignUp: config.authDisableSignUp ?? false, }, }; diff --git a/server/src/config.ts b/server/src/config.ts index 5aa0c31e..bcb84b47 100644 --- a/server/src/config.ts +++ b/server/src/config.ts @@ -37,6 +37,7 @@ export interface Config { allowedHostnames: string[]; authBaseUrlMode: AuthBaseUrlMode; authPublicBaseUrl: string | undefined; + authDisableSignUp: boolean; databaseMode: DatabaseMode; databaseUrl: string | undefined; embeddedPostgresDataDir: string; @@ -142,6 +143,9 @@ export function loadConfig(): Config { authBaseUrlModeFromEnv ?? fileConfig?.auth?.baseUrlMode ?? (authPublicBaseUrl ? "explicit" : "auto"); + const authDisableSignUp: boolean = + process.env.PAPERCLIP_AUTH_DISABLE_SIGN_UP === "true" || + fileConfig?.auth?.disableSignUp === true; const allowedHostnamesFromEnvRaw = process.env.PAPERCLIP_ALLOWED_HOSTNAMES; const allowedHostnamesFromEnv = allowedHostnamesFromEnvRaw ? allowedHostnamesFromEnvRaw @@ -203,6 +207,7 @@ export function loadConfig(): Config { allowedHostnames, authBaseUrlMode, authPublicBaseUrl, + authDisableSignUp, databaseMode: fileDatabaseMode, databaseUrl: process.env.DATABASE_URL ?? fileDbUrl, embeddedPostgresDataDir: resolveHomeAwarePath(