Add build.sh for Cloudflare Pages env-based config injection

- Add build.sh that generates auth-config.js from environment variables
  (API_BASE_URL, GOOGLE_CLIENT_ID, ALLOWED_EMAILS) at build time
- Move email whitelist from hardcoded login.html to window.ALLOWED_EMAILS
  in auth-config.js, so it can be configured via env vars
- Reset auth-config.js to placeholder defaults in repo
- Update README.md and README_CN.md deployment docs for both options

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
0xcathiefish
2026-02-14 15:45:33 +00:00
parent 9812bc7635
commit 619391f87a
5 changed files with 75 additions and 90 deletions
+20 -36
View File
@@ -13,6 +13,7 @@ If deploying the backend is too difficult, you can temporarily use my public bac
![tv-1](https://img.cathiefish.art/ns/tv-1.png) ![tv-1](https://img.cathiefish.art/ns/tv-1.png)
![tv-2](https://img.cathiefish.art/ns/tv-2.png) ![tv-2](https://img.cathiefish.art/ns/tv-2.png)
![tv-3](https://img.cathiefish.art/ns/tv-3.png) ![tv-3](https://img.cathiefish.art/ns/tv-3.png)
![tv-3](https://img.cathiefish.art/ns/tv-4.png)
## ✨ Features ## ✨ Features
@@ -228,23 +229,24 @@ docker compose up -d
Before building the frontend container, you need to configure authentication and API connection. Before building the frontend container, you need to configure authentication and API connection.
**1. Configure Google OAuth — `auth-config.js`** **1. Configure `auth-config.js`**
Since the frontend runs inside the Docker network, it accesses the backend via the **container name**: Since the frontend runs inside the Docker network, it accesses the backend via the **container name**:
```js ```js
// Use the backend container name as the hostname (internal Docker DNS)
window.API_CONFIG = { baseUrl: 'http://backend:3000' }; window.API_CONFIG = { baseUrl: 'http://backend:3000' };
const AUTH_CONFIG = { const AUTH_CONFIG = {
// Replace with your Google OAuth Client ID from GCP Console
clientId: 'YOUR_CLIENT_ID.apps.googleusercontent.com', clientId: 'YOUR_CLIENT_ID.apps.googleusercontent.com',
onSuccess: (user) => { console.log('Auth successful:', user.email); }, onSuccess: (user) => { console.log('Auth successful:', user.email); },
onError: (error) => { console.error('Auth error:', error); } onError: (error) => { console.error('Auth error:', error); }
}; };
window.AUTH_CONFIG = AUTH_CONFIG; window.AUTH_CONFIG = AUTH_CONFIG;
window.ALLOWED_EMAILS = ['your-email@gmail.com'];
``` ```
Replace `clientId` with your Google OAuth Client ID from GCP Console, and `ALLOWED_EMAILS` with your email whitelist.
To find the backend container IP (useful for debugging): To find the backend container IP (useful for debugging):
```bash ```bash
@@ -252,15 +254,7 @@ $ docker inspect backend --format '{{range .NetworkSettings.Networks}}{{.IPAddre
172.18.0.3 172.18.0.3
``` ```
**2. Configure Email Whitelist — `login.html`** > [!IMPORTANT]
Add your Google account email to the whitelist:
```js
const allowedEmails = ['your-email@gmail.com'];
```
> [!IMPORTANT]
> Google OAuth requires a Client ID from GCP Console. Tutorial placeholder — to be added. > Google OAuth requires a Client ID from GCP Console. Tutorial placeholder — to be added.
**3. Build & Run** **3. Build & Run**
@@ -353,28 +347,7 @@ Since the frontend will be served from Cloudflare (outside your Docker network),
> [!IMPORTANT] > [!IMPORTANT]
> Enable **Websockets Support** for this proxy host — required for real-time candle streaming. > Enable **Websockets Support** for this proxy host — required for real-time candle streaming.
#### Step 3: Configure Frontend #### Step 3: Deploy to Cloudflare Pages
Before deploying to Cloudflare, update the config files:
**`auth-config.js`** — point `baseUrl` to the **public backend domain** from Step 2:
```js
window.API_CONFIG = { baseUrl: 'https://api.yourdomain.com' };
const AUTH_CONFIG = {
clientId: 'YOUR_CLIENT_ID.apps.googleusercontent.com',
// ...
};
```
**`login.html`** — add your email to the whitelist:
```js
const allowedEmails = ['your-email@gmail.com'];
```
#### Step 4: Deploy to Cloudflare Pages
1. Fork or clone this repository to your own GitHub account 1. Fork or clone this repository to your own GitHub account
2. Go to [Cloudflare Dashboard](https://dash.cloudflare.com/) → **Workers & Pages****Create** 2. Go to [Cloudflare Dashboard](https://dash.cloudflare.com/) → **Workers & Pages****Create**
@@ -385,10 +358,21 @@ const allowedEmails = ['your-email@gmail.com'];
| Setting | Value | | Setting | Value |
|---------|-------| |---------|-------|
| Production branch | `main` | | Production branch | `main` |
| Build command | *(leave empty)* | | Build command | `sh build.sh` |
| Build output directory | `frontend` | | Build output directory | `frontend` |
6. Click **Save and Deploy** 6. Add **Environment Variables** (Settings → Environment Variables):
| Variable | Value | Description |
|----------|-------|-------------|
| `API_BASE_URL` | `https://api.yourdomain.com` | Public backend API URL from Step 2 |
| `GOOGLE_CLIENT_ID` | `YOUR_CLIENT_ID.apps.googleusercontent.com` | Google OAuth Client ID from GCP Console |
| `ALLOWED_EMAILS` | `alice@gmail.com,bob@gmail.com` | Comma-separated email whitelist |
7. Click **Save and Deploy**
> [!NOTE]
> The `build.sh` script generates `auth-config.js` from environment variables at build time. No sensitive values are stored in the repository — all credentials are configured via Cloudflare's environment variables dashboard.
Cloudflare will assign a `*.pages.dev` domain. You can add a custom domain in **Pages****Custom domains**. Cloudflare will assign a `*.pages.dev` domain. You can add a custom domain in **Pages****Custom domains**.
+20 -36
View File
@@ -11,6 +11,7 @@
![tv-1](https://img.cathiefish.art/ns/tv-1.png) ![tv-1](https://img.cathiefish.art/ns/tv-1.png)
![tv-2](https://img.cathiefish.art/ns/tv-2.png) ![tv-2](https://img.cathiefish.art/ns/tv-2.png)
![tv-3](https://img.cathiefish.art/ns/tv-3.png) ![tv-3](https://img.cathiefish.art/ns/tv-3.png)
![tv-3](https://img.cathiefish.art/ns/tv-4.png)
## ✨ 功能 ## ✨ 功能
@@ -226,23 +227,24 @@ docker compose up -d
构建前端容器之前,需要先配置认证和 API 连接。 构建前端容器之前,需要先配置认证和 API 连接。
**1. 配置 Google OAuth — `auth-config.js`** **1. 配置 `auth-config.js`**
前端在 Docker 网络内部运行,通过**容器名**访问后端: 前端在 Docker 网络内部运行,通过**容器名**访问后端:
```js ```js
// 使用后端容器名作为主机名(Docker 内部 DNS)
window.API_CONFIG = { baseUrl: 'http://backend:3000' }; window.API_CONFIG = { baseUrl: 'http://backend:3000' };
const AUTH_CONFIG = { const AUTH_CONFIG = {
// 替换为你从 GCP Console 获取的 Google OAuth Client ID
clientId: 'YOUR_CLIENT_ID.apps.googleusercontent.com', clientId: 'YOUR_CLIENT_ID.apps.googleusercontent.com',
onSuccess: (user) => { console.log('Auth successful:', user.email); }, onSuccess: (user) => { console.log('Auth successful:', user.email); },
onError: (error) => { console.error('Auth error:', error); } onError: (error) => { console.error('Auth error:', error); }
}; };
window.AUTH_CONFIG = AUTH_CONFIG; window.AUTH_CONFIG = AUTH_CONFIG;
window.ALLOWED_EMAILS = ['your-email@gmail.com'];
``` ```
`clientId` 替换为你从 GCP Console 获取的 Google OAuth Client ID,将 `ALLOWED_EMAILS` 替换为你的邮箱白名单。
查询后端容器 IP(调试用): 查询后端容器 IP(调试用):
```bash ```bash
@@ -250,15 +252,7 @@ $ docker inspect backend --format '{{range .NetworkSettings.Networks}}{{.IPAddre
172.18.0.3 172.18.0.3
``` ```
**2. 配置邮箱白名单 — `login.html`** > [!IMPORTANT]
将你的 Google 邮箱添加到白名单:
```js
const allowedEmails = ['your-email@gmail.com'];
```
> [!IMPORTANT]
> Google OAuth 需要从 GCP Console 获取 Client ID。教程待补充。 > Google OAuth 需要从 GCP Console 获取 Client ID。教程待补充。
**3. 构建并运行** **3. 构建并运行**
@@ -351,28 +345,7 @@ docker compose up -d
> [!IMPORTANT] > [!IMPORTANT]
> 为此 Proxy Host 启用 **Websockets Support** —— 实时 K 线推送需要 WebSocket。 > 为此 Proxy Host 启用 **Websockets Support** —— 实时 K 线推送需要 WebSocket。
#### 第三步:配置前端 #### 第三步:部署到 Cloudflare Pages
部署到 Cloudflare 之前,更新配置文件:
**`auth-config.js`** —— 将 `baseUrl` 指向第二步的**公网后端域名**
```js
window.API_CONFIG = { baseUrl: 'https://api.yourdomain.com' };
const AUTH_CONFIG = {
clientId: 'YOUR_CLIENT_ID.apps.googleusercontent.com',
// ...
};
```
**`login.html`** —— 添加你的邮箱到白名单:
```js
const allowedEmails = ['your-email@gmail.com'];
```
#### 第四步:部署到 Cloudflare Pages
1. Fork 或 Clone 本仓库到你自己的 GitHub 账号 1. Fork 或 Clone 本仓库到你自己的 GitHub 账号
2. 进入 [Cloudflare 控制台](https://dash.cloudflare.com/) → **Workers & Pages****创建** 2. 进入 [Cloudflare 控制台](https://dash.cloudflare.com/) → **Workers & Pages****创建**
@@ -383,10 +356,21 @@ const allowedEmails = ['your-email@gmail.com'];
| 设置 | 值 | | 设置 | 值 |
|------|---| |------|---|
| 生产分支 | `main` | | 生产分支 | `main` |
| 构建命令 | *(留空)* | | 构建命令 | `sh build.sh` |
| 构建输出目录 | `frontend` | | 构建输出目录 | `frontend` |
6. 点击 **保存并部署** 6. 添加**环境变量**(设置 → 环境变量):
| 变量 | 值 | 说明 |
|------|---|------|
| `API_BASE_URL` | `https://api.yourdomain.com` | 第二步的公网后端 API 地址 |
| `GOOGLE_CLIENT_ID` | `YOUR_CLIENT_ID.apps.googleusercontent.com` | 从 GCP Console 获取的 Google OAuth Client ID |
| `ALLOWED_EMAILS` | `alice@gmail.com,bob@gmail.com` | 逗号分隔的邮箱白名单 |
7. 点击 **保存并部署**
> [!NOTE]
> `build.sh` 脚本会在构建时从环境变量生成 `auth-config.js`。仓库中不存储任何敏感信息 —— 所有凭据通过 Cloudflare 环境变量面板配置。
Cloudflare 会分配一个 `*.pages.dev` 域名。你可以在 **Pages****自定义域** 中添加自定义域名。 Cloudflare 会分配一个 `*.pages.dev` 域名。你可以在 **Pages****自定义域** 中添加自定义域名。
Executable
+31
View File
@@ -0,0 +1,31 @@
#!/bin/sh
# Build script for Cloudflare Pages
# Generates auth-config.js from environment variables
#
# Set these in Cloudflare Pages > Settings > Environment Variables:
# API_BASE_URL - Backend API URL (e.g. https://api.yourdomain.com)
# GOOGLE_CLIENT_ID - Google OAuth Client ID
# ALLOWED_EMAILS - Comma-separated email whitelist (e.g. alice@gmail.com,bob@gmail.com)
API_BASE_URL="${API_BASE_URL:-https://xxx.xxx.com}"
GOOGLE_CLIENT_ID="${GOOGLE_CLIENT_ID:-xxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com}"
ALLOWED_EMAILS="${ALLOWED_EMAILS:-your-email@gmail.com}"
cat > frontend/auth-config.js << JSEOF
window.API_CONFIG = { baseUrl: '${API_BASE_URL}' };
const AUTH_CONFIG = {
clientId: '${GOOGLE_CLIENT_ID}',
onSuccess: (user) => {
console.log('Authentication successful:', user.email);
},
onError: (error) => {
console.error('Authentication error:', error);
}
};
window.AUTH_CONFIG = AUTH_CONFIG;
window.ALLOWED_EMAILS = '${ALLOWED_EMAILS}'.split(',').map(e => e.trim());
JSEOF
echo "Generated auth-config.js with API_BASE_URL=${API_BASE_URL}"
+3 -17
View File
@@ -1,28 +1,14 @@
window.API_CONFIG = { baseUrl: 'https://api-view.cathiefish.org' }; window.API_CONFIG = { baseUrl: 'https://xxx.xxx.com' };
/**
* Google OAuth Configuration
* Configure your Google OAuth Client ID here
* Access control is managed via the test users list in GCP Console
*/
const AUTH_CONFIG = { const AUTH_CONFIG = {
// Client ID obtained from GCP Console clientId: 'xxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com',
// Replace with your actual Client ID
clientId: '136939086552-bt28icv34nucmjna8hfndr6bopr5qcp4.apps.googleusercontent.com',
// Authentication success callback
onSuccess: (user) => { onSuccess: (user) => {
console.log('Authentication successful:', user.email); console.log('Authentication successful:', user.email);
// Additional logic can be added here, e.g. logging
}, },
// Authentication failure callback
onError: (error) => { onError: (error) => {
console.error('Authentication error:', error); console.error('Authentication error:', error);
// Error handling logic can be added here
} }
}; };
// Export configuration
window.AUTH_CONFIG = AUTH_CONFIG; window.AUTH_CONFIG = AUTH_CONFIG;
window.ALLOWED_EMAILS = ['your-email@gmail.com'];
+1 -1
View File
@@ -127,7 +127,7 @@
const userData = parseJwt(credential); const userData = parseJwt(credential);
// Email whitelist verification // Email whitelist verification
const allowedEmails = ['your-email@gmail.com']; const allowedEmails = window.ALLOWED_EMAILS || ['your-email@gmail.com'];
if (!allowedEmails.includes(userData.email)) { if (!allowedEmails.includes(userData.email)) {
document.getElementById('error-msg').textContent = 'Access denied: unauthorized email.'; document.getElementById('error-msg').textContent = 'Access denied: unauthorized email.';
document.getElementById('error-msg').style.display = 'block'; document.getElementById('error-msg').style.display = 'block';