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

Password reset is not working #77

Open
renardeinside opened this issue Nov 26, 2022 · 49 comments
Open

Password reset is not working #77

renardeinside opened this issue Nov 26, 2022 · 49 comments
Assignees
Labels
bug Something isn't working

Comments

@renardeinside
Copy link

renardeinside commented Nov 26, 2022

Bug report

I'm trying to set up password reset flow in my nextjs app with supabase and supabase auth ui. It's not working and I'm struggling to understand the root cause.

Describe the bug

When a reset link is clicked, no password reset dialog is shown.

To Reproduce

Steps to reproduce the behavior, please provide code snippets or a repository:

  1. Instantiate a nextjs app with supabase and auth-ui
  2. Create a new page with the following content:
// LOCATED IN pages/auth-ui.jsx
import {
    Auth,
    // Import predefined theme
    ThemeSupa,
} from '@supabase/auth-ui-react'
import {useSupabaseClient} from "@supabase/auth-helpers-react";
import Container from "@mui/material/Container";

const AuthUi = () => {
    const supabase = useSupabaseClient();

    return(
        <Container maxWidth={"sm"}>
            <Auth
                supabaseClient={supabase}
                appearance={{ theme: ThemeSupa }}
                theme="dark"
                redirectTo={`http://app.local/auth-ui`}
            />
        </Container>

    )
}

export default AuthUi
  1. Setup your auth settings in supabase:
Site URL: http://app.local
Redirect Url: http://app.local

Side note - I'm using http here since I have a local instance of my app on this redirect URL, so the certificate is not a concern.

  1. Using the AuthUI, generate an email for a password reset. The link in the email will be in the format of:
https://XXX.supabase.co/auth/v1/verify?token=XXX&type=recovery&redirect_to=http://app.local/auth-ui
  1. Click the link
  2. Auth flow will end up with the following path:
http:/app.local/auth-ui#

The user will remain signed in, but no reset password view will be shown.

Expected behavior

It works and doesn't require users to debug this - it's such a basic functionality, strange that it's not working correctly by default.

Screenshots

If applicable, add screenshots to help explain your problem.

System information

  • OS: [e.g. macOS, Windows] macos
  • Browser (if applies) [e.g. chrome, safari] chrome
  • Version of supabase-js: [e.g. 6.0.2]:
    "@supabase/auth-helpers-nextjs": "^0.5.2",
    "@supabase/auth-helpers-react": "^0.3.1",
    "@supabase/auth-ui-react": "^0.2.6",
    "@supabase/supabase-js": "^2.1.0",
  • Version of Node.js: [e.g. 10.10.0]:
> node -v    
v16.7.0

Additional context

If you'll click the link second time, you'll not get a proper error handle, instead, the redirect will look like this:

http://xxx.local/auth-ui#error=unauthorized_client&error_code=401&error_description=Email+link+is+invalid+or+has+expired

It's quite clear that it should look like this (query, not an anchor):

http://xxx.local/auth-ui?error=unauthorized_client&error_code=401&error_description=Email+link+is+invalid+or+has+expired
@renardeinside renardeinside added the bug Something isn't working label Nov 26, 2022
@0x111
Copy link

0x111 commented Nov 28, 2022

Possible duplicate of #72

@mryechkin
Copy link

mryechkin commented Dec 8, 2022

Seems like issue #349 in the gotrue-js repo is related.

In the past, with the old Auth component from the now-deprecated Supabase UI library and v1 of the client lib, I had to listen to the changes in auth state manually in my auth provider, and set the UI view accordingly:

useEffect(() => {
  const activeSession = supabase.auth.session();
  setSession(activeSession);
  setUser(activeSession?.user ?? null);

  const { data: authListener } = supabase.auth.onAuthStateChange(
    (event, currentSession) => {
      // ...
      switch (event) {
          case EVENTS.PASSWORD_RECOVERY:
            setView(VIEWS.UPDATE_PASSWORD);
            break;
          case EVENTS.SIGNED_OUT:
          case EVENTS.USER_UPDATED:
            setView(VIEWS.SIGN_IN);
            break;
          default:
        }
    }
  );

  return () => {
    authListener?.unsubscribe();
  };
}, []);

