Skip to content

Commit 1f892a6

Browse files
committed
📝 新增 VitePress 文档站并精简 README
使用 GitHub Pages 发布指南、OIDC 与部署文档,技术细节迁出 README。
1 parent ce08ffb commit 1f892a6

21 files changed

Lines changed: 3539 additions & 3745 deletions

.github/workflows/docs.yml

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
name: Docs
2+
3+
on:
4+
push:
5+
branches: [master]
6+
paths:
7+
- "docs/**"
8+
- "pnpm-lock.yaml"
9+
- "pnpm-workspace.yaml"
10+
- "package.json"
11+
- ".github/workflows/docs.yml"
12+
workflow_dispatch:
13+
14+
permissions:
15+
contents: read
16+
pages: write
17+
id-token: write
18+
19+
concurrency:
20+
group: pages
21+
cancel-in-progress: true
22+
23+
jobs:
24+
build:
25+
runs-on: ubuntu-latest
26+
steps:
27+
- uses: actions/checkout@v4
28+
with:
29+
fetch-depth: 0
30+
31+
- uses: pnpm/action-setup@v4
32+
with:
33+
version: 10.32.1
34+
35+
- uses: actions/setup-node@v4
36+
with:
37+
node-version: 24
38+
cache: pnpm
39+
40+
- run: pnpm install --frozen-lockfile
41+
42+
- name: Build docs
43+
env:
44+
DOCS_BASE: /${{ github.event.repository.name }}/
45+
run: pnpm docs:build
46+
47+
- uses: actions/upload-pages-artifact@v3
48+
with:
49+
path: docs/.vitepress/dist
50+
51+
deploy:
52+
needs: build
53+
runs-on: ubuntu-latest
54+
environment:
55+
name: github-pages
56+
url: ${{ steps.deployment.outputs.page_url }}
57+
steps:
58+
- id: deployment
59+
uses: actions/deploy-pages@v4

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ build/
88
coverage/
99
.next/
1010
.turbo/
11+
docs/.vitepress/dist
12+
docs/.vitepress/cache
1113
*.tsbuildinfo
1214

1315
# env and local config

AGENTS.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
## 项目结构与模块组织
44

55
- `src/` 存放应用代码。OIDC 协议与 HTTP 相关逻辑位于 `src/oidc/``src/routes/``src/app.ts`;身份认证集成位于 `src/identity/`;持久化、仓储、加密和限流逻辑位于 `src/persistence/`
6+
- `web/` 存放管理后台前端。
7+
- `docs/` 存放 VitePress 文档站,由 GitHub Pages 发布。
68
- `test/` 存放服务测试和集成测试;针对单个模块的测试也可以放在源码旁,例如 `src/identity/providers/*.test.ts`
79
- `scripts/` 存放数据库和环境初始化脚本。`deploy/` 存放 Docker Compose 文件及客户端配置示例,`docker/` 存放辅助镜像配置。
8-
- 构建产物写入 `dist/`,不得提交到仓库。
10+
- 构建产物写入 `dist/``docs/.vitepress/dist/`,不得提交到仓库。
911

1012
## 构建、测试与开发命令
1113

@@ -18,6 +20,8 @@ pnpm test # 运行全部测试
1820
pnpm lint # 检查环境变量来源规则和 TypeScript 类型
1921
pnpm build # 将编译产物输出到 dist/
2022
pnpm format # 使用 Prettier 格式化仓库
23+
pnpm docs:dev # 本地预览文档站
24+
pnpm docs:build # 构建文档站静态产物
2125
pnpm init-env --force --profile test # 生成本地测试环境配置
2226
pnpm docker:up # 构建并启动本地服务栈
2327
pnpm docker:down # 停止本地服务栈

README.md

Lines changed: 23 additions & 242 deletions
Large diffs are not rendered by default.

