Closed YChebotaev closed 4 years ago
Should I invoke recoverAccount handle?
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/
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.
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.
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.
hmm thanks for commenting. i’ll look into this in a couple days
@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?
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.
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));
}
@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.
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>
)
}
@ljosberinn I mean, here: https://github.com/sw-yx/react-netlify-identity/pull/32/commits/0033b604f441e54b65037dfac8c733c9918eee42 You pushState
to history
.
And in Your comment this line:
const [token] = useState(location.state?.token);
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.
@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.
Like, what for example? The only code getting replaced is the document.location.hash
.
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?