35 lines
2.9 KiB
JavaScript
35 lines
2.9 KiB
JavaScript
import { resolve } from 'node:path';
|
|||
|
|
import { createApp } from './app.mjs';
|
||
|
|
import { openStore } from './store.mjs';
|
||
|
|
import { startTelemetry } from './telemetry.mjs';
|
||
|
|
import { startSIEM } from './siem.mjs';
|
||
|
|
import {startAuditRetention} from './audit-retention.mjs';
|
||
|
|
const env=process.env;
|
||
|
|
const publicUrl=(env.PUBLIC_URL||'http://127.0.0.1:4310').replace(/\/$/,'');
|
||
|
|
const u=new URL(publicUrl);
|
||
|
|
if(u.protocol!=='https:' && !['127.0.0.1','localhost','[::1]'].includes(u.hostname))throw Error('Remote management requires HTTPS');
|
||
|
|
if(u.protocol==='http:'&&(!env.ADMIN_TOKEN||env.ADMIN_TOKEN.length<32))throw Error('Local development requires ADMIN_TOKEN of at least 32 characters');
|
||
|
|
if(u.protocol==='http:'&&env.HOST&&!['127.0.0.1','localhost','::1'].includes(env.HOST))throw Error('Development HTTP management must bind only to loopback');
|
||
|
|
if(u.protocol==='https:'&&(!env.OIDC_ISSUER||!env.OIDC_CLIENT_ID))throw Error('HTTPS management requires enterprise OIDC configuration; shared bootstrap administrator tokens are disabled');
|
||
|
|
const config={publicUrl,secure:u.protocol==='https:',adminToken:env.ADMIN_TOKEN,oidcIssuer:env.OIDC_ISSUER,oidcClientId:env.OIDC_CLIENT_ID,oidcClientSecret:env.OIDC_CLIENT_SECRET,oidcAdminGroup:env.OIDC_ADMIN_GROUP||'safetynet-admins',oidcGroupsClaim:env.OIDC_GROUPS_CLAIM||'groups',aiBaseUrl:env.AI_BASE_URL,aiKey:env.AI_API_KEY,aiModel:env.AI_MODEL,inspectorUrl:env.INSPECTOR_URL,inspectorToken:env.INSPECTOR_TOKEN};
|
||
|
|
const store=openStore(resolve(env.DATA_DIR||'data'));
|
||
|
|
config.evidenceKeyFile=env.EVIDENCE_KEY_FILE;
|
||
|
|
config.evidenceRetentionDays=Number(env.EVIDENCE_RETENTION_DAYS||30);
|
||
|
|
config.oidcDeviceGroup=env.OIDC_DEVICE_GROUP;
|
||
|
|
config.oidcOperatorGroup=env.OIDC_OPERATOR_GROUP;
|
||
|
|
config.oidcAuditorGroup=env.OIDC_AUDITOR_GROUP;
|
||
|
|
config.requireIndependentPolicyApproval=env.REQUIRE_INDEPENDENT_POLICY_APPROVAL==='true';
|
||
|
|
config.requirePQManagement=env.REQUIRE_PQ_MANAGEMENT_CHANNEL!=='false';
|
||
|
|
if(u.protocol==='https:'&&!config.requirePQManagement)throw Error('Remote deployment requires the protected management channel');
|
||
|
|
config.aiEndpointId=env.AI_ENDPOINT_ID||'default';
|
||
|
|
const telemetry=startTelemetry();
|
||
|
|
const siem=startSIEM(store,resolve(env.DATA_DIR||'data'));
|
||
|
|
config.siemStatus=()=>siem.status();
|
||
|
|
const retention=startAuditRetention(store,siem,{days:Number(env.AUDIT_RETENTION_DAYS||0)});
|
||
|
|
config.auditRetentionStatus=()=>retention.status();
|
||
|
|
const server=createApp(store,config).listen(Number(env.PORT||4310),env.HOST||'127.0.0.1',()=>console.log(`SafetyNet management: ${publicUrl}`));
|
||
|
|
const timer=setInterval(()=>{
|
||
|
|
for(const table of ['sessions','logins','tickets','enrollments'])store.db.prepare(`DELETE FROM ${table} WHERE expires<?`).run(Date.now());
|
||
|
|
},60000);timer.unref();
|
||
|
|
async function stop(){clearInterval(timer);retention.stop();siem.stop();server.close(async()=>{store.db.close();await telemetry?.shutdown();process.exit(0);});}
|
||
|
|
process.on('SIGINT',stop);process.on('SIGTERM',stop);
|