UNPKG

@azure/communication-common

Version:
125 lines (124 loc) 4.42 kB
var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var autoRefreshTokenCredential_exports = {}; __export(autoRefreshTokenCredential_exports, { AutoRefreshTokenCredential: () => AutoRefreshTokenCredential }); module.exports = __toCommonJS(autoRefreshTokenCredential_exports); var import_tokenParser = require("./tokenParser.js"); const expiredToken = { token: "", expiresOnTimestamp: -10 }; const minutesToMs = (minutes) => minutes * 1e3 * 60; const defaultExpiringSoonInterval = minutesToMs(10); const defaultRefreshAfterLifetimePercentage = 0.5; class AutoRefreshTokenCredential { refresh; refreshProactively; expiringSoonIntervalInMs = defaultExpiringSoonInterval; refreshAfterLifetimePercentage = defaultRefreshAfterLifetimePercentage; currentToken; activeTimeout; activeTokenFetching = null; activeTokenUpdating = null; disposed = false; constructor(refreshArgs) { const { tokenRefresher, token, refreshProactively } = refreshArgs; this.refresh = tokenRefresher; this.currentToken = token ? (0, import_tokenParser.parseToken)(token) : expiredToken; this.refreshProactively = refreshProactively ?? false; if (this.refreshProactively) { this.scheduleRefresh(); } } async getToken(options) { if (!this.isTokenExpiringSoon(this.currentToken)) { return this.currentToken; } if (!this.isTokenValid(this.currentToken)) { const updatePromise = this.updateTokenAndReschedule(options?.abortSignal); await updatePromise; } return this.currentToken; } dispose() { this.disposed = true; this.activeTokenFetching = null; this.activeTokenUpdating = null; this.currentToken = expiredToken; if (this.activeTimeout) { clearTimeout(this.activeTimeout); } } async updateTokenAndReschedule(abortSignal) { if (this.activeTokenUpdating) { return this.activeTokenUpdating; } this.activeTokenUpdating = this.refreshTokenAndReschedule(abortSignal); try { await this.activeTokenUpdating; } finally { this.activeTokenUpdating = null; } } async refreshTokenAndReschedule(abortSignal) { const newToken = await this.refreshToken(abortSignal); if (!this.isTokenValid(newToken)) { throw new Error("The token returned from the tokenRefresher is expired."); } this.currentToken = newToken; if (this.refreshProactively) { this.scheduleRefresh(); } } async refreshToken(abortSignal) { try { if (!this.activeTokenFetching) { this.activeTokenFetching = this.refresh(abortSignal); } return (0, import_tokenParser.parseToken)(await this.activeTokenFetching); } finally { this.activeTokenFetching = null; } } scheduleRefresh() { if (this.disposed) { return; } if (this.activeTimeout) { clearTimeout(this.activeTimeout); } const tokenTtlInMs = this.currentToken.expiresOnTimestamp - Date.now(); let timespanInMs = null; if (this.isTokenExpiringSoon(this.currentToken)) { timespanInMs = tokenTtlInMs * this.refreshAfterLifetimePercentage; } else { timespanInMs = tokenTtlInMs - this.expiringSoonIntervalInMs; } this.activeTimeout = setTimeout(() => this.updateTokenAndReschedule(), timespanInMs); } isTokenValid(token) { return token && Date.now() < token.expiresOnTimestamp; } isTokenExpiringSoon(token) { return !token || Date.now() >= token.expiresOnTimestamp - this.expiringSoonIntervalInMs; } } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { AutoRefreshTokenCredential }); //# sourceMappingURL=autoRefreshTokenCredential.js.map