93 lines
2.4 KiB
TypeScript
93 lines
2.4 KiB
TypeScript
// vim: set tw=80 ts=2 sw=2 sts=2 :
|
|
|
|
import { Injectable, Injector } from '@angular/core';
|
|
import {
|
|
HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpErrorResponse
|
|
} from '@angular/common/http';
|
|
|
|
import { Observable} from 'rxjs/Rx';
|
|
import 'rxjs/add/operator/catch';
|
|
|
|
import { Logger } from '@nsalaun/ng-logger';
|
|
|
|
import { LoginService } from './login.service';
|
|
import { Token } from './token';
|
|
|
|
@Injectable()
|
|
export class AuthInterceptor implements HttpInterceptor {
|
|
private observable: Observable<Token>;
|
|
|
|
constructor(
|
|
private logger: Logger,
|
|
private injector: Injector,
|
|
) {}
|
|
|
|
injectAuthorizationHeader(request: HttpRequest<any>, accessToken: string) {
|
|
this.logger.log('Injecting Authorization header');
|
|
|
|
return request;
|
|
}
|
|
|
|
intercept(
|
|
request: HttpRequest<any>,
|
|
next: HttpHandler,
|
|
pass?: number
|
|
): Observable<HttpEvent<any>> {
|
|
if(!pass) {
|
|
pass = 1;
|
|
}
|
|
|
|
let loginService = this.injector.get(LoginService);
|
|
|
|
if(request.url == loginService.url) {
|
|
this.logger.log("Login URL, do not handle.");
|
|
|
|
return next.handle(request);
|
|
}
|
|
|
|
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}`)
|
|
});
|
|
}
|
|
|
|
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();
|
|
}
|
|
|
|
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);
|
|
});
|
|
}
|
|
);
|
|
}
|
|
}
|