diff options
Diffstat (limited to 'client/src/app/shared/auth')
-rw-r--r-- | client/src/app/shared/auth/auth-http.service.ts | 93 | ||||
-rw-r--r-- | client/src/app/shared/auth/auth-interceptor.service.ts | 62 | ||||
-rw-r--r-- | client/src/app/shared/auth/index.ts | 2 |
3 files changed, 63 insertions, 94 deletions
diff --git a/client/src/app/shared/auth/auth-http.service.ts b/client/src/app/shared/auth/auth-http.service.ts deleted file mode 100644 index 0fbaab0a8..000000000 --- a/client/src/app/shared/auth/auth-http.service.ts +++ /dev/null | |||
@@ -1,93 +0,0 @@ | |||
1 | import { Injectable } from '@angular/core' | ||
2 | import { | ||
3 | ConnectionBackend, | ||
4 | Headers, | ||
5 | Http, | ||
6 | Request, | ||
7 | RequestMethod, | ||
8 | RequestOptions, | ||
9 | RequestOptionsArgs, | ||
10 | Response, | ||
11 | XHRBackend | ||
12 | } from '@angular/http' | ||
13 | import { Observable } from 'rxjs/Observable' | ||
14 | |||
15 | import { AuthService } from '../../core' | ||
16 | |||
17 | @Injectable() | ||
18 | export class AuthHttp extends Http { | ||
19 | constructor (backend: ConnectionBackend, defaultOptions: RequestOptions, private authService: AuthService) { | ||
20 | super(backend, defaultOptions) | ||
21 | } | ||
22 | |||
23 | request (url: string | Request, options?: RequestOptionsArgs): Observable<Response> { | ||
24 | if (!options) options = {} | ||
25 | |||
26 | options.headers = new Headers() | ||
27 | this.setAuthorizationHeader(options.headers) | ||
28 | |||
29 | return super.request(url, options) | ||
30 | .catch((err) => { | ||
31 | if (err.status === 401) { | ||
32 | return this.handleTokenExpired(url, options) | ||
33 | } | ||
34 | |||
35 | return Observable.throw(err) | ||
36 | }) | ||
37 | } | ||
38 | |||
39 | delete (url: string, options?: RequestOptionsArgs): Observable<Response> { | ||
40 | if (!options) options = {} | ||
41 | options.method = RequestMethod.Delete | ||
42 | |||
43 | return this.request(url, options) | ||
44 | } | ||
45 | |||
46 | get (url: string, options?: RequestOptionsArgs): Observable<Response> { | ||
47 | if (!options) options = {} | ||
48 | options.method = RequestMethod.Get | ||
49 | |||
50 | return this.request(url, options) | ||
51 | } | ||
52 | |||
53 | post (url: string, body: any, options?: RequestOptionsArgs): Observable<Response> { | ||
54 | if (!options) options = {} | ||
55 | options.method = RequestMethod.Post | ||
56 | options.body = body | ||
57 | |||
58 | return this.request(url, options) | ||
59 | } | ||
60 | |||
61 | put (url: string, body: any, options?: RequestOptionsArgs): Observable<Response> { | ||
62 | if (!options) options = {} | ||
63 | options.method = RequestMethod.Put | ||
64 | options.body = body | ||
65 | |||
66 | return this.request(url, options) | ||
67 | } | ||
68 | |||
69 | private handleTokenExpired (url: string | Request, options: RequestOptionsArgs) { | ||
70 | return this.authService.refreshAccessToken() | ||
71 | .flatMap(() => { | ||
72 | this.setAuthorizationHeader(options.headers) | ||
73 | |||
74 | return super.request(url, options) | ||
75 | }) | ||
76 | } | ||
77 | |||
78 | private setAuthorizationHeader (headers: Headers) { | ||
79 | headers.set('Authorization', this.authService.getRequestHeaderValue()) | ||
80 | } | ||
81 | } | ||
82 | |||
83 | export function useFactory (backend: XHRBackend, defaultOptions: RequestOptions, authService: AuthService) { | ||
84 | return new AuthHttp(backend, defaultOptions, authService) | ||
85 | } | ||
86 | |||
87 | export const AUTH_HTTP_PROVIDERS = [ | ||
88 | { | ||
89 | provide: AuthHttp, | ||
90 | useFactory, | ||
91 | deps: [ XHRBackend, RequestOptions, AuthService ] | ||
92 | } | ||
93 | ] | ||
diff --git a/client/src/app/shared/auth/auth-interceptor.service.ts b/client/src/app/shared/auth/auth-interceptor.service.ts new file mode 100644 index 000000000..1e890d8f3 --- /dev/null +++ b/client/src/app/shared/auth/auth-interceptor.service.ts | |||
@@ -0,0 +1,62 @@ | |||
1 | import { Injectable, Injector } from '@angular/core' | ||
2 | import { | ||
3 | HttpInterceptor, | ||
4 | HttpRequest, | ||
5 | HttpEvent, | ||
6 | HttpHandler, HTTP_INTERCEPTORS | ||
7 | } from '@angular/common/http' | ||
8 | import { Observable } from 'rxjs/Observable' | ||
9 | |||
10 | import { AuthService } from '../../core' | ||
11 | import 'rxjs/add/operator/switchMap' | ||
12 | |||
13 | @Injectable() | ||
14 | export class AuthInterceptor implements HttpInterceptor { | ||
15 | private authService: AuthService | ||
16 | |||
17 | // https://github.com/angular/angular/issues/18224#issuecomment-316957213 | ||
18 | constructor (private injector: Injector) {} | ||
19 | |||
20 | intercept (req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { | ||
21 | if (this.authService === undefined) { | ||
22 | this.authService = this.injector.get(AuthService) | ||
23 | } | ||
24 | |||
25 | const authReq = this.cloneRequestWithAuth(req) | ||
26 | |||
27 | // Pass on the cloned request instead of the original request | ||
28 | // Catch 401 errors (refresh token expired) | ||
29 | return next.handle(authReq) | ||
30 | .catch(err => { | ||
31 | if (err.status === 401) { | ||
32 | return this.handleTokenExpired(req, next) | ||
33 | } | ||
34 | |||
35 | return Observable.throw(err) | ||
36 | }) | ||
37 | } | ||
38 | |||
39 | private handleTokenExpired (req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { | ||
40 | return this.authService.refreshAccessToken() | ||
41 | .switchMap(() => { | ||
42 | const authReq = this.cloneRequestWithAuth(req) | ||
43 | |||
44 | return next.handle(authReq) | ||
45 | }) | ||
46 | } | ||
47 | |||
48 | private cloneRequestWithAuth (req: HttpRequest<any>) { | ||
49 | const authHeaderValue = this.authService.getRequestHeaderValue() | ||
50 | |||
51 | if (authHeaderValue === null) return req | ||
52 | |||
53 | // Clone the request to add the new header | ||
54 | return req.clone({ headers: req.headers.set('Authorization', authHeaderValue) }) | ||
55 | } | ||
56 | } | ||
57 | |||
58 | export const AUTH_INTERCEPTOR_PROVIDER = { | ||
59 | provide: HTTP_INTERCEPTORS, | ||
60 | useClass: AuthInterceptor, | ||
61 | multi: true | ||
62 | } | ||
diff --git a/client/src/app/shared/auth/index.ts b/client/src/app/shared/auth/index.ts index 0f2bfb0d6..84a07196f 100644 --- a/client/src/app/shared/auth/index.ts +++ b/client/src/app/shared/auth/index.ts | |||
@@ -1 +1 @@ | |||
export * from './auth-http.service' | export * from './auth-interceptor.service' | ||