UNPKG

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
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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