87 * @var int |
90 * @var int |
88 */ |
91 */ |
89 |
92 |
90 var AJAX_STATE_EARLY_INIT = 1; |
93 var AJAX_STATE_EARLY_INIT = 1; |
91 var AJAX_STATE_LOADING_KEY = 2; |
94 var AJAX_STATE_LOADING_KEY = 2; |
|
95 |
|
96 /** |
|
97 * Switch to decide if DiffieHellman shows a "browser incompatible" error |
|
98 * @var bool |
|
99 */ |
|
100 |
|
101 var ajax_login_prevent_dh = IE || is_iPhone; |
92 |
102 |
93 /** |
103 /** |
94 * Performs the AJAX request to get an encryption key and from there spawns the login form. |
104 * Performs the AJAX request to get an encryption key and from there spawns the login form. |
95 * @param function The function that will be called once authentication completes successfully. |
105 * @param function The function that will be called once authentication completes successfully. |
96 * @param int The security level to authenticate at - see http://docs.enanocms.org/Help:Appendix_B |
106 * @param int The security level to authenticate at - see http://docs.enanocms.org/Help:Appendix_B |
228 // Append a br or two to space things properly |
238 // Append a br or two to space things properly |
229 div.appendChild(document.createElement('br')); |
239 div.appendChild(document.createElement('br')); |
230 div.appendChild(document.createElement('br')); |
240 div.appendChild(document.createElement('br')); |
231 |
241 |
232 var img = document.createElement('img'); |
242 var img = document.createElement('img'); |
233 img.src = ( ajax_login_loadimg_path ) ? ajax_login_loadimg_path : scriptPath + '/images/loading-big.gif'; |
243 img.src = ( ajax_login_lockimg_path ) ? ajax_login_lockimg_path : scriptPath + '/images/lock48.png'; |
234 div.appendChild(img); |
244 div.appendChild(img); |
235 |
245 |
236 // Another coupla brs |
246 // Another coupla brs |
237 div.appendChild(document.createElement('br')); |
247 div.appendChild(document.createElement('br')); |
238 div.appendChild(document.createElement('br')); |
248 div.appendChild(document.createElement('br')); |
478 */ |
488 */ |
479 |
489 |
480 window.ajaxLoginBuildForm = function(data) |
490 window.ajaxLoginBuildForm = function(data) |
481 { |
491 { |
482 // let's hope this effectively preloads the image... |
492 // let's hope this effectively preloads the image... |
483 var _ = document.createElement('img'); |
493 var _1 = document.createElement('img'); |
484 _.src = ( ajax_login_successimg_path ) ? ajax_login_successimg_path : scriptPath + '/images/check.png'; |
494 _1.src = ( ajax_login_successimg_path ) ? ajax_login_successimg_path : scriptPath + '/images/check.png'; |
|
495 var _2 = document.createElement('img'); |
|
496 _2.src = ( ajax_login_lockimg_path ) ? ajax_login_lockimg_path : scriptPath + '/images/lock48.png'; |
485 |
497 |
486 var div = document.createElement('div'); |
498 var div = document.createElement('div'); |
487 div.id = 'ajax_login_form'; |
499 div.id = 'ajax_login_form'; |
488 |
500 |
489 var show_captcha = ( data.locked_out && data.lockout_info.lockout_policy == 'captcha' ) ? data.lockout_info.captcha : false; |
501 var show_captcha = ( data.locked_out && data.lockout_info.lockout_policy == 'captcha' ) ? data.lockout_info.captcha : false; |
646 |
658 |
647 form.appendChild(lbl_remember); |
659 form.appendChild(lbl_remember); |
648 } |
660 } |
649 |
661 |
650 // Field: enable Diffie Hellman |
662 // Field: enable Diffie Hellman |
651 if ( IE || is_iPhone ) |
663 if ( ajax_login_prevent_dh ) |
652 { |
664 { |
653 var lbl_dh = document.createElement('span'); |
665 var lbl_dh = document.createElement('span'); |
654 lbl_dh.style.fontSize = 'smaller'; |
666 lbl_dh.style.fontSize = 'smaller'; |
655 lbl_dh.style.display = 'block'; |
667 lbl_dh.style.display = 'block'; |
656 lbl_dh.style.textAlign = 'center'; |
668 lbl_dh.style.textAlign = 'center'; |
754 { |
766 { |
755 alert('BUG: AES self-test failed'); |
767 alert('BUG: AES self-test failed'); |
756 login_cache.mb_object.destroy(); |
768 login_cache.mb_object.destroy(); |
757 return false; |
769 return false; |
758 } |
770 } |
|
771 // Early submit hook |
|
772 eval(setHook('login_submit_early')); |
759 // Hide the error message and captcha |
773 // Hide the error message and captcha |
760 if ( document.getElementById('ajax_login_error_box') ) |
774 if ( document.getElementById('ajax_login_error_box') ) |
761 { |
775 { |
762 document.getElementById('ajax_login_error_box').parentNode.removeChild(document.getElementById('ajax_login_error_box')); |
776 document.getElementById('ajax_login_error_box').parentNode.removeChild(document.getElementById('ajax_login_error_box')); |
763 } |
777 } |
794 { |
808 { |
795 var do_dh = document.getElementById('ajax_login_field_dh').checked; |
809 var do_dh = document.getElementById('ajax_login_field_dh').checked; |
796 } |
810 } |
797 else |
811 else |
798 { |
812 { |
799 if ( IE || is_iPhone ) |
813 if ( ajax_login_prevent_dh ) |
800 { |
814 { |
801 // IE/MobileSafari doesn't have this control, continue silently IF the rest |
815 // IE/MobileSafari doesn't have this control, continue silently IF the rest |
802 // of the login form is there |
816 // of the login form is there |
803 if ( !document.getElementById('ajax_login_field_username') ) |
817 if ( !document.getElementById('ajax_login_field_username') ) |
804 { |
818 { |
835 { |
849 { |
836 // Wait while the browser updates the login window |
850 // Wait while the browser updates the login window |
837 setTimeout(function() |
851 setTimeout(function() |
838 { |
852 { |
839 ajaxLoginSubmitForm(true, username, password, captcha, remember_session); |
853 ajaxLoginSubmitForm(true, username, password, captcha, remember_session); |
840 }, 200); |
854 }, 20); |
841 return true; |
855 return true; |
842 } |
856 } |
|
857 var dh_start = (new Date()).getTime(); |
843 // Perform Diffie Hellman stuff |
858 // Perform Diffie Hellman stuff |
844 var dh_priv = dh_gen_private(); |
859 var dh_priv = dh_gen_private(); |
845 var dh_pub = dh_gen_public(dh_priv); |
860 var dh_pub = dh_gen_public(dh_priv); |
846 var secret = dh_gen_shared_secret(dh_priv, logindata.key_dh); |
861 var secret = dh_gen_shared_secret(dh_priv, logindata.key_dh); |
847 // secret_hash is used to verify that the server guesses the correct secret |
862 // secret_hash is used to verify that the server guesses the correct secret |
848 var secret_hash = hex_sha1(secret); |
863 var secret_hash = hex_sha1(secret); |
849 // crypt_key is the actual AES key |
864 // crypt_key is the actual AES key |
850 var crypt_key = (hex_sha256(secret)).substr(0, (keySizeInBits / 4)); |
865 var crypt_key = (hex_sha256(secret)).substr(0, (keySizeInBits / 4)); |
|
866 var dh_time = (new Date()).getTime() - dh_start; |
|
867 console.debug("DH: complete, time = %dms", dh_time); |
851 } |
868 } |
852 else |
869 else |
853 { |
870 { |
854 var crypt_key = logindata.key_aes; |
871 var crypt_key = logindata.key_aes; |
855 } |
872 } |
974 switch ( response.error_code ) |
991 switch ( response.error_code ) |
975 { |
992 { |
976 default: |
993 default: |
977 var ls = $lang.get('user_err_' + response.error_code); |
994 var ls = $lang.get('user_err_' + response.error_code); |
978 if ( ls == 'user_err_' + response.error_code ) |
995 if ( ls == 'user_err_' + response.error_code ) |
979 ls = $lang.get(response.error_code); |
996 // Adding response here allows language strings to utilize additional information passed from the error packet |
|
997 ls = $lang.get(response.error_code, response); |
980 |
998 |
981 return ls; |
999 return ls; |
982 break; |
1000 break; |
983 case 'locked_out': |
1001 case 'locked_out': |
984 if ( response.respawn_info.lockout_info.lockout_policy == 'lockout' ) |
1002 if ( response.respawn_info.lockout_info.lockout_policy == 'lockout' ) |
1074 body.appendChild(mydiv); |
1092 body.appendChild(mydiv); |
1075 } |
1093 } |
1076 |
1094 |
1077 window.ajaxInitLogout = function() |
1095 window.ajaxInitLogout = function() |
1078 { |
1096 { |
1079 load_component(['messagebox', 'l10n', 'flyin', 'fadefilter']); |
1097 load_component(['messagebox', 'l10n', 'flyin', 'fadefilter', 'jquery', 'jquery-ui']); |
1080 var mb = new MessageBox(MB_YESNO|MB_ICONQUESTION, $lang.get('user_logout_confirm_title'), $lang.get('user_logout_confirm_body')); |
1098 |
1081 mb.onclick['Yes'] = function() |
1099 var title = $lang.get('user_logout_confirm_title'); |
1082 { |
1100 var message = ( auth_level > USER_LEVEL_MEMBER ) ? $lang.get('user_logout_confirm_body_nelev') : $lang.get('user_logout_confirm_body_normal'); |
1083 window.location = makeUrlNS('Special', 'Logout/' + csrf_token + '/' + title); |
1101 var buttons = []; |
1084 } |
1102 buttons.push({ |
|
1103 text: $lang.get('user_logout_confirm_btn_logout'), |
|
1104 color: 'red', |
|
1105 style: { |
|
1106 fontWeight: 'bold' |
|
1107 }, |
|
1108 onclick: function() |
|
1109 { |
|
1110 miniPromptDestroy(this); |
|
1111 window.location = makeUrlNS('Special', 'Logout/' + csrf_token + '/' + window.title); |
|
1112 return false; |
|
1113 } |
|
1114 }); |
|
1115 if ( auth_level > USER_LEVEL_MEMBER ) |
|
1116 { |
|
1117 buttons.push({ |
|
1118 text: $lang.get('user_logout_confirm_btn_deauth'), |
|
1119 color: 'blue', |
|
1120 onclick: function() |
|
1121 { |
|
1122 miniPromptDestroy(this); |
|
1123 ajaxLoginPerformRequest({ |
|
1124 mode: 'logout', |
|
1125 level: auth_level, |
|
1126 csrf_token: csrf_token |
|
1127 }); |
|
1128 return false; |
|
1129 } |
|
1130 }); |
|
1131 } |
|
1132 buttons.push({ |
|
1133 text: $lang.get('etc_cancel'), |
|
1134 onclick: function() |
|
1135 { |
|
1136 miniPromptDestroy(this); |
|
1137 return false; |
|
1138 } |
|
1139 }); |
|
1140 |
|
1141 miniPromptMessage({ |
|
1142 title: title, |
|
1143 message: message, |
|
1144 buttons: buttons |
|
1145 }); |
1085 } |
1146 } |
1086 |
1147 |
1087 window.mb_logout = function() |
1148 window.mb_logout = function() |
1088 { |
1149 { |
1089 ajaxInitLogout(); |
1150 ajaxInitLogout(); |