feat: auth capture — remote browser credential extraction
- BrowserSessionService: add create_ephemeral() for temp sessions
- New auth_capture_service.py: extract cookies, localStorage, sessionStorage from page
- New auth_capture router: POST /sessions, GET /sessions/{id}/extract, DELETE /sessions/{id}
- Frontend AuthCaptureDialog: URL input → browser view → extract → pick candidate
- Upstreams.vue: '提取' button next to Bearer Token field
- No sensitive values logged
This commit is contained in:
@@ -326,3 +326,38 @@ export const browserSessionsApi = {
|
||||
return `${proto}//${location.host}/api/browser-sessions/${id}/ws?${params.toString()}`
|
||||
},
|
||||
}
|
||||
|
||||
// ——— Auth Capture ———
|
||||
export interface AuthCaptureSession {
|
||||
session_id: string
|
||||
ws_url: string
|
||||
}
|
||||
|
||||
export interface AuthCaptureResult {
|
||||
cookies: Record<string, any>[]
|
||||
storage: Record<string, string>
|
||||
session_storage: Record<string, string>
|
||||
candidates: {
|
||||
type: 'bearer_token' | 'cookie' | 'credential'
|
||||
source: string
|
||||
value: string
|
||||
label: string
|
||||
cookie_name?: string
|
||||
cookie_value?: string
|
||||
}[]
|
||||
}
|
||||
|
||||
export const authCaptureApi = {
|
||||
createSession: (url: string, width?: number, height?: number) =>
|
||||
api.post<AuthCaptureSession>('/api/auth-capture/sessions', { url, width, height }),
|
||||
extract: (sessionId: string) =>
|
||||
api.get<AuthCaptureResult>(`/api/auth-capture/sessions/${sessionId}/extract`),
|
||||
closeSession: (sessionId: string) =>
|
||||
api.delete(`/api/auth-capture/sessions/${sessionId}`),
|
||||
wsUrl: (sessionId: string, token?: string) => {
|
||||
const proto = location.protocol === 'https:' ? 'wss:' : 'ws:'
|
||||
const params = new URLSearchParams()
|
||||
if (token) params.set('token', token)
|
||||
return `${proto}//${location.host}/api/browser-sessions/${sessionId}/ws?${params.toString()}`
|
||||
},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user