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
This commit is contained in:
Jason
2026-03-08 09:38:32 +08:00
parent 416177ae4c
commit 3860812323
3 changed files with 8 additions and 0 deletions

View File

@@ -55,6 +55,7 @@ export const serverConfigSchema = z.object({
export const authConfigSchema = z.object({ export const authConfigSchema = z.object({
baseUrlMode: z.enum(AUTH_BASE_URL_MODES).default("auto"), baseUrlMode: z.enum(AUTH_BASE_URL_MODES).default("auto"),
publicBaseUrl: z.string().url().optional(), publicBaseUrl: z.string().url().optional(),
disableSignUp: z.boolean().default(false),
}); });
export const storageLocalDiskConfigSchema = z.object({ export const storageLocalDiskConfigSchema = z.object({
@@ -103,6 +104,7 @@ export const paperclipConfigSchema = z
server: serverConfigSchema, server: serverConfigSchema,
auth: authConfigSchema.default({ auth: authConfigSchema.default({
baseUrlMode: "auto", baseUrlMode: "auto",
disableSignUp: false,
}), }),
storage: storageConfigSchema.default({ storage: storageConfigSchema.default({
provider: "local_disk", provider: "local_disk",

View File

@@ -86,6 +86,7 @@ export function createBetterAuthInstance(db: Db, config: Config, trustedOrigins?
emailAndPassword: { emailAndPassword: {
enabled: true, enabled: true,
requireEmailVerification: false, requireEmailVerification: false,
disableSignUp: config.authDisableSignUp ?? false,
}, },
}; };

View File

@@ -37,6 +37,7 @@ export interface Config {
allowedHostnames: string[]; allowedHostnames: string[];
authBaseUrlMode: AuthBaseUrlMode; authBaseUrlMode: AuthBaseUrlMode;
authPublicBaseUrl: string | undefined; authPublicBaseUrl: string | undefined;
authDisableSignUp: boolean;
databaseMode: DatabaseMode; databaseMode: DatabaseMode;
databaseUrl: string | undefined; databaseUrl: string | undefined;
embeddedPostgresDataDir: string; embeddedPostgresDataDir: string;
@@ -142,6 +143,9 @@ export function loadConfig(): Config {
authBaseUrlModeFromEnv ?? authBaseUrlModeFromEnv ??
fileConfig?.auth?.baseUrlMode ?? fileConfig?.auth?.baseUrlMode ??
(authPublicBaseUrl ? "explicit" : "auto"); (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 allowedHostnamesFromEnvRaw = process.env.PAPERCLIP_ALLOWED_HOSTNAMES;
const allowedHostnamesFromEnv = allowedHostnamesFromEnvRaw const allowedHostnamesFromEnv = allowedHostnamesFromEnvRaw
? allowedHostnamesFromEnvRaw ? allowedHostnamesFromEnvRaw
@@ -203,6 +207,7 @@ export function loadConfig(): Config {
allowedHostnames, allowedHostnames,
authBaseUrlMode, authBaseUrlMode,
authPublicBaseUrl, authPublicBaseUrl,
authDisableSignUp,
databaseMode: fileDatabaseMode, databaseMode: fileDatabaseMode,
databaseUrl: process.env.DATABASE_URL ?? fileDbUrl, databaseUrl: process.env.DATABASE_URL ?? fileDbUrl,
embeddedPostgresDataDir: resolveHomeAwarePath( embeddedPostgresDataDir: resolveHomeAwarePath(