fix(config-backup): ignore a web tab's lastOpenedAt, audit multi-user restores, refuse symlinked or loosened snapshots, keep the folder settings on restore

This commit is contained in:
Devvyn committed 2026-10-20 18:01:43 +08:00
1 parent 71fcefbaf2
commit c5f1e99036
5 files changed
+146 -6

No files matched your search

+16
View File
@@ -137,6 +137,22 @@ describe('/api/config-backups', () => {
}
});
it('multi-user: a restore is written to the admin audit log', async () => {
process.env.CODEMAN_MULTIUSER = '1';
const { app } = await createRouteTestHarness(registerConfigBackupRoutes, {
authUser: { username: 'root', role: 'admin' },
});
const id = (await app.inject({ method: 'POST', url: '/api/config-backups' })).json().data.id;
await app.inject({ method: 'POST', url: `/api/config-backups/${id}/restore` });
const auditPath = join(getDataDir(), 'admin-audit.jsonl');
const written = () => existsSync(auditPath) && readFileSync(auditPath, 'utf8').includes('config_backup_restore');
for (let i = 0; i < 40 && !written(); i++) await new Promise((r) => setTimeout(r, 25));
const last = JSON.parse(readFileSync(auditPath, 'utf8').trim().split('\n').pop()!);
expect(last).toMatchObject({ admin: 'root', action: 'config_backup_restore', target: id });
expect(last.detail.restored).toContain('settings.json');
rmSync(auditPath, { force: true });
});
it('multi-user: an admin is allowed', async () => {
process.env.CODEMAN_MULTIUSER = '1';
const { app } = await createRouteTestHarness(registerConfigBackupRoutes, {