@trimble-oss/trimble-id
Version:
Trimble Identity SDK for JavaScript/ TypeScript
116 lines (110 loc) • 5.83 kB
JavaScript
;
(function (root, factory) {
/* istanbul ignore next */
if (typeof define === 'function' && define.amd) {
// AMD
define(['./RefreshableTokenProvider', './HttpClient', './AnalyticsHttpClient', 'btoa'], (RefreshableTokenProvider, HttpClient, AnalyticsHttpClient, btoa) => {
return factory({
RefreshableTokenProvider: RefreshableTokenProvider,
HttpClient: HttpClient,
AnalyticsHttpClient: AnalyticsHttpClient,
btoa: btoa
});
});
} else if (typeof exports === 'object') {
// CommonJS
module.exports = factory({
RefreshableTokenProvider: require('./RefreshableTokenProvider'),
HttpClient: require('./HttpClient'),
AnalyticsHttpClient: require('./AnalyticsHttpClient'),
btoa: root.btoa || require('btoa')
});
} else {
// Browser globals (Note: root is window)
root.OnBehalfGrantTokenProvider = factory(root);
}
}(this, function (imports) {
/**
* @implements {ITokenProvider}
* @description The On Behalf grant flow allows an application to act on behalf of a user. The On Behalf grant is only supported for access tokens. It does not work with any other type of token, including refresh tokens.
*/
class OnBehalfGrantTokenProvider {
/**
* @description Public constructor for OnBehalfGrantTokenProvider class
* @param {IEndpointProvider} endpointProvider An endpoint provider that provides the URL for the Trimble Identity token endpoints.
* It can be be OpenIdEndpointProvider/FixedEndpointProvider
* @param {string} consumerKey The consumer key for the calling application
* @param {string} consumerSecret The consumer secret for the calling application
* @param {string} accessToken The access token that this application wishes to act on behalf of when calling another API
*/
constructor(endpointProvider, consumerKey, consumerSecret, accessToken) {
this._endpointProvider = endpointProvider;
this._consumerKey = consumerKey;
this._consumerSecret = consumerSecret;
this._accessToken = accessToken;
this._scopes = [];
//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 Task 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);
if (!this._refreshableTokenProvider) {
return this._retrieveToken();
}
return this._refreshableTokenProvider.RetrieveToken();
}
_retrieveToken() {
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=urn:ietf:params:oauth:grant-type:token-exchange' +
'&subject_token_type=urn:ietf:params:oauth:token-type:jwt' +
'&subject_token=' + encodeURIComponent(self._accessToken) +
'&scope=' + encodeURIComponent(self._scopes.join(' '));
new imports.HttpClient().httpPost(endpoint, content, requestSettings)
.then(function (json) {
var result = JSON.parse(json);
var now = new Date();
self._refreshableTokenProvider = new imports.RefreshableTokenProvider(self._endpointProvider, self._consumerKey, self._consumerSecret, result.access_token, new Date(now.getTime() + result.expires_in * 1000), null, result.refresh_token);
resolve(result.access_token);
})
.catch((err) => {
self._analyticshttpclient.sendExceptionEvent(self.RetrieveToken.name, err, self._consumerKey);
reject('On-behalf grant failed: ' + err);
});
})
.catch((err) => {
self._analyticshttpclient.sendExceptionEvent(self.RetrieveToken.name, err, self._consumerKey);
reject('On-behalf grant failed: ' + err);
});
});
}
}
// Exposed public methods
return OnBehalfGrantTokenProvider;
}));