the-djmaze / snappymail

Simple, modern & fast web-based email client
https://snappymail.eu
GNU Affero General Public License v3.0
1.01k stars 121 forks source link

[NC] NGINX Snappymail doesn't work when front_controller_active is enabled #723

Closed msva closed 1 year ago

msva commented 1 year ago

Describe the bug Hi there! I've found, that if I set envidonment varable front_controller_active to true (as it is in default nextcloud .htaccess file) to make NC use "pretty URLs" (without /index.php/ crap), SnappyMail plugin brakes up, and shows this error: image

To Reproduce Steps to reproduce the behavior:

  1. Use PHP as PHP-FPM or as NginX-Unit module
  2. Set front_controller_active env variable to true
  3. login to NC instance and select SnapyMail Email app
  4. See error

Expected behavior Working fine exactly as it does if there is .../index.php/apps/snapymail in URL.

the-djmaze commented 1 year ago

Go to /apps/snappymail/?admin#/config And check the value of app_path

If that also fails, open /data/appdata_snappymail/_data_/_default_/configs/application.ini and check the value there.

My Nextcloud is in /nextcloud and Nextcloud config.php has

'htaccess.RewriteBase' => '/nextcloud',

Then i did sudo -u username php occ maintenance:update:htaccess and works fine.

My application.ini app_path value is /nextcloud/apps/snappymail/app/

Therefore you should debug your installation and find the issue.

msva commented 1 year ago

There is /apps/snappymail/app (I have NC in the root of domain) And there is no index.php mentioned there.

Also, /apps/snappymail/?admin#/config redirects to files app somewhy :man_shrugging:

Also, 1) I don't use Apache, so regenerating .htaccess is useless (but I did it just in case :man_shrugging:) 2) Also, if I open network log in browser inspector, I see a request to https://domain.tld/apps/snappymail/?/AppData/0/40240954361558834/ which gets 404 (because that url assumes that request was made to /apps/snappymail/index.php, which does not exist) and so it doesn't even goes to backend server. 3) I know, that this is useless argument, but, well... "all other ("official", at least) apps works fine" (I guess, that is because they don't use ./?/ requests :man_shrugging:).

I'd bet that right way would be to load not ./?/AppData/0/..., but /?/AppData/0/...(from root, not from current dir)

So, for now, I made a kludgy hack for that in NginX config:

location = /apps/snappymail/ {
  return 307 /index.php$request_uri;
}

But I'd like to avoid /index.php/ on URL even here.

msva commented 1 year ago

Well... I exeprimented a bit and found that /?/AppData/0 doesn't help, but modifying ./? to /index.php/apps/snappymail/? in apps/snappymail/app/snappymail/v/2.22.4/static/js/min/boot.min.js helps.

Although, then it fails on ./?/Plugins/0/User/, but at least directon is clear...

So, right way would be to don't use ./?/, and use /index.php${app_path}/?/ instead.

(but my JS-foo is not enough to make a proper PR)

// Also I'm not sure about a way to don't brake it's work in out-of-nextcloud installation

msva commented 1 year ago

btw, for anyone who will look here in case this won't be fixed in the future, I've modified nginx-side workaround to:

location = /apps/snappymail/ {
  if ($is_args) {
    rewrite ^ /index.php$uri?$args;
  }
}

for now, so, it allows to have app url without index.php

the-djmaze commented 1 year ago

Great finding. Now are getting somewhere.

I don't have nginx so i can't test, but the problem is in there. I think the ?query part breaks the rules and nginx doesn't fallback to the root index.php

I shall also search online for options to solve this.

the-djmaze commented 1 year ago

Looking online, maybe something like:

location / {
        try_files $uri $uri/ /index.php;
    }

Atleast most examples use something with try_files

msva commented 1 year ago

Well, there is similar rule already (but with /index.php$request_uri) anyway and it doesn't work :shrug:

Another interesting part is that $request_uri supposed to be exactly $uri$is_args$args (where $is_args is ? if $args not empty), and still somewhy it doesn't work in rewrite rule in workaround I posted above.

But anyway, just having such try_files in location / {} wouldn't help, as request goes to /apps/snapymail/, which exists as directory ("file" in meaning of try_files).

So, by try_files request goes to index file of that directory (and as there is no index.php neither others index specified, nginx fires 404.

And I can't see any way to handle such situation except either

#

[1]

$ grep -lr '\./[?]/' apps/snappymail/app --exclude '*.min.js'
apps/snappymail/app/snappymail/v/2.22.4/app/templates/Index.html
apps/snappymail/app/snappymail/v/2.22.4/app/libraries/snappymail/http/csp.php
apps/snappymail/app/snappymail/v/2.22.4/app/libraries/RainLoop/Actions/Themes.php
apps/snappymail/app/snappymail/v/2.22.4/app/libraries/RainLoop/Actions.php
apps/snappymail/app/snappymail/v/2.22.4/static/js/boot.js
the-djmaze commented 1 year ago

Please test with v2.25.4