From b51dea6f521d6972c8694978b20d0624e80ad796 Mon Sep 17 00:00:00 2001 From: brother7 <7brother7@gmail.com> Date: Wed, 19 Aug 2026 16:55:05 +0800 Subject: [PATCH] docs(integration): record Square auth lifecycle merge --- .../adr-004-square-auth-lifecycle-boundary.md | 29 ++++++++++ .project-docs/10-decisions/decision-index.md | 1 + .project-docs/20-architecture/data-flow.md | 2 +- .../20-architecture/system-overview.md | 5 +- .project-docs/30-worklog/current-state.md | 8 +++ ...819-integrate-square-auth-client-2f7c9a.md | 45 +++++++++++++++ ...0260819-square-auth-proxy-client-8c4f2a.md | 57 ------------------- 7 files changed, 87 insertions(+), 60 deletions(-) create mode 100644 .project-docs/10-decisions/adr-004-square-auth-lifecycle-boundary.md create mode 100644 .project-docs/30-worklog/tasks/20260819-integrate-square-auth-client-2f7c9a.md delete mode 100644 .project-docs/30-worklog/tasks/20260819-square-auth-proxy-client-8c4f2a.md diff --git a/.project-docs/10-decisions/adr-004-square-auth-lifecycle-boundary.md b/.project-docs/10-decisions/adr-004-square-auth-lifecycle-boundary.md new file mode 100644 index 0000000..77429dc --- /dev/null +++ b/.project-docs/10-decisions/adr-004-square-auth-lifecycle-boundary.md @@ -0,0 +1,29 @@ +# ADR-004: Works Square Owns The Desktop Authentication Lifecycle Boundary + +## Status + +Accepted and implemented on 2026-08-19. + +## Context + +The desktop client obtained tokens from Works Square but refreshed them directly against the custom identity service with an embedded OAuth client secret. That mixed issuer/client boundary made rotation dependent on two independently configured clients and could turn an otherwise valid persisted session into `invalid_grant`, returning the user to the login page hours later. + +## Decision + +- Renderer sends authentication operations only to Electron Main. +- Electron Main owns access/refresh tokens, encrypted persistence, refresh rotation, terminal failure cleanup, and the seven-day inactivity policy. +- Desktop login, mobile login, refresh, and logout use fixed Works Square `/api/auth/*` endpoints. +- Works Square owns the confidential upstream OAuth client configuration and proxies the lifecycle to the identity service. +- The desktop bundle must not contain an OAuth client secret or call the custom identity service directly. + +## Consequences + +- The matching Works Square server endpoints must be deployed before this client is released. +- OAuth credential rotation or upstream endpoint changes are server-side configuration changes rather than desktop releases. +- A terminal refresh `400` or `401` still fails closed and clears the local session; transient failures preserve the established retry behavior. + +## Evidence + +- Source commit: `dc776ff` +- Integration merge: `f52c2c8` +- Feature verification: 2,190 client tests passed, typecheck passed, Vite build passed, and lint reported no errors. diff --git a/.project-docs/10-decisions/decision-index.md b/.project-docs/10-decisions/decision-index.md index 56c0ded..4b2ed03 100644 --- a/.project-docs/10-decisions/decision-index.md +++ b/.project-docs/10-decisions/decision-index.md @@ -7,6 +7,7 @@ | ADR-001 | AI 绘画采用 Workspace / Conversation / Task 分层状态与服务端持久 Conversation Session | Accepted | 2026-08-11 | AI 绘画客户端、Main 适配器、Works Square API | `adr-001-ai-design-conversation-ownership.md` | | ADR-002 | Robot V1 采用 Main 门控的引导式热点配网并衔接现有六位 Binding | Accepted / implemented, default on | 2026-08-16 | Robot Renderer、Host API、Electron Main、现有固件热点入口 | `adr-002-robot-guided-hotspot-binding-v1.md` | | ADR-003 | Robot 配网页内扫描并连接 Windows/macOS 热点 | Accepted / implemented with physical release gates pending | 2026-08-16 | Robot Renderer、Host API、Electron Main、Windows WLAN、macOS CoreWLAN/CoreLocation | `adr-003-robot-in-app-hotspot-connection.md` | +| ADR-004 | Works Square 统一拥有桌面认证生命周期边界 | Accepted / implemented | 2026-08-19 | Renderer、Host API、Electron Main、Works Square auth facade | `adr-004-square-auth-lifecycle-boundary.md` | ## Superseded Decisions diff --git a/.project-docs/20-architecture/data-flow.md b/.project-docs/20-architecture/data-flow.md index 0325d06..a7db6be 100644 --- a/.project-docs/20-architecture/data-flow.md +++ b/.project-docs/20-architecture/data-flow.md @@ -4,7 +4,7 @@ | Flow | Source | Destination | Notes | |---|---|---|---| -| 登录续期 | Renderer 活动信号 | Main Works Session | 连续 7 天未使用才清除会话 | +| 桌面认证生命周期 | Renderer 登录、刷新与注销请求 | Host API → Main Works Session → Works Square `/api/auth/{login,mobile-login,refresh,logout}` → one-feel auth | Main 加密持有并先持久化轮换 token;客户端不携带 OAuth client secret;连续 7 天未使用才清除会话,终止性 `400`/`401` fail closed | | 用户模块入口策略 | 会话恢复 / 登录 / 刷新 | Electron Main → Works `/api/auth/me` → 四布尔安全投影 → Renderer auth store → 卡片/路由/provider gate | 缺失对象或字段默认 `true`;`design` 映射 `painting`;终止性 `401` 清理 Main/Renderer 会话;全局 `/settings` 不受 Code gate | | 项目创建 | 新建项目对话框 | Host API → Main 项目初始化 | 创建时固定 `ProjectType`;小游戏/小程序原子生成受控模板,自定义只生成项目空间 | | 一键提交 | `ProjectPublishAction` | Renderer capability → Host API → Main 本地 npm/Vite build → built snapshot preflight → source+built+contract 上传 | 只对小游戏/小程序开放;首次 create 通过单一 multipart 合同原子提交文字资料与必选 PNG/JPEG/WebP 封面,创建失败或冲突不上传版本;已有 draft/published 只提交版本并沿用云端资料/封面,不做无条件 metadata PATCH | diff --git a/.project-docs/20-architecture/system-overview.md b/.project-docs/20-architecture/system-overview.md index 99da1f7..925f653 100644 --- a/.project-docs/20-architecture/system-overview.md +++ b/.project-docs/20-architecture/system-overview.md @@ -12,7 +12,7 @@ Makelore 是 Electron 桌面客户端。Renderer 负责项目操作与状态展 | Host API | 校验本地项目请求并投影安全响应 | 发布 mutation 还必须通过 Renderer capability;Host token/base 不能单独触发发布 | | Project Configuration & Template | 保存不可变 `ProjectType`,原子生成新项目骨架 | 小游戏/小程序生成受控 Vite 模板;自定义保持最小项目空间 | | Project Release Builder | Main-owned 安全快照、本地 npm/Vite 构建、双归档与 artifact contract | 固定 npm 11.6.2;Vite 由项目 lockfile 锁定;产物与预检使用同一内存字节 | -| Works Session | 七天真实活动滑动续期 | 刷新凭据由 Main 安全持有 | +| Works Session | Main-owned 登录、刷新、注销与七天真实活动滑动续期 | 登录、刷新、注销统一经过 Works Square;轮换凭据由 Main 安全持有和持久化,客户端不携带 OAuth client secret | | Module Access Policy | Main-owned `/api/auth/me` projection → Renderer auth state → module chooser/router | Renderer 只接收 Code/Canvas/Learning/Robot 四个布尔值;缺失对象或字段默认开启,服务端 `design` 映射客户端 `painting` | | Submission Binding | 保存云端已接受的精确 app/version/review/hash 绑定 | schema v2 只记录成功提交;旧中间态迁移为 `legacy_retired`,不恢复后台任务 | | Play URL Projection | 校验服务端公共播放地址 | 只接受同源 HTTPS 和精确 `/apps/{app_id}/`;优先 `play_url`,`runtime_url` 仅一版本回退 | @@ -34,6 +34,7 @@ Makelore 是 Electron 桌面客户端。Renderer 负责项目操作与状态展 ## Important Boundaries +- Renderer 只能通过 Main Host API 发起认证操作。Electron Main 是 access/refresh token 的唯一客户端所有者;登录、刷新、注销统一经过 Works Square 固定路由,客户端不得直连 one-feel/custom 身份服务,也不得保存 confidential OAuth client secret。 - Code、Canvas、Learning 与 Robot 是四个已启用顶层产品模块;Robot 仍是唯一硬件产品模块,不存在单独 Hardware 卡片。 - 每个登录用户可由 Works `module_access` 关闭任意顶层模块入口。Main 只投影四个布尔值;被关闭卡片置灰不可点,根/深层/别名路由在 `MainLayout` 和模块初始化前拦截。Code provider 必须等待 auth policy hydration,而全局 `/settings` 不属于 Code policy guard。 - 模块入口策略是用户交互与客户端初始化边界,不是服务端 API 授权。终止性 `/api/auth/me` `401` 必须清理 Main 和 Renderer 会话;各模块 API 仍须独立强制认证与授权。 @@ -76,7 +77,7 @@ Makelore 是 Electron 桌面客户端。Renderer 负责项目操作与状态展 ## Related Decisions -- 当前长期边界记录于 README、ADR-001、ADR-002、集成任务 `20260807-integrate-login-client-a4f8`、源任务 `20260810-static-release-only-a91c`、`20260812-client-built-release-makelore-7e5b`、`20260812-design-image-to-image-client-c91e` 及本次 Integration Gate;后续如改变唯一入口、凭据所有权、构建执行边界、Conversation 状态归属、Robot 配网/绑定安全边界或重新引入客户端部署协调器,应新增 ADR。 +- 当前长期边界记录于 README、ADR-001 至 ADR-004、集成任务 `20260807-integrate-login-client-a4f8`、源任务 `20260810-static-release-only-a91c`、`20260812-client-built-release-makelore-7e5b`、`20260812-design-image-to-image-client-c91e` 及本次 Integration Gate;后续如改变唯一入口、凭据所有权、构建执行边界、Conversation 状态归属、Robot 配网/绑定安全边界或重新引入客户端部署协调器,应新增 ADR。 ## Last Updated diff --git a/.project-docs/30-worklog/current-state.md b/.project-docs/30-worklog/current-state.md index d926a9a..5614c6a 100644 --- a/.project-docs/30-worklog/current-state.md +++ b/.project-docs/30-worklog/current-state.md @@ -4,6 +4,14 @@ This file is the integrated default-branch snapshot. Feature tasks record progre ## Integrated Through +- Square-auth lifecycle source commit `dc776ff` from feature task + `20260819-square-auth-proxy-client-8c4f2a` is integrated on the candidate `main` + tree through merge `f52c2c8`. Desktop login, refresh, and logout now use fixed + Works Square endpoints; Electron Main remains the sole token owner, persists + rotated credentials before exposing the refreshed session, and keeps the + existing seven-day inactivity boundary. The client no longer embeds a + confidential OAuth client secret or refreshes directly against the custom + identity service. The matching Square service change must be deployed first. - AI Design request-freeze source commit `87e4140` from feature task `20260819-design-freeze-live-6e2c` is integrated on `main` through `5bff5d3` by promotion task `20260819-promote-design-freeze-main-91c2e4`. Main-owned Workspace JSON diff --git a/.project-docs/30-worklog/tasks/20260819-integrate-square-auth-client-2f7c9a.md b/.project-docs/30-worklog/tasks/20260819-integrate-square-auth-client-2f7c9a.md new file mode 100644 index 0000000..7857655 --- /dev/null +++ b/.project-docs/30-worklog/tasks/20260819-integrate-square-auth-client-2f7c9a.md @@ -0,0 +1,45 @@ +# Task: Integrate Square auth proxy into Makelore main + +## Identity + +- Task ID: 20260819-integrate-square-auth-client-2f7c9a +- Mode: Integration +- Branch: codex/20260819-integrate-square-auth-client-2f7c9a-integrate-square-auth-client +- Worktree: D:\Datas\OthersProjects\makelore-integrate-square-auth-2f7c9a +- Base commit: 1907924203a1a998182c8e44e8884682ef216d95 +- Owner: codex-root +- Status: In Progress + +## Scope + +- Integrate feature commit `dc776ff` from task `20260819-square-auth-proxy-client-8c4f2a` into `main` based at `1907924`. +- Promote the desktop authentication lifecycle boundary into canonical project memory. +- Re-run merged-tree authentication and static verification before attempting a default-branch fast-forward. + +## Intent And Constraints + +- Keep Renderer credential-free and Electron Main as the sole owner of access/refresh token persistence and idle-session cleanup. +- Route login, refresh, and logout through fixed Works Square endpoints; do not restore the embedded OAuth client secret or direct custom-service refresh. +- Preserve the unrelated untracked task record in the primary `main` worktree; do not adopt or overwrite another task's work without explicit authorization. + +## Outcome + +- Merged source commit `dc776ff` into the isolated candidate integration branch as merge commit `f52c2c8` without conflicts. +- Promoted the Square-owned desktop authentication lifecycle boundary into the canonical current state, architecture flow, system boundary, decision index, and ADR-004. +- The candidate tree is verified, but local `main` still points to `1907924`: its primary worktree contains the unrelated untracked task record `.project-docs/30-worklog/tasks/20260819-package-learning-off-115-9c4d.md`, which this task is not authorized to adopt or overwrite. + +## Verification + +- `pnpm exec vitest run tests/unit/works-square-session.test.ts tests/unit/auth-routes.test.ts`: 56 passed. +- `pnpm exec vitest run`: 184 test files and 2,190 tests passed. +- `pnpm run typecheck`: passed. +- `git diff --check`: passed before task-record finalization. + +## Follow-ups + +- Obtain explicit ownership/adoption of the existing primary-worktree task record, or have its owner clean/release the `main` worktree, then fast-forward `main` to this candidate integration branch. +- Deploy and smoke-test the matching Works Square server endpoints before releasing a desktop build. + +## Promotion Candidates + +- None; the accepted boundary is already promoted in this integration worktree. diff --git a/.project-docs/30-worklog/tasks/20260819-square-auth-proxy-client-8c4f2a.md b/.project-docs/30-worklog/tasks/20260819-square-auth-proxy-client-8c4f2a.md deleted file mode 100644 index 92a2ac6..0000000 --- a/.project-docs/30-worklog/tasks/20260819-square-auth-proxy-client-8c4f2a.md +++ /dev/null @@ -1,57 +0,0 @@ -# Task: Route Makelore auth lifecycle through Works Square - -## Identity - -- Task ID: 20260819-square-auth-proxy-client-8c4f2a -- Mode: Feature -- Branch: codex/20260819-square-auth-proxy-client-8c4f2a-square-auth-proxy-client -- Worktree: D:\Datas\OthersProjects\makelore-square-auth-proxy-8c4f2a -- Base commit: 1907924203a1a998182c8e44e8884682ef216d95 -- Owner: codex-root -- Status: Ready for Integration - -## Scope - -- Route Works Square access-token refresh through `POST /api/auth/refresh` instead of calling the one-feel OAuth endpoint from Electron Main. -- Route remote logout through `POST /api/auth/logout` on Works Square while preserving Main-owned session cleanup behavior. -- Update focused session and auth-route regression tests, including rotated refresh-token persistence. - -## Intent And Constraints - -- Login, refresh, and logout must share the Works Square authentication boundary. -- Do not embed the deployed `custom` OAuth client secret in Makelore. -- Preserve Main ownership of tokens, the seven-day inactivity policy, refresh single-flight behavior, fail-closed persistence semantics, and local runtime cleanup. -- Do not change unrelated browser/OAuth-provider integrations. - -## Outcome - -- Electron Main now refreshes managed Works Square sessions with `POST https://square.nianxx.cn/api/auth/refresh` and a JSON refresh-token payload. It no longer sends an OAuth Basic credential or calls the one-feel token endpoint directly. -- Main-owned logout now calls `POST https://square.nianxx.cn/api/auth/logout` with the current Main access token, while retaining the existing local session, secure persistence, event-session, provider-key, and runtime cleanup behavior. -- Removed the now-unused Electron auth configuration module that embedded the legacy `app` client secret and password encryption key. -- Preserved refresh-token rotation, single-flight behavior, terminal 400/401 clearing, transient-error retention, and persistence-before-return semantics. - -## Verification - -- Red phase: focused tests failed in five expected places because refresh and logout still targeted `biz.nianxx.cn` with the legacy method/credential contract. -- `pnpm exec vitest run tests/unit/works-square-session.test.ts tests/unit/auth-routes.test.ts`: 56 passed. -- Focused session/auth compatibility suite: 86 passed across five test files. -- Full `pnpm exec vitest run`: 184 test files and 2190 tests passed. -- `pnpm run typecheck`: passed. -- `pnpm run lint:check`: passed with 0 errors and 7 pre-existing React warnings in unrelated files. -- `pnpm run build:vite`: passed for Renderer, Electron Main, preload, and utility worker. -- Full `pnpm run build` stopped before compilation because the required Learning Player artifact/source was not supplied; the subsequent direct Vite production build passed. -- `git diff --check`: passed. Source scan found no direct one-feel refresh/logout URL, Basic auth header, embedded client secret, or deleted auth-config import under `electron/`. - -## Follow-ups - -- Deploy the Works Square refresh/logout endpoints before distributing a Makelore build containing this client change. -- Supply the separately managed Learning Player artifact when producing the final packaged installer. - -## Promotion Candidates - -- Target canonical document: `.project-docs/20-architecture/data-flow.md` and the authentication decision index. - Proposal: record Works Square as the required boundary for the complete desktop authentication lifecycle (login, refresh, and logout), with confidential OAuth clients owned only by Works Square. - Evidence: focused request-contract tests, full 2190-test client suite, typecheck, lint, and production Vite build. - Future impact: new desktop authentication operations must be added to Square rather than embedding service credentials or direct one-feel calls in Makelore. - Semantic conflicts: none; this completes the proxy work explicitly deferred by the integrated native-login task. - Human confirmation required: no; the user explicitly selected the unified Square boundary.