Skip to content

feat(auth): last-login audit fields + ADR-0069 status (P1 completion)#2570

Merged
os-zhuang merged 1 commit into
mainfrom
claude/adr-0069-p1-last-login-audit
Jul 4, 2026
Merged

feat(auth): last-login audit fields + ADR-0069 status (P1 completion)#2570
os-zhuang merged 1 commit into
mainfrom
claude/adr-0069-p1-last-login-audit

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

概述

任务是「评估现有代码,不要重复开发」——评估结论:ADR-0069 P1(密码策略 D1 / 账号锁定 D2 / 强制 MFA D3)+ 大部分 P2 早已实现并合并(auth-manager.ts 里 assertPasswordComplexity/assertPasswordNotReused/HIBP 插件/assertAccountNotLocked/recordSignInOutcome/computeAuthGateMFA_REQUIRED,settings manifest 字段全齐),只是 ADR 文档还标 Proposed

本 PR 不重复开发已有功能,只补上评估中发现的唯一 P1 缺口 + 纠正文档滞后。

变更

D7 唯一缺口:last-login 审计字段

  • platform-objects:sys_user 新增 last_login_at(datetime)+ last_login_ip(text, 45 = IPv6 最大长度),readonly / Admin 分组。
  • plugin-auth:AuthManager.stampLastLogin 在每次成功 /sign-in/email 的 after-hook 里写入,独立于锁定阈值(recordSignInOutcome 在锁定关闭时 no-op,审计不应受此影响)。IP 取自可信转发头(x-forwarded-forcf-connecting-ipx-real-ip,与 D5 IP 白名单中间件同优先级),截断到列宽。best-effort:绝不把有效登录变成错误。
  • 4 个单测(Date 时间戳 + IP、锁定关闭时仍写、IP 超长截断、引擎失败不抛)。

文档纠偏

  • ADR-0069 状态 ProposedAccepted — P1 + P2 implemented,新增「实现状态矩阵」逐条标注已落地 vs 剩余 P2 缺口(per-org sys_organization.allowed_ip_ranges、多节点共享限流 store)。

验证

  • 单测:plugin-auth 5 文件、platform-objects 2 文件全绿。
  • 真实 app 实测(showcase --fresh :39620,Playwright,见 PR 讨论附图):
    • last_login_at 登录后落库、last_login_ipx-forwarded-for 取到 198.51.100.22(本 PR 改动)
    • 现有 D1:弱密码被 PASSWORD_POLICY_VIOLATION 拒、强密码通过
    • 现有 D2:失败 3 次后锁定,正确密码也返回 403 ACCOUNT_LOCKED

剩余(不在本 PR,建议后续)

  • P2 缺口:per-org / per-user allowed_ip_ranges 记录级字段(现仅全局设置);限流共享 store(现为内存,多节点 gap)。
  • 这两项已在 ADR-0069 实现状态矩阵中标注。

关联

🤖 Generated with Claude Code

https://claude.ai/code/session_014y5kiH3aPLWtRRRGcVrXcT


Generated by Claude Code

…69 D7)

Fills the one missing ADR-0069 D7 identity field pair — the rest of P1
(complexity/history/expiry/HIBP/lockout/enforced-MFA) was already
implemented (this task was evaluate-first, don't re-develop).

- platform-objects: add sys_user.last_login_at (datetime) +
  last_login_ip (text, 45 = IPv6 max), both readonly/Admin group.
- plugin-auth: AuthManager.stampLastLogin stamps them on every
  successful /sign-in/email via the after-hook, independent of the
  lockout threshold (which gates recordSignInOutcome). IP from the
  trusted forwarded headers (x-forwarded-for → cf-connecting-ip →
  x-real-ip), capped to the column width. Best-effort: never turns a
  valid login into an error.
- 4 unit tests (Date stamp + IP, runs when lockout off, IP cap, never
  throws on engine failure).
- ADR-0069 status Proposed → Accepted (P1/P2 implemented) with an
  implementation-status matrix documenting what is landed and the
  remaining P2 gaps (per-org sys_organization.allowed_ip_ranges,
  shared-store rate limiting for multi-node).

Verified: plugin-auth 5 files / platform-objects 2 files green; live
showcase run shows last_login_at/ip populated after sign-in (IP from
x-forwarded-for), and the pre-existing D1 complexity + D2 lockout
enforced end-to-end when enabled via settings.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014y5kiH3aPLWtRRRGcVrXcT
@vercel

vercel Bot commented Jul 4, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
spec Ready Ready Preview, Comment Jul 4, 2026 9:28am

Request Review

@github-actions github-actions Bot added documentation Improvements or additions to documentation tests tooling size/m labels Jul 4, 2026
@github-actions

github-actions Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 2 package(s): @objectstack/platform-objects, @objectstack/plugin-auth.

11 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/concepts/implementation-status.mdx (via @objectstack/plugin-auth)
  • content/docs/concepts/packages.mdx (via @objectstack/platform-objects, @objectstack/plugin-auth)
  • content/docs/concepts/setup-app.mdx (via @objectstack/platform-objects)
  • content/docs/getting-started/cli.mdx (via @objectstack/plugin-auth)
  • content/docs/guides/auth-sso.mdx (via @objectstack/plugin-auth)
  • content/docs/guides/authentication.mdx (via @objectstack/plugin-auth)
  • content/docs/guides/kernel-services.mdx (via @objectstack/plugin-auth)
  • content/docs/guides/packages.mdx (via @objectstack/platform-objects, @objectstack/plugin-auth)
  • content/docs/guides/plugins.mdx (via @objectstack/plugin-auth)
  • content/docs/guides/production-readiness.mdx (via @objectstack/plugin-auth)
  • content/docs/releases/v9.mdx (via @objectstack/plugin-auth)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

@os-zhuang
os-zhuang marked this pull request as ready for review July 4, 2026 10:25
@os-zhuang
os-zhuang merged commit 07f055c into main Jul 4, 2026
16 checks passed
@os-zhuang
os-zhuang deleted the claude/adr-0069-p1-last-login-audit branch July 4, 2026 10:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants