caoranach / DiscordConnect

This is a FoundryVTT module designed to mirror Foundry chat to a Discord channel.
5 stars 11 forks source link

CORS issues #14

Open azekeil opened 3 years ago

azekeil commented 3 years ago

I get this: image when attempting to connect the Discord Webhook to my Foundry server running on HTTPS. Googling, it looks like you need to send the Access-Control-Allow-Origin in both the OPTIONS and the POST request: https://stackoverflow.com/questions/63586021/discord-webhook-access-control-allow-origin

azekeil commented 3 years ago

I tried replacing your sendToWebhook function with the below:

function sendToWebhook(message, msgText, hookEmbed, hook, img){
    // To conform to the 'simple requests' to avoid triggering CORS,
    // https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests
    // which is no longer supported by browsers (servers only) or discord's API
    // with the move to discord.com, we send multipart/form-data

    // Discord supports passing a stringified JSON body as a form value as payload_json instead:
    // https://discord.com/developers/docs/resources/webhook#execute-webhook

    var request = new XMLHttpRequest();
    request.open("POST", hook);
    request.setRequestHeader('Content-type', 'multipart/form-data');

    var params = {
        username: message.alias,
        // avatar_url: encodeURI(img),
        content: msgText,
        // embeds: hookEmbed
    }
    formData = new FormData();
    formData.append("payload_json", JSON.stringify(params))
    request.send(formData);
}

But even that was still giving CORS errors. I think discord have just blocked browsers from accessing even their webhook APIs, which makes me sad, and renders this plugin broken, unless you're willing to override CORS security in your browser :(

azekeil commented 3 years ago

I found this https://chriscarey.com/blog/2014/06/13/apache-proxy-with-cors-headers/ but I didn't have much luck getting it to work for me. I've given up for now :(

azekeil commented 3 years ago

I got it working! Turns out you have to strip out most of the headers that your client sends, or discord gets its knickers in a twist. I'll submit a PR with an updated readme and proxy code shortly, but here's a (genericised) config for apache that also proxies for VTT (in case you want to host multiple things on your single IP).

Note there are two sections in the config:

<VirtualHost *:443>
        # General SSL settings (Required for both VTT and DiscordProxy)
        ServerName vtt.example.com
        SSLEngine On
        SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
        SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem

        # START: VTT Proxy Server Configuration
        ProxyPreserveHost       On
        ProxyPass "/socket.io/" "ws://localhost:30000/socket.io/"
        ProxyPass /             http://localhost:30000/
        ProxyPassReverse /      http://localhost:30000/
        # END: VTT Proxy Server Configuration

        # START: DiscordProxy settings
        SSLProxyEngine On

        <LocationMatch "/discordproxy/">
           ProxyPreserveHost Off
           RequestHeader unset Referer
           RequestHeader unset sec-ch-ua
           RequestHeader unset Connection
           RequestHeader unset Origin
           RequestHeader unset Sec-Fetch-Site
           RequestHeader unset Sec-Fetch-Mode
           RequestHeader unset Sec-Fetch-Dest
           RequestHeader unset Cookie
           ProxyPass https://discord.com/api/
           ProxyPassReverse https://discord.com/api/
           Header always set "Access-Control-Allow-Origin" "https://vtt.example.com"
           Header always set "User-Agent" "discordproxy/1.0"
        </LocationMatch>
        # END: DiscordProxy settings

</VirtualHost>