- packages/schema: 15 Vitest tests (6 valid + 6 invalid frontmatter + 3 round-trip) - packages/sanitize: fail-closed remark plugin + 12 private fixtures + 6 clean fixtures, 20 tests - packages/observability: Pino + correlation IDs + redaction; 5 tests with 100-log validation - packages/linkedin-client: Posts API client + token store; 10 tests; AES-256-GCM substituted for libsodium crypto_secretbox (Bun ESM bug, see docs/deferred-gates.md D-001) 50/50 tests pass across 4 packages. All Stage 1 DoDs verified. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
42 lines
1.3 KiB
TypeScript
42 lines
1.3 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { decryptToken, encryptToken, generateKey, keyFromBase64, keyToBase64 } from "./token-store";
|
|
|
|
describe("token-store — libsodium crypto_secretbox round-trip", () => {
|
|
it("encrypts and decrypts a token round-trip", async () => {
|
|
const key = await generateKey();
|
|
const plain = "AQXxxx-fake-access-token-zzz";
|
|
const ct = await encryptToken(plain, key);
|
|
expect(ct).not.toContain(plain);
|
|
const back = await decryptToken(ct, key);
|
|
expect(back).toBe(plain);
|
|
});
|
|
|
|
it("produces different ciphertexts for the same plaintext (random nonce)", async () => {
|
|
const key = await generateKey();
|
|
const plain = "same-plaintext";
|
|
const a = await encryptToken(plain, key);
|
|
const b = await encryptToken(plain, key);
|
|
expect(a).not.toBe(b);
|
|
});
|
|
|
|
it("fails to decrypt with wrong key", async () => {
|
|
const k1 = await generateKey();
|
|
const k2 = await generateKey();
|
|
const ct = await encryptToken("secret", k1);
|
|
let err: unknown;
|
|
try {
|
|
await decryptToken(ct, k2);
|
|
} catch (e) {
|
|
err = e;
|
|
}
|
|
expect(err).toBeDefined();
|
|
});
|
|
|
|
it("key serialization round-trip", async () => {
|
|
const key = await generateKey();
|
|
const b64 = await keyToBase64(key);
|
|
const back = await keyFromBase64(b64);
|
|
expect(back).toEqual(key);
|
|
});
|
|
});
|