UNPKG

@twurple/auth

Version:

Authenticate with Twitch and stop caring about refreshing tokens.

110 lines (109 loc) 4.16 kB
import { __decorate } from "tslib"; import { Enumerable } from '@d-fischer/shared-utils'; import { extractUserId, rtfm } from '@twurple/common'; import { accessTokenIsExpired } from "../AccessToken.mjs"; import { getAppToken } from "../helpers.mjs"; import { TokenFetcher } from "../TokenFetcher.mjs"; /** * An auth provider that gets tokens using client credentials. */ let AppTokenAuthProvider = class AppTokenAuthProvider { /** * Creates a new auth provider to receive an application token with using the client ID and secret. * * @param clientId The client ID of your application. * @param clientSecret The client secret of your application. * @param impliedScopes The scopes that are implied for your application, * for example an extension that is allowed to access subscriptions. */ constructor(clientId, clientSecret, impliedScopes = []) { this._clientId = clientId; this._clientSecret = clientSecret; this._impliedScopes = impliedScopes; this._fetcher = new TokenFetcher(async (scopes) => await this._fetch(scopes)); } /** * The client ID. */ get clientId() { return this._clientId; } /** * The scopes that are currently available using the access token. */ get currentScopes() { return this._impliedScopes; } /** * Can only get tokens for implied scopes (i.e. extension subscription support). * * The consumer is expected to take care that this is actually set up in the Twitch developer console. * * @param user The user to get an access token for. * @param scopeSets The requested scopes. */ async getAccessTokenForUser(user, ...scopeSets) { if (scopeSets.every(scopeSet => { var _a; return (_a = scopeSet === null || scopeSet === void 0 ? void 0 : scopeSet.some(scope => this._impliedScopes.includes(scope))) !== null && _a !== void 0 ? _a : true; })) { const appToken = await this.getAppAccessToken(); return { ...appToken, userId: extractUserId(user), }; } throw new Error('Can not get user access token for AppTokenAuthProvider'); } /** * Throws, because this auth provider does not support user authentication. */ getCurrentScopesForUser() { return this._impliedScopes; } /** * Fetches an app access token. */ async getAnyAccessToken() { return await this._fetcher.fetch(); } /** * Fetches an app access token. * * @param forceNew Whether to always get a new token, even if the old one is still deemed valid internally. */ async getAppAccessToken(forceNew = false) { if (forceNew) { this._token = undefined; } return await this._fetcher.fetch(); } async _fetch(scopeSets) { if (scopeSets.length > 0) { for (const scopes of scopeSets) { if (this._impliedScopes.length) { if (scopes.every(scope => !this._impliedScopes.includes(scope))) { throw new Error(`One of the scopes ${scopes.join(', ')} requested but only the scope ${this._impliedScopes.join(', ')} is implied`); } } else { throw new Error(`One of the scopes ${scopes.join(', ')} requested but the client credentials flow does not support scopes`); } } } if (!this._token || accessTokenIsExpired(this._token)) { return (this._token = await getAppToken(this._clientId, this._clientSecret)); } return this._token; } }; __decorate([ Enumerable(false) ], AppTokenAuthProvider.prototype, "_clientSecret", void 0); __decorate([ Enumerable(false) ], AppTokenAuthProvider.prototype, "_token", void 0); __decorate([ Enumerable(false) ], AppTokenAuthProvider.prototype, "_fetcher", void 0); AppTokenAuthProvider = __decorate([ rtfm('auth', 'AppTokenAuthProvider', 'clientId') ], AppTokenAuthProvider); export { AppTokenAuthProvider };