SPB Git

spb/drive Public

SPB Drive — self-hosted personal cloud drive (files, previews, sharing) on the MacLustr cluster.

JavaScript 82.7% CSS 10.6% Nunjucks 3.6% Shell 1.8% SQL 1.3%
2.9 KB · 76 lines javascript
Raw Blame History
1/**2 * ─────────────────────────────────────────────3 *  SPB Drive — Personal Cloud Drive4 * ─────────────────────────────────────────────5 *  Author  : Simon-Pierre Boucher6 *  Contact : contact@spboucher.ai7 *  File    : src/config.mjs8 *  Purpose : zod-validated environment configuration + data-dir layout9 *  License : MIT © Simon-Pierre Boucher10 * ─────────────────────────────────────────────11 */1213import { mkdirSync } from 'node:fs';14import path from 'node:path';15import { z } from 'zod';1617const schema = z.object({18  SPBDRIVE_DATA_DIR: z.string().default('/srv/drive'),19  SPBDRIVE_PORT: z.coerce.number().int().min(1).max(65535).default(7430),20  SPBDRIVE_HOST: z.string().default('127.0.0.1'),21  SPBDRIVE_PUBLIC_URL: z.string().url().default('https://drive.spboucher.ai'),22  SPBDRIVE_LOG_LEVEL: z.enum(['silent', 'fatal', 'error', 'warn', 'info', 'debug', 'trace']).default('info'),23  SPBDRIVE_TRUST_PROXY: z24    .string()25    .default('true')26    .transform((v) => v === 'true' || v === '1'),27  /** Read once at first boot to seed the login password; ignored afterwards. */28  SPBDRIVE_BOOTSTRAP_PASSWORD: z.string().optional(),29});3031const env = schema.parse(process.env);32const dataDir = path.resolve(env.SPBDRIVE_DATA_DIR);3334/** Resolved, validated application configuration (frozen). */35export const config = Object.freeze({36  port: env.SPBDRIVE_PORT,37  host: env.SPBDRIVE_HOST,38  publicUrl: env.SPBDRIVE_PUBLIC_URL.replace(/\/$/, ''),39  logLevel: env.SPBDRIVE_LOG_LEVEL,40  trustProxy: env.SPBDRIVE_TRUST_PROXY,41  bootstrapPassword: env.SPBDRIVE_BOOTSTRAP_PASSWORD ?? null,4243  dataDir,44  filesDir: path.join(dataDir, 'files'),45  dbDir: path.join(dataDir, 'db'),46  cacheDir: path.join(dataDir, 'cache'),47  uploadsDir: path.join(dataDir, 'cache', 'uploads'),48  logsDir: path.join(dataDir, 'logs'),49  dbFile: path.join(dataDir, 'db', 'drive.sqlite'),50  authFile: path.join(dataDir, 'auth.json'),51  keysFile: path.join(dataDir, 'keys.json'),5253  chunkSize: 8 * 1024 * 1024,54  sessionTtlMs: 24 * 60 * 60 * 1000,55  rememberTtlMs: 30 * 24 * 60 * 60 * 1000,56  trashRetentionDays: 30,57  loginMaxFailures: 5,58  loginLockoutMs: 15 * 60 * 1000,59});6061/** Create every runtime directory (idempotent, restrictive perms). */62export function ensureDataDirs() {63  for (const dir of [64    config.dataDir, config.filesDir, config.dbDir, config.cacheDir,65    config.uploadsDir, config.logsDir,66    path.join(config.cacheDir, 'thumbs'),67    path.join(config.cacheDir, 'transcode'),68    path.join(config.cacheDir, 'office'),69    path.join(config.cacheDir, 'peaks'),70    path.join(config.cacheDir, 'text'),71    path.join(config.cacheDir, 'tmp'),72  ]) {73    mkdirSync(dir, { recursive: true, mode: 0o700 });74  }75}76