includes/clientside/static/login.js
changeset 1227 bdac73ed481e
parent 1210 ad49fa34ff3c
child 1231 4797a4a88533
--- a/includes/clientside/static/login.js	Sun Mar 28 21:49:26 2010 -0400
+++ b/includes/clientside/static/login.js	Sun Mar 28 23:10:46 2010 -0400
@@ -12,22 +12,22 @@
 
 window.ajaxLogonToMember = function()
 {
-  // IE <6 pseudo-compatibility
-  if ( KILL_SWITCH )
-    return true;
-  if ( auth_level >= USER_LEVEL_MEMBER )
-    return true;
-  ajaxLoginInit(function(k)
-    {
-      if ( on_main_page && main_page_members != physical_title )
-      {
-        window.location = makeUrl(main_page_members);
-      }
-      else
-      {
-        window.location.reload();
-      }
-    }, USER_LEVEL_MEMBER);
+	// IE <6 pseudo-compatibility
+	if ( KILL_SWITCH )
+		return true;
+	if ( auth_level >= USER_LEVEL_MEMBER )
+		return true;
+	ajaxLoginInit(function(k)
+		{
+			if ( on_main_page && main_page_members != physical_title )
+			{
+				window.location = makeUrl(main_page_members);
+			}
+			else
+			{
+				window.location.reload();
+			}
+		}, USER_LEVEL_MEMBER);
 }
 
 /**
@@ -36,16 +36,16 @@
 
 window.ajaxLogonToElev = function()
 {
-  if ( auth_level == user_level )
-    return true;
-  
-  ajaxLoginInit(function(k)
-    {
-      ENANO_SID = k;
-      var url = String(' ' + window.location).substr(1);
-      url = append_sid(url);
-      window.location = url;
-    }, user_level);
+	if ( auth_level == user_level )
+		return true;
+	
+	ajaxLoginInit(function(k)
+		{
+			ENANO_SID = k;
+			var url = String(' ' + window.location).substr(1);
+			url = append_sid(url);
+			window.location = url;
+		}, user_level);
 }
 
 /*
@@ -65,13 +65,13 @@
  */
 
 if ( !ajax_login_loadimg_path )
-  var ajax_login_loadimg_path = false;
+	var ajax_login_loadimg_path = false;
 
 if ( !ajax_login_successimg_path )
-  var ajax_login_successimg_path = false;
+	var ajax_login_successimg_path = false;
 
 if ( !ajax_login_lockimg_path )
