botframework-connector
Version:
Bot Connector is autorest generated connector client.
180 lines • 7.01 kB
JavaScript
"use strict";
/**
* @module botframework-connector
*/
/**
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AppCredentials = void 0;
const tokenCredentials_1 = require("./tokenCredentials");
const authenticationConstants_1 = require("./authenticationConstants");
/**
* General AppCredentials auth implementation and cache.
* Subclasses can implement refreshToken to acquire the token.
*/
class AppCredentials {
/**
* Initializes a new instance of the [AppCredentials](xref:botframework-connector.AppCredentials) class.
*
* @param appId The App ID.
* @param channelAuthTenant Tenant ID of the Azure AD tenant where the bot is created.
* - Required for SingleTenant app types.
* - Optional for MultiTenant app types. **Note**: '_botframework.com_' is the default tenant when no value is provided.
*
* More information: https://learn.microsoft.com/en-us/security/zero-trust/develop/identity-supported-account-types.
* @param oAuthScope The scope for the token.
*/
constructor(appId, channelAuthTenant, oAuthScope = null) {
this.appId = appId;
this.tenant = channelAuthTenant;
this.oAuthEndpoint = this.GetToChannelFromBotLoginUrlPrefix() + this.tenant;
this.oAuthScope = oAuthScope && oAuthScope.length > 0 ? oAuthScope : this.GetToChannelFromBotOAuthScope();
}
// Protects against JSON.stringify leaking secrets
toJSON() {
return {
name: this.constructor.name,
appId: this.appId,
tenant: this.tenant,
oAuthEndpoint: this.oAuthEndpoint,
oAuthScope: this.oAuthScope,
};
}
/**
* Gets tenant to be used for channel authentication.
*
* @returns The channel auth token tenant for this credential.
*/
get tenant() {
return this._tenant;
}
/**
* Sets tenant to be used for channel authentication.
*/
set tenant(value) {
this._tenant = value && value.length > 0 ? value : this.GetDefaultChannelAuthTenant();
}
/**
* Gets the OAuth scope to use.
*
* @returns The OAuth scope to use.
*/
get oAuthScope() {
return this._oAuthScope;
}
/**
* Sets the OAuth scope to use.
*/
set oAuthScope(value) {
this._oAuthScope = value;
this.tokenCacheKey = `${this.appId}${this.oAuthScope}-cache`;
}
/**
* Gets the OAuth endpoint to use.
*
* @returns The OAuthEndpoint to use.
*/
get oAuthEndpoint() {
return this._oAuthEndpoint;
}
/**
* Sets the OAuth endpoint to use.
*/
set oAuthEndpoint(value) {
// aadApiVersion is set to '1.5' to avoid the "spn:" concatenation on the audience claim
// For more info, see https://github.com/AzureAD/azure-activedirectory-library-for-nodejs/issues/128
this._oAuthEndpoint = value;
}
/**
* Adds the host of service url to trusted hosts.
* If expiration time is not provided, the expiration date will be current (utc) date + 1 day.
*/
static trustServiceUrl() {
// no-op
}
/**
* Checks if the service url is for a trusted host or not.
*
* @returns {boolean} True if the host of the service url is trusted; False otherwise.
*/
static isTrustedServiceUrl() {
return true;
}
/**
* Apply the credentials to the HTTP request.
*
* @param webResource The WebResource HTTP request.
* @returns A Promise representing the asynchronous operation.
*/
signRequest(webResource) {
return __awaiter(this, void 0, void 0, function* () {
if (this.shouldSetToken()) {
return new tokenCredentials_1.TokenCredentials(yield this.getToken()).signRequest(webResource);
}
return webResource;
});
}
/**
* Gets an OAuth access token.
*
* @param forceRefresh True to force a refresh of the token; or false to get
* a cached token if it exists.
* @returns A Promise that represents the work queued to execute.
* @remarks If the promise is successful, the result contains the access token string.
*/
getToken(forceRefresh = false) {
return __awaiter(this, void 0, void 0, function* () {
if (!forceRefresh) {
// check the global cache for the token. If we have it, and it's valid, we're done.
const oAuthToken = AppCredentials.cache.get(this.tokenCacheKey);
// Check if the token is not expired.
if (oAuthToken && oAuthToken.expiresOn > new Date()) {
return oAuthToken.accessToken;
}
}
// We need to refresh the token, because:
// 1. The user requested it via the forceRefresh parameter
// 2. We have it, but it's expired
// 3. We don't have it in the cache.
const res = yield this.refreshToken();
if (res && res.accessToken) {
// Subtract 5 minutes from expiresOn so they'll we'll get a new token before it expires.
res.expiresOn.setMinutes(res.expiresOn.getMinutes() - 5);
AppCredentials.cache.set(this.tokenCacheKey, res);
return res.accessToken;
}
else {
throw new Error('Authentication: No response or error received from MSAL.');
}
});
}
GetToChannelFromBotOAuthScope() {
return authenticationConstants_1.AuthenticationConstants.ToChannelFromBotOAuthScope;
}
GetToChannelFromBotLoginUrlPrefix() {
return authenticationConstants_1.AuthenticationConstants.ToChannelFromBotLoginUrlPrefix;
}
GetDefaultChannelAuthTenant() {
return authenticationConstants_1.AuthenticationConstants.DefaultChannelAuthTenant;
}
/**
* @private
*/
shouldSetToken() {
return this.appId && this.appId !== authenticationConstants_1.AuthenticationConstants.AnonymousSkillAppId;
}
}
exports.AppCredentials = AppCredentials;
AppCredentials.cache = new Map();
//# sourceMappingURL=appCredentials.js.map