feat: add OAuth outbound transport plugin system

This commit is contained in:
shaw committed 2026-08-24 09:03:37 +08:00
1 parent d45135d87d
commit 40ea3aebad
98 files changed
+7681 -141

No files matched your search

+11 -2
View File
@@ -35,6 +35,7 @@ import affiliatesAPI from './affiliates'
import riskControlAPI from './riskControl'
import adminComplianceAPI from './compliance'
import auditAPI from './audit'
import pluginsAPI from './plugins'
/**
* Unified admin API object for convenient access
@@ -71,7 +72,8 @@ export const adminAPI = {
affiliates: affiliatesAPI,
riskControl: riskControlAPI,
compliance: adminComplianceAPI,
audit: auditAPI
audit: auditAPI,
plugins: pluginsAPI
}
export {
@@ -106,7 +108,8 @@ export {
affiliatesAPI,
riskControlAPI,
adminComplianceAPI,
auditAPI
auditAPI,
pluginsAPI
}
export default adminAPI
@@ -118,3 +121,9 @@ export type { ErrorPassthroughRule, CreateRuleRequest, UpdateRuleRequest } from
export type { BackupAgentHealth, DataManagementConfig } from './dataManagement'
export type { TLSFingerprintProfile, CreateProfileRequest, UpdateProfileRequest } from './tlsFingerprintProfile'
export type { ContentModerationConfig, ContentModerationLog, ModerationMode } from './riskControl'
export type {
PluginInstallation,
PluginCompatibility,
PluginUISession,
PluginTestResult
} from './plugins'
+156
View File
@@ -0,0 +1,156 @@
import { apiClient } from '../client'
export interface PluginCapability {
id: string
platform: string
account_type: string
}
export interface PluginRequirements {
sub2api: string
recommended_sub2api_version?: string
tested_sub2api_versions?: string[]
plugin_protocol: number
transport_api: number
ui_bridge: number
}
export interface PluginManifest {
schema_version: number
id: string
name: string
version: string
description?: string
author?: string
requires: PluginRequirements
capabilities: PluginCapability[]
ui: { entrypoint: string }
}
export interface PluginCompatibility {
compatible: boolean
tested: boolean
status: 'compatible' | 'untested' | 'incompatible'
message: string
current_sub2api_version: string
required_sub2api_version: string
recommended_sub2api_version: string
plugin_protocol: number
transport_api: number
ui_bridge: number
}
export interface PluginBinding {
id: number
plugin_id: number
capability: string
platform: string
account_type: string
enabled: boolean
rollout_percent: number
}
export interface PluginInstallation {
id: number
plugin_key: string
name: string
version: string
description: string
author: string
manifest: PluginManifest
binary_sha256: string
signature_status: 'trusted' | 'unsigned'
state: 'disabled' | 'starting' | 'enabled' | 'error' | 'incompatible'
last_error: string
installed_at: string
enabled_at?: string
updated_at: string
bindings: PluginBinding[]
compatibility: PluginCompatibility
runtime_healthy: boolean
runtime_message: string
}
export interface PluginTestResult {
success: boolean
message: string
latency_ms: number
}
export interface PluginUISession {
url: string
bridge_token: string
ui_bridge_version: number
expires_at: string
}
export async function list(): Promise<PluginInstallation[]> {
const { data } = await apiClient.get<PluginInstallation[]>('/admin/plugins')
return data
}
export async function upload(file: File): Promise<PluginInstallation> {
const form = new FormData()
form.append('plugin', file)
const { data } = await apiClient.post<PluginInstallation>('/admin/plugins/upload', form, {
headers: { 'Content-Type': 'multipart/form-data' },
timeout: 120000
})
return data
}
export async function enable(
id: number,
rolloutPercent: number,
acceptUntested: boolean
): Promise<PluginInstallation> {
const { data } = await apiClient.post<PluginInstallation>(`/admin/plugins/${id}/enable`, {
rollout_percent: rolloutPercent,
accept_untested: acceptUntested
})
return data
}
export async function disable(id: number): Promise<PluginInstallation> {
const { data } = await apiClient.post<PluginInstallation>(`/admin/plugins/${id}/disable`)
return data
}
export async function remove(id: number): Promise<void> {
await apiClient.delete(`/admin/plugins/${id}`)
}
export async function getConfig(id: number): Promise<Record<string, unknown>> {
const { data } = await apiClient.get<Record<string, unknown>>(`/admin/plugins/${id}/config`)
return data
}
export async function saveConfig(
id: number,
config: Record<string, unknown>
): Promise<Record<string, unknown>> {
const { data } = await apiClient.put<Record<string, unknown>>(`/admin/plugins/${id}/config`, config)
return data
}
export async function test(id: number): Promise<PluginTestResult> {
const { data } = await apiClient.post<PluginTestResult>(`/admin/plugins/${id}/test`)
return data
}
export async function createUISession(id: number): Promise<PluginUISession> {
const { data } = await apiClient.post<PluginUISession>(`/admin/plugins/${id}/ui-session`)
return data
}
export default {
list,
upload,
enable,
disable,
remove,
getConfig,
saveConfig,
test,
createUISession
}
+2
View File
@@ -727,6 +727,7 @@ export interface SystemSettings {
model_plaza_enabled: boolean;
model_plaza_require_auth: boolean;
model_plaza_description: string;
plugin_management_enabled: boolean;
// Affiliate (邀请返利) feature switch
affiliate_enabled: boolean;
@@ -1026,6 +1027,7 @@ export interface UpdateSettingsRequest {
model_plaza_enabled?: boolean;
model_plaza_require_auth?: boolean;
model_plaza_description?: string;
plugin_management_enabled?: boolean;
// Affiliate (邀请返利) feature switch
affiliate_enabled?: boolean;