Skip to content

Improve handling of form submissions that redirect and implement form submission proxy#4212

Closed
westonruter wants to merge 5 commits intodevelopfrom
add/form-submission-proxy
Closed

Improve handling of form submissions that redirect and implement form submission proxy#4212
westonruter wants to merge 5 commits intodevelopfrom
add/form-submission-proxy

Conversation

@westonruter
Copy link
Copy Markdown
Member

@westonruter westonruter commented Feb 3, 2020

Summary

  • Add support for automatically redirecting users when WordPress uses header('Location: …') in the same way as before wp_redirect(…) was able to automatically supply the AMP-Redirect-To response header. This should eliminate the need for this shim code in Gravity Forms. The corresponding playbook information will also be obsolete with this PR.
  • Add support for submitting forms to external domains by means of a new REST API form submission proxy.

Fixes #4191.

Iterates on #2425. Revisits #911. See also #923.

Testing

  1. First of all, fire up this Glitch to be able to test remote form submissions.
  2. Then install the Test POST Form plugin.
  3. Add two shortcodes to a post: [test_post_form] and [test_post_form action="https://brook-paranthodon-k6ttvyw9a.glitch.me/"]. For example:
<!-- wp:paragraph -->
<p><strong>Internal action:</strong></p>
<!-- /wp:paragraph -->

<!-- wp:shortcode -->
[test_post_form]
<!-- /wp:shortcode -->

<!-- wp:paragraph -->
<p><strong>External action:</strong></p>
<!-- /wp:paragraph -->

<!-- wp:shortcode -->
[test_post_form action="https://brook-paranthodon-k6ttvyw9a.glitch.me/?foo=bar"]
<!-- /wp:shortcode -->
  1. Check the behavior of submitting the internal action and external action forms when on an AMP page.

Any submission request type that has a JSON response (including the use of wp_die()) should have a response looking like:

image

or

image

If the form handler does not respond with something that can be represented as JSON (e.g. returning with an HTML page) then the expected output should look like:

image

or

image

Note that the underlying HTTP status code and status text should be displayed in this message.

Additionally, if a form submission results in a redirect, either via wp_redirect() or using an underlying header('Location: …') call, then the user should be redirected after seeing a “Redirecting…” message momentarily:

image

Similar behavior should work both for when the form submission is handled internally by the present WordPress or if the form submission is pointing to another domain.

Checklist

  • My pull request is addressing an open issue (please create one otherwise).
  • My code is tested and passes existing tests.
  • My code follows the Engineering Guidelines (updates are often made to the guidelines, check it out periodically).

@googlebot googlebot added the cla: yes Signed the Google CLA label Feb 3, 2020
@westonruter westonruter added this to the v1.5 milestone Feb 5, 2020
@westonruter westonruter force-pushed the add/form-submission-proxy branch from e5c71dd to b246797 Compare February 5, 2020 22:50
@westonruter westonruter marked this pull request as ready for review February 5, 2020 22:59
@westonruter
Copy link
Copy Markdown
Member Author

Build for testing: amp.zip (v1.5.0-alpha-20200205T225235Z-b246797c6)

@westonruter
Copy link
Copy Markdown
Member Author

westonruter commented Feb 6, 2020

In testing making Genesis eNews Extended AMP-compatible in kraftbj/genesis-enews-extended#146, I was trying to supply an action-xhr for the FeedBurner form as opposed to action:

