docs: change password - #9
Merged
Merged
Conversation
New page for `POST /auth/password`, and moves the roadmap item from Planned to Shipped. Leads with why the endpoint asks for the current password, because that is the entire security story and it is not self-evident: a stolen access token already grants the account until it expires, and if it could also change the password it would grant the account permanently while locking the owner out of their own recovery. Explains the shared throttle rather than just stating it — one budget with step-up, because both verify the same secret and separate allowances would only widen the total. Same for the session sweep: which session survives, and that the one to keep comes from the caller's own verified token so it cannot be aimed at someone else's. The client section is honest that `lukk-nuxt` has no composable for this yet and shows the `useLukkFetch` call to use meanwhile. Also cross-links from password-reset (a signed-in user wants the other page), the configuration feature table, and the events table — `PasswordChanged` is deliberately distinct from Laravel's `PasswordReset`, since "your password was changed" and "your password was reset" mean different things to a reader and an unexpected one of either is how takeover gets noticed.
The page said the client had no composable and showed a `useLukkFetch` call — true when written, not any more (stsepelin/lukk-js#46). Documents the composable and keeps a `useLukkForm` example, since the 422 validation bag is the thing most callers actually need to wire up. Two corrections from the security review of the server side: A success releases the `login` counter as well as `confirm`. Without that, a user who was being brute-forced, noticed, and changed their password stayed locked out of login everywhere else — the page now says so, because "changing your password fixes it" is exactly what a reader would otherwise assume. The session sweep is not unconditional: a token carrying no `fid` identifies no session to preserve, so every session is revoked rather than none. The page described only the common case.
A second call while one is in flight rejects with 409 and sends nothing. Worth documenting rather than leaving as an implementation detail, because the reason is not obvious: the second request would carry a `current_password` the first has already replaced, so it reads as a wrong password and spends one of the account's consecutive-failure attempts.
My change-password example was wrong. It showed `form.post('/password')` for
mapping a 422 onto fields, but `useLukkForm` submits through `useLukkFetch`,
which resolves against `apiBaseURL` — the app's API base (`api.target`, or the
proxy mount in BFF mode), not lukk's auth base. So the call would have reached
the reader's own `/password` route, or 404'd, and never `POST /auth/password`.
Replaced with the pattern that works: catch the `LukkError` and read its
`errors` bag, which is what the composable rejects with anyway.
The root cause was upstream of my mistake — `use-lukk-form.md` never said which
base its URLs resolve against, and two of its examples (`/register`,
`/password`) read exactly like lukk auth endpoints. It now states the split
before any example uses a URL: useLukkForm and useLukkFetch are for endpoints
you own; lukk's are reached through the composables, which hold the right base.
Both examples now say so inline.
I added the table row and not the copyable snippet beside it, so the one thing a reader actually pastes was missing the only default-ON flag in the block — the one case where you need the key precisely because you might want to turn it off. Also reordered the table row to sit after `lockout`, matching both the snippet and config/lukk.php. It had been appended at the end, so the two lists read in different orders despite listing the same keys. Checked programmatically rather than by eye: the snippet and the table now hold the same keys in the same order, and that order matches the config file.
I added it as a row in the table introduced as "lukk also dispatches standard Laravel auth events" — which it isn't. Every other `Lukk\Events\*` class on the page has its own subsection under Security events; this was the one exception, and it made the taxonomy say something false about where the class comes from. Now a `### PasswordChanged` subsection alongside the others, with a listener example matching their format. The contrast with `Illuminate\Auth\Events\ PasswordReset` is kept and now reads as an explicit cross-reference rather than as two adjacent rows the reader has to tell apart — which was the only reason the row was there. Verified all six package events are documented and none is left in the framework table.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Documents
POST /auth/passwordfrom stsepelin/lukk#27, and moves the roadmap item from Planned to Shipped.Leads with why the endpoint asks for the current password, since that's the entire security story and isn't self-evident — a stolen token already grants the account until it expires; if it could change the password it would grant the account permanently.
Explains the shared throttle and the session sweep rather than just stating them, and is honest that
lukk-nuxthas no composable yet, showing theuseLukkFetchcall to use meanwhile.Cross-linked from password-reset, the configuration feature table, and the events table.
pnpm docs:buildpasses withignoreDeadLinks: false.Greptile Summary
Documents the authenticated change-password endpoint and moves the feature into the shipped roadmap.
Confidence Score: 3/5
The documentation should not merge until the Nuxt example uses the correct authentication transport and accurately explains validation-error handling.
The server documentation is broadly consistent, but copying the client example directs the request through the application API base rather than the lukk auth endpoint, and its direct fetch call cannot provide the promised automatic field-error mapping.
Files Needing Attention: docs/change-password.md, docs/configuration.md, docs/events.md
Important Files Changed
Prompt To Fix All With AI
Reviews (1): Last reviewed commit: "docs: change password" | Re-trigger Greptile