From what I’ve observed, OpenEMR doesn’t ship with a way for users to change or reset their own passwords. If a therapist forgets theirs, an admin has to dig into the database. I built a small drop-in module to solve this for my own deployments and open-sourced it under GPL-3.0 in case anyone else can use it.
It’s three files that go into your public_html directory. No existing OpenEMR files are modified. Two flows:
Password change. The user knows their current password and wants to update it. Username + current password, verify, set new password.
Email-link reset. The user forgot their password or it’s their first login. They enter the email on their user record, receive a one-time reset link, click it, set a new password.
The four database tables it uses are created automatically on first use. No migrations to run.
About email changes. The package ships with email field locked in the UI ($lockEmail = true in change_password.php, around line 203). My own deployments use the email field as an identity key downstream, so I keep it admin-only. If your OpenEMR install doesn’t have that coupling, flip the flag to false and users can update their email during the password-change flow. The backend validation, uniqueness check, and update SQL are already wired up. The email-link reset flow is always locked regardless because the email is the identity proof in that flow; you can’t change identity in the same transaction that’s proving it.
Security
Password policy: 8+ characters, mixed case, digit, special char
Reuse prevention: cannot reuse the current password or the last 4 passwords
One-time tokens stored as SHA-256 hashes; plaintext is never persisted
Tested on OpenEMR 7.0.2 Patch 3. Should work across 7.x; uses only stable APIs (sqlQuery, sqlStatement, AuthHash, $GLOBALS).
PHP 8.0+
No Composer dependencies
Install
cd /path/to/openemr/public_html
unzip /path/to/emrflow-openemr-password-reset.zip -o
# Done. Navigate to https://your-domain.com/change_password.php
The email-link flow requires SMTP configured in Admin → Config → Notifications → Email Notification Settings. The current-password change flow works without email.
Full README, install/uninstall instructions, and database table reference are in the repo. PRs and issues welcome; happy to take suggestions for adjacent OpenEMR versions.
This sounds really promising, a much needed missing piece of the puzzle.
However you say it has only been tested on OpenEMR 7.0.2 Patch 3 which was released in November 2024, and that it “Should work across 7.x” but we are now well into OpenEMR 8.0 with 8.1 due soon. I would be interested in testing this if there was compatibility with the current state of OpenEMR.
Thanks Pete, that’s exactly the right question to ask. You’re right that 7.0.2p3 is just where I’ve been running it in production, so that’s all I could honestly claim it was tested against.
I did go through the code against the 8.0 source and the pieces it leans on (the auth/hashing classes, the core DB helpers, the users_secure table) all look unchanged, so I’m optimistic. But “looks fine in the source” isn’t the same as “actually ran it,” so I’m spinning up a clean OpenEMR 8.0 install now to put it through its paces properly. Once I’ve confirmed the change-password and reset-token flows both work end to end, I’ll update the README with a tested-on note for 8.0.
I’ll report back here when that’s done. If you happen to test it on your end in the meantime, I’d love to hear how it goes, and I can turn around any fixes quickly.
@PeteBoyd I went ahead and tested it on both. On a clean OpenEMR 8.0.0 patch 3, and again on the current 8.1 development build, every flow passes: the username plus current-password change, the email-link reset, the password policy, reuse prevention against the last five passwords, and the automatic table creation on first use. I also confirmed the password actually re-authenticates afterward, and that the email field stays locked in the reset flow so the identity email can’t be changed in the same step that proves it.
The reason it holds up is that the module only leans on the stable parts of OpenEMR’s core: AuthHash for hashing and verification, sqlQuery and sqlStatement for the database, and the users_secure history columns. None of that changed between 7.0.2, 8.0, and 8.1, so the drop-in install behaves the same. The only caveat worth noting is that 8.1 is still a development build, so treat that result as a strong signal rather than a guarantee on the eventual GA release.
I’ve updated the README to note 8.0.0 patch 3 as tested and 8.1 dev as verified.