mirror of
https://github.com/Wei-Shaw/claude-relay-service.git
synced 2026-01-22 16:43:35 +00:00
fix: 修复droid追加和代理代理IP提交异常的问题
This commit is contained in:
@@ -781,6 +781,7 @@ class DroidAccountService {
|
|||||||
throw new Error(`Droid account not found: ${accountId}`)
|
throw new Error(`Droid account not found: ${accountId}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const storedAccount = await redis.getDroidAccount(accountId)
|
||||||
const sanitizedUpdates = { ...updates }
|
const sanitizedUpdates = { ...updates }
|
||||||
|
|
||||||
if (typeof sanitizedUpdates.accessToken === 'string') {
|
if (typeof sanitizedUpdates.accessToken === 'string') {
|
||||||
@@ -902,7 +903,12 @@ class DroidAccountService {
|
|||||||
sanitizedUpdates.proxy = account.proxy || ''
|
sanitizedUpdates.proxy = account.proxy || ''
|
||||||
}
|
}
|
||||||
|
|
||||||
const existingApiKeyEntries = this._parseApiKeyEntries(account.apiKeys)
|
// 使用 Redis 中的原始数据获取加密的 API Key 条目
|
||||||
|
const existingApiKeyEntries = this._parseApiKeyEntries(
|
||||||
|
storedAccount && Object.prototype.hasOwnProperty.call(storedAccount, 'apiKeys')
|
||||||
|
? storedAccount.apiKeys
|
||||||
|
: ''
|
||||||
|
)
|
||||||
const newApiKeysInput = Array.isArray(updates.apiKeys) ? updates.apiKeys : []
|
const newApiKeysInput = Array.isArray(updates.apiKeys) ? updates.apiKeys : []
|
||||||
const wantsClearApiKeys = Boolean(updates.clearApiKeys)
|
const wantsClearApiKeys = Boolean(updates.clearApiKeys)
|
||||||
|
|
||||||
|
|||||||
@@ -3137,26 +3137,117 @@ const determinePlatformGroup = (platform) => {
|
|||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
|
|
||||||
// 初始化代理配置
|
const createDefaultProxyState = () => ({
|
||||||
const initProxyConfig = () => {
|
enabled: false,
|
||||||
if (props.account?.proxy && props.account.proxy.host && props.account.proxy.port) {
|
type: 'socks5',
|
||||||
return {
|
host: '',
|
||||||
enabled: true,
|
port: '',
|
||||||
type: props.account.proxy.type || 'socks5',
|
username: '',
|
||||||
host: props.account.proxy.host,
|
password: ''
|
||||||
port: props.account.proxy.port,
|
})
|
||||||
username: props.account.proxy.username || '',
|
|
||||||
password: props.account.proxy.password || ''
|
const parseProxyResponse = (rawProxy) => {
|
||||||
|
if (!rawProxy) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
let proxyObject = rawProxy
|
||||||
|
if (typeof rawProxy === 'string') {
|
||||||
|
try {
|
||||||
|
proxyObject = JSON.parse(rawProxy)
|
||||||
|
} catch (error) {
|
||||||
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {
|
|
||||||
enabled: false,
|
if (!proxyObject || typeof proxyObject !== 'object') {
|
||||||
type: 'socks5',
|
return null
|
||||||
host: '',
|
|
||||||
port: '',
|
|
||||||
username: '',
|
|
||||||
password: ''
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const host =
|
||||||
|
typeof proxyObject.host === 'string'
|
||||||
|
? proxyObject.host.trim()
|
||||||
|
: proxyObject.host !== undefined && proxyObject.host !== null
|
||||||
|
? String(proxyObject.host).trim()
|
||||||
|
: ''
|
||||||
|
|
||||||
|
const port =
|
||||||
|
proxyObject.port !== undefined && proxyObject.port !== null
|
||||||
|
? String(proxyObject.port).trim()
|
||||||
|
: ''
|
||||||
|
|
||||||
|
const type =
|
||||||
|
typeof proxyObject.type === 'string' && proxyObject.type.trim()
|
||||||
|
? proxyObject.type.trim()
|
||||||
|
: 'socks5'
|
||||||
|
|
||||||
|
const username =
|
||||||
|
typeof proxyObject.username === 'string'
|
||||||
|
? proxyObject.username
|
||||||
|
: proxyObject.username !== undefined && proxyObject.username !== null
|
||||||
|
? String(proxyObject.username)
|
||||||
|
: ''
|
||||||
|
|
||||||
|
const password =
|
||||||
|
typeof proxyObject.password === 'string'
|
||||||
|
? proxyObject.password
|
||||||
|
: proxyObject.password !== undefined && proxyObject.password !== null
|
||||||
|
? String(proxyObject.password)
|
||||||
|
: ''
|
||||||
|
|
||||||
|
return {
|
||||||
|
type,
|
||||||
|
host,
|
||||||
|
port,
|
||||||
|
username,
|
||||||
|
password
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const normalizeProxyFormState = (rawProxy) => {
|
||||||
|
const parsed = parseProxyResponse(rawProxy)
|
||||||
|
|
||||||
|
if (parsed && parsed.host && parsed.port) {
|
||||||
|
return {
|
||||||
|
enabled: true,
|
||||||
|
type: parsed.type || 'socks5',
|
||||||
|
host: parsed.host,
|
||||||
|
port: parsed.port,
|
||||||
|
username: parsed.username || '',
|
||||||
|
password: parsed.password || ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return createDefaultProxyState()
|
||||||
|
}
|
||||||
|
|
||||||
|
const buildProxyPayload = (proxyState) => {
|
||||||
|
if (!proxyState || !proxyState.enabled) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
const host = (proxyState.host || '').trim()
|
||||||
|
const portNumber = Number.parseInt(proxyState.port, 10)
|
||||||
|
|
||||||
|
if (!host || Number.isNaN(portNumber) || portNumber <= 0) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
const username = proxyState.username ? proxyState.username.trim() : ''
|
||||||
|
const password = proxyState.password ? proxyState.password.trim() : ''
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: proxyState.type || 'socks5',
|
||||||
|
host,
|
||||||
|
port: portNumber,
|
||||||
|
username: username || null,
|
||||||
|
password: password || null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化代理配置
|
||||||
|
const initProxyConfig = () => {
|
||||||
|
return normalizeProxyFormState(props.account?.proxy)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 表单数据
|
// 表单数据
|
||||||
@@ -3488,17 +3579,8 @@ const nextStep = async () => {
|
|||||||
const generateSetupTokenAuthUrl = async () => {
|
const generateSetupTokenAuthUrl = async () => {
|
||||||
setupTokenLoading.value = true
|
setupTokenLoading.value = true
|
||||||
try {
|
try {
|
||||||
const proxyConfig = form.value.proxy?.enabled
|
const proxyPayload = buildProxyPayload(form.value.proxy)
|
||||||
? {
|
const proxyConfig = proxyPayload ? { proxy: proxyPayload } : {}
|
||||||
proxy: {
|
|
||||||
type: form.value.proxy.type,
|
|
||||||
host: form.value.proxy.host,
|
|
||||||
port: parseInt(form.value.proxy.port),
|
|
||||||
username: form.value.proxy.username || null,
|
|
||||||
password: form.value.proxy.password || null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
: {}
|
|
||||||
|
|
||||||
const result = await accountsStore.generateClaudeSetupTokenUrl(proxyConfig)
|
const result = await accountsStore.generateClaudeSetupTokenUrl(proxyConfig)
|
||||||
setupTokenAuthUrl.value = result.authUrl
|
setupTokenAuthUrl.value = result.authUrl
|
||||||
@@ -3567,14 +3649,9 @@ const exchangeSetupTokenCode = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 添加代理配置(如果启用)
|
// 添加代理配置(如果启用)
|
||||||
if (form.value.proxy?.enabled) {
|
const proxyPayload = buildProxyPayload(form.value.proxy)
|
||||||
data.proxy = {
|
if (proxyPayload) {
|
||||||
type: form.value.proxy.type,
|
data.proxy = proxyPayload
|
||||||
host: form.value.proxy.host,
|
|
||||||
port: parseInt(form.value.proxy.port),
|
|
||||||
username: form.value.proxy.username || null,
|
|
||||||
password: form.value.proxy.password || null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const tokenInfo = await accountsStore.exchangeClaudeSetupTokenCode(data)
|
const tokenInfo = await accountsStore.exchangeClaudeSetupTokenCode(data)
|
||||||
@@ -3606,21 +3683,15 @@ const handleOAuthSuccess = async (tokenInfo) => {
|
|||||||
form.value.unifiedClientId = generateClientId()
|
form.value.unifiedClientId = generateClientId()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const proxyPayload = buildProxyPayload(form.value.proxy)
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
name: form.value.name,
|
name: form.value.name,
|
||||||
description: form.value.description,
|
description: form.value.description,
|
||||||
accountType: form.value.accountType,
|
accountType: form.value.accountType,
|
||||||
groupId: form.value.accountType === 'group' ? form.value.groupId : undefined,
|
groupId: form.value.accountType === 'group' ? form.value.groupId : undefined,
|
||||||
groupIds: form.value.accountType === 'group' ? form.value.groupIds : undefined,
|
groupIds: form.value.accountType === 'group' ? form.value.groupIds : undefined,
|
||||||
proxy: form.value.proxy.enabled
|
proxy: proxyPayload
|
||||||
? {
|
|
||||||
type: form.value.proxy.type,
|
|
||||||
host: form.value.proxy.host,
|
|
||||||
port: parseInt(form.value.proxy.port),
|
|
||||||
username: form.value.proxy.username || null,
|
|
||||||
password: form.value.proxy.password || null
|
|
||||||
}
|
|
||||||
: null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const currentPlatform = form.value.platform
|
const currentPlatform = form.value.platform
|
||||||
@@ -3903,21 +3974,15 @@ const createAccount = async () => {
|
|||||||
|
|
||||||
loading.value = true
|
loading.value = true
|
||||||
try {
|
try {
|
||||||
|
const proxyPayload = buildProxyPayload(form.value.proxy)
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
name: form.value.name,
|
name: form.value.name,
|
||||||
description: form.value.description,
|
description: form.value.description,
|
||||||
accountType: form.value.accountType,
|
accountType: form.value.accountType,
|
||||||
groupId: form.value.accountType === 'group' ? form.value.groupId : undefined,
|
groupId: form.value.accountType === 'group' ? form.value.groupId : undefined,
|
||||||
groupIds: form.value.accountType === 'group' ? form.value.groupIds : undefined,
|
groupIds: form.value.accountType === 'group' ? form.value.groupIds : undefined,
|
||||||
proxy: form.value.proxy.enabled
|
proxy: proxyPayload
|
||||||
? {
|
|
||||||
type: form.value.proxy.type,
|
|
||||||
host: form.value.proxy.host,
|
|
||||||
port: parseInt(form.value.proxy.port),
|
|
||||||
username: form.value.proxy.username || null,
|
|
||||||
password: form.value.proxy.password || null
|
|
||||||
}
|
|
||||||
: null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (form.value.platform === 'claude') {
|
if (form.value.platform === 'claude') {
|
||||||
@@ -4168,21 +4233,15 @@ const updateAccount = async () => {
|
|||||||
|
|
||||||
loading.value = true
|
loading.value = true
|
||||||
try {
|
try {
|
||||||
|
const proxyPayload = buildProxyPayload(form.value.proxy)
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
name: form.value.name,
|
name: form.value.name,
|
||||||
description: form.value.description,
|
description: form.value.description,
|
||||||
accountType: form.value.accountType,
|
accountType: form.value.accountType,
|
||||||
groupId: form.value.accountType === 'group' ? form.value.groupId : undefined,
|
groupId: form.value.accountType === 'group' ? form.value.groupId : undefined,
|
||||||
groupIds: form.value.accountType === 'group' ? form.value.groupIds : undefined,
|
groupIds: form.value.accountType === 'group' ? form.value.groupIds : undefined,
|
||||||
proxy: form.value.proxy.enabled
|
proxy: proxyPayload
|
||||||
? {
|
|
||||||
type: form.value.proxy.type,
|
|
||||||
host: form.value.proxy.host,
|
|
||||||
port: parseInt(form.value.proxy.port),
|
|
||||||
username: form.value.proxy.username || null,
|
|
||||||
password: form.value.proxy.password || null
|
|
||||||
}
|
|
||||||
: null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 只有非空时才更新token
|
// 只有非空时才更新token
|
||||||
@@ -4761,24 +4820,7 @@ watch(
|
|||||||
if (newAccount) {
|
if (newAccount) {
|
||||||
initModelMappings()
|
initModelMappings()
|
||||||
// 重新初始化代理配置
|
// 重新初始化代理配置
|
||||||
const proxyConfig =
|
const proxyConfig = normalizeProxyFormState(newAccount.proxy)
|
||||||
newAccount.proxy && newAccount.proxy.host && newAccount.proxy.port
|
|
||||||
? {
|
|
||||||
enabled: true,
|
|
||||||
type: newAccount.proxy.type || 'socks5',
|
|
||||||
host: newAccount.proxy.host,
|
|
||||||
port: newAccount.proxy.port,
|
|
||||||
username: newAccount.proxy.username || '',
|
|
||||||
password: newAccount.proxy.password || ''
|
|
||||||
}
|
|
||||||
: {
|
|
||||||
enabled: false,
|
|
||||||
type: 'socks5',
|
|
||||||
host: '',
|
|
||||||
port: '',
|
|
||||||
username: '',
|
|
||||||
password: ''
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取分组ID - 可能来自 groupId 字段或 groupInfo 对象
|
// 获取分组ID - 可能来自 groupId 字段或 groupInfo 对象
|
||||||
let groupId = ''
|
let groupId = ''
|
||||||
|
|||||||
@@ -2341,6 +2341,14 @@ const loadAccounts = async (forceReload = false) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
filteredAccounts = filteredAccounts.map((account) => {
|
||||||
|
const proxyConfig = normalizeProxyData(account.proxyConfig || account.proxy)
|
||||||
|
return {
|
||||||
|
...account,
|
||||||
|
proxyConfig: proxyConfig || null
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
accounts.value = filteredAccounts
|
accounts.value = filteredAccounts
|
||||||
cleanupSelectedAccounts()
|
cleanupSelectedAccounts()
|
||||||
|
|
||||||
@@ -2479,24 +2487,86 @@ const filterByGroup = () => {
|
|||||||
loadAccounts()
|
loadAccounts()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 规范化代理配置,支持字符串与对象
|
||||||
|
const normalizeProxyData = (proxy) => {
|
||||||
|
if (!proxy) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
let proxyObject = proxy
|
||||||
|
if (typeof proxy === 'string') {
|
||||||
|
try {
|
||||||
|
proxyObject = JSON.parse(proxy)
|
||||||
|
} catch (error) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!proxyObject || typeof proxyObject !== 'object') {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
const candidate =
|
||||||
|
proxyObject.proxy && typeof proxyObject.proxy === 'object' ? proxyObject.proxy : proxyObject
|
||||||
|
|
||||||
|
const host =
|
||||||
|
typeof candidate.host === 'string'
|
||||||
|
? candidate.host.trim()
|
||||||
|
: candidate.host !== undefined && candidate.host !== null
|
||||||
|
? String(candidate.host).trim()
|
||||||
|
: ''
|
||||||
|
|
||||||
|
const port =
|
||||||
|
candidate.port !== undefined && candidate.port !== null ? String(candidate.port).trim() : ''
|
||||||
|
|
||||||
|
if (!host || !port) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
const type =
|
||||||
|
typeof candidate.type === 'string' && candidate.type.trim() ? candidate.type.trim() : 'socks5'
|
||||||
|
|
||||||
|
const username =
|
||||||
|
typeof candidate.username === 'string'
|
||||||
|
? candidate.username
|
||||||
|
: candidate.username !== undefined && candidate.username !== null
|
||||||
|
? String(candidate.username)
|
||||||
|
: ''
|
||||||
|
|
||||||
|
const password =
|
||||||
|
typeof candidate.password === 'string'
|
||||||
|
? candidate.password
|
||||||
|
: candidate.password !== undefined && candidate.password !== null
|
||||||
|
? String(candidate.password)
|
||||||
|
: ''
|
||||||
|
|
||||||
|
return {
|
||||||
|
type,
|
||||||
|
host,
|
||||||
|
port,
|
||||||
|
username,
|
||||||
|
password
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 格式化代理信息显示
|
// 格式化代理信息显示
|
||||||
const formatProxyDisplay = (proxy) => {
|
const formatProxyDisplay = (proxy) => {
|
||||||
if (!proxy || !proxy.host || !proxy.port) return null
|
const parsed = normalizeProxyData(proxy)
|
||||||
|
if (!parsed) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
// 缩短类型名称
|
const typeShort = parsed.type.toLowerCase() === 'socks5' ? 'S5' : parsed.type.toUpperCase()
|
||||||
const typeShort = proxy.type === 'socks5' ? 'S5' : proxy.type.toUpperCase()
|
|
||||||
|
|
||||||
// 缩短主机名(如果太长)
|
let host = parsed.host
|
||||||
let host = proxy.host
|
|
||||||
if (host.length > 15) {
|
if (host.length > 15) {
|
||||||
host = host.substring(0, 12) + '...'
|
host = host.substring(0, 12) + '...'
|
||||||
}
|
}
|
||||||
|
|
||||||
let display = `${typeShort}://${host}:${proxy.port}`
|
let display = `${typeShort}://${host}:${parsed.port}`
|
||||||
|
|
||||||
// 如果有用户名密码,添加认证信息(部分隐藏)
|
if (parsed.username) {
|
||||||
if (proxy.username) {
|
display = `${typeShort}://***@${host}:${parsed.port}`
|
||||||
display = `${typeShort}://***@${host}:${proxy.port}`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return display
|
return display
|
||||||
|
|||||||
Reference in New Issue
Block a user