@@ -5,6 +5,53 @@ breaking changes; those are called out explicitly.
55
66___
77
8+ ## 0.3.0 - 2026-06-20
9+
10+ Account shapes. CRUDAuth's identity and recovery are now read from your model instead of assumed
11+ to be email, so an app can log in by username, recover by phone, or hold no email at all, with the
12+ same flows and the same security. Plus pluggable delivery channels, a server-side provisioning
13+ seam, and a ten-recipe cookbook.
14+
15+ #### Added
16+ - ** Model-driven identity contract** (` make_auth_identity() ` + ` IdentityConfig ` ): the account
17+ * shape* is read from the model and the * intent* (login order, recovery factor) is declared in
18+ ` IdentityConfig ` , validated against the model at construction. Username-only accounts (no email)
19+ and non-email recovery become configuration, not forks.
20+ - ** Recovery-factor verification:** "verified" now means the contract's recovery factor is proven
21+ controlled, with email as the special case. A phone-recovery app verifies and resets over SMS,
22+ and ` current_user(verified=True) ` gates on the recovery factor. The verify and reset request
23+ endpoints are shaped to the factor, so a phone app drives them with ` {"phone": ...} ` .
24+ - ** Pluggable delivery channels** (` DeliveryChannel ` port, ` channels=[...] ` ): recovery tokens
25+ route over email, SMS, push, or any medium you implement; email is a built-in channel and every
26+ channel fires best-effort.
27+ - ** Provisioning seam** (` new_user_fields ` / ` new_user_defaults ` ): set app-owned columns on new
28+ users from a server-built context, on both ` /register ` and OAuth signup, gated so a client can't
29+ reach a privileged column.
30+ - A ** Cookbook** of ten from-scratch recipes (the three account shapes, OAuth, token APIs,
31+ existing-table onboarding, production), an Identity API reference page, and a refreshed
32+ architecture page.
33+
34+ #### Changed
35+ - ` current_user(verified=True) ` gates on ` recovery_verified ` (which equals ` email_verified ` for an
36+ email-recovery app) and raises at construction when the contract has no recovery factor.
37+ - The recovery ` verify ` / ` reset ` request bodies are generated for the recovery factor; the
38+ change-email endpoints mount only when the model has an ` email ` column.
39+ - A non-email recovery factor emits a ` {factor}_verified ` bookkeeping column (e.g. ` phone_verified ` )
40+ alongside the app-declared factor column.
41+
42+ #### Breaking changes
43+ - ** ` AuthHooks.on_after_email_verified ` → ` on_after_recovery_verified ` .** The verification hook is
44+ factor-neutral now; ` on_after_email_changed ` keeps its name (it proves a real email). Apps
45+ registering the old hook must rename it.
46+ - ** ` EmailFlowService.request_email_verification ` / ` confirm_email_verification ` →
47+ ` request_recovery_verification ` / ` confirm_recovery_verification ` ** , and the verify / reset
48+ request methods take a factor ` value ` instead of ` email ` . The service is constructed internally,
49+ so most apps are unaffected; direct callers must update.
50+ - ** Login resolves against the contract's ` login ` fields** , replacing the ` @ ` -in-identifier
51+ heuristic. The default (email + username) behaves the same.
52+
53+ ___
54+
855## 0.2.1 - 2026-06-15
956
1057#### Changed
0 commit comments