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