mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-18 21:16:47 +00:00
test(server): storage slice-1 review follow-ups — mirror s3-replica probe decrypt, all-encrypted seed without key, test-route 401
This commit is contained in:
@@ -109,6 +109,9 @@ describe('Storage admin e2e (real auth + admin guard + managed guard + temp SQLi
|
||||
// class-level (JwtAuthGuard + AdminGuard on the controller), not re-added
|
||||
// per handler where a future handler could forget them.
|
||||
expect((await request(server).put('/api/admin/storage').send({ backends: [], categories: {} })).status).toBe(401);
|
||||
expect(
|
||||
(await request(server).post('/api/admin/storage/test').send({ backend: { name: 'x', type: 'local', options: { root: '/tmp' } } })).status,
|
||||
).toBe(401);
|
||||
});
|
||||
|
||||
it('STORE2E-002 403 for a non-admin', async () => {
|
||||
|
||||
@@ -320,4 +320,36 @@ describe('StorageAdminService.testBackend', () => {
|
||||
}),
|
||||
).rejects.toThrow("re-enter the secret 'secretAccessKey' for 'ghost'");
|
||||
});
|
||||
|
||||
it('STORADM-025 a mirror with a stored s3 replica decrypts the enc:v1: secret for the probe', async () => {
|
||||
const goodRoot = makeTmpDir();
|
||||
const { service, uploadsRoot } = makeService();
|
||||
service.applyConfig(configWith(uploadsRoot, {
|
||||
backends: [
|
||||
{ name: 'good-local', type: 'local', options: { root: goodRoot } },
|
||||
{
|
||||
name: 'off-box',
|
||||
type: 's3',
|
||||
options: { ...S3_OPTIONS, endpoint: 'http://127.0.0.1:1', retries: 0, timeoutMs: 200 },
|
||||
},
|
||||
],
|
||||
categories: {},
|
||||
}));
|
||||
// applyConfig encrypted the secret at rest — the snapshot the mirror
|
||||
// expansion reads holds ciphertext, so this probe exercises the full
|
||||
// snapshot → decryptBackendSecrets → ephemeral S3Driver chain.
|
||||
expect(readRow(BACKENDS_KEY)).toContain('enc:v1:');
|
||||
const result = await service.testBackend({
|
||||
name: 'cand-mirror',
|
||||
type: 'mirror',
|
||||
options: { primary: 'good-local', replicas: ['off-box'] },
|
||||
});
|
||||
expect(result.targets).toEqual([
|
||||
{ name: 'good-local', ok: true },
|
||||
expect.objectContaining({ name: 'off-box', ok: false }),
|
||||
]);
|
||||
// Decrypt succeeded: the replica failed on the network. A decrypt failure
|
||||
// would reject the whole call (decryptBackendSecrets throws), not mark a target.
|
||||
expect(result.targets[1]!.error).not.toContain('could not decrypt');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -589,6 +589,33 @@ describe('seed-once storage-config.json import', () => {
|
||||
expect(readRow('storage.backends')).toBe(firstRow);
|
||||
expect(second.resolve('backups').backendName).toBe('nas');
|
||||
});
|
||||
|
||||
it('SEED-010 an all-encrypted seed imports without ENCRYPTION_KEY (the gate is plaintext-only)', () => {
|
||||
const cipher = encrypt_api_key('sk-seed');
|
||||
writeSeed(
|
||||
JSON.stringify({
|
||||
backends: [
|
||||
{
|
||||
name: 'off-box',
|
||||
type: 's3',
|
||||
options: {
|
||||
endpoint: 'http://127.0.0.1:9000',
|
||||
bucket: 'trek',
|
||||
accessKeyId: 'ak',
|
||||
secretAccessKey: cipher,
|
||||
},
|
||||
},
|
||||
],
|
||||
categories: { backups: 'off-box' },
|
||||
}),
|
||||
);
|
||||
const registry = makeUnseededRegistry({ encryptionKeySet: false });
|
||||
registry.onModuleInit();
|
||||
// enc:v1: values are not "plaintext secrets" — the key-presence gate must
|
||||
// not fire, and the ciphertext must persist byte-for-byte (idempotent encrypt).
|
||||
expect(registry.resolve('backups').driver).toBeInstanceOf(S3Driver);
|
||||
expect(readRow('storage.backends')).toContain(cipher);
|
||||
});
|
||||
});
|
||||
|
||||
// ── snapshot() — effective world with provenance ──────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user