mediawiki-extensions-Confir.../Turnstile/resources/ve-confirmedit-turnstile/ve.init.mw.TurnstileSaveErrorHandler.js
alex4401 92bcb7f2a2
Turnstile's response field uses a static name instead of IDs
The script was originally looking for the field by ID. This resulted in an infinite challenge loop when saving edits through the VisualEditor.

This bug stopped our [wiki.gg] rollout of Turnstile over the network last week, so upstreaming this fix in case someone else needs it.

Bug: T361098
Change-Id: I0354a33d0d1af988c8788ad2bb021c585384b038
2024-06-25 03:24:25 +02:00

73 lines
2.3 KiB
JavaScript

mw.loader.using( 'ext.visualEditor.targetLoader' ).then( () => {
mw.libs.ve.targetLoader.addPlugin( () => {
ve.init.mw.TurnstileSaveErrorHandler = function () {};
OO.inheritClass( ve.init.mw.TurnstileSaveErrorHandler, ve.init.mw.SaveErrorHandler );
ve.init.mw.TurnstileSaveErrorHandler.static.name = 'confirmEditTurnstile';
ve.init.mw.TurnstileSaveErrorHandler.static.getReadyPromise = function () {
const onLoadFn = 'onTurnstileLoadCallback' + Date.now();
let deferred, config, scriptURL, params;
if ( !this.readyPromise ) {
deferred = $.Deferred();
config = mw.config.get( 'wgConfirmEditConfig' );
scriptURL = new mw.Uri( config.turnstileScriptURL );
params = { onload: onLoadFn, render: 'explicit' };
scriptURL.query = Object.assign( scriptURL.query, params );
this.readyPromise = deferred.promise();
window[ onLoadFn ] = deferred.resolve;
mw.loader.load( scriptURL.toString() );
}
return this.readyPromise;
};
ve.init.mw.TurnstileSaveErrorHandler.static.matchFunction = function ( data ) {
const captchaData = ve.getProp( data, 'visualeditoredit', 'edit', 'captcha' );
return !!( captchaData && captchaData.type === 'turnstile' );
};
ve.init.mw.TurnstileSaveErrorHandler.static.process = function ( data, target ) {
const self = this,
config = mw.config.get( 'wgConfirmEditConfig' ),
siteKey = config.turnstileSiteKey,
$container = $( '<div>' );
// Register extra fields
target.saveFields.wpCaptchaWord = function () {
// eslint-disable-next-line no-jquery/no-global-selector
return $( 'input[ name="cf-turnstile-response" ]' ).val();
};
this.getReadyPromise()
.then( () => {
if ( self.widgetId ) {
window.turnstile.reset( self.widgetId );
} else {
target.saveDialog.showMessage( 'api-save-error', $container, { wrap: false } );
self.widgetId = window.turnstile.render( $container[ 0 ], {
sitekey: siteKey,
callback: function () {
target.saveDialog.executeAction( 'save' );
},
'expired-callback': function () {},
'error-callback': function () {}
} );
target.saveDialog.updateSize();
}
target.emit( 'saveErrorCaptcha' );
} );
};
ve.init.mw.saveErrorHandlerFactory.register( ve.init.mw.TurnstileSaveErrorHandler );
} );
} );