Mattflaschen has uploaded a new change for review.
https://gerrit.wikimedia.org/r/233660
Change subject: Fix CAPTCHA on new editors
......................................................................
Fix CAPTCHA on new editors
Previously, the CAPTCHA error showed the raw HTML, and also
there was no way to submit the CAPTCHA.
* Standardize on onEditorSaveContent
* Pass specific i18n message related to the spam filter flag to
the API response so we know which ones it's safe to treat as HTML.
Bug: T109554
Change-Id: I5df07700540898c7997b9ad0d8c5f81f3b6af721
---
M includes/Block/Block.php
M modules/flow/dm/api/mw.flow.dm.APIHandler.js
M modules/flow/ui/widgets/mw.flow.ui.BoardDescriptionWidget.js
M modules/flow/ui/widgets/mw.flow.ui.NewTopicWidget.js
M modules/flow/ui/widgets/mw.flow.ui.ReplyWidget.js
5 files changed, 107 insertions(+), 24 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Flow
refs/changes/60/233660/1
diff --git a/includes/Block/Block.php b/includes/Block/Block.php
index ccc5740..9d47053 100644
--- a/includes/Block/Block.php
+++ b/includes/Block/Block.php
@@ -329,7 +329,8 @@
return true;
}
- $this->addError( 'spamfilter', $status->getMessage() );
+ $message = $status->getMessage();
+ $this->addError( 'spamfilter', $message, $message->getKey() );
return false;
}
diff --git a/modules/flow/dm/api/mw.flow.dm.APIHandler.js
b/modules/flow/dm/api/mw.flow.dm.APIHandler.js
index 71324bd..8819b6d 100644
--- a/modules/flow/dm/api/mw.flow.dm.APIHandler.js
+++ b/modules/flow/dm/api/mw.flow.dm.APIHandler.js
@@ -112,16 +112,32 @@
};
/**
+ * Adds CAPTCHA to parameters if applicable
+ *
+ * @param {object} captcha CAPTCHA object
+ * @param {string} id CAPTCHA ID
+ * @param {string} answer CAPTCHA answer (user-provided)
+ */
+ mw.flow.dm.APIHandler.prototype.addCaptcha = function ( params, captcha
) {
+ // TODO: Find a better way to plug this in.
+ if ( captcha ) {
+ params.wpCaptchaId = captcha.id;
+ params.wpCaptchaWord = captcha.answer;
+ }
+ };
+
+ /**
* Send an edit request to the API to save a reply.
*
* @param {string} topicId Topic Id
* @param {string} replyTo The parent of this reply
* @param {string} content Reply content
* @param {string} format Reply content format
+ * @param {object} [captcha] CAPTCHA information
* @return {jQuery.Promise} Promise that is resolved with the id of the
workflow
* that this reply belongs to
*/
- mw.flow.dm.APIHandler.prototype.saveReply = function ( topicId,
replyTo, content, format ) {
+ mw.flow.dm.APIHandler.prototype.saveReply = function ( topicId,
replyTo, content, format, captcha ) {
var params = {
action: 'flow',
submodule: 'reply',
@@ -130,6 +146,8 @@
repcontent: content,
repformat: format
};
+
+ this.addCaptcha( params, captcha );
return ( new mw.Api() ).postWithToken( 'edit', params )
.then( function ( data ) {
@@ -143,9 +161,10 @@
* @param {string} title Topic title
* @param {string} content Topic content
* @param {string} format Content format
+ * @param {object} [captcha] CAPTCHA information
* @return {jQuery.Promise} Promise that is resolved with the new topic
id
*/
- mw.flow.dm.APIHandler.prototype.saveNewTopic = function ( title,
content, format ) {
+ mw.flow.dm.APIHandler.prototype.saveNewTopic = function ( title,
content, format, captcha ) {
var params = {
action: 'flow',
submodule: 'new-topic',
@@ -154,6 +173,8 @@
ntcontent: content,
ntformat: format
};
+
+ this.addCaptcha( params, captcha );
return ( new mw.Api() ).postWithToken( 'edit', params )
.then( function ( response ) {
@@ -183,10 +204,11 @@
* Save header information.
*
* @param {string} content Header content
- * @param {string} [format='fixed-html'] Content format for board
description
+ * @param {string} format Content format for board description
+ * @param {string} [captcha] CAPTCHA information
* @return {jQuery.Promise} Promise that is resolved with the saved
header revision id
*/
- mw.flow.dm.APIHandler.prototype.saveDescription = function ( content,
format ) {
+ mw.flow.dm.APIHandler.prototype.saveDescription = function ( content,
format, captcha ) {
var xhr,
params = {
page: this.page,
@@ -195,6 +217,8 @@
ehprev_revision: this.currentRevision
};
+ this.addCaptcha( params, captcha );
+
// return ( new mw.Api() ).postWithToken( 'edit', params )
xhr = this.postEdit( 'edit-header', params )
.then( function ( data ) {
diff --git a/modules/flow/ui/widgets/mw.flow.ui.BoardDescriptionWidget.js
b/modules/flow/ui/widgets/mw.flow.ui.BoardDescriptionWidget.js
index 8c74dea..c1d7e6b 100644
--- a/modules/flow/ui/widgets/mw.flow.ui.BoardDescriptionWidget.js
+++ b/modules/flow/ui/widgets/mw.flow.ui.BoardDescriptionWidget.js
@@ -160,10 +160,22 @@
* @param {string} contentFormat Format of content
*/
mw.flow.ui.BoardDescriptionWidget.prototype.onEditorSaveContent =
function ( content, format ) {
- var widget = this;
+ var widget = this, $captchaField, captcha;
this.editor.pushPending();
- this.api.saveDescription( content, format )
+
+ $captchaField = this.error.$label.find(
'[name="wpCaptchaWord"]' );
+ if ( $captchaField.length > 0 ) {
+ captcha = {
+ id: this.error.$label.find(
'[name="wpCaptchaId"]' ).val(),
+ answer: $captchaField.val()
+ };
+ }
+
+ this.error.setLabel( '' );
+ this.error.toggle( false );
+
+ this.api.saveDescription( content, format, captcha )
.then( function ( newRevisionId ) {
// Update revisionId in the API
widget.api.setCurrentRevision( newRevisionId );
@@ -182,8 +194,15 @@
widget.showContent( true );
} )
.then( null, function ( errorCode, errorObj ) {
- var $errorMessage = $( '<span>' ).text(
errorObj.error && errorObj.error.info || errorObj.exception );
- widget.error.setLabel( $errorMessage );
+ if ( /spamfilter$/.test( errorCode ) &&
errorObj.error.spamfilter === 'flow-spam-confirmedit-form' ) {
+ widget.error.setLabel(
+ // CAPTCHA form
+ new OO.ui.HtmlSnippet(
errorObj.error.info )
+ );
+ } else {
+ widget.error.setLabel( errorObj.error
&& errorObj.error.info || errorObj.exception );
+ }
+
widget.error.toggle( true );
} )
.always( function () {
diff --git a/modules/flow/ui/widgets/mw.flow.ui.NewTopicWidget.js
b/modules/flow/ui/widgets/mw.flow.ui.NewTopicWidget.js
index 5d43d18..67228b0 100644
--- a/modules/flow/ui/widgets/mw.flow.ui.NewTopicWidget.js
+++ b/modules/flow/ui/widgets/mw.flow.ui.NewTopicWidget.js
@@ -48,7 +48,7 @@
// Events
this.editor.connect( this, {
change: 'updateSaveButtonState',
- saveContent: 'onEditorSave',
+ saveContent: 'onEditorSaveContent',
cancel: 'onEditorCancel'
} );
this.editor.once( 'switch', function ( promise ) {
@@ -125,29 +125,50 @@
* @param {string} content Content
* @param {string} format Content format
*/
- mw.flow.ui.NewTopicWidget.prototype.onEditorSave = function ( content,
format ) {
+ mw.flow.ui.NewTopicWidget.prototype.onEditorSaveContent = function (
content, format ) {
var widget = this,
- title = this.title.getValue();
+ title = this.title.getValue(),
+ $captchaField,
+ captcha;
- this.error.toggle( false );
this.editor.pushPending();
this.title.pushPending();
this.title.setDisabled( true );
- this.api.saveNewTopic( title, content, format )
+
+ $captchaField = this.error.$label.find(
'[name="wpCaptchaWord"]' );
+ if ( $captchaField.length > 0 ) {
+ captcha = {
+ id: this.error.$label.find(
'[name="wpCaptchaId"]' ).val(),
+ answer: $captchaField.val()
+ };
+ }
+
+ this.error.setLabel( '' );
+ this.error.toggle( false );
+
+ this.api.saveNewTopic( title, content, format, captcha )
.then( function ( topicId ) {
widget.toggleExpanded( false );
widget.emit( 'save', topicId );
} )
.then( null, function ( errorCode, errorObj ) {
- var $errorMessage = $( '<span>' ).text(
errorObj.error && errorObj.error.info || errorObj.exception );
- widget.error.setLabel( $errorMessage );
+ if ( /spamfilter$/.test( errorCode ) &&
errorObj.error.spamfilter === 'flow-spam-confirmedit-form' ) {
+ widget.error.setLabel(
+ // CAPTCHA form
+ new OO.ui.HtmlSnippet(
errorObj.error.info )
+ );
+ } else {
+ widget.error.setLabel( errorObj.error
&& errorObj.error.info || errorObj.exception );
+ }
+
widget.error.toggle( true );
} )
.always( function () {
widget.editor.popPending();
widget.title.popPending();
widget.title.setDisabled( false );
-
+ } )
+ .done( function () {
// Clear for next use
widget.title.setValue( '' );
widget.editor.setContent( '', 'html' );
diff --git a/modules/flow/ui/widgets/mw.flow.ui.ReplyWidget.js
b/modules/flow/ui/widgets/mw.flow.ui.ReplyWidget.js
index 0aef4c7..ed302ac 100644
--- a/modules/flow/ui/widgets/mw.flow.ui.ReplyWidget.js
+++ b/modules/flow/ui/widgets/mw.flow.ui.ReplyWidget.js
@@ -52,7 +52,7 @@
// Events
this.editor.connect( this, {
- saveContent: 'onEditorSave',
+ saveContent: 'onEditorSaveContent',
cancel: 'onEditorCancel'
} );
@@ -107,12 +107,23 @@
/**
* Respond to editor save
*/
- mw.flow.ui.ReplyWidget.prototype.onEditorSave = function ( content,
format ) {
- var widget = this;
+ mw.flow.ui.ReplyWidget.prototype.onEditorSaveContent = function (
content, format ) {
+ var widget = this, $captchaField,
+ captcha;
- this.error.toggle( false );
+ $captchaField = this.error.$label.find(
'[name="wpCaptchaWord"]' );
+ if ( $captchaField.length > 0 ) {
+ captcha = {
+ id: this.error.$label.find(
'[name="wpCaptchaId"]' ).val(),
+ answer: $captchaField.val()
+ };
+ }
+
+ this.error.setLabel( '' );
+ this.error.toggle( false )
+ ;
this.editor.pushPending();
- this.api.saveReply( this.topicId, this.replyTo, content, format
)
+ this.api.saveReply( this.topicId, this.replyTo, content,
format, captcha )
.then( function ( workflow ) {
if ( widget.expandable ) {
widget.triggerInput.toggle( true );
@@ -123,8 +134,15 @@
widget.emit( 'saveContent', workflow, content,
format );
} )
.then( null, function ( errorCode, errorObj ) {
- var $errorMessage = $( '<span>' ).text(
errorObj.error && errorObj.error.info || errorObj.exception );
- widget.error.setLabel( $errorMessage );
+ if ( /spamfilter$/.test( errorCode ) &&
errorObj.error.spamfilter === 'flow-spam-confirmedit-form' ) {
+ widget.error.setLabel(
+ // CAPTCHA form
+ new OO.ui.HtmlSnippet(
errorObj.error.info )
+ );
+ } else {
+ widget.error.setLabel( errorObj.error
&& errorObj.error.info || errorObj.exception );
+ }
+
widget.error.toggle( true );
} )
.always( function () {
--
To view, visit https://gerrit.wikimedia.org/r/233660
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I5df07700540898c7997b9ad0d8c5f81f3b6af721
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Flow
Gerrit-Branch: master
Gerrit-Owner: Mattflaschen <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits