mirror of
https://github.com/immich-app/immich
synced 2025-10-17 18:19:27 +00:00
chore(mobile): refactor authentication (#14322)
This commit is contained in:
parent
5417e34fb6
commit
21f14be949
26 changed files with 619 additions and 354 deletions
|
|
@ -11,9 +11,7 @@ import 'package:immich_mobile/providers/oauth.provider.dart';
|
|||
import 'package:immich_mobile/providers/gallery_permission.provider.dart';
|
||||
import 'package:immich_mobile/routing/router.dart';
|
||||
import 'package:immich_mobile/entities/store.entity.dart';
|
||||
import 'package:immich_mobile/providers/api.provider.dart';
|
||||
import 'package:immich_mobile/providers/asset.provider.dart';
|
||||
import 'package:immich_mobile/providers/authentication.provider.dart';
|
||||
import 'package:immich_mobile/providers/auth.provider.dart';
|
||||
import 'package:immich_mobile/providers/backup/backup.provider.dart';
|
||||
import 'package:immich_mobile/providers/server_info.provider.dart';
|
||||
import 'package:immich_mobile/utils/provider_utils.dart';
|
||||
|
|
@ -40,13 +38,12 @@ class LoginForm extends HookConsumerWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final usernameController =
|
||||
final emailController =
|
||||
useTextEditingController.fromValue(TextEditingValue.empty);
|
||||
final passwordController =
|
||||
useTextEditingController.fromValue(TextEditingValue.empty);
|
||||
final serverEndpointController =
|
||||
useTextEditingController.fromValue(TextEditingValue.empty);
|
||||
final apiService = ref.watch(apiServiceProvider);
|
||||
final emailFocusNode = useFocusNode();
|
||||
final passwordFocusNode = useFocusNode();
|
||||
final serverEndpointFocusNode = useFocusNode();
|
||||
|
|
@ -85,7 +82,7 @@ class LoginForm extends HookConsumerWidget {
|
|||
|
||||
/// Fetch the server login credential and enables oAuth login if necessary
|
||||
/// Returns true if successful, false otherwise
|
||||
Future<bool> getServerLoginCredential() async {
|
||||
Future<void> getServerAuthSettings() async {
|
||||
final serverUrl = sanitizeUrl(serverEndpointController.text);
|
||||
|
||||
// Guard empty URL
|
||||
|
|
@ -95,13 +92,12 @@ class LoginForm extends HookConsumerWidget {
|
|||
msg: "login_form_server_empty".tr(),
|
||||
toastType: ToastType.error,
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
isLoadingServer.value = true;
|
||||
final endpoint = await apiService.resolveAndSetEndpoint(serverUrl);
|
||||
final endpoint =
|
||||
await ref.read(authProvider.notifier).validateServerUrl(serverUrl);
|
||||
|
||||
// Fetch and load server config and features
|
||||
await ref.read(serverInfoProvider.notifier).getServerInfo();
|
||||
|
|
@ -127,7 +123,6 @@ class LoginForm extends HookConsumerWidget {
|
|||
isOauthEnable.value = false;
|
||||
isPasswordLoginEnable.value = true;
|
||||
isLoadingServer.value = false;
|
||||
return false;
|
||||
} on HandshakeException {
|
||||
ImmichToast.show(
|
||||
context: context,
|
||||
|
|
@ -138,7 +133,6 @@ class LoginForm extends HookConsumerWidget {
|
|||
isOauthEnable.value = false;
|
||||
isPasswordLoginEnable.value = true;
|
||||
isLoadingServer.value = false;
|
||||
return false;
|
||||
} catch (e) {
|
||||
ImmichToast.show(
|
||||
context: context,
|
||||
|
|
@ -149,11 +143,9 @@ class LoginForm extends HookConsumerWidget {
|
|||
isOauthEnable.value = false;
|
||||
isPasswordLoginEnable.value = true;
|
||||
isLoadingServer.value = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
isLoadingServer.value = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
useEffect(
|
||||
|
|
@ -168,67 +160,50 @@ class LoginForm extends HookConsumerWidget {
|
|||
);
|
||||
|
||||
populateTestLoginInfo() {
|
||||
usernameController.text = 'demo@immich.app';
|
||||
emailController.text = 'demo@immich.app';
|
||||
passwordController.text = 'demo';
|
||||
serverEndpointController.text = 'https://demo.immich.app';
|
||||
}
|
||||
|
||||
populateTestLoginInfo1() {
|
||||
usernameController.text = 'testuser@email.com';
|
||||
emailController.text = 'testuser@email.com';
|
||||
passwordController.text = 'password';
|
||||
serverEndpointController.text = 'http://10.1.15.216:2283/api';
|
||||
serverEndpointController.text = 'http://10.1.15.216:3000/api';
|
||||
}
|
||||
|
||||
login() async {
|
||||
TextInput.finishAutofillContext();
|
||||
// Start loading
|
||||
isLoading.value = true;
|
||||
|
||||
// This will remove current cache asset state of previous user login.
|
||||
ref.read(assetProvider.notifier).clearAllAsset();
|
||||
isLoading.value = true;
|
||||
|
||||
// Invalidate all api repository provider instance to take into account new access token
|
||||
invalidateAllApiRepositoryProviders(ref);
|
||||
|
||||
try {
|
||||
final isAuthenticated =
|
||||
await ref.read(authenticationProvider.notifier).login(
|
||||
usernameController.text,
|
||||
passwordController.text,
|
||||
sanitizeUrl(serverEndpointController.text),
|
||||
);
|
||||
if (isAuthenticated) {
|
||||
// Resume backup (if enable) then navigate
|
||||
if (ref.read(authenticationProvider).shouldChangePassword &&
|
||||
!ref.read(authenticationProvider).isAdmin) {
|
||||
context.pushRoute(const ChangePasswordRoute());
|
||||
} else {
|
||||
final hasPermission = await ref
|
||||
.read(galleryPermissionNotifier.notifier)
|
||||
.hasPermission;
|
||||
if (hasPermission) {
|
||||
// Don't resume the backup until we have gallery permission
|
||||
ref.read(backupProvider.notifier).resumeBackup();
|
||||
}
|
||||
context.replaceRoute(const TabControllerRoute());
|
||||
}
|
||||
final result = await ref.read(authProvider.notifier).login(
|
||||
emailController.text,
|
||||
passwordController.text,
|
||||
);
|
||||
|
||||
if (result.shouldChangePassword && !result.isAdmin) {
|
||||
context.pushRoute(const ChangePasswordRoute());
|
||||
} else {
|
||||
ImmichToast.show(
|
||||
context: context,
|
||||
msg: "login_form_failed_login".tr(),
|
||||
toastType: ToastType.error,
|
||||
gravity: ToastGravity.TOP,
|
||||
);
|
||||
context.replaceRoute(const TabControllerRoute());
|
||||
}
|
||||
} catch (error) {
|
||||
ImmichToast.show(
|
||||
context: context,
|
||||
msg: "login_form_failed_login".tr(),
|
||||
toastType: ToastType.error,
|
||||
gravity: ToastGravity.TOP,
|
||||
);
|
||||
} finally {
|
||||
// Make sure we stop loading
|
||||
isLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
oAuthLogin() async {
|
||||
var oAuthService = ref.watch(oAuthServiceProvider);
|
||||
ref.watch(assetProvider.notifier).clearAllAsset();
|
||||
String? oAuthServerUrl;
|
||||
|
||||
try {
|
||||
|
|
@ -262,11 +237,8 @@ class LoginForm extends HookConsumerWidget {
|
|||
"Finished OAuth login with response: ${loginResponseDto.userEmail}",
|
||||
);
|
||||
|
||||
final isSuccess = await ref
|
||||
.watch(authenticationProvider.notifier)
|
||||
.setSuccessLoginInfo(
|
||||
final isSuccess = await ref.watch(authProvider.notifier).saveAuthInfo(
|
||||
accessToken: loginResponseDto.accessToken,
|
||||
serverUrl: sanitizeUrl(serverEndpointController.text),
|
||||
);
|
||||
|
||||
if (isSuccess) {
|
||||
|
|
@ -309,7 +281,7 @@ class LoginForm extends HookConsumerWidget {
|
|||
ServerEndpointInput(
|
||||
controller: serverEndpointController,
|
||||
focusNode: serverEndpointFocusNode,
|
||||
onSubmit: getServerLoginCredential,
|
||||
onSubmit: getServerAuthSettings,
|
||||
),
|
||||
const SizedBox(height: 18),
|
||||
Row(
|
||||
|
|
@ -344,7 +316,7 @@ class LoginForm extends HookConsumerWidget {
|
|||
),
|
||||
),
|
||||
onPressed:
|
||||
isLoadingServer.value ? null : getServerLoginCredential,
|
||||
isLoadingServer.value ? null : getServerAuthSettings,
|
||||
icon: const Icon(Icons.arrow_forward_rounded),
|
||||
label: const Text(
|
||||
'login_form_next_button',
|
||||
|
|
@ -402,7 +374,7 @@ class LoginForm extends HookConsumerWidget {
|
|||
if (isPasswordLoginEnable.value) ...[
|
||||
const SizedBox(height: 18),
|
||||
EmailInput(
|
||||
controller: usernameController,
|
||||
controller: emailController,
|
||||
focusNode: emailFocusNode,
|
||||
onSubmit: passwordFocusNode.requestFocus,
|
||||
),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue