diff --git a/src/core/api.js b/src/core/api.js index 9dd4b1cc..c7e06284 100644 --- a/src/core/api.js +++ b/src/core/api.js @@ -131,14 +131,14 @@ export function runAPI(express, app, gitCommit, gitBranch, __dirname) { const checkBaseLength = q.t.length === 21 && q.e.length === 13; const checkSafeLength = q.h.length === 43 && q.s.length === 43 && q.i.length === 22; if (checkQueries && checkBaseLength && checkSafeLength) { - let streamInfo = verifyStream(q.t, q.h, q.e, q.s, q.i); - if (streamInfo.error) { - return res.status(streamInfo.status).json(apiJSON(0, { t: streamInfo.error }).body); - } if (q.p) { return res.status(200).json({ status: "continue" - }); + }) + } + let streamInfo = verifyStream(q.t, q.h, q.e, q.s, q.i); + if (streamInfo.error) { + return res.status(streamInfo.status).json(apiJSON(0, { t: streamInfo.error }).body); } return stream(res, streamInfo); } diff --git a/src/modules/stream/manage.js b/src/modules/stream/manage.js index 03821a8b..c30beec2 100644 --- a/src/modules/stream/manage.js +++ b/src/modules/stream/manage.js @@ -6,6 +6,8 @@ import { decryptStream, encryptStream, generateHmac } from "../sub/crypto.js"; import { streamLifespan } from "../config.js"; import { strict as assert } from "assert"; +const M3U_SERVICES = ['dailymotion', 'vimeo', 'rutube']; + const streamNoAccess = { error: "i couldn't verify if you have access to this stream. go back and try again!", status: 401 @@ -73,24 +75,28 @@ export function getInternalStream(id) { return internalStreamCache[id]; } -export function createInternalStream(obj = {}) { - assert(typeof obj.url === 'string'); +export function createInternalStream(url, obj = {}) { + assert(typeof url === 'string'); const streamID = nanoid(); internalStreamCache[streamID] = { - url: obj.url, + url, service: obj.service, controller: new AbortController() }; - let streamLink = new URL('/api/istream', `http://127.0.0.1:${process.env.API_PORT}`); + let streamLink = new URL('/api/istream', `http://127.0.0.1:${process.env.API_PORT || 9000}`); streamLink.searchParams.set('t', streamID); return streamLink.toString(); } export function destroyInternalStream(url) { - const id = new URL(url).searchParams.get('t'); - assert(id); + url = new URL(url); + if (url.hostname !== '127.0.0.1') { + return; + } + + const id = url.searchParams.get('t'); if (internalStreamCache[id]) { internalStreamCache[id].controller.abort(); @@ -98,6 +104,28 @@ export function destroyInternalStream(url) { } } +function wrapStream(streamInfo) { + /* m3u8 links are currently not supported + * for internal streams, skip them */ + if (M3U_SERVICES.includes(streamInfo.service)) { + return streamInfo; + } + + const url = streamInfo.urls; + + if (typeof url === 'string') { + streamInfo.urls = createInternalStream(url, streamInfo); + } else if (Array.isArray(url)) { + for (const idx in streamInfo.urls) { + streamInfo.urls[idx] = createInternalStream( + streamInfo.urls[idx], streamInfo + ); + } + } else throw 'invalid urls'; + + return streamInfo; +} + export function verifyStream(id, hmac, exp, secret, iv) { try { const ghmac = generateHmac(`${id},${exp},${iv},${secret}`, hmacSalt); @@ -113,25 +141,7 @@ export function verifyStream(id, hmac, exp, secret, iv) { if (Number(exp) <= new Date().getTime()) return streamNoExist; - if (!streamInfo.originalUrls) { - streamInfo.originalUrls = streamInfo.urls; - } - - if (typeof streamInfo.originalUrls === 'string') { - streamInfo.urls = createInternalStream({ - url: streamInfo.originalUrls, - ...streamInfo - }); - } else if (Array.isArray(streamInfo.originalUrls)) { - for (const idx in streamInfo.originalUrls) { - streamInfo.originalUrls[idx] = createInternalStream({ - url: streamInfo.originalUrls[idx], - ...streamInfo - }); - } - } else throw 'invalid urls'; - - return streamInfo; + return wrapStream(streamInfo); } catch { return {