Compare commits

..

22 Commits

Author SHA1 Message Date
Supra4E8C
2be7ced21a 实现移动端侧边栏功能,添加移动菜单按钮及遮罩,优化导航项点击事件,更新样式以提升用户体验。 2025-10-03 15:09:41 +08:00
Supra4E8C
b61155d215 v0.0.6
添加代理 URL 支持,更新 API 配置模态框,增强 XSS 防护,优化界面样式,修复若干 UI 问题,版本更新至 0.0.6
2025-10-02 17:34:26 +08:00
Supra4E8C
5488d6153d Update README.md 2025-10-01 16:36:06 +08:00
Supra4E8C
30f5300bb4 Update README_CN.md 2025-10-01 16:10:47 +08:00
Supra4E8C
52169200f1 Update README.md 2025-10-01 16:10:22 +08:00
Supra4E8C
80b2597611 0.0.5
为Cli Proxy API主程序兼容做准备
2025-10-01 16:06:12 +08:00
Luis Pater
04f21eea98 change release file name 2025-10-01 02:00:53 +08:00
Luis Pater
f6a4bae8c6 add auto release script 2025-10-01 01:57:53 +08:00
Supra4E8C
c9f09ccf37 Update README_CN.md 2025-09-25 17:17:44 +08:00
Supra4E8C
5b8fd04ba3 Update README.md 2025-09-25 17:17:00 +08:00
Supra4E8C
3c791a2313 Update README.md 2025-09-25 17:15:15 +08:00
Supra4E8C
2ef64d8064 Add files via upload 2025-09-25 17:14:50 +08:00
Supra4E8C
f2dc4bcf98 Update 0.0.3Beta 2025-09-25 17:04:02 +08:00
Supra4E8C
5f597afb42 update app.js
1.去除了部分无法使用的OAuth逻辑
2.修复了Gemini Web保存功能
2025-09-25 15:52:52 +08:00
Supra4E8C
e5bef7e2b0 Add files via upload 2025-09-25 15:29:48 +08:00
Supra4E8C
d8df9ce680 Add files via upload 2025-09-25 15:29:26 +08:00
Supra4E8C
44594220b2 Add files via upload 2025-09-24 19:26:09 +08:00
Supra4E8C
86fc9fe86e 更新 README.md 2025-09-24 19:25:23 +08:00
Supra4E8C
67f009b81c Delete README_EN.md 2025-09-24 19:22:48 +08:00
Supra4E8C
6618312360 更新 README_EN.md 2025-09-24 19:19:30 +08:00
Supra4E8C
9e49824c52 创建 README_EN.md 2025-09-24 19:18:02 +08:00
Supra4E8C
015754237b 更新 README.md
更新readme 使内容与0.0.1版本匹配
2025-09-24 19:10:23 +08:00
15 changed files with 6804 additions and 3896 deletions

61
.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,61 @@
name: Build and Release
on:
push:
tags:
- 'v*'
jobs:
build-and-release:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build all-in-one HTML
run: npm run build
- name: Prepare release assets
run: |
cd dist
mv index.html management.html
ls -lh management.html
- name: Create Release
uses: softprops/action-gh-release@v1
with:
files: dist/management.html
body: |
## CLI Proxy API Management Center - ${{ github.ref_name }}
### Download and Usage
1. Download the `management.html` file
2. Open it directly in your browser
3. All assets (CSS, JavaScript, images) are bundled into this single file
### Features
- Single file, no external dependencies required
- Complete management interface for CLI Proxy API
- Support for local and remote connections
- Multi-language support (Chinese/English)
- Dark/Light theme support
---
🤖 Generated with GitHub Actions
draft: false
prerelease: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

22
.gitignore vendored Normal file
View File

@@ -0,0 +1,22 @@
# Node modules
node_modules/
# Build output
dist/
# Temporary build files
index.build.html
# npm lock files
package-lock.json
# IDE and editor files
.vscode/
.idea/
*.swp
*.swo
*~
# OS files
.DS_Store
Thumbs.db

69
BUILD_RELEASE.md Normal file
View File

