Open Pheggas opened 1 year ago
I may have stumbled upon a fix for Android.
I stumbled upon it because I'm using Auth0 who do not accept custom schemes with the precise shape used by Immich in their input validation for callbacks, i.e. app.immich:/
is invalid, so it's impossible to configure Immich to so that the mobile app initiates the flow with a valid callback.
I discovered that by adding two forward slashes to the requested callback (it can be modified because it's not part of the signed payload) then two necessary things happen: the IdP accepts the callback (as long as app.immich:///
is authorized in the app settings), and app.immich:///
correctly redirects to the mobile app to conclude the interactive client flow.
In summary, if there were a toggle in Immich admin to configure the mobile client to request a callback on app.immich:///
then it's only necessary for the IdP to allow that URL, or a redirector that responds with HTTP header location: app.immich:///
.
I partially worked around the Auth0 limitation on iOS in the same way. I captured the initiating auth request URL with the requested callback and modified it to match the one that's allowed by Auth0, app.immich:///
.
The flow succeeds until the redirect is finally called and app.immich:///
doesn't resolve to an app launcher registration in iOS, so presumably Immich is hard-coded to suit iOS devices that expect a custom scheme with only one forward slash like app.immich:/
.
If I change Immich to use a mobile URI override that responds with location: app.immich:/
then the iOS app is launched but the concluding step of the client flow is lost somehow, and so the iOS app only displays the login form as was originally reported here for the Android devices.
It seems the problem is universal to mobile-initiated OAuth, and possibly limited to cases where the mobile URI override is necessary.
That scheme has always looked weird to me. Is it normal? Should it really have two forward slashes instead?
app.immich:/
is not a complete URI scheme. It's missing a trailing slash. The meaning of location: app.immich:///
should be interpreted as "the root resource for app.immich" e.g., file:///
means /
in the filesystem.
There's probably some historical reason why app.immich:/
is too painful to change without protest, so the only paths forward I see are redress the mobile callback so that it's compatible with both iOS and Android or branch the logic to handle each separately.
Honestly, I'd be fine changing it from app.immich:/
to app.immich://
as long as that is more correct, standard, and is proven to be the fix for this issue.
Cool. I'm testing the change for Android. Can someone tell me how or help with testing in iOS? I have an old iPhone SE.
Damn. I can't believe this is actually getting resolved (hopefully). Fingers crossed!
Does anyone have a Flutter env set up on macOS? I'm guessing that we've built and tested manually for iOS because the mobile build workflow targets only Android.
It would be good to have a few more Android testers at least, too. @Pheggas will you loan one of your Android devices to this cause by installing the test build (link may require GitHub login)?
To test, uninstall the Immich app and unzip the download. If you can't find a way to do it on mobile then attach Android device with USB and enable developer option USB debugging so you can run adb install app-release.apk
on the laptop to install Immich test build on the Android device.
@Pheggas will you loan one of your Android devices to this cause by installing the test build (link may require GitHub login)?
Sure. I already did and it does exactly the same thing it did before. Is there something i should alter in the setup in order to have correct setup?
For your information, i have configured Google OAuth for mobile using this method. And as it points to app.immich:/
, which is not the correct format (according to this conversation), it probably shouldn't work by now (?)
To confirm, you installed the experimental "release" APK from this branch that changes the requested callback to app.immich:///
. Your Google OAuth client is configured to allow callback URI app.immich:///
in the web application credential settings in "Authorized redirect URIs."
With this configuration, you still experience the following symptom after successfully authenticating with Google on an Android tablet device: there are no errors, and the experimental build of the Immich app is launched, but not logged in. Instead, the login screen or server URL form are displayed, as if the token was not successfully passed to the app.
The Immich app has a "logs" link at the bottom of the UI. Will you see if there are any clues there about why the final oauth step failed?
Your Google OAuth client is configured to allow callback URI
app.immich:///
in the web application credential settings in "Authorized redirect URIs."
Sorry for late reply. I tried to add app.immich:///
to the authorized redirect URIs but it throws error:
That's why i didn't follow the default option with app.immich:/
. Could you provide me some workaroud how could i fix this issue? Related to #1174
Full list of URIs:
This tells me Google OAuth requires only standard, not custom, URI schemes, so it's necessary to utilize Immich's URI redirector feature with Google.
For example, configure Google OAuth with authorized redirect URI https://immich.example.eu/api/oauth/mobile-redirect
, and ensure Immich's URI redirector is set to app.immich:///
by installing the Immich server built from PR branch associated with this GitHub issue: https://github.com/qrkourier/immich/tree/mobile-oauth-scheme
As i don't want to mess up my existing setup, i'll spin up new instance with immich and reply you with results. This would take some time (days) so please, be patient. I'll let you know.
Wonderful. Thank you for the assist. I found that Immich's endpoint /api/oauth/mobile-redirect
is already enabled, so you can skip the step to configure a custom URI redirector. /api/oauth/mobile-redirect
for the experimental Immich server in this branch always redirects to app.immich:///
, so it works around the issue where some OAuth providers, like Google, do not permit custom schemes.
For example, configure Google OAuth with authorized redirect URI
https://immich.example.eu/api/oauth/mobile-redirect
, and ensure Immich's URI redirector is set toapp.immich:///
by installing the Immich server built from PR branch associated with this GitHub issue: https://github.com/qrkourier/immich/tree/mobile-oauth-scheme
Hello. I finally got into it. Could you please pack that specific build to docker image (and provide URL to download) so i can run it in docker environment as normal immich build? I think docker stack could stay unchanged for this test.
@Pheggas I've merged upstream and pushed to my PR source branch and pushed the image to Docker Hub.
.env
for compose project like this:
IMMICH_IMAGE="qrkourier/immich-server"
IMMICH_VERSION="mobile-oauth-scheme"
where compose.yml
is like this:
services:
immich-server:
image: ${IMMICH_IMAGE:-ghcr.io/immich-app/immich-server}:${IMMICH_VERSION:-release}
Well, after some troubleshooting with manifest unknown error in portainer, i finally got it working with following compose file:
name: immich
services:
immich-server:
container_name: immich_server_test
image: qrkourier/immich-server:${IMMICH_VERSION}
volumes:
- ${UPLOAD_LOCATION}:/usr/src/app/upload
- /etc/localtime:/etc/localtime:ro
env_file:
- stack.env
ports:
- 2284:3001
depends_on:
- redis
- database
restart: always
immich-machine-learning:
container_name: immich_machine_learning_test
image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION_VERSION:-release}
volumes:
- model-cache:/cache
env_file:
- stack.env
restart: always
redis:
container_name: immich_redis_test
image: docker.io/redis:6.2-alpine@sha256:328fe6a5822256d065debb36617a8169dbfbd77b797c525288e465f56c1d392b
healthcheck:
test: redis-cli ping || exit 1
restart: always
database:
container_name: immich_postgres_test
image: docker.io/tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:90724186f0a3517cf6914295b5ab410db9ce23190a2d9d0b9dd6463e3fa298f0
environment:
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_USER: ${DB_USERNAME}
POSTGRES_DB: ${DB_DATABASE_NAME}
POSTGRES_INITDB_ARGS: '--data-checksums'
volumes:
- ${DB_DATA_LOCATION}:/var/lib/postgresql/data
healthcheck:
test: pg_isready --dbname='${DB_DATABASE_NAME}' --username='${DB_USERNAME}' || exit 1; Chksum="$$(psql --dbname='${DB_DATABASE_NAME}' --username='${DB_USERNAME}' --tuples-only --no-align --command='SELECT COALESCE(SUM(checksum_failures), 0) FROM pg_stat_database')"; echo "checksum failure count is $$Chksum"; [ "$$Chksum" = '0' ] || exit 1
interval: 5m
start_interval: 30s
start_period: 5m
command: ["postgres", "-c" ,"shared_preload_libraries=vectors.so", "-c", 'search_path="$$user", public, vectors', "-c", "logging_collector=on", "-c", "max_wal_size=2GB", "-c", "shared_buffers=512MB", "-c", "wal_compression=on"]
restart: always
volumes:
model-cache:
I had to change port to expose and also container names as those ones with default name are already used. I also did some kung-fu with images to pull as you can see above. Just the server
one is pulled from your repo - others are from the same repos as specified in the official docker_compose
. If you ask what is that IMMICH_VERSION_VERSION
env variable, i had to change the default variable's name as the default one is used in the custom server image you provided. To understand it better, here's .env contents:
UPLOAD_LOCATION=/home/docker/docker_immich_test/library
DB_DATA_LOCATION=/home/docker/docker_immich_test/postgres
IMMICH_VERSION=mobile-oauth-scheme
DB_PASSWORD=postgres
DB_USERNAME=postgres
DB_DATABASE_NAME=immich
IMMICH_IMAGE=qrkourier/immich-server
IMMICH_VERSION_VERSION=release
I've also configured Google cloud console like following:
You don't need to pay attention to top 3 lines as those are for my actual official immich build. The 3 bottom lines are what i added. I hope it doesn't need to be in separated credentials section.
I also configured the OAuth section in Immich web ui so i can actually use the OAuth. Verified it works on Web UI. Then i installed the edited apk version of immich you provided to the tablet device, created account and wanted to try the login using oauth. Unfortunately, it did the same thing as before. Nothing really changed. For further questions, just ask.
PS: Adding the immich web ui configuration as well to have it here completed:
When you request the built-in redirector from the experimental Immich Server build, do you get the new location?
curl -sSD - 'https://immich.example.com/api/oauth/mobile-redirect' | grep -i ^location
Expected output:
location: app.immich:///?
Here's what @Pheggas wrote at the top of this issue:
Immich will show the initial screen with target server URL again without properly log me in
and
It only happens on tablet devices, not mobile-format one
I think you're getting the same symptom on Android tablets now. Maybe the issue with Android tablets is something else entirely. If so, truly sorry for hijacking this issue with what should probably be described like "Fix custom URL scheme for OAuth clients" (because some OAuth providers require the proper ://
separator).
Expected output:
location: app.immich:///?
Yes, i'm getting expected output as you mentioned.
If so, truly sorry for hijacking this issue
No problem. At least i had a hope 😁 The thing is it sometimes (JUST SOMETIMES) gets through and logs me in perfectly. The issue is it doesn't log in all the time. Most of the times it returns me to initial screen as described in original post.
The bug
According to our discussion, i'm opening this issue. I have 3 Android tablet devices at home from which none is able to login with OAuth. After i enter correct URL as target server and click
Login with OAuth
(and in case of having multiple google accounts log in, selecting correct google account), Chrome embeded browser will just close (as it should) and Immich will show the initial screen with target server URL again without properly log me in.It only happens on tablet devices, not mobile-format one. I've tested it on Android 13, 11 and 7.1.1. I've also did same test on emulated android tablet device and there it worked perfectly. In fact, i've been able to log in with Android 11 tablet device once after disabling
Blokada 5
(which is Ad-blocking app for android). Then i logged off and tried the same thing with having Blokada turned on. After this weird bug appearing again, i turned off the Blokada again and tried the login process. Yet the behavior didn't change unexpectedly.The OS that Immich Server is running on
Ubuntu Server 22.04 LTS
Version of Immich Server
v1.63.0 (first time spotted on v1.62.0)
Version of Immich Mobile App
1.63.0
Platform with the issue
Your docker-compose.yml content
Your .env content
Reproduction steps
Additional information
No response