# GSoC 2018 - Reset Password via Email Project

**URL:** <https://talk.openmrs.org/t/gsoc-2018-reset-password-via-email-project/18066>\
**Category:** GSoC\
**Created:** [May 17, 2018, 2:27pm UTC](https://talk.openmrs.org/t/gsoc-2018-reset-password-via-email-project/18066 "2018-05-17T14:27:25Z")\
**Posts on this page:** 1\
**Showing post:** 5

<div class="post-metadata">

**Author:** ![burke](https://talk.openmrs.org/user_avatar/talk.openmrs.org/burke/32/17_2.png) [@burke](https://talk.openmrs.org/u/burke)\
**Post date:** [May 17, 2018, 9:32pm UTC](https://talk.openmrs.org/t/gsoc-2018-reset-password-via-email-project/18066/5 "2018-05-17T21:32:13Z")

</div>

@harisu,

OpenMRS uses a [REST](https://en.wikipedia.org/wiki/Representational_state_transfer) API. By design, this means your are interacting with resources via HTTP calls. It can be a little tricky to switch your thinking from the method-based approach of languages like Java to a resource-based API. In general, everything in the API is a “thing.” For resources like users, patients, encounters, locations, etc. it’s fairly obvious that each thing is a resource. When you want to take an action (like resetting a password), it’s tempting to add a method name (i.e., action) like `/password/forgot`; however, that’s not the RESTful approach. In REST, we turn these actions (verbs) into resources (nouns) using [reification](https://www.thoughtworks.com/insights/blog/rest-api-design-resource-modeling). In this use case, we could make a resource like a `PasswordResetRequest` (e.g., `/ws/rest/v1/passwordresetrequest`), where you would POST a password request request with appropriate details.

> [@harisu](#):
>
> I Extract the email address from the request,.

We would probably want to support a request by username or email address.

> [@harisu](#):
>
> if the email does not exist i send a custom Mail message telling the user that the address was not found and that the user should contact the administrator. with the email having information on how to contact Administrator or ask for help.

For security, it is best practice not to “leak” information about users in this manner. For example, with your proposed approach, an anonymous attacker could send password reset requests with random usernames and, based on the response, infer which usernames existed in the system. Basically, any response to a non-authenticated request should be the same regardless of whether or not the user exists.

So, for this use case, the response to an _anonymous_ POST to `/passwordresetrequest` would always be a HTTP `200 OK` with a “request received” or “Check your email for further instructions” response, regardless of whether or not the username or email exists in the system. If the POST is authenticated (i.e., an admin… see comment below), then you could return a status (success or failure).

> [@harisu](#):
>
> I Then Create a Mail message send it to the user with provided email and as a link /password/reset?token={$token\_generated\_hashed) to be used for reseting. The content of the mail which will have the expiry time which i suggest 30 minutes from time of innitialization of the reset email process.

The link will probably need to be configurable and can start out with our default password reset page (and obviously would need to include the reset token as you suggest). It’s worth noting that the code responding to the link (the web page request) is not going to be performing the password reset itself; rather, it is going to be invoking the REST API to perform the password reset. While we will want to create a password reset page for the Reference Application, different distributions will likely have their own password reset page and will depend on having the REST API to perform the actual reset (e.g., perform a GET to `/passwordresetrequest/{token}` and, if that succeeds, then POST a new password).

> [@harisu](#):
>
> I get the token which would be a hidden field, user\_id, new Password from the request check again if the token is valid then i call the reset method on the user and reset the password for that user . I Delete the reset\_token.

We should not be performing the password reset directly via web pages / servlets as in a simple web application; rather, the password reset process should be exposed via the REST API and the web page(s) will assist the user in using the REST API to reset their password.

So, the user’s browser makes a request to a URL like `/resetpassword?token={token}`, a servlet returns a web page (e.g., React app) that fetches the token from the page request and uses it to perform a `GET /passwordresetrequest/{token}`. If not successful, it tells the user their request is invalid and provides suggestions for what to do. If the GET is successful, then it prompts the user for their new password twice and, if both entries match, would POST the new password to `/resetpasswordrequest/{token}` and, based on the response, tell the user whether or not the password reset request was successful.

> [@harisu](#):
>
> Should the admin be able to trigger password reset via email for a user?. My own point of view. I think since the admin already has means of resetting a password(setting a temporal password) for a another user. Reseting via email should only be left to the user. Hence the botleneck on the admin is reduced. the admin should not trigger reseting for another user via email. Either way it is still possible everyone can do it if they have your email.

Yes. An admin should be able to trigger a password reset for a user. In this case, the username will already be known and used in the REST API call. If a user doesn’t already have an email address defined in the database, then the request would fail.

One of the goals of implementing this feature is to eliminate the current feature of setting a temporary password. In the best design, nobody except the user should ever know their password. Even an admin should not be able to set the user’s password (and thereby know it… even temporarily).

> [@wyclif](#):
>
> I think we don’t need a new table just to store the token and timestamp, we could use the user\_properties table to save them, have you considered looking into JWT?

Good thoughts. Some additional thoughts…

- We want one request per user. If two reset requests are made back-to-back, only the latest one is valid.
- If we use `user_properties`, do we clean up after ourselves (purge an unused reset token)? My initial impression is I wouldn’t want to leave a trail when password reset tokens are unused.

---

_[View the full topic](https://talk.openmrs.org/t/gsoc-2018-reset-password-via-email-project/18066)._