docs/.vitepress/config.ts

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import { defineConfig } from "vitepress";
2+
3+
const base = process.env.DOCS_BASE || "/";
4+
5+
export default defineConfig({
6+
title: "CQUT Auth",
7+
description: "重庆理工大学 OIDC Provider 文档",
8+
lang: "zh-CN",
9+
base,
10+
cleanUrls: true,
11+
lastUpdated: true,
12+
head: [
13+
[
14+
"link",
15+
{ rel: "icon", href: `${base}logo.svg`, type: "image/svg+xml" },
16+
],
17+
],
18+
themeConfig: {
19+
logo: "/logo.svg",
20+
nav: [
21+
{ text: "指南", link: "/guide/introduction" },
22+
{ text: "OIDC 接入", link: "/oidc/overview" },
23+
{ text: "部署", link: "/deploy/production" },
24+
{
25+
text: "仓库",
26+
link: "https://github.com/CQUT-OpenProject/CQUT-Auth",
27+
},
28+
],
29+
sidebar: {
30+
"/guide/": [
31+
{
32+
text: "指南",
33+
items: [
34+
{ text: "项目介绍", link: "/guide/introduction" },
35+
{ text: "本地启动", link: "/guide/getting-started" },
36+
{ text: "开发", link: "/guide/development" },
37+
{ text: "安全说明", link: "/guide/security" },
38+
],
39+
},
40+
],
41+
"/oidc/": [
42+
{
43+
text: "OIDC 接入",
44+
items: [
45+
{ text: "端点与流程", link: "/oidc/overview" },
46+
{ text: "Scope 与 Claim", link: "/oidc/scopes" },
47+
{ text: "客户端生命周期", link: "/oidc/client-lifecycle" },
48+
],
49+
},
50+
],
51+
"/deploy/": [
52+
{
53+
text: "部署",
54+
items: [
55+
{ text: "生产部署", link: "/deploy/production" },
56+
{ text: "配置说明", link: "/deploy/configuration" },
57+
{ text: "UIS / CAS", link: "/deploy/uis-cas" },
58+
],
59+
},
60+
],
61+
},
62+
socialLinks: [
63+
{
64+
icon: "github",
65+
link: "https://github.com/CQUT-OpenProject/CQUT-Auth",
66+
},
67+
],
68+
search: {
69+
provider: "local",
70+
},
71+
editLink: {
72+
pattern:
73+
"https://github.com/CQUT-OpenProject/CQUT-Auth/edit/master/docs/:path",
74+
text: "在 GitHub 上编辑此页",
75+
},
76+
footer: {
77+
message: "基于 MIT 协议开源",
78+
copyright: "Copyright © CQUT OpenProject",
79+
},
80+
outline: {
81+
label: "本页目录",
82+
},
83+
docFooter: {
84+
prev: "上一页",
85+
next: "下一页",
86+
},
87+
lastUpdated: {
88+
text: "最后更新",
89+
},
90+
},
91+
});

docs/deploy/configuration.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# 配置说明
2+
3+
`deploy/.env.example` 是部署期配置模板。以下变量决定应用能否安全启动:
4+
5+
| 变量 | 说明 |
6+
| --- | --- |
7+
| `APP_ENV` | `production``development``test` |
8+
| `OIDC_ISSUER` | 对外 Issuer;非测试环境必须使用 HTTPS |
9+
| `DATABASE_URL` | 应用使用的 PostgreSQL URL,由 Compose 根据数据库变量组装 |
10+
| `REDIS_URL` | Redis URL;生产环境必需 |
11+
| `OIDC_KEY_ENCRYPTION_SECRET` | 数据库签名私钥加密密钥 |
12+
| `OIDC_ARTIFACT_ENCRYPTION_SECRET` | OIDC Artifact 载荷加密密钥,必须与前者不同 |
13+
| `OIDC_COOKIE_KEYS` | Cookie 签名密钥列表,可按顺序轮换 |
14+
| `OIDC_CSRF_SIGNING_SECRET` | CSRF Token 签名密钥 |
15+
| `TRUST_PROXY_HOPS` | 生产环境固定为一层可信代理 |
16+
| `TRUSTED_PROXY_CIDRS` | 允许提供转发 IP 的代理来源 CIDR |
17+
| `OIDC_ADMIN_SUBJECT_IDS` | 管理员 Subject ID 白名单 |
18+
| `OIDC_AUTO_SEED_SIGNING_KEY` | 是否在无签名密钥时自动初始化,生产常态应为 `false` |
19+
| `CQUT_UIS_BASE_URL` | UIS 基础地址 |
20+
| `CQUT_CAS_APPLICATION_CODE` | CAS 应用代码 |
21+
| `CQUT_CAS_SERVICE_URL` | CAS Ticket 绑定的 Service URL |
22+
23+
## 管理后台配置
24+
25+
邮件发送参数、Token 和会话时效、验证码策略、业务限流及项目配额都在管理后台的「系统设置」中维护。启动时会忽略对应的旧环境变量,不应再用它们配置这些项目。
26+
27+
## 引导客户端
28+
29+
`deploy/oidc-clients.json` 只在客户端表为空时执行一次引导导入。数据库已有客户端后,修改该文件不会更新现有记录。

