diff --git a/chrome-extension/manifest.json b/chrome-extension/manifest.json
index 1d126e5..7f457cb 100644
--- a/chrome-extension/manifest.json
+++ b/chrome-extension/manifest.json
@@ -3,7 +3,7 @@
"name": "Alta Proxy Tool Bridge",
"version": "1.0.0",
"description": "Send Alta session cookies to the Alta Proxy Tool desktop app.",
- "permissions": ["cookies", "activeTab"],
+ "permissions": ["cookies", "activeTab", "clipboardWrite"],
"host_permissions": [
"https://*.avasecurity.com/*",
"https://*.avigilon.com/*",
diff --git a/chrome-extension/popup.css b/chrome-extension/popup.css
index ed6c4f1..e4c5e8d 100644
--- a/chrome-extension/popup.css
+++ b/chrome-extension/popup.css
@@ -44,7 +44,13 @@ h1 {
border-color: #F44336;
}
-.send-btn {
+.action-buttons {
+ display: grid;
+ gap: 8px;
+}
+
+.primary-btn,
+.secondary-btn {
display: block;
width: 100%;
padding: 10px 16px;
@@ -59,11 +65,26 @@ h1 {
transition: background 0.2s ease;
}
-.send-btn:hover:not(:disabled) {
+.primary-btn {
+ background: #0E7AFE;
+}
+
+.secondary-btn {
+ background: #2D2D30;
+ border: 1px solid #0E7AFE;
+ color: #E0E0E0;
+}
+
+.primary-btn:hover:not(:disabled) {
background: #0A5FD9;
}
-.send-btn:disabled {
+.secondary-btn:hover:not(:disabled) {
+ background: #0E7AFE;
+}
+
+.primary-btn:disabled,
+.secondary-btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}
diff --git a/chrome-extension/popup.html b/chrome-extension/popup.html
index e82ba1a..a1e04a2 100644
--- a/chrome-extension/popup.html
+++ b/chrome-extension/popup.html
@@ -10,7 +10,10 @@
diff --git a/chrome-extension/popup.js b/chrome-extension/popup.js
index d40a852..a43bb5d 100644
--- a/chrome-extension/popup.js
+++ b/chrome-extension/popup.js
@@ -3,6 +3,7 @@ const APT_TOKEN = 'apt-local-bridge-token';
const tabInfo = document.getElementById('tabInfo');
const sendBtn = document.getElementById('sendBtn');
+const copyBtn = document.getElementById('copyBtn');
const statusMsg = document.getElementById('statusMsg');
let detectedOrigin = null;
@@ -12,6 +13,29 @@ function showStatus(message, type) {
statusMsg.className = 'status-msg ' + type;
}
+function setActionButtonsDisabled(disabled) {
+ sendBtn.disabled = disabled;
+ copyBtn.disabled = disabled;
+}
+
+async function getVaCookieValue() {
+ if (!detectedOrigin) {
+ throw new Error('No Alta deployment detected.');
+ }
+
+ const cookie = await chrome.cookies.get({ url: detectedOrigin, name: 'va' });
+
+ if (!cookie || !cookie.value) {
+ throw new Error('No "va" session cookie found. Are you logged in?');
+ }
+
+ if (cookie.expirationDate && cookie.expirationDate < Date.now() / 1000) {
+ throw new Error('Session cookie has expired. Please log in again.');
+ }
+
+ return cookie.value;
+}
+
// Check the active tab on popup open
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
if (!tabs || tabs.length === 0) {
@@ -42,30 +66,18 @@ chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
detectedOrigin = url.origin;
tabInfo.textContent = 'Detected: ' + hostname;
tabInfo.className = 'tab-info detected';
- sendBtn.disabled = false;
+ setActionButtonsDisabled(false);
});
// Send cookie on button click
sendBtn.addEventListener('click', async () => {
if (!detectedOrigin) return;
- sendBtn.disabled = true;
- showStatus('Retrieving cookie...', 'info');
+ setActionButtonsDisabled(true);
+ showStatus('Retrieving VA token...', 'info');
try {
- const cookie = await chrome.cookies.get({ url: detectedOrigin, name: 'va' });
-
- if (!cookie || !cookie.value) {
- showStatus('No "va" session cookie found. Are you logged in?', 'error');
- sendBtn.disabled = false;
- return;
- }
-
- if (cookie.expirationDate && cookie.expirationDate < Date.now() / 1000) {
- showStatus('Session cookie has expired. Please log in again.', 'error');
- sendBtn.disabled = false;
- return;
- }
+ const cookieValue = await getVaCookieValue();
showStatus('Sending to Alta Proxy Tool...', 'info');
@@ -77,17 +89,16 @@ sendBtn.addEventListener('click', async () => {
},
body: JSON.stringify({
deploymentUrl: detectedOrigin,
- cookieValue: cookie.value
+ cookieValue
})
});
const data = await response.json();
if (data.success) {
- showStatus('Cookie sent successfully!', 'success');
+ showStatus('VA token sent successfully!', 'success');
} else {
showStatus('Error: ' + (data.message || 'Unknown error'), 'error');
- sendBtn.disabled = false;
}
} catch (err) {
if (err.message && err.message.includes('Failed to fetch')) {
@@ -95,6 +106,25 @@ sendBtn.addEventListener('click', async () => {
} else {
showStatus('Error: ' + err.message, 'error');
}
- sendBtn.disabled = false;
+ } finally {
+ setActionButtonsDisabled(false);
+ }
+});
+
+// Copy VA token on button click
+copyBtn.addEventListener('click', async () => {
+ if (!detectedOrigin) return;
+
+ setActionButtonsDisabled(true);
+ showStatus('Retrieving VA token...', 'info');
+
+ try {
+ const cookieValue = await getVaCookieValue();
+ await navigator.clipboard.writeText(cookieValue);
+ showStatus('VA token copied to clipboard!', 'success');
+ } catch (err) {
+ showStatus('Error: ' + err.message, 'error');
+ } finally {
+ setActionButtonsDisabled(false);
}
});