mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-20 16:07:11 +08:00
116 lines
3.3 KiB
JavaScript
116 lines
3.3 KiB
JavaScript
const assert = require('node:assert/strict');
|
|
const fs = require('node:fs');
|
|
const os = require('node:os');
|
|
const path = require('node:path');
|
|
const { DatabaseSync } = require('node:sqlite');
|
|
const { test } = require('node:test');
|
|
|
|
const { migrateLocalSqlitePath } = require('../dist/migration/migration.js');
|
|
const {
|
|
openLocalSqliteRuntimeDatabase,
|
|
} = require('../dist/runtime/runtimeDatabase.js');
|
|
|
|
function insertSecret(database, name, version, createdAtMs) {
|
|
database
|
|
.prepare(
|
|
`INSERT INTO "QingLong3LocalSecretEnvelopes"
|
|
("project_id", "secret_name", "version", "mutation_id", "key_id",
|
|
"algorithm", "nonce", "ciphertext", "auth_tag", "created_at_ms")
|
|
VALUES ('default', ?, ?, ?, 'active-key', 'aes-256-gcm', ?, ?, ?, ?)`,
|
|
)
|
|
.run(
|
|
name,
|
|
version,
|
|
`00000000-0000-4000-8000-${String(createdAtMs).padStart(12, '0')}`,
|
|
Buffer.alloc(12, version),
|
|
Buffer.from(`cipher-${name}-${version}`),
|
|
Buffer.alloc(16, version),
|
|
createdAtMs,
|
|
);
|
|
}
|
|
|
|
test('lists only current Secret metadata with a stable bounded cursor', async (t) => {
|
|
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'ql3-secret-meta-'));
|
|
t.after(() => fs.rmSync(directory, { recursive: true, force: true }));
|
|
const options = {
|
|
directory,
|
|
profile: 'edge',
|
|
databasePath: path.join(directory, 'qinglong3.sqlite'),
|
|
};
|
|
await migrateLocalSqlitePath(options);
|
|
const database = new DatabaseSync(options.databasePath);
|
|
insertSecret(database, 'alpha', 1, 101);
|
|
insertSecret(database, 'alpha', 2, 102);
|
|
insertSecret(database, 'beta', 1, 103);
|
|
insertSecret(database, 'gamma', 1, 104);
|
|
database.close();
|
|
|
|
const runtime = await openLocalSqliteRuntimeDatabase(options);
|
|
const first = await runtime.localSecretMetadata.listLocalSecretMetadata({
|
|
projectId: 'default',
|
|
limit: 2,
|
|
});
|
|
assert.deepEqual(first, {
|
|
secrets: [
|
|
{
|
|
projectId: 'default',
|
|
name: 'alpha',
|
|
currentVersion: 2,
|
|
createdAtMs: 102,
|
|
},
|
|
{
|
|
projectId: 'default',
|
|
name: 'beta',
|
|
currentVersion: 1,
|
|
createdAtMs: 103,
|
|
},
|
|
],
|
|
truncated: true,
|
|
next: { name: 'beta' },
|
|
});
|
|
assert.equal(JSON.stringify(first).includes('cipher'), false);
|
|
assert.equal(JSON.stringify(first).includes('key'), false);
|
|
assert.deepEqual(
|
|
await runtime.localSecretMetadata.listLocalSecretMetadata({
|
|
projectId: 'default',
|
|
limit: 2,
|
|
after: first.next,
|
|
}),
|
|
{
|
|
secrets: [
|
|
{
|
|
projectId: 'default',
|
|
name: 'gamma',
|
|
currentVersion: 1,
|
|
createdAtMs: 104,
|
|
},
|
|
],
|
|
truncated: false,
|
|
},
|
|
);
|
|
|
|
await runtime.close();
|
|
await assert.rejects(
|
|
runtime.localSecretMetadata.listLocalSecretMetadata({
|
|
projectId: 'default',
|
|
limit: 1,
|
|
}),
|
|
{ name: 'LocalSecretMetadataUnavailableError' },
|
|
);
|
|
});
|
|
|
|
test('rejects widened and over-budget metadata queries before storage', async () => {
|
|
const source = Object.create(
|
|
require('../dist/security/secretMetadataRepository.js')
|
|
.LocalSqliteSecretMetadataRepository.prototype,
|
|
);
|
|
assert.throws(
|
|
() =>
|
|
source.listLocalSecretMetadata({
|
|
projectId: 'default',
|
|
limit: 65,
|
|
}),
|
|
/options are invalid/u,
|
|
);
|
|
});
|