@@ -0,0 +1,69 @@
# Build and Release Instructions
## Overview
This project uses webpack to bundle all HTML, CSS, JavaScript, and images into a single all-in-one HTML file. The GitHub workflow automatically builds and releases this file when you create a new tag.
## How to Create a Release
1. Make sure all your changes are committed
2. Create and push a new tag:
```bash
git tag v1.0.0
git push origin v1.0.0
```
3. The GitHub workflow will automatically:
- Install dependencies
- Build the all-in-one HTML file using webpack
- Create a new release with the tag
- Upload the bundled HTML file to the release
## Manual Build
To build locally:
```bash
# Install dependencies
npm install
# Build the all-in-one HTML file
npm run build
```
The output will be in the `dist/` directory as `index.html`.
## How It Works
1. **build-scripts/prepare-html.js**: Pre-build script
- Reads the original `index.html`
- Removes local CSS and JavaScript references
- Generates temporary `index.build.html` for webpack
2. **webpack.config.js**: Configures webpack to bundle all assets
- Uses `style-loader` to inline CSS
- Uses `asset/inline` to embed images as base64
- Uses `html-inline-script-webpack-plugin` to inline JavaScript
- Uses `index.build.html` as template (generated dynamically)
3. **bundle-entry.js**: Entry point that imports all resources
- Imports CSS files
- Imports JavaScript modules
- Imports and sets logo image
4. **package.json scripts**:
- `prebuild`: Automatically runs before build to generate `index.build.html`
- `build`: Runs webpack to bundle everything
- `postbuild`: Cleans up temporary `index.build.html` file
5. **.github/workflows/release.yml**: GitHub workflow
- Triggers on tag push
- Builds the project (prebuild → build → postbuild)
- Creates a release with the bundled HTML file
## External Dependencies
The bundled HTML file still relies on these CDN resources:
- Font Awesome (icons)
- Chart.js (charts and graphs)
These are loaded from CDN to keep the file size reasonable and leverage browser caching.

216
README.md
View File

