# 星线智联技术概览

星线智联是用于确认星线账户网页登录请求的微信小程序。它在手机微信中核对发起站点、浏览器和两位核对码，由用户主动确认或取消，再由原浏览器领取结果。工程位于 `identity/mini-program/`，后端桥接位于 `identity/server/wechat-mobile.ts`。资料依据 2026 年 10 月 23 日源码与实施记录整理；联调与发布工作仍处于暂停状态。

## 当前交付与发布状态

开发版本 `0.1.0` 已有历史上传记录，尚未确认提交审核或正式发布。受控记录已验证真实 `wx.login` 到 code2Session 的身份交换；2026 年 10 月 23 日记录还确认手机主动批准、原浏览器领取待绑定凭据通过。领取后仍是原账户会话，没有形成微信新会话，因此完整绑定、微信复登、会话保持与正式 URL Link 唤起仍待验收。开发上传和局部流程通过不能合并成公众登录已可用。

现有记录保持公众入口关闭；配置中的 published、launch 等标志只是服务端开关，不是微信平台审核或发布回执。后续恢复需确认有效事务与真实平台状态，不能继续使用已过期的扫描或确认凭据。更新说明、编译或页面预览不会自动恢复暂停的联调和发布流程。

## 工程与页面

小程序使用原生 JavaScript、WXML、WXSS，没有把网页嵌入 WebView 完成批准。`app.json` 声明首页、确认页和隐私页，网络封装与状态机分别在 `lib/api.js`、`lib/confirmation.js`。工程与网站扫码微信渠道使用不同的小程序身份，不能混填网站应用的 AppID、密钥或授权配置。

| 页面或模块 | 实际行为 | 边界 |
| --- | --- | --- |
| `pages/index/index` | 品牌与隐私入口 | 不调用 wx.login，不创建登录事务 |
| `pages/confirm/index` | 读取短时扫描参数，核对并主动决定 | 无参数或非法参数直接无效，不模拟成功 |
| `pages/privacy/index` | 展示数据处理与公开政策 | 不读取账户资料或发起登录 |
| `lib/api.js` | 固定 Account HTTPS API，调用微信登录与请求 | 不从参数接收任意后端地址 |
| `lib/confirmation.js` | 单次加载、倒计时、批准/拒绝、后台恢复与销毁 | 凭据保存在模块内存，不写页面数据和本地存储 |

首页不会主动索取手机号、昵称、头像。确认过程调用 `wx.login` 获得微信临时 code，不依赖手机号授权来确认网页登录。页面隐藏分享菜单，不提供传播扫描凭据的分享处理；项目没有广告或统计 SDK。公开政策与页面告知仍需在正式审核时和真实后台配置保持一致。

## 三类证明与数据流

服务端创建三个用途分离的随机证明：原浏览器保存 `receiverToken`，手机启动参数携带 `scanToken`，inspect 成功后手机内存保存 `approvalToken`。服务端当前严格校验 43 位 URL-safe 证明，数据库存摘要与加密事务载荷。它们都不是账户长期访问令牌，也不能互换。

1. 原浏览器在 Account 发起事务，保存领取证明与核对信息。
2. 微信打开确认页，页面用 scanToken 和一次性 wx.login code 调用 inspect。
3. 服务端先消费扫描证明，再交换微信身份，创建等待主动确认的审批证明。
4. 手机显示精确 `https://account.thestarline.cn`、浏览器及两位码。点击确认或取消后，单次提交 decide。
5. 原浏览器检查状态，只有批准状态才可 complete。最终登录仍执行账户身份、风险、绑定及凭据版本检查。

小程序确认成功不会取得网页 Cookie，不把登录结果交给其他浏览器，也不自动打开网页。浏览器领取绑定创建事务时的上下文；复制 receiver 到另一浏览器会被拒绝。微信 `session_key` 在服务端校验后丢弃，不返回小程序；UnionID 当前不用于自动合并账户，`wechat_mini` 与网站 `wechat` 是独立身份命名空间。

## 状态、到期与不确定结果

事务逻辑有效期 300 秒。服务端内部状态依次可能为 pending、exchanging、awaiting_confirmation、approved，再由原浏览器消费；取消、过期、交换失败会结束流程。浏览器 status 对前三种中间态统一返回 pending，不应据此认为手机还没有扫描。

小程序有 idle、loading、ready、submitting 及多个终态。ready 时才启用决定按钮；提交前先取走内存中的 approvalToken，两次点击、确认后再取消等操作不会再发第二次决定。倒计时依据服务端毫秒时间戳与本机当前时间计算，不因进入后台而重置。回到前台立即复核绝对期限，卸载页面清除证明、取消请求并忽略迟到回调。

提交决定后断网，或请求在途时跨过本地期限，页面显示结果暂未确认：服务端可能已接受决定，不能简单显示“未批准”并提供重放按钮。用户应返回原浏览器查看。未提交的请求自然到期则显示已过期。这些状态是处理网络与单次证明的实际规则，不能用重新生成页面状态绕过。

## 后端能力与配置

`IDENTITY_WECHAT_MINI_ENABLED` 控制配置参与，`IDENTITY_WECHAT_MINI_PUBLISHED` 和 `IDENTITY_WECHAT_MINI_LAUNCH_ENABLED` 共同参与公众可用判断；受控预览另需 `IDENTITY_WECHAT_MINI_VERIFICATION_ENABLED` 及 Account 管理员认证。上述布尔量都只在精确字符串 `true` 时启用。独立小程序身份和服务端密钥必须配置在后端，不能进入小程序包。

公众 start 在具备条件时请求微信正式 URL Link，指向 `pages/confirm/index`，只携带扫描证明。返回链接仅接受微信 `wxaurl.cn` HTTPS 形式。受控 preview/start 返回开发工具可用页面路径，仍受管理员身份与来源校验保护，不能当作公开入口或审核可访问方案。

## 验证与后续范围

项目有 `api.test.js`、`confirmation.test.js`、`pages.test.js`，覆盖参数、固定来源、单次决定、凭据不进入页面数据、后台与迟到响应等契约；`scripts/validate.js` 检查工程、语法与上传排除项。账户端另有 `identity/tests/wechat-mobile.test.ts` 和 `wechat-mini-adapter.test.ts`。这些测试与原生编译不代替真实微信身份和原浏览器回程。

恢复后的必要验收包括 iOS、Android 微信真实流程，新旧绑定身份、明确拒绝、过期、扫描与审批重放、断网、后台返回、原浏览器独占领取及登录保持。已通过的手机批准与待绑定领取仍需与完整身份绑定、复登结果分别记录；之后才是审核、正式发布和正式入口复核。具体路由、错误与联调次序见[智联接入流程](https://document.thestarline.cn/zhilian/integration.md)，账户会话边界见[星线账户](https://document.thestarline.cn/account/)。
