UNPKG

@yash101/schwab-api-client

Version:

A TypeScript client library for interacting with the Charles Schwab Brokerage APIs.

165 lines 5.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.AutoRefreshAuthTokens = exports.AuthTokens = void 0; const auth_1 = require("./auth"); const idtoken_1 = require("./idtoken"); /** * Represents a set of authentication tokens, including access and refresh tokens, * along with their expiration times. Provides methods to retrieve, set, and check * the expiration status of these tokens. */ class AuthTokens { accessToken = ''; refreshToken = ''; scope = ''; idToken; atExpiresAt; rtExpiresAt; getAccessToken() { return this.accessToken; } getRefreshToken() { return this.refreshToken; } getAccessTokenExpiresAt() { return this.atExpiresAt || new Date(); } getRefreshTokenExpiresAt() { return this.rtExpiresAt || new Date(); } getUserId() { return this.idToken; } getScope() { return this.scope; } isAccessTokenExpired() { return (!this.atExpiresAt) || this.atExpiresAt <= new Date(); } isRefreshTokenExpired() { return (!this.rtExpiresAt) || this.rtExpiresAt <= new Date(); } setAccessToken(token) { this.accessToken = token; } setRefreshToken(token) { this.refreshToken = token; } setAccessTokenExpiresAt(expiresAt) { this.atExpiresAt = expiresAt; } setRefreshTokenExpiresAt(expiresAt) { this.rtExpiresAt = expiresAt; } setIdToken(token) { this.idToken = token; } setScope(scope) { this.scope = scope; } getAuthHeader() { return `Bearer ${this.accessToken}`; } } exports.AuthTokens = AuthTokens; /** * Represents a set of authentication tokens with automatic refresh capabilities. * Inherits from AuthTokens and adds functionality to refresh the access token * using the refresh token at regular intervals. */ class AutoRefreshAuthTokens extends AuthTokens { refreshInterval; appConfig; refreshIntervalTimer; onRefreshTokenChanged = () => { }; constructor(appConfig, refreshToken, accessToken, refreshInterval = 1000 * 60 * 20) { super(); this.refreshToken = refreshToken; this.accessToken = accessToken || ''; this.appConfig = appConfig; this.refreshIntervalTimer = refreshInterval; } // Method to refresh the access token using the refresh token doRefreshAccessToken(retries) { if (retries && retries > 5) { console.error('Failed to refresh access token after 5 retries. No longer attempting to refresh.'); clearInterval(this.refreshInterval); return; } // Perform API call to refresh the access token (0, auth_1.getNewAccessToken)({ authTokens: this, appConfig: this.appConfig, }) .then((response) => { this.setAccessToken(response.accessToken); this.setAccessTokenExpiresAt(response.accessTokenExpiresAt); this.setIdToken((0, idtoken_1.decodeIdToken)(Buffer.from(response.id_token, 'base64'))); if (response.refreshToken && response.refreshToken !== this.refreshToken) { this.setRefreshToken(response.refreshToken); this.setRefreshTokenExpiresAt(new Date(Date.now() + 1000 * 60 * 60 * 24 * 7)); this.onRefreshTokenChanged(this); } }) .catch(e => { console.error(`Failed to refresh access token: ${e.message}`); // Try again setTimeout(() => { if (!retries) { retries = 0; } this.doRefreshAccessToken(retries + 1); }, 60 * 1000); }); } // Method to start the automatic refresh interval start() { if (this.refreshInterval) { this.stop(); } // every 20 minutes this.refreshInterval = setInterval(() => { this.doRefreshAccessToken(); }, this.refreshIntervalTimer); return this; } stop() { clearInterval(this.refreshInterval); this.refreshInterval = undefined; return this; } refreshImmediately() { this.doRefreshAccessToken(); return this; } setRefreshInterval(interval) { this.refreshIntervalTimer = interval; if (this.refreshInterval) { this.stop(); this.start(); } return this; } setOnRefreshTokenChanged(callback) { this.onRefreshTokenChanged = callback; return this; } static async fromAuthCode(code, appConfig, apiUri) { if (!apiUri) { apiUri = 'https://api.schwabapi.com/v1/oauth/token'; } const initialAuth = await (0, auth_1.getInitialTokensFromAuthorizationCode)({ authCode: code, appConfig, apiUri, }); const tokens = new AutoRefreshAuthTokens(appConfig, initialAuth.refreshToken, initialAuth.accessToken); tokens.setAccessTokenExpiresAt(initialAuth.accessTokenExpiresAt); tokens.setRefreshTokenExpiresAt(initialAuth.refreshTokenExpiresAt); tokens.setIdToken((0, idtoken_1.decodeIdToken)(Buffer.from(initialAuth.id_token, 'base64'))); tokens.setScope(initialAuth.scope); return tokens; } } exports.AutoRefreshAuthTokens = AutoRefreshAuthTokens; //# sourceMappingURL=tokens.js.map