139 lines
4.1 KiB
JavaScript
139 lines
4.1 KiB
JavaScript
const smartupInput = document.getElementById('smartup')
|
||
const codeInput = document.getElementById('code')
|
||
const submitButton = document.getElementById('submit')
|
||
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 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()
|
||
})
|
||
|
||
void loadSavedConfig()
|