# Lifecycle hooks

Subclass **`BaseUserManager`** and override async hooks to integrate email, analytics, or domain side effects. Default no-op implementations live on **`UserManagerHooks`**, which `BaseUserManager` inherits, so existing subclasses keep the same override points. Hooks are **best-effort** extension points: keep them fast; offload I/O to background tasks when needed.

!!! warning "Timing and enumeration-resistant hooks"
    `forgot_password`, verify-token requests, and duplicate registration handling use enumeration-resistant logic in the manager/controller layers. Hooks such as **`on_after_forgot_password`**, **`on_after_request_verify_token`**, and **`on_after_register_duplicate`** may perform I/O (e.g. sending email). Timing differences from real SMTP or HTTP calls can still leak information unless you delegate to a **queue or background worker**. See [Registration](registration.md).

## Hook reference

| Hook | When it runs | Typical use |
| ---- | ------------ | ----------- |
| `on_after_register(user, token)` | After a new user is persisted and a verification token exists | Send verification email, analytics |
| `on_after_register_duplicate(user)` | After registration detects an already-existing account before returning the generic register failure | Notify the existing account owner out-of-band; keep I/O off the request path |
| `on_after_login(user)` | After a successful login issues a session / tokens | Audit, last-login updates |
| `on_after_verify(user)` | After email verification succeeds | Welcome email, entitlement updates |
| `on_after_request_verify_token(user, token)` | After verify-token handling completes (`user` and `token` may be `None` for unknown or already-verified emails) | Resend verification email; **always** do equivalent async work whether `user` is `None` |
| `on_after_forgot_password(user, token)` | After forgot-password handling (`user` and `token` may be `None` when unknown email) | Send reset email; **always** do equivalent async work whether `user` is `None` (see manager docstring) |
| `on_after_reset_password(user)` | After password successfully changed | Notify user, revoke other sessions (strategies also invalidate) |
| `on_after_update(user, update_dict)` | After profile fields saved | Sync directory, re-index search |
| `on_before_delete(user)` | Before user deletion | Soft checks, cascade hints |
| `on_after_delete(user)` | After user removed (or soft-deleted per policy) | GDPR export cleanup, cache purge |
| `on_after_organization_invitation(invitation, token)` | After organization-admin invitation creation stores the token hash | Enqueue invitation email or another out-of-band delivery job; the raw token is only available in this hook and the returned issue object |

Exact signatures and default implementations live on **`UserManagerHooks`**, inherited by **`BaseUserManager`** — see [Manager API](../api/manager.md).

## Flow sketch (register → verify → reset)

```mermaid
sequenceDiagram
  participant API as HTTP controller
  participant M as BaseUserManager
  participant Hook as Your hooks
  API->>M: create / verify / reset
  M->>M: persist + tokens
  M->>Hook: on_after_register / on_after_verify / on_after_reset_password
  Hook-->>API: return
```

## Related

- [Extending](extending.md) — user model, factories, controllers.
- [Registration](registration.md) — verification and forgot-password semantics.
