# HG changeset patch # User Dan # Date 1231727869 18000 # Node ID 5c807fe77020e1414b3b8f255eb65305cf50f9d5 # Parent 7fd2b8a58ae40bb60ae2972df7aa20dbd2a698a2 Added support for live re-auth and de-auth; fully AJAX, no page reload required, plus plugin-usable API. diff -r 7fd2b8a58ae4 -r 5c807fe77020 includes/clientside/static/login.js --- a/includes/clientside/static/login.js Sun Jan 11 21:37:39 2009 -0500 +++ b/includes/clientside/static/login.js Sun Jan 11 21:37:49 2009 -0500 @@ -393,9 +393,16 @@ // Did the server send a plaintext error? if ( response.mode == 'error' ) { - 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); + 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 @@ -446,6 +453,12 @@ }, 2500); } break; + case 'logout_success': + if ( ENANO_SID ) + { + ajaxLoginReplaceSIDInline(false, ENANO_SID, USER_LEVEL_MEMBER); + } + break; case 'noop': break; } @@ -1159,16 +1172,17 @@ window.location = loc; } -window.ajaxDynamicReauth = function(adminpage) +window.ajaxDynamicReauth = function(adminpage, level) { var old_sid = ENANO_SID; var targetpage = adminpage; + if ( !level ) + { + level = USER_LEVEL_ADMIN; + } ajaxLogonInit(function(k) { - var body = document.getElementsByTagName('body')[0]; - var replace = new RegExp(old_sid, 'g'); - body.innerHTML = body.innerHTML.replace(replace, k); - ENANO_SID = k; + ajaxLoginReplaceSIDInline(k, old_sid, level); mb_current_obj.destroy(); console.debug(targetpage); if ( typeof(targetpage) == 'string' ) @@ -1179,7 +1193,7 @@ { targetpage(); } - }, USER_LEVEL_ADMIN); + }, level); ajaxLoginShowFriendlyError({ error_code: 'admin_session_timed_out', respawn_info: {} @@ -1190,3 +1204,125 @@ { 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); + } + } + ] + }); +} + +/** + * Take an SID and patch all internal links on the page. + * @param string New key. If false, removes keys from the page. + * @param string Old key. If false, only appends the new SID (more work as it uses DOM, use when dynamically going up to elevated) + * @param int New level, not a huge deal but sets auth_level. Try to specify it as some functions depend on it. + */ + +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; + } + } + 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, ''); + } + } + } + } +} diff -r 7fd2b8a58ae4 -r 5c807fe77020 includes/clientside/static/messagebox.js --- a/includes/clientside/static/messagebox.js Sun Jan 11 21:37:39 2009 -0500 +++ b/includes/clientside/static/messagebox.js Sun Jan 11 21:37:49 2009 -0500 @@ -296,9 +296,7 @@ } if(typeof mb.onclick[val] == 'function') { - o = mb.onclick[val]; - o(); - o = false; + (mb.onclick[val])(); } } diff -r 7fd2b8a58ae4 -r 5c807fe77020 includes/sessions.php --- a/includes/sessions.php Sun Jan 11 21:37:39 2009 -0500 +++ b/includes/sessions.php Sun Jan 11 21:37:49 2009 -0500 @@ -4046,6 +4046,35 @@ 'respawn_info' => $this->process_login_request(array('mode' => 'getkey')) ))); break; + case 'logout': + if ( !$this->started ) + $this->start(); + if ( !isset($req['csrf_token']) ) + return array( + 'mode' => 'error', + 'error' => 'Invalid CSRF token' + ); + + if ( $req['csrf_token'] !== $this->csrf_token ) + return array( + 'mode' => 'error', + 'error' => 'Invalid CSRF token' + ); + $level = isset($req['level']) && is_int($req['level']) ? $req['level'] : USER_LEVEL_MEMBER; + if ( ($result = $this->logout($level)) === 'success' ) + { + return array( + 'mode' => 'logout_success' + ); + } + else + { + return array( + 'mode' => 'error', + 'error' => $result + ); + } + break; } } diff -r 7fd2b8a58ae4 -r 5c807fe77020 language/english/admin.json --- a/language/english/admin.json Sun Jan 11 21:37:39 2009 -0500 +++ b/language/english/admin.json Sun Jan 11 21:37:49 2009 -0500 @@ -493,6 +493,7 @@ err_upgrade_bad_target_version: 'This plugin cannot be upgraded because it does not support its own version. Please contact the author and ask them to fix this.', err_upgrade_to_older: 'You are trying to upgrade to an older release of this plugin. This is unsupported and must be done manually.', err_upgrade_bad_query: 'There is a problem with one of the SQL queries the plugin is trying to make.', + err_dmbs_not_supported: 'This plugin doesn\'t support %dbdriver% databases.', err_import_no_strings: 'This plugin doesn\'t have language support.', err_demo_mode: 'You can\'t manipulate plugins in the Enano demo for security reasons.',