-  var ajax_login_lockimg_path = false;
+	var ajax_login_lockimg_path = false;
 
 /**
  * Status variables
@@ -108,58 +108,58 @@
 
 window.ajaxLoginInit = function(call_on_finish, user_level)
 {
-  load_component(['messagebox', 'flyin', 'fadefilter', 'jquery', 'jquery-ui', 'l10n', 'crypto']);
-  
-  logindata = {};
-  
-  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, 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);
-      setTimeout(function() {
-          var d = document.getElementById('autoCaptcha');
-          d.parentNode.removeChild(d);
-        }, to);
-    }
-    // Ask the server to delete the encryption key we're using
-    ajaxLoginPerformRequest({
-        mode: 'clean_key',
-        key_aes: logindata.key_aes,
-        key_dh: logindata.key_dh
-    });
-  };
-  
-  // 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;
-  }
-  
-  // Fetch the inner content area
-  logindata.mb_inner = document.getElementById('messageBox').getElementsByTagName('div')[0];
-  
-  // Initialize state
-  logindata.showing_status = false;
-  logindata.user_level = user_level;
-  logindata.successfunc = call_on_finish;
-  
-  // Build the "loading" window
-  ajaxLoginSetStatus(AJAX_STATUS_LOADING_KEY);
-  
-  // Request the key
-  ajaxLoginPerformRequest({ mode: 'getkey' });
+	load_component(['messagebox', 'flyin', 'fadefilter', 'jquery', 'jquery-ui', 'l10n', 'crypto']);
+	
+	logindata = {};
+	
+	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, 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);
+			setTimeout(function() {
+					var d = document.getElementById('autoCaptcha');
+					d.parentNode.removeChild(d);
+				}, to);
+		}
+		// Ask the server to delete the encryption key we're using
+		ajaxLoginPerformRequest({
+				mode: 'clean_key',
+				key_aes: logindata.key_aes,
+				key_dh: logindata.key_dh
+		});
+	};
+	
+	// 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;
+	}
+	
+	// Fetch the inner content area
+	logindata.mb_inner = document.getElementById('messageBox').getElementsByTagName('div')[0];
+	
+	// Initialize state
+	logindata.showing_status = false;
+	logindata.user_level = user_level;
+	logindata.successfunc = call_on_finish;
+	
+	// Build the "loading" window
+	ajaxLoginSetStatus(AJAX_STATUS_LOADING_KEY);
+	
+	// Request the key
+	ajaxLoginPerformRequest({ mode: 'getkey' });
 }
 
 /**
@@ -169,7 +169,7 @@
 
 window.ajaxLogonInit = function(call_on_finish, user_level)
 {
-  return ajaxLoginInit(call_on_finish, user_level);
+	return ajaxLoginInit(call_on_finish, user_level);
 }
 
 /**
@@ -179,200 +179,200 @@
 
 window.ajaxLoginSetStatus = function(status)
 {
-  if ( !logindata.mb_inner )
-    return false;
-  if ( logindata.showing_status )
-  {
-    var div = document.getElementById('ajax_login_status');
-    if ( div )
-      logindata.mb_inner.removeChild(div);
-  }
-  switch(status)
-  {
-    case AJAX_STATUS_LOADING_KEY:
-      
-      // Create the status div
-      var div = document.createElement('div');
-      div.id = 'ajax_login_status';
-      div.style.marginTop = '10px';
-      div.style.textAlign = 'center';
-      
-      // The circly ball ajaxy image + status message
-      var status_msg = $lang.get('user_login_ajax_fetching_key');
-      
-      // Insert the status message
-      div.appendChild(document.createTextNode(status_msg));
-      
-      // Append a br or two to space things properly
-      div.appendChild(document.createElement('br'));
-      div.appendChild(document.createElement('br'));
-      
-      var img = document.createElement('img');
-      img.src = ( ajax_login_loadimg_path ) ? ajax_login_loadimg_path : scriptPath + '/images/loading-big.gif';
-      div.appendChild(img);
-      
-      // Another coupla brs
-      div.appendChild(document.createElement('br'));
-      div.appendChild(document.createElement('br'));
-      
-      // The link to the full login form
-      var small = document.createElement('small');
-      small.innerHTML = $lang.get('user_login_ajax_link_fullform', { link_full_form: makeUrlNS('Special', 'Login/' + title) });
-      div.appendChild(small);
-      
-      // Insert the entire message into the login window
-      logindata.mb_inner.innerHTML = '';
-      logindata.mb_inner.appendChild(div);
-      
-      break;
-    case AJAX_STATUS_GENERATING_KEY:
-      
-      // Create the status div
-      var div = document.createElement('div');
-      div.id = 'ajax_login_status';
-      div.style.marginTop = '10px';
-      div.style.textAlign = 'center';
-      
-      // The circly ball ajaxy image + status message
-      var status_msg = $lang.get('user_login_ajax_generating_key');
-      
-      // Insert the status message
-      div.appendChild(document.createTextNode(status_msg));
-      
-      // Append a br or two to space things properly
-      div.appendChild(document.createElement('br'));
-      div.appendChild(document.createElement('br'));
-      
-      var img = document.createElement('img');
-      img.src = ( ajax_login_lockimg_path ) ? ajax_login_lockimg_path : scriptPath + '/images/lock48.png';
-      div.appendChild(img);
-      
-      // Another coupla brs
-      div.appendChild(document.createElement('br'));
-      div.appendChild(document.createElement('br'));
-      
-      // The link to the full login form
-      var small = document.createElement('small');
-      small.innerHTML = $lang.get('user_login_ajax_link_fullform_dh', { link_full_form: makeUrlNS('Special', 'Login/' + title) });
-      div.appendChild(small);
-      
-      // Insert the entire message into the login window
-      logindata.mb_inner.innerHTML = '';
-      logindata.mb_inner.appendChild(div);
-      
-      break;
-    case AJAX_STATUS_LOGGING_IN:
-      
-      // Create the status div
-      var div = document.createElement('div');
-      div.id = 'ajax_login_status';
-      div.style.marginTop = '10px';
-      div.style.textAlign = 'center';
-      
-      // The circly ball ajaxy image + status message
-      var status_msg = $lang.get('user_login_ajax_loggingin');
-      
-      // Insert the status message
-      div.appendChild(document.createTextNode(status_msg));
-      
-      // Append a br or two to space things properly
-      div.appendChild(document.createElement('br'));
-      div.appendChild(document.createElement('br'));
-      
-      var img = document.createElement('img');
-      img.src = ( ajax_login_loadimg_path ) ? ajax_login_loadimg_path : scriptPath + '/images/loading-big.gif';
-      div.appendChild(img);
-      
-      // Insert the entire message into the login window
-      logindata.mb_inner.innerHTML = '';
-      logindata.mb_inner.appendChild(div);
-      
-      break;
-    case AJAX_STATUS_SUCCESS:
-      
-      // Create the status div
-      var div = document.createElement('div');
-      div.id = 'ajax_login_status';
-      div.style.marginTop = '10px';
-      div.style.textAlign = 'center';
-      
-      // The circly ball ajaxy image + status message
-      var status_msg = $lang.get('user_login_success_short');
-      
-      // Insert the status message
-      div.appendChild(document.createTextNode(status_msg));
-      
-      // Append a br or two to space things properly
-      div.appendChild(document.createElement('br'));
-      div.appendChild(document.createElement('br'));
-      
-      var img = document.createElement('img');
-      img.src = ( ajax_login_successimg_path ) ? ajax_login_successimg_path : scriptPath + '/images/check.png';
-      div.appendChild(img);
-      
-      // Insert the entire message into the login window
-      logindata.mb_inner.innerHTML = '';
-      logindata.mb_inner.appendChild(div);
-      
-      break;
-      
-    case AJAX_STATUS_ERROR:
-      // Create the status div
-      var div = document.createElement('div');
-      div.id = 'ajax_login_status';
-      div.style.marginTop = '10px';
-      div.style.textAlign = 'center';
-      
-      // The circly ball ajaxy image + status message
-      var status_msg = $lang.get('user_login_ajax_err_crypto');
-      
-      // Insert the status message
-      div.appendChild(document.createTextNode(status_msg));
-      
-      // Append a br or two to space things properly
-      div.appendChild(document.createElement('br'));
-      div.appendChild(document.createElement('br'));
-      
-      var img = document.createElement('img');
-      img.src = ( ajax_login_successimg_path ) ? ajax_login_successimg_path : scriptPath + '/images/checkbad.png';
-      div.appendChild(img);
-      
-      // Append a br or two to space things properly
-      div.appendChild(document.createElement('br'));
-      div.appendChild(document.createElement('br'));
-      
-      // The circly ball ajaxy image + status message
-      var detail_msg = $lang.get('user_login_ajax_err_crypto_details');
-      var full_link = $lang.get('user_login_ajax_err_crypto_link');
-      var link = document.createElement('a');
-      link.href = makeUrlNS('Special', 'Login/' + title, 'level=' + logindata.user_level, true);
-      link.appendChild(document.createTextNode(full_link));
-      var span = document.createElement('span');
-      span.style.fontSize = 'smaller';
-      
-      // Insert the message
-      span.appendChild(document.createTextNode(detail_msg + ' '));
-      span.appendChild(link);
-      div.appendChild(span);
-      
-      // Insert the entire message into the login window
-      logindata.mb_inner.innerHTML = '';
-      logindata.mb_inner.appendChild(div);
-      
-      break;
-      
-    default:
-      eval(setHook('login_set_status'));
-      break;
-      
-    case AJAX_STATUS_DESTROY:
-    case null:
-    case undefined:
-      logindata.showing_status = false;
-      return;
-      break;
-  }
-  logindata.showing_status = true;
+	if ( !logindata.mb_inner )
+		return false;
+	if ( logindata.showing_status )
+	{
+		var div = document.getElementById('ajax_login_status');
+		if ( div )
+			logindata.mb_inner.removeChild(div);
+	}
+	switch(status)
+	{
+		case AJAX_STATUS_LOADING_KEY:
+			
+			// Create the status div
+			var div = document.createElement('div');
+			div.id = 'ajax_login_status';
+			div.style.marginTop = '10px';
+			div.style.textAlign = 'center';
+			
+			// The circly ball ajaxy image + status message
+			var status_msg = $lang.get('user_login_ajax_fetching_key');
+			
+			// Insert the status message
+			div.appendChild(document.createTextNode(status_msg));
+			
+			// Append a br or two to space things properly
+			div.appendChild(document.createElement('br'));
+			div.appendChild(document.createElement('br'));
+			
+			var img = document.createElement('img');
+			img.src = ( ajax_login_loadimg_path ) ? ajax_login_loadimg_path : scriptPath + '/images/loading-big.gif';
+			div.appendChild(img);
+			
+			// Another coupla brs
+			div.appendChild(document.createElement('br'));
+			div.appendChild(document.createElement('br'));
+			
+			// The link to the full login form
+			var small = document.createElement('small');
+			small.innerHTML = $lang.get('user_login_ajax_link_fullform', { link_full_form: makeUrlNS('Special', 'Login/' + title) });
+			div.appendChild(small);
+			
+			// Insert the entire message into the login window
+			logindata.mb_inner.innerHTML = '';
+			logindata.mb_inner.appendChild(div);
+			
+			break;
+		case AJAX_STATUS_GENERATING_KEY:
+			
+			// Create the status div
+			var div = document.createElement('div');
+			div.id = 'ajax_login_status';
+			div.style.marginTop = '10px';
+			div.style.textAlign = 'center';
+			
+			// The circly ball ajaxy image + status message
+			var status_msg = $lang.get('user_login_ajax_generating_key');
+			
+			// Insert the status message
+			div.appendChild(document.createTextNode(status_msg));
+			
+			// Append a br or two to space things properly
+			div.appendChild(document.createElement('br'));
+			div.appendChild(document.createElement('br'));
+			
+			var img = document.createElement('img');
+			img.src = ( ajax_login_lockimg_path ) ? ajax_login_lockimg_path : scriptPath + '/images/lock48.png';
+			div.appendChild(img);
+			
+			// Another coupla brs
+			div.appendChild(document.createElement('br'));
+			div.appendChild(document.createElement('br'));
+			
+			// The link to the full login form
+			var small = document.createElement('small');
+			small.innerHTML = $lang.get('user_login_ajax_link_fullform_dh', { link_full_form: makeUrlNS('Special', 'Login/' + title) });
+			div.appendChild(small);
+			
+			// Insert the entire message into the login window
+			logindata.mb_inner.innerHTML = '';
+			logindata.mb_inner.appendChild(div);
+			
+			break;
+		case AJAX_STATUS_LOGGING_IN:
+			
+			// Create the status div
+			var div = document.createElement('div');
+			div.id = 'ajax_login_status';
+			div.style.marginTop = '10px';
+			div.style.textAlign = 'center';
+			
+			// The circly ball ajaxy image + status message
+			var status_msg = $lang.get('user_login_ajax_loggingin');
+			
+			// Insert the status message
+			div.appendChild(document.createTextNode(status_msg));
+			
+			// Append a br or two to space things properly
+			div.appendChild(document.createElement('br'));
+			div.appendChild(document.createElement('br'));
+			
+			var img = document.createElement('img');
+			img.src = ( ajax_login_loadimg_path ) ? ajax_login_loadimg_path : scriptPath + '/images/loading-big.gif';
+			div.appendChild(img);
+			
+			// Insert the entire message into the login window
+			logindata.mb_inner.innerHTML = '';
+			logindata.mb_inner.appendChild(div);
+			
+			break;
+		case AJAX_STATUS_SUCCESS:
+			
+			// Create the status div
+			var div = document.createElement('div');
+			div.id = 'ajax_login_status';
+			div.style.marginTop = '10px';
+			div.style.textAlign = 'center';
+			
+			// The circly ball ajaxy image + status message
+			var status_msg = $lang.get('user_login_success_short');
+			
+			// Insert the status message
+			div.appendChild(document.createTextNode(status_msg));
+			
+			// Append a br or two to space things properly
+			div.appendChild(document.createElement('br'));
+			div.appendChild(document.createElement('br'));
+			
+			var img = document.createElement('img');
+			img.src = ( ajax_login_successimg_path ) ? ajax_login_successimg_path : scriptPath + '/images/check.png';
+			div.appendChild(img);
+			
+			// Insert the entire message into the login window
+			logindata.mb_inner.innerHTML = '';
+			logindata.mb_inner.appendChild(div);
+			
+			break;
+			
+		case AJAX_STATUS_ERROR:
+			// Create the status div
+			var div = document.createElement('div');
+			div.id = 'ajax_login_status';
+			div.style.marginTop = '10px';
+			div.style.textAlign = 'center';
+			
+			// The circly ball ajaxy image + status message
+			var status_msg = $lang.get('user_login_ajax_err_crypto');
+			
+			// Insert the status message
+			div.appendChild(document.createTextNode(status_msg));
+			
+			// Append a br or two to space things properly
+			div.appendChild(document.createElement('br'));
+			div.appendChild(document.createElement('br'));
+			
+			var img = document.createElement('img');
+			img.src = ( ajax_login_successimg_path ) ? ajax_login_successimg_path : scriptPath + '/images/checkbad.png';
+			div.appendChild(img);
+			
+			// Append a br or two to space things properly
+			div.appendChild(document.createElement('br'));
+			div.appendChild(document.createElement('br'));
+			
+			// The circly ball ajaxy image + status message
+			var detail_msg = $lang.get('user_login_ajax_err_crypto_details');
+			var full_link = $lang.get('user_login_ajax_err_crypto_link');
+			var link = document.createElement('a');
+			link.href = makeUrlNS('Special', 'Login/' + title, 'level=' + logindata.user_level, true);
+			link.appendChild(document.createTextNode(full_link));
+			var span = document.createElement('span');
+			span.style.fontSize = 'smaller';
+			
+			// Insert the message
+			span.appendChild(document.createTextNode(detail_msg + ' '));
+			span.appendChild(link);
+			div.appendChild(span);
+			
+			// Insert the entire message into the login window
+			logindata.mb_inner.innerHTML = '';
+			logindata.mb_inner.appendChild(div);
+			
+			break;
+			
+		default:
+			eval(setHook('login_set_status'));
+			break;
+			
+		case AJAX_STATUS_DESTROY:
+		case null:
+		case undefined:
+			logindata.showing_status = false;
+			return;
+			break;
+	}
+	logindata.showing_status = true;
 }
 
 /**
@@ -383,24 +383,24 @@
 
 window.ajaxLoginPerformRequest = function(json, _hookfunc)
 {
-  json = toJSONString(json);
-  json = ajaxEscape(json);
-  var hookfunc = typeof(_hookfunc) == 'function' ? _hookfunc : false;
-  ajaxPost(makeUrlNS('Special', 'Login/action.json'), 'r=' + json, function(ajax)
-    {
-      if ( ajax.readyState == 4 && ajax.status == 200 )
-      {
-        // parse response
-        var response = String(ajax.responseText + '');
-        if ( !check_json_response(response) )
-        {
-          handle_invalid_json(response);
-          return false;
-        }
-        response = parseJSON(response);
-        ajaxLoginProcessResponse(response, hookfunc);
-      }
-    }, true);
+	json = toJSONString(json);
+	json = ajaxEscape(json);
+	var hookfunc = typeof(_hookfunc) == 'function' ? _hookfunc : false;
+	ajaxPost(makeUrlNS('Special', 'Login/action.json'), 'r=' + json, function(ajax)
+		{
+			if ( ajax.readyState == 4 && ajax.status == 200 )
+			{
+				// parse response
+				var response = String(ajax.responseText + '');
+				if ( !check_json_response(response) )
+				{
+					handle_invalid_json(response);
+					return false;
+				}
+				response = parseJSON(response);
+				ajaxLoginProcessResponse(response, hookfunc);
+			}
+		}, true);
 }
 
 /**
@@ -410,78 +410,78 @@
 
 window.ajaxLoginProcessResponse = function(response, hookfunc)
 {
-  // Did the server send a plaintext error?
-  if ( response.mode == 'error' )
-  {
-    if ( logindata.mb_object )
-    {
-      logindata.mb_object.destroy();
-      var error_msg = $lang.get('user_' + ( response.error.toLowerCase() ));
-      new MessageBox(MB_ICONSTOP | MB_OK, $lang.get('user_err_login_generic_title'), error_msg);
-    }
-    else
-    {
-      alert(response.error);
-    }
-    return false;
-  }
-  
-  // Main mode switch
-  switch ( response.mode )
-  {
-    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;
-    case 'login_success':
-      ajaxLoginSetStatus(AJAX_STATUS_SUCCESS);
-      logindata.successfunc(response.key, response);
-      break;
-    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
-    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 )
-      {
-        ajaxLoginReplaceSIDInline(false, ENANO_SID, USER_LEVEL_MEMBER);
-      }
-      break;
-    case 'noop':
-      break;
-  }
-  if ( hookfunc )
-  {
-    hookfunc(response);
-  }
+	// Did the server send a plaintext error?
+	if ( response.mode == 'error' )
+	{
+		if ( logindata.mb_object )
+		{
+			logindata.mb_object.destroy();
+			var error_msg = $lang.get('user_' + ( response.error.toLowerCase() ));
+			new MessageBox(MB_ICONSTOP | MB_OK, $lang.get('user_err_login_generic_title'), error_msg);
+		}
+		else
+		{
+			alert(response.error);
+		}
+		return false;
+	}
+	
+	// Main mode switch
+	switch ( response.mode )
+	{
+		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;
+		case 'login_success':
+			ajaxLoginSetStatus(AJAX_STATUS_SUCCESS);
+			logindata.successfunc(response.key, response);
+			break;
+		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
+		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 )
+			{
+				ajaxLoginReplaceSIDInline(false, ENANO_SID, USER_LEVEL_MEMBER);
+			}
+			break;
+		case 'noop':
+			break;
+	}
+	if ( hookfunc )
+	{
+		hookfunc(response);
+	}
 }
 
 /*
@@ -495,837 +495,837 @@
 
 window.ajaxLoginBuildForm = function(data)
 {
-  // let's hope this effectively preloads the image...
-  var _1 = document.createElement('img');
-  _1.src = ( ajax_login_successimg_path ) ? ajax_login_successimg_path : scriptPath + '/images/check.png';
-  var _2 = document.createElement('img');
-  _2.src = ( ajax_login_lockimg_path ) ? ajax_login_lockimg_path : scriptPath + '/images/lock48.png';
-  
-  var div = document.createElement('div');
-  div.id = 'ajax_login_form';
-  
-  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 )
-  {
-    div.innerHTML += $lang.get('user_login_ajax_prompt_body_elev') + '<br /><br />';
-  }
-  
-  // Create the form
-  var form = document.createElement('form');
-  form.action = 'javascript:void(ajaxLoginSubmitForm());';
-  form.onsubmit = function()
-  {
-    ajaxLoginSubmitForm();
-    return false;
-  }
-  if ( IE )
-  {
-    form.style.marginTop = '-20px';
-  }
-  
-  // Using tables to wrap form elements because it results in a
-  // more visually appealing form. Yes, tables suck. I don't really
-  // care - they make forms look good.
-  
-  var table = document.createElement('table');
-  table.style.margin = '0 auto';
-  
-  // Field - username
-  var tr1 = document.createElement('tr');
-  var td1_1 = document.createElement('td');
-  td1_1.appendChild(document.createTextNode($lang.get('user_login_field_username') + ':'));
-  tr1.appendChild(td1_1);
-  var td1_2 = document.createElement('td');
-  var f_username = document.createElement('input');
-  f_username.id = 'ajax_login_field_username';
-  f_username.name = 'ajax_login_field_username';
-  f_username.type = 'text';
-  f_username.size = '25';
-  if ( data.username )
-    f_username.value = data.username;
-  td1_2.appendChild(f_username);
-  tr1.appendChild(td1_2);
-  table.appendChild(tr1);
-  
-  // Field - password
-  var tr2 = document.createElement('tr');
-  var td2_1 = document.createElement('td');
-  td2_1.appendChild(document.createTextNode($lang.get('user_login_field_password') + ':'));
-  tr2.appendChild(td2_1);
-  var td2_2 = document.createElement('td');
-  var f_password = document.createElement('input');
-  f_password.id = 'ajax_login_field_password';
-  f_password.name = 'ajax_login_field_username';
-  f_password.type = 'password';
-  f_password.size = '25';
-  if ( !show_captcha )
-  {
-    f_password.onkeyup = function(e)
-    {
-      if ( !e )
-        e = window.event;
-      if ( !e && IE )
-        return true;
-      if ( e.keyCode == 13 )
-      {
-        ajaxLoginSubmitForm();
-      }
-    }
-  }
-  td2_2.appendChild(f_password);
-  tr2.appendChild(td2_2);
-  table.appendChild(tr2);
-  
-  // Field - captcha
-  if ( show_captcha )
-  {
-    var tr3 = document.createElement('tr');
-    var td3_1 = document.createElement('td');
-    td3_1.appendChild(document.createTextNode($lang.get('user_login_field_captcha') + ':'));
-    tr3.appendChild(td3_1);
-    var td3_2 = document.createElement('td');
-    var f_captcha = document.createElement('input');
-    f_captcha.id = 'ajax_login_field_captcha';
-    f_captcha.name = 'ajax_login_field_username';
-    f_captcha.type = 'text';
-    f_captcha.size = '25';
-    f_captcha.onkeyup = function(e)
-    {
-      if ( !e )
-        e = window.event;
-      if ( !e.keyCode )
-        return true;
-      if ( e.keyCode == 13 )
-      {
-        ajaxLoginSubmitForm();
-      }
-    }
-    td3_2.appendChild(f_captcha);
-    tr3.appendChild(td3_2);
-    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);
-  
-  // Checkbox container
-  var boxen = document.createElement('div');
-  boxen.style.textAlign = 'center';
-  boxen.style.padding = '7px 0';
-  
-  // Field: remember login
-  if ( logindata.user_level <= USER_LEVEL_MEMBER )
-  {
-    var lbl_remember = document.createElement('label');
-    lbl_remember.style.fontSize = 'smaller';
-    lbl_remember.style.textAlign = 'center';
-    
-    // figure out what text to put in the "remember me" checkbox
-    // infinite session length?
-    if ( data.extended_time == 0 )
-    {
-      // yes, infinite
-      var txt_remember = $lang.get('user_login_ajax_check_remember_infinite');
-    }
-    else
-    {
-      if ( data.extended_time % 7 == 0 )
-      {
-        // number of days is a multiple of 7
-        // use weeks as our unit
-        var sess_time = data.extended_time / 7;
-        var unit = 'week';
-      }
-      else
-      {
-        // use days as our unit
-        var sess_time = data.extended_time;
-        var unit = 'day';
-      }
-      // more than one week or day?
-      if ( sess_time != 1 )
-        unit += 's';
-      
-      // assemble the string
-      var txt_remember = $lang.get('user_login_ajax_check_remember', {
-          session_length: sess_time,
-          length_units: $lang.get('etc_unit_' + unit)
-        });
-    }
-    var check_remember = document.createElement('input');
-    check_remember.type = 'checkbox';
-    // this onclick attribute changes the cookie whenever the checkbox or label is clicked
-    check_remember.setAttribute('onclick', 'var ck = ( this.checked ) ? "enable" : "disable"; createCookie("login_remember", ck, 3650);');
-    if ( readCookie('login_remember') != 'disable' )
-      check_remember.setAttribute('checked', 'checked');
-    check_remember.id = 'ajax_login_field_remember';
-    lbl_remember.appendChild(check_remember);
-    lbl_remember.innerHTML += ' ' + txt_remember;
-    
-    boxen.appendChild(lbl_remember);
-  }
-  
-  var bullet = document.createElement('span');
-  bullet.innerHTML = '&nbsp;';
-  bullet.style.fontSize = '12pt';
-  bullet.style.borderRight = '1px solid #aaa';
-  bullet.style.margin = '0 6px 0 4px';
-  
-  // Field: enable Diffie Hellman
-  if ( ajax_login_prevent_dh )
-  {
-    if ( logindata.user_level <= USER_LEVEL_MEMBER )
-      // only show this if both checkboxes are visible
-      boxen.appendChild(bullet);
-      
-    var lbl_dh = document.createElement('span');
-    lbl_dh.style.fontSize = 'smaller';
-    lbl_dh.style.textAlign = 'center';
-    lbl_dh.innerHTML = $lang.get('user_login_ajax_check_dh_ie');
-    boxen.appendChild(lbl_dh);
-  }
-  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');
-    check_dh.type = 'hidden';
-    check_dh.id = 'ajax_login_field_dh';
-    boxen.appendChild(check_dh);
-  }
-  else
-  {
-    if ( logindata.user_level <= USER_LEVEL_MEMBER )
-      // only show this if both checkboxes are visible
-      boxen.appendChild(bullet);
-    
-    var lbl_dh = document.createElement('label');
-    lbl_dh.style.fontSize = 'smaller';
-    lbl_dh.style.textAlign = 'center';
-    var check_dh = document.createElement('input');
-    check_dh.type = 'checkbox';
-    // this onclick attribute changes the cookie whenever the checkbox or label is clicked
-    check_dh.setAttribute('onclick', 'var ck = ( this.checked ) ? "enable" : "disable"; createCookie("diffiehellman_login", ck, 3650);');
-    if ( readCookie('diffiehellman_login') != 'disable' )
-      check_dh.setAttribute('checked', 'checked');
-    check_dh.id = 'ajax_login_field_dh';
-    lbl_dh.appendChild(check_dh);
-    lbl_dh.innerHTML += ' ' + $lang.get('user_login_ajax_check_dh');
-    boxen.appendChild(lbl_dh);
-  }
-  
-  form.appendChild(boxen);
-  
-  if ( IE )
-  {
-    div.innerHTML += form.outerHTML;
-  }
-  else
-  {
-    div.appendChild(form);
-  }
-  
-  // Diagnostic / help links
-  // (only displayed in login, not in re-auth)
-  if ( logindata.user_level == USER_LEVEL_MEMBER )
-  {
-    var links = document.createElement('small');
-    links.style.display = 'block';
-    links.style.textAlign = 'center';
-    links.innerHTML = '';
-    if ( !show_captcha )
-      links.innerHTML += $lang.get('user_login_ajax_link_fullform', { link_full_form: makeUrlNS('Special', 'Login/' + title) }) + ' &bull; ';
-    // Always shown
-    links.innerHTML += $lang.get('user_login_ajax_link_forgotpass', { forgotpass_link: makeUrlNS('Special', 'PasswordReset') }) + ' &bull; ';
-    if ( !show_captcha )
-      links.innerHTML += $lang.get('user_login_ajax_createaccount_blurb', { reg_link: makeUrlNS('Special', 'Register') });
-    div.appendChild(links);
-  }
-  
-  // Insert the entire form into the login window
-  logindata.mb_inner.innerHTML = '';
-  logindata.mb_inner.appendChild(div);
-  
-  // Post operations: field focus
-  setTimeout(
-    function()
-    {
-      if ( logindata.loggedin_username )
-        document.getElementById('ajax_login_field_password').focus();
-      else
-        document.getElementById('ajax_login_field_username').focus();
-    }, 750);        
-  
-  // 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.crypto.aes_key;
-  logindata.key_dh = data.crypto.dh_public_key;
-  logindata.captcha_hash = show_captcha;
-  logindata.loggedin_username = data.username;
-  
-  // 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');
-  }
+	// let's hope this effectively preloads the image...
+	var _1 = document.createElement('img');
+	_1.src = ( ajax_login_successimg_path ) ? ajax_login_successimg_path : scriptPath + '/images/check.png';
+	var _2 = document.createElement('img');
+	_2.src = ( ajax_login_lockimg_path ) ? ajax_login_lockimg_path : scriptPath + '/images/lock48.png';
+	
+	var div = document.createElement('div');
+	div.id = 'ajax_login_form';
+	
+	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 )
+	{
+		div.innerHTML += $lang.get('user_login_ajax_prompt_body_elev') + '<br /><br />';
+	}
+	
+	// Create the form
+	var form = document.createElement('form');
+	form.action = 'javascript:void(ajaxLoginSubmitForm());';
+	form.onsubmit = function()
+	{
+		ajaxLoginSubmitForm();
+		return false;
+	}
+	if ( IE )
+	{
+		form.style.marginTop = '-20px';
+	}
+	
+	// Using tables to wrap form elements because it results in a
+	// more visually appealing form. Yes, tables suck. I don't really
+	// care - they make forms look good.
+	
+	var table = document.createElement('table');
+	table.style.margin = '0 auto';
+	
+	// Field - username
+	var tr1 = document.createElement('tr');
+	var td1_1 = document.createElement('td');
+	td1_1.appendChild(document.createTextNode($lang.get('user_login_field_username') + ':'));
+	tr1.appendChild(td1_1);
+	var td1_2 = document.createElement('td');
+	var f_username = document.createElement('input');
+	f_username.id = 'ajax_login_field_username';
+	f_username.name = 'ajax_login_field_username';
+	f_username.type = 'text';
+	f_username.size = '25';
+	if ( data.username )
+		f_username.value = data.username;
+	td1_2.appendChild(f_username);
+	tr1.appendChild(td1_2);
+	table.appendChild(tr1);
+	
+	// Field - password
+	var tr2 = document.createElement('tr');
+	var td2_1 = document.createElement('td');
+	td2_1.appendChild(document.createTextNode($lang.get('user_login_field_password') + ':'));
+	tr2.appendChild(td2_1);
+	var td2_2 = document.createElement('td');
+	var f_password = document.createElement('input');
+	f_password.id = 'ajax_login_field_password';
+	f_password.name = 'ajax_login_field_username';
+	f_password.type = 'password';
+	f_password.size = '25';
+	if ( !show_captcha )
+	{
+		f_password.onkeyup = function(e)
+		{
+			if ( !e )
+				e = window.event;
+			if ( !e && IE )
+				return true;
+			if ( e.keyCode == 13 )
+			{
+				ajaxLoginSubmitForm();
+			}
+		}
+	}
+	td2_2.appendChild(f_password);
+	tr2.appendChild(td2_2);
+	table.appendChild(tr2);
+	
+	// Field - captcha
+	if ( show_captcha )
+	{
+		var tr3 = document.createElement('tr');
+		var td3_1 = document.createElement('td');
+		td3_1.appendChild(document.createTextNode($lang.get('user_login_field_captcha') + ':'));
+		tr3.appendChild(td3_1);
+		var td3_2 = document.createElement('td');
+		var f_captcha = document.createElement('input');
+		f_captcha.id = 'ajax_login_field_captcha';
+		f_captcha.name = 'ajax_login_field_username';
+		f_captcha.type = 'text';
+		f_captcha.size = '25';
+		f_captcha.onkeyup = function(e)
+		{
+			if ( !e )
+				e = window.event;
+			if ( !e.keyCode )
+				return true;
+			if ( e.keyCode == 13 )
+			{
+				ajaxLoginSubmitForm();
+			}
+		}
+		td3_2.appendChild(f_captcha);
+		tr3.appendChild(td3_2);
+		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);
+	
+	// Checkbox container
+	var boxen = document.createElement('div');
+	boxen.style.textAlign = 'center';
+	boxen.style.padding = '7px 0';
+	
+	// Field: remember login
+	if ( logindata.user_level <= USER_LEVEL_MEMBER )
+	{
+		var lbl_remember = document.createElement('label');
+		lbl_remember.style.fontSize = 'smaller';
+		lbl_remember.style.textAlign = 'center';
+		
+		// figure out what text to put in the "remember me" checkbox
+		// infinite session length?
+		if ( data.extended_time == 0 )
+		{
+			// yes, infinite
+			var txt_remember = $lang.get('user_login_ajax_check_remember_infinite');
+		}
+		else
+		{
+			if ( data.extended_time % 7 == 0 )
+			{
+				// number of days is a multiple of 7
+				// use weeks as our unit
+				var sess_time = data.extended_time / 7;
+				var unit = 'week';
+			}
+			else
+			{
+				// use days as our unit
+				var sess_time = data.extended_time;
+				var unit = 'day';
+			}
+			// more than one week or day?
+			if ( sess_time != 1 )
+				unit += 's';
+			
+			// assemble the string
+			var txt_remember = $lang.get('user_login_ajax_check_remember', {
+					session_length: sess_time,
+					length_units: $lang.get('etc_unit_' + unit)
+				});
+		}
+		var check_remember = document.createElement('input');
+		check_remember.type = 'checkbox';
+		// this onclick attribute changes the cookie whenever the checkbox or label is clicked
+		check_remember.setAttribute('onclick', 'var ck = ( this.checked ) ? "enable" : "disable"; createCookie("login_remember", ck, 3650);');
+		if ( readCookie('login_remember') != 'disable' )
+			check_remember.setAttribute('checked', 'checked');
+		check_remember.id = 'ajax_login_field_remember';
+		lbl_remember.appendChild(check_remember);
+		lbl_remember.innerHTML += ' ' + txt_remember;
+		
+		boxen.appendChild(lbl_remember);
+	}
+	
+	var bullet = document.createElement('span');
+	bullet.innerHTML = '&nbsp;';
+	bullet.style.fontSize = '12pt';
+	bullet.style.borderRight = '1px solid #aaa';
+	bullet.style.margin = '0 6px 0 4px';
+	
+	// Field: enable Diffie Hellman
+	if ( ajax_login_prevent_dh )
+	{
+		if ( logindata.user_level <= USER_LEVEL_MEMBER )
+			// only show this if both checkboxes are visible
+			boxen.appendChild(bullet);
+			
+		var lbl_dh = document.createElement('span');
+		lbl_dh.style.fontSize = 'smaller';
+		lbl_dh.style.textAlign = 'center';
+		lbl_dh.innerHTML = $lang.get('user_login_ajax_check_dh_ie');
+		boxen.appendChild(lbl_dh);
+	}
+	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');
+		check_dh.type = 'hidden';
+		check_dh.id = 'ajax_login_field_dh';
+		boxen.appendChild(check_dh);
+	}
+	else
+	{
+		if ( logindata.user_level <= USER_LEVEL_MEMBER )
+			// only show this if both checkboxes are visible
+			boxen.appendChild(bullet);
+		
+		var lbl_dh = document.createElement('label');
+		lbl_dh.style.fontSize = 'smaller';
+		lbl_dh.style.textAlign = 'center';
+		var check_dh = document.createElement('input');
+		check_dh.type = 'checkbox';
+		// this onclick attribute changes the cookie whenever the checkbox or label is clicked
+		check_dh.setAttribute('onclick', 'var ck = ( this.checked ) ? "enable" : "disable"; createCookie("diffiehellman_login", ck, 3650);');
+		if ( readCookie('diffiehellman_login') != 'disable' )
+			check_dh.setAttribute('checked', 'checked');
+		check_dh.id = 'ajax_login_field_dh';
+		lbl_dh.appendChild(check_dh);
+		lbl_dh.innerHTML += ' ' + $lang.get('user_login_ajax_check_dh');
+		boxen.appendChild(lbl_dh);
+	}
+	
+	form.appendChild(boxen);
+	
+	if ( IE )
+	{
+		div.innerHTML += form.outerHTML;
+	}
+	else
+	{
+		div.appendChild(form);
+	}
+	
+	// Diagnostic / help links
+	// (only displayed in login, not in re-auth)
+	if ( logindata.user_level == USER_LEVEL_MEMBER )
+	{
+		var links = document.createElement('small');
+		links.style.display = 'block';
+		links.style.textAlign = 'center';
+		links.innerHTML = '';
+		if ( !show_captcha )
+			links.innerHTML += $lang.get('user_login_ajax_link_fullform', { link_full_form: makeUrlNS('Special', 'Login/' + title) }) + ' &bull; ';
+		// Always shown
+		links.innerHTML += $lang.get('user_login_ajax_link_forgotpass', { forgotpass_link: makeUrlNS('Special', 'PasswordReset') }) + ' &bull; ';
+		if ( !show_captcha )
+			links.innerHTML += $lang.get('user_login_ajax_createaccount_blurb', { reg_link: makeUrlNS('Special', 'Register') });
+		div.appendChild(links);
+	}
+	
+	// Insert the entire form into the login window
+	logindata.mb_inner.innerHTML = '';
+	logindata.mb_inner.appendChild(div);
+	
+	// Post operations: field focus
+	setTimeout(
+		function()
+		{
+			if ( logindata.loggedin_username )
+				document.getElementById('ajax_login_field_password').focus();
+			else
+				document.getElementById('ajax_login_field_username').focus();
+		}, 750);        
+	
+	// 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.crypto.aes_key;
+	logindata.key_dh = data.crypto.dh_public_key;
+	logindata.captcha_hash = show_captcha;
+	logindata.loggedin_username = data.username;
+	
+	// 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');
+	}
 }
 
 window.ajaxLoginSubmitForm = function(real, username, password, captcha, remember)
 {
-  // Perform AES test to make sure it's all working
-  if ( !aes_self_test() )
-  {
-    alert('BUG: AES self-test failed');
-    login_cache.mb_object.destroy();
-    return false;
-  }
-  // 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'));
-  }
-  if ( document.getElementById('autoCaptcha') )
-  {
-    var to = fly_out_top(document.getElementById('autoCaptcha'), false, true);
-    setTimeout(function() {
-        var d = document.getElementById('autoCaptcha');
-        d.parentNode.removeChild(d);
-      }, to);
-  }
-  // "Remember session" switch
-  if ( typeof(remember) == 'boolean' )
-  {
-    var remember_session = remember;
-  }
-  else
-  {
-    if ( document.getElementById('ajax_login_field_remember') )
-    {
-      var remember_session = ( document.getElementById('ajax_login_field_remember').checked ) ? true : false;
-    }
-    else
-    {
-      var remember_session = false;
-    }
-  }
-  // Encryption: preprocessor
-  if ( real )
-  {
-    var do_dh = true;
-  }
-  else if ( document.getElementById('ajax_login_field_dh') )
-  {
-    var do_dh = document.getElementById('ajax_login_field_dh').checked;
-  }
-  else
-  {
-    if ( ajax_login_prevent_dh )
-    {
-      // IE/MobileSafari doesn't have this control, continue silently IF the rest
-      // of the login form is there
-      if ( !document.getElementById('ajax_login_field_username') )
-      {
-        return false;
-      }
-    }
-    else
-    {
-      // The user probably clicked ok when the form wasn't in there.
-      return false;
-    }
-  }
-  
-  if ( typeof(username) != 'string' )
-  {
-    var username = document.getElementById('ajax_login_field_username').value;
-  }
-  if ( typeof(password) != 'string' )
-  {
-    var password = document.getElementById('ajax_login_field_password').value;
-  }
-  if ( !captcha && document.getElementById('ajax_login_field_captcha') )
-  {
-    var captcha = document.getElementById('ajax_login_field_captcha').value;
-  }
-  
-  // Only run early submit hook once
-  if ( !window.logindata.early_submit_run )
-    eval(setHook('login_submit_early'));
-  
-  window.logindata.early_submit_run = true;
-  
-  try
-  {
-  
-  if ( do_dh )
-  {
-    ajaxLoginSetStatus(AJAX_STATUS_GENERATING_KEY);
-    if ( !real )
-    {
-      // Wait while the browser updates the login window
-      setTimeout(function()
-        {
-          ajaxLoginSubmitForm(true, username, password, captcha, remember_session);
-        }, 20);
-      return true;
-    }
-    var dh_start = (new Date()).getTime();
-    // Perform Diffie Hellman stuff
-    var dh_priv = dh_gen_private();
-    var dh_pub = dh_gen_public(dh_priv);
-    var secret = dh_gen_shared_secret(dh_priv, logindata.key_dh);
-    // secret_hash is used to verify that the server guesses the correct secret
-    var secret_hash = hex_sha1(secret);
-    // crypt_key is the actual AES key
-    var crypt_key = (hex_sha256(secret)).substr(0, (keySizeInBits / 4));
-    var dh_time = (new Date()).getTime() - dh_start;
-    console.debug("DH: complete, time = %dms", dh_time);
-  }
-  else
-  {
-    var crypt_key = logindata.key_aes;
-  }
-  
-  ajaxLoginSetStatus(AJAX_STATUS_LOGGING_IN);
-  
-  // Encrypt the password and username
-  var userinfo = {
-      username: username,
-      password: password
-    };
-    
-  eval(setHook('login_build_userinfo'));
-    
-  userinfo = toJSONString(userinfo);
-  var crypt_key_ba = hexToByteArray(crypt_key);
-  userinfo = stringToByteArray(userinfo);
-  
-  userinfo = rijndaelEncrypt(userinfo, crypt_key_ba, 'ECB');
-  userinfo = byteArrayToHex(userinfo);
-  // Encrypted username and password (serialized with JSON) are now in the userinfo string
-  
-  // Collect other needed information
-  if ( logindata.captcha_hash )
-  {
-    var captcha_hash = logindata.captcha_hash;
-    var captcha_code = captcha;
-  }
-  else
-  {
-    var captcha_hash = false;
-    var captcha_code = false;
-  }
-  
-  // Ship it across the 'net
-  if ( do_dh )
-  {
-    var json_packet = {
-      mode: 'login_dh',
-      userinfo: userinfo,
-      captcha_code: captcha_code,
-      captcha_hash: captcha_hash,
-      dh_public_key: logindata.key_dh,
-      dh_client_key: dh_pub,
-      dh_secret_hash: secret_hash,
-      level: logindata.user_level,
-      remember: remember_session
-    }
-  }
-  else
-  {
-    var json_packet = {
-      mode: 'login_aes',
-      userinfo: userinfo,
-      captcha_code: captcha_code,
-      captcha_hash: captcha_hash,
-      key_aes: hex_md5(crypt_key),
-      level: logindata.user_level,
-      remember: remember_session
-    }
-  }
-  }
-  catch(e)
-  {
-    ajaxLoginSetStatus(AJAX_STATUS_ERROR);
-    console.error('Exception caught in login process; backtrace follows');
-    console.debug(e);
-    return false;
-  }
-  // reset this...
-  window.logindata.early_submit_run = false;
-  ajaxLoginPerformRequest(json_packet);
+	// Perform AES test to make sure it's all working
+	if ( !aes_self_test() )
+	{
+		alert('BUG: AES self-test failed');
+		login_cache.mb_object.destroy();
+		return false;
+	}
+	// 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'));
+	}
+	if ( document.getElementById('autoCaptcha') )
+	{
+		var to = fly_out_top(document.getElementById('autoCaptcha'), false, true);
+		setTimeout(function() {
+				var d = document.getElementById('autoCaptcha');
+				d.parentNode.removeChild(d);
+			}, to);
+	}
+	// "Remember session" switch
+	if ( typeof(remember) == 'boolean' )
+	{
+		var remember_session = remember;
+	}
+	else
+	{
+		if ( document.getElementById('ajax_login_field_remember') )
+		{
+			var remember_session = ( document.getElementById('ajax_login_field_remember').checked ) ? true : false;
+		}
+		else
+		{
+			var remember_session = false;
+		}
+	}
+	// Encryption: preprocessor
+	if ( real )
+	{
+		var do_dh = true;
+	}
+	else if ( document.getElementById('ajax_login_field_dh') )
+	{
+		var do_dh = document.getElementById('ajax_login_field_dh').checked;
+	}
+	else
+	{
+		if ( ajax_login_prevent_dh )
+		{
+			// IE/MobileSafari doesn't have this control, continue silently IF the rest
+			// of the login form is there
+			if ( !document.getElementById('ajax_login_field_username') )
+			{
+				return false;
+			}
+		}
+		else
+		{
+			// The user probably clicked ok when the form wasn't in there.
+			return false;
+		}
+	}
+	
+	if ( typeof(username) != 'string' )
+	{
+		var username = document.getElementById('ajax_login_field_username').value;
+	}
+	if ( typeof(password) != 'string' )
+	{
+		var password = document.getElementById('ajax_login_field_password').value;
+	}
+	if ( !captcha && document.getElementById('ajax_login_field_captcha') )
+	{
+		var captcha = document.getElementById('ajax_login_field_captcha').value;
+	}
+	
+	// Only run early submit hook once
+	if ( !window.logindata.early_submit_run )
+		eval(setHook('login_submit_early'));
+	
+	window.logindata.early_submit_run = true;
+	
+	try
+	{
+	
+	if ( do_dh )
+	{
+		ajaxLoginSetStatus(AJAX_STATUS_GENERATING_KEY);
+		if ( !real )
+		{
+			// Wait while the browser updates the login window
+			setTimeout(function()
+				{
+					ajaxLoginSubmitForm(true, username, password, captcha, remember_session);
+				}, 20);
+			return true;
+		}
+		var dh_start = (new Date()).getTime();
+		// Perform Diffie Hellman stuff
+		var dh_priv = dh_gen_private();
+		var dh_pub = dh_gen_public(dh_priv);
+		var secret = dh_gen_shared_secret(dh_priv, logindata.key_dh);
+		// secret_hash is used to verify that the server guesses the correct secret
+		var secret_hash = hex_sha1(secret);
+		// crypt_key is the actual AES key
+		var crypt_key = (hex_sha256(secret)).substr(0, (keySizeInBits / 4));
+		var dh_time = (new Date()).getTime() - dh_start;
+		console.debug("DH: complete, time = %dms", dh_time);
+	}
+	else
+	{
+		var crypt_key = logindata.key_aes;
+	}
+	
+	ajaxLoginSetStatus(AJAX_STATUS_LOGGING_IN);
+	
+	// Encrypt the password and username
+	var userinfo = {
+			username: username,
+			password: password
+		};
+		
+	eval(setHook('login_build_userinfo'));
+		
+	userinfo = toJSONString(userinfo);
+	var crypt_key_ba = hexToByteArray(crypt_key);
+	userinfo = stringToByteArray(userinfo);
+	
+	userinfo = rijndaelEncrypt(userinfo, crypt_key_ba, 'ECB');
+	userinfo = byteArrayToHex(userinfo);
+	// Encrypted username and password (serialized with JSON) are now in the userinfo string
+	
+	// Collect other needed information
+	if ( logindata.captcha_hash )
+	{
+		var captcha_hash = logindata.captcha_hash;
+		var captcha_code = captcha;
+	}
+	else
+	{
+		var captcha_hash = false;
+		var captcha_code = false;
+	}
+	
+	// Ship it across the 'net
+	if ( do_dh )
+	{
+		var json_packet = {
+			mode: 'login_dh',
+			userinfo: userinfo,
+			captcha_code: captcha_code,
+			captcha_hash: captcha_hash,
+			dh_public_key: logindata.key_dh,
+			dh_client_key: dh_pub,
+			dh_secret_hash: secret_hash,
+			level: logindata.user_level,
+			remember: remember_session
+		}
+	}
+	else
+	{
+		var json_packet = {
+			mode: 'login_aes',
+			userinfo: userinfo,
+			captcha_code: captcha_code,
+			captcha_hash: captcha_hash,
+			key_aes: hex_md5(crypt_key),
+			level: logindata.user_level,
+			remember: remember_session
+		}
+	}
+	}
+	catch(e)
+	{
+		ajaxLoginSetStatus(AJAX_STATUS_ERROR);
+		console.error('Exception caught in login process; backtrace follows');
+		console.debug(e);
+		return false;
+	}
+	// reset this...
+	window.logindata.early_submit_run = false;
+	ajaxLoginPerformRequest(json_packet);
 }
 
 window.ajaxLoginShowFriendlyError = function(response)
 {
-  var text = ajaxLoginGetErrorText(response);
-  if ( text == false )
-    return true;
-    
-  if ( document.getElementById('ajax_login_error_box') )
-  {
-    // console.info('Reusing existing error-box');
-    document.getElementById('ajax_login_error_box').innerHTML = text;
-    return true;
-  }
-  
-  // console.info('Drawing new error-box');
-  
-  // calculate position for the top of the box
-  var mb_bottom = $dynano('messageBoxButtons').Top() + $dynano('messageBoxButtons').Height();
-  // if the box isn't done flying in yet, just estimate
-  if ( mb_bottom < ( getHeight() / 2 ) )
-  {
-    mb_bottom = ( getHeight() / 2 ) + 120;
-  }
-  var win_bottom = getHeight() + getScrollOffset();
-  var top = mb_bottom + ( ( win_bottom - mb_bottom ) / 2 ) - 32;
-  // left position = 0.2 * window_width, seeing as the box is 60% width this works hackishly but nice and quick
-  var left = getWidth() * 0.2;
-  
-  // create the div
-  var errbox = document.createElement('div');
-  errbox.className = 'error-box-mini';
-  errbox.style.position = 'absolute';
-  errbox.style.width = '60%';
-  errbox.style.top = top + 'px';
-  errbox.style.left = left + 'px';
-  errbox.style.zIndex = getHighestZ();
-  errbox.innerHTML = text;
-  errbox.id = 'ajax_login_error_box';
-  
-  var body = document.getElementsByTagName('body')[0];
-  body.appendChild(errbox);
+	var text = ajaxLoginGetErrorText(response);
+	if ( text == false )
+		return true;
+		
+	if ( document.getElementById('ajax_login_error_box') )
+	{
+		// console.info('Reusing existing error-box');
+		document.getElementById('ajax_login_error_box').innerHTML = text;
+		return true;
+	}
+	
+	// console.info('Drawing new error-box');
+	
+	// calculate position for the top of the box
+	var mb_bottom = $dynano('messageBoxButtons').Top() + $dynano('messageBoxButtons').Height();
+	// if the box isn't done flying in yet, just estimate
+	if ( mb_bottom < ( getHeight() / 2 ) )
+	{
+		mb_bottom = ( getHeight() / 2 ) + 120;
+	}
+	var win_bottom = getHeight() + getScrollOffset();
+	var top = mb_bottom + ( ( win_bottom - mb_bottom ) / 2 ) - 32;
+	// left position = 0.2 * window_width, seeing as the box is 60% width this works hackishly but nice and quick
+	var left = getWidth() * 0.2;
+	
+	// create the div
+	var errbox = document.createElement('div');
+	errbox.className = 'error-box-mini';
+	errbox.style.position = 'absolute';
+	errbox.style.width = '60%';
+	errbox.style.top = top + 'px';
+	errbox.style.left = left + 'px';
+	errbox.style.zIndex = getHighestZ();
+	errbox.innerHTML = text;
+	errbox.id = 'ajax_login_error_box';
+	
+	var body = document.getElementsByTagName('body')[0];
+	body.appendChild(errbox);
 }
 
 window.ajaxLoginGetErrorText = function(response)
 {
-  if ( response.lockout )
-  {
-    // set this pluralality thing
-    response.lockout.plural = response.lockout.time_rem == 1 ? '' : $lang.get('meta_plural');
-  }
-  
-  if ( response.mode == 'initial' )
-  {
-    // 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 || ! (/^[a-z0-9_]+/).test(response.error) )
-          error = x;
-        else
-          error = $lang.get('user_err_' + response.error);
-        if ( response.lockout.active && response.lockout.policy == 'lockout' )
-        {
-          // 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);
-        }
-        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;
+	if ( response.lockout )
+	{
+		// set this pluralality thing
+		response.lockout.plural = response.lockout.time_rem == 1 ? '' : $lang.get('meta_plural');
+	}
+	
+	if ( response.mode == 'initial' )
+	{
+		// 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 || ! (/^[a-z0-9_]+/).test(response.error) )
+					error = x;
+				else
+					error = $lang.get('user_err_' + response.error);
+				if ( response.lockout.active && response.lockout.policy == 'lockout' )
+				{
+					// 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);
+				}
+				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)
 {
-  var mydiv = document.createElement('div');
-  mydiv.style.backgroundColor = '#FFFFFF';
-  mydiv.style.padding = '10px';
-  mydiv.style.position = 'absolute';
-  mydiv.style.top = '0px';
-  mydiv.id = 'autoCaptcha';
-  mydiv.style.zIndex = String( getHighestZ() + 1 );
-  var img = document.createElement('img');
-  img.onload = function()
-  {
-    if ( this.loaded )
-      return true;
-    var mydiv = document.getElementById('autoCaptcha');
-    var width = getWidth();
-    var divw = $dynano(mydiv).Width();
-    var left = ( width / 2 ) - ( divw / 2 );
-    mydiv.style.left = left + 'px';
-    fly_in_top(mydiv, false, true);
-    this.loaded = true;
-  };
-  img.src = makeUrlNS('Special', 'Captcha/' + code);
-  img.onclick = function() { this.src = this.src + '/a'; };
-  img.style.cursor = 'pointer';
-  mydiv.appendChild(img);
-  domObjChangeOpac(0, mydiv);
-  var body = document.getElementsByTagName('body')[0];
-  body.appendChild(mydiv);
+	var mydiv = document.createElement('div');
+	mydiv.style.backgroundColor = '#FFFFFF';
+	mydiv.style.padding = '10px';
+	mydiv.style.position = 'absolute';
+	mydiv.style.top = '0px';
+	mydiv.id = 'autoCaptcha';
+	mydiv.style.zIndex = String( getHighestZ() + 1 );
+	var img = document.createElement('img');
+	img.onload = function()
+	{
+		if ( this.loaded )
+			return true;
+		var mydiv = document.getElementById('autoCaptcha');
+		var width = getWidth();
+		var divw = $dynano(mydiv).Width();
+		var left = ( width / 2 ) - ( divw / 2 );
+		mydiv.style.left = left + 'px';
+		fly_in_top(mydiv, false, true);
+		this.loaded = true;
+	};
+	img.src = makeUrlNS('Special', 'Captcha/' + code);
+	img.onclick = function() { this.src = this.src + '/a'; };
+	img.style.cursor = 'pointer';
+	mydiv.appendChild(img);
+	domObjChangeOpac(0, mydiv);
+	var body = document.getElementsByTagName('body')[0];
+	body.appendChild(mydiv);
 }
 
 window.ajaxInitLogout = function()
 {
-  load_component(['messagebox', 'l10n', 'flyin', 'fadefilter', 'jquery', 'jquery-ui']);
-  
-  var title = $lang.get('user_logout_confirm_title');
-  var message = ( auth_level > USER_LEVEL_MEMBER ) ? $lang.get('user_logout_confirm_body_nelev') : $lang.get('user_logout_confirm_body_normal');
-  var buttons = [];
-  buttons.push({
-      text: $lang.get('user_logout_confirm_btn_logout'),
-      color: 'red',
-      style: {
-        fontWeight: 'bold'
-      },
-      onclick: function()
-      {
-        miniPromptDestroy(this);
-        window.location = makeUrlNS('Special', 'Logout/' + csrf_token + '/' + window.title);
-        return false;
-      }
-    });
-  if ( auth_level > USER_LEVEL_MEMBER )
-  {
-    buttons.push({
-        text: $lang.get('user_logout_confirm_btn_deauth'),
-        color: 'blue',
-        onclick: function()
-        {
-          var mp = miniPromptGetParent(this);
-          var whitey = whiteOutMiniPrompt(mp);
-          
-          ajaxLoginPerformRequest({
-              mode:  'logout',
-              level: auth_level,
-              csrf_token: csrf_token
-          }, function(response)
-            {
-              whiteOutReportSuccess(whitey);
-            });
-          return false;
-        }
-      });
-  }
-  buttons.push({
-      text: $lang.get('etc_cancel'),
-      onclick: function()
-      {
-        miniPromptDestroy(this);
-        return false;
-      }
-    });
-  
-  miniPromptMessage({
-      title: title,
-      message: message,
-      buttons: buttons
-  });
+	load_component(['messagebox', 'l10n', 'flyin', 'fadefilter', 'jquery', 'jquery-ui']);
+	
+	var title = $lang.get('user_logout_confirm_title');
+	var message = ( auth_level > USER_LEVEL_MEMBER ) ? $lang.get('user_logout_confirm_body_nelev') : $lang.get('user_logout_confirm_body_normal');
+	var buttons = [];
+	buttons.push({
+			text: $lang.get('user_logout_confirm_btn_logout'),
+			color: 'red',
+			style: {
+				fontWeight: 'bold'
+			},
+			onclick: function()
+			{
+				miniPromptDestroy(this);
+				window.location = makeUrlNS('Special', 'Logout/' + csrf_token + '/' + window.title);
+				return false;
+			}
+		});
+	if ( auth_level > USER_LEVEL_MEMBER )
+	{
+		buttons.push({
+				text: $lang.get('user_logout_confirm_btn_deauth'),
+				color: 'blue',
+				onclick: function()
+				{
+					var mp = miniPromptGetParent(this);
+					var whitey = whiteOutMiniPrompt(mp);
+					
+					ajaxLoginPerformRequest({
+							mode:  'logout',
+							level: auth_level,
+							csrf_token: csrf_token
+					}, function(response)
+						{
+							whiteOutReportSuccess(whitey);
+						});
+					return false;
+				}
+			});
+	}
+	buttons.push({
+			text: $lang.get('etc_cancel'),
+			onclick: function()
+			{
+				miniPromptDestroy(this);
+				return false;
+			}
+		});
+	
+	miniPromptMessage({
+			title: title,
+			message: message,
+			buttons: buttons
+	});
 }
 
 window.mb_logout = function()
 {
-  ajaxInitLogout();
+	ajaxInitLogout();
 }
 
 window.ajaxStartLogin = function()
 {
-  ajaxLogonToMember();
+	ajaxLogonToMember();
 }
 
 window.ajaxStartAdminLogin = function()
 {
-  // IE <6 pseudo-compatibility
-  if ( KILL_SWITCH )
-    return true;
-  if ( auth_level < USER_LEVEL_ADMIN )
-  {
-    ajaxLoginInit(function(k) {
-      ENANO_SID = k;
-      auth_level = USER_LEVEL_ADMIN;
-      var loc = makeUrlNS('Special', 'Administration');
-      if ( (ENANO_SID + ' ').length > 1 )
-        window.location = loc;
-    }, USER_LEVEL_ADMIN);
-    return false;
-  }
-  var loc = makeUrlNS('Special', 'Administration');
-  window.location = loc;
+	// IE <6 pseudo-compatibility
+	if ( KILL_SWITCH )
+		return true;
+	if ( auth_level < USER_LEVEL_ADMIN )
+	{
+		ajaxLoginInit(function(k) {
+			ENANO_SID = k;
+			auth_level = USER_LEVEL_ADMIN;
+			var loc = makeUrlNS('Special', 'Administration');
+			if ( (ENANO_SID + ' ').length > 1 )
+				window.location = loc;
+		}, USER_LEVEL_ADMIN);
+		return false;
+	}
+	var loc = makeUrlNS('Special', 'Administration');
+	window.location = loc;
 }
 
 window.ajaxAdminPage = function()
 {
-  // IE <6 pseudo-compatibility
-  if ( KILL_SWITCH )
-    return true;
-  if ( auth_level < USER_LEVEL_ADMIN )
-  {
-    ajaxPromptAdminAuth(function(k) {
-      ENANO_SID = k;
-      auth_level = USER_LEVEL_ADMIN;
-      var loc = String(window.location + '');
-      window.location = append_sid(loc);
-      var loc = makeUrlNS('Special', 'Administration', 'module=' + namespace_list['Admin'] + 'PageManager&source=ajax&page_id=' + ajaxEscape(title));
-      if ( (ENANO_SID + ' ').length > 1 )
-        window.location = loc;
-    }, 9);
-    return false;
-  }
-  var loc = makeUrlNS('Special', 'Administration', 'module=' + namespace_list['Admin'] + 'PageManager&source=ajax&page_id=' + ajaxEscape(title));
-  window.location = loc;
+	// IE <6 pseudo-compatibility
+	if ( KILL_SWITCH )
+		return true;
+	if ( auth_level < USER_LEVEL_ADMIN )
+	{
+		ajaxPromptAdminAuth(function(k) {
+			ENANO_SID = k;
+			auth_level = USER_LEVEL_ADMIN;
+			var loc = String(window.location + '');
+			window.location = append_sid(loc);
+			var loc = makeUrlNS('Special', 'Administration', 'module=' + namespace_list['Admin'] + 'PageManager&source=ajax&page_id=' + ajaxEscape(title));
+			if ( (ENANO_SID + ' ').length > 1 )
+				window.location = loc;
+		}, 9);
+		return false;
+	}
+	var loc = makeUrlNS('Special', 'Administration', 'module=' + namespace_list['Admin'] + 'PageManager&source=ajax&page_id=' + ajaxEscape(title));
+	window.location = loc;
 }
 
 window.ajaxLoginNavTo = function(namespace, page_id, min_level, get)
 {
-  // IE <6 pseudo-compatibility
-  if ( KILL_SWITCH )
-    return true;
-  void(namespace);
-  void(page_id);
-  get = get || false;
-  if ( auth_level < min_level )
-  {
-    ajaxPromptAdminAuth(function(k) {
-      ENANO_SID = k;
-      auth_level = min_level;
-      var loc = makeUrlNS(namespace, page_id, get);
-      if ( (ENANO_SID + ' ').length > 1 )
-        window.location = loc;
-    }, min_level);
-    return false;
-  }
-  var loc = makeUrlNS(namespace, page_id, get);
-  window.location = loc;
+	// IE <6 pseudo-compatibility
+	if ( KILL_SWITCH )
+		return true;
+	void(namespace);
+	void(page_id);
+	get = get || false;
+	if ( auth_level < min_level )
+	{
+		ajaxPromptAdminAuth(function(k) {
+			ENANO_SID = k;
+			auth_level = min_level;
+			var loc = makeUrlNS(namespace, page_id, get);
+			if ( (ENANO_SID + ' ').length > 1 )
+				window.location = loc;
+		}, min_level);
+		return false;
+	}
+	var loc = makeUrlNS(namespace, page_id, get);
+	window.location = loc;
 }
 
 window.ajaxAdminUser = function(username)
 {
-  // IE <6 pseudo-compatibility
-  if ( KILL_SWITCH )
-    return true;
-  if ( auth_level < USER_LEVEL_ADMIN )
-  {
-    ajaxPromptAdminAuth(function(k) {
-      ENANO_SID = k;
-      auth_level = USER_LEVEL_ADMIN;
-      var loc = String(window.location + '');
-      window.location = append_sid(loc);
-      var loc = makeUrlNS('Special', 'Administration', 'module=' + namespace_list['Admin'] + 'UserManager&src=get&user=' + ajaxEscape(username));
-      if ( (ENANO_SID + ' ').length > 1 )
-        window.location = loc;
-    }, 9);
-    return false;
-  }
-  var loc = makeUrlNS('Special', 'Administration', 'module=' + namespace_list['Admin'] + 'UserManager&src=get&user=' + ajaxEscape(username));
-  window.location = loc;
+	// IE <6 pseudo-compatibility
+	if ( KILL_SWITCH )
+		return true;
+	if ( auth_level < USER_LEVEL_ADMIN )
+	{
+		ajaxPromptAdminAuth(function(k) {
+			ENANO_SID = k;
+			auth_level = USER_LEVEL_ADMIN;
+			var loc = String(window.location + '');
+			window.location = append_sid(loc);
+			var loc = makeUrlNS('Special', 'Administration', 'module=' + namespace_list['Admin'] + 'UserManager&src=get&user=' + ajaxEscape(username));
+			if ( (ENANO_SID + ' ').length > 1 )
+				window.location = loc;
+		}, 9);
+		return false;
+	}
+	var loc = makeUrlNS('Special', 'Administration', 'module=' + namespace_list['Admin'] + 'UserManager&src=get&user=' + ajaxEscape(username));
+	window.location = loc;
 }
 
 window.ajaxDynamicReauth = function(adminpage, level)
 {
-  if ( auth_level < USER_LEVEL_MEMBER )
-  {
-    ajaxStartLogin();
-    return false;
-  }
-  
-  var old_sid = ENANO_SID;
-  var targetpage = adminpage;
-  if ( !level )
-  {
-    level = USER_LEVEL_ADMIN;
-  }
-  
-  ajaxLogonInit(function(k, response)
-    {
-      ajaxLoginReplaceSIDInline(k, old_sid, level);
-      window.user_id = response.user_id;
-      window.user_level = response.user_level;
-      mb_current_obj.destroy();
-      if ( typeof(targetpage) == 'string' )
-      {
-        ajaxPage(targetpage);
-      }
-      else if ( typeof(targetpage) == 'function' )
-      {
-        targetpage(k);
-      }
-    }, level);
-  if ( typeof(adminpage) == 'string' )
-  {
-    ajaxLoginShowFriendlyError({
-        error_code: 'admin_session_timed_out',
-        respawn_info: {}
-    });
-  }
+	if ( auth_level < USER_LEVEL_MEMBER )
+	{
+		ajaxStartLogin();
+		return false;
+	}
+	
+	var old_sid = ENANO_SID;
+	var targetpage = adminpage;
+	if ( !level )
+	{
+		level = USER_LEVEL_ADMIN;
+	}
+	
+	ajaxLogonInit(function(k, response)
+		{
+			ajaxLoginReplaceSIDInline(k, old_sid, level);
+			window.user_id = response.user_id;
+			window.user_level = response.user_level;
+			mb_current_obj.destroy();
+			if ( typeof(targetpage) == 'string' )
+			{
+				ajaxPage(targetpage);
+			}
+			else if ( typeof(targetpage) == 'function' )
+			{
+				targetpage(k);
+			}
+		}, level);
+	if ( typeof(adminpage) == 'string' )
+	{
+		ajaxLoginShowFriendlyError({
+				error_code: 'admin_session_timed_out',
+				respawn_info: {}
+		});
+	}
 }
 
 window.ajaxRenewSession = function()
 {
-  ajaxDynamicReauth(false);
+	ajaxDynamicReauth(false);
 }
 
 window.ajaxTrashElevSession = function()
 {
-  load_component(['messagebox', 'fadefilter', 'l10n', 'flyin', 'jquery', 'jquery-ui']);
-  miniPromptMessage({
-    title: $lang.get('user_logout_confirm_title_elev'),
-    message: $lang.get('user_logout_confirm_body_elev'),
-    buttons: [
-      {
-        text: $lang.get('user_logout_confirm_btn_logout'),
-        color: 'red',
-        style: {
-          fontWeight: 'bold'
-        },
-        onclick: function()
-        {
-          ajaxLoginPerformRequest({
-              mode:  'logout',
-              level: auth_level,
-              csrf_token: csrf_token
-          });
-          miniPromptDestroy(this);
-        }
-      },
-      {
-        text: $lang.get('etc_cancel'),
-        onclick: function()
-        {
-          miniPromptDestroy(this);
-        }
-      }
-    ]
-  });
+	load_component(['messagebox', 'fadefilter', 'l10n', 'flyin', 'jquery', 'jquery-ui']);
+	miniPromptMessage({
+		title: $lang.get('user_logout_confirm_title_elev'),
+		message: $lang.get('user_logout_confirm_body_elev'),
+		buttons: [
+			{
+				text: $lang.get('user_logout_confirm_btn_logout'),
+				color: 'red',
+				style: {
+					fontWeight: 'bold'
+				},
+				onclick: function()
+				{
+					ajaxLoginPerformRequest({
+							mode:  'logout',
+							level: auth_level,
+							csrf_token: csrf_token
+					});
+					miniPromptDestroy(this);
+				}
+			},
+			{
+				text: $lang.get('etc_cancel'),
+				onclick: function()
+				{
+					miniPromptDestroy(this);
+				}
+			}
+		]
+	});
 }
 
 /**
@@ -1337,84 +1337,84 @@
 
 window.ajaxLoginReplaceSIDInline = function(key, oldkey, level)
 {
-  var host = String(window.location.hostname);
-  var exp = new RegExp('^https?://' + host.replace('.', '\.') + contentPath.replace('.', '\.'), 'g');
-  var rexp = new RegExp('^https?://' + host.replace('.', '\.'), 'g');
-  
-  if ( key )
-  {
-    if ( oldkey )
-    {
-      var body = document.getElementsByTagName('body')[0];
-      var replace = new RegExp(oldkey, 'g');
-      body.innerHTML = body.innerHTML.replace(replace, key);
-      ENANO_SID = key;
-    }
-    else
-    {
-      // append SID to all internal links
-      ENANO_SID = key;
-      
-      var links = document.getElementsByTagName('a');
-      for ( var i = 0; i < links.length; i++ )
-      {
-        if ( links[i].href.match(exp, links[i]) && links[i].href.indexOf('#') == -1 )
-        {
-          var newurl = (String(append_sid(links[i].href))).replace(rexp, '');
-          links[i].href = newurl;
-        }
-      }
-      
-      var forms = document.getElementsByTagName('form');
-      for ( var i = 0; i < forms.length; i++ )
-      {
-        if ( forms[i].method.toLowerCase() == 'post' )
-        {
-          if ( forms[i].action.match(exp, links[i]) )
-          {
-            var newurl = (String(append_sid(forms[i].action))).replace(rexp, '');
-            forms[i].action = newurl;
-          }
-        }
-        else
-        {
-          if ( !forms[i].auth )
-          {
-            var auth = document.createElement('input');
-            auth.type = 'hidden';
-            auth.name = 'auth';
-            auth.value = key;
-            forms[i].appendChild(auth);
-          }
-          else
-          {
-            forms[i].auth.value = key;
-          }
-        }
-      }
-    }
-    if ( level )
-    {
-      auth_level = level;
-    }
-    window.location.hash = '#auth:' + key;
-  }
-  else
-  {
-    auth_level = USER_LEVEL_MEMBER;
-    ENANO_SID = false;
-    if ( oldkey )
-    {
-      var links = document.getElementsByTagName('a');
-      for ( var i = 0; i < links.length; i++ )
-      {
-        if ( links[i].href.match(exp, links[i]) && links[i].href.indexOf('#') == -1 )
-        {
-          links[i].href = links[i].href.replace(/\?auth=([a-f0-9]+)(&|#|$)/, '$2').replace(/&auth=([a-f0-9]+)/, '').replace(rexp, '');
-        }
-      }
-    }
-    window.location.hash = '#auth:false';
-  }
-  window.stdAjaxPrefix = append_sid(scriptPath + '/ajax.php?title=' + title);
+	var host = String(window.location.hostname);
+	var exp = new RegExp('^https?://' + host.replace('.', '\.') + contentPath.replace('.', '\.'), 'g');
+	var rexp = new RegExp('^https?://' + host.replace('.', '\.'), 'g');
+	
+	if ( key )
+	{
+		if ( oldkey )
+		{
+			var body = document.getElementsByTagName('body')[0];
+			var replace = new RegExp(oldkey, 'g');
+			body.innerHTML = body.innerHTML.replace(replace, key);
+			ENANO_SID = key;
+		}
+		else
+		{
+			// append SID to all internal links
+			ENANO_SID = key;
+			
+			var links = document.getElementsByTagName('a');
+			for ( var i = 0; i < links.length; i++ )
+			{
+				if ( links[i].href.match(exp, links[i]) && links[i].href.indexOf('#') == -1 )
+				{
+					var newurl = (String(append_sid(links[i].href))).replace(rexp, '');
+					links[i].href = newurl;
+				}
+			}
+			
+			var forms = document.getElementsByTagName('form');
+			for ( var i = 0; i < forms.length; i++ )
+			{
+				if ( forms[i].method.toLowerCase() == 'post' )
+				{
+					if ( forms[i].action.match(exp, links[i]) )
+					{
+						var newurl = (String(append_sid(forms[i].action))).replace(rexp, '');
+						forms[i].action = newurl;
+					}
+				}
+				else
+				{
+					if ( !forms[i].auth )
+					{
+						var auth = document.createElement('input');
+						auth.type = 'hidden';
+						auth.name = 'auth';
+						auth.value = key;
+						forms[i].appendChild(auth);
+					}
+					else
+					{
+						forms[i].auth.value = key;
+					}
+				}
+			}
+		}
+		if ( level )
+		{
+			auth_level = level;
+		}
+		window.location.hash = '#auth:' + key;
+	}
+	else
+	{
+		auth_level = USER_LEVEL_MEMBER;
+		ENANO_SID = false;
+		if ( oldkey )
+		{
+			var links = document.getElementsByTagName('a');
+			for ( var i = 0; i < links.length; i++ )
+			{
+				if ( links[i].href.match(exp, links[i]) && links[i].href.indexOf('#') == -1 )
+				{
+					links[i].href = links[i].href.replace(/\?auth=([a-f0-9]+)(&|#|$)/, '$2').replace(/&auth=([a-f0-9]+)/, '').replace(rexp, '');
+				}
+			}
+		}
+		window.location.hash = '#auth:false';
+	}
+	window.stdAjaxPrefix = append_sid(scriptPath + '/ajax.php?title=' + title);
 }