Skip to content

Commit cce5335

Browse files
authored
feat(profile): 密钥管理入口 (Infisical) + CONTRIBUTING 基础设施访问段 (#303)
* feat(profile): 开发者选项入口 — 密钥管理 (Infisical) 和 AdminLinkIfOwnerAdmin 刻意分开:AdminLink 是 admin 专属入口,这个对所有登录 用户开放(只要访问的是自己主页)。对应的访问控制不在前端——Infisical 自己有 GitHub OAuth + project-level RBAC,非 admin 协作者登录后只看得到自己有权限的 secrets。 - 新加 DeveloperToolsIfOwner client 组件:owner 判定条件和 AdminLinkIfOwnerAdmin 保持一致(githubId 或 username 任一匹配即视为本人) - profile 页按钮栏里插在 AdminLink 前,顺序:编辑 → 密钥管理 → 管理员界面 → 排行 - data-umami-event 埋点 profile_devtools_secrets_click,方便看谁在用 - target=_blank 到 secrets.involutionhell.com(自托管 Infisical 实例) * docs(CONTRIBUTING): 加基础设施访问段 新协作者进来要知道怎么登主站 / Infisical / pgAdmin,怎么申请 admin 角色, .env 文件的分布与规则。之前这些都在脑子里或散在 wiki 里,CONTRIBUTING 作为贡献指南得自带一份快速索引。 - 服务一览表:谁能进 / 登录方式 - admin 权限申请流程(别手工 insert user_accounts 踩孤儿坑) - .env 文件位置和为什么 prod/dev 故意不一样(链到 wiki changelog) - 个人主页的开发者自助入口说明 - Spring Boot 本地启动的 source .env 姿势(memory 里的 feedback_ih_backend_dev_start) 放在 🚀 开发环境 和 📚 文档规范 之间,让人 setup 完环境后紧接着看到。 * docs(CONTRIBUTING): 修正密钥管理按钮的可见性表述 CR 指出 '所有登录协作者可见' 有歧义——按钮实现只在本人访问自己主页时 渲染,路人和其他登录用户在别人主页上看不到。Infisical 站本身才是对所有协作 者开放。分清楚两层语义避免贡献者迷惑。
1 parent 2ee1f20 commit cce5335

3 files changed

Lines changed: 123 additions & 8 deletions

File tree

CONTRIBUTING.md

Lines changed: 67 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@
3636

3737
```Markdown
3838
# 标题1
39-
## 标题2
39+
## 标题2
4040
```
41-
41+
4242
每点击一行,左边都有加号按钮,可以快捷添加你要的内容块
4343

4444
![image.png](https://pub-fa1987abe8794da6ba45cdf9284954b3.r2.dev/users/7/contributing-guide/1765632611285-image.png)
@@ -71,7 +71,6 @@
7171

7272
点击右上角的commit changes
7373

74-
7574
4. 点击 `Commit changes`,若是第一次投稿,GitHub 会提示先 Fork 仓库;按提示操作一次即可
7675
![fork](./public//git_assets/need_fork.png)
7776

@@ -182,31 +181,34 @@ git push origin doc_raven
182181
**解决方案**
183182

184183
1. **确保使用正确的 pnpm 版本**
184+
185185
```bash
186186
# 检查当前版本
187187
pnpm --version
188-
188+
189189
# 应该显示: 10.20.0
190190
# 如果不是,请使用以下命令之一:
191-
191+
192192
# 方法 1: 使用 corepack(推荐)
193193
corepack enable
194194
corepack prepare pnpm@10.20.0 --activate
195-
195+
196196
# 方法 2: 全局安装
197197
npm install -g pnpm@10.20.0
198198
```
199199

200200
2. **验证版本一致性**
201+
201202
```bash
202203
pnpm check:pnpm-version
203204
```
204205

205206
3. **如果 lockfile 已经被错误修改**
207+
206208
```bash
207209
# 丢弃 lockfile 的修改
208210
git checkout pnpm-lock.yaml
209-
211+
210212
# 确认使用正确的 pnpm 版本后重新安装
211213
pnpm install
212214
```
@@ -217,10 +219,12 @@ git push origin doc_raven
217219
#### 问题:CI 检查失败,提示 lockfile 不一致
218220

219221
这通常意味着:
222+
220223
1. 你本地使用的 pnpm 版本与项目要求的不一致
221224
2. lockfile 被错误修改或损坏
222225

223226
**解决方案**
227+
224228
```bash
225229
# 1. 确认并切换到正确的 pnpm 版本
226230
corepack enable
@@ -239,12 +243,14 @@ git status
239243
#### 问题:为什么要使用 corepack 而不是全局安装?
240244

241245
**Corepack 的优势**
246+
242247
- 自动读取 `package.json``packageManager` 字段
243248
- 每个项目可以使用不同的 pnpm 版本而不冲突
244249
- 新贡献者克隆项目后自动使用正确的版本
245250
- 减少版本不匹配导致的问题
246251

247252
**如何为团队启用 corepack**
253+
248254
```bash
249255
# 一次性设置,之后所有项目都会受益
250256
corepack enable
@@ -305,13 +311,13 @@ pnpm check:pnpm-version
305311
#### ⚠️ 为什么版本一致性很重要?
306312

307313
不同版本的 pnpm 在序列化 `pnpm-lock.yaml` 时可能使用不同的格式(如单引号 vs 双引号),导致:
314+
308315
- PR 中产生大量无意义的 diff
309316
- 增加代码审查负担
310317
- 可能导致 CI 检查失败
311318

312319
我们的 CI 工作流会自动检查版本一致性,如果检测到版本不匹配会导致构建失败。
313320

314-
315321
### 3. 本地开发
316322

317323
运行开发服务器:
@@ -343,6 +349,59 @@ pnpm postinstall # 同步必要的 Husky/Fumadocs 配置
343349

344350
---
345351

352+
## 🔐 基础设施访问
353+
354+
项目除了 GitHub 仓库,还有几个对外/对内服务。所有登录都走**同一个 GitHub 账号**,不再有每处独立密码。
355+
356+
### 服务一览
357+
358+
| 用途 | URL | 谁能进 | 登录方式 |
359+
| ------------ | ----------------------------------------------- | --------------------------------------- | --------------------------------------- |
360+
| 主站 | `https://involutionhell.com` | 所有登录用户 | GitHub OAuth |
361+
| 后端 API | `https://api.involutionhell.com` | — (内部调用) | sa-token (cookie/header) |
362+
| **密钥管理** | `https://secrets.involutionhell.com` | **所有登录协作者**,按 project 权限查看 | GitHub OAuth(复用主站 App) |
363+
| 数据库管理 | `https://api.involutionhell.com/admin/pgadmin/` | **仅 admin** | 主站 cookie 自动通过 Caddy forward_auth |
364+
| 网站分析 | `https://umami.involutionhell.com` | **仅 admin** | 本地 umami 账号 |
365+
366+
### 怎么拿到 admin / 密钥权限
367+
368+
1. **申请 admin 角色**:现有 superadmin 在 `/admin/users` 页面勾选即可授予(产品规则:superadmin 本身不能通过 API 变动)
369+
2. **申请 Infisical 项目访问**:登录 `secrets.involutionhell.com` 后(GitHub OAuth 自动建账号),联系现有 admin 加到对应 project。Infisical 内部按 environment 分 `dev` / `prod` / `shared`
370+
3. **不要自己手动 INSERT `user_accounts` 表挂 admin 角色** —— OAuth 登录按 `github_<id>` 匹配 username,手工 insert 的人类 username 行永远是孤儿,用户登录后会另开一行丢 admin。历史上有人踩过
371+
372+
### `.env` 文件规则
373+
374+
- 本地 dev:
375+
- 后端:`involution-hell-project/backend/.env``set -a && . ./.env && set +a` 注入 Spring Boot)
376+
- 前端:`involution-hell-project/frontend/.env`
377+
- 生产:`/home/ubuntu/involution-hell/.env`**只在部署机**,不在仓库里;CI 不覆盖)
378+
- 两份 .env **故意有差异**(PGHOST / SERVER_PORT / AUTH_URL)—— 不要强行统一,参见 wiki [Changelog 2026-04-17](https://github.com/InvolutionHell/involutionhell/wiki/Changelog-2026-04-17-Self-Hosted-Infra) 的架构说明
379+
- **所有秘密值**将来会迁到 Infisical 单一真源,`.env` 只存极少数 bootstrap 配置。改动期间前后仓两份并存,改值要同步改两处
380+
381+
### 开发者自助入口
382+
383+
登录主站后,访问**自己**的个人主页 `/u/<你的 github id>`,在顶部按钮栏能看到:
384+
385+
- **密钥管理 ↗**(本人访问自己主页时可见) → 跳 Infisical
386+
- **管理员界面**(仅 admin 本人访问自己主页时可见) → 跳 `/admin`
387+
- **编辑**(仅本人访问自己主页时可见) → 跳 profile 编辑
388+
389+
三个按钮都走 "只有本人看自己主页时才渲染",路人和其他登录用户在这里看不到。
390+
**但 Infisical 站本身** (`secrets.involutionhell.com`) **对所有登录协作者开放** ——
391+
入口按钮只是 UX 便利,不影响访问权(路人可以直接敲地址栏进入)。
392+
393+
### Spring Boot 后端本地启动
394+
395+
```bash
396+
cd involution-hell-project/backend
397+
set -a && . ./.env && set +a # .env 里有 SERVER_PORT=8081 等
398+
./mvnw spring-boot:run
399+
```
400+
401+
前端 `BACKEND_URL``http://localhost:8081`,前后一致。
402+
403+
---
404+
346405
## 📚 文档规范
347406

348407
所有文档放在 `docs/` 目录。
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
"use client";
2+
3+
/**
4+
* 个人主页的"开发者选项"入口块。
5+
*
6+
* 和 AdminLinkIfOwnerAdmin 的区别——这里**不限 admin**,只要是主页 owner(当前登录
7+
* 用户 === 这个主页本人)就看得见。理由:
8+
* - 密钥管理 (Infisical) 是每个开发者都要用的,不是管理员专属。
9+
* Infisical 自己按 project / environment 做权限细分,进去后看不到自己没权限的 secrets。
10+
* - 以后其他"个人开发者工具"(比如 CI tokens、个人 API key 管理)也可以挂在这里
11+
*
12+
* 渲染条件:
13+
* 1. 已登录
14+
* 2. 当前登录用户就是这个主页的 owner(路人看不到)
15+
*
16+
* 注意:单独加 Link 而不是走 AdminGuard 风格,因为这是"入口按钮"不是"整页权限",
17+
* 二次校验由目标服务(Infisical)自己做。
18+
*/
19+
20+
import Link from "next/link";
21+
import { useAuth } from "@/lib/use-auth";
22+
23+
interface Props {
24+
ownerGithubId: number | null;
25+
ownerUsername: string;
26+
}
27+
28+
export function DeveloperToolsIfOwner({ ownerGithubId, ownerUsername }: Props) {
29+
const { user, status } = useAuth();
30+
if (status !== "authenticated" || !user) return null;
31+
32+
const isOwner =
33+
(ownerGithubId != null && user.githubId === ownerGithubId) ||
34+
user.username === ownerUsername;
35+
if (!isOwner) return null;
36+
37+
return (
38+
<Link
39+
href="https://secrets.involutionhell.com"
40+
target="_blank"
41+
rel="noopener noreferrer"
42+
className="font-mono text-[11px] uppercase tracking-widest px-2 py-1 border border-[var(--foreground)] text-[var(--foreground)] hover:bg-[var(--foreground)] hover:text-[var(--background)] transition-colors font-bold"
43+
data-umami-event="profile_devtools_secrets_click"
44+
title="Infisical 密钥管理(GitHub OAuth 登录,按 project 权限查看)"
45+
>
46+
密钥管理 ↗
47+
</Link>
48+
);
49+
}

app/u/[username]/page.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { Footer } from "@/app/components/Footer";
88
import { ProfileCard } from "./ProfileCard";
99
import { EditLinkIfOwner } from "./EditLinkIfOwner";
1010
import { AdminLinkIfOwnerAdmin } from "./AdminLinkIfOwnerAdmin";
11+
import { DeveloperToolsIfOwner } from "./DeveloperToolsIfOwner";
1112
import { ActivityHeatmap } from "./ActivityHeatmap";
1213
import { FollowButton } from "./FollowButton";
1314
import { GithubRepos, GithubReposSkeleton } from "./GithubRepos";
@@ -387,6 +388,12 @@ export default async function UserProfilePage({ params }: Param) {
387388
ownerUsername={user.username}
388389
identifier={username}
389390
/>
391+
{/* 开发者工具入口(所有本人都看得见;权限由目标服务自己管):
392+
目前只有 Infisical 密钥管理,未来可挂 CI token / API key 等 */}
393+
<DeveloperToolsIfOwner
394+
ownerGithubId={user.githubId ?? null}
395+
ownerUsername={user.username}
396+
/>
390397
{/* 管理员自见入口:只有 roles=admin 的本人访问自己主页时才渲染 */}
391398
<AdminLinkIfOwnerAdmin
392399
ownerGithubId={user.githubId ?? null}

0 commit comments

Comments
 (0)