/** * Tests for `crypto.fromBase64`, `crypto.toBase64`, and * `crypto.toBase64URL`. * * Ente delivers most binary fields as standard base64 strings (with `+`, * `/`, and `=` padding). A few fields, notably the auth token returned by * the login flow, are URL-safe base64 (with `-` and `_` instead of `+` and * `/`, and stripped padding). quak must accept both forms on input and * produce the right form on output. * * These tests pin the contract: * - `toBase64(b)` produces standard base64 with padding. * - `toBase64URL(b)` produces URL-safe base64 without padding. * - `fromBase64(s)` accepts both forms transparently and round-trips. */ import { beforeAll, describe, expect, it } from "vitest"; import { fromBase64, init, toBase64, toBase64URL, } from "../../src/crypto/index.js"; describe("crypto encoding helpers", () => { beforeAll(async () => { await init(); }); /** * The test input contains bytes that produce `+`, `/`, and `=` in * standard base64. Specifically the bytes `0xFB 0xFF 0xBF` encode to * `+/+/` in standard base64 and `-_-_` in URL-safe base64. This makes * the alphabet difference observable. */ const BYTES_WITH_AMBIGUOUS_CHARS = new Uint8Array([0xfb, 0xff, 0xbf]); it("round-trips arbitrary bytes through standard base64", () => { const original = new Uint8Array([0, 1, 2, 127, 128, 250, 255]); const encoded = toBase64(original); expect(typeof encoded).toBe("string"); expect(fromBase64(encoded)).toEqual(original); }); it("toBase64 produces a standard-alphabet string", () => { // Standard base64 may contain `+`, `/`, and trailing `=`. URL-safe // base64 is forbidden from containing those characters. We test // that toBase64 chose the standard alphabet. const encoded = toBase64(BYTES_WITH_AMBIGUOUS_CHARS); // For these specific bytes the encoding contains both `+` and `/`, // proving the alphabet is the standard one. expect(encoded).toMatch(/[+/]/); }); it("toBase64URL produces a URL-safe string with no padding", () => { const encoded = toBase64URL(BYTES_WITH_AMBIGUOUS_CHARS); // URL-safe alphabet: no `+`, `/`, or `=`. expect(encoded).not.toMatch(/[+/=]/); // The substitutions `-` and `_` should appear. expect(encoded).toMatch(/[-_]/); }); it("fromBase64 accepts standard input", () => { const standard = toBase64(BYTES_WITH_AMBIGUOUS_CHARS); expect(fromBase64(standard)).toEqual(BYTES_WITH_AMBIGUOUS_CHARS); }); it("fromBase64 accepts URL-safe input", () => { const urlSafe = toBase64URL(BYTES_WITH_AMBIGUOUS_CHARS); expect(fromBase64(urlSafe)).toEqual(BYTES_WITH_AMBIGUOUS_CHARS); }); it("fromBase64 accepts URL-safe input even without padding", () => { // Construct a URL-safe form with the padding stripped, as Ente // delivers it. `fromBase64` must still decode it correctly. const stripped = toBase64URL(BYTES_WITH_AMBIGUOUS_CHARS).replace( /=+$/, "", ); expect(fromBase64(stripped)).toEqual(BYTES_WITH_AMBIGUOUS_CHARS); }); it("fromBase64 rejects garbage", () => { // Non-base64 characters should not silently decode to something. We // do not commit to the exact error type but we do commit that the // call cannot return data successfully. expect(() => fromBase64("!!! not base64 !!!")).toThrow(); }); });