const smartupInput = document.getElementById('smartup') const codeInput = document.getElementById('code') const submitButton = document.getElementById('submit') const saveOriginButton = document.getElementById('save-origin') const statusEl = document.getElementById('status') function setStatus(text, cls = '') { statusEl.textContent = text statusEl.className = `status ${cls}`.trim() } function normalizeOrigin(value) { const text = String(value || '').trim().replace(/\/+$/, '') if (!/^https?:\/\//.test(text)) return '' return text } function parseImportCode(value) { const parts = String(value || '').trim().split(':') if (parts.length < 2 || !parts[0] || !parts.slice(1).join(':')) return null return { sessionId: parts.shift(), secret: parts.join(':'), } } async function loadSavedConfig() { const saved = await chrome.storage.local.get(['smartupOrigin', 'importCode']) smartupInput.value = saved.smartupOrigin || 'http://127.0.0.1:8899' codeInput.value = saved.importCode || '' } async function saveConfig(origin, code) { await chrome.storage.local.set({ smartupOrigin: origin, importCode: code }) } async function saveOriginOnly() { const smartupOrigin = normalizeOrigin(smartupInput.value) if (!smartupOrigin) { setStatus('SmartUp 地址必须以 http:// 或 https:// 开头', 'err') return } saveOriginButton.disabled = true try { await chrome.storage.local.set({ smartupOrigin }) smartupInput.value = smartupOrigin setStatus('SmartUp 地址已保存', 'ok') } catch (error) { setStatus(error?.message || '保存失败', 'err') } finally { saveOriginButton.disabled = false } } async function getActiveTab() { const [tab] = await chrome.tabs.query({ active: true, currentWindow: true }) if (!tab?.id || !tab.url || !/^https?:\/\//.test(tab.url)) { throw new Error('请切换到已登录的 http/https 目标页面') } return tab } async function readPageStorage(tabId) { const [result] = await chrome.scripting.executeScript({ target: { tabId }, func: () => { const copyStorage = (storage) => { const out = {} for (let i = 0; i < storage.length; i += 1) { const key = storage.key(i) if (key) out[key] = storage.getItem(key) || '' } return out } return { local_storage: copyStorage(window.localStorage), session_storage: copyStorage(window.sessionStorage), } }, }) return result?.result || { local_storage: {}, session_storage: {} } } async function readCookies(url) { const cookies = await chrome.cookies.getAll({ url }) return cookies.map((cookie) => ({ name: cookie.name, value: cookie.value, domain: cookie.domain, path: cookie.path, httpOnly: Boolean(cookie.httpOnly), secure: Boolean(cookie.secure), })) } function getAuthHeaders(tabId, origin) { return new Promise((resolve) => { chrome.runtime.sendMessage({ type: 'get-auth-headers', tabId, origin }, (response) => { resolve(response?.auth_headers || []) }) }) } async function submitImport() { const smartupOrigin = normalizeOrigin(smartupInput.value) const importCode = codeInput.value.trim() const parsed = parseImportCode(importCode) if (!smartupOrigin) { setStatus('SmartUp 地址必须以 http:// 或 https:// 开头', 'err') return } if (!parsed) { setStatus('导入码格式应为 session_id:secret', 'err') return } submitButton.disabled = true setStatus('正在采集当前页凭证…') try { await saveConfig(smartupOrigin, importCode) const tab = await getActiveTab() const pageUrl = tab.url const pageOrigin = new URL(pageUrl).origin const [cookies, storage, authHeaders] = await Promise.all([ readCookies(pageUrl), readPageStorage(tab.id), getAuthHeaders(tab.id, pageOrigin), ]) const response = await fetch(`${smartupOrigin}/api/auth-capture/import-sessions/${parsed.sessionId}/submit`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ secret: parsed.secret, page_url: pageUrl, cookies, local_storage: storage.local_storage || {}, session_storage: storage.session_storage || {}, auth_headers: authHeaders, }), }) if (!response.ok) { const text = await response.text() throw new Error(text || `提交失败:${response.status}`) } setStatus(`已提交:${cookies.length} 个 cookie,${authHeaders.length} 个认证请求头`, 'ok') } catch (error) { setStatus(error?.message || '提交失败', 'err') } finally { submitButton.disabled = false } } submitButton.addEventListener('click', () => { void submitImport() }) saveOriginButton.addEventListener('click', () => { void saveOriginOnly() }) void loadSavedConfig()