1
0
mirror of https://github.com/snobu/destreamer.git synced 2026-01-17 05:22:18 +00:00
Files
destreamer-mirror/src/TokenCache.ts
2021-04-15 21:09:59 +02:00

106 lines
3.1 KiB
TypeScript

import { chromeCacheFolder } from './destreamer';
import { ERROR_CODE } from './Errors';
import { logger } from './Logger';
import { getPuppeteerChromiumPath } from './PuppeteerHelper';
import { Session } from './Types';
import fs from 'fs';
import jwtDecode from 'jwt-decode';
import puppeteer from 'puppeteer';
export class TokenCache {
private tokenCacheFile = '.token_cache';
public Read(): Session | null {
if (!fs.existsSync(this.tokenCacheFile)) {
logger.warn(`${this.tokenCacheFile} not found. \n`);
return null;
}
const session: Session = JSON.parse(fs.readFileSync(this.tokenCacheFile, 'utf8'));
type Jwt = {
[key: string]: any
}
const decodedJwt: Jwt = jwtDecode(session.AccessToken);
const now: number = Math.floor(Date.now() / 1000);
const exp: number = decodedJwt['exp'];
const timeLeft: number = exp - now;
if (timeLeft < 120) {
logger.warn('Access token has expired! \n');
return null;
}
logger.info(`Access token still good for ${Math.floor(timeLeft / 60)} minutes.\n`.green);
return session;
}
public Write(session: Session): void {
const s: string = JSON.stringify(session, null, 4);
fs.writeFile(this.tokenCacheFile, s, (err: any) => {
if (err) {
return logger.error(err);
}
logger.info(`Fresh access token dropped into ${this.tokenCacheFile} \n`.green);
});
}
}
export async function refreshSession(url: string): Promise<Session> {
const videoId: string = url.split('/').pop() ?? process.exit(ERROR_CODE.INVALID_VIDEO_GUID);
const browser: puppeteer.Browser = await puppeteer.launch({
executablePath: getPuppeteerChromiumPath(),
headless: false, // NEVER TRUE OR IT DOES NOT WORK
userDataDir: chromeCacheFolder,
args: [
'--disable-dev-shm-usage',
'--fast-start',
'--no-sandbox'
]
});
const page: puppeteer.Page = (await browser.pages())[0];
await page.goto(url, { waitUntil: 'load' });
await browser.waitForTarget((target: puppeteer.Target) => target.url().includes(videoId), { timeout: 30000 });
let session: Session | null = null;
let tries = 1;
while (!session) {
try {
let sessionInfo: any;
session = await page.evaluate(
() => {
return {
AccessToken: sessionInfo.AccessToken,
ApiGatewayUri: sessionInfo.ApiGatewayUri,
ApiGatewayVersion: sessionInfo.ApiGatewayVersion
};
}
);
}
catch (error) {
if (tries > 5) {
process.exit(ERROR_CODE.NO_SESSION_INFO);
}
session = null;
tries++;
await page.waitFor(3000);
}
}
browser.close();
return session;
}