microsoft-adal-angular6
Version:
This is a wrapper library for Angular 6 (Angular 6.X.X and Angular 7.X.X) modules over Microsoft ADAL (Azure Active Directory Authentication Library)
243 lines (236 loc) • 16.7 kB
JavaScript
import { Injectable, Inject, NgModule, defineInjectable, inject as inject$1 } from '@angular/core';
import { bindCallback } from 'rxjs';
import { inject } from 'adal-angular';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
class MsAdalAngular6Service {
/**
* @param {?} adalConfig
*/
constructor(adalConfig) {
this.adalConfig = adalConfig;
if (typeof adalConfig === 'function') {
this.adalConfig = adalConfig();
}
this.context = inject(this.adalConfig);
this.handleCallback();
}
/**
* @return {?}
*/
get LoggedInUserEmail() {
if (this.isAuthenticated) {
return this.context.getCachedUser().userName;
}
return '';
}
/**
* @return {?}
*/
get LoggedInUserName() {
if (this.isAuthenticated) {
return this.context.getCachedUser().profile.name;
}
return '';
}
/**
* @return {?}
*/
login() {
this.context.login();
}
/**
* @return {?}
*/
logout() {
this.context.logOut();
}
/**
* @param {?} url
* @return {?}
*/
GetResourceForEndpoint(url) {
let /** @type {?} */ resource = null;
if (url) {
resource = this.context.getResourceForEndpoint(url);
if (!resource) {
resource = this.adalConfig.clientId;
}
}
return resource;
}
/**
* @param {?} url
* @return {?}
*/
RenewToken(url) {
let /** @type {?} */ resource = this.GetResourceForEndpoint(url);
return this.context.clearCacheForResource(resource); // Trigger the ADAL token renew
}
/**
* @param {?} url
* @return {?}
*/
acquireToken(url) {
const /** @type {?} */ _this = this; // save outer this for inner function
let /** @type {?} */ errorMessage;
return bindCallback(acquireTokenInternal, (token) => {
if (!token && errorMessage) {
throw (errorMessage);
}
return token;
})();
/**
* @param {?} cb
* @return {?}
*/
function acquireTokenInternal(cb) {
let /** @type {?} */ s = null;
let /** @type {?} */ resource;
resource = _this.GetResourceForEndpoint(url);
_this.context.acquireToken(resource, (error, tokenOut) => {
if (error) {
_this.context.error('Error when acquiring token for resource: ' + resource, error);
errorMessage = error;
cb(/** @type {?} */ (null));
}
else {
cb(tokenOut);
s = tokenOut;
}
});
return s;
}
}
/**
* @param {?} url
* @return {?}
*/
getToken(url) {
const /** @type {?} */ resource = this.context.getResourceForEndpoint(url);
const /** @type {?} */ storage = this.adalConfig.cacheLocation;
let /** @type {?} */ key;
if (resource) {
key = 'adal.access.token.key' + resource;
}
else {
key = 'adal.idtoken';
}
if (storage === 'localStorage') {
return localStorage.getItem(key);
}
else {
return sessionStorage.getItem(key);
}
}
/**
* @return {?}
*/
handleCallback() {
this.context.handleWindowCallback();
}
/**
* @return {?}
*/
get userInfo() {
return this.context.getCachedUser();
}
/**
* @return {?}
*/
get accessToken() {
return this.context.getCachedToken(this.adalConfig.clientId);
}
/**
* @return {?}
*/
get isAuthenticated() {
return (this.userInfo && this.accessToken) ? true : false;
}
}
MsAdalAngular6Service.decorators = [
{ type: Injectable, args: [{
providedIn: 'root'
},] },
];
/** @nocollapse */
MsAdalAngular6Service.ctorParameters = () => [
{ type: undefined, decorators: [{ type: Inject, args: ['adalConfig',] },] },
];
/** @nocollapse */ MsAdalAngular6Service.ngInjectableDef = defineInjectable({ factory: function MsAdalAngular6Service_Factory() { return new MsAdalAngular6Service(inject$1("adalConfig")); }, token: MsAdalAngular6Service, providedIn: "root" });
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
class AuthenticationGuard {
/**
* @param {?} adalSvc
*/
constructor(adalSvc) {
this.adalSvc = adalSvc;
}
/**
* @param {?} route
* @param {?} state
* @return {?}
*/
canActivate(route, state) {
if (this.adalSvc.isAuthenticated) {
return true;
}
else {
this.adalSvc.login();
return false;
}
}
/**
* @param {?} childRoute
* @param {?} state
* @return {?}
*/
canActivateChild(childRoute, state) {
return this.canActivate(childRoute, state);
}
}
AuthenticationGuard.decorators = [
{ type: Injectable },
];
/** @nocollapse */
AuthenticationGuard.ctorParameters = () => [
{ type: MsAdalAngular6Service, },
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
class MsAdalAngular6Module {
/**
* @param {?} adalConfig
* @return {?}
*/
static forRoot(adalConfig) {
return {
ngModule: MsAdalAngular6Module,
providers: [MsAdalAngular6Service, { provide: 'adalConfig', useValue: adalConfig }]
};
}
}
MsAdalAngular6Module.decorators = [
{ type: NgModule, args: [{
imports: [],
declarations: [],
exports: []
},] },
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
export { MsAdalAngular6Service, AuthenticationGuard, MsAdalAngular6Module };
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWljcm9zb2Z0LWFkYWwtYW5ndWxhcjYuanMubWFwIiwic291cmNlcyI6WyJuZzovL21pY3Jvc29mdC1hZGFsLWFuZ3VsYXI2L3NyYy9tcy1hZGFsLWFuZ3VsYXI2LnNlcnZpY2UudHMiLCJuZzovL21pY3Jvc29mdC1hZGFsLWFuZ3VsYXI2L3NyYy9hdXRoZW50aWNhdGlvbi1ndWFyZC50cyIsIm5nOi8vbWljcm9zb2Z0LWFkYWwtYW5ndWxhcjYvc3JjL21zLWFkYWwtYW5ndWxhcjYubW9kdWxlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vLyA8cmVmZXJlbmNlIHBhdGg9Jy4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL0B0eXBlcy9hZGFsL2luZGV4LmQudHMnLz5cbmltcG9ydCB7IEluamVjdGFibGUsIEluamVjdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgYmluZENhbGxiYWNrIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgKiBhcyBhZGFsTGliIGZyb20gJ2FkYWwtYW5ndWxhcic7XG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXG59KVxuZXhwb3J0IGNsYXNzIE1zQWRhbEFuZ3VsYXI2U2VydmljZSB7XG4gIHByaXZhdGUgY29udGV4dDogYWRhbC5BdXRoZW50aWNhdGlvbkNvbnRleHQ7XG5cbiAgY29uc3RydWN0b3IoQEluamVjdCgnYWRhbENvbmZpZycpIHByaXZhdGUgYWRhbENvbmZpZzogYW55KSB7XG4gICAgaWYgKHR5cGVvZiBhZGFsQ29uZmlnID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aGlzLmFkYWxDb25maWcgPSBhZGFsQ29uZmlnKCk7XG4gICAgfSBcbiAgICB0aGlzLmNvbnRleHQgPSBhZGFsTGliLmluamVjdCh0aGlzLmFkYWxDb25maWcpO1xuICAgIHRoaXMuaGFuZGxlQ2FsbGJhY2soKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgTG9nZ2VkSW5Vc2VyRW1haWwoKSB7XG4gICAgaWYgKHRoaXMuaXNBdXRoZW50aWNhdGVkKSB7XG4gICAgICByZXR1cm4gdGhpcy5jb250ZXh0LmdldENhY2hlZFVzZXIoKS51c2VyTmFtZTtcbiAgICB9XG4gICAgcmV0dXJuICcnO1xuICB9XG5cbiAgcHVibGljIGdldCBMb2dnZWRJblVzZXJOYW1lKCkge1xuICAgIGlmICh0aGlzLmlzQXV0aGVudGljYXRlZCkge1xuICAgICAgcmV0dXJuIHRoaXMuY29udGV4dC5nZXRDYWNoZWRVc2VyKCkucHJvZmlsZS5uYW1lO1xuICAgIH1cbiAgICByZXR1cm4gJyc7XG4gIH1cblxuICBwdWJsaWMgbG9naW4oKSB7XG4gICAgdGhpcy5jb250ZXh0LmxvZ2luKCk7XG4gIH1cblxuICBwdWJsaWMgbG9nb3V0KCkge1xuICAgIHRoaXMuY29udGV4dC5sb2dPdXQoKTtcbiAgfVxuXG4gIHB1YmxpYyBHZXRSZXNvdXJjZUZvckVuZHBvaW50KHVybDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBsZXQgcmVzb3VyY2UgPSBudWxsO1xuICAgIGlmICh1cmwpIHtcbiAgICAgIHJlc291cmNlID0gdGhpcy5jb250ZXh0LmdldFJlc291cmNlRm9yRW5kcG9pbnQodXJsKTtcbiAgICAgIGlmICghcmVzb3VyY2UpIHtcbiAgICAgICAgcmVzb3VyY2UgPSB0aGlzLmFkYWxDb25maWcuY2xpZW50SWQ7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXNvdXJjZTtcbiAgfVxuXG4gIHB1YmxpYyBSZW5ld1Rva2VuKHVybDogc3RyaW5nKSB7XG4gICAgbGV0IHJlc291cmNlID0gdGhpcy5HZXRSZXNvdXJjZUZvckVuZHBvaW50KHVybCk7XG4gICAgcmV0dXJuIHRoaXMuY29udGV4dC5jbGVhckNhY2hlRm9yUmVzb3VyY2UocmVzb3VyY2UpOyAvLyBUcmlnZ2VyIHRoZSBBREFMIHRva2VuIHJlbmV3IFxuICB9XG5cbiAgcHVibGljIGFjcXVpcmVUb2tlbih1cmw6IHN0cmluZykge1xuICAgIGNvbnN0IF90aGlzID0gdGhpczsgICAvLyBzYXZlIG91dGVyIHRoaXMgZm9yIGlubmVyIGZ1bmN0aW9uXG4gICAgbGV0IGVycm9yTWVzc2FnZTogc3RyaW5nO1xuXG4gICAgcmV0dXJuIGJpbmRDYWxsYmFjayhhY3F1aXJlVG9rZW5JbnRlcm5hbCwgKHRva2VuOiBzdHJpbmcpID0+IHtcbiAgICAgIGlmICghdG9rZW4gJiYgZXJyb3JNZXNzYWdlKSB7XG4gICAgICAgIHRocm93IChlcnJvck1lc3NhZ2UpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRva2VuO1xuICAgIH0pKCk7XG5cbiAgICBmdW5jdGlvbiBhY3F1aXJlVG9rZW5JbnRlcm5hbChjYjogYW55KSB7XG4gICAgICBsZXQgczogc3RyaW5nID0gbnVsbDtcbiAgICAgIGxldCByZXNvdXJjZTogc3RyaW5nO1xuICAgICAgcmVzb3VyY2UgPSBfdGhpcy5HZXRSZXNvdXJjZUZvckVuZHBvaW50KHVybCk7XG5cbiAgICAgIF90aGlzLmNvbnRleHQuYWNxdWlyZVRva2VuKHJlc291cmNlLCAoZXJyb3I6IHN0cmluZywgdG9rZW5PdXQ6IHN0cmluZykgPT4ge1xuICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICBfdGhpcy5jb250ZXh0LmVycm9yKCdFcnJvciB3aGVuIGFjcXVpcmluZyB0b2tlbiBmb3IgcmVzb3VyY2U6ICcgKyByZXNvdXJjZSwgZXJyb3IpO1xuICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yO1xuICAgICAgICAgIGNiKG51bGwgYXMgc3RyaW5nKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjYih0b2tlbk91dCk7XG4gICAgICAgICAgcyA9IHRva2VuT3V0O1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBzO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBnZXRUb2tlbih1cmw6IHN0cmluZyk6IHN0cmluZyB7XG5cbiAgICBjb25zdCByZXNvdXJjZSA9IHRoaXMuY29udGV4dC5nZXRSZXNvdXJjZUZvckVuZHBvaW50KHVybCk7XG4gICAgY29uc3Qgc3RvcmFnZSA9IHRoaXMuYWRhbENvbmZpZy5jYWNoZUxvY2F0aW9uO1xuICAgIGxldCBrZXk7XG4gICAgaWYgKHJlc291cmNlKSB7XG4gICAgICBrZXkgPSAnYWRhbC5hY2Nlc3MudG9rZW4ua2V5JyArIHJlc291cmNlO1xuICAgIH0gZWxzZSB7XG4gICAgICBrZXkgPSAnYWRhbC5pZHRva2VuJztcbiAgICB9XG4gICAgaWYgKHN0b3JhZ2UgPT09ICdsb2NhbFN0b3JhZ2UnKSB7XG4gICAgICByZXR1cm4gbG9jYWxTdG9yYWdlLmdldEl0ZW0oa2V5KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHNlc3Npb25TdG9yYWdlLmdldEl0ZW0oa2V5KTtcbiAgICB9XG4gIH1cblxuICBoYW5kbGVDYWxsYmFjaygpIHtcbiAgICB0aGlzLmNvbnRleHQuaGFuZGxlV2luZG93Q2FsbGJhY2soKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgdXNlckluZm8oKSB7XG4gICAgcmV0dXJuIHRoaXMuY29udGV4dC5nZXRDYWNoZWRVc2VyKCk7XG4gIH1cblxuICBwdWJsaWMgZ2V0IGFjY2Vzc1Rva2VuKCkge1xuICAgIHJldHVybiB0aGlzLmNvbnRleHQuZ2V0Q2FjaGVkVG9rZW4odGhpcy5hZGFsQ29uZmlnLmNsaWVudElkKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgaXNBdXRoZW50aWNhdGVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAodGhpcy51c2VySW5mbyAmJiB0aGlzLmFjY2Vzc1Rva2VuKSA/IHRydWUgOiBmYWxzZTtcbiAgfVxufSIsImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IHsgQ2FuQWN0aXZhdGUsIENhbkFjdGl2YXRlQ2hpbGQsIEFjdGl2YXRlZFJvdXRlU25hcHNob3QsIFJvdXRlclN0YXRlU25hcHNob3QgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuaW1wb3J0IHsgTXNBZGFsQW5ndWxhcjZTZXJ2aWNlIH0gZnJvbSBcIi4vbXMtYWRhbC1hbmd1bGFyNi5zZXJ2aWNlXCI7XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBBdXRoZW50aWNhdGlvbkd1YXJkIGltcGxlbWVudHMgQ2FuQWN0aXZhdGUsIENhbkFjdGl2YXRlQ2hpbGQge1xuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgYWRhbFN2YzogTXNBZGFsQW5ndWxhcjZTZXJ2aWNlKSB7IH1cblxuICAgIHB1YmxpYyBjYW5BY3RpdmF0ZShyb3V0ZTogQWN0aXZhdGVkUm91dGVTbmFwc2hvdCwgc3RhdGU6IFJvdXRlclN0YXRlU25hcHNob3QpOiBib29sZWFuIHtcbiAgICAgICAgaWYgKHRoaXMuYWRhbFN2Yy5pc0F1dGhlbnRpY2F0ZWQpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5hZGFsU3ZjLmxvZ2luKCk7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgY2FuQWN0aXZhdGVDaGlsZChjaGlsZFJvdXRlOiBBY3RpdmF0ZWRSb3V0ZVNuYXBzaG90LCBzdGF0ZTogUm91dGVyU3RhdGVTbmFwc2hvdCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5jYW5BY3RpdmF0ZShjaGlsZFJvdXRlLCBzdGF0ZSk7XG4gICAgfVxufSIsImltcG9ydCB7IE5nTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBNb2R1bGVXaXRoUHJvdmlkZXJzIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBNc0FkYWxBbmd1bGFyNlNlcnZpY2UgfSBmcm9tICcuL21zLWFkYWwtYW5ndWxhcjYuc2VydmljZSc7XG5cbkBOZ01vZHVsZSh7XG4gIGltcG9ydHM6IFtdLFxuICBkZWNsYXJhdGlvbnM6IFtdLFxuICBleHBvcnRzOiBbXVxufSlcbmV4cG9ydCBjbGFzcyBNc0FkYWxBbmd1bGFyNk1vZHVsZSB7IFxuICBzdGF0aWMgZm9yUm9vdChhZGFsQ29uZmlnOiBhbnkpOiBNb2R1bGVXaXRoUHJvdmlkZXJzIHtcbiAgICByZXR1cm4ge1xuICAgICAgbmdNb2R1bGU6IE1zQWRhbEFuZ3VsYXI2TW9kdWxlLFxuICAgICAgcHJvdmlkZXJzOiBbTXNBZGFsQW5ndWxhcjZTZXJ2aWNlLCB7IHByb3ZpZGU6ICdhZGFsQ29uZmlnJywgdXNlVmFsdWU6IGFkYWxDb25maWcgfV1cbiAgICB9O1xuICB9XG59Il0sIm5hbWVzIjpbImFkYWxMaWIuaW5qZWN0Il0sIm1hcHBpbmdzIjoiOzs7Ozs7OztBQUNBOzs7O0lBVUUsWUFBMEM7UUFBQSxlQUFVLEdBQVYsVUFBVTtRQUNsRCxJQUFJLE9BQU8sVUFBVSxLQUFLLFVBQVUsRUFBRTtZQUNwQyxJQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsRUFBRSxDQUFDO1NBQ2hDO1FBQ0QsSUFBSSxDQUFDLE9BQU8sR0FBR0EsTUFBYyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUMvQyxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7S0FDdkI7Ozs7UUFFVSxpQkFBaUI7UUFDMUIsSUFBSSxJQUFJLENBQUMsZUFBZSxFQUFFO1lBQ3hCLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhLEVBQUUsQ0FBQyxRQUFRLENBQUM7U0FDOUM7UUFDRCxPQUFPLEVBQUUsQ0FBQzs7Ozs7UUFHRCxnQkFBZ0I7UUFDekIsSUFBSSxJQUFJLENBQUMsZUFBZSxFQUFFO1lBQ3hCLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhLEVBQUUsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDO1NBQ2xEO1FBQ0QsT0FBTyxFQUFFLENBQUM7Ozs7O0lBR0wsS0FBSztRQUNWLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLENBQUM7Ozs7O0lBR2hCLE1BQU07UUFDWCxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDOzs7Ozs7SUFHakIsc0JBQXNCLENBQUMsR0FBVztRQUN2Qyxx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