Email workspacePassword reset contract
Purpose: deliver a requested password-reset link and its instructions. Referenced API implementation: App\Mail\passwordReset; baseline view resources/views/emails/users/passwordReset.blade.php; caller AuthController::sendresetlink. This Mailable is queued by the existing caller.
Suggested subject: Password Reset. This preserves the current subject.
Suggested preheader: Reset your Built password. This link is single use and expires in 5 minutes.
Portable placeholder contract
| Token | Existing Laravel source / derivation | Requirement |
|---|---|---|
| {{logo_url}} | Existing Built app_name PNG | Optional deployment override; concrete project HTTPS logo is the default |
| {{preheader}} | Suggested fixed copy above | Required escaped text; five minutes is the existing copy, not a new configurable field |
| {{reset_url}} | $link supplied to passwordReset's constructor and passed into the Blade view | Required complete trusted URL; same value for button and visible fallback |
The caller builds $link as config('app.url') + '/confirmreset/' + encrypt($new_request->id). Preserve that complete URL. The portable name reset_url maps to the existing link field; it does not require renaming the PHP binding or creating another reset record. Unlike the new-device alert, this reset email has no user/name/device/geolocation inputs. Do not add those tokens.
Required content and states
- Enter a new password.
- Confirm the new password.
- Click Submit.
- The link is valid for one use only and expires in 5 minutes.
- If the reset was not requested, disregard the email or contact the customer service department.
- Keep the visible fallback URL inside the email.
All instructions remain in the HTML and text alternative. The draft changes presentation and natural copy; it does not replace the steps with a link alone. It does not invent a support address or phone number absent from this view. The five-minute/single-use statements come from the existing body; expiry enforcement was not changed or runtime-audited.
The states are the normal request and a long fictional link. No expired-link email or new backend status is invented. Every preview action ends on the local design explanation.
Integration and uncertainty
The separately cataloged ResetPassword scaffold is apparently unused. ResetPassword and passwordReset differ in word order, not just case; there is no case-only class collision between them. ResetPassword references emails.users.resetpassword, while the referenced custom sender passwordReset uses emails.users.passwordReset. Verify the exact target class/view path and do not wire the unused scaffold as a second flow. This batch supplies one reset design for the referenced custom API workflow, not a second live sender.
ready/password-reset.txt and each populated state's .txt file provide text alternatives. Convert reset_url explicitly to the current $link Blade expression. Escape values and attributes, validate the complete URL against the configured app/approved hosts, and retain signed/encrypted parameters. Logo hosting/CID, provider limitations and progressive dark mode are covered in integration-notes.html. No production code or application behavior is changed here.
Approved compact refinement
The reset action and existing single-use/five-minute notice now precede the three preserved reset steps. All instructions, the unsolicited-request notice and fallback URL remain inside HTML/text alternatives. The copy is transactional and no longer includes a friendly team sign-off or product-marketing footer. Body text stays 16px; supporting fallback instructions use 14px. No action destination or expiry behavior changes.