feat: first-run config.json auto-generation on blank PVC
- loadConfig(): if config.json missing, create data/ dir, write default config with random sessionSecret and empty passwordHash, log instructions - loadData(): throw clear error if units.json missing instead of crashing opaquely - deployment.yaml: remove envFrom secretRef (SESSION_SECRET/PASSWORD_HASH not read from env — config.json on PVC is the source of truth)
This commit is contained in:
@@ -31,9 +31,6 @@ spec:
|
|||||||
value: "https://humorunits.com"
|
value: "https://humorunits.com"
|
||||||
- name: ALLOWED_ORIGINS
|
- name: ALLOWED_ORIGINS
|
||||||
value: "https://humorunits.com,https://www.humorunits.com,https://dickloads.com,https://www.dickloads.com"
|
value: "https://humorunits.com,https://www.humorunits.com,https://dickloads.com,https://www.dickloads.com"
|
||||||
envFrom:
|
|
||||||
- secretRef:
|
|
||||||
name: humor-units-secrets # SESSION_SECRET, PASSWORD_HASH
|
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name: data
|
- name: data
|
||||||
mountPath: /app/data
|
mountPath: /app/data
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { readFileSync, writeFileSync, renameSync } from 'fs';
|
import { readFileSync, writeFileSync, renameSync, existsSync, mkdirSync } from 'fs';
|
||||||
|
import { randomBytes } from 'crypto';
|
||||||
import { resolve } from 'path';
|
import { resolve } from 'path';
|
||||||
import type { UnitsData } from '$lib/types';
|
import type { UnitsData } from '$lib/types';
|
||||||
|
|
||||||
@@ -25,6 +26,9 @@ export interface AppConfig {
|
|||||||
|
|
||||||
/** Read units.json synchronously. Returns parsed UnitsData. */
|
/** Read units.json synchronously. Returns parsed UnitsData. */
|
||||||
export function loadData(): UnitsData {
|
export function loadData(): UnitsData {
|
||||||
|
if (!existsSync(UNITS_PATH)) {
|
||||||
|
throw new Error(`[humor-units] units.json not found at ${UNITS_PATH}. Mount it via a ConfigMap or PVC.`);
|
||||||
|
}
|
||||||
const raw = readFileSync(UNITS_PATH, 'utf8');
|
const raw = readFileSync(UNITS_PATH, 'utf8');
|
||||||
return JSON.parse(raw) as UnitsData;
|
return JSON.parse(raw) as UnitsData;
|
||||||
}
|
}
|
||||||
@@ -36,8 +40,20 @@ export function saveData(data: UnitsData): void {
|
|||||||
renameSync(tmp, UNITS_PATH);
|
renameSync(tmp, UNITS_PATH);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Read config.json synchronously. */
|
/** Read config.json synchronously. Creates a default config on first run if missing. */
|
||||||
export function loadConfig(): AppConfig {
|
export function loadConfig(): AppConfig {
|
||||||
|
if (!existsSync(CONFIG_PATH)) {
|
||||||
|
mkdirSync(DATA_DIR, { recursive: true });
|
||||||
|
const defaultConfig: AppConfig = {
|
||||||
|
adminPath: 'admin',
|
||||||
|
passwordHash: '',
|
||||||
|
sessionSecret: randomBytes(32).toString('hex'),
|
||||||
|
};
|
||||||
|
writeFileSync(CONFIG_PATH, JSON.stringify(defaultConfig, null, 2) + '\n', 'utf8');
|
||||||
|
console.log('[humor-units] First run: generated default config.json with random sessionSecret.');
|
||||||
|
console.log('[humor-units] Set an admin password via: node scripts/set-password.js <password>');
|
||||||
|
return defaultConfig;
|
||||||
|
}
|
||||||
const raw = readFileSync(CONFIG_PATH, 'utf8');
|
const raw = readFileSync(CONFIG_PATH, 'utf8');
|
||||||
return JSON.parse(raw) as AppConfig;
|
return JSON.parse(raw) as AppConfig;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user