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';
13 const LOGIN_PATH = '/staff/login';
14 const WS_MANAGE_PATH = '/staff/admin/workstation/workstations/manage';
17 * Load data used by all staff modules.
20 export class StaffResolver implements Resolve<Observable<any>> {
22 // Tracks the primary resolve observable.
23 observer: Observer<any>;
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
38 route: ActivatedRouteSnapshot,
39 state: RouterStateSnapshot): Observable<any> {
41 // Staff cookies stay in /$base/staff/
42 // NOTE: storing session data at '/' so it can be shared by
44 this.store.loginSessionBasePath = '/';
45 // ^-- = this.ngLocation.prepareExternalUrl('/staff');
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') {
53 const observable: Observable<any>
54 = Observable.create(o => this.observer = o);
56 this.auth.testAuthToken().then(
58 this.confirmStaffPerms().then(
60 this.auth.verifyWorkstation().then(
62 this.loadStartupData()
63 .then(ok => this.observer.complete());
65 wsNotOk => this.handleInvalidWorkstation(path)
70 'User does not have staff permissions');
74 tokenNotOk => this.handleInvalidToken(state)
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(
90 if (permMap.STAFF_LOGIN.length) {
91 resolve('perm check OK');
93 reject('perm check faield');
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');
110 handleInvalidWorkstation(path: string): void {
112 if (path.startsWith(WS_MANAGE_PATH)) {
113 // user is navigating to the WS admin page.
114 this.observer.complete();
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`);
123 * Fetches data common to all staff interfaces.
125 loadStartupData(): Promise<void> {
127 // Fetch settings needed globally. This will cache the values
128 // in the org service.
129 return this.org.settings([
131 'webstaff.format.dates',
132 'webstaff.format.date_and_time',
133 'ui.staff.max_recent_patrons'
134 ]).then(settings => {
135 this.format.wsOrgTimezone = settings['lib.timezone'];
136 this.format.dateFormat = settings['webstaff.format.dates'];
137 this.format.dateTimeFormat = settings['webstaff.format.date_and_time'];