Then manually show the "Reset Password" form, as it seemed to be the only way to get this to work:

if (view === VIEWS.UPDATE_PASSWORD) {
  return (
    <Auth.UpdatePassword supabaseClient={supabase} />
  );
}

return (
  <Layout>
    {user && (
      {/** Logged-in state */}
    )}
    {!user && <Auth view={view} supabaseClient={supabase} />}
  </Layout>
);

But I'm now discovering this doesn't work anymore for some reason. The PASSWORD_RECOVERY event never seems to fire after going to the URL in the Reset Password email.

Even with the old code and library versions, it doesn't seem to work anymore. I wrote a full post on doing this with the old library, and discovered this issue while updating it for v2 and the new Auth UI.

Seems like the issue is present in both v1 and v2. I found more related issues on this as well:

supabase/auth#960
supabase/auth-js#305

And this comment goes into more detail on the reset password flow.

EDIT: Found another comment that may shed some light on this behaviour.

The TL;DR is that it seems like the Auth UI still doesn't automatically handle what should be a pretty straightforward auth flow.

@jt6677
Copy link

jt6677 commented Dec 10, 2022

The provided Auth UI code just does not work whatsoever. It did not mention @supabase/auth-helpers-react. If you cannot provide any working example, why bother to release this?

@silentworks
Copy link
Contributor

@jt6677 this repository has no relation to auth-helpers-react, they are two independent projects which can be used together if the developer wishes to. There are many examples inside of storybook in this repo. Also there are projects using the Auth UI, so I would think its working, it would be useful if you provided more concrete example of what is not working, even better if you provide a minimal reproducible repository with the issue you are having.

@silentworks
Copy link
Contributor

@renardeinside please provide a repo with the issue you are having, since you are using NextJS its likely that you are getting redirected to the wrong page because the server loads before the client and you get redirect by the server as when it checks to see if you are logged in you would not be at the time the server side page renders.

@Jared-Dahlke
Copy link

im having this problem too. After i click 'reset password' link in email, i just get taken to my regular login page.

@hiroshinishio
Copy link

@giovanniRodighiero
Copy link
Contributor

I didn't try it properly yet, but I can se that in the Solid.js version of the Auth component there's an event listener that handles the redirect you're talking about.

  createEffect(() => {
    /**
     * Overrides the authview if it is changed externally
     */
    const { data: authListener } =
      mergedProps().supabaseClient.auth.onAuthStateChange((event, session) => {
        if (event === 'PASSWORD_RECOVERY') {
          setAuthView(VIEWS.UPDATE_PASSWORD)
        } else if (event === 'USER_UPDATED') {
          setAuthView(VIEWS.SIGN_IN)
        }
      })
    setAuthView(mergedProps().view)

    onCleanup(() => authListener.subscription.unsubscribe())
  })

In the React.js version it's missing

  useEffect(() => {
    /**
     * Overrides the authview if it is changed externally
     */
    setAuthView(view)
  }, [view])

I don't know the project, so it might be that I'm missing something here, but to me it looks like those two bits of code should be the same.

@chrisk-7777
Copy link

chrisk-7777 commented Feb 8, 2023

I've created a very minimal example here: https://github.com/chrisk-7777/supabase-reset-test

It does "work", but it doesn't feel entirely intuitive or documented. Unless I'm missing something in the docs.
I've read this dicusssion a half dozen times to really "get" what is going on.

Disclaimer, I'm new to Supabase and its ecosystem, but not new to authentication.

