Files
jkooe 7ddd344d7f chore: 初始化仓库并落地 T-1 批次1(安全地基与仓库卫生)
- 新增 .gitignore,排除 node_modules / dist / release / server/data 数据库与备份 / .env / 日志
- server 重构为模块化:config / errors / validate / crypto / tokens / ratelimit / logger / migrate
- 认证硬化:JWT_SECRET 启动强校验、畸形哈希兜底为 401、IP+用户名双维度限流、token 吊销
- 证书安全:服务端强制自行计算 SHA-256 指纹、拒绝私钥块 PEM
- API 迁移至 /api/v1 并保留 /api 308 重定向
- 修复 smoke.mjs 因入口判定导致必然连接失败的缺陷
- 测试夹具改为运行期拼装 + base64,规避 gitleaks 误报与全局 *.pem 忽略规则
- 测试:server 43 例 + launcher 26 例全绿,server 行覆盖 74.77%
2026-10-26 00:10:01 +08:00

5.2 KiB
Raw Permalink Blame History

Only in One — 产品需求文档(PRD)草案

状态:v1.0 已对齐(决策已锁定) 定位:团队内部工具(非对外产品) 最后更新:2026-08-23


1. 背景与问题

团队内部存在多台设备(Windows 小主机、MacBook 等),需要:远程串流桌面/游戏、跨设备使用 USB 设备、双向传输文件。现有方案痛点:

  • 商用串流工具延迟或连接步骤繁琐,USB/文件支持弱
  • 自搭方案组件割裂,配对需手动输 PIN
  • 设备角色固定,无法双向控制

2. 目标与成功指标

目标

  • 低延迟:局域网端到端 ≤15ms,网络 ≤3ms
  • 连接方便:云账户免 PIN 自动配对 + 局域网自动发现 + 公网可选虚拟组网
  • 双向控制:Windows ⇄ Mac 互为主/被控
  • USB 透传 + 文件共享

成功指标(验收量化)

  • 局域网端到端延迟 ≤15ms
  • 同账户设备免 PIN 连接成功率 = 100%
  • 点击连接到出画面 ≤3s
  • 已知兼容 USB 设备挂载成功率 = 100%
  • 共享目录可正常读写,断开后设备正常释放

3. 用户与角色

角色 职责
团队成员(使用者) 登录账户 → 看设备列表 → 一键连接 / 挂载 USB / 打开共享
运维/管理员 部署账户服务器、配置设备
软件(设备端) 既作 Sunshine 服务端,又作 Moonlight 客户端

4. 范围

V1(MVP,阶段 0–3)

  • 局域网串流:Windows 被控、Mac 主控
  • 账户 + 启动器 MVP:免 PIN 一键连接
  • USB/IP:Windows 共享 → Mac 挂载(单向)
  • 文件共享:SMB,Windows 共享 → Mac 打开(单向;双向后置)

V2(阶段 4–6)

  • 双向控制(Mac 被控)
  • 公网 + 虚拟组网(Tailscale)
  • 安全加固 + 安装包发布

明确不在 V1:公网连接、Mac 作为被控端、对外发布、自动更新。

5. 功能清单与需求(EARS)

5.1 账户与认证

  • [Ubiquitous] 账户服务器仅承载控制面(认证/设备注册/证书同步),数据面不经过服务器。
  • [Ubiquitous] 所有控制面 API 强制 HTTPS,敏感操作需 JWT 鉴权。
  • [Event-driven] 当用户注册/登录时,系统签发 JWT 供后续请求使用。

5.2 设备与一键连接

  • [Event-driven] 当设备启动器上线时,向账户服务器心跳上报在线状态与 IP。
  • [Event-driven] 当用户点击设备「连接」时,系统拉取该设备证书写入本机 Sunshine 凭据目录,拉起 Moonlight 免 PIN 连接。
  • [State-driven] 当目标设备证书不存在时,系统引导用户首次手动配对(输 PIN)并自动上传证书。

5.3 USB 透传

  • [Event-driven] 当用户在 Windows 点击「共享」某 USB 设备时,系统执行 usbipd bind。
  • [Event-driven] 当用户在 Mac 点击「挂载」时,系统执行 usbip attach(需授权)。
  • [Unwanted] 若设备挂载失败,系统给出明确错误并记录不兼容设备。

5.4 文件共享

  • [Event-driven] 当用户首次开启文件共享时,系统在 Windows 创建加密 SMB 共享。
  • [Event-driven] 当用户点击「打开共享文件夹」时,系统调用文件管理器打开 smb:// 路径。

5.5 非功能

  • [Ubiquitous] 编码器自动探测(NVENC/AMF/VideoToolbox),无硬编时兜底 x264。
  • [Ubiquitous] 敏感信息(token/证书)存储于系统钥匙串(Keychain / Credential Manager)。
  • [Unwanted] 若账户服务器不可用,设备凭本地缓存证书仍可离线连接。

6. 关键流程

  1. 一键免密连接:登录 → 设备列表 → 点击连接 → 拉取目标证书 → 写入本机 Sunshine 凭据目录 → 拉起 Moonlight(对应 launcher/src/connect.ts)。
  2. USB 挂载:Windows 共享(usbipd bind)→ Mac 挂载(usbip attach)→ 出现在 Finder。
  3. 文件共享:Windows 建 SMB 共享 → Mac open smb://host/OnlyInOne。

7. 已确认决策

  • 团队规模 10 人以内 → SQLite 单文件足够。
  • V1 设备矩阵:仅 Windows 小主机 + MacBook。
  • V1 角色:Mac 主控、Windows 被控;Mac 被控后置 V2。
  • 网络:局域网 V1;公网/虚拟组网 V2。
  • Sunshine 选型:上游 stable 为主;foundation-sunshine 在 P0 顺带验证,不阻塞主线。
  • 证书安全:私钥不上云,只同步公钥证书。
  • macOS 虚拟显示器:后置 V2(V1 只需 Windows 虚拟显示器,上游已内置)。

8. 技术决策结论(Q5/Q6/Q7)

Q5 — Sunshine 选型 默认上游 LizardByte Sunshine(stable):主动维护、NVENC/AMF/VideoToolbox 硬编、REST API、Windows 内置虚拟显示器。foundation-sunshine 用途需 P0 确认后决定是否采用,不阻塞主线。

Q6 — 私钥是否上云 不上云私钥。Sunshine 免 PIN 只需要客户端「公钥证书」,私钥留在本机;同步只传公钥即可。若确需同步敏感信息,用端到端加密(密钥只存用户设备、服务端不可解密),服务端仅作盲存储。

Q7 — macOS 虚拟显示器 macOS 无原生虚拟显示器,需第三方(BetterDisplay 类)或物理 HDMI 假负载。因 V1 是 Mac 主控、Windows 被控,此问题整体延后到 V2;V1 只需 Windows 侧虚拟显示器(上游已内置)。