Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

User:Justarandomamerican/globalUserLock.js: Difference between revisions

From WikiOasis Meta
maybe?
No edit summary
Line 19: Line 19:
// ── Load Dependencies First ────────────────────────────────────────────────
// ── Load Dependencies First ────────────────────────────────────────────────
$.when(
$.when(
mw.loader.using( [ 'mediawiki.util', 'oojs-ui-core', 'oojs-ui-widgets', 'oojs-ui-windows' ] ),
mw.loader.using( [ 'mediawiki.util', 'mediawiki.api', 'oojs-ui-core', 'oojs-ui-widgets', 'oojs-ui-windows' ] ),
$.ready
$.ready
).then( function () {
).then( function () {
// Initialize the MediaWiki API helper
const api = new mw.Api();


// ── OOUI Dialog Definition ─────────────────────────────────────────────
// ── OOUI Dialog Definition ─────────────────────────────────────────────
Line 298: Line 301:


// ── API helpers ────────────────────────────────────────────────────────
// ── API helpers ────────────────────────────────────────────────────────
function getCSRFToken() {
return $.ajax( {
url:  API_ENDPOINT,
data: { action: 'query', meta: 'tokens', type: 'csrf', format: 'json' }
} ).then( function ( data ) {
return data.query.tokens.csrftoken;
} );
}
function fetchMatchingUsers( query, fromUser ) {
function fetchMatchingUsers( query, fromUser ) {
const deferred    = $.Deferred();
const deferred    = $.Deferred();
Line 332: Line 326:
if ( continueFrom ) { params.agufrom = continueFrom; }
if ( continueFrom ) { params.agufrom = continueFrom; }


$.ajax( { url: API_ENDPOINT, data: params } )
api.get( params )
.done( function ( data ) {
.done( function ( data ) {
const users = ( data.query || {} ).globalallusers || [];
const users = ( data.query || {} ).globalallusers || [];
Line 356: Line 350:
}
}
} )
} )
.fail( function ( xhr ) {
.fail( function ( code ) {
deferred.reject( 'API request failed: ' + xhr.statusText );
deferred.reject( 'API request failed: ' + code );
} );
} );
}
}
Line 365: Line 359:
}
}


function lockAccount( username, token, reason, hide, suppress ) {
function lockAccount( username, reason, hide, suppress ) {
const payload = {
const payload = {
action: 'setglobalaccountstatus',
action: 'setglobalaccountstatus',
Line 371: Line 365:
locked: 'lock',
locked: 'lock',
reason: reason,
reason: reason,
token:  token,
format: 'json'
format: 'json'
};
};
Line 381: Line 374:
}
}


return $.ajax( { url: API_ENDPOINT, method: 'POST', data: payload } );
return api.postWithToken( 'csrf', payload );
}
}


Line 458: Line 451:
const skipLocked = $( '#gul-skip-locked' ).prop( 'checked' );
const skipLocked = $( '#gul-skip-locked' ).prop( 'checked' );


if ( !reason ) { setStatus( 'A lock reason is required.', 'error' ); return; }
if ( !reason ) {  
setStatus( '🛑 A lock reason is required before locking.', 'error' );  
$( '#gul-reason' ).trigger( 'focus' );
return;  
}


const selected = [];
const selected = [];
Line 464: Line 461:


if ( selected.length === 0 ) { setStatus( 'No accounts selected.', 'warning' ); return; }
if ( selected.length === 0 ) { setStatus( 'No accounts selected.', 'warning' ); return; }
if ( !confirm( 'You are about to globally lock ' + selected.length + ' account(s).\n\nReason: ' + reason + '\n' + ( hide ? 'Hide username: YES\n' : '' ) + ( suppress ? 'Suppress username: YES\n' : '' ) + '\nThis action will be logged. Proceed?' ) ) { return; }


$( '#gul-btn-lock, #gul-btn-search' ).prop( 'disabled', true );
const confirmMessage = 'You are about to globally lock ' + selected.length + ' account(s).\n\n' +
$( '#gul-progress' ).addClass( 'visible' );
'Reason: ' + reason + '\n' +
setProgress( 0, selected.length );
( hide ? 'Hide username: YES\n' : '' ) +
setStatus( 'Fetching CSRF token…', 'info' );
( suppress ? 'Suppress username: YES\n' : '' ) +
'\nThis action will be logged. Proceed?';
 