There were two key points that I initially missed:

  1. Auth UI includes a "forget password" view, but not a "reset password" view. To me this was confusing. The confusion comes from my experience with other auth solutions like Auth0 and Laravel's Sanctum/Fortify/Breeze - where a reset flow isn't also a magic link / sign in combo. I can't recall which one Firebase uses, I'll check later. I noticed this recent PR, which is off the back of this confusion. But if anything, that makes it more confusing because someone (like myself) may conflate that to mean that "forgot" is "reset".
    If the team is open to it, I would like to raise a PR saying that "reset password" view is excluded.
    The docs kind of hint to the user being signed in here but it doesn't actually mention a session is started, just that a sign in event occurred. Maybe that is obvious to others, but reading around on various issues/discussions its not.

  2. Within the React version of Auth UI, it never reaches the update_password by itself (correct me if I'm wrong). So for the particular case of a post-forget-magic-link-login PASSWORD_RECOVERY event, we need to set some app level state, and manually set the view in consumer land. In hindsight, I guess this makes sense, it makes it handy to have that view available for general password updates, but its confusing that view is sometimes handled internally (swapping between login, register and forgot views), and sometimes handled externally (update password view). Maybe its just me?

Bonus: One other thing that completely caught me off guard was onAuthStateChange should be unregistered, like this, right? Again, I'm new to Supabase, but without unsubscribing, a component re-render will re-fire useEffect, and queue up multiple listeners - is that right? I bring it up because the documentation here outlines the subscribe occurring in a useEffect without any cleanup.

Separately, I believe there is some NextJS funkiness going on. The same thing that @mryechkin is experiencing (sorry to @ you, but I've seen you pop up in nearly every password reset discussion/issue across supabase's repo's, and have helped me understand what is going on). As mentioned somewhere else, the "PASSWORD_RECOVERY" event isn't fired, but is probably related to a clash with Next' routing / rendering modes. I'll try put together a minimal repo for that too.

None of this should be taken as criticism, I'm just trying to clarify my understanding after a day of going around in circles.

@chrisk-7777
Copy link

A minimal repo for NextJS: https://github.com/chrisk-7777/supabase-reset-next-test

I'm intentionally avoiding the convenience helpers to keep the surface area small.

If onAuthStateChange is subscribed to within a root page (like index.tsx), or a sub page (like reset.tsx) then everything works fine, just with the same notes from my previous comment.

Note: This is all SSG, no SSR.

@mryechkin
Copy link

@chrisk-7777 I ended up ditching the Auth UI library and just created my own Auth forms - much easier than trying to work around the gotchas in this library (see my comment here).

Auth UI includes a "forget password" view, but not a "reset password" view. To me this was confusing.
...
But if anything, that makes it more confusing because someone (like myself) may conflate that to mean that "forgot" is "reset"

I wholeheartedly agree with this, and also find it quite strange that the "Forgot" form is included, but not the "Reset". In my mind the two go hand-in-hand.

So for the particular case of a post-forget-magic-link-login PASSWORD_RECOVERY event, we need to set some app level state, and manually set the view in consumer land. In hindsight, I guess this makes sense, it makes it handy to have that view available for general password updates, but its confusing that view is sometimes handled internally (swapping between login, register and forgot views), and sometimes handled externally (update password view). Maybe its just me?

Yup.. also agreed, and no it's not just you - I was also quite confused when I started looking into this initially. It's again the reason I opted to not use the provided UI library once I moved to Supabase v2, and created my own auth forms and the context provider.

@silentworks silentworks self-assigned this Mar 1, 2023
@silentworks
Copy link
Contributor

To everyone in this thread I really appreciate the time you've all taken to explain the difficulties you are facing with the library and the lack of documentation which has led to these difficulties. I am taking it all into consideration as we formulate how to best fix these issues. I think the first step is to document how you would go about handling password reset as this is something that keeps on coming up and it differs per environment [server-side generated (SSG) and single page application (SPA)]. There is also scenarios where it may even work different in SPA environments too because in the case of you using a router in your SPA like React Router you would use the component similar to how you would use it in a SSG environment. I've added in the event listener in the auth-ui-react library to match that of the auth-ui-solid version, but this in effect is only useful in an SPA without a router setup.

@silentworks
Copy link
Contributor

I just want to come back and give an update here that this issue hasn't been forgotten. I'm currently working on some docs to explain how this flow is supposed to work and then will create some examples with the Auth UI to show how it works.

@chrisk-7777
Copy link

Thanks @silentworks

Is it only changes in the docs that are needed? Or is it upstream in GoTrue? Or the Supabase wrappers?
Aside from the two minimal repo's replicating the issue, is there a way to help this along?

@silentworks
Copy link
Contributor

@chrisk-7777 It's mainly a documentation issue. I've written the docs already but just waiting on a certain feature to rollout fully to all projects on the Supabase platform.

You can view the docs PR here supabase/supabase#14111

Note that this doc isn't Auth UI specific but a general password reset doc, I will add examples of how you would do this with Auth UI in later on.

@Bartel-C8
Copy link

Would it be possible to use the auth-ui-react Auth component and be able to use the Password Reset functionality in combination with Next.JS (SSR)? It seems that this is not supported, out of the box?

@chrisk-7777
Copy link

@Bartel-C8 looks like the docs were updated here: https://supabase.com/docs/guides/auth/auth-password-reset . This covers the SSR flow

With the merged PR that Silentworks mentioned above.

@Bartel-C8
Copy link

@chrisk-7777 , thank you.

But this should be handled/done already in the auth-ui-react package: https://github.com/supabase/auth-ui/blob/main/packages/react/src/components/Auth/interfaces/ForgottenPassword.tsx

But when using that (actually I am just using the todo template: https://github.com/supabase/supabase/tree/master/examples/todo-list/nextjs-todo-list), there is no way to see the Reset Password page somehow. In my case, clicking the reset password link, as received in the email, acts as a "magic link" just showing the page as a user was just logged in. I see no reset_password view unfortunately...

Could be related to: supabase/supabase#14890 (comment)

@levity
Copy link

levity commented Jul 11, 2023

@chrisk-7777 It's mainly a documentation issue. I've written the docs already but just waiting on a certain feature to rollout fully to all projects on the Supabase platform.

You can view the docs PR here supabase/supabase#14111

Note that this doc isn't Auth UI specific but a general password reset doc, I will add examples of how you would do this with Auth UI in later on.

Can you give an example of how you would do this with Auth UI? I can't figure it out. This is the basic pattern I was expecting to work:

const [session, setSession] = useState()

useEffect(() => {
  supabase.auth.getSession().then(({ data: { session } }) => setSession(session))
}, [])

if (!session) return <Auth supabaseClient={supabase} />
return <MyContent>

However, this won't work with the password recovery links that Auth UI sends, because the user gets logged in and then the Auth UI doesn't render. What else can I check to keep rendering Auth instead of MyContent, in order to update the password? It doesn't seem like I can check type=recovery in the query params because something in the auth code changes the URL.

@MichalOsadowski
Copy link

@chrisk-7777 It's mainly a documentation issue. I've written the docs already but just waiting on a certain feature to rollout fully to all projects on the Supabase platform.
You can view the docs PR here supabase/supabase#14111
Note that this doc isn't Auth UI specific but a general password reset doc, I will add examples of how you would do this with Auth UI in later on.

Can you give an example of how you would do this with Auth UI? I can't figure it out. This is the basic pattern I was expecting to work:

const [session, setSession] = useState()

useEffect(() => {
  supabase.auth.getSession().then(({ data: { session } }) => setSession(session))
}, [])

if (!session) return <Auth supabaseClient={supabase} />
return <MyContent>

However, this won't work with the password recovery links that Auth UI sends, because the user gets logged in and then the Auth UI doesn't render. What else can I check to keep rendering Auth instead of MyContent, in order to update the password? It doesn't seem like I can check type=recovery in the query params because something in the auth code changes the URL.

I have same problem.

@chrisk-7777
Copy link

@chrisk-7777 , thank you.

But this should be handled/done already in the auth-ui-react package: https://github.com/supabase/auth-ui/blob/main/packages/react/src/components/Auth/interfaces/ForgottenPassword.tsx

But when using that (actually I am just using the todo template: https://github.com/supabase/supabase/tree/master/examples/todo-list/nextjs-todo-list), there is no way to see the Reset Password page somehow. In my case, clicking the reset password link, as received in the email, acts as a "magic link" just showing the page as a user was just logged in. I see no reset_password view unfortunately...

Could be related to: supabase/supabase#14890 (comment)

I mentioned something similar above: #77 (comment) (dot point 1). Your description of "magic link" is correct in my opinion.

This is also part of the updated docs in this PR (https://github.com/supabase/supabase/pull/14111/files). They even use the term "magic link". You will need to "manually" present some password UI (like an input box) and call the updateUser method.

Maybe resetPasswordForEmail is the wrong term to start this flow, but I can't think of a better one tbh.

@silentworks
Copy link
Contributor

silentworks commented Jul 12, 2023

Hey folks I can see that there are still confusion around how this process works. I think one of the issue here is that folks think the Auth UI is supposed to be a smart component when in-fact it's just a dumb component, it doesn't do much more than provide you with a UI and make the API call, the rest is up to you the developer to handle. When doing a password reset flow you need to provide the page that the update password should happen on, on that page you can use the Auth UI component. You can take a look at the examples I've created here https://github.com/supabase-community/supabase-by-example/tree/main/reset-flow/auth-ui, note that you might see new component names being introduced like ForgottenPassword these are just wrappers around the Auth component that set the view property to the correct state. These could have easily been the Auth component with view property set to forgotten_password. You can see this component here https://github.com/supabase/auth-ui/blob/main/packages/react/src/components/Auth/ui/index.tsx#L93-L105

@chrisk-7777
Copy link

chrisk-7777 commented Jul 12, 2023

I agree regarding the confusion, its probably related to the typical "forget" flow being different (I made a few comparisons to other auth solutions in my comment above).

So it might be worth highlighting this difference in the docs?

Just a few bits like:

  • In the supported views section, link to the supabase reset flow
  • Rename "forgotten password" to "password reset" for consistent language
  • Highlight that the "forgotten password" / "password reset" view doesn't (yet) include an update password view. Simply to avoid further confusion, and possibly redirect them over to the auth-password-reset docs again.

@silentworks
Copy link
Contributor

@chrisk-7777 good suggestions. I will add them to my list of todos and get the docs update to match this. Do note that there is an update password view, it's just that you have to manually set the views with the Auth component.

You can see the individual component which just uses this view in the Auth component.
https://github.com/supabase/auth-ui/blob/main/packages/react/src/components/Auth/ui/index.tsx#L107-L114

@levity
Copy link

levity commented Jul 12, 2023

Hey folks I can see that there are still confusion around how this process works. I think one of the issue here is that folks think the Auth UI is supposed to be a smart component when in-fact it's just a dumb component, it doesn't do much more than provide you with a UI and make the API call, the rest is up to you the developer to handle. When doing a password reset flow you need to provide the page that the update password should happen on, on that page you can use the Auth UI component. You can take a look at the examples I've created here https://github.com/supabase-community/supabase-by-example/tree/main/reset-flow/auth-ui, note that you might see new component names being introduced like ForgottenPassword these are just wrappers around the Auth component that set the view property to the correct state. These could have easily been the Auth component with view property set to forgotten_password. You can see this component here https://github.com/supabase/auth-ui/blob/main/packages/react/src/components/Auth/ui/index.tsx#L93-L105

I think the confusion arises because the Auth component is “half-smart”.

If you just drop it in, it lets you switch between all the different views, so it will already allow login, signup, and sending password reset links. Which is great! So it makes you think it Just Works.

But it doesn’t let you configure each of those views separately. You can’t customize redirectTo only for the password reset link. If we could do that, for example, this would be easy to fix.

So I think it’d be better either for it to be really dumb (not handle switching views with setAuthView, out-of-the-box), or smarter. Obviously I prefer the latter. :) Happy to help out with a PR if I hear some consensus about what to do.

@mryechkin
Copy link

@levity this is exactly why I opted to just use my own auth forms instead of relying on what feels like a half-baked solution with Auth UI. It would be great it it handled all the things like you said - but the fact that it doesn't let us configure some things while also requiring to manually implement other things makes using this component an exercise in frustration, and not really worth the effort IMO.

@ozanmakes
Copy link

I made a PR that does what @levity describes and that works for me. You can see it here: #223 with my comment describing the desired reset password flow. But I must still be missing something regarding how to implement this flow without re-implementing a bunch of these components or even doing everything server-side. I would really appreciate pointers on how to get this working with the Auth components.

@TylerAHolden
Copy link

I think where I'm most confused is that it presents itself as a fully baked component... There are no state change callback props. For example, if the "view" is changed in the component, and we are supposed to handle that separately, why is there no onViewChange callback? I see that maybe theres a hash added to the url but having a callback would be a lot more intuitive and clear about how the component can be handled - especially if we want to customize a specific view. There's no way for me to handle, for example, onSignup vs onSignin or some sort of auth change type callback from that view component so I can send the user to an additional form for sign up details IF they just signed up. I understand that can be done by listening to auth helpers but i just think some callbacks from the auth ui would make setup a lot easier and more intuitive as to how you can handle it.

@rsaksida
Copy link

I'm pretty confused with how this feature is supposed to work. How do I distinguish between recovering a password and restoring the session in a client app? Using the React quickstart from the docs, the recovery link logs you in immediately and I don't see a simple way to fix it.

@kev2010
Copy link

kev2010 commented Oct 19, 2023

Here to +1 to the fact that the Auth UI component is extremely misleading. Spent a decent chunk of time trying to use the component for my app, but instead kept uncovering limitations that make it a complete hassle to implement.

For those of you who happen to be reading this and are considering using Auth UI — don't! Implement your own or use another service instead of this one since it's half-baked as @mryechkin said.

The documentation should make it extremely clear that this is not a working solution. I went down this rabbit hole because the official documentation on Supabase's site made it look like it was an appealing solution

@selalipop
Copy link

selalipop commented Nov 1, 2023

Any reason Supabase isn't updating on this? I personally ran into a ton of issues, then by happenstance ran into another developer on a completely unrelated project running head first into the same brick walls I was at an event.

Not a good look for Supabase to show up at events as the problem child for something as pivotal as auth. End result is most people just go to Clerk.dev, and in turn probably go with Vercel's Postgres over yours.

@oldbettie
Copy link

I am getting in on this. The documentation is terrible for this feature. The examples given don't include the implementation in the documentation so I still have not found a solution that works. I can get to the point where an email is sent and the redirect is handled correctly. But I cannot exchange the token for a session so the user is never logged in to change the password. I just get an error code challenge does not match previously saved code verifier no matter which way I try to implement it I get the same error

@MichalOsadowski
Copy link

I am getting in on this. The documentation is terrible for this feature. The examples given don't include the implementation in the documentation so I still have not found a solution that works. I can get to the point where an email is sent and the redirect is handled correctly. But I cannot exchange the token for a session so the user is never logged in to change the password. I just get an error code challenge does not match previously saved code verifier no matter which way I try to implement it I get the same error

@oldbettie do you mean url redirect url with fragment in it? Make sure that supabase client is created globally and it will handle it for yourself. I spent few hours figuring out why the hell fragment is being removed on its own and then I found out that client is removing it after usage.

I feel like the whole auth flow on client side is inconsequential designed. On one side Auth component is not supposed to be smart and we have to handle auth logic here, but then client is doing things automagically without it being documented anywhere.

@oldbettie
Copy link

oldbettie commented Jan 4, 2024

@MichalBunkowski I followed this https://supabase.com/docs/guides/auth/server-side/email-based-auth-with-pkce-flow-for-ssr

I am able to create the session in the auth/confirm/route.ts but when it redirects to the page to update the password the session doesn't exist. I even tried to add a setSession call after it was processed. here is what I ended up with.

No matter what I do I cant get the session to persist using that verifyOtp method
const {data: { session}, error } = await supabase.auth.verifyOtp({
      type,
      token_hash,
    })

    if (session) {
      const s = await supabase.auth.setSession(session)
      console.log(s)

      return NextResponse.redirect(redirectTo);
    }
    ```
    

@daveycodez
Copy link

daveycodez commented Feb 4, 2024

BUMP @supabase where are you? Give us forgotPasswordRedirectUrl param. Simple fix. Thanks!

@tonypee
Copy link

tonypee commented Feb 14, 2024

+1 I'm struggling with having no 'forgotPasswordRedirectUrl' also - im going to have to import from ^^ that PR, or hack it to switch the redirectTo value, as my SSO is redirecting to my change-password link. This is ridiculous that it isnt being addressed

@nmauersberg
Copy link

nmauersberg commented Feb 28, 2024

I am stuck with this too. I was able to retrieve the session, but no matter what I do, the PASSWORD_RECOVERY event is not fired.

I am using Next JS 14, with app router. I tried various things, authenticating server side, a "use client" page for the reset of the password, etc. But the event does not show up either on the server or in the client.

A solution would be much appreciated, as this is a crucial part of the auth flow and introduces possible security issues, if not handled correctly.

As of now I think I have to resort to leaving the password reset page open for authenticated users, but that would mean, that any logged in user could reset the password without clicking the link in the email.

@zlever01
Copy link

This guide worked for me https://github.com/mryechkin/nextjs-supabase-auth for setting up supabase auth with nextjs

@nmauersberg
Copy link

@zlever01 Thx for pointing out an example.

But it looks like the example is not checking for the "PASSWORD_RECOVERY" event, just for the session, that is accessible with the token in the link in the password reset mail. Therefor the password reset page in the example repo does work for any authenticated user (to reset the pw to that account) and not just for someone, who has access to the mailaccount. Theoretically someone can set a new password for any logged in session without knowing the old password or having access to the email account, so the solution is not ideal.

@j4y33
Copy link

j4y33 commented Mar 16, 2024

same issue here, i cannot get a session passed onto the resetpassword screen. using expo-react-native. its unnerving. however, i used a workaround that works as follows.
user clicks password reset -> using sign-in-with-otp

const resetPassword = async () => {
    const { error } = await supabase.auth.signInWithOtp({
      email, 
      options: { emailRedirectTo: `com.supabase://reset-pw`}, 
    });

-> sendingmagic link -> directing user conditioned on param.type = "magiclink" -> to password reset screen (i set the session manually like this

if (params.type == 'magiclink' && params.access_token) {
        const access_token = params.access_token;
        const refresh_token = params.refresh_token;
        
        const { data } = await supabase.auth.setSession({
          access_token,
          refresh_token,
        })

        const session = data.session 
        
        dispatch({ type: 'SET_USER', payload: { email: email } });
        RootNavigation.navigate('ResetPassword', { session });
      } 

-> updateUser -> done.

NOTE: probably this workaround with manually setting the session from refresh token and access token would also work for password reset (same flow), but honestly tired of trying :)

hope this helps

@Vaidik2473
Copy link

Hello,

I am also very confused as to why this is so complicated and why the half remaining user auth like forgot password or reset password are suppose to bee build differently, The forgot password link it redirects to makes user login but it would be much easier to redirect user to a specific page and from there user can change password

So i am confused does Auth ui has this reset password components but are hidden somewhere which canbe initiated using a simple prop pass? and if there is then ehat is the props and types?

i want the flow like this

user -> Sign up -> Token available
user -> Login -> Token available
user -> reset password? -> change passsword form -> Token available

@shrir
Copy link

shrir commented Apr 9, 2024

Hello, I made a workaround in my next.js app. I repurpose the login page for reset password (in the absence of resetPasswordRedirectTo) based on the query param code. It seems to be working.

"use client";
import { ViewType, VIEWS } from "@supabase/auth-ui-shared";
import { useRouter, useSearchParams } from "next/navigation";
import { useState } from "react";

export default function LoginPage() {
  const router = useRouter();
  const searchParams = useSearchParams();
  const supabase = createClient();

  const [authView, setAuthView] = useState<ViewType>(VIEWS.SIGN_IN);
  const code = searchParams.get("code");

  supabase.auth.onAuthStateChange(async (event) => {
      if (code !== null && code !== "") {
        setAuthView(VIEWS.UPDATE_PASSWORD);
        return;
      } else if (event === "SIGNED_IN" || event === "TOKEN_REFRESHED") {
        router.push("/");
      } else {
        setAuthView(VIEWS.SIGN_IN);
      }
  }

  return (
    <>
      {authView === VIEWS.SIGN_IN ? (
        <Auth
          supabaseClient={supabase}
          view={VIEWS.SIGN_IN}
          redirectTo="http://localhost:3000/login"
          showLinks={true}
        />
      ) : (
        <Auth
          supabaseClient={supabase}
          view={VIEWS.UPDATE_PASSWORD}
          redirectTo="http://localhost:3000/login"
        />
      )}
    </>
  );
}

Hope this helps.

@valleymatch
Copy link

I ended up using a variation of @shrir 's strategy but split the VIEWS.UPDATE_PASSWORD view to another page/route, then listened to USER_UPDATED to trigger the post-password-change redirect. Handling the various views on separate routes allows us to handle the onAuthStateChange events in isolation which leads to more predictable behavior.

@ElectricCodeGuy
Copy link

ElectricCodeGuy commented May 30, 2024

I have this problem, but it is only for a few users. I could not replicate it my self since on all the different machines and accounts i tried it on i do get a session, but a few users we have the session would not persist to the password reset page...

Edit:
I changed the flow to see if this would work, so now:

User insert email to password reset:
User Click link in Email:
User is redirected to password reset page, WITH the token_hash set as a searchparam, so this is NOT consumed in the first api route.
User insert new password and click update. The token_hash is included in the server action and is consumed before the update.user.

This works for me, but again the other way around also worked for me but still caused unpredictable behavior. Will try this now and report back.

@michelcrypt4d4mus
Copy link

michelcrypt4d4mus commented Jun 14, 2024

i'm not using this auth-ui package but i built my own supabase-based auth for a react native app using deeplink URLs and i'm just here to note that i've never seen the PASSWORD_RECOVERY event fire. the flow looks like this:

  1. when a user clicks the "forgot password" link in the email it indeed contains a type=recovery parameter
  2. i am able to successfully log them in with the tokens passed to the app
  3. a SIGNED_IN event is then fired

but i'm logging all auth state events and i've never seen a PASSWORD_RECOVERY fire, ever. seems a decent workaround is to manually parse the URL and look for type=recovery to determine that the user requested a password reset but is there some undocumented aspect where i'm supposed to be passing the type=recovery param to supabase when i'm using the token to instantiate the session?

is it possible the PASSWORD_RECOVERY event is being fired before the user is logged in and thus the client never gets it? presumably you'd have to be logged in to get user specific events and (almost) by definition the user is not logged in at the moment they click the "forgot password" link.

@akshatsabavat
Copy link

im having this problem too. After i click 'reset password' link in email, i just get taken to my regular login page.

You need to go to your project dashboard and then click URL configuration and enter the URL under redirect URLs so supabase understands that this is the list of URLs that are authenticated and can be redirected towards. Refer to the Screen shot below

image

@FocusCookie
Copy link

For everybody who uses the supabase/ssr package:

I had a similar issue today that the session was not forwarded to my middleware in nextjs. After a long day of debugging and searching I went into the supabase discord and I found this posting:

supabase/ssr@7dc1837

Try to use npm i @supabase/ssr@patched for version 4.0.1 this fixes the issue with password recovery.

@huseKivrak
Copy link

For everybody who uses the supabase/ssr package:

I had a similar issue today that the session was not forwarded to my middleware in nextjs. After a long day of debugging and searching I went into the supabase discord and I found this posting:

supabase/ssr@7dc1837

Try to use npm i @supabase/ssr@patched for version 4.0.1 this fixes the issue with password recovery.

Thanks so much! Can't believe that the solution was in an hour-old comment and just 0.4.0 -> 0.4.1.

@mwolf1989
Copy link

s

You ended my 2 day journey of getting this to work, Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests