From 29595dd98f81b27d27c3fc4fe806c8654544f898 Mon Sep 17 00:00:00 2001 From: Jos Vooges | STH Date: Tue, 25 Aug 2026 00:55:20 +0200 Subject: [PATCH] Fix Fastify Stremio routes: wildcard must be last path segment. Co-authored-by: Cursor --- apps/master-api/src/stremio/routes.ts | 32 +++++++++++++++------------ 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/apps/master-api/src/stremio/routes.ts b/apps/master-api/src/stremio/routes.ts index 4ed596a..e8eed25 100644 --- a/apps/master-api/src/stremio/routes.ts +++ b/apps/master-api/src/stremio/routes.ts @@ -24,13 +24,16 @@ const MANIFEST = { export async function registerStremioRoutes(app: FastifyInstance, config: Config) { const playback = new PlaybackService(config); - app.options("/stremio/*", async (_request, reply) => { - reply - .header("Access-Control-Allow-Origin", "*") - .header("Access-Control-Allow-Methods", "GET, OPTIONS") - .header("Access-Control-Allow-Headers", "Content-Type") - .status(204) - .send(); + app.addHook("onRequest", async (request, reply) => { + if (!request.url.startsWith("/stremio/")) return; + reply.header("Access-Control-Allow-Origin", "*"); + if (request.method === "OPTIONS") { + reply + .header("Access-Control-Allow-Methods", "GET, OPTIONS") + .header("Access-Control-Allow-Headers", "Content-Type") + .status(204) + .send(); + } }); app.get("/stremio/:token/manifest.json", async (request, reply) => { @@ -39,17 +42,21 @@ export async function registerStremioRoutes(app: FastifyInstance, config: Config if (!userId) { return reply.status(401).send({ error: "Invalid addon token" }); } - reply.header("Access-Control-Allow-Origin", "*"); return MANIFEST; }); - app.get("/stremio/:token/catalog/:type/:id/*.json", async (request, reply) => { - const { token, type, id } = request.params as { token: string; type: string; id: string }; + // Stremio catalog with extras: /catalog/movie/movies/search=matrix.json + app.get("/stremio/:token/catalog/:type/:id/*", async (request, reply) => { + const { token, type, id } = request.params as { + token: string; + type: string; + id: string; + "*": string; + }; const userId = await validateAddonToken(token); if (!userId) { return reply.status(401).send({ error: "Invalid addon token" }); } - reply.header("Access-Control-Allow-Origin", "*"); const extra = (request.params as { "*": string })["*"] ?? ""; const search = parseExtraSearch(extra); @@ -68,7 +75,6 @@ export async function registerStremioRoutes(app: FastifyInstance, config: Config if (!userId) { return reply.status(401).send({ error: "Invalid addon token" }); } - reply.header("Access-Control-Allow-Origin", "*"); if (type === "movie") { return { metas: await getMovieCatalog(id, config) }; @@ -85,7 +91,6 @@ export async function registerStremioRoutes(app: FastifyInstance, config: Config if (!userId) { return reply.status(401).send({ error: "Invalid addon token" }); } - reply.header("Access-Control-Allow-Origin", "*"); if (type === "movie") { const meta = await getMovieMeta(id); @@ -104,7 +109,6 @@ export async function registerStremioRoutes(app: FastifyInstance, config: Config if (!userId) { return reply.status(401).send({ error: "Invalid addon token" }); } - reply.header("Access-Control-Allow-Origin", "*"); const streams = await getStreams(type, id, userId, playback); return { streams };