mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-09 06:49:02 +08:00
fix(volcengine): address security and error handling issues
- Add safeStorage availability check before encryption to prevent failures on unsupported platforms - Add file permission restriction (0o600) to credentials file for owner-only access - Improve error handling in listModels to differentiate credential/auth errors from network errors - Add error handler to useEffect for hasCredentials check with proper logging Addresses PR review comments from #11482 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
cafc1648d9
commit
771e5e6c3e
@ -382,6 +382,10 @@ class VolcengineService {
|
||||
throw new VolcengineServiceError('Access Key ID and Secret Access Key are required')
|
||||
}
|
||||
|
||||
if (!safeStorage.isEncryptionAvailable()) {
|
||||
throw new VolcengineServiceError('Secure storage is not available on this platform')
|
||||
}
|
||||
|
||||
const credentials: VolcengineCredentials = { accessKeyId, secretAccessKey }
|
||||
const credentialsJson = JSON.stringify(credentials)
|
||||
const encryptedData = safeStorage.encryptString(credentialsJson)
|
||||
@ -393,6 +397,7 @@ class VolcengineService {
|
||||
}
|
||||
|
||||
await fs.promises.writeFile(this.credentialsFilePath, encryptedData)
|
||||
await fs.promises.chmod(this.credentialsFilePath, 0o600) // Read/write for owner only
|
||||
logger.info('Volcengine credentials saved successfully')
|
||||
} catch (error) {
|
||||
logger.error('Failed to save Volcengine credentials:', error as Error)
|
||||
|
||||
@ -64,9 +64,23 @@ export class VolcengineAPIClient extends OpenAIAPIClient {
|
||||
return models
|
||||
} catch (error) {
|
||||
logger.error('Failed to list Volcengine models:', error as Error)
|
||||
// Notify user before falling back
|
||||
window.toast?.warning('Failed to fetch Volcengine models. Check credentials if this persists.')
|
||||
// Fall back to standard OpenAI-compatible API on error
|
||||
|
||||
const errorMessage = error instanceof Error ? error.message : String(error)
|
||||
|
||||
// Credential errors should not fall back - user must fix
|
||||
if (errorMessage.includes('could not be loaded') || errorMessage.includes('credentials')) {
|
||||
window.toast?.error('Volcengine credentials error. Please re-enter your credentials in settings.')
|
||||
throw error
|
||||
}
|
||||
|
||||
// Auth errors should not fall back
|
||||
if (errorMessage.includes('401') || errorMessage.includes('403')) {
|
||||
window.toast?.error('Volcengine authentication failed. Please verify your Access Key.')
|
||||
throw error
|
||||
}
|
||||
|
||||
// Only fall back for transient network errors
|
||||
window.toast?.warning('Temporarily unable to fetch Volcengine models. Using fallback.')
|
||||
logger.info('Falling back to OpenAI-compatible model list')
|
||||
return super.listModels()
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { loggerService } from '@logger'
|
||||
import { HStack } from '@renderer/components/Layout'
|
||||
import { PROVIDER_URLS } from '@renderer/config/providers'
|
||||
import { useVolcengineSettings } from '@renderer/hooks/useVolcengine'
|
||||
@ -24,7 +25,13 @@ const VolcengineSettings: FC = () => {
|
||||
|
||||
// Check if credentials exist on mount
|
||||
useEffect(() => {
|
||||
window.api.volcengine.hasCredentials().then(setHasCredentials)
|
||||
window.api.volcengine
|
||||
.hasCredentials()
|
||||
.then(setHasCredentials)
|
||||
.catch((error) => {
|
||||
loggerService.withContext('VolcengineSettings').error('Failed to check credentials:', error as Error)
|
||||
window.toast?.error('Failed to check Volcengine credentials')
|
||||
})
|
||||
}, [])
|
||||
|
||||
// Sync local state with store (only for region and projectName)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user