Forgot password
This pack adds password-recovery endpoints. A user who forgets their password requests a reset link by email through a public endpoint, then submits a new password with the token carried in that link.
- The request endpoint returns the same response whether or not the email is registered, so it cannot be used to discover which addresses have accounts.
- Both the reset email and the request endpoint are throttled against abuse.
- A branded, MJML reset-password email that links to your frontend with the token.
This pack extends the auth pack's User model and reuses its transactional email setup. Apply the auth pack first.
Apply the forgot password pack with Flow. Start a new session in your selected coding agent and execute the following slash command inside it.
After applying, Flow will make the following changes to your app.
-
Land the backend as shipped, from the password-reset table and the User mixin through the validators, the controller, the reset mailer and email template.
-
Add the request and reset endpoints to your public API group.
-
Run the tests, then drive the endpoints and show you the result.
Apply the forgot password pack to your API by hand by working through the steps below in order. It builds on the auth pack, adding two public endpoints: one that emails a reset link, and one that sets a new password from the token carried in that link.
-
Confirm your auth foundation
This pack builds on the auth pack. Make sure your API already has it before continuing.
- Your User model composes
withAuthFinder(...)andwithManagedEmail(), and@adonisplus/personais installed. - The transactional email setup is wired: the
emailLayoutcomponent and thebrandNamemail global exist, mail is configured, andappFrontendUrlis exposed fromconfig/app.ts(fromFRONTEND_URL). formsThrottleis defined instart/limiter.ts, and your public/api/v1group exists.
- Your User model composes
Flow adapts the pack to your app, so the exact set of created and edited files depends on what you already have. This is the shape of an apply onto the API starter kit with the auth pack in place.
Configuration
The reset link is minted by the withManagedPassword() mixin on the User model, the mixin this pack adds beside auth's withManagedEmail(). It creates each reset token, hashes it, and stores it in a database table. Pass an options object to the mixin to change its defaults.
expiresIn
How long a reset link stays valid, as a number of seconds or a time expression. Defaults to 1 day.
table
The table reset tokens are read from and written to. Defaults to password_reset_tokens.
tokenSecretLength
The length of the random secret behind each token. Defaults to 40.
export default class User extends compose(
UserSchema,
withAuthFinder(hash),
withManagedEmail(),
withManagedPassword({ expiresIn: '1 hour' })
) {}
A request answers the same way for every email
The request action looks the user up but answers the same whether or not an account exists, so the flow cannot be used to discover which addresses are registered. The reset email is sent only when the account exists, and minting a token is throttled to one send a minute per address, so a burst of requests still delivers at most one message. The request route sits behind the formsThrottle limiter, which rate-limits the endpoint itself.
A reset link works once, then expires
Setting a new password verifies the token and updates the password in one step, then clears the account's remaining reset tokens, so any other outstanding link stops working. A link that is invalid or past its expiry is rejected and the password stays unchanged. Change how long a link stays valid with the mixin's expiresIn option above.
1.0.0
Initial release.