1import { describe, it, expect } from "vitest";2import { deriveKey, generateSalt } from "./argon2";3import { encrypt, decrypt, zeroKey } from "../background/aes";45describe("vault crypto", () => {6 it("round-trips plaintext through encrypt/decrypt", async () => {7 const salt = generateSalt();8 const key = await deriveKey("correct-horse", salt);9 const { nonce, ciphertext, tag } = await encrypt(key, "hello peach");10 const plain = await decrypt(key, nonce, ciphertext, tag);11 expect(plain).toBe("hello peach");12 });1314 it("rejects tampered ciphertext", async () => {15 const salt = generateSalt();16 const key = await deriveKey("correct-horse", salt);17 const { nonce, ciphertext, tag } = await encrypt(key, "secret data");18 const tampered = ciphertext.slice(0, -2) + "ff";19 await expect(decrypt(key, nonce, tampered, tag)).rejects.toThrow();20 });2122 it("rejects wrong password", async () => {23 const salt = generateSalt();24 const key1 = await deriveKey("right-password", salt);25 const { nonce, ciphertext, tag } = await encrypt(key1, "secret");26 const key2 = await deriveKey("wrong-password", salt);27 await expect(decrypt(key2, nonce, ciphertext, tag)).rejects.toThrow();28 });2930 it("generates fresh nonce on each encrypt", async () => {31 const salt = generateSalt();32 const key = await deriveKey("test", salt);33 const e1 = await encrypt(key, "data");34 const e2 = await encrypt(key, "data");35 expect(e1.nonce).not.toBe(e2.nonce);36 });37});