cachet icon indicating copy to clipboard operation
cachet copied to clipboard

APP_URL not taken into account : ugly hotfix

Open thomvaill opened this issue 4 years ago • 10 comments

Hello,

I am running Cachet behind an ALB, which is itself behind an HAProxy (because exposed on an intranet). The ALB performs the SSL termination and the HAProxy exposes Cachet on a custom port. As a result, Cachet is completely confused when generating its URLs:

  • uses http:// instead of https://
  • does not take into account the custom port

I thought the APP_URL would solve my issue, but it is unfortunately not taken into account at all. A lot of issues reference this problem:

  • https://github.com/CachetHQ/Docker/issues/262
  • https://github.com/CachetHQ/Docker/issues/271
  • https://github.com/CachetHQ/Cachet/issues/1545
  • https://github.com/CachetHQ/Cachet/issues/2522

Each time, we see only one solution: patch a file with \URL::forceSchema('https');... Unfortunately, the solution, in addition to being ugly, is not complete because the redirection after login to the dashboard is still not fixed.

So, for those who might be interested, here is how I managed to patch the Docker image to make it fully work:

FROM cachethq/docker:2.3.15

RUN set -e; \
    # HOTFIX #1: force root URL and schema
    # We locate the boot() method in AppServiceProvider.php
    line=$(grep -n 'public function boot(Dispatcher $dispatcher)$' /var/www/html/app/Foundation/Providers/AppServiceProvider.php | tail -n1 | cut -f1 -d:); \
\
    # We insert the code 2 lines after because there is a "{" on a separate line
    insertAtLine=$((line+2)); \
\
    # We insert the hotfix
    sed -i "$insertAtLine i \\
        // Begin hotfix \n \
        if (getenv('APP_URL')) { \n \
            if (strpos(getenv('APP_URL'), 'https') === 0) { \n \
                \\\URL::forceSchema('https'); \n \
            } \n \
            \\\URL::forceRootUrl(getenv('APP_URL')); \n \
        } \n \
        // End hotfix \n \
    " /var/www/html/app/Foundation/Providers/AppServiceProvider.php; \
\
    # We forward the APP_URL environment variable to FPM
    echo '[www]' > /etc/php7/php-fpm.d/app-url-fix.conf; \
    echo 'env[APP_URL] = $APP_URL' >> /etc/php7/php-fpm.d/app-url-fix.conf; \
\
    # HOTFIX #2: fix login redirection to dashboard
    # Normally it redirects to the last URL, but since Cachet is not able to detect URLs right, we force a redirection to dashboard
    sed -i "s/Redirect::intended('dashboard');/Redirect::route('dashboard.index');/g" \
        /var/www/html/app/Http/Controllers/AuthController.php

Of course, this is ugly and works only for a specific version of Cachet. Is it possible to implement this fix correctly?

thomvaill avatar Feb 27 '20 11:02 thomvaill

:wave: Thank you for opening your first issue. I'm just an automated bot that's here to help you get the information you need quicker, so please ignore this message if it doesn't apply to your issue. If you're looking for support, you should try the Slack group by registering your email address at https://cachethq-slack.herokuapp.com. Alternatively, email [email protected] for our Professional support service (please note, this a paid service.) If you're issue is with documentation, you can suggest edits by clicking the Suggest Edits link on any page, or open an issue at https://github.com/CachetHQ/Docs

welcome[bot] avatar Feb 27 '20 11:02 welcome[bot]

And the slightly modified fix for the latest version (2.4 at this time) of the container:

FROM cachethq/docker:latest

RUN set -e; \
    # HOTFIX #1: force root URL and schema
    # We locate the boot() method in AppServiceProvider.php
    line=$(grep -n 'public function boot(Dispatcher $dispatcher)$' /var/www/html/app/Foundation/Providers/AppServiceProvider.php | tail -n1 | cut -f1 -d:); \
\
    # We insert the code 2 lines after because there is a "{" on a separate line
    insertAtLine=$((line+2)); \
\
    # We insert the hotfix
    sed -i "$insertAtLine i \\
        // Begin hotfix \n \
        if (getenv('APP_URL')) { \n \
            if (strpos(getenv('APP_URL'), 'https') === 0) { \n \
                \\\URL::forceScheme('https'); \n \
            } \n \
            \\\URL::forceRootUrl(getenv('APP_URL')); \n \
        } \n \
        // End hotfix \n \
    " /var/www/html/app/Foundation/Providers/AppServiceProvider.php; \
\
    # We forward the APP_URL environment variable to FPM
    echo '[www]' > /etc/php7/php-fpm.d/app-url-fix.conf; \
    echo 'env[APP_URL] = $APP_URL' >> /etc/php7/php-fpm.d/app-url-fix.conf; \
