@azure/communication-common
Version:
Common package for Azure Communication services.
125 lines (124 loc) • 4.42 kB
JavaScript
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