diff --git a/.gitignore b/.gitignore index 7231f1b..63373dd 100644 --- a/.gitignore +++ b/.gitignore @@ -4,5 +4,6 @@ node_modules/ *.zip popup-test-*.png +popup-test.png test-*.html test-*.js diff --git a/manifest.json b/manifest.json index 821cb09..c2ade26 100644 --- a/manifest.json +++ b/manifest.json @@ -3,7 +3,7 @@ "name": "gnexus-creds", "version": "0.1.0", "description": "Browser extension for gnexus-creds secret manager.", - "permissions": ["storage", "activeTab"], + "permissions": ["storage", "activeTab", "alarms"], "host_permissions": ["https://*/*", "http://*/*"], "background": { "service_worker": "src/background.js", diff --git a/src/background.js b/src/background.js index ff460c2..5636a3d 100644 --- a/src/background.js +++ b/src/background.js @@ -51,6 +51,17 @@ }); } +chrome.alarms.create("refresh-secrets-cache", { periodInMinutes: 15 }); + +chrome.alarms.onAlarm.addListener(async (alarm) => { + if (alarm.name !== "refresh-secrets-cache") return; + try { + await getSecretsCached(true); + } catch { + // ignore — no token or network error + } +}); + chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { (async () => { try { diff --git a/src/content.css b/src/content.css index 87b74b7..5e28d67 100644 --- a/src/content.css +++ b/src/content.css @@ -19,12 +19,12 @@ border-top: 2px solid #58a6ff; color: #c9d1d9; font-family: 'IBM Plex Mono', ui-monospace, monospace; - font-size: 12px; - border-radius: 6px; - box-shadow: 0 4px 12px rgba(0,0,0,0.4); - padding: 12px 16px; - min-width: 260px; - max-width: 400px; + font-size: 14px; + border-radius: 0; + box-shadow: 0 6px 16px rgba(0,0,0,0.5); + padding: 16px 20px; + min-width: 300px; + max-width: 460px; width: 100%; opacity: 0; transform: translateY(-12px); @@ -46,12 +46,38 @@ font-weight: 600; color: #58a6ff; word-break: break-word; - margin-bottom: 10px; + margin-bottom: 14px; + font-size: 15px; +} + +.gnexus-creds-autofill-list { + max-height: 200px; + overflow-y: auto; + margin-bottom: 14px; +} + +.gnexus-creds-autofill-row { + display: flex; + align-items: center; + justify-content: space-between; + gap: 10px; + padding: 8px 0; + border-bottom: 1px solid #30363d; +} + +.gnexus-creds-autofill-row:last-child { + border-bottom: none; +} + +.gnexus-creds-autofill-row-title { + font-size: 13px; + color: #c9d1d9; + word-break: break-word; } .gnexus-creds-autofill-actions { display: flex; - gap: 8px; + gap: 10px; justify-content: flex-end; } @@ -59,12 +85,13 @@ background: #238636; border: none; color: #fff; - padding: 5px 12px; - border-radius: 4px; + padding: 7px 16px; + border-radius: 0; font-family: inherit; - font-size: 11px; + font-size: 13px; cursor: pointer; line-height: 1; + flex-shrink: 0; } .gnexus-creds-autofill-btn-secondary { diff --git a/src/content.js b/src/content.js index 47b95a4..9f428e7 100644 --- a/src/content.js +++ b/src/content.js @@ -132,7 +132,7 @@ }, 280); } -function showAutofillCard(form, usernameInput, passwordInput, secret) { +function showAutofillCard(form, usernameInput, passwordInput, secrets) { const key = form || passwordInput; if (!key || shownCards.has(key)) return; shownCards.add(key); @@ -140,22 +140,43 @@ const container = getAutofillContainer(); const card = document.createElement("div"); card.className = "gnexus-creds-autofill-card"; - card.innerHTML = ` -