feat: add encrypted online settings backup keys
Add immutable client-encrypted settings snapshots with independent MDD2 capability keys so fresh installs can restore configuration without transferring backup files. Keep credentials encrypted end to end, preserve queues and history during import, and avoid exposing identifiers in request URLs or errors. Include the persistent API with quota, rate limits, crash-safe storage locking, durability checks, and end-to-end race and recovery coverage.
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
import { resolve } from 'node:path'
|
||||
import { createBackupServer } from './server.mjs'
|
||||
|
||||
const port = Number.parseInt(process.env.PORT ?? '8787', 10)
|
||||
const host = process.env.HOST ?? '127.0.0.1'
|
||||
const rootDir = resolve(process.env.BACKUP_DATA_DIR ?? './data')
|
||||
const allowedOrigins = (process.env.ALLOWED_ORIGINS ?? '')
|
||||
.split(',')
|
||||
.map(origin => origin.trim())
|
||||
.filter(Boolean)
|
||||
const rateLimit = {
|
||||
max: Number.parseInt(process.env.RATE_LIMIT_MAX ?? '60', 10),
|
||||
windowMs: Number.parseInt(process.env.RATE_LIMIT_WINDOW_MS ?? '60000', 10)
|
||||
}
|
||||
const uploadRateLimit = {
|
||||
max: Number.parseInt(process.env.UPLOAD_RATE_LIMIT_MAX ?? '10', 10),
|
||||
windowMs: Number.parseInt(process.env.UPLOAD_RATE_LIMIT_WINDOW_MS ?? '3600000', 10)
|
||||
}
|
||||
const maxStorageBytes = Number.parseInt(process.env.MAX_STORAGE_BYTES ?? String(10 * 1024 * 1024 * 1024), 10)
|
||||
const trustedProxy = process.env.TRUST_PROXY === 'true'
|
||||
|
||||
if (!Number.isSafeInteger(port) || port < 1 || port > 65_535) throw new Error('Invalid PORT')
|
||||
|
||||
const server = createBackupServer({ rootDir, allowedOrigins, rateLimit, uploadRateLimit, maxStorageBytes, trustedProxy })
|
||||
|
||||
server.listen(port, host, () => {
|
||||
process.stdout.write(`Backup API listening on ${host}:${port}\n`)
|
||||
})
|
||||
|
||||
function shutdown() {
|
||||
server.close(error => {
|
||||
if (error) {
|
||||
process.stderr.write('Backup API shutdown failed\n')
|
||||
process.exitCode = 1
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
process.on('SIGINT', shutdown)
|
||||
process.on('SIGTERM', shutdown)
|
||||
Reference in New Issue
Block a user