'use strict'; const http = require('node:http'); const crypto = require('node:crypto'); const { createStore } = require('./store'); const { createHandler } = require('./routes'); const { ensureDirs, FILES_DIR } = require('./covers'); const auth = require('./auth'); const sync = require('./sync'); const { json } = require('./http'); const PORT = Number(process.env.PORT || 3000); async function ensureAdminPassword(store) { if (await store.getSetting('admin_password_hash')) return; const initial = crypto.randomBytes(18).toString('base64url'); await store.setSetting('admin_password_hash', auth.hashPassword(initial)); // Printed in reverse order so it reads top-to-bottom in newest-first log viewers. console.log(''); console.log('============================================================'); console.log('This password is printed only once for this database volume.'); console.log('Open the web UI, log in with this password, then change it in Settings.'); console.log(initial); console.log('Bangumi Vault initial admin password:'); console.log('============================================================'); console.log(''); } // Session cookie HMAC secret persisted in the DB → survives restarts/rebuilds with no env var or re-login. async function ensureSessionSecret(store) { let secret = await store.getSetting('session_secret'); if (!secret) { secret = crypto.randomBytes(32).toString('hex'); await store.setSetting('session_secret', secret); } auth.setSessionSecret(secret); } async function main() { ensureDirs(); const store = await createStore(process.env.DATABASE_URL); await ensureAdminPassword(store); await ensureSessionSecret(store); const handleRequest = createHandler(store); const server = http.createServer((req, res) => { handleRequest(req, res).catch(err => { console.error(err); json(res, 500, { ok: false, error: err.message || String(err) }); }); }); server.listen(PORT, '0.0.0.0', () => { console.log(`Bangumi Vault web server listening on http://0.0.0.0:${PORT}`); console.log(`Database: ${store.kind}`); console.log(`Files directory: ${FILES_DIR}`); }); // Background scheduler: checks once a minute whether an auto-sync is due. setInterval(() => { sync.checkSchedule(store).catch(err => console.error('schedule check failed:', err)); }, 60 * 1000); } main().catch(err => { console.error(err); process.exit(1); });