hoarder-app / hoarder

A self-hostable bookmark-everything app (links, notes and images) with AI-based automatic tagging and full text search
https://hoarder.app
GNU Affero General Public License v3.0
6.4k stars 231 forks source link

Better handling env NEXTAUTH_URL #407

Open ElTopo opened 2 months ago

ElTopo commented 2 months ago

There is an env var in .env file: NEXTAUTH_URL

By default, it's "http://localhost:3000", and the admin is supposed to change it to "https://myhoarder.myname.com".

This is not very friendly to reverse proxies. The app (Hoarder-app) itself should not know or care about by which host or port the clients are accessing its data. If the Hoard-app server has several domain names, the env NEXTAUTH_URL might direct the clients to the wrong sign in page URL when they log out.

For example, if my hoarder server has 2 URLs: https://hd.myname1.com https://hd.myname2.org There would be always chances for a user to log out their account and found they were at the wrong server sign in page.

The thing is, the hoard-app itself should remain "nameless" (without knowing the domain name of its server, its TLS certificate, the accessed port, etc.) All it knows is some client is accessing its data via HTTP protocol. If the hoard-app stays this way, it's much easier for admin to deploy the server (changing domain name, certificates, etc.) Nowadays some reverse proxy servers just automatically deploy apps, it's hard for them to change .env file individually.

How about hoard server does NOT use the env var NEXTAUTH_URL, and always uses whatever the current server?

e.g., logging out from https://hd.myname1.com, go to https://hd.myname1.com/signin; logging out from https://hd.myname2.org, go to https://hd.myname2.org/signin.

I guess a simple "/signin" should do the job correctly.

kamtschatka commented 2 months ago

From what I can tell, this is not really up to us to implement, as this is a nextauth specific thing. From what Copilot said, you can keep it empty and then everything will be relative to the URL, but OAuth will not work. I am not sure if Copilot is correct, but you could try it. Other than that, I don't see any way how hoarder could fix this

ElTopo commented 2 months ago

Well I did try to leave it empty (NEXTAUTH_URL=""), when the user logged out at https://myhd.myname.com, the server returned to http://localhost:3000, which of course is not accessible.

kamtschatka commented 1 month ago

So I was able to improve the situation for local logins, but this WILL NOT work for OAUTH. It requires some cookies to be set and you need the NEXTAUTH_URL to be configured to redirect back to your instance after you authenticated at the 3rd party provider. I personally do not like this solution, but it works. Ultimately it is up to @MohamedBassem to decide if we want to merge this or if we close this issue as not supported (or if there is even another solution, but information on this is pretty scarce)

ElTopo commented 1 month ago

@kamtschatka sounds good to me, thanks.

I was not aware that this was for OAUTH, might be better to have another option for OAUTH: if OAUTH is enabled, require NEXTAUTH_URL as the real auth site; if OAUTH is disabled, then NEXTAUTH_URL could be empty, in that case, just go back to /signin.

BertanAygun commented 1 month ago

I am running in to this issue as well. I need NEXTAUTH_URL to be set to a full DNS name for enabling OAUTH, which is a reverse proxied address to a local IP address hosting the docker container.

While this works for access, the web server fails to get auth provider list so defaults to credentials:

[next-auth][error][CLIENT_FETCH_ERROR] 

https://next-auth.js.org/errors#client_fetch_error fetch failed {

  error: {

    message: 'fetch failed',

    stack: 'TypeError: fetch failed\n' +

      '    at node:internal/deps/undici/undici:12500:13\n' +

      '    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)',

    name: 'TypeError'

  },

  url: 'https://hoarder.<domain>.net/api/auth/providers',

  message: 'fetch failed'

}
kamtschatka commented 1 month ago

doesn't sound like you have the same issue at all. The "fetch failed" sounds like either the URL is not reachable or maybe the other very common issue we see: You are using a self signed certificate that is not trusted?

BertanAygun commented 1 month ago

The certificate is valid and I can browse to https://hoarder.domain.net/api/auth/providers inside my network which also shows the valid certificate (it is a LetsEncrypt one) . It is a HSTS reverse proxy mapped to local IP address of the docker server though so I am guessing that's the problem.

BertanAygun commented 1 month ago

@kamtschatka I debugged this further, the container is missing the new intermediate certificates for Lets Encrypt. In my case it was R10, it has the ISGR X1 root but not R10, R5 etc. So it is not trusting the new Lets Encrypt certificates even though they work perfectly fine in browsers. If I download R10 cert from Lets Encrypt and pass it to curl on the container console, it will succeed. Otherwise it fails with certificate error.

Not sure if this is something I can fix in the docker compose but maybe the base image needs an update? From what I understand this hierarchy from Lets Encrypt is fairly recent (May 2024)

(Tracking this on #467 now as a new issue)