@@ -1,145 +1,145 @@
# Cli-Proxy-API-Management-Center # Cli-Proxy-API-Management-Center
这是一个用于管理 CLI Proxy API 的现代化 Web 界面。 This is a modern web interface for managing the CLI Proxy API.
## 功能特点 [中文文档](README_CN.md)
### 认证管理 Main Project:
- 支持管理密钥认证 https://github.com/router-for-me/CLIProxyAPI
- 可配置 API 基础地址
- 实时连接状态检测
### 基础设置 Example URL:
- **调试模式**: 开启/关闭调试功能 https://remote.router-for.me/
- **代理设置**: 配置代理服务器 URL
- **请求重试**: 设置请求重试次数
- **配额管理**: 配置超出配额时的行为
- **本地访问**: 允许本地未认证访问
### API 密钥管理 Minimum required version: ≥ 6.0.0
- **代理服务认证密钥**: 管理用于代理服务的 API 密钥 Recommended version: ≥ 6.0.19
- **Gemini API**: 管理 Google Gemini 生成式语言 API 密钥
- **Codex API**: 管理 OpenAI Codex API 配置
- **Claude API**: 管理 Anthropic Claude API 配置
- **OpenAI 兼容提供商**: 管理 OpenAI 兼容的第三方提供商
### 认证文件管理 Starting from version 6.0.19, the WebUI has been integrated into the main program and is accessible via `/management.html`.
- 上传认证 JSON 文件
- 下载现有认证文件
- 删除单个或所有认证文件
- 显示文件详细信息
### 系统监控 ## Features
- 实时 API 连接状态
- 最后更新时间跟踪
- 详细的错误信息提示
## 使用方法 ### Authentication Management
- Supports management key authentication
- Configurable API base address
- Real-time connection status detection
### 1. 直接使用(推荐) ### Basic Settings
直接用浏览器打开 `index.html` 文件即可使用。 - **Debug Mode**: Enable/disable debugging
- **Proxy Settings**: Configure proxy server URL
- **Request Retries**: Set the number of request retries
- **Quota Management**: Configure behavior when the quota is exceeded
- **Local Access**: Manage local unauthenticated access
### 2. 使用本地服务器 ### API Key Management
- **Proxy Service Authentication Key**: Manage API keys for the proxy service
- **Gemini API**: Manage Google Gemini generative language API keys
- **Codex API**: Manage OpenAI Codex API configuration
- **Claude API**: Manage Anthropic Claude API configuration
- **OpenAI-Compatible Providers**: Manage OpenAI-compatible third-party providers
### Authentication File Management
- Upload authentication JSON files
- Download existing authentication files
- Delete single or all authentication files
- Display file details
## How to Use
### 1. Direct Use (Recommended)
Simply open the `index.html` file directly in your browser to use it.
### 2. Use a Local Server
```bash ```bash
# 安装依赖 # Install dependencies
npm install npm install
# 使用默认端口(3000 # Start the server on the default port (3000)
npm start npm start
``` ```
### 3. 配置 API 连接 ### 3. Configure API Connection
1. 打开管理界面 1. Open the management interface.
2. 在认证配置区域输入: 2. On the login screen, enter:
- **API 地址**: `http://localhost:8317`/v0/management将会自动为您补全 - **Remote Address**: `http://localhost:8317` (`/v0/management` will be auto-completed for you)
- **管理密钥**: 您的管理密钥 - **Management Key**: Your management key
3. 点击"测试连接"按钮 3. Click the "Connect" button.
4. 连接成功后即可使用所有功能 4. Once connected successfully, all features will be available.
## 界面说明 ## Interface Description
### 导航菜单 ### Navigation Menu
- **基础设置**: 调试、代理、重试等基本配置 - **Basic Settings**: Basic configurations like debugging, proxy, retries, etc.
- **API 密钥**: 各种 API 服务的密钥管理 - **API Keys**: Management of keys for various API services.
- **AI 提供商**: AI 服务提供商配置 - **AI Providers**: Configuration for AI service providers.
- **认证文件**: 认证文件的上传下载管理 - **Auth Files**: Upload and download management for authentication files.
- **系统信息**: 连接状态和系统信息 - **System Info**: Connection status and system information.
### 操作按钮 ## Feature Highlights
- **刷新全部**: 重新加载所有配置数据
- **连接状态**: 检查 API 连接状态
- **添加**: 添加新的配置项
- **编辑**: 编辑现有配置
- **删除**: 删除配置项
## 特性亮点 ### Modern UI
- Responsive design, supports all screen sizes
- Beautiful gradient colors and shadow effects
- Smooth animations and transition effects
- Intuitive icons and status indicators
### 现代化 UI ### Real-time Updates
- 响应式设计,支持各种屏幕尺寸 - Configuration changes take effect immediately
- 美观的渐变色彩和阴影效果 - Real-time status feedback
- 流畅的动画和过渡效果 - Automatic data refresh
- 直观的图标和状态指示
### 实时更新 ### Security Features
- 配置更改立即生效 - Masked display for keys
- 实时状态反馈
- 自动数据刷新
### 安全特性 ### Responsive Design
- 密钥遮蔽显示 - Perfectly adapts to desktop and mobile devices
- Adaptive layout
- Touch-friendly interactions
### 响应式设计 ## Tech Stack
- 完美适配桌面和移动设备
- 自适应布局
- 触摸友好的交互
## 技术栈 - **Frontend**: Plain HTML, CSS, JavaScript
- **Styling**: CSS3 + Flexbox/Grid
- **Icons**: Font Awesome 6.4.0
- **Fonts**: Segoe UI system font
- **API**: RESTful API calls
- **前端**: 纯 HTML、CSS、JavaScript ## Troubleshooting
- **样式**: CSS3 + Flexbox/Grid
- **图标**: Font Awesome 6.4.0
- **字体**: Segoe UI 系统字体
- **API**: RESTful API 调用
## 故障排除 ### Connection Issues
1. Confirm that the CLI Proxy API service is running.
2. Check if the API address is correct.
3. Verify that the management key is valid.
4. Ensure your firewall settings allow the connection.
### 连接问题 ### Data Not Updating
1. 确认 CLI Proxy API 服务正在运行 1. Click the "Refresh All" button.
2. 检查 API 地址是否正确 2. Check your network connection.
3. 验证管理密钥是否有效 3. Check the browser's console for any error messages.
4. 确认防火墙设置允许连接
### 数据不更新 ## Development Information
1. 点击"刷新全部"按钮
2. 检查网络连接
3. 查看浏览器控制台错误信息
## 开发说明 ### File Structure
### 文件结构
``` ```
webui/ webui/
├── index.html # 主页面 ├── index.html # Main page
├── styles.css # 样式文件 ├── styles.css # Stylesheet
├── app.js # 应用逻辑 ├── app.js # Application logic
├── package.json # 项目配置 ├── package.json # Project configuration
── README.md # 说明文档 ── i18n.js # Internationalization support
└── README.md # README document
``` ```
### API 调用 ### API Calls
所有 API 调用都通过 `CLIProxyManager` 类的 `makeRequest` 方法处理,包含: All API calls are handled through the `makeRequest` method of the `ManagerAPI` class, which includes:
- 自动添加认证头 - Automatic addition of authentication headers
- 错误处理 - Error handling
- JSON 响应解析 - JSON response parsing
### 状态管理 ### State Management
- 本地存储保存 API 地址和密钥 - API address and key are saved in local storage
- 内存中维护连接状态 - Connection status is maintained in memory
- 实时数据刷新机制 - Real-time data refresh mechanism
## 许可证 ## Contributing
We welcome Issues and Pull Requests to improve this project! We encourage more developers to contribute to the enhancement of this WebUI!
MIT License This project is licensed under the MIT License.
## 贡献
欢迎提交 Issue 和 Pull Request 来改进这个项目!