docs/deploy/production.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# 生产部署
2+
3+
## 1. 生成部署配置
4+
5+
```bash
6+
pnpm install --frozen-lockfile
7+
pnpm init-env --profile production --issuer https://auth.example.com
8+
```
9+
10+
检查 `deploy/.env`,至少确认:
11+
12+
- `OIDC_ISSUER` 与外部 HTTPS 地址完全一致;
13+
- `OIDC_COOKIE_SECURE=true`
14+
- `TRUST_PROXY_HOPS=1`
15+
- `TRUSTED_PROXY_CIDRS` 只包含实际反向代理来源;
16+
- PostgreSQL 密码和各组安全密钥已妥善保存;
17+
- `CQUT_UIS_BASE_URL``CQUT_CAS_APPLICATION_CODE``CQUT_CAS_SERVICE_URL` 符合当前 UIS 配置。
18+
19+
`init-env` 还会生成演示客户端。请在首次启动前检查 `deploy/oidc-clients.json` 的 Redirect URI 和 Scope;不需要引导客户端时,可以将 `clients` 改为空数组。
20+
21+
在生产模式下,缺少 PostgreSQL 或 Redis、关闭邮箱验证或 Artifact 清理、未启用限流的 fail-closed 策略、使用内存存储,或代理配置不完整,都会导致应用拒绝启动。
22+
23+
## 2. 初始化签名密钥并启动
24+
25+
全新数据库必须先创建一把 OIDC 签名密钥。容器镜像不包含开发期的 `tsx` 和源码,因此首次容器部署可临时设置:
26+
27+
```dotenv
28+
OIDC_AUTO_SEED_SIGNING_KEY=true
29+
```
30+
31+
启动生产服务:
32+
33+
```bash
34+
docker compose -f deploy/docker-compose.prod.yml up -d --build
35+
```
36+
37+
推送 `v*` 版本标签时,GitHub Actions 会构建 `linux/amd64``linux/arm64` 镜像并发布到 GitHub Container Registry(也可手动 `workflow_dispatch`):
38+
39+
```bash
40+
docker pull ghcr.io/cqut-openproject/cqut-auth:latest
41+
```
42+
43+
例如 `v1.2.3` 会生成 `latest``v1.2.3``1.2.3``1.2``1``sha-<commit>` 标签。如果镜像包未设置为公开,拉取前需要先使用具有 `read:packages` 权限的 GitHub Token 登录 `ghcr.io`
44+
45+
确认 `/health/live` 和 Discovery 正常后,将 `OIDC_AUTO_SEED_SIGNING_KEY` 改回 `false` 并重启。后续签名密钥由数据库管理,不需要每次启动重新生成。此时 `/health/ready` 仍可能因为邮件尚未配置而返回 `503`
46+
47+
## 3. 配置反向代理
48+
49+
生产 Compose 默认只把应用绑定到宿主机 `127.0.0.1:3003`。反向代理应:
50+
51+
- 对外提供 HTTPS;
52+
- 将 Host 和协议转发给应用;
53+
- 覆盖而不是透传客户端提供的 `X-Forwarded-For`
54+
- 使应用看到的直连来源位于 `TRUSTED_PROXY_CIDRS`
55+
- 不直接暴露 PostgreSQL 和 Redis。
56+
57+
更换域名后不能只修改代理配置;必须同步更新 `OIDC_ISSUER`,并重新检查所有客户端 Redirect URI。
58+
59+
## 4. 建立管理员
60+
61+
1. 打开 `/manage`,使用学校账号登录;
62+
2. 在管理后台复制当前 Subject ID;
63+
3. 将该值加入 `OIDC_ADMIN_SUBJECT_IDS`,多个值用逗号分隔;
64+
4. 重启服务并重新登录。
65+
66+
管理员可以审核客户端 Revision、管理全局运行策略、配置邮件通道并执行紧急处置。运行策略写入 PostgreSQL 后,需要重启服务才会生效。
67+
68+
完成邮件通道配置和测试后,确认 `/health/ready` 返回 `200 ready`,再将实例加入反向代理或负载均衡器的生产流量。

