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