]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/eg2/src/app/staff/resolver.service.ts
ccee922bbb6fe93d55714917bd0f5f428df008d8
[Evergreen.git] / Open-ILS / src / eg2 / src / app / staff / resolver.service.ts
1 import {Injectable} from '@angular/core';
2 import {Location} from '@angular/common';
3 import {Observable} from 'rxjs/Observable';
4 import {Observer} from 'rxjs/Observer';
5 import {of} from 'rxjs';
6 import {Router, Resolve, RouterStateSnapshot,
7         ActivatedRoute, ActivatedRouteSnapshot} from '@angular/router';
8 import {StoreService} from '@eg/core/store.service';
9 import {NetService} from '@eg/core/net.service';
10 import {AuthService, AuthWsState} from '@eg/core/auth.service';
11 import {PermService} from '@eg/core/perm.service';
12 import {OrgService} from '@eg/core/org.service';
13 import {FormatService} from '@eg/core/format.service';
14
15 const LOGIN_PATH = '/staff/login';
16 const WS_MANAGE_PATH = '/staff/admin/workstation/workstations/manage';
17
18 /**
19  * Load data used by all staff modules.
20  */
21 @Injectable()
22 export class StaffResolver implements Resolve<Observable<any>> {
23
24     // Tracks the primary resolve observable.
25     observer: Observer<any>;
26
27     constructor(
28         private router: Router,
29         private route: ActivatedRoute,
30         private ngLocation: Location,
31         private store: StoreService,
32         private org: OrgService,
33         private net: NetService,
34         private auth: AuthService,
35         private perm: PermService,
36         private format: FormatService
37     ) {}
38
39     resolve(
40         route: ActivatedRouteSnapshot,
41         state: RouterStateSnapshot): Observable<any> {
42
43         // Staff cookies stay in /$base/staff/
44         // NOTE: storing session data at '/' so it can be shared by
45         // Angularjs apps.
46         this.store.loginSessionBasePath = '/';
47         // ^-- = this.ngLocation.prepareExternalUrl('/staff');
48
49         // Not sure how to get the path without params... using this for now.
50         const path = state.url.split('?')[0];
51         if (path === '/staff/login') {
52             return of(true);
53         }
54
55         const observable: Observable<any>
56             = Observable.create(o => this.observer = o);
57
58         this.auth.testAuthToken().then(
59             tokenOk => {
60                 this.confirmStaffPerms().then(
61                     hasPerms => {
62                         this.auth.verifyWorkstation().then(
63                             wsOk => {
64                                 this.loadStartupData()
65                                 .then(ok => this.observer.complete());
66                             },
67                             wsNotOk => this.handleInvalidWorkstation(path)
68                         );
69                     },
70                     hasNotPerms => {
71                         this.observer.error(
72                             'User does not have staff permissions');
73                     }
74                 );
75             },
76             tokenNotOk => this.handleInvalidToken(state)
77         );
78
79         return observable;
80     }
81
82
83     // Confirm the user has the STAFF_LOGIN permission anywhere before
84     // allowing the staff sub-tree to load. This will prevent users
85     // with valid, non-staff authtokens from attempting to connect and
86     // subsequently getting redirected to the workstation admin page
87     // (since they won't have a valid WS either).
88     confirmStaffPerms(): Promise<any> {
89         return new Promise((resolve, reject) => {
90             this.perm.hasWorkPermAt(['STAFF_LOGIN']).then(
91                 permMap => {
92                     if (permMap.STAFF_LOGIN.length) {
93                         resolve('perm check OK');
94                     } else {
95                         reject('perm check faield');
96                     }
97                 }
98             );
99         });
100     }
101
102
103     // A page that's not the login page was requested without a
104     // valid auth token.  Send the caller back to the login page.
105     handleInvalidToken(state: RouterStateSnapshot): void {
106         console.debug('StaffResolver: authtoken is not valid');
107         this.auth.redirectUrl = state.url;
108         this.router.navigate([LOGIN_PATH]);
109         this.observer.error('invalid or no auth token');
110     }
111
112     handleInvalidWorkstation(path: string): void {
113
114         if (path.startsWith(WS_MANAGE_PATH)) {
115             // user is navigating to the WS admin page.
116             this.observer.complete();
117         } else {
118             this.router.navigate([WS_MANAGE_PATH]);
119             this.observer.error(`Auth session linked to no
120                 workstation or a workstation unknown to this browser`);
121         }
122     }
123
124     /**
125      * Fetches data common to all staff interfaces.
126      */
127     loadStartupData(): Promise<void> {
128
129         // Fetch settings needed globally.  This will cache the values
130         // in the org service.
131         return this.org.settings([
132             'lib.timezone',
133             'webstaff.format.dates',
134             'webstaff.format.date_and_time',
135             'ui.staff.max_recent_patrons'
136         ]).then(settings => {
137             this.format.wsOrgTimezone = settings['lib.timezone'];
138             this.format.dateFormat = settings['webstaff.format.dates'];
139             this.format.dateTimeFormat = settings['webstaff.format.date_and_time'];
140         });
141     }
142 }
143