Files

29 lines
2.1 KiB
JavaScript

/**
* portal/config.mjs — 포털 실행 설정. 배포 때 정해지는 값만 환경 변수로 받고 나머지는 data/config.json(운영자 설정 화면)에서 읽는다.
* 비밀값(서비스 키·SSO 비밀·AriMail 키)은 config 가 아니라 vault 에 둔다.
*/
import { readFileSync, existsSync, writeFileSync, mkdirSync, renameSync } from 'node:fs';
import { join } from 'node:path';
export function loadConfig() {
const dataDir = process.env.ARIWEB_PORTAL_DATA || process.env.DATA_DIR || join(process.cwd(), 'data');
mkdirSync(dataDir, { recursive: true, mode: 0o700 });
const file = join(dataDir, 'config.json');
let values = {}; try { values = existsSync(file) ? JSON.parse(readFileSync(file, 'utf8')).values || {} : {}; } catch (_) { values = {}; }
const cfg = {
dataDir, file, port: Number(process.env.PORT || 8910), host: process.env.HOST || '127.0.0.1',
publicUrl: values.publicUrl || process.env.PUBLIC_URL || 'https://my.ariweb.net',
halUrl: values.halUrl || process.env.HAL_URL || 'https://hal.ariweb.net',
webmakerUrl: values.webmakerUrl || process.env.WEBMAKER_URL || 'https://webmaker.ariweb.net',
webmakerInternalUrl: values.webmakerInternalUrl || process.env.WEBMAKER_INTERNAL_URL || 'http://127.0.0.1:3080',
arimailUrl: values.arimailUrl || process.env.ARIMAIL_URL || 'https://webmail.ariweb.net',
arimailInternalUrl: values.arimailInternalUrl || process.env.ARIMAIL_INTERNAL_URL || 'http://127.0.0.1:8790',
mailFrom: values.mailFrom || process.env.MAIL_FROM || 'no-reply@ariweb.net',
operatorEmail: values.operatorEmail || process.env.OPERATOR_EMAIL || '',
values,
/** 설정 저장(운영자 화면). 비밀값은 거부. */
set(patch, by = 'ops') { for (const k of Object.keys(patch)) if (/key|secret|token|pass/i.test(k)) throw new Error(`비밀값(${k})은 설정 파일에 둘 수 없습니다 — 보관소를 쓰세요`); Object.assign(values, patch); const tmp = file + '.tmp'; writeFileSync(tmp, JSON.stringify({ version: 1, updatedAt: new Date().toISOString(), updatedBy: by, values }, null, 1), { mode: 0o600 }); renameSync(tmp, file); Object.assign(cfg, patch); },
};
return cfg;
}