amp-toolbox icon indicating copy to clipboard operation
amp-toolbox copied to clipboard

@ampproject/toolbox-cors error on submitting amp-form from amp-email

Open davecook88 opened this issue 4 years ago • 10 comments

Following all of the setup instructions in the readme, @ampproject/toolbox-cors allows my amp-lists to retrieve dynamic content but when submitting an amp-form, the following error is displayed:

Uncaught (in promise) Error: Class$obf_1009: [https://dynamicmail-pa.googleapis.com/v2/xhrs:proxy?alt=protojson] Cg: Unsupported HTTP status: 400: Class$obf_1011: [object Object]

log.js:258 [amp-form] Form submission failed: Error: Request viewerRenderTemplate failed: Error: Class$obf_1009: [https://dynamicmail-pa.googleapis.com/v2/xhrs:proxy?alt=protojson] Cg: Unsupported HTTP status: 400: Class$obf_1011: [object Object]

I can see from my logs that the request is never reaching my server.

Here is a minimal version of my server setup for reference https://github.com/davecook88/firebase-minimal

davecook88 avatar Dec 15 '20 19:12 davecook88

Hm. that's hard to tell from the error. In your sample code (which looks fine) I've noticed that you're manually configuring cors as well: https://github.com/davecook88/firebase-minimal/blob/master/functions/index.js#L39. Not sure though whether that's a problem in your case.

sebastianbenz avatar Dec 16 '20 11:12 sebastianbenz

@patrickkettner are you aware of any specifics to how AMP email handles post requests that could be a problem here?

sebastianbenz avatar Dec 16 '20 14:12 sebastianbenz

It looks like gmail is blocking the request at the XHR proxy. CORS in amp4email require special configuration to be supported - Here are the docs

patrickkettner avatar Dec 16 '20 14:12 patrickkettner

@patrickkettner

Thank you very much for your response. I understand that the email:true flag in the toolbox library should handle this, though?

I've followed the instructions in the link and I've met the same issue. Also, I'm confused as to why this would be ok in AMP playground but not in Gmail.

@sebastianbenz

To be honest, I've tried everything I can possibly think of, manually configuring CORS, using this library, and a combination of the two. I can say that when those lines are commented out, the issue is the same.

When sending the POST requests from AMP playground, I can follow the process pretty easily from the request in the browser to my server. It seems that when sending from the Gmail context, the request is routed through the AMP cache (which the verifyOrigin flag in the toolbox whitelists, as I understand).

When sending the POST request from Gmail, the request never hits my server and, as the error messages are quite opaque, I'm unsure as to what the precise issue is.

davecook88 avatar Dec 16 '20 14:12 davecook88

@patrickkettner following your response, I wanted to be totally sure that I had exhausted all of my options and I implemented the solution suggested in the documentation that you linked (commenting out the cors and ampCors library references).

This is what I came up with as a nodeJS version of the code on the page:

const isAllowedEmail = (email) => {
    return true; //["[email protected]"].includes(email);
};

app.use((req, res, next) => {
    let senderEmail;
    console.log("request received");
    console.log("headers", req.headers);
    if (req.headers["AMP-Email-Sender"]) {
        console.log("request received");
        senderEmail = req.headers["AMP-Email-Sender"];
        if (isAllowedEmail(senderEmail)) {
            res.set("AMP-Email-Allow-Sender", senderEmail);
        }
    } else if (req.headers["origin"]) {
        const reqOrigin = req.headers["origin"];
        if (!req.query.__amp_source_origin) {
            return next(new Error("Not allowed by CORS"));
        } else {
            senderEmail = req.query.__amp_source_origin;
            if (!isAllowedEmail(senderEmail)) {
                return next(new Error("Not allowed by CORS"));
            }
        }
        console.log("reqOrigin", reqOrigin);
        console.log("senderEmail", senderEmail);
        res.set("Access-Control-Allow-Origin", reqOrigin);
        res.set(
            "Access-Control-Expose-Headers",
            "AMP-Access-Control-Allow-Source-Origin"
        );
        res.set("AMP-Access-Control-Allow-Source-Origin", senderEmail);
        return next();
    }
});

If you can see anything that is incorrect here, please let me know.

Even with this, the result is the same. The amp-lists populate correctly. The amp-forms submit from the playground contexts but the same errors are being returned from the XHR proxy.

davecook88 avatar Dec 16 '20 16:12 davecook88

Would you be able to share the contents of the you are loading that is attempting this fetch?

The error in your original report, that is the devtools console output on gmail.com? Do you see the XHR request firing that triggers that 400? Are you able to see if it is including the required AMP-Email-Sender and AMP-Email-Allow-Sender headers?

patrickkettner avatar Dec 16 '20 17:12 patrickkettner

Thanks again for taking the time to answer. Yes, the errors in my original post are the devtools console errors that show up when I submit the form.

I can see the XHR request. As opposed to when I locate this in the playground, I can see a lot of other codes injected into the request, which I'm wary to make public just incase there's a security risk involved.

The response is:


--batch__V0SyTdSGFOz3Ntwv6DZ2oex4lM3vzwD
Content-Type: application/http
Content-ID: <[email protected]>

HTTP/1.1 400 Bad Request
Vary: Origin
Vary: X-Origin
Vary: Referer
Content-Type: application/json+protobuf; charset=UTF-8

{"1":3,"2":"Request contains an invalid argument."}
--batch__V0SyTdSGFOz3Ntwv6DZ2oex4lM3vzwD--

I can see that the origin matches on the request and the response:

request:

origin: https://mail.google.com
referer: https://mail.google.com/

response:

access-control-allow-origin: https://mail.google.com

The only query string parameter I can see is this:

%24ct: multipart%2Fmixed%3B%20boundary%3Dbatch627546551269428321

I can't see AMP-Email-Sender and AMP-Email-Allow-Sender headers. I was assuming that these would be added by the proxy. I can see the sender email address in the payload, along with other codes etc added by Gmail.

As I mentioned, I can't see that the request ever reaches my server.

davecook88 avatar Dec 16 '20 20:12 davecook88

Is there any news on this? Is it safe to say that this is an issue with the library?

davecook88 avatar Dec 22 '20 18:12 davecook88

I've received an answer from someone at Google about this.

There's a bug with AMP forms submitting with enctype=3D"application/x-www-form-urlencoded" which has been submitted for resolution.

I'll update this thread when I have an update on the ticket.

davecook88 avatar Dec 30 '20 01:12 davecook88

FYI this bug should now be fixed in Gmail.

zhangsu avatar Oct 12 '21 19:10 zhangsu