Skip to content

Commit

Permalink
add root resource path '/' and missing trailing slash to custom schem…
Browse files Browse the repository at this point in the history
…e separator for mobile oauth
  • Loading branch information
qrkourier committed Jul 4, 2024
1 parent 10ea894 commit d91af9b
Show file tree
Hide file tree
Showing 40 changed files with 429 additions and 738 deletions.
12 changes: 6 additions & 6 deletions docs/docs/administration/oauth.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
This page contains details about using OAuth in Immich.

:::tip
Unable to set `app.immich:/` as a valid redirect URI? See [Mobile Redirect URI](#mobile-redirect-uri) for an alternative solution.
Unable to set `app.immich:///` as a valid redirect URI? See [Mobile Redirect URI](#mobile-redirect-uri) for an alternative solution.
:::

## Overview
Expand All @@ -30,15 +30,15 @@ Before enabling OAuth in Immich, a new client application needs to be configured

The **Sign-in redirect URIs** should include:

- `app.immich:/` - for logging in with OAuth from the [Mobile App](/docs/features/mobile-app.mdx)
- `app.immich:///` - for logging in with OAuth from the [Mobile App](/docs/features/mobile-app.mdx)
- `http://DOMAIN:PORT/auth/login` - for logging in with OAuth from the Web Client
- `http://DOMAIN:PORT/user-settings` - for manually linking OAuth in the Web Client

Redirect URIs should contain all the domains you will be using to access Immich. Some examples include:

Mobile

- `app.immich:/` (You **MUST** include this for iOS and Android mobile apps to work properly)
- `app.immich:///` (You **MUST** include this for iOS and Android mobile apps to work properly)

Localhost

Expand Down Expand Up @@ -96,16 +96,16 @@ When Auto Launch is enabled, the login page will automatically redirect the user

## Mobile Redirect URI

The redirect URI for the mobile app is `app.immich:/`, which is a [Custom Scheme](https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app). If this custom scheme is an invalid redirect URI for your OAuth Provider, you can work around this by doing the following:
The redirect URI for the mobile app is `app.immich:///`, which is a [Custom Scheme](https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app). If this custom scheme is an invalid redirect URI for your OAuth Provider, you can work around this by doing the following:

1. Configure an http(s) endpoint to forwards requests to `app.immich:/`
1. Configure an http(s) endpoint to forwards requests to `app.immich:///`
2. Whitelist the new endpoint as a valid redirect URI with your provider.
3. Specify the new endpoint as the `Mobile Redirect URI Override`, in the OAuth settings.

With these steps in place, you should be able to use OAuth from the [Mobile App](/docs/features/mobile-app.mdx) without a custom scheme redirect URI.

:::info
Immich has a route (`/api/oauth/mobile-redirect`) that is already configured to forward requests to `app.immich:/`, and can be used for step 1.
Immich has a route (`/api/oauth/mobile-redirect`) that is already configured to forward requests to `app.immich:///`, and can be used for step 1.
:::

## Example Configuration
Expand Down
2 changes: 1 addition & 1 deletion mobile/lib/services/oauth.service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class OAuthService {
await _apiService.resolveAndSetEndpoint(serverUrl);

final dto = await _apiService.oAuthApi.startOAuth(
OAuthConfigDto(redirectUri: '$callbackUrlScheme:/'),
OAuthConfigDto(redirectUri: '$callbackUrlScheme:///'),
);
return dto?.url;
}
Expand Down
2 changes: 1 addition & 1 deletion server/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export const geodataAdmin1Path = join(GEODATA_ROOT_PATH, 'admin1CodesASCII.txt')
export const geodataAdmin2Path = join(GEODATA_ROOT_PATH, 'admin2Codes.txt');
export const geodataCities500Path = join(GEODATA_ROOT_PATH, citiesFile);

export const MOBILE_REDIRECT = 'app.immich:/';
export const MOBILE_REDIRECT = 'app.immich:///';
export const LOGIN_URL = '/auth/login?autoLaunch=0';

export enum AuthType {
Expand Down
6 changes: 3 additions & 3 deletions server/src/services/auth.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -353,11 +353,11 @@ describe('AuthService', () => {

describe('getMobileRedirect', () => {
it('should pass along the query params', () => {
expect(sut.getMobileRedirect('http://immich.app?code=123&state=456')).toEqual('app.immich:/?code=123&state=456');
expect(sut.getMobileRedirect('http://immich.app?code=123&state=456')).toEqual('app.immich:///?code=123&state=456');
});

it('should work if called without query params', () => {
expect(sut.getMobileRedirect('http://immich.app')).toEqual('app.immich:/?');
expect(sut.getMobileRedirect('http://immich.app')).toEqual('app.immich:///?');
});
});

Expand Down Expand Up @@ -423,7 +423,7 @@ describe('AuthService', () => {
userMock.getByOAuthId.mockResolvedValue(userStub.user1);
sessionMock.create.mockResolvedValue(sessionStub.valid);

await sut.callback({ url: `app.immich:/?code=abc123` }, loginDetails);
await sut.callback({ url: `app.immich:///?code=abc123` }, loginDetails);

expect(callbackMock).toHaveBeenCalledWith('http://mobile-redirect', { state: 'state' }, { state: 'state' });
});
Expand Down
121 changes: 42 additions & 79 deletions web/src/lib/i18n/ar.json
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@
"oauth_issuer_url": "عنوان URL الخاص بجهة الإصدار",
"oauth_mobile_redirect_uri": "عنوان URI لإعادة التوجيه على الهاتف",
"oauth_mobile_redirect_uri_override": "تجاوز عنوان URI لإعادة التوجيه على الهاتف",
"oauth_mobile_redirect_uri_override_description": "قم بتفعيله عندما يكون 'app.immich:/' هو عنوان URI لإعادة التوجيه غير الصالح.",
"oauth_mobile_redirect_uri_override_description": "قم بتفعيله عندما يكون 'app.immich:///' هو عنوان URI لإعادة التوجيه غير الصالح.",
"oauth_scope": "النطاق",
"oauth_settings": "OAuth",
"oauth_settings_description": "إدارة إعدادات تسجيل الدخول OAuth",
Expand Down Expand Up @@ -326,7 +326,7 @@
"advanced": "متقدم",
"age_months": "عمر {months, plural, one {# شهر} other {# أشهر}}",
"age_year_months": "عمر سنة واحدة، {months, plural, one {# شهر} other {# أشهر}}",
"age_years": "{years, plural, other {العمر #}}",
"age_years": "{سنوات , plural, other {العمر #}}",
"album_added": "تمت إضافة الألبوم",
"album_added_notification_setting_description": "تلقي إشعارًا بالبريد الإلكتروني عند إضافتك إلى ألبوم مشترك",
"album_cover_updated": "تم تحديث غلاف الألبوم",
Expand Down Expand Up @@ -386,31 +386,17 @@
"assets_count": "{count, plural, one {# أصل} other {# أصول}}",
"assets_moved_to_trash_count": "تم نقل {count, plural, one {# أصل} other {# أصول}} إلى سلة المهملات",
"assets_permanently_deleted_count": "تم حذف {count, plural, one {# أصل} other {# أصول}} بشكل دائم",
"assets_removed_count": "تمت إزالة {count, plural, one {# أصل} other {# أصول}}",
"assets_restore_confirmation": "هل أنت متأكد أنك تريد استعادة كافة الأصول المحذوفة؟ لا يمكنك التراجع عن هذا الإجراء!",
"assets_restored_count": "تمت استعادة {count, plural, one {# أصل} other {# أصول}}",
"assets_trashed_count": "تم إرسال {count, plural, one {# أصل} other {# أصول}} إلى سلة المهملات",
"assets_were_part_of_album_count": "{count, plural, one {الأصل كان} other {الأصول كانت}} جزءًا من الألبوم بالفعل",
"authorized_devices": "الأجهزه المخولة",
"back": "خلف",
"back_close_deselect": "الرجوع أو الإغلاق أو إلغاء التحديد",
"backward": "الى الوراء",
"birthdate_saved": "تم حفظ تاريخ الميلاد بنجاح",
"birthdate_set_description": "يتم استخدام تاريخ الميلاد لحساب عمر هذا الشخص وقت التقاط الصورة.",
"backward": "",
"blurred_background": "خلفية مشوشة",
"build": "يبني",
"build_image": "بناء الصورة",
"bulk_delete_duplicates_confirmation": "هل أنت متأكد من أنك تريد حذف {count, plural, one {# أصل مكرر} other {# أصول مكررة}} بالجملة؟ سيحتفظ هذا بأكبر أصل من كل مجموعة ويحذف جميع النسخ المكررة الأخرى بشكل دائم. لا يمكنك التراجع عن هذا الإجراء!",
"bulk_keep_duplicates_confirmation": "هل أنت متأكد من أنك تريد الاحتفاظ بـ {count, plural, one {# أصل مكرر} other {# أصول مكررة}}؟ سيؤدي هذا إلى حل جميع مجموعات النسخ المكررة دون حذف أي شيء.",
"bulk_trash_duplicates_confirmation": "هل أنت متأكد من أنك تريد إرسال {count, plural, one {# أصل مكرر} other {# أصول مكررة}} إلى سلة المهملات بالجملة؟ سيحتفظ هذا بأكبر أصل من كل مجموعة ويرسل جميع النسخ المكررة الأخرى إلى سلة المهملات.",
"camera": "الكاميرا",
"camera": "",
"camera_brand": "علامة الكاميرا التجارية",
"camera_model": "طراز الكاميرا",
"cancel": "يلغي",
"cancel_search": "الغي البحث",
"cannot_merge_people": "لا يمكن دمج الأشخاص",
"cannot_undo_this_action": "لا يمكنك التراجع عن هذا الإجراء!",
"cannot_update_the_description": "لا يمكن تحديث الوصف",
"cannot_merge_people": "",
"cannot_update_the_description": "",
"cant_apply_changes": "",
"cant_get_faces": "",
"cant_search_people": "",
Expand All @@ -419,116 +405,93 @@
"change_expiration_time": "تغيير وقت انتهاء الصلاحية",
"change_location": "غيّر الموقع",
"change_name": "غيّر الأسم",
"change_name_successfully": "تم تغيير الاسم بنجاح",
"change_password": "تغيير كلمة المرور",
"change_password_description": "هذه إما هي المرة الأولى التي تقوم فيها بتسجيل الدخول إلى النظام أو أنه تم تقديم طلب لتغيير كلمة المرور الخاصة بك. الرجاء إدخال كلمة المرور الجديدة أدناه.",
"change_your_password": "غير كلمة المرور الخاصة بك",
"changed_visibility_successfully": "تم تغيير الرؤية بنجاح",
"check_all": "تحقق من الكل",
"check_logs": "تحقق من السجلات",
"choose_matching_people_to_merge": "اختر الأشخاص المتطابقين لدمجهم",
"change_name_successfully": "",
"change_password": "تغيير كلمة المرورغيّر كلمة المرور",
"change_your_password": "",
"changed_visibility_successfully": "",
"check_logs": "",
"city": "مدينة",
"clear": "مسح",
"clear_all": "مسح الكل",
"clear_message": "مسح الرسالة",
"clear_value": "مسح القيمة",
"close": "إغلاق",
"collapse": "طي",
"close": "",
"collapse_all": "طيّ الكل",
"color_theme": "نمط الألوان",
"comment_deleted": "تم حذف التعليق",
"comment_options": "خيارات التعليق",
"comments_and_likes": "التعليقات والإعجابات",
"comments_are_disabled": "التعليقات معطلة",
"comments_are_disabled": "",
"confirm": "تأكيد",
"confirm_admin_password": "تأكيد كلمة مرور المسؤول",
"confirm_delete_shared_link": "هل أنت متأكد أنك تريد حذف هذا الرابط المشترك؟",
"confirm_admin_password": "",
"confirm_password": "تأكيد كلمة المرور",
"contain": "محتواة",
"context": "السياق",
"continue": "متابعة",
"copied_image_to_clipboard": "تم نسخ الصورة إلى الحافظة.",
"copied_to_clipboard": "نسخ إلى الحافظة!",
"contain": "",
"context": "",
"continue": "",
"copied_image_to_clipboard": "",
"copy_error": "نسخ الخطأ",
"copy_file_path": "نسخ مسار الملف",
"copy_file_path": "",
"copy_image": "نسخ الصورة",
"copy_link": "نسخ الرابط",
"copy_link_to_clipboard": "انسخ الرابط إلى الحافظة",
"copy_link_to_clipboard": "",
"copy_password": "نسخ كلمة المرور",
"copy_to_clipboard": "نسخ إلى الحافظة",
"copy_to_clipboard": "",
"country": "دولة",
"cover": "تغطي",
"covers": "أغلفة",
"cover": "",
"covers": "",
"create": "انشاء",
"create_album": "إنشاء ألبوم",
"create_library": "إنشاء مكتبة",
"create_link": "إنشاء رابط",
"create_link_to_share": "إنشاء رابط للمشاركة",
"create_link_to_share_description": "السماح لأي شخص لديه الرابط بمشاهدة الصورة (الصور) المحددة",
"create_new_person": "إنشاء شخص جديد",
"create_new_person_hint": "تعيين الأصول المحددة لشخص جديد",
"create_new_user": "إنشاء مستخدم جديد",
"create_new_person": "",
"create_new_user": "",
"create_user": "إنشاء مستخدم",
"created": "تم الإنشاء",
"created": "",
"current_device": "الجهاز الحالي",
"custom_locale": "لغة مخصصة",
"custom_locale_description": "تنسيق التواريخ والأرقام بناءً على اللغة والمنطقة",
"dark": "معتم",
"custom_locale": "",
"custom_locale_description": "",
"dark": "",
"date_after": "التارخ بعد",
"date_and_time": "التاريخ و الوقت",
"date_before": "التاريخ قبل",
"date_of_birth_saved": "تم حفظ تاريخ الميلاد بنجاح",
"date_range": "نطاق الموعد",
"day": "يوم",
"deduplicate_all": "إلغاء تكرار الكل",
"default_locale": "اللغة الافتراضية",
"default_locale_description": "تنسيق التواريخ والأرقام بناءً على لغة المتصفح الخاص بك",
"day": "",
"default_locale": "",
"default_locale_description": "",
"delete": "يمسح",
"delete_album": "حذف الألبوم",
"delete_api_key_prompt": "هل أنت متأكد أنك تريد حذف مفتاح API هذا؟",
"delete_duplicates_confirmation": "هل أنت متأكد أنك تريد حذف هذه التكرارات نهائيًا؟",
"delete_key": "حذف المفتاح",
"delete_library": "حذف المكتبة",
"delete_link": "حذف الرابط",
"delete_shared_link": "حذف الرابط المشترك",
"delete_user": "حذف المستخدم",
"deleted_shared_link": "تم حذف الرابط المشارك",
"deleted_shared_link": "",
"description": "وصف",
"details": "تفاصيل",
"direction": "الإتجاه",
"disabled": "معطل",
"direction": "",
"disallow_edits": "منع التعديلات",
"discover": "يكتشف",
"dismiss_all_errors": "تجاهل كافة الأخطاء",
"discover": "",
"dismiss_all_errors": "",
"dismiss_error": "تجاهل الخطأ",
"display_options": "عرض الخيارات",
"display_order": "عرض الترتيب",
"display_original_photos": "عرض الصور الأصلية",
"display_original_photos_setting_description": "تفضل عرض الصورة الأصلية عند عرض أحد الأصول بدلاً من الصور المصغرة عندما يكون الأصل الأصلي متوافقًا مع الويب. قد يؤدي ذلك إلى بطء سرعات عرض الصور.",
"do_not_show_again": "لا تظهر هذه الرسالة مرة آخرى",
"display_original_photos": "",
"display_original_photos_setting_description": "",
"done": "منتهي",
"download": "تحميل",
"download_settings": "تنزيل",
"download_settings_description": "إدارة الإعدادات المتعلقة بتنزيل الأصول",
"downloading": "جارى التحميل",
"downloading_asset_filename": "تنزيل الأصل {filename}",
"drop_files_to_upload": "قم بإسقاط الملفات في أي مكان لرفعها",
"duplicates": "التكرارات",
"duplicates_description": "قم بحل كل مجموعة من خلال الإشارة إلى التكرارات، إن وجدت",
"duration": "المدة",
"downloading": "",
"duration": "",
"durations": {
"days": "",
"hours": "",
"minutes": "",
"months": "",
"years": ""
},
"edit": "تعديل",
"edit_album": "تعديل الألبوم",
"edit_avatar": "تعديل الصوره الشخصية",
"edit_date": "تعديل التاريخ",
"edit_date_and_time": "تحرير التاريخ والوقت",
"edit_exclusion_pattern": "تحرير نمط الاستبعاد",
"edit_date_and_time": "",
"edit_exclusion_pattern": "",
"edit_faces": "تعديل الوجوه",
"edit_import_path": "",
"edit_import_paths": "",
Expand Down
Loading

0 comments on commit d91af9b

Please sign in to comment.