Record upload IP and add dated administrative key reports
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
import assert from 'node:assert/strict'
|
||||
import test from 'node:test'
|
||||
import { formatRecoveryReport, recoveryMetadata } from '../src/recovery-report.mjs'
|
||||
|
||||
const key = 'MDD2-' + 'A'.repeat(70)
|
||||
|
||||
test('formats date in Berlin time with source IP and the online key', () => {
|
||||
assert.equal(formatRecoveryReport({ createdAt: '2026-09-22T12:30:00.000Z', sourceIp: '203.0.113.7' }, key), `22.09.2026 - 14:30 | IP: 203.0.113.7 | Schlüssel: ${key}\n`)
|
||||
assert.equal(formatRecoveryReport({ createdAt: '2026-01-22T12:30:00.000Z', sourceIp: '2001:db8::7' }, key), `22.01.2026 - 13:30 | IP: 2001:db8::7 | Schlüssel: ${key}\n`)
|
||||
assert.equal(formatRecoveryReport({ createdAt: '2026-09-21T22:00:00.000Z', sourceIp: '::ffff:192.0.2.1' }, key), `22.09.2026 - 00:00 | IP: 192.0.2.1 | Schlüssel: ${key}\n`)
|
||||
})
|
||||
|
||||
test('keeps legacy metadata explicitly unknown and does not invent a date or IP', () => {
|
||||
assert.deepEqual(recoveryMetadata({}), { createdAt: null, sourceIp: null })
|
||||
assert.equal(formatRecoveryReport({}, key), `Datum unbekannt | IP: unbekannt | Schlüssel: ${key}\n`)
|
||||
assert.equal(formatRecoveryReport({ createdAt: 'invalid', sourceIp: 'invalid\nInjected' }, key), `Datum unbekannt | IP: unbekannt | Schlüssel: ${key}\n`)
|
||||
assert.throws(() => formatRecoveryReport({}, key + '\nInjected'))
|
||||
})
|
||||
@@ -61,6 +61,33 @@ test('health endpoint reports readiness without exposing storage details', async
|
||||
assert.equal(response.headers.get('cache-control'), 'no-store')
|
||||
})
|
||||
|
||||
for (const [label, trustedProxy, forwarded, expected] of [
|
||||
['socket peer without proxy trust', false, '203.0.113.7', '127.0.0.1'],
|
||||
['trusted ingress IPv4', true, '203.0.113.7', '203.0.113.7'],
|
||||
['trusted ingress IPv6', true, '2001:db8::7', '2001:db8::7'],
|
||||
['invalid forwarding header', true, 'not-an-ip', '127.0.0.1']
|
||||
]) {
|
||||
test(`records source IP from ${label} without exposing it through restore`, async t => {
|
||||
const api = await startApi({ trustedProxy })
|
||||
t.after(() => api.close())
|
||||
const fixture = backupFixture()
|
||||
const response = await request(api, '/v1/backups', { method: 'POST', headers: { 'content-type': 'application/json', 'x-forwarded-for': forwarded }, body: JSON.stringify(fixture.payload) })
|
||||
assert.equal(response.status, 201)
|
||||
const filename = join(api.rootDir, `${fixture.payload.id}.json`)
|
||||
const original = await readFile(filename, 'utf8')
|
||||
const stored = JSON.parse(original)
|
||||
assert.equal(stored.sourceIp, expected)
|
||||
assert(Number.isFinite(Date.parse(stored.createdAt)))
|
||||
const duplicate = await request(api, '/v1/backups', { method: 'POST', headers: { 'content-type': 'application/json', 'x-forwarded-for': '192.0.2.9' }, body: JSON.stringify(fixture.payload) })
|
||||
assert.equal(duplicate.status, 409)
|
||||
assert.equal(await readFile(filename, 'utf8'), original)
|
||||
const restore = await request(api, '/v1/backups/restore', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ id: fixture.payload.id }) })
|
||||
assert.deepEqual(await restore.json(), { blob: fixture.payload.blob })
|
||||
const forged = await request(api, '/v1/backups', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ ...backupFixture().payload, sourceIp: '192.0.2.99' }) })
|
||||
assert.equal(forged.status, 400)
|
||||
})
|
||||
}
|
||||
|
||||
test('health endpoint rejects an unusable storage path', async t => {
|
||||
const container = await mkdtemp(join(tmpdir(), 'mdd-backup-health-'))
|
||||
const rootDir = join(container, 'not-a-directory')
|
||||
|
||||
Reference in New Issue
Block a user