adal-angular8
Version:
ADAL wrapper for Angular 8+
449 lines (448 loc) • 15.6 kB
JavaScript
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });
var adalLib = require("adal-angular");
var core_1 = require("@angular/core");
var bindCallback_1 = require("rxjs/internal/observable/bindCallback");
var timer_1 = require("rxjs/internal/observable/timer");
var operators_1 = require("rxjs/operators");
var internal_compatibility_1 = require("rxjs/internal-compatibility");
var defaultDoRefreshOption = function () { return Promise.resolve({ shouldProlong: true }); };
/**
*
*
* @export
* @class Adal8Service
*/
var Adal8Service = /** @class */ (function () {
/**
* Creates an instance of Adal8Service.
*
* @memberOf Adal8Service
*/
function Adal8Service() {
/**
*
*
* @private
* @type {adal.User}
* @memberOf Adal8Service
*/
this.adal8User = {
authenticated: false,
userName: '',
error: '',
token: '',
profile: {},
loginCached: false
};
}
Object.defineProperty(Adal8Service.prototype, "config", {
/**
*
*
* @readonly
* @type {adal.Config}
* @memberOf Adal8Service
*/
get: function () {
return this.adalContext.config;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Adal8Service.prototype, "userInfo", {
/**
*
*
* @readonly
* @type {adal.User}
* @memberOf Adal8Service
*/
get: function () {
return this.adal8User;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Adal8Service.prototype, "isInCallbackRedirectMode", {
get: function () {
return window.location.href.indexOf('#access_token') !== -1 || window.location.href.indexOf('#id_token') !== -1;
},
enumerable: true,
configurable: true
});
;
/**
*
*
* @param {adal.Config} configOptions
*
* @memberOf Adal8Service
*/
Adal8Service.prototype.init = function (configOptions) {
if (!configOptions) {
throw new Error('You must set config, when calling init.');
}
// redirect and logout_redirect are set to current location by default
var existingHash = window.location.hash;
var pathDefault = window.location.href;
if (existingHash) {
pathDefault = pathDefault.replace(existingHash, '');
}
configOptions.redirectUri = configOptions.redirectUri || pathDefault;
configOptions.postLogoutRedirectUri = configOptions.postLogoutRedirectUri || pathDefault;
// Get backup of configuration RefreshOption
this.doRefreshOption = configOptions.doRefresh || defaultDoRefreshOption;
// Set the configuration
this.doRefresh = this.doRefreshOption;
// create instance with given config
this.adalContext = adalLib.inject(configOptions);
this.updateDataFromCache();
if (this.adal8User.loginCached && !this.adal8User.authenticated && window.self == window.top && !this.isInCallbackRedirectMode) {
// Override configuration if no authentication
this.doRefresh = defaultDoRefreshOption;
this.refreshLoginToken();
}
else if (this.adal8User.loginCached && this.adal8User.authenticated && !this.loginRefreshTimer && window.self == window.top) {
this.setupLoginTokenRefreshTimer();
}
};
/**
*
*
*
* @memberOf Adal8Service
*/
Adal8Service.prototype.login = function () {
this.adalContext.login();
};
/**
*
*
* @returns {boolean}
*
* @memberOf Adal8Service
*/
Adal8Service.prototype.loginInProgress = function () {
return this.adalContext.loginInProgress();
};
/**
*
*
*
* @memberOf Adal8Service
*/
Adal8Service.prototype.logOut = function () {
this.adalContext.logOut();
};
/**
*
*
*
* @memberOf Adal8Service
*/
Adal8Service.prototype.handleWindowCallback = function (removeHash) {
if (removeHash === void 0) { removeHash = true; }
var hash = window.location.hash;
if (this.adalContext.isCallback(hash)) {
var isPopup = false;
if (this.adalContext._openedWindows.length > 0 && this.adalContext._openedWindows[this.adalContext._openedWindows.length - 1].opener && this.adalContext._openedWindows[this.adalContext._openedWindows.length - 1].opener._adalInstance) {
this.adalContext = this.adalContext._openedWindows[this.adalContext._openedWindows.length - 1].opener._adalInstance;
isPopup = true;
}
else if (window.parent && window.parent._adalInstance) {
this.adalContext = window.parent._adalInstance;
}
var requestInfo = this.adalContext.getRequestInfo(hash);
this.adalContext.saveTokenFromHash(requestInfo);
var callback = this.adalContext._callBackMappedToRenewStates[requestInfo.stateResponse] || this.adalContext.callback;
if (requestInfo.requestType === this.adalContext.REQUEST_TYPE.LOGIN) {
this.updateDataFromCache();
this.setupLoginTokenRefreshTimer();
}
if (requestInfo.stateMatch) {
if (typeof callback === 'function') {
if (requestInfo.requestType === this.adalContext.REQUEST_TYPE.RENEW_TOKEN) {
// Idtoken or Accestoken can be renewed
if (requestInfo.parameters['access_token']) {
callback(this.adalContext._getItem(this.adalContext.CONSTANTS.STORAGE.ERROR_DESCRIPTION), requestInfo.parameters['access_token']);
}
else if (requestInfo.parameters['id_token']) {
callback(this.adalContext._getItem(this.adalContext.CONSTANTS.STORAGE.ERROR_DESCRIPTION), requestInfo.parameters['id_token']);
}
else if (requestInfo.parameters['error']) {
callback(this.adalContext._getItem(this.adalContext.CONSTANTS.STORAGE.ERROR_DESCRIPTION), null);
this.adalContext._renewFailed = true;
}
}
}
}
}
// Remove hash from url
if (removeHash) {
if (window.location.hash) {
if (window.history.replaceState) {
window.history.replaceState('', '/', window.location.pathname);
}
else {
window.location.hash = '';
}
}
}
};
/**
*
*
* @param {string} resource
* @returns {string}
*
* @memberOf Adal8Service
*/
Adal8Service.prototype.getCachedToken = function (resource) {
return this.adalContext.getCachedToken(resource);
};
/**
*
*
* @param {string} resource
* @returns
*
* @memberOf Adal8Service
*/
Adal8Service.prototype.acquireToken = function (resource) {
var _this = this; // save outer this for inner function
return bindCallback_1.bindCallback(function (callback) {
_this.adalContext.acquireToken(resource, function (error, tokenOut) {
if (error) {
_this.adalContext.error('Error when acquiring token for resource: ' + resource, error);
callback(null, error);
}
else {
callback(tokenOut, null);
}
});
})()
.pipe(operators_1.map(function (result) {
if (!result[0] && result[1]) {
throw (result[1]);
}
return result[0];
}));
};
/**
*
*
* @returns {Observable<adal.User>}
*
* @memberOf Adal8Service
*/
Adal8Service.prototype.getUser = function () {
var _this = this; // save outer this for inner function
return bindCallback_1.bindCallback(function (cb) {
_this.adalContext.getUser(function (error, user) {
if (error) {
_this.adalContext.error('Error when getting user', error);
cb(null);
}
else {
cb(user || null);
}
});
})();
};
/**
*
*
*
* @memberOf Adal8Service
*/
Adal8Service.prototype.clearCache = function () {
this.adalContext.clearCache();
};
/**
*
*
* @param {string} resource
*
* @memberOf Adal8Service
*/
Adal8Service.prototype.clearCacheForResource = function (resource) {
this.adalContext.clearCacheForResource(resource);
};
/**
*
*
* @param {string} message
*
* @memberOf Adal8Service
*/
Adal8Service.prototype.info = function (message) {
this.adalContext.info(message);
};
/**
*
*
* @param {string} message
*
* @memberOf Adal8Service
*/
Adal8Service.prototype.verbose = function (message) {
this.adalContext.verbose(message);
};
/**
*
*
* @param {string} url
* @returns {string}
*
* @memberOf Adal8Service
*/
Adal8Service.prototype.getResourceForEndpoint = function (url) {
return this.adalContext.getResourceForEndpoint(url);
};
/**
*
*
* @returns {string}
*
* @memberOf Adal8Service
*/
Adal8Service.prototype.getToken = function () {
if (this.adalContext) {
return this.adalContext._getItem(this.adalContext.CONSTANTS.STORAGE.ACCESS_TOKEN_KEY + this.adalContext.config.loginResource);
}
else {
this.adal8User.token;
}
};
/**
*
*
*
* @memberOf Adal8Service
*/
Adal8Service.prototype.refreshDataFromCache = function () {
this.updateDataFromCache();
};
/**
*
*
* @private
*
* @memberOf Adal8Service
*/
Adal8Service.prototype.updateDataFromCache = function () {
var token = this.adalContext.getCachedToken(this.adalContext.config.loginResource);
this.adal8User.authenticated = token !== null && token.length > 0;
var user = this.adalContext.getCachedUser() || { userName: '', profile: undefined };
if (user) {
this.adal8User.userName = user.userName;
this.adal8User.profile = user.profile;
this.adal8User.token = token;
this.adal8User.error = this.adalContext.getLoginError();
this.adal8User.loginCached = true;
}
else {
this.adal8User.userName = '';
this.adal8User.profile = {};
this.adal8User.token = '';
this.adal8User.error = '';
this.adal8User.loginCached = false;
}
};
;
/**
*
*
*
* @memberOf Adal8Service
*/
Adal8Service.prototype.refreshLoginToken = function () {
var _this_1 = this;
if (!this.adal8User.loginCached) {
throw ('User not logged in');
}
this.doRefresh().then(function (doRefreshExpiration) {
if (doRefreshExpiration.shouldProlong) {
if (doRefreshExpiration.forceSetToken) {
_this_1.handleWindowCallback();
_this_1.refreshDataFromCache();
}
_this_1.acquireToken(_this_1.adalContext.config.loginResource).subscribe(function (token) {
_this_1.adal8User.token = token;
_this_1.userInfo.token = token;
if (!_this_1.adal8User.authenticated) {
// refresh the page
window.location.reload();
}
else {
// Restore configuration if token true
_this_1.doRefresh = _this_1.doRefreshOption;
_this_1.setupLoginTokenRefreshTimer();
if (internal_compatibility_1.isFunction(doRefreshExpiration.callbackFn)) {
doRefreshExpiration.callbackFn();
}
}
}, function (error) {
_this_1.rejectProlong();
});
}
else {
_this_1.rejectProlong();
_this_1.clearCache();
}
}).catch(function () {
console.warn('Do refresh task has been dismissed');
_this_1.doRefresh = defaultDoRefreshOption;
});
};
Adal8Service.prototype.rejectProlong = function () {
this.adal8User.authenticated = false;
this.adal8User.error = this.adalContext.getLoginError();
};
Adal8Service.prototype.now = function () {
return Math.round(new Date().getTime() / 1000.0);
};
Adal8Service.prototype.setupLoginTokenRefreshTimer = function () {
var _this_1 = this;
// Get expiration of login token
var exp = this.adalContext._getItem(this.adalContext.CONSTANTS.STORAGE.EXPIRATION_KEY + this.adalContext.config.loginResource);
// Either wait until the refresh window is valid or refresh in 1 second (measured in seconds)
var timerDelay = exp - this.now() - (this.adalContext.config.expireOffsetSeconds || 300) > 0 ? exp - this.now() - (this.adalContext.config.expireOffsetSeconds || 300) : 1;
if (this.loginRefreshTimer) {
this.loginRefreshTimer.unsubscribe();
}
var loginRefreshTimerFn = function () {
_this_1.loginRefreshTimer = timer_1.timer(timerDelay * 1000)
.pipe(operators_1.first())
.subscribe(function (x) {
_this_1.refreshLoginToken();
});
};
// FIXME : Injector nor NgZone can't be injected in the constructor => gives "Can't resolve all parameters for Adal8Service"
// try {
// const ngZone: NgZone = this.injector.get(NgZone);
// if (ngZone) {
// ngZone.runOutsideAngular(() => {
// loginRefreshTimerFn();
// });
// } else {
loginRefreshTimerFn();
// }
// } catch (e) {
// console.warn('ngZone not available :' + e);
// loginRefreshTimerFn();
// }
};
Adal8Service = __decorate([
core_1.Injectable()
], Adal8Service);
return Adal8Service;
}());
exports.Adal8Service = Adal8Service;