Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to handle exception for expired/invalid signup link #1065

Open
percarlsen opened this issue Oct 17, 2024 · 3 comments
Open

Unable to handle exception for expired/invalid signup link #1065

percarlsen opened this issue Oct 17, 2024 · 3 comments
Labels
auth This issue or pull request is related to authentication bug Something isn't working

Comments

@percarlsen
Copy link

Describe the bug
I've run into a problem related to invalid/expired confirmation links when signing up with email. The (relevant part of the) expired link looks as follows: com.example:///email-signup?error=access_denied&error_code=4&error_description=Email+link+is+invalid+or+has+expired#<...>. I was planning on handling this by checking the error_code query parameter in my app, and giving an appropriate message to the user. The issue, however, is that the deeplink navigation triggers supabase to call GoTrueClient.getSessionFromUrl, which raises an exception. So it never makes its way to the router. I've not been able to neither catch nor disable this exception, meaning that the app crashes whenever a user presses an expired link. I've tried the following without success:

  • Use the onException callback in my GoRouter, but this doesn't seem to be triggered.
  • Initialize supabase with client option setting detectSessionInUri = false.
  • I have a try-catch around the supabase.auth.signUp call, but this doesn't matter because the exception is raised when the link is clicked, not when signUp is called.
[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: AuthException(message: Email link is invalid or has expired, statusCode: 403, errorCode: access_denied)
#0      GoTrueClient.getSessionFromUrl (package:gotrue/src/gotrue_client.dart:780:7)
gotrue_client.dart:780
#1      SupabaseAuth._handleDeeplink (package:supabase_flutter/src/supabase_auth.dart:295:43)
supabase_auth.dart:295
#2      SupabaseAuth._handleIncomingLinks.<anonymous closure> (package:supabase_flutter/src/supabase_auth.dart:235:13)
supabase_auth.dart:235
#3      _RootZone.runUnaryGuarded (dart:async/zone.dart:1594:10)
zone.dart:1594
#4      _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:365:11)
stream_impl.dart:365
#5      _DelayedData.perform (dart:async/stream_impl.dart:541:14)
stream_impl.dart:541
#6      _PendingEvents.handleNext (dart:async/stream_impl.dart:646:11)
stream_impl.dart:646
#7      _PendingEvents.schedule.<anonymous closure> (dart:async/stream_impl.dart:617:7)
stream_impl.dart:617
#8      _microtaskLoop (dart:async/schedule_microtask.dart:40:21)
schedule_microtask.dart:40
#9      _startMicrotaskLoop (dart:async/schedule_microtask.dart:49:5)

To Reproduce
Steps to reproduce the behavior:

  1. Setup a flutter app with supabase_flutter, email+password authentication and GoRouter (though I don't think the last one is necessary)
  2. Set up deep link navigation from the confirmation email link
  3. Sign up, wait for the link to expire, and click it. (Alternatively, resend a new link and then click the old link).

Expected behavior
Clicking the expired link should navigate to that link and not raise an exception. (Alternatively; make it possible to catch that exception.)

Screenshots
NA

Version (please complete the following information):
On Linux/macOS

├── supabase_flutter 2.8.0
│   ├── supabase 2.5.0
│   │   ├── functions_client 2.4.0
│   │   ├── gotrue 2.10.0
│   │   ├── postgrest 2.3.0
│   │   ├── realtime_client 2.4.0
│   │   ├── storage_client 2.2.0

On Windows
NA

Additional context
Deep linking and navigation in this particular app in general works fine, so I'm confident this has nothing to do with the general routing setup.

@percarlsen percarlsen added the bug Something isn't working label Oct 17, 2024
@dshukertjr dshukertjr added the auth This issue or pull request is related to authentication label Oct 18, 2024
@Vinzent03
Copy link
Collaborator

You probably listen to the onAuthStateChanged stream without providing an onError callback to the listen() method. So exceptions that are added to the stream are not caught.

@percarlsen
Copy link
Author

You're right, thanks! I thought I'd checked this, but had forgotten about the other auth state change listener I have in main.dart which was causing the issue. Thanks again :-)

@percarlsen
Copy link
Author

Follow-up question: I now have an onAuthChangeState listener in the screen in question. I'm able to catch the error in the onError callback and provide a message to the user. However, if I navigate to another screen and then into the screen with the listener again, the same onError is triggered once again. I have made sure to cancel the subscription on dispose so I find it strange that the error re-appears the next time I navigate to the screen (also happens on consecutive navigations). I haven't been able to find any good resources on this. Could this be an issue with onAuthStateChange? My code related to the auth state listener looks as follows:

  StreamSubscription? authSubscription;

  @override
  initState() {
    super.initState();
    authSubscription = supabase.auth.onAuthStateChange.listen(
      (data) {
        final AuthChangeEvent event = data.event;
        if (event == AuthChangeEvent.signedIn) {
          // ...
        }
      },
      onError: (Object error) {
        if (error is AuthException && error.statusCode == "403") {
          // Logic to displaying a modal. This is triggered over and over
        } else {
          // This is some other error we don't expect here, so we don't take care of it
          throw error;
        }
      },
    );
  }

  @override
  void dispose() {
    authSubscription?.cancel();
    authSubscription = null;
    super.dispose();
  }

@percarlsen percarlsen reopened this Oct 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
auth This issue or pull request is related to authentication bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants