73 lines
2.6 KiB
TypeScript
73 lines
2.6 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import test from "node:test";
|
|
import {
|
|
decryptImageBytes,
|
|
imageMime,
|
|
shouldDecryptImage,
|
|
} from "../src/lib/media/images";
|
|
import { isHLSURL, nativeHLS, resolvePlayURL } from "../src/lib/media/playback";
|
|
|
|
test("legacy image XOR is immutable, symmetric and changes only the first 100 bytes", () => {
|
|
const plain = Uint8Array.from({ length: 150 }, (_, index) => index),
|
|
original = plain.slice();
|
|
const encrypted = decryptImageBytes(plain.buffer);
|
|
assert.deepEqual(plain, original);
|
|
assert.notDeepEqual(encrypted.slice(0, 100), plain.slice(0, 100));
|
|
assert.deepEqual(encrypted.slice(100), plain.slice(100));
|
|
assert.deepEqual(decryptImageBytes(encrypted.buffer as ArrayBuffer), plain);
|
|
for (const length of [0, 1, 12, 99, 100]) {
|
|
const bytes = plain.slice(0, length);
|
|
assert.deepEqual(
|
|
decryptImageBytes(decryptImageBytes(bytes.buffer).buffer as ArrayBuffer),
|
|
bytes,
|
|
);
|
|
}
|
|
});
|
|
test("image signatures and static exemptions preserve the original loader contract", () => {
|
|
assert.equal(imageMime(new Uint8Array([71, 73, 70, 56])), "image/gif");
|
|
assert.equal(imageMime(new Uint8Array([137, 80, 78, 71])), "image/png");
|
|
assert.equal(
|
|
imageMime(new Uint8Array([82, 73, 70, 70, 0, 0, 0, 0, 87, 69, 66, 80])),
|
|
"image/webp",
|
|
);
|
|
assert.equal(imageMime(new Uint8Array([71, 73, 70, 0])), "image/jpeg");
|
|
for (const src of [
|
|
"/static/brand/placeholder.svg?v=1",
|
|
"blob:abc",
|
|
"data:image/png;base64,abc",
|
|
"https://placehold.co/400",
|
|
])
|
|
assert.equal(shouldDecryptImage(src), false);
|
|
assert.equal(
|
|
shouldDecryptImage("https://cdn.example/encrypted.webp?token=secret"),
|
|
true,
|
|
);
|
|
});
|
|
test("signed relative and absolute media URLs retain every query byte", () => {
|
|
const signed = "archive/main.m3u8?ticket=a%2Bb%3D&expires=99&path=%2Ffoo";
|
|
assert.equal(resolvePlayURL(signed), "/h5/m3u8/" + signed);
|
|
assert.equal(resolvePlayURL("/h5/m3u8/" + signed), "/h5/m3u8/" + signed);
|
|
assert.equal(
|
|
resolvePlayURL("https://cdn.example/" + signed),
|
|
"https://cdn.example/" + signed,
|
|
);
|
|
assert(isHLSURL(resolvePlayURL(signed)));
|
|
assert(!isHLSURL("https://cdn.example/movie.mp4?token=1"));
|
|
});
|
|
test("native HLS only uses Safari and shell browsers keep the inline MSE player", () => {
|
|
const video = {
|
|
canPlayType: () => "probably",
|
|
} as unknown as HTMLVideoElement;
|
|
assert(
|
|
nativeHLS(video, "Mozilla/5.0 (iPhone) Version/18.0 Mobile Safari/604.1"),
|
|
);
|
|
for (const browser of [
|
|
"Quark",
|
|
"MQQBrowser",
|
|
"QQ/9",
|
|
"MicroMessenger",
|
|
"Chrome/130",
|
|
])
|
|
assert(!nativeHLS(video, "Mozilla iPhone Safari/604.1 " + browser));
|
|
});
|