What problem does this solve?
Members had no way to manage their own accounts. Every profile change and every password reset went through a person. That is friction for the member and unpaid support work for the client, and it scales exactly as badly as it sounds.
What constraints did it have to work inside?
The same site as the prayer hours rebuild, under the same security model. Anything touching credentials had to assume it would be attacked. It also had to work for members who are not technical and who get exactly one attempt at a form before deciding the website is broken and calling somebody.
What did I build?
A user dashboard plugin, written from scratch, exposing two AJAX endpoints. Both verify a nonce and both are restricted to authenticated sessions.
Profile saves update the core WordPress user fields through wp_update_user()
alongside custom location meta, so the built-in fields stay canonical rather than
being shadowed by a parallel set of meta values.
The password change verifies the current password with wp_check_password()
before anything else, enforces a length minimum, checks that the confirmation
matches, and updates through wp_set_password(). It then re-issues the auth
cookie and sends a transactional security email.
Every page load issues a fresh nonce, so the AJAX surface is CSRF-safe rather than relying on a token that outlives the page it was minted for.
Decisions
Re-issue the auth cookie after a password change. wp_set_password()
invalidates the current session as a side effect. So the default behaviour is
that a member successfully changes their password and is instantly thrown to the
login screen for their trouble.
It worked. It looks exactly like it broke. And that is the precise moment a non-technical user decides they did something wrong and stops trusting the form. Re-issuing the cookie keeps them signed in and lets them actually read the confirmation. Two extra lines, and it is the difference between a feature people use and a feature people report.
Verify the current password even though the session is already authenticated. An authenticated session proves someone logged in at some point, not that the person at the keyboard right now is the account holder. Asking for the current password is the difference between an unattended browser being an inconvenience and it being an account takeover.
A security email on change, not just a success message. The success message is only seen by whoever made the change. The email is seen by the account holder, which is what makes an unauthorized change visible to the person who would care.
Outcome
Members manage their own profiles and passwords now, which takes that work off the client entirely.
As with the rest of the work on this site, the measurable result is security posture rather than a usage chart: credential changes are verified, CSRF-safe, confirmed by email, and they no longer dump a member onto the login screen for successfully doing what they were asked to do. I do not have adoption numbers yet, and I would rather leave the space empty than fill it with a guess.
Stack
- PHP
- WordPress Plugin API
- AJAX
- Vanilla JavaScript
