forked from DSpace/dspace-angular
-
Notifications
You must be signed in to change notification settings - Fork 36
Expand file tree
/
Copy pathauthorized.operators.ts
More file actions
113 lines (108 loc) · 4.27 KB
/
authorized.operators.ts
File metadata and controls
113 lines (108 loc) · 4.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import { InjectionToken } from '@angular/core';
import {
Router,
UrlTree,
} from '@angular/router';
import {
combineLatest as observableCombineLatest,
Observable,
} from 'rxjs';
import {
filter,
map,
withLatestFrom,
} from 'rxjs/operators';
import { AuthService } from '../auth/auth.service';
import { RemoteData } from '../data/remote-data';
import {
getForbiddenRoute,
getPageNotFoundRoute,
} from '../router/core-routing-paths';
export const REDIRECT_ON_4XX = new InjectionToken<<T>(router: Router, authService: AuthService) => (source: Observable<RemoteData<T>>) => Observable<RemoteData<T>>>('redirectOn4xx', {
providedIn: 'root',
factory: () => redirectOn4xx,
});
/**
* Operator that checks if a remote data object returned a 4xx error
* When it does contain such an error, it will redirect the user to the related error page, without
* altering the current URL
*
* @param router The router used to navigate to a new page
* @param authService Service to check if the user is authenticated
*/
export const redirectOn4xx = <T>(router: Router, authService: AuthService) =>
(source: Observable<RemoteData<T>>): Observable<RemoteData<T>> =>
source.pipe(
withLatestFrom(authService.isAuthenticated()),
filter(([rd, isAuthenticated]: [RemoteData<T>, boolean]) => {
if (rd.hasFailed) {
if (rd.statusCode === 404 || rd.statusCode === 422) {
router.navigateByUrl(getPageNotFoundRoute(), { skipLocationChange: true });
return false;
} else if (rd.statusCode === 403 || rd.statusCode === 401) {
if (isAuthenticated) {
router.navigateByUrl(getForbiddenRoute(), { skipLocationChange: true });
return false;
} else {
authService.setRedirectUrl(router.url);
router.navigateByUrl('login');
return false;
}
}
}
return true;
}),
map(([rd]: [RemoteData<T>, boolean]) => rd),
);
/**
* Redirect to 404 if the requested content is not found (204 No Content)
*
* @param router
* @param authService
*/
export const redirectOn204 = <T>(router: Router, authService: AuthService) =>
(source: Observable<RemoteData<T>>): Observable<RemoteData<T>> =>
source.pipe(
withLatestFrom(authService.isAuthenticated()),
filter(([rd, isAuthenticated]: [RemoteData<T>, boolean]) => {
if (rd.hasNoContent) {
router.navigateByUrl(getPageNotFoundRoute(), { skipLocationChange: true });
return false;
}
return true;
}),
map(([rd]: [RemoteData<T>, boolean]) => rd),
);
/**
* Operator that returns a UrlTree to a forbidden page or the login page when the boolean received is false
* @param router The router used to navigate to a forbidden page
* @param authService The AuthService used to determine whether or not the user is logged in
* @param redirectUrl The URL to redirect back to after logging in
*/
export const returnForbiddenUrlTreeOrLoginOnFalse = (router: Router, authService: AuthService, redirectUrl: string) =>
(source: Observable<boolean>): Observable<boolean | UrlTree> =>
source.pipe(
map((authorized) => [authorized]),
returnForbiddenUrlTreeOrLoginOnAllFalse(router, authService, redirectUrl),
);
/**
* Operator that returns a UrlTree to a forbidden page or the login page when the booleans received are all false
* @param router The router used to navigate to a forbidden page
* @param authService The AuthService used to determine whether or not the user is logged in
* @param redirectUrl The URL to redirect back to after logging in
*/
export const returnForbiddenUrlTreeOrLoginOnAllFalse = (router: Router, authService: AuthService, redirectUrl: string) =>
(source: Observable<boolean[]>): Observable<boolean | UrlTree> =>
observableCombineLatest(source, authService.isAuthenticated()).pipe(
map(([authorizedList, authenticated]: [boolean[], boolean]) => {
if (authorizedList.some((b: boolean) => b === true)) {
return true;
} else {
if (authenticated) {
return router.parseUrl(getForbiddenRoute());
} else {
authService.setRedirectUrl(redirectUrl);
return router.parseUrl('login');
}
}
}));