otsdaq_utilities  v2_04_01
DesktopLogin.js
1 //=====================================================================================
2 //
3 // Created Dec, 2012
4 // by Ryan Rivera ((rrivera at fnal.gov))
5 //
6 // DesktopLogin.js
7 //
8 // This is the desktop code for the user interface for ots. ots is the DAQ
9 // and control software for the Fermi Strips Telescope.
10 //
11 // The desktop consists of a dashboard and an arbitrary amount of windows and a login
12 //
13 //=====================================================================================
14 
15 
16 
17 
18 
19 if (typeof Debug == 'undefined')
20  console.log('ERROR: Debug is undefined! Must include Debug.js before Desktop.js');
21 
22 if (typeof Desktop == 'undefined')
23  console.log('ERROR: Desktop is undefined! Must include Desktop.js before DesktopLogin.js');
24 else {
25 
28  //define Desktop.login to return dashboard class
31  Desktop.login = function() {
32  if(false === (this instanceof Desktop.login)) {
33  //here to correct if called as "var v = Desktop.login();"
34  // instead of "var v = new Desktop.login();"
35  return new Desktop.login();
36  }
37 
38  //------------------------------------------------------------------
39  //create private members variables ----------------------
40  //------------------------------------------------------------------
41 
42  var _DEFAULT_SESSION_STRING_LEN = 512;
43  var _DEFAULT_COOKIE_STRING_LEN = 512;
44  var _DEFAULT_COOKIE_DURATION_DAYS = 1;
45  var _DEFAULT_REMEMBER_ME_DURATION_DAYS = 30;
46  var _DEFAULT_PASSWORD_MIN_LEN = 4;
47  var _DEFAULT_PASSWORD_MAX_LEN = 50;
48  var _DEFAULT_USER_MIN_LEN = 4;
49  var _DEFAULT_USER_MAX_LEN = 50;
50 
51  var _cookieCodeStr = "otsCookieCode";
52  var _cookieUserStr = "otsCookieUser";
53  var _cookieRememberMeStr = "otsRememberMeUser";
54  var _BLACKOUT_COOKIE_STR = "TEMPORARY_SYSTEM_BLACKOUT";
55  var _system_blackout = false;
56  var _user = "";
57  var _displayName = "No-Login";
58  var _permissions = 0;
59  var _cookieCode = 0;
60  var _cookieTime = 0;
61  var _sessionId = 0;
62  var _uid = 0;
63  var _badSessionIdCount = 0;
64 
65  var _areLoginInputsValid = false;
66  var _killLogoutInfiniteLoop = false;
67  var _keepFeedbackText = false;
68  var _keptFeedbackText = "";
69 
70  var _loginDiv;
71 
72  //user preferences
73  var _userPref_bgColor, _userPref_dbColor, _userPref_winColor, _userPref_layout, _sysPref_layout;
74  var _applyUserPreferences;
75  var _updateCurrentLayoutTimeout = 0;
76  var _UPDATE_LAYOUT_TIMEOUT_PERIOD = 2000; //give time for user to stop making changes, in ms
77 
78  //------------------------------------------------------------------
79  //create public members variables ----------------------
80  //------------------------------------------------------------------
81 
82  this.loginDiv;
83 
84  //------------------------------------------------------------------
85  //create PRIVATE members functions ----------------------
86  //------------------------------------------------------------------
87 
88  //_closeLoginPrompt
89  // pass isLoginSuccess=true if called upon successful login!
90  // if true refresh user display name and desktop icons will be created
91  var _closeLoginPrompt = function(isLoginSuccess) {
92 
93  //remove Login
94  var ldiv = document.getElementById("Desktop-loginDiv");
95  if(ldiv) { //should not be any login div so delete
96 
97  Debug.log("found login div and deleted",Debug.LOW_PRIORITY);
98  ldiv.parentNode.removeChild(ldiv);
99  }
100 
101  if(isLoginSuccess)
102  {
103 
104  //update display name
105  ldiv = document.getElementById("DesktopDashboard-user-displayName");
106  var tmpStr = "Welcome to ots, " + _displayName;
107 
108  if(ldiv.innerHTML != "" && //if not first time
109  ldiv.innerHTML != tmpStr) //and name is different
110  {
111  //if _display name is different then close all windows!
112  Debug.log("Desktop.desktop.closeAllWindows() for new user",Debug.LOW_PRIORITY);
113  Desktop.desktop.closeAllWindows();
114  }
115  ldiv.innerHTML = tmpStr;
116 
117  //reset desktop based on user's permissions
118  Desktop.desktop.resetDesktop(_permissions);
119  }
120  }
121 
122  //_loginPrompt --
123  // this function brings up login welcome screen
124  // and logs out. This should be called on manual
125  // "logout" also.
126  var _loginPrompt = function() {
127 
128  Debug.log("loginPrompt " + _keepFeedbackText,Debug.LOW_PRIORITY);
129 
130  if(_attemptedCookieCheck)
131  _deleteCookies(); //local logout/reset
132 
133  //if login screen already displayed then do nothing more
134  if(document.getElementById("Desktop-loginDiv"))
135  {
136  Debug.log("Login screen already up.");
137  if(_keepFeedbackText)
138  {
139  document.getElementById("loginFeedbackDiv").innerHTML = _keptFeedbackText;
140  _keepFeedbackText = false;
141  }
142  return;
143  }
144 
145  //refresh screen to nothing and then draw login
146  _closeLoginPrompt();
147 
148  var ldiv;
149  //create prompt functionality
150  ldiv = document.createElement("div");
151  ldiv.setAttribute("id", "Desktop-loginDiv"); //this div holds everything else and is what is delete at start
152  ldiv.style.width = Desktop.desktop.getDesktopWidth() + "px";
153  ldiv.style.height = Desktop.desktop.getDesktopHeight() + "px";
154 
155  //create table just to center content easily, especially on window resize
156  var str;
157  str = "<table width='100%' height='100%'><td valign='middle' align='center'>";
158  str += "<b><u>Welcome to ots!</u></b><br /><br />";
159  str += "<table><td align='right'><div id='Desktop-loginContent'></div></td></table></td></table>";
160  ldiv.innerHTML = str;
161 
162  //reset pointer (seems to get lost somehow)
163  Desktop.desktop.login.loginDiv = _loginDiv = document.getElementById("DesktopLoginDiv");
164 
165  if(!_loginDiv)
166  {
167  return; //abandon, no login element being displayed
168  }
169 
170  _loginDiv.appendChild(ldiv); //add centering elements to page
171 
172  //now have centered in page div as ldiv
173  ldiv = document.getElementById("Desktop-loginContent");
174  if(!ldiv) //should never happen?
175  {
176  Debug.log("ldiv has no parent!");
177  return;
178  }
179 
180  str = "";
181  var rememberMeName = _getCookie(_cookieRememberMeStr); //if remember me cookie exists, then use saved name assume remember me checked
182  str += "Username: <input id='loginInput0' type='email' spellcheck='false' value='" +
183  (rememberMeName?rememberMeName:"") + "'/>";
184  str += "<br />";
185  str += "<div id='loginInputRememberMeDiv'>" +
186  "<div style='float:left; margin: -5px 0 0 89px;'><input type='checkbox' id='loginInputRememberMe' " +
187  (rememberMeName?"checked":"") + " /></div>" +
188  "<div style='float: left; margin: -7px -50px 0px 6px;'><a href='#' onclick='var el=document.getElementById(\"loginInputRememberMe\"); el.checked = !el.checked;'>Remember me</a></div></div>";
189  str += "Password: <input id='loginInput1' type='password' /><br />";
190  str += "<div id='loginRetypeDiv' style='display:none' >Re-type Password: <input id='loginInput2' type='password' /><br /></div>";
191  str += "<div id='newAccountCodeDiv' style='display:none' >New Account Code: <input id='loginInput3' type='text' /><br /></div>";
192  str += "<a target='_blank' href='" +
193  "https://docs.google.com/document/d/1Mw4HByYfLo1bO5Hy9npDWkD4CFxa9xNsYZ5pJ7qwaTM/edit?usp=sharing" +
194  "' title='Click to open Help documentation' ><img src='/WebPath/images/dashboardImages/icon-Help.png'></a>";
195  str += "<a href='#' onmouseup='Desktop.desktop.login.promptNewUser(this); return false;' style='margin:0 100px 0 50px'>New User?</a>";
196  str += "<input type='submit' class='DesktopDashboard-button' value=' Login ' onmouseup='Desktop.desktop.login.attemptLogin();' /><br />"
197 
198  str += "<div id='loginFeedbackDiv'>" + (_keepFeedbackText?_keptFeedbackText:"") + "</div>";
199  _keepFeedbackText = false;
200 
201  if(!window.chrome)
202  str += "<a href='http://www.google.com/chrome'>Note: ots works best in the Chrome web browser.</a>";
203  ldiv.innerHTML = str; //add login forms to page
204 
205  //if rememberMe then set password as focus
206  //else set user name as focus,
207  //and capture enter button in the text fields
208  if(rememberMeName)
209  document.getElementById('loginInput1').focus();
210  else
211  document.getElementById('loginInput0').focus();
212 
213  for(var i=0;i<4;++i) {
214  document.getElementById('loginInput'+i).onkeydown = function(e) {
215  if(e.keyCode == 13) Desktop.desktop.login.attemptLogin(); //if enter, login
216  else if(e.keyCode == 9) { //if tab focus on next box
217  var newFocusIndex = parseInt(this.id[this.id.length-1])+(e.shiftKey?-1:1);
218  if(newFocusIndex != 0 && newFocusIndex != 1 &&
219  document.getElementById('loginRetypeDiv').style.display == "none") //skip 2nd input if not displayed
220  newFocusIndex += e.shiftKey?2:-2; //take 2 steps back (from 1 step forward)
221  newFocusIndex = (newFocusIndex + 4)%4;
222  document.getElementById('loginInput'+newFocusIndex).focus();
223  }
224  else if((e.keyCode >= 48 && e.keyCode <= 57) || //accept numbers and shifted numbers
225  (e.keyCode >= 96 && e.keyCode <= 105) || //accept keypad numbers
226  (e.keyCode >= 65 && e.keyCode <= 90) || //accept letters and shifted letters
227  e.keyCode == 46 || e.keyCode == 8 || //delete, backspace
228  e.keyCode == 35 || e.keyCode == 36 || //home and end
229  (e.keyCode >= 37 && e.keyCode <= 40)) { //arrows are accepted
230  return true;
231  }
232  return false; //to stop tab and enter (and unaccepted chars) from propagating to window
233  };
234 
235  document.getElementById('loginInput'+i).onkeyup = _checkLoginInputs;
236  }
237  }
238 
239  //_checkLoginInputs --
240  // verify that the three inputs are valid when creating an account
241  // if not creating account, let LoginAttempt validate
242  var _checkLoginInputs = function() {
243 
244  var x = [];
245  for(var i=0;i<3;++i) x[i] = document.getElementById('loginInput'+i).value;
246 
247  document.getElementById('loginFeedbackDiv').style.color = ""; //reset color to default inherited style
248  if(document.getElementById('loginRetypeDiv').style.display != "none") { //3 input case, so check
249 
250  _areLoginInputsValid = false; //assume invalid
251 
252  if(x[1] != x[2]) {
253  document.getElementById('loginFeedbackDiv').innerHTML = "Passwords do not match"; return;
254  }
255  if(x[1].length < _DEFAULT_PASSWORD_MIN_LEN) {
256  document.getElementById('loginFeedbackDiv').innerHTML = "Passwords must be at least " + _DEFAULT_PASSWORD_MIN_LEN + " characters"; return;
257  }
258  if(x[1].length > _DEFAULT_PASSWORD_MAX_LEN) {
259  document.getElementById('loginFeedbackDiv').innerHTML = "Passwords must be at most " + _DEFAULT_PASSWORD_MAX_LEN + " characters"; return;
260  }
261  if(x[0].length < _DEFAULT_USER_MIN_LEN) {
262  document.getElementById('loginFeedbackDiv').innerHTML = "User name must be at least " + _DEFAULT_USER_MIN_LEN + " characters"; return;
263  }
264  if(x[0].length > _DEFAULT_USER_MAX_LEN) {
265  document.getElementById('loginFeedbackDiv').innerHTML = "User name must be at most " + _DEFAULT_USER_MAX_LEN + " characters"; return;
266  }
267 
268  _areLoginInputsValid = true;
269  document.getElementById('loginFeedbackDiv').innerHTML = "Passwords are valid!";
270  document.getElementById('loginFeedbackDiv').style.color = "RGB(100,255,150)";
271  }
272 
273  }
274 
275  //_setCookie --
276  // use this as only method for refreshing and setting login cookie!!
277  // sets 2 cookies, cookieCode to code and userName to _user
278  var _setCookie = function(code) {
279 
280  if(code == _BLACKOUT_COOKIE_STR)
281  {
282  Debug.log("maintaining cookie code = " + _cookieCode);
283 
284  var exdate = new Date();
285  exdate.setDate(exdate.getDate() + _DEFAULT_COOKIE_DURATION_DAYS);
286  var c_value;
287  c_value = escape(code) + ((_DEFAULT_COOKIE_DURATION_DAYS==null) ? "" : "; expires="+exdate.toUTCString());
288  document.cookie= _cookieCodeStr + "=" + c_value;
289 
290  return;
291  }
292 
293  if(_user == "" || !code.length || code.length < 2) return; //only refresh/set cookies if valid user and cookie code
294  if(!_system_blackout && _cookieCode == code) return; //unchanged do nothing (unless coming out of blackout)
295 
296  _cookieCode = code; //set local cookie code values
297  var exdate = new Date();
298  exdate.setDate(exdate.getDate() + _DEFAULT_COOKIE_DURATION_DAYS);
299  var c_value;
300  c_value = escape(code) + ((_DEFAULT_COOKIE_DURATION_DAYS==null) ? "" : "; expires="+exdate.toUTCString());
301  document.cookie= _cookieCodeStr + "=" + c_value;
302  c_value = escape(_user) + ((_DEFAULT_COOKIE_DURATION_DAYS==null) ? "" : "; expires="+exdate.toUTCString());
303  document.cookie= _cookieUserStr + "=" + c_value;
304 
305  //Debug.log("set cookie");
306  var ccdiv = document.getElementById("DesktopContent-cookieCodeMailbox");
307  ccdiv.innerHTML = _cookieCode; //place in mailbox for desktop content
308  ccdiv = document.getElementById("DesktopContent-updateTimeMailbox");
309  ccdiv.innerHTML = (new Date()).getTime(); //set last time of cookieCode update
310  _cookieTime = parseInt(ccdiv.innerHTML);
311  }
312 
313  //_getCookie --
314  // get login cookie
315  var _getCookie = function(c_name) {
316  var i,x,y,ARRcookies=document.cookie.split(";");
317  for (i=0;i<ARRcookies.length;i++)
318  {
319  x=ARRcookies[i].substr(0,ARRcookies[i].indexOf("="));
320  y=ARRcookies[i].substr(ARRcookies[i].indexOf("=")+1);
321  x=x.replace(/^\s+|\s+$/g,"");
322  if (x==c_name)
323  {
324  return unescape(y);
325  }
326  }
327  }
328 
329  //_deleteCookies --
330  // delete login cookies, effectively logout
331  var _deleteCookies = function() {
332  _cookieCode = 0;
333  Debug.log("Delete cookies",Debug.LOW_PRIORITY);
334  var c_value;
335  c_value = "; expires=Thu, 01 Jan 1970 00:00:01 GMT;";
336  document.cookie= _cookieCodeStr + "=" + c_value;
337  c_value = "; expires=Thu, 01 Jan 1970 00:00:01 GMT;";
338  document.cookie= _cookieUserStr + "=" + c_value;
339  }
340 
341  //_getUniqueUserId --
342  //generate a unique user ID (UUID)
343  var _getUniqueUserId = function() {
344  return '4xxx'.replace(/[x]/g, function(c) {
345  var r = Math.random()*16|0, v = r;
346  return v.toString(16);
347  });
348  }
349 
350  //_checkCookieLogin --
351  // Can only be called if sessionId is already set
352  // if cookie, check with server that it is valid
353  // if no cookie open login prompt
354  var _checkCookieLogin = function() {
355  if(_sessionId.length != _DEFAULT_SESSION_STRING_LEN) return; //if no session id, fail
356 
357  var code = _getCookie(_cookieCodeStr);
358  _user = _getCookie(_cookieUserStr);
359 
360  if ((code != null && code != "") &&
361  (_user != null && _user != ""))
362  {
363  Debug.log("Attempting browser cookie login.");
364 
365  //if cookie found, submit cookieCode and jumbled user to server to check if valid
366  Desktop.XMLHttpRequest("LoginRequest?RequestType=checkCookie",
367  "uuid="+_uid+"&ju="+_jumble(_user,_sessionId)+"&cc="+code,
368  _handleCookieCheck);
369  }
370  else
371  {
372  Debug.log("No cookie found (" + code + ")",Debug.LOW_PRIORITY);
373 
374  //attempt CERT login
375  if(!_attemptedLoginWithCert)
376  {
377  Debug.log("Attempting CERT login.");
378  _attemptLoginWithCert();
379  }
380  else
381  _loginPrompt(); //no cookie, so prompt user
382  }
383  }
384 
385  //_handleLoginAttempt --
386  // handler for login request from server
387  // current cookie code and display name is returned on success
388  // on failure, go to loginPrompt
389  var _handleLoginAttempt = function(req) {
390  Debug.log("Received login attempt back",Debug.LOW_PRIORITY);
391 
392  var cookieCode = Desktop.getXMLValue(req,"CookieCode");
393  _displayName = Desktop.getXMLValue(req,"DisplayName");
394 
395  if(Desktop.desktop.security == Desktop.SECURITY_TYPE_NONE) //make user = display name if no login
396  _user = Desktop.getXMLValue(req,"pref_username");
397  _permissions = Desktop.getXMLValue(req,"desktop_user_permissions");
398  if(cookieCode && _displayName && cookieCode.length == _DEFAULT_COOKIE_STRING_LEN)
399  {
400  //success!
401  Debug.log("Login Successful!",Debug.LOW_PRIORITY);
402  _setCookie(cookieCode); //update cookie
403  _applyUserPreferences(req);
404 
405  // Set user name if logged in using cert
406  if (Desktop.getXMLValue(req, "pref_username"))
407  _user = Desktop.getXMLValue(req, "pref_username");
408 
409  var activeSessionCount = parseInt(Desktop.getXMLValue(req,"user_active_session_count"));
410  if(activeSessionCount && _loginDiv) //only if the login div exists
411  {
412  Debug.log("Found other active sessions: " + activeSessionCount,Debug.LOW_PRIORITY);
413  _offerActiveSessionOptions(activeSessionCount);
414  }
415  else
416  _closeLoginPrompt(1); //clear login prompt
417 
418  //success!
419 
420  //Note: only two places where login successful here in _handleCookieCheck() and in _handleLoginAttempt()
421  Desktop.desktopTooltip();
422  _attemptedCookieCheck = false;
423  return;
424  }
425  else
426  {
427  //login failed
428 
429  Debug.log("Login failed.");
430  //Debug.log("Debug failure... " + cookieCode + " - " +
431  // _displayName + " - _attemptedLoginWithCert " +
432  //_attemptedLoginWithCert,Debug.LOW_PRIORITY);
433 
434  //set and keep feedback text
435  if(cookieCode == "1") //invalid uuid
436  _keptFeedbackText = "Sorry, your login session was invalid.<br>" +
437  "A new session has been started - please try again.";
438  else if(req && document.getElementById('loginInput3') &&
439  document.getElementById('loginInput3').value != "")
440  _keptFeedbackText = "New Account Code (or Username/Password) not valid.";
441  else if(req)
442  _keptFeedbackText = "Username/Password not correct.";
443  else
444  _keptFeedbackText = "ots Server failed.";
445  _keepFeedbackText = true;
446 
447  if(_attemptedLoginWithCert)
448  {
449  Debug.log("Hiding feedback after CERT attempt.");
450  _keepFeedbackText = false;
451  }
452 
453  for(var i=1;i<3;++i) if(document.getElementById('loginInput'+i)) document.getElementById('loginInput'+i).value = ""; //clear input boxes
454 
455  //refresh session id
456  _uid = _getUniqueUserId();
457  Desktop.XMLHttpRequest("LoginRequest?RequestType=sessionId","uuid="+_uid,_handleGetSessionId);
458  }
459  }
460 
461  //_handleCookieCheck --
462  // handler for cookie check request from server
463  // current cookie code and display name is returned on success
464  // on failure, go to loginPrompt
465  var _attemptedCookieCheck = false;
466  var _handleCookieCheck = function(req) {
467 
468  var cookieCode = Desktop.getXMLValue(req,"CookieCode");
469  _displayName = Desktop.getXMLValue(req,"DisplayName");
470  _permissions = Desktop.getXMLValue(req,"desktop_user_permissions");
471 
472  if(cookieCode && _displayName && cookieCode.length == _DEFAULT_COOKIE_STRING_LEN)
473  {
474  //success!
475 
476  Debug.log("Cookie is good!",Debug.LOW_PRIORITY);
477  _setCookie(cookieCode); //update cookie
478  _applyUserPreferences(req);
479  _closeLoginPrompt(1); //clear login prompt
480 
481  //Note: only two places where login successful here in _handleCookieCheck() and in _handleLoginAttempt()
482  Desktop.desktopTooltip();
483  _attemptedCookieCheck = false;
484  return;
485  }
486  else
487  {
488  Debug.log("Cookie is bad " + cookieCode.length + _displayName,Debug.LOW_PRIORITY);
489 
490  //attempt CERT login
491  Debug.log("Attempting CERT login.");
492  _attemptLoginWithCert();
493  //_loginPrompt(); //no cookie, so prompt user
494  }
495  }
496 
497  //_handleGetSessionId --
498  // handler called when session id is returned from server
499  // set _sessionId
500  // the chain is passed on to check cookie login from here
501  var _handleGetSessionId = function(req) {
502  _sessionId = 0;
503  if(!req || req.responseText.length != _DEFAULT_SESSION_STRING_LEN) { //sessionId failed
504  Debug.log("Invalid session ID",Debug.HIGH_PRIORITY);
505 
506  if(!req)
507  {
508  _loginPrompt();
509  _killLogoutInfiniteLoop = true;
510  return; //do nothing, because server failed
511  }
512  //try again
513  _uid = _getUniqueUserId();
514 
515  Debug.log("UUID: " + _uid);
516  ++_badSessionIdCount;
517  if (_badSessionIdCount < 10)
518  Desktop.XMLHttpRequest("LoginRequest?RequestType=sessionId","uuid="+_uid,_handleGetSessionId); //if disabled, then cookieCode will return 0 to desktop
519  else
520  Desktop.log("Cannot establish session ID - failed 10 times",Desktop.HIGH_PRIORITY);
521 
522  return;
523  }
524  _badSessionIdCount = 0;
525 
526  //successfully received session ID
527  _sessionId = req.responseText;
528 
529 
530 
531  //check if system blackout exists
532  if(!_attemptedCookieCheck &&
533  _getCookie(_cookieCodeStr) == _BLACKOUT_COOKIE_STR)
534  {
535  _loginPrompt();
536  Debug.log("There is a system wide blackout! (Attempts to login right now may fail - likely someone is rebooting the system)", Debug.WARN_PRIORITY);
537  return;
538  }
539 
540 
541 
542 
543  if(_attemptedCookieCheck)
544  {
545  Debug.log("Already tried browser cookie login. Giving up.");
546  _loginPrompt();
547  return;
548  }
549  _attemptedCookieCheck = true;
550 
551  Debug.log("Attempting browser cookie login with new session ID.");
552  _checkCookieLogin();
553  _killLogoutInfiniteLoop = false;
554  }
555 
556  //_offerActiveSessionOptions --
557  // prompt user with option to close other sessions
558  var _offerActiveSessionOptions = function(cnt) {
559 
560  ldiv = document.getElementById("Desktop-loginContent");
561  if(!ldiv)
562  {
563  Debug.log("No login prompt, so not offering active session options.");
564  _closeLoginPrompt(1); //clear login prompt
565  return;
566  }
567 
568  str = "";
569  str += "<center>Warning! You currently have " + cnt + " other active session" + (cnt > 1?"s":"") + ".<br />";
570  str += "<div id='loginFeedbackDiv'>You can opt to force logout the other session" + (cnt > 1?"s":"") + ", " +
571  "or alternatively leave your other session" + (cnt > 1?"s":"") + " active and continue.</div><br />";
572  str += "<input type='submit' class='DesktopDashboard-button' value=' Logout Other Sessions ' " +
573  "onmouseup='Desktop.desktop.login.activeSessionLogoutOption();' />";
574  str += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
575  str += "<input type='submit' class='DesktopDashboard-button' value=' Ignore and Continue ' " +
576  "onmouseup='Desktop.desktop.login.activeSessionIgnoreOption();' /></center>";
577  ldiv.innerHTML = str; //add login forms to page
578  }
579 
580  var _jumble = function (u,s) {
581  if(s.length%2) return "";
582  var x = [];
583  var l = s.length/2;
584  var ss = l;
585  var p = 0;
586  var c = parseInt(s[p*2]+s[p*2+1],16);
587  for(var i=0;i<l;++i) x[i] = 0;
588  var i = 0,h;
589  var s0 = s[p*2],s1 = s[p*2+1];
590  while(l > 0) {
591  p = (p + parseInt(s0+s1,16)) % ss;
592  while(x[p]) p = (p+1) % ss;
593  x[p] = 1; s0 = s[p*2]; s1 = s[p*2+1];
594  c = (c + parseInt(s[p*2]+s[p*2+1],16) + parseInt((i==0)?u.length:u.charCodeAt(i-1))) % ss;
595  h = c.toString(16); if(h.length == 1) h = "0" + h;
596  s = s.substr(0,p*2) + h + s.substr(p*2+2,s.length-p*2-2);
597  --l; if(i==u.length) i = 1; else ++i;
598  }
599  return s;
600  }
601 
602  var _saveUsernameCookie = function () {
603  Debug.log("Desktop _saveUsernameCookie _user " + _user);
604  var exdate = new Date();
605  exdate.setDate(exdate.getDate() + _DEFAULT_REMEMBER_ME_DURATION_DAYS);
606  var c_value;
607  c_value = escape(_user) + ((_DEFAULT_REMEMBER_ME_DURATION_DAYS==null) ? "" : "; expires="+exdate.toUTCString());
608  document.cookie= _cookieRememberMeStr + "=" + c_value;
609  }
610 
611  var _deleteUsernameCookie = function () {
612  Debug.log("Desktop _deleteUsernameCookie _user " + _user);
613  var c_value;
614  c_value = "; expires=Thu, 01 Jan 1970 00:00:01 GMT;";
615  document.cookie= _cookieRememberMeStr + "=" + c_value;
616  }
617 
618  //_updateLayoutTimeoutHandler
619  // updates all user preference settings (since that is the only method)
620  // just to update the current window layout for user.
621  //
622  // Note: this is very similar to what happens in UserSettings.html/setServerSettings()
623  // They should be changed together.
624  var _updateLayoutTimeoutHandler = function() {
625  Debug.log("Desktop login _updateLayoutTimeoutHandler");
626 
627  var data = "";
628 
630  //colors
631  var colorFields = ["bgcolor","dbcolor","wincolor"];
632  var colorPrefVals = [_userPref_bgColor,_userPref_dbColor,_userPref_winColor];
633  for(var j=0;j<3;++j)
634  data += colorFields[j] + "=" + colorPrefVals[j] + "&";
635 
637  //layout with updated current layout
638  var layoutArray = _userPref_layout.split(";"); //get user layout array
639  layoutArray[layoutArray.length-1] = Desktop.desktop.getWindowLayoutStr(); //update extra layout for most recent layout checkpoint
640 
641  var layoutStr = "";
642  for(var j=0;j<layoutArray.length;++j)
643  layoutStr += layoutArray[j] + (j==layoutArray.length-1?"":";");
644  data += "layout=" + layoutStr + "&";
645 
647  //system layout
648  layoutArray = _sysPref_layout.split(";");
649 
650  layoutStr = "";
651  for(var j=0;j<layoutArray.length;++j)
652  layoutStr += layoutArray[j] + (j==layoutArray.length-1?"":";");
653  data += "syslayout=" + layoutStr + "&";
654 
655 
657  //send save req
658  Debug.log("Desktop Login Settings Save Preferences -- " + data);
659  Desktop.XMLHttpRequest("Request?RequestType=setSettings", data);
660  }
661 
662  //------------------------------------------------------------------
663  //create PUBLIC members functions ----------------------
664  //------------------------------------------------------------------
665 
666  //logout ~
667  // Public logout function. Logs out at server and locally.
668  this.logout = function() {
669  Debug.log("Desktop Logout occured " + _killLogoutInfiniteLoop,Debug.MED_PRIORITY);
670 
671  if(_cookieCode && !_killLogoutInfiniteLoop)
672  Desktop.XMLHttpRequest("LoginRequest?RequestType=logout"); //server logout
673  _deleteCookies(); //local logout
674 
675  //start new session
676  if(!_killLogoutInfiniteLoop)
677  {
678  _uid = _getUniqueUserId();
679  Desktop.XMLHttpRequest("LoginRequest?RequestType=sessionId","uuid="+_uid,_handleGetSessionId);
680  Debug.log("UUID: " + _uid)
681  }
682 
683  _killLogoutInfiniteLoop = false; //prevent infinite logout requests, on server failure
684  //document.getElementById("Desktop-loginContent")?
685  // false:true; //prevent infinite logout requests, on server failure
686  }
687 
688 
689  //blackout ~
690  // use to blackout all open sessions in the same browser
691  // during known periods of server unavailability
692  this.blackout = function(setVal) {
693  setVal = setVal?true:false;
694  if(setVal == _system_blackout)
695  return; // do nothing if already setup with value
696 
697  if(setVal) //start blackout
698  {
699  _setCookie(_BLACKOUT_COOKIE_STR);
700  }
701  else //remove blackout
702  {
703  _setCookie(_cookieCode);
704  }
705 
706  _system_blackout = setVal;
707  Debug.log("Login blackout " + _system_blackout);
708  }
709 
710  //isBlackout ~
711  // use to check for existing system blackout from exernal sources
712  this.isBlackout = function() {
713  var cc = _getCookie(_cookieCodeStr);
714  if(!cc) return false; //may be undefined
715  //Debug.log("Checking for blackout signal = " + cc.substr(0,10));
716  return (cc == _BLACKOUT_COOKIE_STR);
717  }
718 
719  //getCookieCode --
720  // The public getCookieCode function does not actually check the cookie
721  // it is the server which controls if a cookieCode is still valid.
722  // This function just refreshes the cookie and returns the local cookieCode value.
723  // Note: should only refresh from user activity, not auto
724  this.getCookieCode = function(doNotRefresh) {
725  if(!doNotRefresh)
726  {
727  if(this.isBlackout())
728  {
729  Debug.log("Found an external blackout signal.");
730  return;
731  }
732 
733  _setCookie(_cookieCode); //refresh cookies
734  }
735  return _cookieCode;
736  }
737 
738  this.updateCookieFromContent = function(newTime) {
739  _cookieTime = newTime; //set immediately so timer doesn't trip same issue
740  var ccdiv = document.getElementById("DesktopContent-cookieCodeMailbox");
741  _setCookie(ccdiv.innerHTML);
742  }
743 
744  this.getCookieTime = function() {return _cookieTime;}
745  this.getUserDisplayName = function() {return _displayName;}
746  this.getUsername = function() {return _user;}
747 
748  this.redrawLogin = function() {
749  var ldiv = document.getElementById("Desktop-loginDiv");
750  if(!ldiv) return;
751 
752  ldiv.style.width = Desktop.desktop.getDesktopWidth() + "px";
753  ldiv.style.height = Desktop.desktop.getDesktopHeight() + "px";
754  }
755 
756  //toggle re-type password for new user
757  this.promptNewUser = function(linkObj) {
758  document.getElementById('loginFeedbackDiv').innerHTML = ""; //clear feedback text
759  Debug.log("Desktop Login Prompt New User",Debug.LOW_PRIORITY);
760  document.getElementById('loginRetypeDiv').style.display =
761  document.getElementById('loginRetypeDiv').style.display == "none"?"inline":"none";
762  document.getElementById('newAccountCodeDiv').style.display =
763  document.getElementById('newAccountCodeDiv').style.display == "none"?"inline":"none";
764 
765  for(var i=1;i<4;++i) document.getElementById('loginInput'+i).value = ""; //clear input boxes
766 
767  linkObj.innerHTML = document.getElementById('loginRetypeDiv').style.display == "none"?"New User?":"Have an Account?";
768  }
769 
770  this.attemptLogin = function() {
771  Debug.log("Desktop Login Prompt Attempt Login ",Debug.LOW_PRIORITY);
772  _attemptedLoginWithCert = false;
773 
774  var x = [];
775  for(var i=0;i<3;++i) x[i] = document.getElementById('loginInput'+i).value;
776 
777  if(document.getElementById('loginRetypeDiv').style.display != "none" && !_areLoginInputsValid) {
778  Debug.log("Invalid Inputs on new login attempt",Debug.LOW_PRIORITY); return;
779  }
780 
781  document.getElementById('loginFeedbackDiv').innerHTML = ""; //clear feedback text
782  document.getElementById('loginFeedbackDiv').style.color = ""; //reset color to default inherited style
783 
784  if(x[0] == "" || x[1] == "") {
785  document.getElementById('loginFeedbackDiv').innerHTML = "Some fields were left empty."; return;
786  }
787  _user = x[0]; //set local user
788 
789  //if remember me checked, refresh cookie.. else delete whatever is there
790  if(document.getElementById('loginInputRememberMe').checked) _saveUsernameCookie();
791  else _deleteUsernameCookie();
792 
793  Desktop.XMLHttpRequest("LoginRequest?RequestType=login","uuid="+_uid+"&nac="+document.getElementById('loginInput3').value
794  +"&ju="+_jumble(x[0],_sessionId)+"&jp="+_jumble(x[1],_sessionId),_handleLoginAttempt);
795  }
796 
797  function getParameterByName(name, url) {
798  if (!url) url = window.location.href;
799  name = name.replace(/[\[\]]/g, "\\$&");
800  var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
801  results = regex.exec(url);
802  if (!results) return null;
803  if (!results[2]) return '';
804  return decodeURIComponent(results[2].replace(/\+/g, " "));
805  }
806 
807  var _attemptedLoginWithCert = false;
808  var _attemptLoginWithCert = function () {
809  Debug.log("Desktop Login Certificate Attempt Login ", Debug.LOW_PRIORITY);
810 
811  _attemptedLoginWithCert = true; //mark flag so that now error is displayed in login prompt for CERT failure
812  Desktop.XMLHttpRequest("LoginRequest?RequestType=cert", "uuid=" + _uid, _handleLoginAttempt);
813  }
814 
815  //_applyUserPreferences
816  // apply user preferences based on req if provided
817  // window color should always have alpha of 0.9
818  _applyUserPreferences = this.applyUserPreferences = function(req) {
819 
820  if (typeof req != 'undefined') {
821  //update user pref if req is defined as xml doc
822  _userPref_bgColor = Desktop.getXMLValue(req,"pref_bgcolor");
823  _userPref_dbColor = Desktop.getXMLValue(req,"pref_dbcolor");
824  _userPref_winColor = Desktop.getXMLValue(req,"pref_wincolor");
825  _userPref_layout = Desktop.getXMLValue(req,"pref_layout");
826  _sysPref_layout = Desktop.getXMLValue(req,"pref_syslayout");
827  }
828 
829  Desktop.desktop.dashboard.setDefaultDashboardColor(_userPref_dbColor);
830  Desktop.desktop.setDefaultWindowColor(_userPref_winColor);
831  document.body.style.backgroundColor = _userPref_bgColor;
832  }
833 
834  //resetCurrentLayoutUpdateTimer
835  // called by DesktopWindow.js any time a window moves
836  // the timeout allows for maintaining the current layout for the user
837  //
838  // NOTE: This was disabled!! Because what is the point of saving current layout
839  // when users may have multiple logins/multiple instances of the desktop/multiple tabs
840  this.resetCurrentLayoutUpdateTimer = function() {
841  return; //DISABLE THIS FEATURE
842 
843  //Debug.log("Desktop login resetCurrentLayoutUpdateTimer")e;
844  if(_updateCurrentLayoutTimeout)
845  clearTimeout(_updateCurrentLayoutTimeout);
846  _updateCurrentLayoutTimeout = setTimeout(_updateLayoutTimeoutHandler,_UPDATE_LAYOUT_TIMEOUT_PERIOD);
847  }
848 
849  this.getUserDefaultLayout = function(i) { return _userPref_layout.split(";")[i]; }
850  this.getSystemDefaultLayout = function(i) { return _sysPref_layout.split(";")[i]; }
851 
852  this.activeSessionLogoutOption = function() {
853  Debug.log("Desktop login activeSessionLogoutOption");
854  Desktop.XMLHttpRequest("LoginRequest?RequestType=logout","LogoutOthers=1"); //server logout of other active sessions
855  _closeLoginPrompt(1); //clear login prompt - pass 1 just so it will check new username
856 
857  }
858  this.activeSessionIgnoreOption = function() {
859  Debug.log("Desktop activeSessionIgnoreOption");
860  _closeLoginPrompt(1); //clear login prompt - pass 1 just so it will check new username
861  }
862 
863  //------------------------------------------------------------------
864  //handle class construction ----------------------
865  //------------------------------------------------------------------
866 
867 
868 
869  //initially
870  //submit unique uid and get session ID from server using GetSessionId request
871  //check cookie to see if still valid
872  //send isStillActive request to server to see if CookieCode is still valid
873  //if no valid cookie, prompt user
874  //user can login or (if first time) set password
875  //user and jumbled password sent to server for login
876  //if login successful, loginDiv is removed from desktop and cookieCode used by client
877 
878  this.setupLogin = function()
879  {
880  _uid = _getUniqueUserId();
881  if(Desktop.desktop.security == Desktop.SECURITY_TYPE_DIGEST_ACCESS)
882  {
883  this.loginDiv = _loginDiv = document.createElement("div"); //create holder for anything login
884  _loginDiv.setAttribute("id", "DesktopLoginDiv");
885  Desktop.XMLHttpRequest("LoginRequest?RequestType=sessionId",
886  "uuid="+_uid,_handleGetSessionId); //if disabled, then cookieCode will return 0 to desktop
887  }
888  else if(Desktop.desktop.security == Desktop.SECURITY_TYPE_NONE) //straight to login attempt for no security
889  Desktop.XMLHttpRequest("LoginRequest?RequestType=login","uuid="+_uid,_handleLoginAttempt);
890  //else //no login prompt at all
891 
892  Debug.log("UUID: " + _uid);
893  }
894 
895  this.setupLogin();
896  Debug.log("Desktop Login created",Debug.LOW_PRIORITY);
897  }
898 }