Commit fec2f0e
feat(audit): write login/logout rows to sys_audit_log and attribute the last_login_at update (#8244)
* feat(audit): write login/logout rows to sys_audit_log and attribute the last_login_at update (#8144)
sys_audit_log.action declares `login` and `logout`, the shipped `auth_events`
list view filters on them, and two System Overview widgets chart them — but
nothing ever wrote either row: the audit writers subscribe to the ObjectQL CRUD
lifecycle, so create/update/delete/restore were the only actions that could
materialize. The whole trace a sign-in left behind was an unattributed
`update sys_user` row (user_id null) diffing last_login_at.
- plugin-audit registers the `audit` service — the ledger's ingress for events
that are not CRUD. The row shape stays owned by plugin-audit; the caller hands
over an EVENT with a closed `login | logout` union, which is the only
structural protection available on an object whose action enum nothing
validates in either direction (#8203).
- plugin-auth emits from better-auth's session lifecycle hooks:
session.create.after => login (covers every sign-in method, not just
/sign-in/email), session.delete.after under /sign-out => logout. Revokes, bans,
erasure and expired-row collection are deliberately NOT logout — they already
carry their cause on the ADR-0069 D4 tombstone, and naming them logout would be
a wrong record rather than a vague one.
- stampLastLogin now carries attributedUserId (#4586), so the last_login_at diff
row names the person who signed in. Attributed rather than excluded: the write
still authorizes as the system, and suppressing it would delete the
last_login_ip trail repo-wide.
Neither package depends on the other; a stack without plugin-audit writes no auth
rows, exactly as before.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PEVB6w7D7uCszR9Mw1BL73
* test(dogfood): read the auth_events filter from the running registry (#8144)
#8200 retired `permission_change` / `export` from the action enum and narrowed
the `auth_events` view in the same PR. A hard-coded copy of the old filter kept
querying a value nothing can hold while still reporting success — the view has
exactly the shape that hides it, since the login rows alone satisfy the
assertion. Read the shipped filter instead, so the test tracks the view.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PEVB6w7D7uCszR9Mw1BL73
* test(plugin-auth): type the audit sink spy so its call log is a real tuple (#8144)
`vi.fn(async () => undefined)` types `mock.calls` as `[][]` — a zero-length
tuple — so every `calls[0][0]` in this file reached past the end of a tuple the
type system believed was empty (TS2493 x3), and the dereference that followed
was `possibly undefined` (TS18048 x3). Reading the argument back is the entire
point of these cases, so the fix is to declare what the spy receives rather than
to soften the read: the spy's implementation now names its parameter, and the
call log is pulled through `recordedEvents` / `firstEvent`, which name the
"never called" case instead of letting it surface as a TypeError.
Pinning the element type to `AuthSessionAuditEventInput` also makes these
assertions type-check against the real event surface instead of `any`: a
renamed field now fails at compile time rather than quietly comparing
`undefined` to `undefined`. One `(c: any[])` map goes away with it.
Behaviour unchanged — 1113/1113 plugin-auth tests pass, same 20 cases.
Why now: #8225 lowered this package's TEST_DEBT ceiling 131 -> 111 after this
branch was cut, so these six errors stopped being slack and became a violation
in the merge queue. Measured at 117 against the merged tree, 111 after this
commit — exactly the ceiling, ledger untouched.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PEVB6w7D7uCszR9Mw1BL73
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 6500ebb commit fec2f0e
13 files changed
Lines changed: 1562 additions & 43 deletions
File tree
- .changeset
- packages
- plugins
- plugin-audit/src
- plugin-auth/src
- qa/dogfood/test
- scripts
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
14 | 14 | | |
15 | 15 | | |
16 | 16 | | |
| 17 | + | |
17 | 18 | | |
18 | 19 | | |
19 | 20 | | |
| |||
30 | 31 | | |
31 | 32 | | |
32 | 33 | | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
33 | 41 | | |
34 | 42 | | |
35 | 43 | | |
| |||
56 | 64 | | |
57 | 65 | | |
58 | 66 | | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
59 | 92 | | |
60 | 93 | | |
61 | 94 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
193 | 193 | | |
194 | 194 | | |
195 | 195 | | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
196 | 244 | | |
197 | 245 | | |
198 | 246 | | |
| |||
777 | 825 | | |
778 | 826 | | |
779 | 827 | | |
780 | | - | |
781 | | - | |
782 | | - | |
783 | | - | |
784 | | - | |
785 | | - | |
786 | | - | |
787 | | - | |
788 | | - | |
789 | | - | |
790 | | - | |
791 | | - | |
792 | | - | |
793 | | - | |
794 | | - | |
795 | | - | |
796 | | - | |
797 | | - | |
798 | | - | |
799 | | - | |
800 | | - | |
801 | | - | |
802 | | - | |
803 | | - | |
804 | | - | |
805 | | - | |
806 | | - | |
807 | | - | |
808 | | - | |
809 | | - | |
| 828 | + | |
| 829 | + | |
| 830 | + | |
| 831 | + | |
810 | 832 | | |
811 | 833 | | |
812 | 834 | | |
| |||
0 commit comments