\
# HOTFIX #2: fix login redirection to dashboard
    # Normally it redirects to the last URL, but since Laravel is not able to detect URLs right, we force a redirection to dashboard
    sed -i "s/Redirect::intended(cachet_route('dashboard'));/cachet_redirect('dashboard');/g" \
        /var/www/html/app/Http/Controllers/AuthController.php; \
    sed -i "s/Redirect::intended('dashboard');/cachet_redirect('dashboard');/g" \
        /var/www/html/app/Http/Controllers/AuthController.php```

found how to do it based on https://laracasts.com/discuss/channels/laravel/forcescheme-or-forceschema-in-laravel-54

Merci @Thomvaill for the original fix!

Edit: Updated with updated hotfix 2 below

MichaelPereira avatar Apr 06 '20 02:04 MichaelPereira

And the slightly modified fix for the latest version (2.4 at this time) of the container:

FROM cachethq/docker:latest

RUN set -e; \
    # HOTFIX #1: force root URL and schema
    # We locate the boot() method in AppServiceProvider.php
    line=$(grep -n 'public function boot(Dispatcher $dispatcher)$' /var/www/html/app/Foundation/Providers/AppServiceProvider.php | tail -n1 | cut -f1 -d:); \
\
    # We insert the code 2 lines after because there is a "{" on a separate line
    insertAtLine=$((line+2)); \
\
    # We insert the hotfix
    sed -i "$insertAtLine i \\
        // Begin hotfix \n \
        if (getenv('APP_URL')) { \n \
            if (strpos(getenv('APP_URL'), 'https') === 0) { \n \
                \\\URL::forceScheme('https'); \n \
            } \n \
            \\\URL::forceRootUrl(getenv('APP_URL')); \n \
        } \n \
        // End hotfix \n \
    " /var/www/html/app/Foundation/Providers/AppServiceProvider.php; \
\
    # We forward the APP_URL environment variable to FPM
    echo '[www]' > /etc/php7/php-fpm.d/app-url-fix.conf; \
    echo 'env[APP_URL] = $APP_URL' >> /etc/php7/php-fpm.d/app-url-fix.conf; \
\
    # HOTFIX #2: fix login redirection to dashboard
    # Normally it redirects to the last URL, but since Cachet is not able to detect URLs right, we force a redirection to dashboard
    sed -i "s/Redirect::intended('dashboard');/Redirect::route('dashboard.index');/g" \
        /var/www/html/app/Http/Controllers/AuthController.php

found how to do it based on https://laracasts.com/discuss/channels/laravel/forcescheme-or-forceschema-in-laravel-54

Merci @Thomvaill for the original fix!

And here is the correct fix for "HOTFIX #2: fix login redirection to dashboard" for v2.4:

    # HOTFIX #2: fix login redirection to dashboard
    # Normally it redirects to the last URL, but since Laravel is not able to detect URLs right, we force a redirection to dashboard
    sed -i "s/Redirect::intended(cachet_route('dashboard'));/cachet_redirect('dashboard');/g" \
        /var/www/html/app/Http/Controllers/AuthController.php; \
    sed -i "s/Redirect::intended('dashboard');/cachet_redirect('dashboard');/g" \
        /var/www/html/app/Http/Controllers/AuthController.php

thomvaill avatar Apr 10 '20 13:04 thomvaill

Thank you so much for this :)

quentinlesceller avatar Apr 27 '20 19:04 quentinlesceller

Any chance of any of you doing a PR so this get's merged ?

lhirlimann avatar May 26 '20 13:05 lhirlimann

If anyone else comes across this, I rectified this by simply adding TRUSTED_PROXIES=* to the environment variables on startup.

jaxxstorm avatar Jun 15 '20 02:06 jaxxstorm

Looks like a series of recent commits broke this fix. Mostly https://github.com/CachetHQ/Cachet/pull/4071 but event just removing 'foundations' from the fix doesn't gives the same end result.

ppinzon avatar Aug 11 '20 16:08 ppinzon

Hello, Is an update planned to integrate these changes in a sustainable way?

FrBillyD avatar Feb 25 '21 08:02 FrBillyD

Hello,

Since two week i try to make it work the ssl with CachetHQ and I just came across this topic that seems to fix the problems with SSL.

I have follow the installation on cachetHQ documentation: https://docs.cachethq.io/docs/get-started-with-docker git clone https://github.com/cachethq/Docker.git Then had modify docker-compose.yml to use the build last production stable version (2.3.18) and my own environment variables. After that i modify the Dockerfile (downloaded with the git clone) to add these lines below,

I tried to modify the Dockerfile and replace it with the following content:

Dockerfile

FROM cachethq/docker:2.3.18

RUN set -e; \
    # HOTFIX 1: force root URL and schema
    # We locate the boot() method in AppServiceProvider.php
    line=$(grep -n 'public function boot(Dispatcher $dispatcher)$' /var/www/html/app/Foundation/Providers/AppServiceProvider.php | tail -n1 | cut -f1 -d:); \
\
    # We insert the code 2 lines after because there is a "{" on a separate line
    insertAtLine=$((line+2)); \
\
    # We insert the hotfix
    sed -i "$insertAtLine i \\
        // Begin hotfix \n \
        if (getenv('APP_URL')) { \n \
            if (strpos(getenv('APP_URL'), 'https') === 0) { \n \
                \\\URL::forceScheme('https'); \n \
            } \n \
            \\\URL::forceRootUrl(getenv('APP_URL')); \n \
        } \n \
        // End hotfix \n \
    " /var/www/html/app/Foundation/Providers/AppServiceProvider.php; \
\
    # We forward the APP_URL environment variable to FPM
    echo '[www]' > /etc/php7/php-fpm.d/app-url-fix.conf; \
    echo 'env[APP_URL] = $APP_URL' >> /etc/php7/php-fpm.d/app-url-fix.conf; \
\
    # HOTFIX 2: fix login redirection to dashboard
    # Normally it redirects to the last URL, but since Laravel is not able to detect URLs right, we force a redirection to dashboard
    sed -i "s/Redirect::intended(cachet_route('dashboard'));/cachet_redirect('dashboard');/g" \
        /var/www/html/app/Http/Controllers/AuthController.php; \
    sed -i "s/Redirect::intended('dashboard');/cachet_redirect('dashboard');/g" \
        /var/www/html/app/Http/Controllers/AuthController.php```

But i have some issue: the first is : ERROR: dockerfile parse error line 13: unknown instruction: //

If i comment this line the i have another error: Error response from daemon: dockerfile parse error line 14: unknown instruction: IF

I think this is not the right solution I used to solve this ssl problem and i don't understand why it's not working.

If you need i have upload my docker-compose to a better understanding of my issue. (The version of traefik is traefik v2) docker-compose_cachet_postgres.txt

Do you have an idea to help me on this issue ?

Regards,

xoxopeter avatar Mar 19 '21 10:03 xoxopeter

@xoxopeter I think you're getting some copy paste issues from the github formatting.

After messing around with it line by line, this is what worked for me (at least for getting it to build) :

FROM cachethq/docker:2.3.18

RUN set -e; \
    # HOTFIX 1: force root URL and schema
    # We locate the boot() method in AppServiceProvider.php
    line=$(grep -n 'public function boot(Dispatcher $dispatcher)$' /var/www/html/app/Foundation/Providers/AppServiceProvider.php | tail -n1 | cut -f1 -d:); \
\
    # We insert the code 2 lines after because there is a "{" on a separate line
    insertAtLine=$((line+2)); \
\
    # We insert the hotfix
    sed -i "$insertAtLine i \\ \
        if (getenv('APP_URL')) { \n \
            if (strpos(getenv('APP_URL'), 'https') === 0) { \n \
                \\\URL::forceSchema('https'); \n \
            } \n \
            \\\URL::forceRootUrl(getenv('APP_URL')); \n \
        } \n \
    " /var/www/html/app/Foundation/Providers/AppServiceProvider.php; \
\
    # We forward the APP_URL environment variable to FPM
    echo '[www]' > /etc/php7/php-fpm.d/app-url-fix.conf; \
    echo 'env[APP_URL] = $APP_URL' >> /etc/php7/php-fpm.d/app-url-fix.conf; \
\
    # HOTFIX 2: fix login redirection to dashboard
    # Normally it redirects to the last URL, but since Laravel is not able to detect URLs right, we force a redirection to dashboard
    sed -i "s/Redirect::intended(cachet_route('dashboard'));/cachet_redirect('dashboard');/g" \
        /var/www/html/app/Http/Controllers/AuthController.php; \
    sed -i "s/Redirect::intended('dashboard');/cachet_redirect('dashboard');/g" \
        /var/www/html/app/Http/Controllers/AuthController.php

InputObject2 avatar Apr 23 '21 15:04 InputObject2

Thank you for your input on Cachet 2.x. We are shifting our attention and resources to Cachet 3.x and will no longer be supporting the 2.x version. If your feedback or issue is relevant to the 3.x series, we encourage you to engage with the new branch.

For more information on the Cachet rebuild and our plans for 3.x, you can read the announcement here.

We appreciate your understanding and look forward to your contributions to the new version.

jbrooksuk avatar Aug 12 '23 19:08 jbrooksuk