👽 Update third party login
This commit is contained in:
@@ -120,7 +120,7 @@ class _CreateAccountEmailScreen extends HookConsumerWidget {
|
|||||||
return null;
|
return null;
|
||||||
}, [isBusy]);
|
}, [isBusy]);
|
||||||
|
|
||||||
void performNext() {
|
Future<void> performNext() async {
|
||||||
final email = emailController.text.trim();
|
final email = emailController.text.trim();
|
||||||
if (email.isEmpty) {
|
if (email.isEmpty) {
|
||||||
showErrorAlert('fieldCannotBeEmpty'.tr());
|
showErrorAlert('fieldCannotBeEmpty'.tr());
|
||||||
@@ -130,7 +130,18 @@ class _CreateAccountEmailScreen extends HookConsumerWidget {
|
|||||||
showErrorAlert('fieldEmailAddressMustBeValid'.tr());
|
showErrorAlert('fieldEmailAddressMustBeValid'.tr());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validate email availability with API
|
||||||
|
isBusy.value = true;
|
||||||
|
try {
|
||||||
|
final client = ref.watch(apiClientProvider);
|
||||||
|
await client.post('/pass/accounts/validate', data: {'email': email});
|
||||||
onNext();
|
onNext();
|
||||||
|
} catch (err) {
|
||||||
|
showErrorAlert(err);
|
||||||
|
} finally {
|
||||||
|
isBusy.value = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
@@ -343,14 +354,25 @@ class _CreateAccountProfileScreen extends HookConsumerWidget {
|
|||||||
return null;
|
return null;
|
||||||
}, [isBusy]);
|
}, [isBusy]);
|
||||||
|
|
||||||
void performNext() {
|
Future<void> performNext() async {
|
||||||
final username = usernameController.text.trim();
|
final username = usernameController.text.trim();
|
||||||
final nickname = nicknameController.text.trim();
|
final nickname = nicknameController.text.trim();
|
||||||
if (username.isEmpty || nickname.isEmpty) {
|
if (username.isEmpty || nickname.isEmpty) {
|
||||||
showErrorAlert('fieldCannotBeEmpty'.tr());
|
showErrorAlert('fieldCannotBeEmpty'.tr());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validate username availability with API
|
||||||
|
isBusy.value = true;
|
||||||
|
try {
|
||||||
|
final client = ref.watch(apiClientProvider);
|
||||||
|
await client.post('/pass/accounts/validate', data: {'name': username});
|
||||||
onNext();
|
onNext();
|
||||||
|
} catch (err) {
|
||||||
|
showErrorAlert(err);
|
||||||
|
} finally {
|
||||||
|
isBusy.value = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
|
|||||||
@@ -38,6 +38,20 @@ final Map<int, (String, String, IconData)> kFactorTypes = {
|
|||||||
4: ('authFactorPin', 'authFactorPinDescription', Symbols.nest_secure_alarm),
|
4: ('authFactorPin', 'authFactorPinDescription', Symbols.nest_secure_alarm),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Performs post-login tasks including fetching user info, subscribing to push
|
||||||
|
/// notifications, connecting websocket, and closing the login dialog.
|
||||||
|
Future<void> performPostLogin(BuildContext context, WidgetRef ref) async {
|
||||||
|
final userNotifier = ref.read(userInfoProvider.notifier);
|
||||||
|
await userNotifier.fetchUser();
|
||||||
|
final apiClient = ref.read(apiClientProvider);
|
||||||
|
subscribePushNotification(apiClient);
|
||||||
|
final wsNotifier = ref.read(websocketStateProvider.notifier);
|
||||||
|
wsNotifier.connect();
|
||||||
|
if (context.mounted && Navigator.canPop(context)) {
|
||||||
|
Navigator.pop(context, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class _LoginCheckScreen extends HookConsumerWidget {
|
class _LoginCheckScreen extends HookConsumerWidget {
|
||||||
final SnAuthChallenge? challenge;
|
final SnAuthChallenge? challenge;
|
||||||
final SnAuthFactor? factor;
|
final SnAuthFactor? factor;
|
||||||
@@ -80,14 +94,7 @@ class _LoginCheckScreen extends HookConsumerWidget {
|
|||||||
if (!context.mounted) return;
|
if (!context.mounted) return;
|
||||||
|
|
||||||
// Do post login tasks
|
// Do post login tasks
|
||||||
final userNotifier = ref.read(userInfoProvider.notifier);
|
await performPostLogin(context, ref);
|
||||||
userNotifier.fetchUser().then((_) {
|
|
||||||
final apiClient = ref.read(apiClientProvider);
|
|
||||||
subscribePushNotification(apiClient);
|
|
||||||
final wsNotifier = ref.read(websocketStateProvider.notifier);
|
|
||||||
wsNotifier.connect();
|
|
||||||
if (context.mounted) Navigator.pop(context, true);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() {
|
useEffect(() {
|
||||||
@@ -628,17 +635,13 @@ class _LoginLookupScreen extends HookConsumerWidget {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
final challenge = SnAuthChallenge.fromJson(resp.data);
|
final token = resp.data['token'];
|
||||||
onChallenge(challenge);
|
setToken(ref.watch(sharedPreferencesProvider), token);
|
||||||
final factorResp = await client.get(
|
ref.invalidate(tokenProvider);
|
||||||
'/pass/auth/challenge/${challenge.id}/factors',
|
if (!context.mounted) return;
|
||||||
);
|
|
||||||
onFactor(
|
// Do post login tasks
|
||||||
List<SnAuthFactor>.from(
|
await performPostLogin(context, ref);
|
||||||
factorResp.data.map((ele) => SnAuthFactor.fromJson(ele)),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
onNext();
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err is SignInWithAppleAuthorizationException) return;
|
if (err is SignInWithAppleAuthorizationException) return;
|
||||||
showErrorAlert(err);
|
showErrorAlert(err);
|
||||||
|
|||||||
@@ -5,10 +5,12 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:protocol_handler/protocol_handler.dart';
|
import 'package:protocol_handler/protocol_handler.dart';
|
||||||
import 'package:island/pods/activity/activity_rpc.dart';
|
import 'package:island/pods/activity/activity_rpc.dart';
|
||||||
|
import 'package:island/pods/config.dart';
|
||||||
|
import 'package:island/pods/network.dart';
|
||||||
import 'package:island/pods/websocket.dart';
|
import 'package:island/pods/websocket.dart';
|
||||||
import 'package:island/route.dart';
|
import 'package:island/route.dart';
|
||||||
|
import 'package:island/screens/auth/login_content.dart';
|
||||||
import 'package:island/screens/tray_manager.dart';
|
import 'package:island/screens/tray_manager.dart';
|
||||||
import 'package:island/services/event_bus.dart';
|
|
||||||
import 'package:island/pods/web_auth/web_auth_providers.dart';
|
import 'package:island/pods/web_auth/web_auth_providers.dart';
|
||||||
import 'package:island/services/notify.dart';
|
import 'package:island/services/notify.dart';
|
||||||
import 'package:island/services/sharing_intent.dart';
|
import 'package:island/services/sharing_intent.dart';
|
||||||
@@ -117,14 +119,20 @@ class _AppWrapperState extends ConsumerState<AppWrapper>
|
|||||||
TrayService.instance.handleAction(menuItem);
|
TrayService.instance.handleAction(menuItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _handleDeepLink(Uri uri, WidgetRef ref) {
|
void _handleDeepLink(Uri uri, WidgetRef ref) async {
|
||||||
String path = '/${uri.host}${uri.path}';
|
String path = '/${uri.host}${uri.path}';
|
||||||
|
|
||||||
// Special handling for OIDC auth callback
|
// Special handling for OIDC auth callback
|
||||||
if (path == '/auth/callback' &&
|
if (path == '/auth/callback' && uri.queryParameters.containsKey('token')) {
|
||||||
uri.queryParameters.containsKey('challenge')) {
|
final token = uri.queryParameters['token']!;
|
||||||
final challenge = uri.queryParameters['challenge']!;
|
setToken(ref.read(sharedPreferencesProvider), token);
|
||||||
eventBus.fire(OidcAuthCallbackEvent(challenge));
|
ref.invalidate(tokenProvider);
|
||||||
|
|
||||||
|
// Do post login tasks
|
||||||
|
if (mounted) {
|
||||||
|
await performPostLogin(context, ref);
|
||||||
|
}
|
||||||
|
|
||||||
if (!kIsWeb &&
|
if (!kIsWeb &&
|
||||||
(Platform.isWindows || Platform.isLinux || Platform.isMacOS)) {
|
(Platform.isWindows || Platform.isLinux || Platform.isMacOS)) {
|
||||||
windowManager.show();
|
windowManager.show();
|
||||||
|
|||||||
Reference in New Issue
Block a user