import NodeCache from "node-cache"; import { sha256 } from "../sub/crypto.js"; import { streamLifespan } from "../config.js"; const streamCache = new NodeCache({ stdTTL: streamLifespan/1000, checkperiod: 10, deleteOnExpire: true }); const salt = process.env.streamSalt; streamCache.on("expired", (key) => { streamCache.del(key); }); export function createStream(obj) { let streamID = sha256(`${obj.ip},${obj.service},${obj.filename},${obj.audioFormat},${obj.mute}`, salt), exp = Math.floor(new Date().getTime()) + streamLifespan, ghmac = sha256(`${streamID},${obj.service},${obj.ip},${exp}`, salt); if (!streamCache.has(streamID)) { streamCache.set(streamID, { id: streamID, service: obj.service, type: obj.type, urls: obj.u, filename: obj.filename, hmac: ghmac, ip: obj.ip, exp: exp, isAudioOnly: !!obj.isAudioOnly, audioFormat: obj.audioFormat, time: obj.time ? obj.time : false, copy: !!obj.copy, mute: !!obj.mute, metadata: obj.fileMetadata ? obj.fileMetadata : false }); } else { let streamInfo = streamCache.get(streamID); exp = streamInfo.exp; ghmac = streamInfo.hmac; } return `${process.env.selfURL}api/stream?t=${streamID}&e=${exp}&h=${ghmac}`; } export function verifyStream(ip, id, hmac, exp) { try { let streamInfo = streamCache.get(id); if (streamInfo) { let ghmac = sha256(`${id},${streamInfo.service},${ip},${exp}`, salt); if (hmac == ghmac && exp.toString() == streamInfo.exp && ghmac == streamInfo.hmac && ip == streamInfo.ip && exp > Math.floor(new Date().getTime())) { return streamInfo; } else { return { error: 'Unauthorized', status: 401 }; } } else { return { error: 'this stream token does not exist', status: 400 }; } } catch (e) { return { status: 500, body: { status: "error", text: "Internal Server Error" } }; } }