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