Harden the server and add a Links page
Security headers, cross-site write refusal, atomic JSON writes, admin backup download, /healthz and Docker health check, OnlyOffice requires a JWT secret, npm test, CI audit, arm64 hub image. New Links tab for personal bookmarks, saved with per-person settings. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
b0d3aec811
commit
1f8c9493b7
16 files changed
+147
-25
No files matched your search
@@ -3,6 +3,7 @@
|
||||
// Everyone else enrols with a one-time invite code the admin creates; a signed-in person can also invite one of their own devices.
|
||||
const crypto = require('crypto');
|
||||
const fs = require('fs');
|
||||
const atomicWrite = require('./atomic');
|
||||
const path = require('path');
|
||||
const {
|
||||
generateRegistrationOptions, verifyRegistrationResponse,
|
||||
@@ -13,7 +14,7 @@ const users = require('./users');
|
||||
const DATA_DIR = process.env.DATA_DIR || path.join(__dirname, 'data');
|
||||
fs.mkdirSync(DATA_DIR, { recursive: true });
|
||||
const readJson = (f, d) => { try { return JSON.parse(fs.readFileSync(path.join(DATA_DIR, f), 'utf8')); } catch { return d; } };
|
||||
const writeJson = (f, v) => fs.writeFileSync(path.join(DATA_DIR, f), JSON.stringify(v, null, 2), { mode: 0o600 });
|
||||
const writeJson = (f, v) => atomicWrite(path.join(DATA_DIR, f), JSON.stringify(v, null, 2), { mode: 0o600 });
|
||||
|
||||
// Signing secret for cookies: env wins, otherwise generated once and kept so sessions survive restarts.
|
||||
let secret = process.env.COOKIE_SECRET;
|
||||
|
||||
Reference in new issue
Block a user