1import { describe, it, expect } from "vitest";2import { deriveKey, generateSalt } from "./argon2";3import { encrypt, decrypt } 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 19 20 21 const tampered = (ciphertext[0] === "f" ? "0" : "f") + ciphertext.slice(1);22 await expect(decrypt(key, nonce, tampered, tag)).rejects.toThrow();23 });2425 it("rejects wrong password", async () => {26 const salt = generateSalt();27 const key1 = await deriveKey("right-password", salt);28 const { nonce, ciphertext, tag } = await encrypt(key1, "secret");29 const key2 = await deriveKey("wrong-password", salt);30 await expect(decrypt(key2, nonce, ciphertext, tag)).rejects.toThrow();31 });3233 it("generates fresh nonce on each encrypt", async () => {34 const salt = generateSalt();35 const key = await deriveKey("test", salt);36 const e1 = await encrypt(key, "data");37 const e2 = await encrypt(key, "data");38 expect(e1.nonce).not.toBe(e2.nonce);39 });40});