47 lines
1.8 KiB
TypeScript
47 lines
1.8 KiB
TypeScript
import { z } from 'zod'
|
|
|
|
const boolFromEnv = (v: string | undefined, fallback: boolean) => {
|
|
if (v === undefined || v === '') return fallback
|
|
return v === '1' || v.toLowerCase() === 'true'
|
|
}
|
|
|
|
export const configSchema = z.object({
|
|
databaseUrl: z.string().default('sqlite:data/app.db'),
|
|
jwtSecret: z.string().min(8),
|
|
jwtTtlHours: z.coerce.number().positive().default(1),
|
|
refreshTtlDays: z.coerce.number().positive().default(14),
|
|
issuer: z.string().url().default('https://auth.shnt.top'),
|
|
adminEmail: z.string().email().default('admin@shnt.top'),
|
|
adminPassword: z.string().default('admin'),
|
|
adminName: z.string().default('Admin'),
|
|
returnToAllowlist: z.string().default('.shnt.top,localhost,private'),
|
|
serverPort: z.coerce.number().int().positive().default(8080),
|
|
staticDir: z.string().optional(),
|
|
logLevel: z.string().default('info'),
|
|
isProd: z.boolean(),
|
|
})
|
|
|
|
export type AppConfig = z.infer<typeof configSchema>
|
|
|
|
export function loadConfig(env: NodeJS.ProcessEnv = process.env): AppConfig {
|
|
const isProd = env.NODE_ENV === 'production'
|
|
const jwtSecret = env.JWT_SECRET ?? (isProd ? '' : 'dev-secret-change-me')
|
|
|
|
return configSchema.parse({
|
|
databaseUrl: env.DATABASE_URL ?? 'sqlite:data/app.db',
|
|
jwtSecret,
|
|
jwtTtlHours: env.JWT_TTL_HOURS ?? 1,
|
|
refreshTtlDays: env.REFRESH_TTL_DAYS ?? 14,
|
|
issuer: env.ISSUER ?? 'https://auth.shnt.top',
|
|
adminEmail: env.ADMIN_EMAIL ?? 'admin@shnt.top',
|
|
adminPassword: env.ADMIN_PASSWORD ?? 'admin',
|
|
adminName: env.ADMIN_NAME ?? 'Admin',
|
|
returnToAllowlist:
|
|
env.RETURN_TO_ALLOWLIST ?? '.shnt.top,localhost,private',
|
|
serverPort: env.SERVER_PORT ?? 8080,
|
|
staticDir: env.STATIC_DIR || undefined,
|
|
logLevel: env.LOG_LEVEL ?? 'info',
|
|
isProd: boolFromEnv(env.NODE_ENV === 'production' ? 'true' : undefined, false) || isProd,
|
|
})
|
|
}
|