diff --git a/app/lib/backend/http/api/custom_auth.dart b/app/lib/backend/http/api/custom_auth.dart index 554d23186..87e20be03 100644 --- a/app/lib/backend/http/api/custom_auth.dart +++ b/app/lib/backend/http/api/custom_auth.dart @@ -27,6 +27,18 @@ Future customAuthSignUp(String name, String email, String password) async return false; } +_setFieldsFromBody(Map body) { + SharedPreferencesUtil().authToken = body['token'] ?? ''; + SharedPreferencesUtil().tokenExpirationTime = body['exp'] != null ? body['exp'] * 1000 : 0; + SharedPreferencesUtil().uid = body['uid'] ?? ''; + + String name = body['name'] ?? ''; + List nameParts = name.split(' '); + + SharedPreferencesUtil().givenName = nameParts.isNotEmpty ? nameParts[0] : ''; + SharedPreferencesUtil().familyName = nameParts.length > 1 ? nameParts.sublist(1).join(' ') : ''; +} + Future customAuthSignIn(String email, String password) async { if (email.isEmpty || password.isEmpty) { return false; @@ -41,25 +53,33 @@ Future customAuthSignIn(String email, String password) async { try { log('customAuth signIn: ${response.body}'); var body = jsonDecode(response.body); - SharedPreferencesUtil().authToken = body['token']; - SharedPreferencesUtil().tokenExpirationTime = body['exp'] * 1000; - SharedPreferencesUtil().uid = body['uid']; - String name = body['name'] ?? ''; - List nameParts = name.split(' '); - SharedPreferencesUtil().givenName = nameParts[0]; - SharedPreferencesUtil().familyName = nameParts.length > 1 ? nameParts[1] : ''; + _setFieldsFromBody(body); SharedPreferencesUtil().email = email; SharedPreferencesUtil().customAuthPassword = password; - - // TODO: modify also authProvider, to disable any logic there - // TODO: http requests when getting the token, should use this token. - // TODO: on main.dart every time the app is opened return true; } catch (e, stackTrace) { debugPrint(e.toString()); + _setFieldsFromBody({}); + SharedPreferencesUtil().email = ''; + SharedPreferencesUtil().customAuthPassword = ''; CrashReporting.reportHandledCrash(e, stackTrace); return false; } } + _setFieldsFromBody({}); + SharedPreferencesUtil().email = ''; + SharedPreferencesUtil().customAuthPassword = ''; return false; } + +// TODO: +// 1. Check every navigation works as expected. (without customBackend) +// 2. When backend url set, should return to login screen, and setState refreshed, to not show the apple/google login +// 3. Sign up completed, goes back to login screen, snackbar please sign in +// 4. sign in completed, goes back to login screen widget.onSignIn is called +// 5. skip name onboarding widget (on auth completion, but also on wrapper widget loaded) +// 6. everything should work now +// 7. test with custom backend url +// 8. modify sign out to clear email/pwd instead. +// 9. Option to clear backend url widget data, remove it. +// 10. On settings it should be shown that the app is using custom backend URL \ No newline at end of file diff --git a/app/lib/backend/http/shared.dart b/app/lib/backend/http/shared.dart index 082056c6b..45e8f1459 100644 --- a/app/lib/backend/http/shared.dart +++ b/app/lib/backend/http/shared.dart @@ -13,12 +13,18 @@ Future getAuthHeader() async { DateTime? expiry = DateTime.fromMillisecondsSinceEpoch(SharedPreferencesUtil().tokenExpirationTime); bool hasAuthToken = SharedPreferencesUtil().authToken.isNotEmpty; - if (!hasAuthToken || - expiry.isBefore(DateTime.now()) || + bool isExpirationDateValid = !(expiry.isBefore(DateTime.now()) || expiry.isAtSameMomentAs(DateTime.fromMillisecondsSinceEpoch(0)) || - (expiry.isBefore(DateTime.now().add(const Duration(minutes: 5))) && expiry.isAfter(DateTime.now()))) { + (expiry.isBefore(DateTime.now().add(const Duration(minutes: 5))) && expiry.isAfter(DateTime.now()))); + + if (SharedPreferencesUtil().customBackendUrl.isNotEmpty && (!hasAuthToken || !isExpirationDateValid)) { + throw Exception('No auth token found'); + } + + if (!hasAuthToken || !isExpirationDateValid) { SharedPreferencesUtil().authToken = await getIdToken() ?? ''; } + if (!hasAuthToken) { if (isSignedIn()) { // should only throw if the user is signed in but the token is not found diff --git a/app/lib/main.dart b/app/lib/main.dart index 1d1dcd340..2ace35117 100644 --- a/app/lib/main.dart +++ b/app/lib/main.dart @@ -285,7 +285,8 @@ class _DeciderWidgetState extends State { NotificationService.instance.saveNotificationToken(); } - if (context.read().user != null) { + if (context.read().user != null || + (SharedPreferencesUtil().customBackendUrl.isNotEmpty && SharedPreferencesUtil().authToken.isNotEmpty)) { context.read().setupHasSpeakerProfile(); IntercomManager.instance.intercom.loginIdentifiedUser( userId: SharedPreferencesUtil().uid, @@ -305,7 +306,10 @@ class _DeciderWidgetState extends State { Widget build(BuildContext context) { return Consumer( builder: (context, authProvider, child) { - if (SharedPreferencesUtil().onboardingCompleted && authProvider.user != null) { + if (SharedPreferencesUtil().onboardingCompleted && + (authProvider.user != null || + (SharedPreferencesUtil().customBackendUrl.isNotEmpty && + SharedPreferencesUtil().authToken.isNotEmpty))) { return const HomePageWrapper(); } else { return const OnboardingWrapper(); diff --git a/app/lib/pages/onboarding/wrapper.dart b/app/lib/pages/onboarding/wrapper.dart index 69dbed1ef..0305aba7d 100644 --- a/app/lib/pages/onboarding/wrapper.dart +++ b/app/lib/pages/onboarding/wrapper.dart @@ -38,7 +38,8 @@ class _OnboardingWrapperState extends State with TickerProvid _controller = TabController(length: hasSpeechProfile ? 5 : 6, vsync: this); _controller!.addListener(() => setState(() {})); WidgetsBinding.instance.addPostFrameCallback((_) async { - if (isSignedIn()) { + if (isSignedIn() || + (SharedPreferencesUtil().customBackendUrl.isNotEmpty && SharedPreferencesUtil().authToken.isNotEmpty)) { // && !SharedPreferencesUtil().onboardingCompleted if (mounted) { context.read().setupHasSpeakerProfile(); @@ -82,7 +83,7 @@ class _OnboardingWrapperState extends State with TickerProvid MixpanelManager().onboardingStepCompleted('Auth'); context.read().setupHasSpeakerProfile(); IntercomManager.instance.intercom.loginIdentifiedUser( - userId: FirebaseAuth.instance.currentUser!.uid, + userId: SharedPreferencesUtil().uid, ); if (SharedPreferencesUtil().onboardingCompleted) { // previous users diff --git a/app/lib/providers/auth_provider.dart b/app/lib/providers/auth_provider.dart index 770e08991..46edb2f7f 100644 --- a/app/lib/providers/auth_provider.dart +++ b/app/lib/providers/auth_provider.dart @@ -14,10 +14,6 @@ class AuthenticationProvider extends BaseProvider { User? user; String? authToken; - bool isSignedIn() { - return _auth.currentUser != null; - } - AuthenticationProvider() { _auth.authStateChanges().distinct((p, n) => p?.uid == n?.uid).listen((User? user) { if (SharedPreferencesUtil().customBackendUrl.isNotEmpty) return; @@ -49,6 +45,8 @@ class AuthenticationProvider extends BaseProvider { }); } + bool isSignedIn() => _auth.currentUser != null; + Future onGoogleSignIn(Function() onSignIn) async { if (!loading) { setLoadingState(true);