Releases
v2.0.0
Compare
Sorry, something went wrong.
No results found
2.0.0 (2026-11-02)
⚠ BREAKING CHANGES
sso: SCIM tokens issued before the move to managed connections
no longer authenticate, since the legacy scim_provider table is dropped.
Every organization that provisions through SCIM must issue a new token from
the SSO settings page and paste it into its identity provider. The API also
needs a new SCIM_CREDENTIAL_HASH_SECRET (at least 32 characters, required
in production), the HMAC key directory tokens are stored under; rotating it
invalidates every issued token.
Features
admin: add accounts, organizations, audit, team and approvals screens (9ea6652 )
admin: add four-eyes approval of sensitive actions (e3bb4c3 )
admin: add plan overrides and staff notes to the account screens (58c3dc7 )
admin: add staff roles and permissions behind the admin routes (2cdab7e )
admin: add the back office app shell (77e5cdf )
admin: add the inbox home, the palette and private saved views (063280d )
admin: add the operations screen with requeue, heartbeats and stripe replay (945321a )
admin: announce every end of an impersonation (e375a26 )
admin: make admin writes atomic and require a step-up (402790d )
api: add behavioural security signals and a captcha hook (719c4b4 )
api: let instrumentation flush pending events on demand (eba6575 )
app: explain icons, truncated values and disabled controls with tooltips (7de1858 )
app: rebuild every screen on the sober tool direction (1001166 )
app: remove the admin screens and return to the back office after impersonation (47c3ef1 )
app: show a not-found page on unknown urls (8ce5373 )
consents: record when pre-login cookie consent is attached to an account (af3a9f3 )
cron: ping a heartbeat url around the sweep run (9b4aab8 )
ddd-kit: add map, flatmap, maperror, match and all to result (03a4a82 )
ddd-kit: add toresult, trymap and equals to option (4f76953 )
ddd-kit: add uuid parse and make uuidv7 monotonic (34ad911 )
ddd-kit: carry the transaction and collected events in one ambient scope (b519af4 )
ddd-kit: give domain events an id and compare value objects by json (8dbbc16 )
email: claim and settle queued mail by lease with a replayed dead state (e640cf9 )
outbox: add dead state and per handler delivery columns (4a82c3a )
outbox: claim events by lease and settle them per attempt (6c0c92d )
outbox: return the stored event id and document delivery bookkeeping (40770fb )
outbox: run handlers outside transactions with retry and a dead state (d3c6d26 )
sso: provision scim directories through managed connections (4db5983 )
sso: require reconnecting scim directories with managed tokens (efa4464 )
ui: replace the theme with the sober tool direction (1f28182 )
webhooks: claim and settle deliveries by lease with a replayed dead_letter (1dc2a63 )
webhooks: record who replays a webhook delivery (f2feafb )
Bug Fixes
account: show a wrong current password under the right field (95fa666 )
admin: close the approval, override and list gaps found in review (d0edd2e )
admin: close the four-eyes bypasses found in review (e66a0e5 )
admin: close the privilege gaps of the staff model (cf1c34e )
admin: close the production and reuse gaps of the back office shell (8785ec3 )
admin: close the replay, inbox and read failure gaps found in review (e37a96d )
admin: close the step-up and session gaps found in review (f3abfd8 )
admin: end impersonations when staff access is lost (968c882 )
admin: settle stripe verification, replay scope and saved view filters (8e62034 )
api-token: answer 400 to a scan payload that is not a list of entries (cc227cb )
api: attribute an org auto-deleted by scim deprovisioning to its owner (bbeef4a )
api: attribute system events to no user in the audit trail (8524710 )
api: close the review pass defects in errors, auth, limits and csrf (177c61b )
api: commit the public api name change and its event together (90c25cc )
api: keep a failed lease release from failing a committed digest flush (3ef56f2 )
api: keep the api running when the email worker's first drain fails (da2b873 )
api: keep the api running when the outbox dispatcher's first drain fails (90a9a3a )
api: record signup policy acceptance with the trusted-proxy client ip (6476584 )
api: scrub query params and emails from sentry exception text (dbaa8fb )
app: accept only a bare origin as the back office url and close phase k (a338583 )
app: close the defects found by the final review (baf6f8c )
app: fall back to the build mode when the sentry environment is blank (8f918e7 )
app: keep a page heading on admin detail pages while they load (1edee9b )
app: keep loaded data on failed refetches and share page states (23efcb7 )
app: keep status and code on api failures so 4xx stay out of telemetry (fb0081d )
app: keep the user menu initials in its accessible name (ad51923 )
app: stop reporting sso sign-in redirects as unexpected errors (95b5715 )
app: stop the app shell overflowing small viewports (c0c7ee0 )
app: surface silent failures and keep invitees through sign-up (c3aee61 )
app: tell the user when copying the backup codes fails (32893f2 )
auth: record the trusted-proxy ip on new sessions (5b9e8bf )
auth: show translated copy when sso sign-in fails (97f04fa )
billing: let better auth write stripe subscriptions (b7a83e6 )
billing: stop treating prototype names as valid plan tiers (43d3281 )
ci: fail the pre-push chain on api type errors (666e9f8 ), closes api#type-check
ddd-kit: keep watched list change tracking correct across re-adds (fe11cac )
docker: build on the latest published node 26 image (b9ab8d2 )
docker: prune with the turbo version the repo resolves (5f8ec0c )
drizzle: roll back a unit of work whose callback returns a failed result (4b3b0bd )
drizzle: stop reporting every aborted transaction to sentry (6352bb5 )
events: parse a stored api token expiry back into a date (d9aaaa9 )
notifications: stop a rate-limited preference save from toasting twice (d6bee8e )
organization: label the new owner picker in the transfer dialog (4734922 )
outbox: reconnect the listener with backoff and a keepalive (437b5ec )
policies: record the real client ip on policy acceptance (9e7cd14 )
public-api: audit profile name changes made through an api token (0e7e89d )
rgpd: accept imported base32 totp secrets on account deletion (ab5464b )
rgpd: ignore unconfirmed two-factor enrolments on account deletion (0e66ff5 )
rgpd: report totp secret decryption failures to telemetry (7ab08cc )
rgpd: verify totp with the rotated auth secrets (5f749da )
security: confirm copied recovery codes only after the clipboard write (5a09526 )
sso: keep scim connection writes consistent under concurrency (df6b7bd )
sso: let a new user finish their first sso sign-in (5ed0add )
sso: stop reporting rejected sso calls as unexpected failures (45dae25 )
ui: let the app name every label the shared primitives render (b456a84 )
ui: only confirm a copied value once the clipboard write succeeds (391032a )
webhooks: report a failing first drain instead of crashing the api (de3a699 )
webhooks: stop doubling the page padding on the webhooks settings page (ffed148 )
webhooks: stop exposing the previous secret cipher in responses (526955b )
Refactor
access-control: derive the owner grants from the app statement (a2a95d4 )
account: move the avatar upload mutation into its own hook (bfb65a4 )
admin-audit-log: narrow the metadata diff instead of casting it (cb49d40 )
admin-orgs: show a hyphen for an organization without a plan (2c8e4f6 )
admin-users: derive every platform role type from one schema (051653f )
admin: fold the staff forms into the back office app (99adf6b )
admin: read schema columns lazily in the admin stores (019d122 )
admin: report admin store failures once, as typed results (39e0bb9 )
api-token: carry unset token fields as options (c5f7ca2 )
api-token: keep the revoked reason nameable by the front (ac82455 )
api-token: look up the leaked token owner as an option (1543af1 )
api-token: map token rows through a mapper, not a cast (b561724 )
api-tokens: keep the token schema free of react and its labels in the form (0323327 )
api: attribute audit rows and notifications from one actor lookup (dc52f5a )
api: build every retention sweep route from one table pass (02ffda6 )
api: declare the csrf and auth rate-limit guards as tables (47fd98b )
api: declare the sso enforcement body once (5c8b407 )
api: map audit rows through a single record mapper (6c6df74 )
api: move the plan entitlements catalog to the shared kernel (7d32a4f )
api: name tests after their subject and drop duplicated notes (676eadd )
api: pass the email batch idempotency key as an option (1bd794d )
api: point both sso enforcement routes at the shared body (2ce3486 )
api: promote the api token port to the shared kernel (1b48f56 )
api: read org roles and api tokens through one lookup each (eaa9c9d )
api: read the ambient transaction in api-token, profile, quotas, rgpd, webhooks (f36bab1 )
api: read the ambient transaction in billing, consents, notifications, policies (62001ac )
api: read the ambient transaction in shared repositories (87299e0 )
api: report password policy violations as an option (14973c6 )
api: return failed results from units of work instead of throwing (6980c77 )
api: return the next retry instant as an option (0cce360 )
api: route worker and sweep transactions through the unit of work (44babdb )
api: shape store failures with one shared helper (4b597b4 )
api: share one harness across the database check scripts (b6e2f74 )
api: share the best-effort security event emit (a2b6897 )
api: share the retry delay curve between the outbox and email workers (335c28b )
api: stop workers in order under a global shutdown deadline (8da0b12 )
api: tidy shared kernel comments and dead fallbacks (3a8d5d0 )
api: trace every email queue write under its real statement (196a62e )
api: trace the sso enforcement update as its own query (107d163 )
api: write the sso enforcement flag through auth-queries (d18f044 )
app: decide nav entry visibility in one place (0fceb33 )
app: drop billing type re-exports nobody imports (824301d )
app: drop dash punctuation from shared auth, ui and notifications (1551853 )
app: extract the shared web foundation into a package (0f94c36 )
app: gate the org members and invitations queries on the org (243bbc4 )
app: give notification category labels one home (21ec4bd )
app: keep the sign-out shortcut hint and binding together (da0299b )
app: name the placeholder shown for an absent value once (4d92587 )
app: read api error fields through one guard (9666a4b )
app: read consent categories from the shared package (f1ae3f5 )
app: refresh the own session and other tabs through one hook (53024b8 )
app: replace dashes in shared comments and test names (1ba8c04 )
app: resolve a missing active organization in one place (b4d269f )
app: resolve request fallback copy from a catalog key (fc27d2a )
app: stop naming the broadcast channel factory like a hook (7a9fe34 )
app: tidy shared imports and platform admin checks (cddd57c )
app: type the current membership role as an org role (3b3d5b9 )
auth: run the better-auth hooks in the ambient unit of work (f46af3e )
auth: share the sign-in completion and token consumption steps (6715112 )
auth: share the totp settings between two-factor and account deletion (659da3a )
billing: derive subscription statuses from one list (2e96e99 )
billing: open the billing portal through a service and gateway (6aae8fa )
consents: carry optional consent metadata as options (92a3cb2 )
ddd-kit: flatten event collector add into guard clauses (4fb9b0a )
ddd-kit: let repositories declare their error type (7d38772 )
ddd-kit: name event handlers and deliver per handler (0d5cf09 )
developers: stack the event catalog with a flex gap (3502df1 )
drizzle: share the database url guard between both pools (7cc17f4 )
emails: build the digest subject once and name the package exports (a8e8939 )
events: declare api token revocation reasons once (b8d4389 )
i18n: replace em dashes in en and fr copy with plain punctuation (a47dba6 )
jitter: drop the process-clock retry helpers (5761271 )
legal: build policy docs from one helper and trim table markup (28cd92a )
organization: guard member roles instead of casting them (ce0cf94 )
outbox: run audit, webhook and notification fan-out as named handlers (7268902 )
outbox: share lease sql fragments and failure schedule (f024e29 )
policies: carry the acceptance ip as an option in the store port (1cf9d54 )
privacy: render the privacy card lists with the shared list rows (f2e5359 )
quotas: share the usage row filter across quota store reads (f4fae41 )
rgpd: load deletion state and purge user objects in one place (9e756ab )
rgpd: share the deletion dialog footer and flatten the preflight states (3a534c2 )
router: render pathless gates as bare outlets (07ae823 )
security: flatten passkey error branches and name the device label (672fb9e )
sso: narrow the provider tab value instead of casting it (6c39616 )
ui: add a compact initials avatar for organizations (c475738 )
ui: cover inline muted and mono text with primitives (7eb3ff6 )
ui: drop the prose margins paragraphs and lists had to cancel (b093f97 )
ui: give a list row one clickable content slot (932a4b7 )
ui: give command items a hint slot (3809d44 )
ui: let a checkbox field carry a label with inline links (a654b76 )
ui: pin the cookie banner through a bottom banner primitive (e7b4233 )
ui: render label and value pairs as a description list (cd891fd )
uow: join nested runs to the ambient transaction (aa7c1da )
uow: remove the transaction parameter from ports and repositories (c5a4439 )
uow: roll back a run that raised events nobody can persist (1914d19 )
uow: run better-auth transactions as their own outermost unit (f5b0764 )
uploads: check key ownership through one guard (d1a9d05 )
uploads: default the presign ttl bounds in the env schema (4282555 )
webhooks: drive delivery badges and filters from the status lookups (7585c3a )
webhooks: validate event types with one shared schema (6545545 )
Build
deps: load the drizzle env files with dotenv 18 (ca2ed2f )
deps: move @hookform/resolvers to 6 (003087b )
deps: move @sentry/vite-plugin to 11 (1c380f1 )
deps: move inwire to 4 (e2354ff )
deps: move sentry to v11 without letting it start collecting pii (3e2fc4d )
deps: move stripe to 23 (c2ea1d1 )
deps: move to node 26 lts, bun 1.4.4 and pnpm 12 (8c443c6 )
deps: move tsup to 9 (196a62d )
deps: pick up the latest hono and aws sdk patch releases (235e5ce )
deps: pick up the latest minor and patch releases (9b07bc6 )
deps: refresh every workspace to the newest in-range releases (c081d81 )
deps: run every vitest suite on vitest 5 (7c6e131 )
Documentation
api: bring the shared inventory and billing listing up to date (4ad8f5f )
claude: bring the seven claude.md files back to the as-built state (dbaa51a )
claude: drop the em dashes from the agent-facing guides (f23d8f8 )
claude: one guide per app and per package (143c52c )
document the lease model for email and webhook queues (b8718d4 )
drop the em dashes from every guide, inventory and roadmap (12ea3ce )
features: point the legal body selection at policies/bodies.ts (b4be41a )
outbox: document lease delivery, handler names and dead replay (6145f00 )
readme: correct the clone and deploy path (36a0dbe )
record the better-auth 1.7 move and the three remaining pins (babb176 )
record the october 2026 dependency refresh (9dbcbb3 )
refresh event totals and the list of what is left (bfb8a78 )
roadmap: add the openup resync phase and make every phase follow one shape (6b8476a ), closes #70
roadmap: add the standalone back office as phase k (7818e77 )
roadmap: mark the review pass delivered (1d3c944 )
roadmap: plan a front redesign from scratch before the review pass (1d729a1 )
roadmap: record the post phase k follow-ups and what stays open (f873f6e )
You can’t perform that action at this time.