feat: publish Agent Studio integrations and setup guide
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { parseHls, resolveHlsAsset } from "../src/media/hls.js";
|
||||
|
||||
describe("bounded HLS inputs", () => {
|
||||
it("preserves CDN-issued per-path signatures without accepting unrelated parameters", () => {
|
||||
const base = new URL("https://cdn.example/episode/master.m3u8?auth_key=123-0-0-abcdef");
|
||||
expect(resolveHlsAsset(base, "child.m3u8?auth_key=124-0-0-123abc", "/episode/").search).toBe("?auth_key=124-0-0-123abc");
|
||||
for (const uri of ["child.m3u8?auth_key=124-0-0-123abc&token=secret", "child.m3u8?auth_key=oops", "child.m3u8?auth_key=124-0-0-123abc&auth_key=124-0-0-123abc"]) expect(() => resolveHlsAsset(base, uri, "/episode/")).toThrow();
|
||||
});
|
||||
it("parses finite TS playlists and preserves exact durations", () => {
|
||||
expect(parseHls("#EXTM3U\n#EXTINF:4.5,\none.ts\n#EXTINF:2,\ntwo.ts\n#EXT-X-ENDLIST\n")).toEqual({kind:"media",segments:[{uri:"one.ts",duration:4.5},{uri:"two.ts",duration:2}],duration:6.5});
|
||||
});
|
||||
it("rejects incomplete, encrypted and unsupported source structures", () => {
|
||||
for (const text of ["not hls", "#EXTM3U\n#EXTINF:3,\none.ts", "#EXTM3U\n#EXT-X-KEY:METHOD=AES-128\n#EXTINF:3,\none.ts\n#EXT-X-ENDLIST", "#EXTM3U\n#EXT-X-MAP:URI=init.mp4\n#EXTINF:3,\none.m4s\n#EXT-X-ENDLIST", "#EXTM3U\n#EXTINF:-3,\none.ts\n#EXT-X-ENDLIST"]) expect(()=>parseHls(text)).toThrow();
|
||||
});
|
||||
it("recognizes a simple master but refuses separate audio renditions", () => {
|
||||
expect(parseHls("#EXTM3U\n#EXT-X-STREAM-INF:BANDWIDTH=400000\nlow/list.m3u8")).toEqual({kind:"master",variants:["low/list.m3u8"]});
|
||||
expect(()=>parseHls('#EXTM3U\n#EXT-X-MEDIA:TYPE=AUDIO,URI="audio.m3u8"\n#EXT-X-STREAM-INF:BANDWIDTH=1\nvideo.m3u8')).toThrow();
|
||||
});
|
||||
it("keeps signing parameters only within the signed episode's path and origin", () => {
|
||||
const base = new URL("https://cdn.example/video/episode/master.m3u8?auth_key=fixture");
|
||||
expect(resolveHlsAsset(base,"low/0001.ts",base.pathname.slice(0,base.pathname.lastIndexOf('/')+1)).href).toBe("https://cdn.example/video/episode/low/0001.ts?auth_key=fixture");
|
||||
for (const uri of ["https://attacker.example/a.ts","../other.ts","file:///tmp/a.ts","//127.0.0.1/a.ts","%2e%2e/other.ts","one.ts?token=other"]) expect(()=>resolveHlsAsset(base,uri,"/video/episode/")).toThrow();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user