# Wachtwoordherstel

Wachtwoordherstel is een flow in twee stappen: `forgot-password` mailt het contact een herstellink, `reset-password` verbruikt het token uit die link. Beide vereisen de `contacts:write` scope (`customers:write` geaccepteerd) en geen van beide vereist `X-Customer-Token`. Beide dragen de extra rate limit voor credential-endpoints van 10 requests per minuut per IP.

Reset-tokens zijn eenmalig te gebruiken, worden gehasht opgeslagen (SHA-256), en verlopen 60 minuten na uitgifte. De herstellink verwijst naar de geconfigureerde storefront-URL van je winkel in het formaat `{storefront_url}/account/reset?token=...&email=...`; je storefront-pagina op dat pad moet beide query-parameters uitlezen en ze naar `reset-password` sturen. Als de winkel geen `storefront_url` geconfigureerd heeft, wordt er geen e-mail verstuurd (het endpoint retourneert alsnog 202).

## POST /v1/api/contacts/forgot-password

Ook aangeboden op `/v1/api/customers/forgot-password` voor bestaande integraties; identiek request en response.

Vraag een wachtwoordherstel-e-mail aan. Retourneert altijd 202 met dezelfde body, ongeacht of er een account met dat e-mailadres bestaat, zodat het endpoint niet gebruikt kan worden om accounts te enumereren.

### Body-parameters

| Naam | Type | Verplicht | Beschrijving |
| --- | --- | --- | --- |
| `email` | string | Ja | Geldig e-mailadres. Server-side naar lowercase omgezet vóór de lookup. |

```bash title="Request"
curl -X POST https://api.borkol.com/v1/api/contacts/forgot-password \
  -H "Authorization: Bearer {api_key}" \
  -H "Content-Type: application/json" \
  -d '{"email":"jane@example.com"}'
```

Status: `202 Accepted`.

```json title="Response"
{
  "message": "If the account exists, a reset link has been sent."
}
```

### Fouten

- `422` wanneer `email` ontbreekt of geen geldig e-mailadres is.
- `429` wanneer de limiet van 10 requests per minuut per IP is overschreden.

## POST /v1/api/contacts/reset-password

Ook aangeboden op `/v1/api/customers/reset-password` voor bestaande integraties; identiek request en response.

Voltooi een wachtwoordherstel met het token uit de gemailde link. Bij succes zet dit het nieuwe wachtwoord, markeert het het account als niet-gast, zet het `email_verified_at` als dat nog niet gezet was, en trekt het alle sessietokens van het contact in (elk apparaat wordt uitgelogd). Een ongeldig of verlopen token laat het account onaangeroerd.

### Body-parameters

| Naam | Type | Verplicht | Beschrijving |
| --- | --- | --- | --- |
| `email` | string | Ja | Geldig e-mailadres. Moet matchen met het account waarvoor het token is uitgegeven. |
| `token` | string | Ja | Het plain token uit de `token` query-parameter van de herstellink. |
| `password` | string | Ja | Het nieuwe wachtwoord. Minimaal 8 tekens. |

```bash title="Request"
curl -X POST https://api.borkol.com/v1/api/contacts/reset-password \
  -H "Authorization: Bearer {api_key}" \
  -H "Content-Type: application/json" \
  -d '{"email":"jane@example.com","token":"kJ8s...64-char-token...Qw2","password":"new-s3cret-pass"}'
```

Status: `200 OK`.

```json title="Response"
{
  "message": "Password updated."
}
```

### Fouten

- `422` met `errors.token` `["This reset link is invalid or expired."]` voor een onbekend e-mailadres, een verkeerd token, een al gebruikt token, of een token ouder dan 60 minuten.
- `422` bij veldvalidatiefouten (ontbrekende velden, wachtwoord korter dan 8 tekens).
- `429` wanneer de limiet van 10 requests per minuut per IP is overschreden.
