Reset password flow | Sharing personal experience #7487
JeffreyArts
started this conversation in
Feature Requests & Ideas
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Context
After configuring the email service, I wanted to continue developing my authentication flow. Below you can find details upon this journey. I already have a front-end app that I used as a toolbox to help me (among other things) to develop a Strapi authentication flow, and now I am using that as the starting point to re-create the same features, but then using Payload as the back-end
Implementing reset password flow
Resetting the password is relatively easy, I just make a POST request to "/api/[collection-slug]/forgot-password" as it can be found in the documentation. I got this working within a heartbeat, receiving an e-mail with an webaddress that points to my Payload server to reset my password. While this is not the flow that I desire (I want to reset the password in my front-end application) I wanted to check if this work nonetheless. Unfortunately it did not. I entered an password twice, but got a "something went wrong" error message. In the console I got the following error message:
Okay... Back to the documentation and check if it might need some configuration. At the forgot password section that I used to make the API request, I can't find any additional information on certain required configuration. It does has something about a custom e-mail template, so I clicked on that cause eventually I'd like to change the url that is in the reset password mail to my front-end app, and make the post request from there. Here I noticed two things.
There is no additional configuration required for the forgot-password flow
Which is a bummer, since that means that I've got a dead end, and need to find a new starting point for my journey to resolve this error message.
The 'forgotPassword' has two properties "generateEmailHTML" & "generateEmailSubject"
To me, the "generateEmail" section can be taken out of the property. I understand that you want to differentiate from Nodemailers default 'html' & 'subject' properties, since they are of a string type and here you've got two methods that contain parameters that hold valuable variables. So I let that one slide. But in order to stick to the nodemailer naming convention/feature list. I would also like to see a "generateEmailText", just for the consistency & transparency.
Since the documentation leads to a dead end, and I can't figure out a solution by myself based on the errormessage. I resort to my third strategy when I run into a development obstacle: search a solution online; Duckduckgo: "payloadcms APIError: Token is either invalid or has expired", which landed me on this Github page. Which didn't gave me a solution, but it did gave me the idea to validate the request body of the reset-password request from '/admin/reset/9170c546645d299572da3a6e11c2cc0798d92ec8'
This did not look very weird, but nonetheless I wanted to try to make the request as a JSON post request in Postman. I did so, and it got the same result*. I than thought that this could be because the token could actually be expired by now, so I requested a new one but that did not work neither. I than had an insight of why it might not work via the default url. That is because the default url most likely will validate the token against the admin user collection, not against the custom site users collection. An insight that unfortunately brought me nowhere, cause I was making the correct request for getting a password-reset token. Checking the mongoDB I notice a "resetPasswordToken" that matches the value that I was using in my request. What does was odd, is that the resetPasswordExpiration timestamp is 1 hour behind the current time. I guess that this is the UTC timestamp of the moment I requested the password reset (I live in the Netherlands, which UTC+2, Normally UTC+1, but due to summertime its +2).
*The stream of thoughts after the asterisk are misleading. I just messed up the Postman request. I called the forgot-password enpoint, instead of the reset-password endpoint. This was spotted when I looked at the console error messages and saw:
I did not notice this, because in the (Postman) interface within I was exploring my request, I got the same message:
If I would have gotten the errors 'Missing email property' & 'Token is either invalid or has expired', I would have noticed the difference and most likely would have discovered my mistake sooner. Having noticed this I have made the required changes to my front-end application and was no left with modifying the HTML template that would be sent by the e-mail reset flow. So I added the following to my email configuration object
This did nothing... Again, my mistake. I was adding 'forgotPassword' in the 'transportOptions' object of my 'payload.init' method. Where I should have added it in the 'auth' object of my 'CollectionConfig'. This mistake occured due to misreading the documentation combined with the fact that I am in a "email configuration mindstate", expecting that this value should be among all the other e-mail configuration. But it didn't. Sure, intellisense gave forgotPassword as a valid property of the transportOptions, which is undesirable (since it doesn't do anything here), but that might just as well has to do with my local VSCode configuraition.
This also puts my previous comment on the naming convention in perspective, since it belongs in a different location, specifying the word "email" in it makes a lot of sense now(still miss the generateEmailText version though). This also resolve the issue I was foreseeing in having the desire to create different e-mail generation methods for back-end as front-end users.
In conclusion
Overall I am happy with the final result, but I had certain points where I felt really lost. I'll summarize the actions I believe should be taken to improve the developer experience.
Error handling
I suppose that it is mostly because of a lack of time, but it would be of great value if the API would respond error messages. Also for handling front-end errors. Let's take the password reset flow as an example. Not only would it be of great value for me as a developer while I am creating this flow, it would also be of value to the end-user if I could display a message that the token has been expired, versus "something went wrong". Cause that gives 0% information on what to do different to get to the desired goal (getting an e-mail to reset the password).
Is there already a error handling convention in place? So that all API responses return errors in a similar format?
Remove default "password reset mail" for non-admin users
Since this flow doesn't work for non-admin users, it would be preferred to me, to don't fall back to the default authentication mail. Maybe even giving an error message like "Missing auth.forgotPassword.generateEmailHTML method on ", where would be replaced by Collection
Type declaration generateEmailHTML user property
Currently this value is set to 'unknown', I'm curious why that is. Pretty sure that it ain't unknown, it is a basis user (dunno the exact datatype), with the extended properties as specified in the fields property. In order to resolve the typescript error, I currently need to find out what the type is and update it manually. Would be preferable if it would be of this user type by default, and make me write the required code for extending this default value, which I would have to do anyway when I extend this user type.
Beta Was this translation helpful? Give feedback.
All reactions