141
README_CN.md Normal file
View File

@@ -0,0 +1,141 @@
# Cli-Proxy-API-Management-Center
这是一个用于管理 CLI Proxy API 的现代化 Web 界面。
主项目
https://github.com/router-for-me/CLIProxyAPI
示例网站:
https://remote.router-for.me/
最低可用版本 ≥ 5.0.0
推荐版本 ≥ 5.2.6
自6.0.19起WebUI已经集成在主程序中 可以通过/management.html访问
## 功能特点
### 认证管理
- 支持管理密钥认证
- 可配置 API 基础地址
- 实时连接状态检测
### 基础设置
- **调试模式**: 开启/关闭调试功能
- **代理设置**: 配置代理服务器 URL
- **请求重试**: 设置请求重试次数
- **配额管理**: 配置超出配额时的行为
- **本地访问**: 管理本地未认证访问
### API 密钥管理
- **代理服务认证密钥**: 管理用于代理服务的 API 密钥
- **Gemini API**: 管理 Google Gemini 生成式语言 API 密钥
- **Codex API**: 管理 OpenAI Codex API 配置
- **Claude API**: 管理 Anthropic Claude API 配置
- **OpenAI 兼容提供商**: 管理 OpenAI 兼容的第三方提供商
### 认证文件管理
- 上传认证 JSON 文件
- 下载现有认证文件
- 删除单个或所有认证文件
- 显示文件详细信息
## 使用方法
### 1. 直接使用(推荐)
直接用浏览器打开 `index.html` 文件即可使用。
### 2. 使用本地服务器
```bash
# 安装依赖
npm install
# 使用默认端口(3000
npm start
```
### 3. 配置 API 连接
1. 打开管理界面
2. 在登录界面上输入:
- **远程地址**: `http://localhost:8317`/v0/management将会自动为您补全
- **管理密钥**: 您的管理密钥
3. 点击"连接"按钮
4. 连接成功后即可使用所有功能
## 界面说明
### 导航菜单
- **基础设置**: 调试、代理、重试等基本配置
- **API 密钥**: 各种 API 服务的密钥管理
- **AI 提供商**: AI 服务提供商配置
- **认证文件**: 认证文件的上传下载管理
- **系统信息**: 连接状态和系统信息
## 特性亮点
### 现代化 UI
- 响应式设计,支持各种屏幕尺寸
- 美观的渐变色彩和阴影效果
- 流畅的动画和过渡效果
- 直观的图标和状态指示
### 实时更新
- 配置更改立即生效
- 实时状态反馈
- 自动数据刷新
### 安全特性
- 密钥遮蔽显示
### 响应式设计
- 完美适配桌面和移动设备
- 自适应布局
- 触摸友好的交互
## 技术栈
- **前端**: 纯 HTML、CSS、JavaScript
- **样式**: CSS3 + Flexbox/Grid
- **图标**: Font Awesome 6.4.0
- **字体**: Segoe UI 系统字体
- **API**: RESTful API 调用
## 故障排除
### 连接问题
1. 确认 CLI Proxy API 服务正在运行
2. 检查 API 地址是否正确
3. 验证管理密钥是否有效
4. 确认防火墙设置允许连接
### 数据不更新
1. 点击"刷新全部"按钮
2. 检查网络连接
3. 查看浏览器控制台错误信息
## 开发说明
### 文件结构
```
webui/
├── index.html # 主页面
├── styles.css # 样式文件
├── app.js # 应用逻辑
├── package.json # 项目配置
├── i18n.js # 国际化支持
└── README.md # 说明文档
```
### API 调用
所有 API 调用都通过 `ManagerAPI` 类的 `makeRequest` 方法处理,包含:
- 自动添加认证头
- 错误处理
- JSON 响应解析
### 状态管理
- 本地存储保存 API 地址和密钥
- 内存中维护连接状态
- 实时数据刷新机制
## 贡献
欢迎提交 Issue 和 Pull Request 来改进这个项目我们欢迎更多的大佬来对这个WebUI进行更新
本项目采用MIT许可

