d437a7a7c4110cee5e11f038425a727d974d39aa
[working/Evergreen.git] / Open-ILS / xul / staff_client / chrome / content / auth / controller.js
1 dump('entering auth/controller.js\n');
2 // vim:sw=4:ts=4:noet:
3
4 if (typeof auth == 'undefined') auth = {};
5 auth.controller = function (params) {
6     JSAN.use('util.error'); this.error = new util.error();
7     this.w = params.window;
8
9     return this;
10 };
11
12 auth.controller.prototype = {
13
14     'init' : function () {
15
16         var obj = this;  // so the 'this' in event handlers don't confuse us
17         var w = obj.w;
18
19         JSAN.use('OpenILS.data');
20         obj.data = new OpenILS.data(); obj.data.init({'via':'stash'});
21
22         // MVC
23         JSAN.use('util.controller'); obj.controller = new util.controller();
24         obj.controller.init(
25             {
26                 'control_map' : {
27                     'cmd_login' : [
28                         ['command'],
29                         function() {
30                             obj.login();
31                         }
32                     ],
33                     'cmd_standalone' : [
34                         ['command'],
35                         function() {
36                             obj.standalone();
37                         }
38                     ],
39                     'cmd_standalone_import' : [
40                         ['command'],
41                         function() {
42                             obj.standalone_import();
43                         }
44                     ],
45                     'cmd_standalone_export' : [
46                         ['command'],
47                         function() {
48                             obj.standalone_export();
49                         }
50                     ],
51                     'cmd_clear_cache' : [
52                         ['command'],
53                         function() {
54                             obj.debug('clear_cache');
55                         }
56                     ],
57                     'cmd_js_console' : [
58                         ['command'],
59                         function() {
60                             obj.debug('js_console');
61                         }
62                     ],
63                     'cmd_debugger' : [
64                         ['command'],
65                         function() {
66                             start_debugger();
67                         }
68                     ],
69                     'cmd_inspector' : [
70                         ['command'],
71                         function() {
72                             start_inspector();
73                         }
74                     ],
75                     'cmd_chrome_list' : [
76                         ['command'],
77                         function() {
78                             start_chrome_list();
79                         }
80                     ],
81                     'cmd_js_shell' : [
82                         ['command'],
83                         function() {
84                             start_js_shell();
85                         }
86                     ],
87                     'cmd_override' : [
88                         ['command'],
89                         function() {
90                             obj.override();
91                         }
92                     ],
93                     'cmd_logoff' : [
94                         ['command'],
95                         function() {
96                             obj.logoff()
97                         }
98                     ],
99                     'cmd_close_window' : [
100                         ['command'],
101                         function() {
102                             obj.close()
103                         }
104                     ],
105                     'cmd_test_server' : [
106                         ['command'],
107                         function() {
108                             obj.test_server( obj.controller.view.server_prompt.value );
109                         }
110                     ],
111                     'ssl_exception' : [
112                         ['render'],
113                         function(e) {
114                             return function() {
115                                 try {
116                                     obj.controller.view.cmd_ssl_exception.setAttribute('hidden','true');
117                                     var x = new XMLHttpRequest();
118                                     x.open("GET",'chrome://pippki/content/exceptionDialog.xul',false);
119                                     x.send(null);
120                                     obj.controller.view.cmd_ssl_exception.setAttribute('hidden','false');
121                                 } catch(E) {
122                                     obj.controller.view.cmd_ssl_exception.setAttribute('hidden','true');
123                                 }
124                             };
125                         }
126                     ],
127                     'cmd_ssl_exception' : [
128                         ['command'],
129                         function() {
130                             window.openDialog(
131                                 'chrome://pippki/content/exceptionDialog.xul',
132                                 '', 
133                                 'chrome,centerscreen,modal', 
134                                 { 
135                                     'location' : 'https://' + obj.controller.view.server_prompt.value.match(/^[^\/]*/), 
136                                     'prefetchCert' : true 
137                                 } 
138                             );
139                             obj.test_server( obj.controller.view.server_prompt.value );
140                         }
141                     ],
142                     'server_prompt' : [
143                         ['keypress'],
144                         handle_keypress
145                     ],
146                     'server_menu' : [
147                         ['render'],
148                         function(e) {
149                             return function() {
150                                 var list = [];
151                                 for (var s in obj.data.ws_info) {
152                                     list.push(s);
153                                 }
154                                 list.sort();
155                                 for (var i = 0; i < list.length; i++) {
156                                     var mi = document.createElement('menuitem');
157                                     mi.setAttribute('label',list[i]);
158                                     mi.setAttribute('value',list[i]);
159                                     e.appendChild(mi);
160                                 }
161                             };
162                         }
163                     ],
164                     'name_prompt' : [
165                         ['keypress'],
166                         handle_keypress
167                     ],
168                     'password_prompt' : [
169                         ['keypress'],
170                         handle_keypress
171                     ],
172                     'submit_button' : [
173                         ['render'],
174                         function(e) { return function() {} }
175                     ],
176                     'apply_locale_btn' : [
177                         ['render'],
178                         function(e) { return function() {} }
179                     ],
180                     'progress_bar' : [
181                         ['render'],
182                         function(e) { return function() {} }
183                     ],
184                     'status' : [
185                         ['render'],
186                         function(e) { return function() {
187                         } }
188                     ],
189                     'ws_deck' : [
190                         ['render'],
191                         function(e) { return function() {
192                             try {
193                                 JSAN.use('util.widgets'); util.widgets.remove_children(e);
194                                 var x = document.createElement('description');
195                                 e.appendChild(x);
196                                 if (obj.data.ws_info 
197                                     && obj.data.ws_info[ obj.controller.view.server_prompt.value ]) {
198                                     var ws = obj.data.ws_info[ obj.controller.view.server_prompt.value ];
199                                     x.appendChild(
200                                         document.createTextNode(
201                                             ws.name /*+ ' @  ' + ws.lib_shortname*/
202                                         )
203                                     );
204                                     JSAN.use('util.file'); var file = new util.file('last_ws_server');
205                                     file.set_object(obj.controller.view.server_prompt.value);
206                                     file.close();
207                                 } else {
208                                     x.appendChild(
209                                         document.createTextNode(
210                                             document.getElementById('authStrings').getString('staff.auth.controller.not_configured')
211                                         )
212                                     );
213                                 }
214                             } catch(E) {
215                                 alert(E);
216                             }
217                         } }
218                     ],
219                     'menu_spot' : [
220                         ['render'],
221                         function(e) { return function() {
222                         } }
223                     ],
224
225                 }
226             }
227         );
228         obj.controller.view.name_prompt.focus();
229
230         function handle_keypress(ev) {
231             try {
232                 if (ev.keyCode && ev.keyCode == 13) {
233                     switch(this) {
234                         case obj.controller.view.server_prompt:
235                             ev.preventDefault();
236                             obj.controller.view.name_prompt.focus(); obj.controller.view.name_prompt.select();
237                         break;
238                         case obj.controller.view.name_prompt:
239                             ev.preventDefault();
240                             obj.controller.view.password_prompt.focus(); obj.controller.view.password_prompt.select();
241                         break;
242                         case obj.controller.view.password_prompt:
243                             ev.preventDefault();
244                             obj.controller.view.submit_button.focus(); 
245                             obj.login();
246                         break;
247                         default: break;
248                     }
249                 }
250             } catch(E) {
251                 alert(E);
252             }
253         }
254
255         obj.controller.view.server_prompt.addEventListener(
256             'change',
257             function (ev) { 
258                 obj.test_server(ev.target.value);
259                 obj.controller.render('ws_deck'); 
260             },
261             false
262         );
263         obj.controller.view.server_prompt.addEventListener(
264             'command',
265             function (ev) {
266                 obj.controller.view.name_prompt.focus();
267                 obj.controller.view.name_prompt.select();
268                 obj.test_server(ev.target.value);
269                 obj.controller.render('ws_deck'); 
270             },
271             false
272         );
273
274         // This talks to our ILS
275         JSAN.use('auth.session');
276         obj.session = new auth.session(obj.controller.view);
277
278         obj.controller.render();
279         obj.test_server( obj.controller.view.server_prompt.value );
280         obj.controller.render('ws_deck'); 
281
282         if (typeof this.on_init == 'function') {
283             this.error.sdump('D_AUTH','auth.controller.on_init()\n');
284             this.on_init();
285         }
286     },
287
288     'test_server' : function(url) {
289         var obj = this;
290         if (!url) {
291             JSAN.use('util.file'); var file = new util.file('last_ws_server');
292             if (file._file.exists()) {
293                 url = file.get_object(); file.close();
294                 obj.controller.view.server_prompt.value = url;
295             }
296         }
297         url = url.match(/^[^\/]*/).toString(); // Only test the pre-slash URL
298         obj.controller.view.submit_button.disabled = true;
299         obj.controller.view.server_prompt.disabled = true;
300         var s = document.getElementById('status');
301         s.setAttribute('value', document.getElementById('authStrings').getString('staff.auth.controller.testing_hostname'));
302         s.setAttribute('style','color: orange;');
303         document.getElementById('version').value = '';
304         if (!url) {
305             s.setAttribute('value', document.getElementById('authStrings').getString('staff.auth.controller.prompt_hostname'));
306             s.setAttribute('style','color: red;');
307             obj.controller.view.server_prompt.disabled = false;
308             obj.controller.view.server_prompt.focus();
309             return;
310         }
311         try {
312             if ( ! url.match(/^https:\/\//) ) url = 'https://' + url;
313             var x = new XMLHttpRequest();
314             dump('server url = ' + url + '\n');
315             x.open("GET",url,true);
316             x.onreadystatechange = function() {
317                 try {
318                     if (x.readyState != 4) return;
319                     s.setAttribute('value', document.getElementById('authStrings').getFormattedString('staff.auth.controller.status', [x.status, x.statusText]));
320                     if (x.status == 200) {
321                         s.setAttribute('style','color: green;');
322                     } else {
323                         s.setAttribute('style','color: red;');
324                     }
325                     obj.test_version(url);
326                 } catch(E) {
327                     obj.controller.view.server_prompt.disabled = false;
328                     obj.controller.view.server_prompt.focus();
329                     s.setAttribute('value', document.getElementById('authStrings').getString('staff.auth.controller.error_hostname'));
330                     s.setAttribute('style','color: red;');
331                     obj.error.sdump('D_ERROR',E);
332                 }
333             }
334             x.send(null);
335         } catch(E) {
336             s.setAttribute('value', document.getElementById('authStrings').getString('staff.auth.controller.error_hostname'));
337             s.setAttribute('style','color: brown;');
338             obj.error.sdump('D_ERROR',E);
339             obj.controller.view.server_prompt.disabled = false;
340             obj.controller.view.server_prompt.focus();
341         }
342     },
343
344     'test_version' : function(url) {
345         var obj = this;
346         var s = document.getElementById('version');
347         s.setAttribute('value', document.getElementById('authStrings').getString('staff.auth.controller.testing_version'));
348         s.setAttribute('style','color: orange;');
349         try {
350             var x = new XMLHttpRequest();
351             var url2 = url + '/xul/server/';
352             dump('version url = ' + url2 + '\n');
353             x.open("GET",url2,true);
354             x.onreadystatechange = function() {
355                 try {
356                     if (x.readyState != 4) return;
357                     s.setAttribute('value', document.getElementById('authStrings').getFormattedString('staff.auth.controller.status', [x.status, x.statusText]));
358                     if (x.status == 200) {
359                         s.setAttribute('style','color: green;');
360                         obj.controller.view.submit_button.disabled = false;
361                     } else {
362                         s.setAttribute('style','color: red;');
363                         obj.test_upgrade_instructions(url);
364                     }
365                     obj.controller.view.server_prompt.disabled = false;
366                 } catch(E) {
367                     s.setAttribute('value', document.getElementById('authStrings').getString('staff.auth.controller.error_version'));
368                     s.setAttribute('style','color: red;');
369                     obj.error.sdump('D_ERROR',E);
370                     obj.controller.view.server_prompt.disabled = false;
371                 }
372             }
373             x.send(null);
374         } catch(E) {
375             s.setAttribute('value', document.getElementById('authStrings').getString('staff.auth.controller.error_version'));
376             s.setAttribute('style','color: brown;');
377             obj.error.sdump('D_ERROR',E);
378             obj.controller.view.server_prompt.disabled = false;
379         }
380     },
381
382     'test_upgrade_instructions' : function(url) {
383         var obj = this;
384         try {
385             var x = new XMLHttpRequest();
386             var url2 = url + '/xul/versions.html';
387             dump('upgrade url = ' + url2 + '\n');
388             x.open("GET",url2,true);
389             x.onreadystatechange = function() {
390                 try {
391                     if (x.readyState != 4) return;
392                     if (x.status == 200) {
393                         window.open('data:text/html,'+window.escape(x.responseText),'upgrade','chrome,resizable,modal,centered');
394                     } else {
395                         if(typeof(G.upgradeCheck) == "function")
396                         {
397                             if (confirm("This server does not support your version of the staff client, an upgrade may be required. If you wish to check for an upgrade please press Ok. Otherwise please press cancel."))
398                                 G.upgradeCheck();
399                         } else {
400                             alert(document.getElementById('authStrings').getString('staff.auth.controller.version_mismatch'));
401                         }
402                     }
403                     obj.controller.view.server_prompt.disabled = false;
404                 } catch(E) {
405                     obj.error.sdump('D_ERROR',E);
406                     obj.controller.view.server_prompt.disabled = false;
407                 }
408             }
409             x.send(null);
410         } catch(E) {
411             obj.error.sdump('D_ERROR',E);
412             obj.controller.view.server_prompt.disabled = false;
413         }
414     },
415
416     'login' : function() { 
417
418         var obj = this;
419
420         this.error.sdump('D_AUTH',
421             document.getElementById('authStrings').getFormattedString(
422                 'staff.auth.controller.error_login', [
423                     this.controller.view.name_prompt.value,
424                     this.controller.view.password_prompt.value,
425                     this.controller.view.server_prompt.value
426                 ]
427             )
428         ); 
429         this.controller.view.server_prompt.disabled = true;
430         this.controller.view.name_prompt.disabled = true;
431         this.controller.view.password_prompt.disabled = true;
432         this.controller.view.submit_button.disabled = true;
433         this.controller.view.apply_locale_btn.disabled = true;
434         XML_HTTP_SERVER = this.controller.view.server_prompt.value.match(/^[^\/]*/).toString();
435
436         try {
437
438             if (typeof this.on_login == 'function') {
439                 this.error.sdump('D_AUTH','auth.controller.session.on_init = ' +
440                     'auth.controller.on_login\n');
441                 this.session.on_init = this.on_login;
442                 this.session.on_error = function() { obj.logoff(); };
443             }
444             
445             this.session.init();
446
447         } catch(E) {
448             var error = '!! ' + E + '\n';
449             this.error.sdump('D_ERROR',error); 
450             alert(error);
451             this.logoff();
452             if (E == 'open-ils.auth.authenticate.init returned false\n') {
453                 this.controller.view.server_prompt.focus();
454                 this.controller.view.server_prompt.select();
455             }
456
457             if (typeof this.on_login_error == 'function') {
458                 this.error.sdump('D_AUTH','auth.controller.on_login_error()\n');
459                 this.on_login_error(E);
460             }
461         }
462         // Once we are done with it, clear the password
463         this.controller.view.password_prompt.value = '';
464
465     },
466
467     'standalone' : function() {
468         var obj = this;
469         try {
470             if (typeof this.on_standalone == 'function') {
471                 obj.on_standalone();
472             }
473         } catch(E) {
474             var error = '!! ' + E + '\n';
475             obj.error.sdump('D_ERROR',error); 
476             alert(error);
477         }
478     },
479
480     'standalone_import' : function() {
481         var obj = this;
482         try {
483             if (typeof this.on_standalone_import == 'function') {
484                 obj.on_standalone_import();
485             }
486         } catch(E) {
487             var error = '!! ' + E + '\n';
488             obj.error.sdump('D_ERROR',error); 
489             alert(error);
490         }
491     },
492
493     'standalone_export' : function() {
494         var obj = this;
495         try {
496             if (typeof this.on_standalone_export == 'function') {
497                 obj.on_standalone_export();
498             }
499         } catch(E) {
500             var error = '!! ' + E + '\n';
501             obj.error.sdump('D_ERROR',error); 
502             alert(error);
503         }
504     },
505
506     'debug' : function(action) {
507         var obj = this;
508         try {
509             if (typeof this.on_debug == 'function') {
510                 obj.on_debug(action);
511             }
512         } catch(E) {
513             var error = '!! ' + E + '\n';
514             obj.error.sdump('D_ERROR',error);
515             alert(error);
516         }
517     },
518
519     'logoff' : function() { 
520
521         this.data.stash_retrieve();
522         if (typeof this.data.unsaved_data != 'undefined') {
523             if (this.data.unsaved_data > 0) {
524                 var confirmation = window.confirm( document.getElementById('offlineStrings').getString('menu.logoff.unsaved_data_warning') );
525                 if (!confirmation) { return; }
526                 this.data.unsaved_data = 0;
527                 this.data.stash('unsaved_data');
528             }
529         }
530     
531         this.error.sdump('D_AUTH','logoff' + this.w + '\n'); 
532         this.controller.view.progress_bar.value = 0; 
533         this.controller.view.progress_bar.setAttribute('real','0.0');
534         this.controller.view.submit_button.disabled = false;
535         this.controller.view.apply_locale_btn.disabled = false;
536         this.controller.view.password_prompt.disabled = false;
537         this.controller.view.password_prompt.value = '';
538         this.controller.view.name_prompt.disabled = false;
539         this.controller.view.name_prompt.focus(); 
540         this.controller.view.name_prompt.select();
541         this.controller.view.server_prompt.disabled = false;
542
543         var windowManager = Components.classes["@mozilla.org/appshell/window-mediator;1"].getService();
544         var windowManagerInterface = windowManager.QueryInterface(Components.interfaces.nsIWindowMediator);
545         var enumerator = windowManagerInterface.getEnumerator(null);
546
547         var w; // close all other windows
548         while ( w = enumerator.getNext() ) {
549             if (w != window) {
550                 if (w.xulG) { w.close(); } // FIXME: kludge so we don't close Firefox windows as an extension.  We should define a @windowtype for all the staff client windows and have the enumerator just pull those
551             }
552         }
553
554         this.controller.render('ws_deck');
555
556         this.session.close();
557         this.data.menu_perms = false;
558         this.data.current_hotkeyset = undefined;
559         this.data.enable_debug = this.data.debug_client;
560         this.data.session = undefined;
561         this.data.stash('menu_perms');
562         this.data.stash('current_hotkeyset');
563         this.data.stash('enable_debug');
564         this.data.stash('session');
565
566         /* FIXME - need some locking or object destruction for the async tests */
567         /* this.test_server( this.controller.view.server_prompt.value ); */
568
569         if (typeof this.on_logoff == 'function') {
570             this.error.sdump('D_AUTH','auth.controller.on_logoff()\n');
571             this.on_logoff();
572         }
573         
574     },
575     'close' : function() { 
576     
577         this.error.sdump('D_AUTH','close' + this.w + '\n');
578
579         var confirm_string = document.getElementById('authStrings').getString('staff.auth.controller.confirm_close');
580
581         this.data.stash_retrieve();
582         if (typeof this.data.unsaved_data != 'undefined') {
583             if (this.data.unsaved_data > 0) {
584                 confirm_string = document.getElementById('offlineStrings').getString('menu.shutdown.unsaved_data_warning');
585             }
586         }
587  
588         if (window.confirm(confirm_string)) {
589             this.data.unsaved_data = 0;
590             this.data.stash('unsaved_data');
591             this.logoff();
592             this.w.close(); /* Probably won't go any further */
593
594             if (typeof this.on_close == 'function') {
595                 this.error.sdump('D_AUTH','auth.controller.on_close()\n');
596                 this.on_close();
597             }
598         }
599         
600     }
601 }
602
603 dump('exiting auth/controller.js\n');