Files
immich-folio/lib/env.ts
ralksta 9e52d7a0b8 feat: add visual admin panel with page builder and settings editor
- Add /admin route with password-protected visual page builder
- Page Builder: manage hero images, standalone albums, subpages, and sections
- Album Picker: browse all shared Immich albums with search and filtering
- Settings Editor: theme, grid, footer, legal, SEO configuration
- YAML service with atomic writes and automatic backups (content/.backups/)
- HMAC-signed admin sessions (24h expiry, HttpOnly cookies)
- API endpoints: /api/admin/{auth,gallery,settings,albums,reload}
- Enable with ADMIN_PASSWORD env var; disabled by default
- invalidateConfigCache() export for hot-reload after saves
2026-05-29 17:04:37 +02:00

61 lines
1.7 KiB
TypeScript

/**
* Environment variables parser.
* Parsed once at startup — all env access should go through this module.
*/
export interface Env {
IMMICH_API_URL: string;
IMMICH_API_KEY: string;
SITE_TITLE: string;
SITE_SUBTITLE: string;
CACHE_TTL: number;
RATE_LIMIT_RPM: number;
AUTH_SECRET?: string;
TRUSTED_PROXIES: string[];
WEBHOOK_SECRET?: string;
ADMIN_PASSWORD?: string;
}
function parseEnv(): Env {
const errors: string[] = [];
const urlRaw = process.env.IMMICH_API_URL;
let apiUrl = '';
if (urlRaw) {
try {
apiUrl = new URL(urlRaw).toString().replace(/\/+$/, '');
} catch {
console.warn('⚠️ IMMICH_API_URL is invalid, falling back to empty string for setup.');
}
}
const apiKey = process.env.IMMICH_API_KEY || '';
const cacheTtlStr = process.env.CACHE_TTL;
const cacheTtl =
cacheTtlStr && !isNaN(parseInt(cacheTtlStr, 10)) ? parseInt(cacheTtlStr, 10) : 300;
const rateLimitStr = process.env.RATE_LIMIT_RPM;
const rateLimit =
rateLimitStr && !isNaN(parseInt(rateLimitStr, 10)) ? parseInt(rateLimitStr, 10) : 1500;
return {
IMMICH_API_URL: apiUrl,
IMMICH_API_KEY: apiKey as string,
SITE_TITLE: process.env.SITE_TITLE || 'Gallery',
SITE_SUBTITLE: process.env.SITE_SUBTITLE || '',
CACHE_TTL: Math.max(0, cacheTtl),
RATE_LIMIT_RPM: Math.max(1, rateLimit),
AUTH_SECRET: process.env.AUTH_SECRET,
TRUSTED_PROXIES: (process.env.TRUSTED_PROXIES || '')
.split(',')
.map((ip) => ip.trim())
.filter((ip) => ip !== ''),
WEBHOOK_SECRET: process.env.WEBHOOK_SECRET || undefined,
ADMIN_PASSWORD: process.env.ADMIN_PASSWORD || undefined,
};
}
/** Validated, typed environment variables. */
export const env = parseEnv();