mirror of
https://github.com/Wei-Shaw/claude-relay-service.git
synced 2026-01-23 00:53:33 +00:00
feat: 增加Claude会话强制绑定
This commit is contained in:
130
src/routes/admin/claudeRelayConfig.js
Normal file
130
src/routes/admin/claudeRelayConfig.js
Normal file
@@ -0,0 +1,130 @@
|
||||
/**
|
||||
* Claude 转发配置 API 路由
|
||||
* 管理全局 Claude Code 限制和会话绑定配置
|
||||
*/
|
||||
|
||||
const express = require('express')
|
||||
const { authenticateAdmin } = require('../../middleware/auth')
|
||||
const claudeRelayConfigService = require('../../services/claudeRelayConfigService')
|
||||
const logger = require('../../utils/logger')
|
||||
|
||||
const router = express.Router()
|
||||
|
||||
/**
|
||||
* GET /admin/claude-relay-config
|
||||
* 获取 Claude 转发配置
|
||||
*/
|
||||
router.get('/claude-relay-config', authenticateAdmin, async (req, res) => {
|
||||
try {
|
||||
const config = await claudeRelayConfigService.getConfig()
|
||||
return res.json({
|
||||
success: true,
|
||||
config
|
||||
})
|
||||
} catch (error) {
|
||||
logger.error('❌ Failed to get Claude relay config:', error)
|
||||
return res.status(500).json({
|
||||
error: 'Failed to get configuration',
|
||||
message: error.message
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* PUT /admin/claude-relay-config
|
||||
* 更新 Claude 转发配置
|
||||
*/
|
||||
router.put('/claude-relay-config', authenticateAdmin, async (req, res) => {
|
||||
try {
|
||||
const {
|
||||
claudeCodeOnlyEnabled,
|
||||
globalSessionBindingEnabled,
|
||||
sessionBindingErrorMessage,
|
||||
sessionBindingTtlDays
|
||||
} = req.body
|
||||
|
||||
// 验证输入
|
||||
if (claudeCodeOnlyEnabled !== undefined && typeof claudeCodeOnlyEnabled !== 'boolean') {
|
||||
return res.status(400).json({ error: 'claudeCodeOnlyEnabled must be a boolean' })
|
||||
}
|
||||
|
||||
if (
|
||||
globalSessionBindingEnabled !== undefined &&
|
||||
typeof globalSessionBindingEnabled !== 'boolean'
|
||||
) {
|
||||
return res.status(400).json({ error: 'globalSessionBindingEnabled must be a boolean' })
|
||||
}
|
||||
|
||||
if (sessionBindingErrorMessage !== undefined) {
|
||||
if (typeof sessionBindingErrorMessage !== 'string') {
|
||||
return res.status(400).json({ error: 'sessionBindingErrorMessage must be a string' })
|
||||
}
|
||||
if (sessionBindingErrorMessage.length > 500) {
|
||||
return res
|
||||
.status(400)
|
||||
.json({ error: 'sessionBindingErrorMessage must be less than 500 characters' })
|
||||
}
|
||||
}
|
||||
|
||||
if (sessionBindingTtlDays !== undefined) {
|
||||
if (
|
||||
typeof sessionBindingTtlDays !== 'number' ||
|
||||
sessionBindingTtlDays < 1 ||
|
||||
sessionBindingTtlDays > 365
|
||||
) {
|
||||
return res
|
||||
.status(400)
|
||||
.json({ error: 'sessionBindingTtlDays must be a number between 1 and 365' })
|
||||
}
|
||||
}
|
||||
|
||||
const updateData = {}
|
||||
if (claudeCodeOnlyEnabled !== undefined)
|
||||
updateData.claudeCodeOnlyEnabled = claudeCodeOnlyEnabled
|
||||
if (globalSessionBindingEnabled !== undefined)
|
||||
updateData.globalSessionBindingEnabled = globalSessionBindingEnabled
|
||||
if (sessionBindingErrorMessage !== undefined)
|
||||
updateData.sessionBindingErrorMessage = sessionBindingErrorMessage
|
||||
if (sessionBindingTtlDays !== undefined)
|
||||
updateData.sessionBindingTtlDays = sessionBindingTtlDays
|
||||
|
||||
const updatedConfig = await claudeRelayConfigService.updateConfig(
|
||||
updateData,
|
||||
req.admin?.username || 'unknown'
|
||||
)
|
||||
|
||||
return res.json({
|
||||
success: true,
|
||||
message: 'Configuration updated successfully',
|
||||
config: updatedConfig
|
||||
})
|
||||
} catch (error) {
|
||||
logger.error('❌ Failed to update Claude relay config:', error)
|
||||
return res.status(500).json({
|
||||
error: 'Failed to update configuration',
|
||||
message: error.message
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* GET /admin/claude-relay-config/session-bindings
|
||||
* 获取会话绑定统计
|
||||
*/
|
||||
router.get('/claude-relay-config/session-bindings', authenticateAdmin, async (req, res) => {
|
||||
try {
|
||||
const stats = await claudeRelayConfigService.getSessionBindingStats()
|
||||
return res.json({
|
||||
success: true,
|
||||
data: stats
|
||||
})
|
||||
} catch (error) {
|
||||
logger.error('❌ Failed to get session binding stats:', error)
|
||||
return res.status(500).json({
|
||||
error: 'Failed to get session binding statistics',
|
||||
message: error.message
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
module.exports = router
|
||||
Reference in New Issue
Block a user