Mattflaschen has submitted this change and it was merged.

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, 108 insertions(+), 24 deletions(-)

Approvals:
  Sbisson: Looks good to me, approved
  Mattflaschen: Verified; Looks good to me, approved



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..13b4bbc 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..39bfdad 100644
--- a/modules/flow/ui/widgets/mw.flow.ui.BoardDescriptionWidget.js
+++ b/modules/flow/ui/widgets/mw.flow.ui.BoardDescriptionWidget.js
@@ -160,10 +160,23 @@
         * @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 +195,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..33e6349 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: merged
Gerrit-Change-Id: I5df07700540898c7997b9ad0d8c5f81f3b6af721
Gerrit-PatchSet: 2
Gerrit-Project: mediawiki/extensions/Flow
Gerrit-Branch: master
Gerrit-Owner: Mattflaschen <mflasc...@wikimedia.org>
Gerrit-Reviewer: Catrope <roan.katt...@gmail.com>
Gerrit-Reviewer: Mattflaschen <mflasc...@wikimedia.org>
Gerrit-Reviewer: Sbisson <sbis...@wikimedia.org>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to