includes/clientside/static/login.js
changeset 1132 05fe0039d952
parent 1125 367768040a61
child 1136 8c664c96fccd
--- a/includes/clientside/static/login.js	Sun Oct 25 00:09:11 2009 -0400
+++ b/includes/clientside/static/login.js	Tue Nov 03 22:08:48 2009 -0500
@@ -115,13 +115,14 @@
   var title = ( user_level > USER_LEVEL_MEMBER ) ? $lang.get('user_login_ajax_prompt_title_elev') : $lang.get('user_login_ajax_prompt_title');
   logindata.mb_object = new MessageBox(MB_OKCANCEL | MB_ICONLOCK, title, '');
   
+  //
+  // Cancel function: called when the "Cancel" button is clicked
+  //
   logindata.mb_object.onclick['Cancel'] = function()
   {
-    // Hide the error message and captcha
-    if ( document.getElementById('ajax_login_error_box') )
-    {
-      document.getElementById('ajax_login_error_box').parentNode.removeChild(document.getElementById('ajax_login_error_box'));
-    }
+    // Hide the error message, if any
+    $('ajax_login_error_box').remove();
+    // Hide the captcha, if any
     if ( document.getElementById('autoCaptcha') )
     {
       var to = fly_out_top(document.getElementById('autoCaptcha'), false, true);
@@ -130,7 +131,7 @@
           d.parentNode.removeChild(d);
         }, to);
     }
-    // Ask the server to clean our key
+    // Ask the server to delete the encryption key we're using
     ajaxLoginPerformRequest({
         mode: 'clean_key',
         key_aes: logindata.key_aes,
@@ -138,8 +139,10 @@
     });
   };
   
+  // Clicking OK will not cause the box to destroy, as this function returns true.
   logindata.mb_object.onbeforeclick['OK'] = function()
   {
+    // Just call the submitter and let it take care of everything
     ajaxLoginSubmitForm();
     return true;
   }
@@ -160,7 +163,8 @@
 }
 
 /**
- * For compatibility only.
+ * For compatibility only. Really, folks, it's ajaxLoginInit. If you need a
+ * mnemonic device, use "two 'in's."
  */
 
 window.ajaxLogonInit = function(call_on_finish, user_level)
@@ -170,7 +174,7 @@
 
 /**
  * Sets the contents of the AJAX login window to the appropriate status message.
- * @param int One of AJAX_STATUS_*
+ * @param int One of AJAX_STATUS_* constants
  */
 
 window.ajaxLoginSetStatus = function(status)
@@ -365,7 +369,7 @@
     case null:
     case undefined:
       logindata.showing_status = false;
-      return null;
+      return;
       break;
   }
   logindata.showing_status = true;
@@ -374,6 +378,7 @@
 /**
  * Performs an AJAX logon request to the server and calls ajaxLoginProcessResponse() on the result.
  * @param object JSON packet to send
+ * @param function Optional function to call on the response as well.
  */
 
 window.ajaxLoginPerformRequest = function(json, _hookfunc)
@@ -420,12 +425,15 @@
     }
     return false;
   }
+  
   // Main mode switch
   switch ( response.mode )
   {
-    case 'build_box':
+    case 'initial':
       // Rid ourselves of any loading windows
       ajaxLoginSetStatus(AJAX_STATUS_DESTROY);
+      // show any errors
+      ajaxLoginShowFriendlyError(response);
       // The server wants us to build the login form, all the information is there
       ajaxLoginBuildForm(response);
       break;
@@ -433,49 +441,33 @@
       ajaxLoginSetStatus(AJAX_STATUS_SUCCESS);
       logindata.successfunc(response.key, response);
       break;
-    case 'login_failure':
-      // Rid ourselves of any loading windows
-      ajaxLoginSetStatus(AJAX_STATUS_DESTROY);
-      document.getElementById('messageBox').style.backgroundColor = '#C0C0C0';
-      var mb_parent = document.getElementById('messageBox').parentNode;
-      var do_respawn = ( typeof(response.respawn) == 'boolean' && response.respawn == true ) || typeof(response.respawn) != 'boolean';
-      if ( do_respawn )
-      {
-        $(mb_parent).effect("shake", {}, 200);
-        setTimeout(function()
-          {
-            document.getElementById('messageBox').style.backgroundColor = '#FFF';
-            
-            ajaxLoginBuildForm(response.respawn_info);
-            ajaxLoginShowFriendlyError(response);
-          }, 2500);
-      }
-      else
-      {
-        ajaxLoginShowFriendlyError(response);
-      }
-      break;
-    case 'login_success_reset':
+    case 'reset_pass_used':
+      // We logged in with a temporary password. Prompt the user to go to the temp password page and
+      // reset their real password. If they click no, treat it as a login failure, as no session key
+      // is actually issued when this type of login is performed.
+      
       var conf = confirm($lang.get('user_login_ajax_msg_used_temp_pass'));
       if ( conf )
       {
         var url = makeUrlNS('Special', 'PasswordReset/stage2/' + response.user_id + '/' + response.temp_password);
         window.location = url;
+        break;
       }
-      else
-      {
-        // treat as a failure
-        ajaxLoginSetStatus(AJAX_STATUS_DESTROY);
-        document.getElementById('messageBox').style.backgroundColor = '#C0C0C0';
-        var mb_parent = document.getElementById('messageBox').parentNode;
-        $(mb_parent).effect("shake", {}, 1500);
-        setTimeout(function()
-          {
-            document.getElementById('messageBox').style.backgroundColor = '#FFF';
-            ajaxLoginBuildForm(response.respawn_info);
-            // don't show an error here, just silently respawn
-          }, 2500);
-      }
+      // else, treat as a failure
+    default:
+      // Rid ourselves of any loading windows
+      ajaxLoginSetStatus(AJAX_STATUS_DESTROY);
+      document.getElementById('messageBox').style.backgroundColor = '#C0C0C0';
+      var mb_parent = document.getElementById('messageBox').parentNode;
+      $(mb_parent).effect("shake", {}, 200);
+      setTimeout(function()
+        {
+          document.getElementById('messageBox').style.backgroundColor = '#FFF';
+          console.debug(response);
+          ajaxLoginShowFriendlyError(response);
+          ajaxLoginBuildForm(response);
+        }, 2500);
+      
       break;
     case 'logout_success':
       if ( ENANO_SID )
@@ -512,7 +504,7 @@
   var div = document.createElement('div');
   div.id = 'ajax_login_form';
   
-  var show_captcha = ( data.locked_out.locked_out && data.locked_out.lockout_policy == 'captcha' ) ? data.locked_out.captcha : false;
+  var show_captcha = ( data.lockout.active && data.lockout.policy == 'captcha' ) ? data.lockout.captcha : false;
   
   // text displayed on re-auth
   if ( logindata.user_level > USER_LEVEL_MEMBER )
@@ -586,8 +578,6 @@
   tr2.appendChild(td2_2);
   table.appendChild(tr2);
   
-  eval(setHook('login_build_form'));
-  
   // Field - captcha
   if ( show_captcha )
   {
@@ -617,6 +607,14 @@
     table.appendChild(tr3);
   }
   
+  // ok, this is a compatibility hack
+  data.locked_out = { locked_out: data.lockout.active };
+  
+  // hook for the login form
+  eval(setHook('login_build_form'));
+  
+  delete(data.locked_out);
+  
   // Done building the main part of the form
   form.appendChild(table);
   
@@ -696,7 +694,7 @@
     lbl_dh.innerHTML = $lang.get('user_login_ajax_check_dh_ie');
     boxen.appendChild(lbl_dh);
   }
-  else if ( !data.allow_diffiehellman )
+  else if ( !data.crypto.dh_enable )
   {
     // create hidden control - server requested that DiffieHellman be disabled (usually means not supported)
     var check_dh = document.createElement('input');
@@ -769,24 +767,21 @@
   
   // Post operations: show captcha window
   if ( show_captcha )
+  {
     ajaxShowCaptcha(show_captcha);
+  }
   
   // Post operations: stash encryption keys and All That Jazz(TM)
-  logindata.key_aes = data.aes_key;
-  logindata.key_dh = data.dh_public_key;
+  logindata.key_aes = data.crypto_aes_key;
+  logindata.key_dh = data.crypto.dh_public_key;
   logindata.captcha_hash = show_captcha;
-  logindata.loggedin_username = data.username
+  logindata.loggedin_username = data.username;
   
-  // Are we locked out? If so simulate an error and disable the controls
-  if ( data.lockout_info.lockout_policy == 'lockout' && data.locked_out.locked_out )
+  // If policy is lockout, also disable controls
+  if ( data.lockout.policy == 'lockout' && data.lockout.active )
   {
     f_username.setAttribute('disabled', 'disabled');
     f_password.setAttribute('disabled', 'disabled');
-    var fake_packet = {
-      error_code: 'locked_out',
-      respawn_info: data
-    };
-    ajaxLoginShowFriendlyError(fake_packet);
   }
 }
 