5096
app.js

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,30 @@
const fs = require('fs');
const path = require('path');
// Read the original index.html
const indexPath = path.resolve(__dirname, '../index.html');
const outputPath = path.resolve(__dirname, '../index.build.html');
let htmlContent = fs.readFileSync(indexPath, 'utf8');
// Remove local CSS reference
htmlContent = htmlContent.replace(
/<link rel="stylesheet" href="styles\.css">\n?/g,
''
);
// Remove local JavaScript references
htmlContent = htmlContent.replace(
/<script src="i18n\.js"><\/script>\n?/g,
''
);
htmlContent = htmlContent.replace(
/<script src="app\.js"><\/script>\n?/g,
''
);
// Write the modified HTML to a temporary build file
fs.writeFileSync(outputPath, htmlContent, 'utf8');
console.log('✓ Generated index.build.html for webpack processing');

132
build.js Normal file
View File

@@ -0,0 +1,132 @@
'use strict';
const fs = require('fs');
const path = require('path');
const projectRoot = __dirname;
const distDir = path.join(projectRoot, 'dist');
const sourceFiles = {
html: path.join(projectRoot, 'index.html'),
css: path.join(projectRoot, 'styles.css'),
i18n: path.join(projectRoot, 'i18n.js'),
app: path.join(projectRoot, 'app.js')
};
const logoCandidates = ['logo.png', 'logo.jpg', 'logo.jpeg', 'logo.svg', 'logo.webp', 'logo.gif'];
const logoMimeMap = {
'.png': 'image/png',
'.jpg': 'image/jpeg',
'.jpeg': 'image/jpeg',
'.svg': 'image/svg+xml',
'.webp': 'image/webp',
'.gif': 'image/gif'
};
function readFile(filePath) {
try {
return fs.readFileSync(filePath, 'utf8');
} catch (err) {
console.error(`读取文件失败: ${filePath}`);
throw err;
}
}
function readBinary(filePath) {
try {
return fs.readFileSync(filePath);
} catch (err) {
console.error(`读取文件失败: ${filePath}`);
throw err;
}
}
function escapeForScript(content) {
return content.replace(/<\/(script)/gi, '<\\/$1');
}
function escapeForStyle(content) {
return content.replace(/<\/(style)/gi, '<\\/$1');
}
function ensureDistDir() {
if (fs.existsSync(distDir)) {
fs.rmSync(distDir, { recursive: true, force: true });
}
fs.mkdirSync(distDir);
}
function loadLogoDataUrl() {
for (const candidate of logoCandidates) {
const filePath = path.join(projectRoot, candidate);
if (!fs.existsSync(filePath)) continue;
const ext = path.extname(candidate).toLowerCase();
const mime = logoMimeMap[ext];
if (!mime) {
console.warn(`未知 Logo 文件类型,跳过内联: ${candidate}`);
continue;
}
const buffer = readBinary(filePath);
const base64 = buffer.toString('base64');
return `data:${mime};base64,${base64}`;
}
return null;
}
function build() {
ensureDistDir();
let html = readFile(sourceFiles.html);
const css = escapeForStyle(readFile(sourceFiles.css));
const i18n = escapeForScript(readFile(sourceFiles.i18n));
const app = escapeForScript(readFile(sourceFiles.app));
html = html.replace(
'<link rel="stylesheet" href="styles.css">',
`<style>
${css}
</style>`
);
html = html.replace(
'<script src="i18n.js"></script>',
`<script>
${i18n}
</script>`
);
html = html.replace(
'<script src="app.js"></script>',
`<script>
${app}
</script>`
);
const logoDataUrl = loadLogoDataUrl();
if (logoDataUrl) {
const logoScript = `<script>window.__INLINE_LOGO__ = "${logoDataUrl}";</script>`;
if (html.includes('</body>')) {
html = html.replace('</body>', `${logoScript}\n</body>`);
} else {
html += `\n${logoScript}`;
}
} else {
console.warn('未找到可内联的 Logo 文件,将保持运行时加载。');
}
const outputPath = path.join(distDir, 'index.html');
fs.writeFileSync(outputPath, html, 'utf8');
console.log('构建完成: dist/index.html');
}
try {
build();
} catch (error) {
console.error('构建失败:', error);
process.exit(1);
}

