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';
15 const LOGIN_PATH = '/staff/login';
16 const WS_MANAGE_PATH = '/staff/admin/workstation/workstations/manage';
19 * Load data used by all staff modules.
22 export class StaffResolver implements Resolve<Observable<any>> {
24 // Tracks the primary resolve observable.
25 observer: Observer<any>;
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
40 route: ActivatedRouteSnapshot,
41 state: RouterStateSnapshot): Observable<any> {
43 // Staff cookies stay in /$base/staff/
44 // NOTE: storing session data at '/' so it can be shared by
46 this.store.loginSessionBasePath = '/';
47 // ^-- = this.ngLocation.prepareExternalUrl('/staff');
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') {
55 const observable: Observable<any>
56 = Observable.create(o => this.observer = o);
58 this.auth.testAuthToken().then(
60 this.confirmStaffPerms().then(
62 this.auth.verifyWorkstation().then(
64 this.loadStartupData()
65 .then(ok => this.observer.complete());
67 wsNotOk => this.handleInvalidWorkstation(path)
72 'User does not have staff permissions');
76 tokenNotOk => this.handleInvalidToken(state)
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(
92 if (permMap.STAFF_LOGIN.length) {
93 resolve('perm check OK');
95 reject('perm check faield');
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');
112 handleInvalidWorkstation(path: string): void {
114 if (path.startsWith(WS_MANAGE_PATH)) {
115 // user is navigating to the WS admin page.
116 this.observer.complete();
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`);
125 * Fetches data common to all staff interfaces.
127 loadStartupData(): Promise<void> {
129 // Fetch settings needed globally. This will cache the values
130 // in the org service.
131 return this.org.settings([
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'];