Files
qinglong/packages/ql3-local-owner-console/test/credentialRecovery.test.cjs
T

96 lines
3.0 KiB
JavaScript

const assert = require('node:assert/strict');
const { test } = require('node:test');
const {
createLocalOwnerCredentialRecoveryService,
} = require('../dist/credential-recovery');
test('issues a distinct credential and replays acknowledged completion', async () => {
const previous = {
credentialId: `own_${'a'.repeat(22)}`,
version: 1,
pepperKeyId: 'owner-key-1',
state: 'active',
subject: { type: 'user', id: `usr_${'b'.repeat(22)}` },
subjectStatus: 'active',
secretDigest: '1'.repeat(64),
createdAtMs: 100,
notBeforeAtMs: 100,
expiresAtMs: 100000000,
};
let recovery = null;
const credentials = {
async resolve(credentialId) {
return credentialId === previous.credentialId ? previous : null;
},
};
const repository = {
async resolve() {
return recovery;
},
async issue(command) {
recovery = {
issueMutationId: command.mutationId,
issueRequestId: command.requestId,
subjectId: command.replacementCredential.subject.id,
previousCredentialId: command.previousCredentialId,
previousCredentialVersion: command.expectedPreviousVersion,
replacementCredential: command.replacementCredential,
state: 'issued',
issuedAtMs: command.replacementCredential.createdAtMs,
};
return { status: 'inserted', recovery };
},
async acknowledge() {
throw new Error('not used');
},
async complete(command) {
assert.equal(recovery.state, 'acknowledged');
recovery = {
...recovery,
state: 'completed',
completeMutationId: command.mutationId,
completeRequestId: command.requestId,
revokedCredentialVersion: command.revokedCredential.version,
completedAtMs: command.revokedCredential.createdAtMs,
};
return { status: 'inserted', recovery };
},
};
let nowMs = 1000;
const service = createLocalOwnerCredentialRecoveryService(
repository,
credentials,
Buffer.alloc(32, 7).toString('base64url'),
{
pepperKeyId: 'owner-key-1',
now: () => nowMs,
randomBytes: (size) => Buffer.alloc(size, size),
},
);
const issueMutationId = '00000000-0000-4000-8000-000000000801';
const issued = await service.issue({
mutationId: issueMutationId,
requestId: 'recover-issue-801',
previousCredentialId: previous.credentialId,
expectedPreviousVersion: 1,
});
assert.equal(issued.status, 'inserted');
assert.notEqual(issued.replacementCredentialId, previous.credentialId);
assert.match(issued.replacementCredentialToken, /^ql3c_/);
recovery = {
...recovery,
state: 'acknowledged',
deliveryDigest: '2'.repeat(64),
acknowledgedAtMs: 1100,
};
nowMs = 1200;
const completion = {
issueMutationId,
mutationId: '00000000-0000-4000-8000-000000000802',
requestId: 'recover-complete-802',
};
assert.equal((await service.complete(completion)).status, 'inserted');
assert.equal((await service.complete(completion)).status, 'existing');
});