Skip to content

Implement a reset password flow.#3041

Open
drgrice1 wants to merge 1 commit into
openwebwork:WeBWorK-2.21from
drgrice1:password-reset-flow
Open

Implement a reset password flow.#3041
drgrice1 wants to merge 1 commit into
openwebwork:WeBWorK-2.21from
drgrice1:password-reset-flow

Conversation

@drgrice1

@drgrice1 drgrice1 commented Jul 7, 2026

Copy link
Copy Markdown
Member

In order to enable the reset password flow, the course environment variable $password_reset_sender_email must be set. This can be set per course in the course.conf files.

If that is set, then a "Forgot Password" link will appear on the course login page to the right of the "Continue" button. When that link is used a "Forgot Password" page is shown. The user will then need to enter their username and click "Request Password Reset". Then an email is sent to the user (assuming the user has a valid email address in the database) containing a "Reset Password" link. A single use token is embeded in the link, and that token expires in 15 minutes. When that link is used a "Reset Password" page is shown. On that page the user must enter a new password, and confirm it by entering it again, and then click "Reset Password". If the token in the link is valid, then the user's password is changed.

If two factor authentication is enabled, then when the reset link that is emailed to the user is used, the user must enter a one-time security code as well as a new password in order to reset their password. Also, if the user has not yet set up two factor authentication for their account, then password reset is not allowed for the user.

All requests to reset a user's password and the success or failure when using the reset password link are logged to the login log.

This is to address issue #2976.

Remember to upgrade the admin database and the course used when testing this.

@drgrice1 drgrice1 force-pushed the password-reset-flow branch 3 times, most recently from a1633c4 to 1d59448 Compare July 7, 2026 21:47
@taniwallach

Copy link
Copy Markdown
Member

I would recommend that requests to reset the password and successful resets be logged to the login.log file.

Maybe when a user has a MFA secret saved in the course, a password change should depend on providing an valid OTP result. That would make the system more secure against possibly malicious use.

@drgrice1

drgrice1 commented Jul 8, 2026

Copy link
Copy Markdown
Member Author

I would recommend that requests to reset the password and successful resets be logged to the login.log file.

I will add this I suppose.

Maybe when a user has a MFA secret saved in the course, a password change should depend on providing an valid OTP result. That would make the system more secure against possibly malicious use.

This is true, and I will see about implementing this. This may take some effort though, and may need to wait.

@taniwallach

Copy link
Copy Markdown
Member

Don;t hold things back about the OTP side, it would be nice to have, as it protects from an email compromise becoming a compromise of webwork. The logging is in my opinion more important, in case issues come up with claims of account compromise via the password reset system, it provides some data on when it occurred.

@drgrice1 drgrice1 force-pushed the password-reset-flow branch from 1d59448 to ea9ab05 Compare July 8, 2026 17:32
@drgrice1

drgrice1 commented Jul 8, 2026

Copy link
Copy Markdown
Member Author

@taniwallach: I have added the two factor authentication requirement when it is enabled, and the login log logging.

@drgrice1 drgrice1 force-pushed the password-reset-flow branch from ea9ab05 to 8fa10b3 Compare July 11, 2026 11:07
Comment thread lib/WeBWorK/ContentGenerator/ForgotPassword.pm Outdated
->subject($c->maketext('Reset Password'))
->text_body($c->maketext(
"Use the following link to reset your password: [_1]\n\nThat link will only be valid until [_2].",
$resetURL, $c->formatDateTime($password->reset_token_expiration)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My testing server can't send emails, so for now I am just reading code more than actual testing. Can you confirm that the time which is presented here is either in the user's local time locale, or the course's? If it is the server's time, that could be confusing. There are some servers (notably RS) that are in one time zone, but users actually do all their business in a different one.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be displayed in the same time zone that all other times are displayed in webwork2 which would be server time. Perhaps this could be configured to show the time zone of the server, but there is no way that it can be displayed in the users time zone. The server would not know that.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about it using the course's time zone? That is, the time zone that might be specified in the course.conf file for the course in question?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the RS instance, the server is at UTC time, with users all over the place. It might just be better to say "15 minutes from now" and not try to give the exact time.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, that is what I meant. The time will be in the course's time zone.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The formatDateTime method in the the WeBWorK::ContentGenerator module which is used here always defaults to the timezone and language of the course.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem with saying "now" in an email is that "now" is relative. At the time that the user reads the email, 15 minutes from now may be 30 minutes ago.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I change it to say That link will only be valid for 15 minutes (until July 11, 2026, 7:18:31 PM CDT). So now the 15 minute time limit is included as well as the time of expiration including the time zone.

Comment thread lib/WeBWorK/ContentGenerator/ResetPassword.pm Outdated
@drgrice1 drgrice1 force-pushed the password-reset-flow branch from 8fa10b3 to 0b4f837 Compare July 11, 2026 23:36
@Alex-Jordan

Copy link
Copy Markdown
Contributor

My testing server can't actually send emails, and for now I'd rather not put time into setting that up. I did read through the code. And I loaded the branch and see the link, and I see the page with the message after you attempt to start the reset process. That all looks good. I am inclined to just approve this now and I will remember to try everything out once this is in production. Are there any concerns with that?

@drgrice1

Copy link
Copy Markdown
Member Author

That is fine. We can always hotfix if needed!

@Alex-Jordan

Copy link
Copy Markdown
Contributor

OK, I marked it approved!

Thanks for this. It will reduce a fair amount of email traffic I get from faculty asking for password resets.

In order to enable the reset password flow, the course environment
variable `$password_reset_sender_email` must be set. This can be set per
course in the `course.conf` files.

If that is set, then a "Forgot Password" link will appear on the course
login page to the right of the "Continue" button. When that link is used
a "Forgot Password" page is shown. The user will then need to enter
their username and click "Request Password Reset". Then an email is sent
to the user (assuming the user has a valid email address in the
database) containing a "Reset Password" link. A single use token is
embedded in the link, and that token expires in 15 minutes. When that
link is used a "Reset Password" page is shown. On that page the user
must enter a new password, and confirm it by entering it again, and then
click "Reset Password".  If the token in the link is valid, then the
user's password is changed.

If two factor authentication is enabled, then when the reset link that
is emailed to the user is used, the user must enter a one-time security
code as well as a new password in order to reset their password. Also,
if the user has not yet set up two factor authentication for their
account, then password reset is not allowed for the user.

All requests to reset a user's password and the success or failure when
using the reset password link are logged to the login log.

This is to address issue openwebwork#2976.
@drgrice1 drgrice1 force-pushed the password-reset-flow branch from 0b4f837 to db8bfe7 Compare July 12, 2026 00:04
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 this pull request may close these issues.

3 participants