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