docs/deploy/uis-cas.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# UIS / CAS
2+
3+
登录流程由服务端完成,不依赖浏览器保存学校会话:
4+
5+
1. 请求 UIS CAS 登录地址,解析实际 `service`
6+
2. 使用 UIS 登录页的 RSA 规则加密密码,提交 `/center-auth-server/sso/doLogin`
7+
3. 再次请求 CAS 登录地址并停止在 `302`
8+
4.`Location` 提取一次性 `ST-*` Service Ticket;
9+
5. 使用签发 Ticket 时完全相同的 `service` 调用 `/center-auth-server/cas/serviceValidate`
10+
6. 使用带命名空间的 XML 解析器验证 `authenticationSuccess`,拒绝 DOCTYPE、超限响应、重复结果和冲突标识;
11+
7. 比较 `user``uid``user_code` 与登录账号,确认身份一致后建立本地 Subject。
12+
13+
## 字段处理
14+
15+
UIS 实测还会返回 `user_name``user_user_type``universityId``authServerToken`。本系统只使用用户标识,不保存任何真实姓名、数字用户类型或内部令牌。
16+
17+
单一学生样本中 `user_user_type=3` 与办事大厅的 `STUDENT` 类型对应,但该结果不足以证明完整类型映射。
18+
19+
## 注意事项
20+
21+
`serviceValidate?format=JSON` 实测只改变响应头,响应体仍为 XML;接入实现不能依赖该参数进行 JSON 解析。

docs/guide/development.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# 开发
2+
3+
## 常用命令
4+
5+
```bash
6+
pnpm dev # 监听服务端和管理后台构建
7+
pnpm test # 运行服务端与前端测试
8+
pnpm test:server # 仅运行 Node.js / tsx 测试
9+
pnpm test:ui # 仅运行 Vitest 前端测试
10+
pnpm lint # 检查环境变量来源和 TypeScript 类型
11+
pnpm build # 构建服务端与管理后台到 dist/
12+
pnpm format # 使用 Prettier 格式化仓库
13+
pnpm docs:dev # 本地预览文档站
14+
pnpm docs:build # 构建文档站静态产物
15+
```
16+
17+
指定服务端测试:
18+
19+
```bash
20+
pnpm exec tsx --test test/crypto.test.ts
21+
```
22+
23+
`pnpm dev``deploy/.env` 读取配置。需要 PostgreSQL 和 Redis 时,可直接使用开发 Compose;容器会挂载当前工作区并运行监听构建。
24+
25+
## 提交前检查
26+
27+
```bash
28+
pnpm lint
29+
pnpm test
30+
pnpm build
31+
```
32+
33+
## 项目结构
34+
35+
| 路径 | 说明 |
36+
| --- | --- |
37+
| `src/oidc/``src/routes/``src/app.ts` | OIDC 协议与 HTTP |
38+
| `src/identity/` | 身份认证集成 |
39+
| `src/persistence/` | 持久化、仓储、加密和限流 |
40+
| `web/` | 管理后台前端 |
41+
| `docs/` | 文档站(VitePress) |
42+
| `test/` | 服务测试与集成测试 |
43+
| `deploy/` | Docker Compose 与客户端配置示例 |

docs/guide/getting-started.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# 本地启动
2+
3+
以下配置用于本地功能测试,不应作为生产配置:
4+
5+
```bash
6+
pnpm install
7+
pnpm init-env --profile test
8+
pnpm docker:up
9+
```
10+
11+
`init-env` 会生成:
12+
13+
- `deploy/.env`:包含随机数据库密码、加密密钥、Cookie 密钥和 CSRF 密钥;
14+
- `deploy/oidc-clients.json`:包含一个演示客户端及其 scrypt Secret 摘要。
15+
16+
命令会在终端输出一次演示客户端明文 Secret。请立即保存;配置文件和数据库中均无法恢复该明文。
17+
18+
## 默认服务地址
19+
20+
| 地址 | 用途 |
21+
| --- | --- |
22+
| `http://127.0.0.1:3003/manage` | 客户端管理后台 |
23+
| `http://127.0.0.1:3003/.well-known/openid-configuration` | OIDC Discovery |
24+
| `http://127.0.0.1:3003/health/live` | 进程存活检查 |
25+
| `http://127.0.0.1:3003/health/ready` | PostgreSQL、Redis 和邮件状态检查 |
26+
27+
邮箱验证默认启用。在管理员完成邮件通道配置前,`/health/ready` 会返回 `503 degraded``email: unconfigured`;这不妨碍打开管理后台完成首次配置。
28+
29+
## 停止服务
30+
31+
```bash
32+
pnpm docker:down
33+
```
34+
35+
如果目标文件已存在,`init-env` 会拒绝覆盖。只有明确需要重新生成密钥和演示客户端时才使用 `--force`;覆盖后,旧数据中的密文和 Cookie 可能无法继续使用。

0 commit comments

Comments
 (0)