1
0
mirror of https://github.com/snobu/destreamer.git synced 2026-02-26 16:28:24 +00:00

added access token refresh logic (closes #255)

This commit is contained in:
Luca Armaroli
2020-10-11 21:56:08 +02:00
parent 3249759c29
commit 85f3beae71
2 changed files with 31 additions and 15 deletions

View File

@@ -9,6 +9,10 @@ import jwtDecode from 'jwt-decode';
import puppeteer from 'puppeteer'; import puppeteer from 'puppeteer';
type Jwt = {
[key: string]: any
}
export class TokenCache { export class TokenCache {
private tokenCacheFile = '.token_cache'; private tokenCacheFile = '.token_cache';
@@ -21,24 +25,18 @@ export class TokenCache {
const session: Session = JSON.parse(fs.readFileSync(this.tokenCacheFile, 'utf8')); const session: Session = JSON.parse(fs.readFileSync(this.tokenCacheFile, 'utf8'));
type Jwt = { const [isExpiring, timeLeft] = this.isExpiring(session);
[key: string]: any
}
const decodedJwt: Jwt = jwtDecode(session.AccessToken);
const now: number = Math.floor(Date.now() / 1000); if (isExpiring) {
const exp: number = decodedJwt['exp'];
const timeLeft: number = exp - now;
if (timeLeft < 120) {
logger.warn('Access token has expired! \n'); logger.warn('Access token has expired! \n');
return null; return null;
} }
else {
logger.info(`Access token still good for ${Math.floor(timeLeft / 60)} minutes.\n`.green);
logger.info(`Access token still good for ${Math.floor(timeLeft / 60)} minutes.\n`.green); return session;
}
return session;
} }
public Write(session: Session): void { public Write(session: Session): void {
@@ -50,11 +48,23 @@ export class TokenCache {
logger.info('Fresh access token dropped into .token_cachen \n'.green); logger.info('Fresh access token dropped into .token_cachen \n'.green);
}); });
} }
public isExpiring(session: Session): [boolean, number] {
const decodedJwt: Jwt = jwtDecode(session.AccessToken);
const timeLeft: number = decodedJwt['exp']; - Math.floor(Date.now() / 1000);
if (timeLeft < (5 * 60)) {
return [true, 0];
}
else {
return [false, timeLeft];
}
}
} }
export async function refreshSession(url: string): Promise<Session> { 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({ const browser: puppeteer.Browser = await puppeteer.launch({
executablePath: getPuppeteerChromiumPath(), executablePath: getPuppeteerChromiumPath(),
@@ -70,7 +80,7 @@ export async function refreshSession(url: string): Promise<Session> {
const page: puppeteer.Page = (await browser.pages())[0]; const page: puppeteer.Page = (await browser.pages())[0];
await page.goto(url, { waitUntil: 'load' }); await page.goto(url, { waitUntil: 'load' });
await browser.waitForTarget((target: puppeteer.Target) => target.url().includes(videoId), { timeout: 30000 }); await browser.waitForTarget((target: puppeteer.Target) => target.url().endsWith('microsoftstream.com/'), { timeout: 150000 });
let session: Session | null = null; let session: Session | null = null;
let tries = 1; let tries = 1;

View File

@@ -7,7 +7,7 @@ import { setProcessEvents } from './Events';
import { logger } from './Logger'; import { logger } from './Logger';
import { getPuppeteerChromiumPath } from './PuppeteerHelper'; import { getPuppeteerChromiumPath } from './PuppeteerHelper';
import { drawThumbnail } from './Thumbnail'; import { drawThumbnail } from './Thumbnail';
import { TokenCache} from './TokenCache'; import { TokenCache, refreshSession} from './TokenCache';
import { Video, Session } from './Types'; import { Video, Session } from './Types';
import { checkRequirements, parseInputFile, parseCLIinput, getUrlsFromPlaylist} from './Utils'; import { checkRequirements, parseInputFile, parseCLIinput, getUrlsFromPlaylist} from './Utils';
import { getVideosInfo, createUniquePaths } from './VideoUtils'; import { getVideosInfo, createUniquePaths } from './VideoUtils';
@@ -195,6 +195,12 @@ async function downloadVideo(videoGUIDs: Array<string>,
continue; continue;
} }
if (argv.keepLoginCookies && tokenCache.isExpiring(session)) {
logger.info('Trying to refresh access token...');
session = await refreshSession('https://web.microsoftstream.com/');
apiClient.setSession(session);
}
masterParser.push(await apiClient.callUrl(video.playbackUrl).then(res => res?.data)); masterParser.push(await apiClient.callUrl(video.playbackUrl).then(res => res?.data));
masterParser.end(); masterParser.end();