aboutsummaryrefslogtreecommitdiff
path: root/src/lib/Utility/feedToken.test.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/Utility/feedToken.test.ts')
-rw-r--r--src/lib/Utility/feedToken.test.ts44
1 files changed, 44 insertions, 0 deletions
diff --git a/src/lib/Utility/feedToken.test.ts b/src/lib/Utility/feedToken.test.ts
new file mode 100644
index 00000000..ffcb5fd7
--- /dev/null
+++ b/src/lib/Utility/feedToken.test.ts
@@ -0,0 +1,44 @@
+import { describe, expect, it } from "vitest";
+import { decryptFeedToken, encryptFeedToken } from "./feedToken";
+
+// Fixed 32-byte keys so the cipher is exercised without the FEED_TOKEN_KEY env
+// var (production omits the key argument and reads it from env).
+const key = new Uint8Array(32).fill(7);
+const otherKey = new Uint8Array(32).fill(9);
+
+describe("feed token", () => {
+ // Behaviour gate: the feed must still resolve to the same refresh token it
+ // was minted from, and the cleartext must never appear in the URL blob.
+ it("round-trips the refresh token without leaking it", async () => {
+ const refreshToken = "anilist-refresh-token-abc123";
+ const sealed = await encryptFeedToken(refreshToken, key);
+
+ expect(sealed).not.toContain(refreshToken);
+ expect(await decryptFeedToken(sealed, key)).toBe(refreshToken);
+ });
+
+ it("produces a fresh ciphertext each time (random IV)", async () => {
+ expect(await encryptFeedToken("same-token", key)).not.toBe(
+ await encryptFeedToken("same-token", key),
+ );
+ });
+
+ it("rejects a token sealed with a different key", async () => {
+ const sealed = await encryptFeedToken("secret", otherKey);
+
+ expect(await decryptFeedToken(sealed, key)).toBeNull();
+ });
+
+ it("rejects a tampered ciphertext", async () => {
+ const sealed = await encryptFeedToken("secret", key);
+ const tampered = `${sealed[0] === "A" ? "B" : "A"}${sealed.slice(1)}`;
+
+ expect(await decryptFeedToken(tampered, key)).toBeNull();
+ });
+
+ it("rejects malformed input", async () => {
+ expect(await decryptFeedToken("", key)).toBeNull();
+ expect(await decryptFeedToken("short", key)).toBeNull();
+ expect(await decryptFeedToken("not valid base64url!!", key)).toBeNull();
+ });
+});