includes/clientside/static/misc.js
changeset 436 242353360e37
parent 426 f5718d7c2a6a
child 458 c433348f3628
equal deleted inserted replaced
435:a434d60e525d 436:242353360e37
   297   }
   297   }
   298 }
   298 }
   299 
   299 
   300 /*
   300 /*
   301  * AJAX login box (experimental)
   301  * AJAX login box (experimental)
   302  */
   302  * Moved / rewritten in login.js
   303 
   303  */
   304 var ajax_auth_prompt_cache = false;
   304 
   305 var ajax_auth_mb_cache = false;
   305 // Included only for API-compatibility
   306 var ajax_auth_level_cache = false;
       
   307 var ajax_auth_error_string = false;
       
   308 var ajax_auth_show_captcha = false;
       
   309 
       
   310 function ajaxAuthErrorToString($data)
       
   311 {
       
   312   var $errstring = $data.error;
       
   313   // this was literally copied straight from the PHP code.
       
   314   switch($data.error)
       
   315   {
       
   316     case 'key_not_found':
       
   317       $errstring = $lang.get('user_err_key_not_found');
       
   318       break;
       
   319     case 'key_wrong_length':
       
   320       $errstring = $lang.get('user_err_key_wrong_length');
       
   321       break;
       
   322     case 'too_big_for_britches':
       
   323       $errstring = $lang.get('user_err_too_big_for_britches');
       
   324       break;
       
   325     case 'invalid_credentials':
       
   326       $errstring = $lang.get('user_err_invalid_credentials');
       
   327       var subst = {
       
   328         fails: $data.lockout_fails,
       
   329         lockout_threshold: $data.lockout_threshold,
       
   330         lockout_duration: $data.lockout_duration
       
   331       }
       
   332       if ( $data.lockout_policy == 'lockout' )
       
   333       {
       
   334         $errstring += $lang.get('user_err_invalid_credentials_lockout', subst);
       
   335       }
       
   336       else if ( $data.lockout_policy == 'captcha' )
       
   337       {
       
   338         $errstring += $lang.get('user_err_invalid_credentials_lockout_captcha', subst);
       
   339       }
       
   340       break;
       
   341     case 'backend_fail':
       
   342       $errstring = $lang.get('user_err_backend_fail');
       
   343       break;
       
   344     case 'locked_out':
       
   345       $attempts = parseInt($data['lockout_fails']);
       
   346       if ( $attempts > $data['lockout_threshold'])
       
   347         $attempts = $data['lockout_threshold'];
       
   348       $time_rem = $data.time_rem;
       
   349       $s = ( $time_rem == 1 ) ? '' : $lang.get('meta_plural');
       
   350       
       
   351       var subst = {
       
   352         lockout_threshold: $data.lockout_threshold,
       
   353         time_rem: $time_rem,
       
   354         plural: $s,
       
   355         captcha_blurb: ( $data.lockout_policy == 'captcha' ? $lang.get('user_err_locked_out_captcha_blurb') : '' )
       
   356       }
       
   357       
       
   358       $errstring = $lang.get('user_err_locked_out', subst);
       
   359       
       
   360       break;
       
   361   }
       
   362   return $errstring;
       
   363 }
       
   364 
       
   365 function ajaxPromptAdminAuth(call_on_ok, level)
   306 function ajaxPromptAdminAuth(call_on_ok, level)
   366 {
   307 {
   367   if ( typeof(call_on_ok) == 'function' )
   308   ajaxLogonInit(call_on_ok, level);
   368   {
       
   369     ajax_auth_prompt_cache = call_on_ok;
       
   370   }
       
   371   if ( !level )
       
   372     level = USER_LEVEL_MEMBER;
       
   373   ajax_auth_level_cache = level;
       
   374   var loading_win = '<div align="center" style="text-align: center;"> \
       
   375       <p>' + $lang.get('user_login_ajax_fetching_key') + '</p> \
       
   376       <p><small>' + $lang.get('user_login_ajax_link_fullform', { link_full_form: makeUrlNS('Special', 'Login/' + title) }) + '</p> \
       
   377       <p><img alt="Please wait..." src="'+scriptPath+'/images/loading-big.gif" /></p> \
       
   378     </div>';
       
   379   var title = ( level > USER_LEVEL_MEMBER ) ? $lang.get('user_login_ajax_prompt_title_elev') : $lang.get('user_login_ajax_prompt_title');
       
   380   ajax_auth_mb_cache = new messagebox(MB_OKCANCEL|MB_ICONLOCK, title, loading_win);
       
   381   ajax_auth_mb_cache.onbeforeclick['OK'] = ajaxValidateLogin;
       
   382   ajax_auth_mb_cache.onbeforeclick['Cancel'] = function()
       
   383   {
       
   384     if ( document.getElementById('autoCaptcha') )
       
   385     {
       
   386       var to = fly_out_top(document.getElementById('autoCaptcha'), false, true);
       
   387       setTimeout(function() {
       
   388           var d = document.getElementById('autoCaptcha');
       
   389           d.parentNode.removeChild(d);
       
   390         }, to);
       
   391     }
       
   392   }
       
   393   ajaxAuthLoginInnerSetup();
       
   394 }
       
   395 
       
   396 function ajaxAuthLoginInnerSetup()
       
   397 {
       
   398   // let's hope this gets the image cached
       
   399   var _ = new Image(32, 32); 
       
   400   _.src = scriptPath + "/images/check.png";
       
   401   
       
   402   ajaxGet(makeUrlNS('Special', 'Login', 'act=getkey'), function() {
       
   403       if ( ajax.readyState == 4 && ajax.status == 200 )
       
   404       {
       
   405         var response = String(ajax.responseText);
       
   406         if ( response.substr(0,1) != '{' )
       
   407         {
       
   408           handle_invalid_json(response);
       
   409           ajax_auth_mb_cache.destroy();
       
   410           return false;
       
   411         }
       
   412         response = parseJSON(response);
       
   413         var disable_controls = false;
       
   414         if ( response.locked_out && !ajax_auth_error_string )
       
   415         {
       
   416           response.error = 'locked_out';
       
   417           ajax_auth_error_string = ajaxAuthErrorToString(response);
       
   418           if ( response.lockout_policy == 'captcha' )
       
   419           {
       
   420             ajax_auth_show_captcha = response.captcha;
       
   421           }
       
   422           else
       
   423           {
       
   424             disable_controls = true;
       
   425           }
       
   426         }
       
   427         var level = ajax_auth_level_cache;
       
   428         var form_html = '';
       
   429         var shown_error = false;
       
   430         if ( ajax_auth_error_string )
       
   431         {
       
   432           shown_error = true;
       
   433           form_html += '<div class="error-box-mini" id="ajax_auth_error">' + ajax_auth_error_string + '</div>';
       
   434           ajax_auth_error_string = false;
       
   435         }
       
   436         else if ( level > USER_LEVEL_MEMBER )
       
   437         {
       
   438           form_html += $lang.get('user_login_ajax_prompt_body_elev') + '<br /><br />';
       
   439         }
       
   440         if ( ajax_auth_show_captcha )
       
   441          {
       
   442            var captcha_html = ' \
       
   443              <tr> \
       
   444                <td>' + $lang.get('user_login_field_captcha') + ':</td> \
       
   445                <td><input type="hidden" id="ajaxlogin_captcha_hash" value="' + ajax_auth_show_captcha + '" /><input type="text" tabindex="3" size="25" id="ajaxlogin_captcha_code" /> \
       
   446              </tr>';
       
   447          }
       
   448          else
       
   449          {
       
   450            var captcha_html = '';
       
   451          }
       
   452          var disableme = ( disable_controls ) ? 'disabled="disabled" ' : '';
       
   453         form_html += ' \
       
   454           <form action="#" onsubmit="ajaxValidateLogin(); return false;" name="ajax_login_form"> \
       
   455             <table border="0" align="center"> \
       
   456               <tr> \
       
   457                 <td>' + $lang.get('user_login_field_username') + ':</td><td><input tabindex="1" id="ajaxlogin_user" type="text"     ' + disableme + 'size="25" /> \
       
   458               </tr> \
       
   459               <tr> \
       
   460                 <td>' + $lang.get('user_login_field_password') + ':</td><td><input tabindex="2" id="ajaxlogin_pass" type="password" ' + disableme + 'size="25" /> \
       
   461               </tr> \
       
   462               ' + captcha_html + ' \
       
   463               <tr> \
       
   464                 <td colspan="2" style="text-align: center;"> \
       
   465                 <small>' + $lang.get('user_login_ajax_link_fullform', { link_full_form: makeUrlNS('Special', 'Login/' + title, 'level=' + level) }) + '<br />';
       
   466        if ( level <= USER_LEVEL_MEMBER )
       
   467        {
       
   468          form_html += ' \
       
   469                   ' + $lang.get('user_login_ajax_link_forgotpass', { forgotpass_link: makeUrlNS('Special', 'PasswordReset') }) + '<br /> \
       
   470                   ' + $lang.get('user_login_createaccount_blurb', { reg_link: makeUrlNS('Special', 'Register') });
       
   471        }
       
   472        form_html += '</small> \
       
   473                 </td> \
       
   474               </tr> \
       
   475             </table> \
       
   476             <input type="hidden" id="ajaxlogin_crypt_key"       value="' + response.key + '" /> \
       
   477             <input type="hidden" id="ajaxlogin_crypt_challenge" value="' + response.challenge + '" /> \
       
   478           </form>';
       
   479         ajax_auth_mb_cache.updateContent(form_html);
       
   480         $dynano('messageBox').object.nextSibling.firstChild.tabindex = '3';
       
   481         if ( typeof(response.username) == 'string' )
       
   482         {
       
   483           $dynano('ajaxlogin_user').object.value = response.username;
       
   484           if ( IE )
       
   485           {
       
   486             setTimeout("document.forms['ajax_login_form'].password.focus();", 200);
       
   487           }
       
   488           else
       
   489           {
       
   490             $dynano('ajaxlogin_pass').object.focus();
       
   491           }
       
   492         }
       
   493         else
       
   494         {
       
   495           if ( IE )
       
   496           {
       
   497             setTimeout("document.forms['ajax_login_form'].username.focus();", 200);
       
   498           }
       
   499           else
       
   500           {
       
   501             $dynano('ajaxlogin_user').object.focus();
       
   502           }
       
   503         }
       
   504         var enter_obj = ( ajax_auth_show_captcha ) ? 'ajaxlogin_captcha_code' : 'ajaxlogin_pass';
       
   505         $dynano(enter_obj).object.onblur = function(e) { if ( !shift ) $dynano('messageBox').object.nextSibling.firstChild.focus(); };
       
   506         $dynano(enter_obj).object.onkeypress = function(e)
       
   507         {
       
   508           // Trigger a form submit when the password field is focused and the user presses enter
       
   509           
       
   510           // IE doesn't give us an event object when it should - check window.event. If that
       
   511           // still fails, give up.
       
   512           if ( !e )
       
   513           {
       
   514             e = window.event;
       
   515           }
       
   516           if ( !e && IE )
       
   517           {
       
   518             return true;
       
   519           }
       
   520           if ( e.keyCode == 13 )
       
   521           {
       
   522             ajaxValidateLogin();
       
   523           }
       
   524         };
       
   525         /*
       
   526         ## This causes the background image to disappear under Fx 2
       
   527         if ( shown_error )
       
   528         {
       
   529           // fade to #FFF4F4
       
   530           var fader = new Spry.Effect.Highlight('ajax_auth_error', {duration: 1000, from: '#FFF4F4', to: '#805600', restoreColor: '#805600', finish: function()
       
   531               {
       
   532                 var fader = new Spry.Effect.Highlight('ajax_auth_error', {duration: 3000, from: '#805600', to: '#FFF4F4', restoreColor: '#FFF4F4'});
       
   533                 fader.start();
       
   534           }});
       
   535           fader.start();
       
   536         }
       
   537         */
       
   538         if ( ajax_auth_show_captcha )
       
   539         {
       
   540           ajaxShowCaptcha(ajax_auth_show_captcha);
       
   541           ajax_auth_show_captcha = false;
       
   542         }
       
   543       }
       
   544     });
       
   545 }
       
   546 
       
   547 function ajaxValidateLogin()
       
   548 {
       
   549   var username,password,auth_enabled,crypt_key,crypt_data,challenge_salt,challenge_data;
       
   550   username = document.getElementById('ajaxlogin_user');
       
   551   if ( !username )
       
   552     return false;
       
   553   username = document.getElementById('ajaxlogin_user').value;
       
   554   password = document.getElementById('ajaxlogin_pass').value;
       
   555   auth_enabled = false;
       
   556   
       
   557   if ( document.getElementById('autoCaptcha') )
       
   558   {
       
   559     var to = fly_out_top(document.getElementById('autoCaptcha'), false, true);
       
   560     setTimeout(function() {
       
   561         var d = document.getElementById('autoCaptcha');
       
   562         d.parentNode.removeChild(d);
       
   563       }, to);
       
   564   }
       
   565   
       
   566   disableJSONExts();
       
   567   
       
   568   var auth_enabled = aes_self_test();
       
   569   
       
   570   if ( !auth_enabled )
       
   571   {
       
   572     alert('Login error: encryption sanity check failed\n');
       
   573     return true;
       
   574   }
       
   575   
       
   576   crypt_key = document.getElementById('ajaxlogin_crypt_key').value;
       
   577   challenge_salt = document.getElementById('ajaxlogin_crypt_challenge').value;
       
   578   
       
   579   var crypt_key_md5 = hex_md5(crypt_key);
       
   580   
       
   581   challenge_data = hex_md5(password + challenge_salt) + challenge_salt;
       
   582   
       
   583   password = stringToByteArray(password);
       
   584   crypt_key = hexToByteArray(crypt_key);
       
   585   
       
   586   crypt_data = rijndaelEncrypt(password, crypt_key, 'ECB');
       
   587   crypt_data = byteArrayToHex(crypt_data);
       
   588   
       
   589   var json_data = {
       
   590     'username' : username,
       
   591     'crypt_key' : crypt_key_md5,
       
   592     'challenge' : challenge_data,
       
   593     'crypt_data' : crypt_data,
       
   594     'level' : ajax_auth_level_cache
       
   595   };
       
   596   
       
   597   if ( document.getElementById('ajaxlogin_captcha_hash') )
       
   598   {
       
   599     json_data.captcha_hash = document.getElementById('ajaxlogin_captcha_hash').value;
       
   600     json_data.captcha_code = document.getElementById('ajaxlogin_captcha_code').value;
       
   601   }
       
   602   
       
   603   json_data = toJSONString(json_data);
       
   604   json_data = encodeURIComponent(json_data);
       
   605   
       
   606   var loading_win = '<div align="center" style="text-align: center;"> \
       
   607       <p>' + $lang.get('user_login_ajax_loggingin') + '</p> \
       
   608       <p><img alt="Please wait..." src="'+scriptPath+'/images/loading-big.gif" /></p> \
       
   609     </div>';
       
   610     
       
   611   ajax_auth_mb_cache.updateContent(loading_win);
       
   612   
       
   613   ajaxPost(makeUrlNS('Special', 'Login', 'act=ajaxlogin'), 'params=' + json_data, function() {
       
   614       if ( ajax.readyState == 4 && ajax.status == 200 )
       
   615       {
       
   616         var response = ajax.responseText;
       
   617         if ( response.substr(0,1) != '{' )
       
   618         {
       
   619           alert('Invalid JSON response from server: ' + response);
       
   620           ajaxAuthLoginInnerSetup();
       
   621           return false;
       
   622         }
       
   623         response = parseJSON(response);
       
   624         switch(response.result)
       
   625         {
       
   626           case 'success':
       
   627             var success_win = '<div align="center" style="text-align: center;"> \
       
   628                   <p>' + $lang.get('user_login_success_short') + '</p> \
       
   629                   <p><img alt=" " src="'+scriptPath+'/images/check.png" /></p> \
       
   630                 </div>';
       
   631             ajax_auth_mb_cache.updateContent(success_win);
       
   632             if ( typeof(ajax_auth_prompt_cache) == 'function' )
       
   633             {
       
   634               ajax_auth_prompt_cache(response.key);
       
   635             }
       
   636             break;
       
   637           case 'success_reset':
       
   638             var conf = confirm($lang.get('user_login_ajax_msg_used_temp_pass'));
       
   639             if ( conf )
       
   640             {
       
   641               var url = makeUrlNS('Special', 'PasswordReset/stage2/' + response.user_id + '/' + response.temppass);
       
   642               window.location = url;
       
   643             }
       
   644             else
       
   645             {
       
   646               ajaxAuthLoginInnerSetup();
       
   647             }
       
   648             break;
       
   649           case 'error':
       
   650             if ( response.data.error == 'invalid_credentials' || response.data.error == 'locked_out' )
       
   651             {
       
   652               ajax_auth_error_string = ajaxAuthErrorToString(response.data);
       
   653               mb_current_obj.updateContent('');
       
   654               document.getElementById('messageBox').style.backgroundColor = '#C0C0C0';
       
   655               var mb_parent = document.getElementById('messageBox').parentNode;
       
   656               new Spry.Effect.Shake(mb_parent, {duration: 1500}).start();
       
   657               setTimeout("document.getElementById('messageBox').style.backgroundColor = '#FFF'; ajaxAuthLoginInnerSetup();", 2500);
       
   658               
       
   659               if ( response.data.lockout_policy == 'captcha' && response.data.error == 'locked_out' )
       
   660               {
       
   661                 ajax_auth_show_captcha = response.captcha;
       
   662               }
       
   663             }
       
   664             else
       
   665             {
       
   666               ajax_auth_error_string = ajaxAuthErrorToString(response.data);
       
   667               ajaxAuthLoginInnerSetup();
       
   668             }
       
   669             break;
       
   670           default:
       
   671             alert(ajax.responseText);
       
   672             break;
       
   673         }
       
   674       }
       
   675     });
       
   676   
       
   677   return true;
       
   678   
       
   679 }
   309 }
   680 
   310 
   681 // This code is in the public domain. Feel free to link back to http://jan.moesen.nu/
   311 // This code is in the public domain. Feel free to link back to http://jan.moesen.nu/
   682 function sprintf()
   312 function sprintf()
   683 {
   313 {