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';
14 const LOGIN_PATH = '/staff/login';
15 const WS_MANAGE_PATH = '/staff/admin/workstation/workstations/manage';
18 * Load data used by all staff modules.
21 export class StaffResolver implements Resolve<Observable<any>> {
23 // Tracks the primary resolve observable.
24 observer: Observer<any>;
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
40 route: ActivatedRouteSnapshot,
41 state: RouterStateSnapshot): Observable<any> {
45 // Staff cookies stay in /$base/staff/
46 // NOTE: storing session data at '/' so it can be shared by
48 this.store.loginSessionBasePath = '/';
49 // ^-- = this.ngLocation.prepareExternalUrl('/staff');
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') {
57 const observable: Observable<any>
58 = Observable.create(o => this.observer = o);
60 this.auth.testAuthToken().then(
62 this.confirmStaffPerms().then(
64 this.auth.verifyWorkstation().then(
66 this.loadStartupData()
68 // Resolve observable must emit /something/
69 this.observer.next(true);
70 this.observer.complete();
73 wsNotOk => this.handleInvalidWorkstation(path)
78 'User does not have staff permissions');
82 tokenNotOk => this.handleInvalidToken(state)
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(
98 if (permMap.STAFF_LOGIN.length) {
99 resolve('perm check OK');
101 reject('perm check faield');
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');
118 handleInvalidWorkstation(path: string): void {
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();
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`);
133 * Fetches data common to all staff interfaces.
135 loadStartupData(): Promise<void> {
137 // Fetch settings needed globally. This will cache the values
138 // in the org service.
139 return this.org.settings([
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'];
150 if (settings['webstaff.format.dates']) {
151 this.format.dateFormat = settings['webstaff.format.dates'];
153 if (settings['webstaff.format.date_and_time']) {
154 this.format.dateTimeFormat =
155 settings['webstaff.format.date_and_time'];