Files
WebDrop/web/src/core-bridge/worker/accountCrypto.test.ts
T

20 lines
1.3 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import { decryptInvitation, encryptInvitation, generateInvitationKeys, openJson, sealJson } from './accountCrypto';
describe('encrypted invitation recipient binding', () => {
it('only the addressed account and channel can decrypt the member link', async () => {
const bob = await generateInvitationKeys(); const carol = await generateInvitationKeys();
const payload = await encryptInvitation('https://drop.test/c/channel#k=secret', 'bob', 'channel', bob.publicKey);
expect(payload).not.toContain('secret');
expect(await decryptInvitation(payload, 'bob', 'channel', bob.privateKey)).toContain('#k=secret');
await expect(decryptInvitation(payload, 'carol', 'channel', carol.privateKey)).rejects.toThrow();
await expect(decryptInvitation(payload, 'bob', 'other-channel', bob.privateKey)).rejects.toThrow();
});
it('modified encrypted vault contents are rejected', async () => {
const key = await crypto.subtle.generateKey({ name: 'AES-GCM', length: 256 }, false, ['encrypt', 'decrypt']);
const encrypted = await sealJson({ resources: [] }, key);
const raw = Uint8Array.from(atob(encrypted), (c) => c.charCodeAt(0)); raw[13] = (raw[13] ?? 0) ^ 1;
const corrupted = btoa(String.fromCharCode(...raw));
await expect(openJson(corrupted, key)).rejects.toThrow('校验失败');
});
});