accountant-ui/src/login/authInterceptor.ts

93 lines
2.4 KiB
TypeScript
Raw Normal View History

2017-08-01 23:51:52 +02:00
// vim: set tw=80 ts=2 sw=2 sts=2 :
2017-08-04 08:32:49 +02:00
import { Injectable, Injector } from '@angular/core';
2017-08-01 23:51:52 +02:00
import {
HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpErrorResponse
} from '@angular/common/http';
import { Observable} from 'rxjs/Rx';
2017-08-04 08:32:49 +02:00
import 'rxjs/add/operator/catch';
2017-08-01 23:51:52 +02:00
import { Logger } from '@nsalaun/ng-logger';
import { LoginService } from './login.service';
2017-08-04 08:32:49 +02:00
import { Token } from './token';
2017-08-01 23:51:52 +02:00
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
2017-08-04 08:32:49 +02:00
private observable: Observable<Token>;
2017-08-01 23:51:52 +02:00
constructor(
private logger: Logger,
2017-08-04 08:32:49 +02:00
private injector: Injector,
2017-08-01 23:51:52 +02:00
) {}
2017-08-04 08:32:49 +02:00
injectAuthorizationHeader(request: HttpRequest<any>, accessToken: string) {
this.logger.log('Injecting Authorization header');
return request;
}
2017-08-01 23:51:52 +02:00
intercept(
2017-08-04 08:32:49 +02:00
request: HttpRequest<any>,
next: HttpHandler,
pass?: number
2017-08-01 23:51:52 +02:00
): Observable<HttpEvent<any>> {
2017-08-04 08:32:49 +02:00
if(!pass) {
pass = 1;
}
2017-08-01 23:51:52 +02:00
2017-08-04 08:32:49 +02:00
let loginService = this.injector.get(LoginService);
2017-08-01 23:51:52 +02:00
2017-08-04 08:32:49 +02:00
if(request.url == loginService.url) {
this.logger.log("Login URL, do not handle.");
return next.handle(request);
2017-08-01 23:51:52 +02:00
}
2017-08-04 08:32:49 +02:00
this.logger.log(`Intercepted request, pass #${pass}`, request, next);
let accessToken = loginService.accessToken;
if(accessToken){
request = request.clone({
headers: request.headers.set('Authorization', `Bearer ${accessToken}`)
});
}
2017-08-01 23:51:52 +02:00
2017-08-04 08:32:49 +02:00
this.logger.log('Request', request);
let observable: Observable<any> = next.handle(request);
return observable.catch(
(error, caught): Observable<any> => {
this.logger.error("Error", error, caught);
if(!(error instanceof HttpErrorResponse) || error.status != 401) {
return Observable.throw(error);
}
this.logger.log('Unauthorized', error);
if(pass === 3) {
return Observable.throw(error);
}
if(!this.observable) {
this.logger.log("No current login observable.")
this.observable = loginService.login();
2017-08-01 23:51:52 +02:00
}
2017-08-04 08:32:49 +02:00
return this.observable.flatMap((token: Token): Observable<HttpEvent<any>> => {
this.logger.log("Logged in, access_token:", token.access_token);
this.observable = null;
return this.intercept(request, next, ++pass);
}).catch((error) => {
this.observable = null;
return Observable.throw(error);
});
2017-08-01 23:51:52 +02:00
}
);
}
}