btcpayserver / woocommerce-greenfield-plugin

BTCPay Server for WooCommerce V2 plugin.
MIT License
16 stars 9 forks source link

Allow extra Onion URL #4

Open Sjors opened 2 years ago

Sjors commented 2 years ago

I added a Tor hidden service to my WooCommerce site today, to provide a safer experience for folks who use Tor. I also made my BTC Instance reachable over Tor (different hidden service).

This presents a problem, because I need to direct clear-web folks to the regular BTCPay URL and Tor users to the hidden service. I hacked together a "solution" that basically checks if ONION_DOMAIN is set and then modifies the checkout link: https://github.com/Sjors/woocommerce-greenfield-plugin/commit/4e567a6b120df52329477610ab0f13106390f6b0

It might be nicer if the admin panel had a second onion URL field.

There's not really a standard way for users to configure WordPress to run an onion service. I used the approach here, which isn't super elegant. Pending such a convention, the instruction could simply state that ONION_DOMAIN must be set.

ndeet commented 2 years ago

Interesting, did not know this was even possible make it available on clearnet and tor, especially because WP is one of the few CMS that hardcodes the URLs in its database and not only store absolute paths like others (Drupal, Joomla, ...) do to become domain agnostic. Thats why the guide you mentioned has to rewrite all the content urls on the fly which likely also slightly slows down the site and breaks some static file caches. But I think this might be useful for others too to be able to serve both, clearnet and tor users.

In your code you check for the constant ONION_DOMAIN which is only available when you follow the guide you mentioned above. So this is not ideal to hardcode in the plugin I think.

Thinking about it a bit more we may not even need a second settings field for the .onion url at all? What if we detect if the current user browses a .onion url and if that is the case replace the checkout link domain with the .onion one.

E.g. if we use that same check (from the guide you linked) that detects .onion url:

if( preg_match( "/^([a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9]\.)?[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9]\.onion$/", $_SERVER['SERVER_NAME'] ) ){

we can replace the checkout link url (which we know from settings already) with the .onion url? (I assume $_SERVER['SERVER_NAME'] can't be faked or tricked from outside of the server but did not double check that)

What do you think?

ndeet commented 2 years ago

did not test and likely we need to make sure the url has no trailing slash but something like that might work; also not sure if onion urls are limited to 61 chars or not

            $url = $invoice->getData()['checkoutLink'];
            if ( preg_match( "/^([a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9]\.)?[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9]\.onion$/", $_SERVER['SERVER_NAME'] ) ){
                $url = str_replace($this->apiHelper->url, $_SERVER['SERVER_NAME'], $url);
            }

            return [
                'result'   => 'success',
                'redirect' => $url,
            ];