UNPKG

@trimble-oss/trimble-id

Version:

Trimble Identity SDK for JavaScript/ TypeScript

123 lines (115 loc) 5.57 kB
'use strict'; // implements ITokenProvider (function (root, factory) { /* istanbul ignore next */ if (typeof define === 'function' && define.amd) { // AMD define(['./HttpClient', './AnalyticsHttpClient', 'btoa'], (HttpClient, AnalyticsHttpClient, btoa) => { return factory({ HttpClient: HttpClient, AnalyticsHttpClient: AnalyticsHttpClient, btoa: btoa }); }); } else if (typeof exports === 'object') { // CommonJS module.exports = factory({ HttpClient: require('./HttpClient'), AnalyticsHttpClient: require('./AnalyticsHttpClient'), btoa: root.btoa || require('btoa') }); } else { // Browser globals (Note: root is window) root.ClientCredentialTokenProvider = factory(root); } }(this, function (imports) { /** * @implements {ITokenProvider} * @description The Client Credentials grant is used when applications request an access token to access their own resources. */ class ClientCredentialTokenProvider { /** * @description Public constructor for ClientCredentialTokenProvider class * @param {IEndpointProvider} endpointProvider An endpoint provider that provides the URL for the Trimble Identity token endpoint. * It can be OpenIdEndpointProvider/FixedEndpointProvider * @param {string} consumerKey The consumer key for the calling application * @param {string} consumerSecret The consumer secret for the calling application */ constructor(endpointProvider, consumerKey, consumerSecret) { this._endpointProvider = endpointProvider; this._consumerKey = consumerKey; this._consumerSecret = consumerSecret; this._scopes = []; this._accessToken = null; this._tokenExpiry = new Date(0); //Send analytics this._analyticshttpclient = imports.AnalyticsHttpClient; this._analyticshttpclient.sendInitEvent(this.constructor.name, consumerKey); } /** * @description Fluent extension to add scopes * @param {IEnumerable<string>} scopes The scopes to add to the token provider */ WithScopes(scopes) { this._scopes = this._scopes.concat(scopes); return this; } /** * @description Retrieves an access token for the application * @returns {PromiseLike<string>} A promise that resolves to the value of the access token on completion * @exception Thrown when a token endpoint is not provided by the endpoint provider * @exception Thrown when a call to the token endpoint fails */ RetrieveToken() { //Send analytics this._analyticshttpclient.sendMethodEvent(this.RetrieveToken.name, this._consumerKey); var self = this; return new Promise(function (resolve, reject) { if (self._tokenExpiry < new Date()) self._refreshToken() .then(() => { resolve(self._accessToken); }) .catch((err) => { self._analyticshttpclient.sendExceptionEvent(self.RetrieveToken.name, err, self._consumerKey); reject('Unable to refresh token: ' + err); }); else resolve(self._accessToken); }); } _refreshToken() { var self = this; return new Promise(function (resolve, reject) { self._endpointProvider.RetrieveTokenEndpoint() .then((endpoint) => { var basicHeader = 'Basic ' + imports.btoa(self._consumerKey + ':' + self._consumerSecret); var requestSettings = { headers: { Authorization: basicHeader, "Content-Type": 'application/x-www-form-urlencoded', Accept: 'application/json', } }; var content = 'grant_type=client_credentials&scope=' + encodeURIComponent(self._scopes.join(' ')); new imports.HttpClient().httpPost(endpoint, content, requestSettings) .then((json) => { var result = JSON.parse(json); self._accessToken = result.access_token; var now = new Date(); self._tokenExpiry = new Date(now.getTime() + result.expires_in * 1000); resolve(); }) .catch((err) => { self._analyticshttpclient.sendExceptionEvent(self.RetrieveToken.name, err, self._consumerKey); reject('Client credential grant method failed: ' + err); }); }) .catch((err) => { self._analyticshttpclient.sendExceptionEvent(self.RetrieveToken.name, err, self._consumerKey); reject('Unable to retrieve token endpoint: ' + err); }); }); } } // Exposed public methods return ClientCredentialTokenProvider; }));