German for 'quack', matching the Ente (German for 'duck') naming. All references updated: package name, CLI binary, X-Client-Package header, test descriptions, temp dir prefixes, README, Makefile docker tag.
90 lines
3.5 KiB
TypeScript
90 lines
3.5 KiB
TypeScript
/**
|
|
* 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();
|
|
});
|
|
});
|