OO.ui.confirm( confirmMessage ).done( function ( confirmed ) {
if ( !confirmed ) { return; }


getCSRFToken()
$( '#gul-btn-lock, #gul-btn-search' ).prop( 'disabled', true );
.then( function ( token ) {
$( '#gul-progress' ).addClass( 'visible' );
setStatus( 'Locking ' + selected.length + ' account(s)…', 'info' );
setProgress( 0, selected.length );
let done = 0, locked = 0, skipped = 0, failed = 0;
setStatus( 'Locking ' + selected.length + ' account(s)…', 'info' );
let done = 0, locked = 0, skipped = 0, failed = 0;


function processNext( i ) {
function processNext( i ) {
if ( i >= selected.length ) {
if ( i >= selected.length ) {
setProgress( done, selected.length );
setProgress( done, selected.length );
setStatus( 'Done. <strong>' + locked + '</strong> locked, <strong>' + skipped + '</strong> skipped, <strong>' + failed + '</strong> failed.', failed > 0 ? 'warning' : 'success' );
setStatus( 'Done. <strong>' + locked + '</strong> locked, <strong>' + skipped + '</strong> skipped, <strong>' + failed + '</strong> failed.', failed > 0 ? 'warning' : 'success' );
$( '#gul-btn-search' ).prop( 'disabled', false );
$( '#gul-btn-search' ).prop( 'disabled', false );
$( '#gul-lock-summary' ).remove();
$( '#gul-lock-summary' ).remove();
$( '#gul-results-wrap' ).append( $( '<div id="gul-lock-summary">' ).addClass( 'gul-summary' ).html( '<strong>Summary:</strong> ' + locked + ' locked · ' + skipped + ' skipped · ' + failed + ' failed' ) );
$( '#gul-results-wrap' ).append( $( '<div id="gul-lock-summary">' ).addClass( 'gul-summary' ).html( '<strong>Summary:</strong> ' + locked + ' locked · ' + skipped + ' skipped · ' + failed + ' failed' ) );
return;
return;
}
}


const username = selected[ i ];
const username = selected[ i ];
const wasLocked = $( 'tr[data-user="' + $.escapeSelector( username ) + '"] td:nth-child(3)' ).text().trim() === 'Locked';
const wasLocked = $( 'tr[data-user="' + $.escapeSelector( username ) + '"] td:nth-child(3)' ).text().trim() === 'Locked';


if ( skipLocked && wasLocked ) {
if ( skipLocked && wasLocked ) {
skipped++; done++;
skipped++; done++;
setBadge( username, 'skipped', 'Skipped' );
setBadge( username, 'skipped', 'Skipped' );
setProgress( done, selected.length );
setProgress( done, selected.length );
processNext( i + 1 );
processNext( i + 1 );
return;
return;
}
}


setBadge( username, 'pending', 'Locking…' );
setBadge( username, 'pending', 'Locking…' );


lockAccount( username, token, reason, hide, suppress )
lockAccount( username, reason, hide, suppress )
.done( function ( data ) {
.done( function ( data ) {
if ( data.error ) {
if ( data.error ) {
failed++;
failed++;
setBadge( username, 'failed', 'Error: ' + mw.html.escape( data.error.info || data.error.code ) );
setBadge( username, 'failed', 'Error: ' + mw.html.escape( data.error.info || data.error.code ) );
} else {
} else {
locked++;
locked++;
setBadge( username, 'locked', 'Locked ✓' );
setBadge( username, 'locked', 'Locked ✓' );
}
}
} )
} )
.fail( function () { failed++; setBadge( username, 'failed', 'Network error' ); } )
.fail( function ( code, result ) {  
.always( function () {
failed++;  
done++;
const errMsg = (result && result.error && result.error.info) ? result.error.info : code;
setProgress( done, selected.length );
setBadge( username, 'failed', 'Error: ' + mw.html.escape( errMsg ) );  
setStatus( 'Processing ' + done + ' / ' + selected.length + '…', 'info' );
} )
setTimeout( function () { processNext( i + 1 ); }, 300 );
.always( function () {
} );
done++;
}
setProgress( done, selected.length );
processNext( 0 );
setStatus( 'Processing ' + done + ' / ' + selected.length + '…', 'info' );
} )
setTimeout( function () { processNext( i + 1 ); }, 300 );
.fail( function () {
} );
setStatus( 'Failed to obtain token. Are you logged in with the centralauth-lock right?', 'error' );
}
$( '#gul-btn-lock, #gul-btn-search' ).prop( 'disabled', false );
processNext( 0 );
} );
} );
}
}


Cookies help us deliver our services. By using our services, you agree to our use of cookies.