const AUTH_KEY = "pts_authdata"; const statusEl = document.getElementById("status"); const backendInput = document.getElementById("backendUrl"); chrome.storage.local.get(["backendUrl"], (data) => { if (data.backendUrl) backendInput.value = data.backendUrl; }); function isPtsUrl(url) { return !!url && url.includes("tw-timesheet.supermicro.com"); } async function getActiveTab() { const [tab] = await chrome.tabs.query({ active: true, currentWindow: true }); return tab; } function readAuthViaMessage(tabId) { return new Promise((resolve) => { chrome.tabs.sendMessage(tabId, { type: "GET_PTS_AUTH" }, (response) => { if (chrome.runtime.lastError) { resolve({ ok: false, error: chrome.runtime.lastError.message, }); return; } resolve(response || { ok: false, error: "No response from content script" }); }); }); } async function readAuthViaInjection(tabId) { const results = await chrome.scripting.executeScript({ target: { tabId }, func: (key) => { const raw = localStorage.getItem(key); if (!raw) return null; try { return JSON.parse(raw); } catch { return null; } }, args: [AUTH_KEY], }); const auth = results?.[0]?.result ?? null; return { ok: true, auth }; } async function readAuthFromPage(tab) { let result = await readAuthViaMessage(tab.id); if (!result.ok || !result.auth) { result = await readAuthViaInjection(tab.id); } return result; } async function syncSession(auth, backendUrl) { if (!auth?.accessToken) { throw new Error("找不到登入憑證,請確認已登入工時系統"); } const res = await fetch(`${backendUrl}/api/session`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ accessToken: auth.accessToken, refreshToken: auth.refreshToken, groupCode: auth.groupCode, raw: auth, }), }); const data = await res.json().catch(() => ({})); if (!res.ok) throw new Error(data.detail || res.statusText); return data; } document.getElementById("syncBtn").addEventListener("click", async () => { statusEl.textContent = "同步中..."; const backendUrl = backendInput.value.trim().replace(/\/$/, ""); chrome.storage.local.set({ backendUrl }); try { const tab = await getActiveTab(); if (!tab?.id || !isPtsUrl(tab.url)) { throw new Error("請先切到工時系統分頁(tw-timesheet.supermicro.com)再按同步"); } const pageAuth = await readAuthFromPage(tab); if (!pageAuth.auth) { throw new Error( pageAuth.error ? `${pageAuth.error}。請重新整理工時系統頁面後再試` : "無法讀取登入憑證,請重新整理工時系統頁面並確認已登入" ); } const result = await syncSession(pageAuth.auth, backendUrl); statusEl.textContent = `成功:${result.message || "已同步"}`; } catch (err) { statusEl.textContent = `失敗:${err.message}`; } });