diff --git a/class-bjgk-genesis-enews-extended.php b/class-bjgk-genesis-enews-extended.php
index 0dbce39..e3bf7d1 100644
--- a/class-bjgk-genesis-enews-extended.php
+++ b/class-bjgk-genesis-enews-extended.php
@@ -130,14 +130,15 @@ class BJGK_Genesis_ENews_Extended extends WP_Widget {
 		if ( ! empty( $instance['id'] ) ) : ?>
 			<form
 				id="subscribe-<?php echo esc_attr( $this->id ); ?>"
-				action="https://feedburner.google.com/fb/a/mailverify"
 				method="post"
 				name="<?php echo esc_attr( $this->id ); ?>"
 				<?php if ( ! $this->is_amp() ) : ?>
 					target="popupwindow"
 					onsubmit="window.open( 'https://feedburner.google.com/fb/a/mailverify?uri=<?php echo esc_js( $instance['id'] ); ?>', 'popupwindow', 'scrollbars=yes,width=550,height=520');return true"
+					action="https://feedburner.google.com/fb/a/mailverify"
 				<?php else: ?>
 					on="<?php echo esc_attr( sprintf( "submit-success:AMP.navigateTo( url=%s, target=_blank )", wp_json_encode( 'https://feedburner.google.com/fb/a/mailverify?uri=' . $instance['id'], JSON_UNESCAPED_SLASHES ) ) ); ?>"
+					action-xhr="https://feedburner.google.com/fb/a/mailverify"
 				<?php endif; ?>
 			>
 				<label for="subbox" class="screenread"><?php echo esc_attr( $instance['input_text'] ); ?></label><input type="<?php echo current_theme_supports( 'html5' ) ? 'email' : 'text'; ?>" value="" id="subbox" placeholder="<?php echo esc_attr( $instance['input_text'] ); ?>" name="email"

When I did this, however, I got an error in the console:

Access to fetch at 'https://feedburner.google.com/fb/a/mailverify?__amp_source_origin=https%3A%2F%2Fwordpressdev.lndo.site' from origin 'https://wordpressdev.lndo.site' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

I did not get this error when I used the proxy. This would seem to indicate a problem with access-control.

That brings something to mind. Should the proxy be prevented from relaying JSON if the proxied endpoint does not return Access-Control-Allow-Origin? The risk seems to be that an AMP page in WordPress could potentially request unauthorized endpoint on another domain. Nevertheless, since the proxy does not forward any cookies in the request (which wouldn't make sense anyway), this risk seems lessened. Nevertheless, if there is an auth key provided as a URL parameter then this could be an issue.

I believe to harden this the proxy should be looking at any Access-Control-Allow-Origin and only allowing any JSON to pass through if the origin matches. Otherwise, since the proxy is on the same origin as the site, the access-control constraint would effectively be bypassed.

This PR warrants a good security review.

@chvillanuevap
Copy link
Copy Markdown

I just tested this version of the AMP plugin, and it worked great! I also tested the Genesis eNews Extended plugin and the target="_blank" bit worked as intended.

Thanks!

…submission-proxy

* 'develop' of github.com:ampproject/amp-wp: (4571 commits)
  Fix logic error
  Skip `AMP_Post_Meta_Box::get_amp_blocks_in_use()` test if on WP < 5.0
  Add tests
  Remove deprecation notice
  Use alternative method of getting blocks used in post
  Fix typo
  Show deprecation warning notice if an AMP-specific block is in the editor
  Hide AMP-specific blocks if they are not in the post
  Extend @wordpress/stylelint-config stylelint config
  Remove puppeteer dependency (now provided by @wordpress/scripts)
  Update package-lock.json
  Bump @wordpress/scripts from 12.6.1 to 13.0.1
  Bump @wordpress/blocks from 6.25.1 to 6.25.2
  Bump @wordpress/plugins from 2.24.1 to 2.24.2
  Bump @wordpress/data from 4.26.1 to 4.26.2
  Bump @wordpress/url from 2.21.0 to 2.21.1
  Bump @wordpress/babel-preset-default from 4.20.0 to 5.0.0
  Bump @wordpress/edit-post from 3.26.1 to 3.26.2
  Bump eslint-plugin-jsdoc from 31.2.1 to 31.4.0
  Update package-lock.json
  ...
@codecov
Copy link
Copy Markdown

codecov bot commented Feb 1, 2021

Codecov Report

Merging #4212 (cdfd29c) into develop (5a359d2) will decrease coverage by 0.30%.
The diff coverage is 25.53%.

Impacted file tree graph

@@              Coverage Diff              @@
##             develop    #4212      +/-   ##
=============================================
- Coverage      75.13%   74.83%   -0.31%     
- Complexity      5647     5665      +18     
=============================================
  Files            210      210              
  Lines          16961    17029      +68     
=============================================
  Hits           12743    12743              
- Misses          4218     4286      +68     
Flag Coverage Δ Complexity Δ
javascript 75.93% <ø> (ø) 0.00 <ø> (ø)
php 74.79% <25.53%> (-0.32%) 0.00 <32.00> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ Complexity Δ
includes/class-amp-http.php 64.57% <21.68%> (-25.30%) 80.00 <32.00> (+27.00) ⬇️
includes/class-amp-theme-support.php 86.30% <50.00%> (-0.26%) 233.00 <0.00> (-9.00)
includes/sanitizers/class-amp-form-sanitizer.php 95.61% <50.00%> (-2.59%) 43.00 <0.00> (ø)
includes/amp-helper-functions.php 84.33% <100.00%> (-0.09%) 0.00 <0.00> (ø)

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Feb 1, 2021

Plugin builds for f2484db are ready 🛎️!

@natoinet
Copy link
Copy Markdown

natoinet commented May 7, 2021

Hi @westonruter,

Will it be released with AMP-wp v2.2 ?
Or how can I add a Revue newsletter subscription form (using Revue Jetpack block) on a wordpress website running AMP-wp in standard mode ?

I've also been testing Jetpack Revue block along with AMP-wp v2.1.0-alpha-20210201T193527Z-cdfd29c.
While clicking on the subscribe button does not return an error anymore (while with AMP-wp v2.1, it was returning an error), the user is still not redirected to Revue after clicking on the Subscribe button.

Thanks :)

@westonruter westonruter added this to the v2.2 milestone May 8, 2021
@westonruter
Copy link
Copy Markdown
Member Author

@natoinet Yes, I want to finally get this into 2.2. This has been a long-standing pain point that needs to finally be addressed. I'll look at the Revue Block to see how it can be made compatible in the mean time.

@westonruter
Copy link
Copy Markdown
Member Author

I've implemented an external form submission proxy for the AMP plugin in this mini plugin: https://gist.github.com/westonruter/c08134bf8b33a49ef780a70b337d456f

I tried testing it with Revue, however, and I wasn't having much luck. More testing is needed.

@westonruter westonruter removed this from the v2.2 milestone Jun 4, 2021
@westonruter
Copy link
Copy Markdown
Member Author

The better bet here is going to be just allowing non-XHR POST forms on AMP pages. Without this, we have to resort to hacks. See ampproject/amphtml#27638 (comment).

In the mean time, I hope my mini plugin is useful as a workaround.

@westonruter westonruter closed this Jun 4, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla: yes Signed the Google CLA WS:Core Work stream for Plugin core

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support external POST forms via form submission proxy

5 participants