Skip to content

How to confirm email? #5

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

Closed
YChebotaev opened this issue Apr 20, 2019 · 15 comments · Fixed by #32
Closed

How to confirm email? #5

YChebotaev opened this issue Apr 20, 2019 · 15 comments · Fixed by #32

Comments

@YChebotaev
Copy link
Contributor

I invited user (myself) from netlify Identity console, and receive email titled "You've been invited to join ..." with "Accept the invite" link within it.

I follow this link and turned up at my-app.com/login page. When I enter my email and empty password I get error: invalid_grant: Email not confirmed

So i'm wondering how do I suppose to confirm email before using?

@YChebotaev
Copy link
Contributor Author

Should I invoke recoverAccount handle?

@swyxio
Copy link
Contributor

swyxio commented Apr 21, 2019

good question. i probably should document this better but we rely on a hash: https://github.com/sw-yx/react-netlify-identity/blob/48726cb891917b085b942027959a6c67d19d2fa0/src/index.tsx#L78

and the confirmation is automatically done through a React useEffect hook.

dont forget you can see open source working examples in https://netlify-gotrue-in-react.netlify.com/

@YChebotaev
Copy link
Contributor Author

I'm make change to use <NetlifyIdentity> as a component, but it does not help.

Same error: invalid_grant: Email not confirmed when trying to login after registration.

@YChebotaev
Copy link
Contributor Author

See into console:
Failed to load resource: the server responded with a status of 422 ()
Invited users must specify a password at ...

It should definetely have confirmUser(password: String) handle.

@YChebotaev
Copy link
Contributor Author

YChebotaev commented Apr 22, 2019

As a workaround, I create this code:

const confirmUser = async password => {
    try {
      const { token } = match.params
      _goTrueInstance._setRememberHeaders(remember)
      const response = await _goTrueInstance._request('/verify', {
        method: 'POST',
        body: JSON.stringify({
          token,
          password,
          type: 'signup'
        })
      })
      const user = await _goTrueInstance.createUser(response, remember)
      setUser(user)
      return user
    } catch (error) {
      console.error(error)
      throw error
    }
  }

Will be happy if this gets merged into react-netlify-identity as well.

@swyxio
Copy link
Contributor

swyxio commented Apr 22, 2019

hmm thanks for commenting. i’ll look into this in a couple days

@ljosberinn
Copy link
Contributor

ljosberinn commented Jan 16, 2020

@YChebotaev sorry for pinging you. v0.2.0 introduced a TokenParam that you can destructure from useNetlifyIdentity().

const {
    param: { token, type }, // type being 'invite' | 'recovery' | 'email_change' | undefined
} = useIdentityContext();

It's not quite what you proposed and I'll see whether I can create a wrapper for your logic. I haven't tried inviting users yet, from the looks of it you chose their initial password?

What would be the preferred flow?

  • user accepts invite mail
  • token gets parsed by this package
  • exposes token & type via hook().param
  • dev implements redirect to appropriate route
  • user confirms identity via password => confirmation & login?

@YChebotaev
Copy link
Contributor Author

YChebotaev commented Jan 17, 2020

No. The problem with accepting invite. The lib (at times I leave workaround) simply don't support accepting invites at all — it's just not working.

Just try to use it, and You probably will face the problem, as I were.

@ljosberinn
Copy link
Contributor

ljosberinn commented Jan 18, 2020

This should work with #32:

// App.js
const { replace } = useHistory();
const { param: { token, type } } = useNetlifyIdentity();

if(token && pathname === '/' && type === 'invite') {
  replace('/invite', { token }); // history.location.state.token
}

// Invite route: show password field
const { verifyToken, user, signupUser } = useNetlifyIdentity();
const { location } = useHistory();
const [token] = useState(location.state?.token);
const [password, setPassword] = useState(undefined);

function handleSubmit(event) {
  event.preventDefault();

  verifyToken()
    .then(user => signupUser(user.email, password, {}, true));
}

@YChebotaev
Copy link
Contributor Author

YChebotaev commented Jan 18, 2020

@ljosberinn Cool, thanks!

But I think that pass token via location.state is not good idea. I want more explicit way of getting token.

Well, if my app may rely on history api, it would strange if one library change it. I definetely don't want to use such a lib.

@ljosberinn
Copy link
Contributor

ljosberinn commented Jan 18, 2020

Sorry, I should've been clearer - useHistory comes from react-router!

import { useHistory, Route, Switch } from 'react-router-dom';
import { useNetlifyIdentity } from 'react-netlify-identity';

function App() {
  const { replace } = useHistory();
  const { param: { token, type } } = useNetlifyIdentity();
 
  if(token && pathname === '/' && type === 'invite') {
    replace('/invite', { token }); // or just replace(`/invite/${token}`) if you dont mind the token being in the url
  }

  return (
    <Switch>
      <Route exact path="/" component={...} />
      <Route exact path="/invite/:token" component={...} />
      <Route exact path="/reset-password/:token?" component={...} />
    </Switch>
  )
}

@YChebotaev
Copy link
Contributor Author

@ljosberinn I mean, here: 0033b60 You pushState to history.

And in Your comment this line:

const [token] = useState(location.state?.token);

@ljosberinn
Copy link
Contributor

ljosberinn commented Jan 18, 2020

Oh sorry now I got you. It should probably be replaceState too.

We don't really have another way of getting the token, do we? It's a given by Netlify, so all this lib can do is parse it, cleaning the URL and deliver the token to the dev.

Both replace(path, { token }) or replace(path + token) together with useState(location.state?.token) are implementation detail; it's just an example.

@YChebotaev
Copy link
Contributor Author

@ljosberinn But why? If I put something useful for My app in state, Your code will replace it. I don't like lib which doing so.

@ljosberinn
Copy link
Contributor

Like, what for example? The only code getting replaced is the document.location.hash.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants