ConfirmEdit: Support No CAPTCHA reCAPTCHA

Extend Captcha save error handler to verify user using
noCaptchaReCaptcha.

Bug: T203478
Change-Id: Ia5438bba6ff797dee822caf7664b911f01684744
This commit is contained in:
Nouman Saleem 2018-12-07 12:44:46 -08:00 committed by Zoranzoki21
parent 294258d568
commit e614050b6a
6 changed files with 124 additions and 2 deletions

View file

@ -7,6 +7,7 @@
},
"AutoloadClasses": {
"ReCaptchaNoCaptcha": "includes/ReCaptchaNoCaptcha.php",
"ReCaptchaNoCaptchaHooks": "includes/ReCaptchaNoCaptchaHooks.php",
"HTMLReCaptchaNoCaptchaField": "includes/HTMLReCaptchaNoCaptchaField.php",
"ReCaptchaNoCaptchaAuthenticationRequest": "includes/ReCaptchaNoCaptchaAuthenticationRequest.php"
},
@ -16,5 +17,20 @@
"ReCaptchaSecretKey": "",
"ReCaptchaSendRemoteIP": false
},
"ResourceFileModulePaths": {
"localBasePath": "resources",
"remoteExtPath": "ConfirmEdit/ReCaptchaNoCaptcha/resources"
},
"ResourceModules": {
"ext.confirmEdit.reCaptchaNoCaptcha.visualEditor": {
"scripts": "ve-confirmedit-reCaptchaNoCaptcha/ve.init.mw.NoCaptchaReCaptchaSaveErrorHandler.js"
}
},
"Hooks": {
"ResourceLoaderGetConfigVars": "ReCaptchaNoCaptchaHooks::onResourceLoaderGetConfigVars"
},
"VisualEditorPluginModules": [
"ext.confirmEdit.reCaptchaNoCaptcha.visualEditor"
],
"manifest_version": 1
}

View file

@ -82,8 +82,12 @@ HTML;
protected function getCaptchaParamsFromRequest( WebRequest $request ) {
// ReCaptchaNoCaptcha combines captcha ID + solution into a single value
// API is hardwired to return captchaWord, so use that if the standard isempty
// "captchaWord" is sent as "captchaword" by visual editor
$index = 'not used';
$response = $request->getVal( 'g-recaptcha-response', $request->getVal( 'captchaWord' ) );
$response = $request->getVal( 'g-recaptcha-response',
$request->getVal( 'captchaWord',
$request->getVal( 'captchaword' )
) );
return [ $index, $response ];
}

View file

@ -0,0 +1,23 @@
<?php
class ReCaptchaNoCaptchaHooks {
/**
* Adds extra variables to the global config
*
* @param array &$vars Global variables object
* @return bool Always true
*/
public static function onResourceLoaderGetConfigVars( array &$vars ) {
global $wgReCaptchaSiteKey;
global $wgCaptchaClass;
if ( $wgCaptchaClass === 'ReCaptchaNoCaptcha' ) {
$vars['wgConfirmEditConfig'] = [
'reCaptchaSiteKey' => $wgReCaptchaSiteKey,
'reCaptchaScriptURL' => 'https://www.google.com/recaptcha/api.js'
];
}
return true;
}
}

View file

@ -0,0 +1,6 @@
{
"globals": {
"ve": false,
"OO": false
}
}

View file

@ -0,0 +1,69 @@
mw.libs.ve.targetLoader.addPlugin( function () {
ve.init.mw.NoCaptchaReCaptchaSaveErrorHandler = function () {};
OO.inheritClass( ve.init.mw.NoCaptchaReCaptchaSaveErrorHandler, ve.init.mw.SaveErrorHandler );
ve.init.mw.NoCaptchaReCaptchaSaveErrorHandler.static.name = 'confirmEditNoCaptchaReCaptcha';
ve.init.mw.NoCaptchaReCaptchaSaveErrorHandler.static.getReadyPromise = function () {
var onLoadFn = 'onRecaptchaLoadCallback' + Date.now(),
deferred, config, scriptURL, params;
if ( !this.readyPromise ) {
deferred = $.Deferred();
config = mw.config.get( 'wgConfirmEditConfig' );
scriptURL = new mw.Uri( config.reCaptchaScriptURL );
params = { onload: onLoadFn, render: 'explicit' };
scriptURL.query = $.extend( scriptURL.query, params );
this.readyPromise = deferred.promise();
window[ onLoadFn ] = deferred.resolve;
mw.loader.load( scriptURL.toString() );
}
return this.readyPromise;
};
ve.init.mw.NoCaptchaReCaptchaSaveErrorHandler.static.matchFunction = function ( data ) {
var captchaData = ve.getProp( data, 'visualeditoredit', 'edit', 'captcha' );
return !!( captchaData && captchaData.type === 'recaptchanocaptcha' );
};
ve.init.mw.NoCaptchaReCaptchaSaveErrorHandler.static.process = function ( data, target ) {
var self = this,
config = mw.config.get( 'wgConfirmEditConfig' ),
siteKey = config.reCaptchaSiteKey,
$container = $( '<div>' );
// Register extra fields
target.saveFields.wpCaptchaWord = function () {
return $( '#g-recaptcha-response' ).val();
};
this.getReadyPromise()
.then( function () {
if ( self.widgetId ) {
window.grecaptcha.reset( self.widgetId );
} else {
target.saveDialog.showMessage( 'api-save-error', $container );
self.widgetId = window.grecaptcha.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.NoCaptchaReCaptchaSaveErrorHandler );
} );

View file

@ -4,7 +4,8 @@
"test": "grunt test"
},
"devDependencies": {
"eslint-config-wikimedia": "0.8.1",
"eslint-config-wikimedia": "^0.9.0",
"eslint-plugin-jquery": "^1.5.0",
"grunt": "1.0.3",
"grunt-banana-checker": "0.6.0",
"grunt-eslint": "21.0.0",
@ -12,5 +13,8 @@
"grunt-stylelint": "0.10.1",
"stylelint": "9.2.0",
"stylelint-config-wikimedia": "0.4.3"
},
"dependencies": {
"eslint-plugin-qunit": "^3.3.1"
}
}