Files
2026-06-02 15:32:43 +08:00

163 lines
4.8 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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()