2 * Core Service - egStartup
4 * Coordinates all startup routines and consolidates them into
5 * a single startup promise. Startup can be launched from multiple
6 * controllers, etc., but only one startup routine will be run.
8 * If no valid authtoken is found, startup will exit early and
9 * change the page href to the login page. Otherwise, the global
10 * promise returned by startup.go() will be resolved after all
11 * async data is arrived.
14 angular.module('egCoreMod')
16 .config(['$locationProvider','$compileProvider',
17 function($locationProvider , $compileProvider) {
18 $locationProvider.html5Mode(true);
19 $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|mailto|blob):/);
23 ['$q','$rootScope','$location','$window','egIDL','egAuth','egEnv','egOrg',
25 function($q, $rootScope, $location, $window, egIDL, egAuth, egEnv , egOrg ,
28 var service = { promise : null }
30 // Some org settings affect every page. Load them during startup.
31 // Other startup data loaders can be added by appending to egEnv.loaders.
32 // egEnv.loaders functions must return a promise.
35 return egOrg.settings([
36 'webstaff.format.dates',
37 'webstaff.format.date_and_time',
38 'ui.staff.max_recent_patrons', // affects navbar
39 'ui.staff.traditional_catalog.enabled', // affects navbar
43 $rootScope.egDateFormat =
44 set['webstaff.format.dates'] || 'shortDate';
45 $rootScope.egDateAndTimeFormat =
46 set['webstaff.format.date_and_time'] || 'short';
48 // default to 1 for backwards compat.
49 if (set['ui.staff.max_recent_patrons'] === null)
50 set['ui.staff.max_recent_patrons'] = 1
56 // returns true if we are staying on the current page
57 // false if we are redirecting to login
58 service.expiredAuthHandler = function(data) {
59 if (lf.isOffline) return true; // Only set by the offline UI
61 console.debug('egStartup.expiredAuthHandler()');
63 // Only notify other tabs the auth session has expired
64 // when this tab was the first tab to know it.
65 // Note that there is a hole here: when the AngularJS
66 // login page is displayed again after a logout, there
67 // will be at least one more invocation of expiredAuthHandler
68 // by egStartup due to there being no authtoken - and this
69 // invocation will send a message on the eg.auth channel.
70 // However, because the AngularJS app doesn't start _listening_
71 // to the channel until the staff user has logged in, that
72 // second invocation has a much lower risk of causing
74 var broadcast = !(data && data.startedElsewhere);
76 egAuth.logout(broadcast); // clean up
78 // no need to redirect if we're on the /login page
79 if ($location.path() == '/login') return true;
81 // change locations to the login page, using the current page
82 // as the 'route_to' destination on /login
83 $window.location.href = $location
86 $window.location.pathname + $window.location.search})
92 // if during startup or any time in the future we encounter an expired
93 // authtoken, call our epired token handler
94 // we handle this here instead egAuth, since it affects the flow
95 // of the startup routines when no valid token exists during startup.
96 // Note that we need to ensure that we pass along the startedElsewhere
97 // flag, if available, to ensure that we don't start a broadcast storm
98 // on the eg.auth BroadcastChannel of any other tabs that happen to have
99 // the AngularJS staff client open.
100 $rootScope.$on('egAuthExpired', function(event, data) {service.expiredAuthHandler(data)});
102 // in case we just left an Angular context, clear the hold target
103 // and notify any open Angular catalog tabs to do the same
104 function clearHoldTarget() {
105 var patronHoldTarget = $cookies.get(
106 'eg.circ.patron_hold_target'
108 if (patronHoldTarget) {
110 'eg.circ.patron_hold_target'
112 if (typeof BroadcastChannel !== 'undefined') {
113 var broadcaster = new BroadcastChannel(
114 'eg.circ.patron_hold_target'
116 broadcaster.postMessage(
117 { removedTarget: patronHoldTarget }
125 service.go = function () {
126 if (service.promise) {
127 // startup already started, return our existing promise
128 return service.promise;
131 // Apply the locale from the cookie before any network
133 var locale = $cookies.get('eg_locale');
135 // Cookie is stored aa_bb. OpenSRF wants aa-BB
136 var parts = locale.split(/_/);
137 OpenSRF.locale = parts[0] + '-' + parts[1].toUpperCase();
138 console.debug('Applying locale ' + OpenSRF.locale);
141 // create a new promise and fire off startup
142 var deferred = $q.defer();
143 service.promise = deferred.promise;
145 // IDL parsing is sync. No promises required
147 egAuth.testAuthToken().then(
149 // testAuthToken resolved
152 function() { deferred.resolve() },
154 deferred.reject('egEnv did not resolve')
159 // testAuthToken rejected
161 console.log('egAuth found no valid authtoken');
162 if (service.expiredAuthHandler()) deferred.resolve();
166 return service.promise;