25
bundle-entry.js Normal file
View File

@@ -0,0 +1,25 @@
// Import CSS
import './styles.css';
// Import JavaScript modules
import './i18n.js';
import './app.js';
// Import logo image
import logoImg from './logo.jpg';
// Set logo after DOM is loaded
document.addEventListener('DOMContentLoaded', () => {
const loginLogo = document.getElementById('login-logo');
const siteLogo = document.getElementById('site-logo');
if (loginLogo) {
loginLogo.src = logoImg;
loginLogo.style.display = 'block';
}
if (siteLogo) {
siteLogo.src = logoImg;
siteLogo.style.display = 'block';
}
});

1293
i18n.js

File diff suppressed because it is too large Load Diff

1058
index.html

File diff suppressed because it is too large Load Diff

1064
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -6,7 +6,7 @@
"scripts": { "scripts": {
"start": "npx serve .", "start": "npx serve .",
"dev": "npx serve . --port 3000", "dev": "npx serve . --port 3000",
"build": "echo '无需构建,直接使用静态文件'", "build": "node build.js",
"lint": "echo '使用浏览器开发者工具检查代码'" "lint": "echo '使用浏览器开发者工具检查代码'"
}, },
"keywords": [ "keywords": [

1427
styles.css

File diff suppressed because it is too large Load Diff

64
webpack.config.js Normal file
View File

@@ -0,0 +1,64 @@
const HtmlWebpackPlugin = require('html-webpack-plugin');
const HtmlInlineScriptPlugin = require('html-inline-script-webpack-plugin');
const path = require('path');
module.exports = {
mode: 'production',
entry: {
main: './bundle-entry.js'
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].bundle.js',
clean: true
},
module: {
rules: [
{
test: /\.css$/i,
use: ['style-loader', 'css-loader']
},
{
test: /\.(png|jpg|jpeg|gif|svg)$/i,
type: 'asset/inline'
},
{
test: /\.html$/i,
loader: 'html-loader',
options: {
sources: {
list: [
{
tag: 'img',
attribute: 'src',
type: 'src'
}
]
}
}
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './index.build.html',
filename: 'index.html',
inject: 'body',
minify: {
collapseWhitespace: true,
removeComments: true,
removeRedundantAttributes: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true,
useShortDoctype: true
}
}),
new HtmlInlineScriptPlugin({
htmlMatchPattern: [/index.html$/],
scriptMatchPattern: [/.js$/]
})
],
optimization: {
minimize: true
}
};