immich icon indicating copy to clipboard operation
immich copied to clipboard

[Feature]: Automatically add /api when signing into Mobile App

Open mtthidoteu opened this issue 3 years ago • 2 comments

Feature detail

I find it a bit confusing to have to put https://immich.domain.com/api as the 'environment' and I think it would be easier to have it add it by itself. So 'Server URL' simply becomes https://immich.domain.com and the app calls /api.

It would be safer as well for everything after the / to be removed. So if people put a https://immich.domain.com/api. It would still work (and not do /api/api) because the backend would be removing the path of the URL.

Platform

Mobile App

mtthidoteu avatar Sep 07 '22 15:09 mtthidoteu

Good idea!

alextran1502 avatar Sep 07 '22 15:09 alextran1502

I was sleeping on this last night. This would create an issue for users with a different endpoint directly proxy to /api of the server; for example, you can create a domain immichapi.yourdomain.com to proxy directly to your localip:2283/api. By automatically append /api to immichapi.yourdomain.com I think it will break that proxy method

alextran1502 avatar Sep 08 '22 12:09 alextran1502

We could have the app try both the base url and /api on login, and store what it actually connects with. The priority should be whatever the user enters, followed by trying /api

zackpollard avatar Sep 30 '22 23:09 zackpollard

How about a .well-known file on the webserver? Matrix does something similar for finding server back-end details for clients. https://spec.matrix.org/v1.5/client-server-api/#well-known-uri

/.well-known/immich/client

If the entered URL is the API, use that. Otherwise, look for the .well-known file, read the JSON, and use specified URL for the API.

Mortein avatar Dec 03 '22 04:12 Mortein

@Mortein That's a cool idea, which could make self-discovery a bit easier.

jrasm91 avatar Dec 14 '22 16:12 jrasm91

I also would really like it.

Since it is related: adding https:// if only the hostname is suggested would also greatly improve UX for entering the Server URL.

akoyaxd avatar Jan 06 '23 14:01 akoyaxd

I'm interested in taking a stab at implementing this.

I'm thinking an endpoint: /.well-known/immich with payload:

{
  "api": {
    "endpoint": "https://api.example.com/"
  }
}

Re: auto-adding https if missing. This is easy enough implement, but I wonder if it adds too many special cases? And the UI already informs the user that http/s is required, so the UX isn't terrible. Maybe I'll add it to start, and we can strip it back out if decided unnecessary.

conneryn avatar Jan 11 '23 23:01 conneryn

Will this just be a static file? How will it be hosted?

jrasm91 avatar Jan 11 '23 23:01 jrasm91

I think hosted as part of the web project makes the most sense, that way we can use an environment variable to control the value. If performance is a concern, sveltejs should be able to pre-render/cache the endpoint as a static (though, I'm a little new to svelte, so not 100% sure what the right incantations are, yet, but I'm pretty sure it's possible 😅).

I should have an initial PR for this shortly, to show what I'm thinking.

conneryn avatar Jan 12 '23 01:01 conneryn

Sounds good to me. I was wondering if you couldn't get the hostname from the request and return a dynamic response. An env variable sounds good though.

jrasm91 avatar Jan 12 '23 01:01 jrasm91

Re: auto-adding https if missing. This is easy enough implement, but I wonder if it adds too many special cases? And the UI already informs the user that http/s is required, so the UX isn't terrible. Maybe I'll add it to start, and we can strip it back out if decided unnecessary.

The full URL (including the protocol and port if non-standard) in the .well-known file would be best (so "endpoint": "https://immich15.example.com:4443/api"), as it would allow discovery by anything, not just the mobile app (things like backup systems, other Immich servers, upload tools, or other crazy things not yet thought of).

Ideally, the user should need to enter only enough for the mobile app to identify the actual API endpoint URL. Assume HTTPS if the user doesn't include a protocol.

Entering:

  • immich15.example.com would try https://immich15.example.com/.well-known/immich and find nothing, as the API is on a non-standard HTTPS port
  • http://immich15.example.com would try http://immich15.example.com/.well-known/immich and find nothing, as the API is not running on HTTP port 80
  • immich15.example.com:4443 would try https://immich15.example.com:4443/.well-known/immich and find some JSON which includes the api.endpoint
  • https://immich15.example.com:4443/api would not look for /.well-known/immich as there's already a path. Instead it would directly find the API
    • immich15.example.com:4443/api would also work, as it would try https://immich15.example.com:4443/api

There will be a disconnect between the entered URL and the API endpoint URL, but that's okay, as the API could be on a completely different domain (maybe you enter immich.example.com and api.endpoint sends you to https://immich22.example.net:14333/cats/api). It makes more sense for the user to enter the friendly URL.

Mortein avatar Jan 12 '23 02:01 Mortein

Thanks @Mortein, the clear examples of each scenario is very helpful. I've update my PR to include the logic as described (See here).

However, I do wonder about the last example, where a path exists. Even if a path exists in the input, I could see an argument to still first check for a .well-known. I'm imagining a case where a deployment have the public immich web available at: https://example.com/immich, and an end-user could (understandably) enter that as the URL when signing in, but we would still want to resolve a proper API endpoint. Thoughts?

conneryn avatar Jan 12 '23 21:01 conneryn

Thanks @Mortein, the clear examples of each scenario is very helpful. I've update my PR to include the logic as described (See here).

However, I do wonder about the last example, where a path exists. Even if a path exists in the input, I could see an argument to still first check for a .well-known. I'm imagining a case where a deployment have the public immich web available at: https://example.com/immich, and an end-user could (understandably) enter that as the URL when signing in, but we would still want to resolve a proper API endpoint. Thoughts?

From historical information, if the user use /immich or equivalent configuration for proxy, it wouldn't work

alextran1502 avatar Jan 12 '23 22:01 alextran1502

(#516)

jrasm91 avatar Jan 12 '23 22:01 jrasm91

I think you're right @conneryn. Even though there can only be a single instance on a specific hostname for now (until #516), that doesn't mean it couldn't just check for .well-known anyway, even if there is a path...

So (continuing the immich15.example.com host from earlier), entering:

  • https://immich15.example.com:4443/BobsPhotos would look for https://immich15.example.com:4443/BobsPhotos/.well-known/immich and either find some JSON which includes the correct api.endpoint, or use the given URL as the API URL

Mortein avatar Jan 13 '23 00:01 Mortein

I'll just add add that this is how openid discovery works as well, so it would make it consistent to support prefixes.

jrasm91 avatar Jan 13 '23 01:01 jrasm91