cc / src /validators /clients /geminiCliValidator.js
hequ's picture
Upload 224 files
6c6056a verified
const logger = require('../../utils/logger')
const { CLIENT_DEFINITIONS } = require('../clientDefinitions')
/**
* Gemini CLI 验证器
* 验证请求是否来自 Gemini CLI
*/
class GeminiCliValidator {
/**
* 获取客户端ID
*/
static getId() {
return CLIENT_DEFINITIONS.GEMINI_CLI.id
}
/**
* 获取客户端名称
*/
static getName() {
return CLIENT_DEFINITIONS.GEMINI_CLI.name
}
/**
* 获取客户端描述
*/
static getDescription() {
return CLIENT_DEFINITIONS.GEMINI_CLI.description
}
/**
* 获取客户端图标
*/
static getIcon() {
return CLIENT_DEFINITIONS.GEMINI_CLI.icon || '💎'
}
/**
* 验证请求是否来自 Gemini CLI
* @param {Object} req - Express 请求对象
* @returns {boolean} 验证结果
*/
static validate(req) {
try {
const userAgent = req.headers['user-agent'] || ''
const path = req.originalUrl || ''
// 1. 必须是 /gemini 开头的路径
if (!path.startsWith('/gemini')) {
// 非 /gemini 路径不属于 Gemini
return false
}
// 2. 对于 /gemini 路径,检查是否包含 generateContent
if (path.includes('generateContent')) {
// 包含 generateContent 的路径需要验证 User-Agent
const geminiCliPattern = /^GeminiCLI\/v?[\d\.]+/i
if (!geminiCliPattern.test(userAgent)) {
logger.debug(
`Gemini CLI validation failed - UA mismatch for generateContent: ${userAgent}`
)
return false
}
}
// 所有必要检查通过
logger.debug(`Gemini CLI validation passed for path: ${path}`)
return true
} catch (error) {
logger.error('Error in GeminiCliValidator:', error)
// 验证出错时默认拒绝
return false
}
}
/**
* 比较版本号
* @returns {number} -1: v1 < v2, 0: v1 = v2, 1: v1 > v2
*/
static compareVersions(v1, v2) {
const parts1 = v1.split('.').map(Number)
const parts2 = v2.split('.').map(Number)
for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {
const part1 = parts1[i] || 0
const part2 = parts2[i] || 0
if (part1 < part2) return -1
if (part1 > part2) return 1
}
return 0
}
/**
* 获取验证器信息
*/
static getInfo() {
return {
id: this.getId(),
name: this.getName(),
description: this.getDescription(),
icon: CLIENT_DEFINITIONS.GEMINI_CLI.icon
}
}
}
module.exports = GeminiCliValidator