@@ -978,11 +973,10 @@
 
 window.ajaxLoginShowFriendlyError = function(response)
 {
-  if ( !response.respawn_info )
-    return false;
-  if ( !response.error_code )
-    return false;
   var text = ajaxLoginGetErrorText(response);
+  if ( text == false )
+    return true;
+    
   if ( document.getElementById('ajax_login_error_box') )
   {
     // console.info('Reusing existing error-box');
@@ -1021,85 +1015,53 @@
 
 window.ajaxLoginGetErrorText = function(response)
 {
-  if ( !response.error_code.match(/^[a-z0-9]+_[a-z0-9_]+$/) )
+  if ( response.lockout )
   {
-    return response.error_code;
+    // set this pluralality thing
+    response.lockout.plural = response.lockout.time_rem == 1 ? '' : $lang.get('meta_plural');
   }
-  switch ( response.error_code )
+  
+  if ( response.mode == 'initial' )
   {
-    default:
-      eval(setHook('ajax_login_process_error'));
-      if ( !ls )
-      {
-        var ls = $lang.get('user_err_' + response.error_code);
-        if ( ls == 'user_err_' + response.error_code )
-          // Adding response here allows language strings to utilize additional information passed from the error packet
-          ls = $lang.get(response.error_code, response);
-      }
-      
-      return ls;
-      break;
-    case 'locked_out':
-      if ( response.respawn_info.lockout_info.lockout_policy == 'lockout' )
-      {
-        return $lang.get('user_err_locked_out', { 
-                  lockout_threshold: response.respawn_info.lockout_info.lockout_threshold,
-                  lockout_duration: response.respawn_info.lockout_info.lockout_duration,
-                  time_rem: response.respawn_info.lockout_info.time_rem,
-                  plural: ( response.respawn_info.lockout_info.time_rem == 1 ) ? '' : $lang.get('meta_plural'),
-                  captcha_blurb: ''
-                });
-        break;
-      }
-    case 'invalid_credentials':
-      var base = $lang.get('user_err_invalid_credentials');
-      if ( response.respawn_info.locked_out.locked_out )
-      {
-        base += ' ';
-        var captcha_blurb = '';
-        switch(response.respawn_info.lockout_info.lockout_policy)
+    // Just showing the box for the first time. If there's an error now, it's based on a preexisting lockout.
+    if ( response.lockout.active )
+    {
+      return $lang.get('user_err_locked_out_initial_' + response.lockout.policy, response.lockout);
+    }
+    return false;
+  }
+  else
+  {
+    // An attempt was made.
+    switch(response.mode)
+    {
+      case 'login_failure':
+        // Generic login user error.
+        var error = '', x;
+        if ( (x = $lang.get(response.error)) != response.error )
+          error = x;
+        else
+          error = $lang.get('user_err_' + response.error);
+        if ( response.lockout.active && response.lockout.policy == 'lockout' )
         {
-          case 'captcha':
-            captcha_blurb = $lang.get('user_err_locked_out_captcha_blurb');
-            break;
-          case 'lockout':
-            break;
-          default:
-            base += 'WTF? Shouldn\'t be locked out with lockout policy set to disable. ';
-            break;
+          // Lockout enforcement was just activated.
+          return $lang.get('user_err_locked_out_initial_' + response.lockout.policy, response.lockout);
+        }
+        else if ( response.lockout.policy != 'disable' && !response.lockout.active && response.lockout.fails > 0 )
+        {
+          // Lockout is in a warning state.
+          error += ' ' + $lang.get('user_err_invalid_credentials_' + response.lockout.policy, response.lockout);
         }
-        base += $lang.get('user_err_locked_out', { 
-                  captcha_blurb: captcha_blurb,
-                  lockout_threshold: response.respawn_info.lockout_info.lockout_threshold,
-                  lockout_duration: response.respawn_info.lockout_info.lockout_duration,
-                  time_rem: response.respawn_info.lockout_info.time_rem,
-                  plural: ( response.respawn_info.lockout_info.time_rem == 1 ) ? '' : $lang.get('meta_plural')
-                });
-      }
-      else if ( response.respawn_info.lockout_info.lockout_policy == 'lockout' || response.respawn_info.lockout_info.lockout_policy == 'captcha' )
-      {
-        // if we have a lockout policy of captcha or lockout, then warn the user
-        switch ( response.respawn_info.lockout_info.lockout_policy )
-        {
-          case 'captcha':
-            base += $lang.get('user_err_invalid_credentials_lockout_captcha', { 
-                fails: response.respawn_info.lockout_info.lockout_fails,
-                lockout_threshold: response.respawn_info.lockout_info.lockout_threshold,
-                lockout_duration: response.respawn_info.lockout_info.lockout_duration
-              });
-            break;
-          case 'lockout':
-            base += $lang.get('user_err_invalid_credentials_lockout', { 
-                fails: response.respawn_info.lockout_info.lockout_fails,
-                lockout_threshold: response.respawn_info.lockout_info.lockout_threshold,
-                lockout_duration: response.respawn_info.lockout_info.lockout_duration
-              });
-            break;
-        }
-      }
-      return base;
-      break;
+        return error;
+        break;
+      case 'api_error':
+        // Error in the API.
+        return $lang.get('user_err_login_generic_title') + ': ' + $lang.get('user_' + response.error.toLowerCase());
+        break;
+    }
   }
+  
+  return typeof(response.error) == 'string' ? response.error : false;
 }
 
 window.ajaxShowCaptcha = function(code)
@@ -1302,6 +1264,7 @@
   {
     level = USER_LEVEL_ADMIN;
   }
+  
   ajaxLogonInit(function(k, response)
     {
       ajaxLoginReplaceSIDInline(k, old_sid, level);