diff --git a/.gitignore b/.gitignore index b1da8aa..28d9091 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,3 @@ src/**/*.js src/**/*.map .tmp test-built -typings diff --git a/.idea/angular2-adal.iml b/.idea/angular2-adal.iml new file mode 100644 index 0000000..24643cc --- /dev/null +++ b/.idea/angular2-adal.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/dictionaries/corey.xml b/.idea/dictionaries/corey.xml new file mode 100644 index 0000000..493f1a9 --- /dev/null +++ b/.idea/dictionaries/corey.xml @@ -0,0 +1,7 @@ + + + + adal + + + \ No newline at end of file diff --git a/.idea/jsLibraryMappings.xml b/.idea/jsLibraryMappings.xml new file mode 100644 index 0000000..b8387eb --- /dev/null +++ b/.idea/jsLibraryMappings.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..e01539a --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..7b19f12 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/typescript-compiler.xml b/.idea/typescript-compiler.xml new file mode 100644 index 0000000..aee2d0c --- /dev/null +++ b/.idea/typescript-compiler.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..8dd6f59 --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,438 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + this.adalService.acquireToken + adalService.acquireToken + + + $PROJECT_DIR$/src + + + + + + + + + + + + + false + + false + false + + + true + + + $PROJECT_DIR$/gulpfile.js + + + DEFINITION_ORDER + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + project + + + + + + + + + + + + + + + + project + + + true + + + + DIRECTORY + + false + + + + + + + + + 1487869027299 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.npmignore b/.npmignore index cff501b..a65b9e8 100644 --- a/.npmignore +++ b/.npmignore @@ -7,4 +7,3 @@ src/**/*.js src/**/*.map .tmp test-built -typings diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..ccdda08 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "typescript.check.workspaceVersion": false +} \ No newline at end of file diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 906e6e7..0000000 --- a/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2016 Zhuyun DAI - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/README.md b/README.md index 54375fc..222c139 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,43 @@ -# angular2-adal +# ng2-adal + +`master` branch of this repo is now Angular 4+ compatible. Thanks to @Cyberdada. +For Angular2, I have created a separate `Angular 2` branch. NPM package starting from version 2.0 is for Angular 4. Packages 1.x are for Angular 2. + +**BREAKING CHANGE**: Make sure you're importing AdalService like this: `import { AdalService } from "ng2-adal/dist/core"` + +**Note**: NPM package 1.02 is also Angular 4 and was published by mistake, you can ignore that one + To do authentication against Microsoft Windows Azure AD, using the Microsoft ADAL library underneath. Note this library is extracted from the adal-angular package. -NPM Package: https://www.npmjs.com/package/angular2-adal +This also provide `AuthHttp` class, which actually gets token in background for external webapis. + +NPM Package: https://www.npmjs.com/package/ng2-adal + +Example and guideline: +https://github.com/ranveeraggarwal/angular-adal-quickstart (An example for Angular 4 is on master - Angular 2 has its own branch) + +Pop-Up example : https://github.com/mazhisai/ng2-adal-QuickStart + +**BREAKING CHANGE ** +Usage Http Interceptor + +import { HTTP_INTERCEPTORS } from '@angular/common/http'; +import { AuthHttpInterceptor} from 'ng2-adal/dist/core'; + +Then in the providers section add: +{ + provide: HTTP_INTERCEPTORS, + useClass: AuthHttpInterceptor, + multi: true +} + +Do a http request / service example: (Replace the old AuthHttp with the normal HttpClient in your constructor) + constructor( + private router: Router, + private authHttp: HttpClient // AuthHttp = old + ) { } -Example and guideline: https://github.com/alenny/angular2-adal-example + public gettest(): Observable { + return this.authHttp.get('https://yoururl.com'); + } \ No newline at end of file diff --git a/assets/readme.npm.tmpl.md b/assets/readme.npm.tmpl.md index 9cc503d..b7e978c 100644 --- a/assets/readme.npm.tmpl.md +++ b/assets/readme.npm.tmpl.md @@ -1,8 +1,10 @@ # <%= pkg.name %> (https://travis-ci.org/salemdar/angular2-cookie) [![npm version](https://badge.fury.io/js/angular2-cookie.svg)](http://badge.fury.io/js/angular2-cookie) [![Downloads](http://img.shields.io/npm/dm/angular2-adal.svg)](https://npmjs.org/package/angular2-adal) -> <%= pkg.description %> **v<%= pkg.version %>** +> <%= pkg.description %> -_Upgraded to Angular2 release candidates._ +_Latest Version **v<%= pkg.version %>** + +_Upgraded to Angular 4._ ## Table of contents: - [Get Started](#get-started) @@ -30,10 +32,10 @@ You can install this package locally with npm. ```bash # To get the latest stable version and update package.json file: -npm install angular2-adal --save +npm install ng2-adal --save ``` -After installing the library, you need to include angular2-adal and adal in the SystemJS configurations. +After installing the library, you need to include ng2-adal and adal in the SystemJS configurations. ```javascript /** @@ -47,7 +49,7 @@ After installing the library, you need to include angular2-adal and adal in the 'angular2-in-memory-web-api': 'lib/angular2-in-memory-web-api', 'rxjs': 'lib/rxjs', 'angular2-cookie': 'lib/angular2-cookie', - 'angular2-adal': 'lib/angular2-adal', + 'ng2-adal': 'lib/ng2-adal', 'adal': 'lib/adal-angular/lib' }; // packages tells the System loader how to load when no filename and/or no extension @@ -56,7 +58,7 @@ After installing the library, you need to include angular2-adal and adal in the 'rxjs': { defaultExtension: 'js' }, 'angular2-in-memory-web-api': { defaultExtension: 'js' }, 'angular2-cookie': { main: 'core.js', defaultExtension: 'js' }, - 'angular2-adal': { main: 'core.js', defaultExtension: 'js' }, + 'ng2-adal': { main: 'core.js', defaultExtension: 'js' }, 'adal': { main: 'adal.js', defaultExtension: 'js' } }; var ngPackageNames = [ @@ -85,7 +87,7 @@ After installing the library, you need to include angular2-adal and adal in the To enable building TypeScript, you need to add ADAL library definitions to typings/index.d.ts. ```typescript -/// +/// /// /// ``` diff --git a/gulp/bundle.js b/gulp/bundle.js index 8b21dac..2e5f7d1 100644 --- a/gulp/bundle.js +++ b/gulp/bundle.js @@ -12,30 +12,29 @@ const bundleConfig = { path.join('.', 'node_modules', '@angular', '*', 'package.json') ], paths: { - 'angular2-adal/*': '*', + 'npm:': './node_modules/', + 'ng2-adal/*': '*', '@angular/*': './node_modules/@angular/*', - 'adal.js': './node_modules/adal-angular/lib/adal.js', + 'adal-angular': './node_modules/adal-angular/lib/adal.js', '*': './node_modules/*' }, + map: { + '@angular/core': 'npm:@angular/core/bundles/core.umd.js', + '@angular/common': 'npm:@angular/common/bundles/common.umd.js', + '@angular/common/http': 'npm:@angular/common/bundles/common-http.umd.js', + '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js', + '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js', + 'tslib': 'npm:tslib', + 'rxjs': 'npm:rxjs' + }, packages: { - '@angular/core': { - main: 'index.js', - defaultExtension: 'js' - }, - '@angular/compiler': { - main: 'index.js', - defaultExtension: 'js' - }, - '@angular/common': { - main: 'index.js', - defaultExtension: 'js' - }, - '@angular/platform-browser': { - main: 'index.js', + + 'rxjs': { + main: 'Rx.js', defaultExtension: 'js' }, - rxjs: { - main: 'Rx.js', + 'tslib': { + main: 'tslib.js', defaultExtension: 'js' } } @@ -43,7 +42,8 @@ const bundleConfig = { function bundle(moduleName, moduleBundleName, minify, done) { const outputConfig = { - sourceMaps: true, minify + sourceMaps: true, + minify }; const builder = new Builder(bundleConfig); const outputFile = @@ -56,11 +56,11 @@ function bundle(moduleName, moduleBundleName, minify, done) { } gulp.task('bundle:cjs', ['scripts:cjs'], (done) => { - bundle('angular2-adal/core', 'angular2-adal', false, done); + bundle('ng2-adal/core', 'ng2-adal', false, done); }); gulp.task('bundle:cjs:min', ['scripts:cjs'], (done) => { - bundle('angular2-adal/core', 'angular2-adal', true, done); + bundle('ng2-adal/core', 'ng2-adal', true, done); }); -gulp.task('bundle', ['bundle:cjs', 'bundle:cjs:min']); +gulp.task('bundle', ['bundle:cjs', 'bundle:cjs:min']); \ No newline at end of file diff --git a/gulp/clean.js b/gulp/clean.js index 7d003f4..ee68830 100644 --- a/gulp/clean.js +++ b/gulp/clean.js @@ -2,6 +2,6 @@ const gulp = require('gulp'); const del = require('del'); const config = require('./config'); -gulp.task('clean:dist', (done) => del([config.PATHS.dist.base], done)); +gulp.task('clean:dist', (done) => del([config.PATHS.dist.base + "/*"], done)); gulp.task('clean', ['clean:dist']); \ No newline at end of file diff --git a/gulp/scripts.js b/gulp/scripts.js index 8a13d75..ba5a689 100644 --- a/gulp/scripts.js +++ b/gulp/scripts.js @@ -28,9 +28,9 @@ const taskConfigCjs = $.typescript.createProject(config.PATHS.tsConfig, { }); gulp.task('scripts:cjs', () => { - const tsResult = gulp.src([config.PATHS.tsSrcFiles, 'typings/index.d.ts']) + const tsResult = gulp.src([config.PATHS.tsSrcFiles]) .pipe($.sourcemaps.init()) - .pipe($.typescript(taskConfigCjs)); + .pipe(taskConfigCjs()); return merge([ tsResult.dts .pipe($.header(banner, { pkg: config.pkg })), diff --git a/package.json b/package.json index 6712914..ea746c3 100644 --- a/package.json +++ b/package.json @@ -1,59 +1,68 @@ { - "name": "angular2-adal", - "version": "0.1.4", - "description": "Use Azure AD Library - ADAL in Angular 2", - "repository": { - "type": "git", - "url": "git+https://github.com/alenny/angular2-adal.git" - }, - "keywords": [ - "angular2", - "ng2", - "adal", - "azure", - "ad", - "angular2-adal", - "ng2-adal", - "adal-angular2", - "adal-ng2" - ], - "author": "Zhuyun Dai", - "license": "MIT", - "bugs": { - "url": "https://github.com/alenny/angular2-adal/issues" - }, - "homepage": "https://github.com/alenny/angular2-adal#readme", - "engines": { - "node": ">=5.0.0" - }, - "scripts": { - "postinstall": "typings install" - }, - "dependencies": { - "@angular/common": "^2.0.0-rc.1", - "@angular/compiler": "^2.0.0-rc.1", - "@angular/core": "^2.0.0-rc.1", - "@angular/platform-browser": "^2.0.0-rc.1", - "reflect-metadata": "^0.1.3", - "rxjs": "5.0.0-beta.6", - "zone.js": "^0.6.12", - "adal-angular": "1.0.10" - }, - "devDependencies": { - "gulp": "^3.9.1", - "gulp-typescript": "^2.13.6", - "gulp-sourcemaps": "^1.6.0", - "gulp-header": "^1.8.2", - "gulp-load-plugins": "^1.2.4", - "gulp-git": "^1.8.0", - "gulp-rename": "^1.2.2", - "gulp-template": "^4.0.0", - "del": "^2.2.0", - "typescript": "^1.8.10", - "typings": "^1.0.4", - "require-dir": "^0.3.0", - "run-sequence": "^1.2.1", - "systemjs-builder": "^0.15.19", - "merge2": "^1.0.2" - } + "name": "ng2-adal", + "version": "3.0.0", + "description": "Use Azure AD Library - ADAL in Angular 4 & 2. For Angular 4, use latest version 1.x.x. For Angular 2 use 0.3.1 version. For Angular 5 use version 3.x.x", + "repository": { + "type": "git", + "url": "git+https://github.com/sureshchahal/angular2-adal.git" + }, + "keywords": [ + "angular2", + "ng2", + "adal", + "azure", + "ad", + "angular2-adal", + "ng2-adal", + "adal-angular2", + "adal-ng2", + "ng4-adal", + "angular4", + "ng4", + "angular4-adal", + "adal-angular4" + ], + "author": "Suresh Chahal", + "license": "MIT", + "bugs": { + "url": "https://github.com/sureshchahal/angular2-adal/issues" + }, + "homepage": "https://github.com/sureshchahal/angular2-adal#readme", + "engines": { + "node": ">=5.0.0" + }, + "scripts": { + "gulp": "gulp" + }, + "dependencies": { + "@angular/common": "^5.0.3", + "@angular/compiler": "^5.0.3", + "@angular/core": "^5.0.3", + "@angular/http": "^5.0.3", + "@angular/platform-browser": "^5.0.3", + "@types/adal": "^1.0.29", + "adal-angular": "^1.0.15", + "reflect-metadata": "^0.1.10", + "rxjs": "^5.5.2", + "zone.js": "^0.8.18" + }, + "devDependencies": { + "del": "^2.2.0", + "gulp": "^3.9.1", + "gulp-git": "^1.8.0", + "gulp-header": "^1.8.2", + "gulp-load-plugins": "^1.2.4", + "gulp-rename": "^1.2.2", + "gulp-resolve-dependencies": "^2.2.0", + "gulp-sourcemaps": "^1.6.0", + "gulp-template": "^4.0.0", + "gulp-typescript": "^3.1.3", + "gulp-util": "^3.0.8", + "merge2": "^1.0.2", + "require-dir": "^0.3.0", + "run-sequence": "^1.2.1", + "systemjs-builder": "^0.16.3", + "typescript": "^2.5.2", + "typings": "^2.1.1" + } } \ No newline at end of file diff --git a/src/adal-angular/index.d.ts b/src/adal-angular/index.d.ts new file mode 100644 index 0000000..387cc9e --- /dev/null +++ b/src/adal-angular/index.d.ts @@ -0,0 +1,28 @@ +declare module 'adal-angular' { + export function inject(config: adal.Config): adal.AuthenticationContext; +} + +declare namespace adal { + interface AuthenticationContext { + REQUEST_TYPE: { + LOGIN: string, + RENEW_TOKEN: string, + UNKNOWN: string + }; + + callback : any; + + _getItem : any; + + _renewFailed : any; + + CONSTANTS : any; + } + +} + +interface Window { + AuthenticationContext : any; + callBackMappedToRenewStates : any; +} + diff --git a/src/core.ts b/src/core.ts index 7f0dfab..74ac12f 100644 --- a/src/core.ts +++ b/src/core.ts @@ -1,8 +1,3 @@ -import {provide} from "@angular/core"; -import {AdalService} from './services'; - -export * from './services'; - -export const ANGULAR2_ADAL_PROVIDERS: any[] = [ - provide(AdalService, {useClass: AdalService}) -]; \ No newline at end of file +export { AdalService, OAuthData } from './services'; +export { AdalModule, AuthHttpModule } from './modules'; +export { AuthHttpInterceptor } from './interceptors'; diff --git a/src/interceptors.ts b/src/interceptors.ts new file mode 100644 index 0000000..8e2571e --- /dev/null +++ b/src/interceptors.ts @@ -0,0 +1 @@ +export {AuthHttpInterceptor} from './interceptors/authHttp.interceptor'; \ No newline at end of file diff --git a/src/interceptors/authHttp.interceptor.ts b/src/interceptors/authHttp.interceptor.ts new file mode 100644 index 0000000..afe275f --- /dev/null +++ b/src/interceptors/authHttp.interceptor.ts @@ -0,0 +1,59 @@ +import { Injectable } from '@angular/core'; +import { HttpRequest, HttpHandler, HttpEvent, HttpHeaders, HttpInterceptor} from '@angular/common/http'; +import { AdalService } from 'ngx-adal-test/services/adal.service'; +import { Observable } from 'rxjs/Observable'; +import 'rxjs/add/operator/catch'; +import 'rxjs/add/operator/mergeMap'; +import 'rxjs/add/observable/throw'; + + +@Injectable() +export class AuthHttpInterceptor implements HttpInterceptor { + private authHeaders: HttpHeaders; + constructor( + private adalService: AdalService, + ) { + } + + private _setAuthHeaders(access_token: any, token_type = 'Bearer') { + this.authHeaders = new HttpHeaders(); + this.authHeaders = this.authHeaders.append('Authorization', token_type + ' ' + access_token); + this.authHeaders = this.authHeaders.append('Content-Type', 'application/json'); + } + + handleInterception( + token: string, + request: HttpRequest, + next: HttpHandler + ) { + if (this.adalService.userInfo.isAuthenticated) { + // setting authHeaders + this._setAuthHeaders(token); + request = request.clone({ + headers: this.authHeaders + }); + } else { + throw new Error('User Not Authenticated.'); + } + return next.handle(request).catch(this.handleError); + } + intercept(request: HttpRequest, next: HttpHandler): Observable> { + const resource: any = this.adalService.GetResourceForEndpoint(request.url); + const token: any = this.adalService.acquireToken(resource); + if (resource) { + if (token instanceof Observable) { + return token.mergeMap((asyncToken: string) => { + return this.handleInterception(asyncToken, request, next); + }); + } else { + return this.handleInterception(token, request, next); + } + } else { + return next.handle(request); + } + } + + private handleError(error: any) { + return Observable.throw(error); + } +} diff --git a/src/modules.ts b/src/modules.ts new file mode 100644 index 0000000..418040e --- /dev/null +++ b/src/modules.ts @@ -0,0 +1,2 @@ +export { AdalModule } from './modules/adal.module'; +export { AuthHttpModule } from './modules/authHttp.module'; \ No newline at end of file diff --git a/src/modules/adal.module.ts b/src/modules/adal.module.ts new file mode 100644 index 0000000..6d53781 --- /dev/null +++ b/src/modules/adal.module.ts @@ -0,0 +1,11 @@ +import { NgModule } from '@angular/core'; + +import { AdalService } from './../services/adal.service'; + +@NgModule({ + imports: [], + exports: [], + declarations: [], + providers: [AdalService], +}) +export class AdalModule { } diff --git a/src/modules/authHttp.module.ts b/src/modules/authHttp.module.ts new file mode 100644 index 0000000..57b4008 --- /dev/null +++ b/src/modules/authHttp.module.ts @@ -0,0 +1,17 @@ +import { NgModule } from '@angular/core'; + +import { AdalModule } from './adal.module'; +import { HTTP_INTERCEPTORS } from '@angular/common/http' +import { AuthHttpInterceptor } from './../interceptors/authHttp.interceptor' + +@NgModule({ + imports: [AdalModule], + exports: [], + declarations: [], + providers: [ { + provide: HTTP_INTERCEPTORS, + useClass: AuthHttpInterceptor, + multi: true + }], +}) +export class AuthHttpModule { } diff --git a/src/services/adal.service.ts b/src/services/adal.service.ts index f643b77..a39054b 100644 --- a/src/services/adal.service.ts +++ b/src/services/adal.service.ts @@ -1,18 +1,21 @@ -import {Injectable} from '@angular/core'; -import 'rxjs/Rx'; -import {Observable} from "rxjs/Observable"; -import adalLib = require('adal'); -import {OAuthData} from "./oauthdata.model"; +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs/Observable'; +import { BehaviorSubject } from 'rxjs/BehaviorSubject'; +import 'rxjs/add/observable/bindCallback'; +import * as adalLib from 'adal-angular'; +import { OAuthData } from './oauthdata.model'; +import User = adal.User; @Injectable() export class AdalService { - + private authenticationStatus = new BehaviorSubject(false); private adalContext: adal.AuthenticationContext; private oauthData: OAuthData = { isAuthenticated: false, userName: '', loginError: '', - profile: {} + profile: {}, + authenticationStatus: this.authenticationStatus.asObservable(), }; public init(configOptions: adal.Config) { @@ -21,8 +24,8 @@ export class AdalService { } // redirect and logout_redirect are set to current location by default - var existingHash = window.location.hash; - var pathDefault = window.location.href; + let existingHash = window.location.hash; + let pathDefault = window.location.href; if (existingHash) { pathDefault = pathDefault.replace(existingHash, ''); } @@ -33,6 +36,8 @@ export class AdalService { // create instance with given config this.adalContext = adalLib.inject(configOptions); + window.AuthenticationContext = this.adalContext.constructor; + // loginresource is used to set authenticated status this.updateDataFromCache(this.adalContext.config.loginResource); } @@ -64,7 +69,28 @@ export class AdalService { this.adalContext.saveTokenFromHash(requestInfo); if (requestInfo.requestType === this.adalContext.REQUEST_TYPE.LOGIN) { this.updateDataFromCache(this.adalContext.config.loginResource); + } else if (requestInfo.requestType === this.adalContext.REQUEST_TYPE.RENEW_TOKEN) { + this.adalContext.callback = window.parent.callBackMappedToRenewStates[requestInfo.stateResponse]; + } + + if (requestInfo.stateMatch) { + if (typeof this.adalContext.callback === 'function') { + if (requestInfo.requestType === this.adalContext.REQUEST_TYPE.RENEW_TOKEN) { + // Idtoken or Accestoken can be renewed + if (requestInfo.parameters['access_token']) { + this.adalContext.callback(this.adalContext._getItem(this.adalContext.CONSTANTS.STORAGE.ERROR_DESCRIPTION) + , requestInfo.parameters['access_token']); + } else if (requestInfo.parameters['id_token']) { + this.adalContext.callback(this.adalContext._getItem(this.adalContext.CONSTANTS.STORAGE.ERROR_DESCRIPTION) + , requestInfo.parameters['id_token']); + } + else if (requestInfo.parameters['error']) { + this.adalContext.callback(this.adalContext._getItem(this.adalContext.CONSTANTS.STORAGE.ERROR_DESCRIPTION), null); + this.adalContext._renewFailed = true; + } + } + } } } } @@ -74,21 +100,36 @@ export class AdalService { } public acquireToken(resource: string) { - return Observable.bindCallback(function (cb) { - this.adalContext.acquireToken(resource, function (error: string, tokenOut: string) { + let _this = this; // save outer this for inner function + + let errorMessage: string; + return Observable.bindCallback(acquireTokenInternal, function (token: string) { + if (!token && errorMessage) { + throw (errorMessage); + } + return token; + })(); + + function acquireTokenInternal(cb: any): string { + let s: string = ''; + + _this.adalContext.acquireToken(resource, (error: string, tokenOut: string) => { if (error) { - this.adalContext.error('Error when acquiring token for resource: ' + resource, error); - cb(null); + _this.adalContext.error('Error when acquiring token for resource: ' + resource, error); + errorMessage = error; + cb(null); } else { cb(tokenOut); + s = tokenOut; } }); - }); + return s; + } } public getUser(): Observable { - return Observable.bindCallback(function (cb: (u: adal.User) => void) { - this.adalContext.getUser(function (error: string, user: adal.User) { + return Observable.bindCallback((cb: (u: adal.User) => User) => { + this.adalContext.getUser((error: string, user: adal.User) => { if (error) { this.adalContext.error('Error when getting user', error); cb(null); @@ -115,18 +156,22 @@ export class AdalService { this.adalContext.verbose(message); } + public GetResourceForEndpoint(url: string): string { + return this.adalContext.getResourceForEndpoint(url); + } + + public refreshDataFromCache() { + this.updateDataFromCache(this.adalContext.config.loginResource); + } + private updateDataFromCache(resource: string): void { let token = this.adalContext.getCachedToken(resource); this.oauthData.isAuthenticated = token !== null && token.length > 0; - var user = this.adalContext.getCachedUser(); - if (user) { - this.oauthData.userName = user.userName; - this.oauthData.profile = user.profile; - this.oauthData.loginError = this.adalContext.getLoginError(); - } else { - this.oauthData.userName = ''; - this.oauthData.profile = {}; - this.oauthData.loginError = ''; - } + let user = this.adalContext.getCachedUser() || { userName: '', profile: undefined }; + this.oauthData.userName = user.userName; + this.oauthData.profile = user.profile; + this.oauthData.loginError = this.adalContext.getLoginError(); + this.authenticationStatus.next(this.oauthData.isAuthenticated); + }; } diff --git a/src/services/oauthdata.model.ts b/src/services/oauthdata.model.ts index 682b83d..24f2e8b 100644 --- a/src/services/oauthdata.model.ts +++ b/src/services/oauthdata.model.ts @@ -1,5 +1,8 @@ +import { Observable } from "rxjs/Observable"; + export interface OAuthData { isAuthenticated: boolean; + authenticationStatus: Observable; userName: string; loginError: string; profile: any; diff --git a/tsconfig.json b/tsconfig.json index 08b805a..bc5ba76 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,15 +3,24 @@ "module": "commonjs", "target": "es5", "noImplicitAny": true, + "noImplicitThis": true, "experimentalDecorators": true, "outDir": "dist/", "rootDir": "src/", "sourceMap": true, - "removeComments": false + "removeComments": false, + "lib": [ + "es2015", + "dom" + ], + "types": [ + "adal" + ] }, "exclude": [ "node_modules", "gulp", "dist" - ] -} \ No newline at end of file + ], + "skipLibCheck": true +} diff --git a/typings.json b/typings.json deleted file mode 100644 index 4fca66e..0000000 --- a/typings.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "name": "angular2-adal", - "main": "index.d.ts", - "author": "Zhuyun Dai", - "description": "Use Azure AD Library - ADAL in Angular 2", - "globalDependencies": { - "core-js": "registry:dt/core-js#0.0.0+20160317120654", - "jasmine": "registry:dt/jasmine#2.2.0+20160505161446" - } -}