feat: 新增一键部署到 Cloudflare Workers

This commit is contained in:
nap0o committed 2026-03-07 13:56:36 +08:00
1 parent e6a86b2050
commit b7fc210bd1
13 files changed
+226 -147

No files matched your search

+7 -20
View File
@@ -22,27 +22,17 @@ jobs:
node-version: '20'
cache: 'npm'
cache-dependency-path: |
frontend/package.json
backend/package.json
package.json
# 安装前端依赖 (Wrangler 构建需要)
- name: Install Frontend Dependencies
run: |
cd frontend
npm install
# 安装后端依赖
- name: Install Backend Dependencies
run: |
cd backend
npm install
# 安装全部依赖
- name: Install Dependencies
run: npm install
# 准备配置文件
- name: Prepare Wrangler Config
env:
CONFIG_FILE: ${{ env.WRANGLER_CONFIG || 'wrangler.toml' }}
run: |
cd backend
cp wrangler.toml wrangler.toml.bak
if [ "$CONFIG_FILE" != "wrangler.toml" ]; then
@@ -57,8 +47,8 @@ jobs:
CLOUDFLARE_D1_DATABASE_NAME: ${{ secrets.CLOUDFLARE_D1_DATABASE_NAME || '2fauth-db' }}
run: |
# 仅替换第一个匹配到的 database_id (对应生产环境配置),保留 dev 环境配置
sed -i "0,/database_id =/s/database_id = \".*\"/database_id = \"$CLOUDFLARE_D1_DATABASE_ID\"/" "backend/wrangler.toml"
sed -i "0,/database_name =/s/database_name = \".*\"/database_name = \"$CLOUDFLARE_D1_DATABASE_NAME\"/" "backend/wrangler.toml"
sed -i "0,/database_id =/s/database_id = \".*\"/database_id = \"$CLOUDFLARE_D1_DATABASE_ID\"/" "wrangler.toml"
sed -i "0,/database_name =/s/database_name = \".*\"/database_name = \"$CLOUDFLARE_D1_DATABASE_NAME\"/" "wrangler.toml"
# 更新数据库结构
- name: Update Database Schema
@@ -66,8 +56,7 @@ jobs:
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
workingDirectory: 'backend'
command: d1 execute ${{ secrets.CLOUDFLARE_D1_DATABASE_NAME || '2fauth-db' }} --remote --file=schema.sql
command: d1 execute ${{ secrets.CLOUDFLARE_D1_DATABASE_NAME || '2fauth-db' }} --remote --file=backend/schema.sql
# 动态生成 Secrets 列表 (仅包含已配置的变量)
- name: Generate Secret List
@@ -131,7 +120,6 @@ jobs:
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
workingDirectory: 'backend'
command: deploy --minify
secrets: ${{ steps.secret_list.outputs.secrets }}
env:
@@ -162,7 +150,6 @@ jobs:
- name: Restore Wrangler Config
if: always()
run: |
cd backend
if [ -f wrangler.toml.bak ]; then
mv wrangler.toml.bak wrangler.toml
fi
+3 -1
View File
@@ -5,11 +5,13 @@ logs
.secrets
.actrc
.event
.dev.vars
.vscode/*
.devcontainer/*
.test/*
.wrangler/*
package-lock.json
backend/.dev.vars
backend/.wrangler
backend/README.md
backend/node_modules
+113 -84
View File
@@ -53,110 +53,140 @@
## 🚀 详细部署指南
本项目设计为通过 **GitHub Actions** 自动化一键部署到你的 Cloudflare 账号下。只需几分钟即可获得你专属的 2FA 管理器。
本项目支持 2 种部署方式:**一键部署到 Cloudflare Workers** 和 **通过 GitHub Actions 部署**。请根据你的需要选择其中一种即可。
### 第一步:准备工作
---
### 方式一:一键部署到 Cloudflare Workers(推荐,新手友好)
这是最简便的部署方式,只需点击下方按钮,按照页面向导提示操作即可快速上线。
[![Deploy to Cloudflare Workers](https://deploy.workers.cloudflare.com/button)](https://deploy.workers.cloudflare.com/?url=https://github.com/nap0o/2fauth-worker)
**部署说明:**
1. 在部署之前,建议你先准备好你打算使用的**第三方登录(OAuth)配置**,例如 GitHub 的 Client ID / Secret(详见下文:[获取第三方登录密钥](#2-配置第三方登录))。
2. Fork 本仓库
2. 点击上方的 **Deploy to Cloudflare Workers** 按钮进入 Cloudflare 部署向导。
3. 根据向导提示,授权 Cloudflare 读取该仓库(系统会自动在你的 GitHub 账号下创建一个该项目的私有克隆)。
**授权 Cloudflare 读取 Github 仓库 步骤:**
<img height="400" alt="0001" src="https://github.com/user-attachments/assets/cb64bc2f-6dcc-40cb-a781-3bc2c7bc5b28" />
<img height="500" alt="0002" src="https://github.com/user-attachments/assets/3f186ea6-80f5-4d78-b90f-724af33a73ae" />
<img height="500" alt="0003" src="https://github.com/user-attachments/assets/c1f2d5ee-2f3f-47c2-969f-00308cadff21" />
4. 点击`创建和部署`,完成部署!
5. 访问专属的 `xxx.workers.dev` 域名,按照页面提示完成初始化配置。
---
### 方式二:通过 GitHub Actions 自动化部署(适合高级用户)
如果你需要更深入定制或打算持续集成,可以选择原生的 GitHub Actions 自动部署流程。
#### 1. 准备工作
1. 注册一个 [Cloudflare](https://dash.cloudflare.com/) 账号。
2. **Fork** 本仓库到你的 GitHub 账户。
### 第二步:获取 Cloudflare Worker部署令牌
#### 2. 获取 Cloudflare Worker部署令牌
1. 登录 Cloudflare Dashboard
2. [前往获取](https://dash.cloudflare.com/profile/api-tokens)
2. [前往获取](https://dash.cloudflare.com/profile/api-tokens) https://dash.cloudflare.com/profile/api-tokens
3. 点击“创建令牌”
4. 选择使用模版 “编辑 Cloudflare Workers”
5. 配置”帐户资源“和”区域资源“
6. 依次点击”继续以显示摘要“,点击”创建令牌“
5. 配置“帐户资源”和“区域资源”
6. 依次点击“继续以显示摘要”,点击“创建令牌”
7. 复制生成的令牌
<img width="500" alt="image" src="https://github.com/user-attachments/assets/6487aa6e-e505-4980-aef4-e08172116746" /><br />
<img width="800" alt="image" src="https://github.com/user-attachments/assets/d4c737f7-2d9f-4cfb-a712-b1af416c8ef6" />
### 第三步:配置 Cloudflare D1 数据库
#### 3. 配置 Cloudflare D1 数据库
1. 登录 Cloudflare Dashboard。
2. 依次点击左侧菜单的 **存储和数据库** -> **D1 SQL 数据库**。
3. 点击 **创建数据库**,命名为 `2fauth-db` (或自定义名称)。
4. 创建成功后,复制数据库详情页提供的 **`Database ID`**,备用。
### 第四步:配置第三方登录
*注:系统支持 6 种登录方式,你**至少需要配置一种***。推荐使用 `GitHub登录`
#### 4. 配置 GitHub Actions Secrets
前往你 Fork 仓库的 **Settings** -> **Secrets and variables** -> **Actions** -> **New repository secret**,添加下列关键参数:
#### 使用 GitHub 登录
1. 访问 GitHub `Settings` -> `Developer Settings` -> `OAuth Apps` -> **New OAuth App**。
- **基础平台令牌必填:**
- `CLOUDFLARE_ACCOUNT_ID`:你的 CF 账户 ID (CF 面板的概述页右下角可以找到)
- `CLOUDFLARE_API_TOKEN`:刚刚在“步骤 2”获取的部署令牌
- `CLOUDFLARE_D1_DATABASE_ID`:刚刚在“步骤 3”获取的 D1 数据库 ID
- `CLOUDFLARE_D1_DATABASE_NAME`:默认为 `2fauth-db`
- **系统安全与 OAuth 登录密钥:**
- `ENCRYPTION_KEY`、`JWT_SECRET` 及你要使用的 OAuth 登录配置,请统一查阅下方的 **[🧩 通用环境变量配置说明](#-通用环境变量配置说明)** 进行添加。
2. 填写应用信息:
- **名称**: `2FAuth`
- **Homepage URL**: 填入你预期的站点域名,例如 `https://2fa.yourdomain.workers.dev` (部署后可绑定自定义域名)
- **Authorization callback URL**: 重点!必须填写 `https://<Homepage URL>/oauth/callback`
3. 保存生成的 **`Client ID`** 和 **`Client Secret`**。
<img width="800" alt="image" src="https://github.com/user-attachments/assets/aa03b15f-deb2-4e48-bf4b-e57be342adbb" />
#### 方案二:使用 Telegram 登录
1. 在 Telegram 中搜索并添加官方机器人 **[@BotFather](https://t.me/BotFather)**。
2. 发送 `/newbot` 指令,按照提示为你的 2FAuth 创建一个机器人,并获取它的 **`Bot Token`**(如 `123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11`)。
3. 获取机器人的 **`Bot Name`**(就是你刚才设置的以 `bot` 结尾的用户名,例如 `my_2fa_bot`)
4. (非常重要)发送 `/setdomain` 指令,选择你刚才创建的机器人,然后发送你的应用域名(不需要 `https://`,例如:`2fa.yourdomain.workers.dev`)。
5. (非常重要)配置 Webhook
```bash
curl "https://api.telegram.org/bot<你的BotToken>/setWebhook?url=https://<你设置的setdomain>/api/telegram/webhook"
```
### 第五步:配置 GitHub Actions Secrets
前往你 Fork 的 GitHub 仓库的 **Settings** -> **Secrets and variables** -> **Actions** -> **New repository secret**,添加以下必填环境变量:
#### ☁️ 必填:Cloudflare 资源授权
| Secret Name | 说明 | 示例值 |
| :--- | :--- | :--- |
| `CLOUDFLARE_ACCOUNT_ID` | 你的 CF 账户 ID | `a1b2c3d4e5f6g7h8i9j0` (CF 面板的概述页右下角) |
| `CLOUDFLARE_API_TOKEN` | CF 部署令牌 | `r4_xyz...` |
#### 🔐 必填:系统安全参数
> ⚠️ **高危警告:关于 ENCRYPTION_KEY 的修改风险**
> `ENCRYPTION_KEY` 是用于加密数据库中 2FA 核心令牌种子的底层主密钥。**一旦系统投入生产使用并存入了数据,请绝对不要修改此环境变量的值!** 修改后将导致之前存入的所有数据瞬间无法解密,彻底变成死数据。
| Secret Name | 说明 | 示例值 |
| :--- | :--- | :--- |
| `OAUTH_ALLOWED_USERS` | 允许登录的账户白名单邮箱或Telegram 用户数字ID | `me@example.com,you@example.com,5341743823` (多个逗号分隔) |
| `OAUTH_ALLOW_ALL` | 无视白名单放行所有人(**仅限测试**) | `true` 或 `1` (生产环境切勿配置) |
| `JWT_SECRET` | 签发会话状态的系统密钥 | 越长越好, 建议 32 位随机字符 |
| `ENCRYPTION_KEY` | 对数据库持久化2FA核心密码集的唯一底层加密密钥 | **必填**。建议使用 `openssl rand -hex 32` 生成|
#### 🔑 必填:Cloudflare D1数据库参数
| Secret Name | 说明 | 示例值 |
| :--- | :--- | :--- |
| `CLOUDFLARE_D1_DATABASE_ID` | Cloudflare D1 数据库 ID | `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx` |
| `CLOUDFLARE_D1_DATABASE_NAME` | Cloudflare D1 数据库名称 | 默认为 `2fauth-db` |
#### 🔑 必填:OAuth 身份信息 (按需选择对应的组合)
> 如果你用 GitHub 登录,就填下面三个;如果你用 Google,就填 Google 的那三个。
| 平台 | Client ID 变量组 (示例) | Client Secret 变量组 (示例) | Redirect URI 变量组 (示例) |
| :--- | :--- | :--- | :--- |
| **GitHub** | `OAUTH_GITHUB_CLIENT_ID`<br>`Ov23...` | `OAUTH_GITHUB_CLIENT_SECRET`<br>`a1b2...` | `OAUTH_GITHUB_REDIRECT_URI`<br>`https://xxx.workers.dev/oauth/callback` |
| **Telegram** | `OAUTH_TELEGRAM_BOT_NAME`<br>`my_2fa_bot` | `OAUTH_TELEGRAM_BOT_TOKEN`<br>`123:ABC...` | *Telegram 无需 URI 变量* |
| **Google** | `OAUTH_GOOGLE_CLIENT_ID`<br>`123...apps.googleusercontent.com` | `OAUTH_GOOGLE_CLIENT_SECRET`<br>`GOCSPX-...` | `OAUTH_GOOGLE_REDIRECT_URI`<br>`https://xxx.workers.dev/oauth/callback` |
| **Cloudflare Access** | `OAUTH_CLOUDFLARE_CLIENT_ID`<br>`abc.access` | `OAUTH_CLOUDFLARE_CLIENT_SECRET`<br>`def...` | `OAUTH_CLOUDFLARE_REDIRECT_URI`<br>`https://xxx.workers.dev/oauth/callback`<br>*(该平台还需配置 `OAUTH_CLOUDFLARE_ORG_DOMAIN`,如: `https://<team>.cloudflareaccess.com`)* |
| **Gitee** | `OAUTH_GITEE_CLIENT_ID`<br>`bcd...` | `OAUTH_GITEE_CLIENT_SECRET`<br>`efg...` | `OAUTH_GITEE_REDIRECT_URI`<br>`https://xxx.workers.dev/oauth/callback` |
| **NodeLoc** | `OAUTH_NODELOC_CLIENT_ID`<br>`cde...` | `OAUTH_NODELOC_CLIENT_SECRET`<br>`fgh...` | `OAUTH_NODELOC_REDIRECT_URI`<br>`https://xxx.workers.dev/oauth/callback` |
<img width="800" alt="image" src="https://github.com/user-attachments/assets/ef907021-303d-4fd5-ba3e-913e8b0014a5" />
### 第五步:触发自动化部署
#### 5. 触发自动化部署
1. 进入你的 GitHub 仓库的 **Actions** 页面。
2. 找到 `Deploy to Cloudflare Workers` 工作流。
3. 点击 **Run workflow** 手动触发执行(或者随便 Push 一下 main 分支)。
4. **喝杯咖啡 ☕,等待自动化脚本完成:**
- 📦 自动构建 Vue 3 SPA 前端。
- 🗄️ 自动帮你初始化部署 D1 数据库内的表结构(Schema)。
- ⚡ 自动将带有静态前端的后端服务绑定至 Cloudflare 边缘节点。
5. 部署成功后,控制台会输出你的 `xxx.workers.dev` 链接。登录进去,开始你的私有化 2FA 之旅!
4. 等待自动化脚本完成,部署成功后,控制台会输出你的 `xxx.workers.dev` 访问链接。
6. 访问专属的 `xxx.workers.dev` 域名,按照页面提示完成初始化配置。
**手动触发deploy**
<img width="800" height="1350" alt="image" src="https://github.com/user-attachments/assets/b2891365-5c1a-4a46-83c6-5cd53dd4b895" />
**配置Secrets and variables示例**
<img width="800" alt="image" src="https://github.com/user-attachments/assets/ef907021-303d-4fd5-ba3e-913e8b0014a5" />
---
### 🧩 通用环境变量配置说明
以下环境变量,不论是通过 **"方案一:一键部署"** 还是 **"方案二:GitHub Actions"**,都需要在Worker设置页面或仓库 Secrets 中按需配置:
#### 1. 核心安全参数(必填!)
> ⚠️ **高危警告:关于 ENCRYPTION_KEY 的修改风险**
> `ENCRYPTION_KEY` 是用于加密数据库中 2FA 核心令牌种子的底层主密钥。**一旦系统投入生产使用并存入数据,请绝对不要再修改此环境变量的值!** 如果该密钥丢失或更改,数据库里旧的数据将无法解密!
| 变量 / Secret Name | 说明 | 示例值 |
| :--- | :--- | :--- |
| `ENCRYPTION_KEY` | 对数据库持久化2FA核心密种加密的主密钥 | **必填**。建议使用 `openssl rand -hex 32` 生成,务必自己保存好备份。 |
| `JWT_SECRET` | 签发安全会话状态的系统密钥 | **必填**。越长越好, 建议输入 32 位随机字符。 |
| `OAUTH_ALLOWED_USERS` | 允许登录系统的白名单:支持填入邮箱,或 Telegram数字ID | **必填**。`me@example.com,you@example.com,5341743823` (多个配置必须用逗号分隔) |
#### 2. 配置第三方登录
*系统支持多种登录方式,你**至少需要选择一种进行环境配置***。我们最推荐使用 `GitHub` 作为后台登录。
**使用 GitHub 登录获取办法**
1. 访问 GitHub `Settings` -> `Developer Settings` -> `OAuth Apps` -> **New OAuth App**。
2. 填写应用信息:
- **名称**: `2FAuth Worker`
- **Homepage URL**: 填入你预期的站点域名,例如 `https://2fa.yourdomain.workers.dev` (部署后可绑定自定义域名)
- **Authorization callback URL**: 必须填写 `https://<你的Homepage URL>/oauth/callback`
3. 保存并复制生成的 **`Client ID`** 和 **`Client Secret`**。
<img width="800" alt="image" src="https://github.com/user-attachments/assets/aa03b15f-deb2-4e48-bf4b-e57be342adbb" />
**使用 Telegram 登录获取办法**
1. 在 Telegram 中搜索并添加官方机器人 **[@BotFather](https://t.me/BotFather)**。
2. 发送 `/newbot` 指令,按照提示为你的 2FAuth 创建机器人,记录它的 **`Bot Token`**(如 `123456:ABC-DEF1234...`)。
3. 记录机器人的 **`Bot Name`**(也就是你刚设置的以 bot 结尾的用户名,例如 `my_2fa_bot`)
4. (非常重要)发送 `/setdomain` 指令,选择此机器人,然后发送你的应用域名(不需要 `https://`,例如:`2fa.yourdomain.workers.dev`)。
5. (非常重要)由于我们要使用无服务器直接验证,需要配置 Webhook,复制下方链接在浏览器中访问一次注册 Webhook:
```url
https://api.telegram.org/bot<你的BotToken>/setWebhook?url=https://<你的应用域名>/api/telegram/webhook
```
**依据你选取的登录平台填入所需变量(任选一对即可):**
> 如果你使用 GitHub 登录,就在环境变量里配置 GitHub 那一行提供的所有变量选项。其它平台类似。
| 平台 | Client ID 变量群 | Client Secret 变量群 | Redirect URI 回调变量群 (示例:`https://xxx.dev/oauth/callback`) |
| :--- | :--- | :--- | :--- |
| **GitHub** | `OAUTH_GITHUB_CLIENT_ID` | `OAUTH_GITHUB_CLIENT_SECRET` | `OAUTH_GITHUB_REDIRECT_URI` |
| **Telegram** | `OAUTH_TELEGRAM_BOT_NAME`*(填你的Bot名称)* | `OAUTH_TELEGRAM_BOT_TOKEN`*(填Bot的Token密钥)* | *Telegram 无需 URI 回调变量* |
| **Google** | `OAUTH_GOOGLE_CLIENT_ID` | `OAUTH_GOOGLE_CLIENT_SECRET` | `OAUTH_GOOGLE_REDIRECT_URI` |
| **Cloudflare Access** | `OAUTH_CLOUDFLARE_CLIENT_ID` | `OAUTH_CLOUDFLARE_CLIENT_SECRET` | `OAUTH_CLOUDFLARE_REDIRECT_URI`<br>*(该平台还缺一不可:需额外配置 `OAUTH_CLOUDFLARE_ORG_DOMAIN`,如: `https://<team>.cloudflareaccess.com`)* |
| **Gitee** | `OAUTH_GITEE_CLIENT_ID` | `OAUTH_GITEE_CLIENT_SECRET` | `OAUTH_GITEE_REDIRECT_URI` |
| **NodeLoc** | `OAUTH_NODELOC_CLIENT_ID` | `OAUTH_NODELOC_CLIENT_SECRET` | `OAUTH_NODELOC_REDIRECT_URI` |
---
@@ -169,19 +199,20 @@ git clone https://github.com/nap0o/2fauth-worker.git
cd 2fauth-worker
# 1. 给前后端分别安装依赖
cd frontend && npm install
cd ../backend && npm install
npm install
# 2. 在 backend 目录,复制 example.dev.vars 为 .dev.vars, 按说明写入开发用的测试密钥
# 2.复制 example.dev.vars 为 .dev.vars, 按说明写入开发用的测试密钥
cp example.dev.vars .dev.vars
# 3. 初始化本地的 SQLite Sandbox 数据库
npx wrangler d1 execute 2fauth-db-dev --local --env dev --file=schema.sql
npx wrangler d1 execute 2fauth-db-dev --local --env dev --file=backend/schema.sql
# 4. 终端启动应用
npm run dev
```
---
## 🏗️ 全栈项目架构
本项目遵循现代化的 **Feature-based 垂直模块化架构**:
@@ -192,8 +223,6 @@ npm run dev
---
---
## 🛡️ 安全性声明 (Security Policy)
本项目涉及高度敏感的 2FA 认证种子数据的云端存储,在架构安全方面我们做出了如下强制约束:
+2 -6
View File
@@ -1,12 +1,8 @@
{
"name": "2FAuth Worker",
"version": "1.0.2",
"description": "A Secure 2FA Management Tool running on Cloudflare Workers",
"author": "nap0o",
"license": "AGPL-3.0",
"name": "backend",
"type": "module",
"scripts": {
"dev": "wrangler dev --config wrangler.dev.toml --host 0.0.0.0 --port 8787 --test-scheduled",
"dev": "wrangler dev --config ../wrangler.dev.toml --host 0.0.0.0 --port 8787 --test-scheduled",
"deploy": "wrangler deploy --minify"
},
"dependencies": {
+29 -5
View File
@@ -7,6 +7,8 @@ export interface HealthIssue {
level: HealthIssueLevel;
message: string;
suggestion: string;
deploy_by_worker: string;
deploy_by_gitaction: string;
missingFields?: string[];
}
@@ -28,7 +30,9 @@ export const runHealthCheck = (env: EnvBindings): HealthCheckResult => {
field: 'ENCRYPTION_KEY',
level: 'critical',
message: 'encryption_key_too_short',
suggestion: 'encryption_key_suggestion'
suggestion: 'encryption_key_suggestion',
deploy_by_worker: 'suggestion_deploy_by_worker',
deploy_by_gitaction: 'suggestion_deploy_by_gitaction'
});
} else {
passedChecks.push('encryption_key_passed');
@@ -41,7 +45,9 @@ export const runHealthCheck = (env: EnvBindings): HealthCheckResult => {
field: 'JWT_SECRET',
level: 'critical',
message: 'jwt_secret_too_short',
suggestion: 'jwt_secret_suggestion'
suggestion: 'jwt_secret_suggestion',
deploy_by_worker: 'suggestion_deploy_by_worker',
deploy_by_gitaction: 'suggestion_deploy_by_gitaction'
});
} else {
passedChecks.push('jwt_secret_passed');
@@ -53,7 +59,9 @@ export const runHealthCheck = (env: EnvBindings): HealthCheckResult => {
field: 'OAUTH_ALLOW_ALL',
level: 'critical',
message: 'oauth_allow_all_enabled',
suggestion: 'oauth_allow_all_suggestion'
suggestion: 'oauth_allow_all_suggestion',
deploy_by_worker: 'suggestion_deploy_by_worker',
deploy_by_gitaction: 'suggestion_deploy_by_gitaction'
});
} else {
passedChecks.push('oauth_allow_all_passed');
@@ -66,7 +74,9 @@ export const runHealthCheck = (env: EnvBindings): HealthCheckResult => {
field: 'OAUTH_ALLOWED_USERS',
level: 'error',
message: 'allowed_users_empty',
suggestion: 'allowed_users_suggestion'
suggestion: 'allowed_users_suggestion',
deploy_by_worker: 'suggestion_deploy_by_worker',
deploy_by_gitaction: 'suggestion_deploy_by_gitaction'
});
} else {
passedChecks.push('allowed_users_passed');
@@ -92,6 +102,8 @@ export const runHealthCheck = (env: EnvBindings): HealthCheckResult => {
level: 'error',
message: 'github_config_incomplete',
suggestion: 'github_config_suggestion',
deploy_by_worker: 'suggestion_deploy_by_worker',
deploy_by_gitaction: 'suggestion_deploy_by_gitaction',
missingFields: missing
});
} else {
@@ -113,6 +125,8 @@ export const runHealthCheck = (env: EnvBindings): HealthCheckResult => {
level: 'error',
message: 'telegram_config_incomplete',
suggestion: 'telegram_config_suggestion',
deploy_by_worker: 'suggestion_deploy_by_worker',
deploy_by_gitaction: 'suggestion_deploy_by_gitaction',
missingFields: missing
});
} else {
@@ -135,6 +149,8 @@ export const runHealthCheck = (env: EnvBindings): HealthCheckResult => {
level: 'error',
message: 'google_config_incomplete',
suggestion: 'google_config_suggestion',
deploy_by_worker: 'suggestion_deploy_by_worker',
deploy_by_gitaction: 'suggestion_deploy_by_gitaction',
missingFields: missing
});
} else {
@@ -157,6 +173,8 @@ export const runHealthCheck = (env: EnvBindings): HealthCheckResult => {
level: 'error',
message: 'nodeloc_config_incomplete',
suggestion: 'nodeloc_config_suggestion',
deploy_by_worker: 'suggestion_deploy_by_worker',
deploy_by_gitaction: 'suggestion_deploy_by_gitaction',
missingFields: missing
});
} else {
@@ -179,6 +197,8 @@ export const runHealthCheck = (env: EnvBindings): HealthCheckResult => {
level: 'error',
message: 'gitee_config_incomplete',
suggestion: 'gitee_config_suggestion',
deploy_by_worker: 'suggestion_deploy_by_worker',
deploy_by_gitaction: 'suggestion_deploy_by_gitaction',
missingFields: missing
});
} else {
@@ -202,6 +222,8 @@ export const runHealthCheck = (env: EnvBindings): HealthCheckResult => {
level: 'error',
message: 'cloudflare_config_incomplete',
suggestion: 'cloudflare_config_suggestion',
deploy_by_worker: 'suggestion_deploy_by_worker',
deploy_by_gitaction: 'suggestion_deploy_by_gitaction',
missingFields: missing
});
} else {
@@ -216,7 +238,9 @@ export const runHealthCheck = (env: EnvBindings): HealthCheckResult => {
field: 'NO_OAUTH_PROVIDER',
level: 'error',
message: 'no_provider_configured',
suggestion: 'no_provider_suggestion'
suggestion: 'no_provider_suggestion',
deploy_by_worker: 'suggestion_deploy_by_worker',
deploy_by_gitaction: 'suggestion_deploy_by_gitaction'
});
} else {
passedChecks.push('oauth_provider_configured');
File renamed without changes.
@@ -38,6 +38,15 @@
<div class="suggestion-box">
<div class="suggestion-title">{{ $t('healthCheck.how_to_fix') }}</div>
<div v-if="issue.deploy_by_worker || issue.deploy_by_gitaction" class="deploy-method-guide">
<p v-if="issue.deploy_by_worker" class="deploy-item">
<el-icon><Monitor /></el-icon> {{ $t(`healthCheck.suggestions.${issue.deploy_by_worker}`) }}
</p>
<p v-if="issue.deploy_by_gitaction" class="deploy-item">
<el-icon><Setting /></el-icon> {{ $t(`healthCheck.suggestions.${issue.deploy_by_gitaction}`) }}
</p>
</div>
<!-- 针对短密码的特殊处理:提供一键生成 -->
<div v-if="issue.message === 'encryption_key_too_short' || issue.message === 'jwt_secret_too_short'" class="fix-action">
<p>{{ $t(`healthCheck.suggestions.${issue.suggestion}`) }}</p>
@@ -90,7 +99,7 @@
<script setup>
import { ref, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { WarningFilled, CopyDocument, Refresh, Document, Select } from '@element-plus/icons-vue'
import { WarningFilled, CopyDocument, Refresh, Document, Select, Monitor, Setting } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import { request } from '@/shared/utils/request'
import { useClipboard } from '@vueuse/core'
@@ -292,6 +301,22 @@ onMounted(() => {
color: var(--el-text-color-regular);
}
.deploy-method-guide {
margin-bottom: 12px;
padding-bottom: 8px;
border-bottom: 1px dashed var(--el-border-color);
}
.deploy-item {
display: flex;
align-items: center;
gap: 6px;
margin: 0 0 8px 0;
font-size: 13px;
color: var(--el-text-color-primary);
font-weight: 500;
}
.text-danger p {
color: var(--el-color-danger);
font-weight: bold;
+12 -10
View File
@@ -546,16 +546,18 @@
}
},
"suggestions": {
"encryption_key_suggestion": "Copy the secure 32-byte key we generated locally below. Paste it into your Cloudflare -> Workers -> Settings -> Variables as ENCRYPTION_KEY.",
"jwt_secret_suggestion": "Copy the pre-generated cryptographically secure key below. Set it as your JWT_SECRET in Cloudflare.",
"oauth_allow_all_suggestion": "Immediate Action Required: Go to your Cloudflare dashboard and delete the OAUTH_ALLOW_ALL variable, or set it to false.",
"allowed_users_suggestion": "Add OAUTH_ALLOWED_USERS in your Cloudflare environment variables, and populate it with your GitHub (or respective platform) registered emails, separated by commas.",
"github_config_suggestion": "Verify your GitHub OAuth App secrets and keys.",
"telegram_config_suggestion": "Check your BotFather configurations and ensure all tokens are present.",
"google_config_suggestion": "Visit the Google Cloud Console and verify credentials.",
"nodeloc_config_suggestion": "Visit the NodeLoc Developer Dashboard and verify credentials.",
"gitee_config_suggestion": "Verify your Gitee developer credentials.",
"cloudflare_config_suggestion": "Four parameters are required: Client ID, Secret, Org Domain, and Redirect URI.",
"suggestion_deploy_by_worker": "One-click Deploy to Worker: Go to Cloudflare Dashboard -> Workers & Pages -> 2fauth-worker -> Settings -> Variables and Secrets",
"suggestion_deploy_by_gitaction": "Deploy via Github Action: Go to Forked Repository -> Settings -> Secrets and variables -> Actions",
"encryption_key_suggestion": "Please copy the high-strength random key pre-generated for you below, and set it as ENCRYPTION_KEY according to your deployment method.",
"jwt_secret_suggestion": "Please copy the high-strength random key pre-generated for you below, and set it as JWT_SECRET according to your deployment method.",
"oauth_allow_all_suggestion": "Depending on your deployment method, remove OAUTH_ALLOW_ALL or set its value to false.",
"allowed_users_suggestion": "Depending on your deployment method, fill in OAUTH_ALLOWED_USERS.",
"github_config_suggestion": "Depending on your deployment method, fill in OAUTH_GITHUB_CLIENT_ID, OAUTH_GITHUB_CLIENT_SECRET, and OAUTH_GITHUB_REDIRECT_URI.",
"telegram_config_suggestion": "Please check the bot configuration in BotFather to ensure the information is complete, and depending on your deployment method, fill in OAUTH_TELEGRAM_BOT_NAME, OAUTH_TELEGRAM_BOT_TOKEN, and OAUTH_TELEGRAM_REDIRECT_URI.",
"google_config_suggestion": "Please check the credentials configuration in Google Cloud Console, and depending on your deployment method, fill in OAUTH_GOOGLE_CLIENT_ID, OAUTH_GOOGLE_CLIENT_SECRET, and OAUTH_GOOGLE_REDIRECT_URI.",
"nodeloc_config_suggestion": "Please check your developer credentials in NodeLoc panel, and depending on your deployment method, fill in OAUTH_NODELOC_CLIENT_ID, OAUTH_NODELOC_CLIENT_SECRET, and OAUTH_NODELOC_REDIRECT_URI.",
"gitee_config_suggestion": "Please verify Gitee developer credentials, and depending on your deployment method, fill in OAUTH_GITEE_CLIENT_ID, OAUTH_GITEE_CLIENT_SECRET, and OAUTH_GITEE_REDIRECT_URI.",
"cloudflare_config_suggestion": "Requires four parameters: Client ID, Secret, Org Domain, Redirect URI. Depending on your deployment method, fill in OAUTH_CLOUDFLARE_CLIENT_ID, OAUTH_CLOUDFLARE_CLIENT_SECRET, and OAUTH_CLOUDFLARE_REDIRECT_URI.",
"no_provider_suggestion": "Consult the README to pick the easiest provider. Retrieve the Client ID and Secret and configure them in Cloudflare's dashboard."
}
}
+12 -10
View File
@@ -546,16 +546,18 @@
}
},
"suggestions": {
"encryption_key_suggestion": "请复制下方为您预生成的高强度随机密钥。请立刻前往 Fork的Github仓库 -> Settings -> Secrets and variables -> Actions -> 将其填入 ENCRYPTION_KEY",
"jwt_secret_suggestion": "请复制下方为您预生成的高强度随机密钥。请立刻前往 Fork的Github仓库 -> Settings -> Secrets and variables -> Actions -> 将其填入 JWT_SECRET",
"oauth_allow_all_suggestion": "请立刻前往 Fork的Github仓库 -> Settings -> Secrets and variables -> Actions,将环境变量 OAUTH_ALLOW_ALL 删除,或将其值修改为 false。",
"allowed_users_suggestion": "请在 Fork的Github仓库 -> Settings -> Secrets and variables -> Actions中添加 OAUTH_ALLOWED_USERS,并填入您在 GitHub(或其它平台)上对应的注册邮箱地址(多个以英文逗号分隔)。",
"github_config_suggestion": "请核对获取的 GitHub OAuth Apps 密钥信息,然后前往 Fork的Github仓库 -> Settings -> Secrets and variables -> Actions,将环境变量 OAUTH_GITHUB_CLIENT_ID、OAUTH_GITHUB_CLIENT_SECRET、OAUTH_GITHUB_REDIRECT_URI 填入",
"telegram_config_suggestion": "请在 BotFather 检查机器人配置,确保信息填全,然后前往 Fork的Github仓库 -> Settings -> Secrets and variables -> Actions,将环境变量 OAUTH_TELEGRAM_BOT_NAME、OAUTH_TELEGRAM_BOT_TOKEN、OAUTH_TELEGRAM_REDIRECT_URI 填入",
"google_config_suggestion": "请前往 Google Cloud Console 检查凭据配置,然后前往 Fork的Github仓库 -> Settings -> Secrets and variables -> Actions,将环境变量 OAUTH_GOOGLE_CLIENT_ID、OAUTH_GOOGLE_CLIENT_SECRET、OAUTH_GOOGLE_REDIRECT_URI 填入",
"nodeloc_config_suggestion": "请前往 NodeLoc 面板检查您的开发者凭据,然后前往 Fork的Github仓库 -> Settings -> Secrets and variables -> Actions,将环境变量 OAUTH_NODELOC_CLIENT_ID、OAUTH_NODELOC_CLIENT_SECRET、OAUTH_NODELOC_REDIRECT_URI 填入",
"gitee_config_suggestion": "请核对 Gitee 开发者凭据,然后前往 Fork的Github仓库 -> Settings -> Secrets and variables -> Actions,将环境变量 OAUTH_GITEE_CLIENT_ID、OAUTH_GITEE_CLIENT_SECRET、OAUTH_GITEE_REDIRECT_URI 填入",
"cloudflare_config_suggestion": "需要四位一体的参数:Client ID, Secret, Org Domain, Redirect URI,然后前往 Cloudflare 后台 -> Workers 和 Pages -> 2fauth-worker -> 设置 -> 变量和机密,将环境变量 OAUTH_CLOUDFLARE_CLIENT_ID、OAUTH_CLOUDFLARE_CLIENT_SECRET、OAUTH_CLOUDFLARE_REDIRECT_URI 填入",
"suggestion_deploy_by_worker": "Worker 一键部署: 前往 Cloudflare 后台 -> Workers 和 Pages -> 2fauth-worker -> 设置 -> 变量和机密",
"suggestion_deploy_by_gitaction": "Github Action部署: 前往 Fork 仓库 -> Settings -> Secrets and variables -> Actions",
"encryption_key_suggestion": "请复制下方为您预生成的高强度随机密钥,根据不同部署方式填入,将其填入 ENCRYPTION_KEY 。",
"jwt_secret_suggestion": "请复制下方为您预生成的高强度随机密钥,根据不同部署方式填入,将其填入 JWT_SECRET 。",
"oauth_allow_all_suggestion": "根据不同部署方式,将 OAUTH_ALLOW_ALL 删除将其值修改为 false。",
"allowed_users_suggestion": "根据不同部署方式,填入 OAUTH_ALLOWED_USERS ",
"github_config_suggestion": "根据不同部署方式,填入 OAUTH_GITHUB_CLIENT_ID、OAUTH_GITHUB_CLIENT_SECRET、OAUTH_GITHUB_REDIRECT_URI ",
"telegram_config_suggestion": "请在 BotFather 检查机器人配置,确保信息填全,根据不同部署方式,填入 OAUTH_TELEGRAM_BOT_NAME、OAUTH_TELEGRAM_BOT_TOKEN、OAUTH_TELEGRAM_REDIRECT_URI",
"google_config_suggestion": "请前往 Google Cloud Console 检查凭据配置,根据不同部署方式,填入 OAUTH_GOOGLE_CLIENT_ID、OAUTH_GOOGLE_CLIENT_SECRET、OAUTH_GOOGLE_REDIRECT_URI",
"nodeloc_config_suggestion": "请前往 NodeLoc 面板检查您的开发者凭据,根据不同部署方式,填入 OAUTH_NODELOC_CLIENT_ID、OAUTH_NODELOC_CLIENT_SECRET、OAUTH_NODELOC_REDIRECT_URI 填入",
"gitee_config_suggestion": "请核对 Gitee 开发者凭据,,根据不同部署方式,填入 OAUTH_GITEE_CLIENT_ID、OAUTH_GITEE_CLIENT_SECRET、OAUTH_GITEE_REDIRECT_URI 填入",
"cloudflare_config_suggestion": "需要四位一体的参数:Client ID, Secret, Org Domain, Redirect URI,根据不同部署方式,填入 OAUTH_CLOUDFLARE_CLIENT_ID、OAUTH_CLOUDFLARE_CLIENT_SECRET、OAUTH_CLOUDFLARE_REDIRECT_URI 填入",
"no_provider_suggestion": "阅读2Fauth Worker 的 README,挑选最适合您且配置最简单的一种登录方式,按照其说明获取 Client ID 与 Secret 并在云端配置。"
}
}
+12
View File
@@ -0,0 +1,12 @@
{
"name": "2fauth-worker",
"version": "1.0.2",
"description": "A Secure 2FA Management Tool running on Cloudflare Workers",
"author": "nap0o",
"license": "AGPL-3.0",
"private": true,
"scripts": {
"postinstall": "npm install --prefix backend && npm install --prefix frontend",
"dev": "npm run dev --prefix backend & npm run dev --prefix frontend"
}
}
@@ -1,16 +1,16 @@
name = "2fauth-worker-demo"
main = "src/app/index.ts"
main = "backend/src/app/index.ts"
compatibility_date = "2024-04-01"
compatibility_flags = ["nodejs_compat"]
[assets]
binding = "ASSETS"
directory = "../frontend/dist"
directory = "frontend/dist"
not_found_handling = "single-page-application"
run_worker_first = true
[build]
command = "npm run build --prefix ../frontend"
command = "npm run build --prefix frontend"
[[d1_databases]]
binding = "DB"
@@ -1,11 +1,11 @@
name = "2fauth-worker-dev"
main = "src/app/index.ts"
main = "backend/src/app/index.ts"
compatibility_date = "2024-04-01"
compatibility_flags = ["nodejs_compat"]
[assets]
binding = "ASSETS"
directory = "../frontend/dist"
directory = "frontend/dist"
not_found_handling = "single-page-application"
run_worker_first = true
+5 -5
View File
@@ -1,16 +1,16 @@
name = "2fauth-worker"
main = "src/app/index.ts"
main = "backend/src/app/index.ts"
compatibility_date = "2024-04-01"
compatibility_flags = ["nodejs_compat"]
[assets]
binding = "ASSETS"
directory = "../frontend/dist"
directory = "frontend/dist"
not_found_handling = "single-page-application"
run_worker_first = false
run_worker_first = true
[build]
command = "npm run build --prefix ../frontend"
command = "npm run build --prefix frontend"
[[d1_databases]]
binding = "DB"
@@ -24,4 +24,4 @@ crons = ["0 2 * * *"]
[[env.dev.d1_databases]]
binding = "DB"
database_name = "2fauth-db-dev"
database_id = "9e591736-5dbb-4f09-8769-0270d7257731"
database_id = "9e591736-5dbb-4f09-8769-0270d7257731"