Skip to content

Fix issues with Firefox #48

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
163 changes: 140 additions & 23 deletions background.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ async function configureAutoArchiving() {
}

// Initialize auto-archiving setup on extension load
configureAutoArchiving();
chrome.runtime.onStartup.addListener(configureAutoArchiving);

// Listen for changes to the auto-archive setting
chrome.storage.onChanged.addListener((changes, area) => {
Expand All @@ -136,35 +136,152 @@ chrome.storage.onChanged.addListener((changes, area) => {
});

chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.type === 'archivebox_add') {
try {
const { urls = [], tags=[] } = JSON.parse(message.body);

addToArchiveBox(urls, tags)
.then(() => {
console.log(`Successfully archived ${urls}`);
sendResponse({ok: true});
switch (message.type) {
case 'archivebox_add':
(async () => {
try {
const { urls = [], tags=[] } = message.body;
await addToArchiveBox(urls, tags);
console.log(`Successfully archived ${urls}`);
sendResponse({ok: true});
} catch (error) {
console.error(`Failed send to ArchiveBox server: ${error.message}`);
sendResponse({ok: false, errorMessage: error.message});
}
})();
return true;

case 'test_server_url':
(async () => {
try {
const serverUrl = message.serverUrl;
console.log("Testing server URL:", serverUrl);

if (!serverUrl || !serverUrl.startsWith('http')) {
sendResponse({ok: false, error: "Invalid server URL"});
return;
}

const origin = new URL(serverUrl).origin;
console.log("Server origin:", origin);

// First try without credentials as Firefox is stricter
try {
console.log("Trying server API endpoint");
let response = await fetch(`${serverUrl}/api/`, {
method: 'GET',
mode: 'cors'
});

if (response.ok) {
console.log("API endpoint test successful");
sendResponse({ok: true});
return;
}

// Try the root URL for older ArchiveBox versions
if (response.status === 404) {
console.log("API endpoint not found, trying root URL");
response = await fetch(`${serverUrl}`, {
method: 'GET',
mode: 'cors'
});

if (response.ok) {
console.log("Root URL test successful");
sendResponse({ok: true});
return;
}
}

console.log("Server returned non-OK response:", response.status, response.statusText);
throw new Error(`${response.status} ${response.statusText}`);
} catch (fetchError) {
console.error("Fetch error:", fetchError);
throw new Error(`NetworkError: ${fetchError.message}`);
}
)
.catch((error) => sendResponse({ok: false, errorMessage: error.message}));
} catch (error) {
console.error(`Failed to parse archivebox_add message, no URLs sent to ArchiveBox server: ${error.message}`);
sendResponse({ok: false, errorMessage: error.message});
} catch (error) {
console.error("test_server_url failed:", error);
sendResponse({ok: false, error: error.message});
}
})();
return true;
}
}

return true;
});
case 'test_api_key':
(async () => {
try {
const { serverUrl, apiKey } = message;
console.log("Testing API key for server:", serverUrl);

if (!serverUrl || !serverUrl.startsWith('http')) {
sendResponse({ok: false, error: "Invalid server URL"});
return;
}

if (!apiKey) {
sendResponse({ok: false, error: "API key is required"});
return;
}

chrome.runtime.onMessage.addListener(async (message) => {
const options_url = chrome.runtime.getURL('options.html') + `?search=${message.id}`;
console.log('i ArchiveBox Collector showing options.html', options_url);
if (message.action === 'openOptionsPage') {
await chrome.tabs.create({ url: options_url });
try {
console.log("Attempting to verify API key...");
const response = await fetch(`${serverUrl}/api/v1/auth/check_api_token`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
mode: 'cors',
body: JSON.stringify({
token: apiKey,
})
});

console.log("API key check response status:", response.status);

if (response.ok) {
const data = await response.json();
console.log("API key check response data:", data);

if (data.user_id) {
sendResponse({ok: true, user_id: data.user_id});
} else {
sendResponse({ok: false, error: 'Invalid API key response'});
}
} else {
sendResponse({ok: false, error: `${response.status} ${response.statusText}`});
}
} catch (fetchError) {
console.error("API key check fetch error:", fetchError);
sendResponse({ok: false, error: `NetworkError: ${fetchError.message}`});
}
} catch (error) {
console.error("test_api_key failed:", error);
sendResponse({ok: false, error: error.message});
}
})();
return true;

case 'open_options':
(async () => {
try {
const options_url = chrome.runtime.getURL('options.html') + `?search=${message.id}`;
console.log('i ArchiveBox Collector showing options.html', options_url);
await chrome.tabs.create({ url: options_url });
sendResponse({ok: true});
} catch (error) {
console.error(`Failed to open options page: ${error.message}`);
sendResponse({ok: false, error: error.message});
}
})();
return true;

default:
console.error('Invalid message: ', message);
return true;
}
});

// Create context menus
chrome.runtime.onInstalled.addListener(function () {
chrome.contextMenus.removeAll();
chrome.contextMenus.create({
Expand Down
39 changes: 13 additions & 26 deletions config-tab.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,25 +48,15 @@ export async function initializeConfigTab() {

// Test request to server.
try {
let response = await fetch(`${serverUrl.value}/api/`, {
method: 'GET',
mode: 'cors',
credentials: 'omit'
const testResult = await chrome.runtime.sendMessage({
type: 'test_server_url',
serverUrl: serverUrl.value
});

// fall back to pre-v0.8.0 endpoint for backwards compatibility
if (response.status === 404) {
response = await fetch(`${serverUrl.value}`, {
method: 'GET',
mode: 'cors',
credentials: 'omit'
});
}

if (response.ok) {
if (testResult.ok) {
updateStatusIndicator(statusIndicator, statusText, true, '✓ Server is reachable');
} else {
updateStatusIndicator(statusIndicator, statusText, false, `✗ Server error: ${response.status} ${response.statusText}`);
updateStatusIndicator(statusIndicator, statusText, false, `✗ Server error: ${testResult.error}`);
}
} catch (err) {
updateStatusIndicator(statusIndicator, statusText, false, `✗ Connection failed: ${err.message}`);
Expand All @@ -79,20 +69,17 @@ export async function initializeConfigTab() {
const statusText = document.getElementById('apiKeyStatusText');

try {
const response = await fetch(`${serverUrl.value}/api/v1/auth/check_api_token`, {
method: 'POST',
mode: 'cors',
credentials: 'omit',
body: JSON.stringify({
token: apiKey.value,
})
// Use the background script to avoid CORS issues
const testResult = await chrome.runtime.sendMessage({
type: 'test_api_key',
serverUrl: serverUrl.value,
apiKey: apiKey.value
});
const data = await response.json();

if (data.user_id) {
updateStatusIndicator(statusIndicator, statusText, true, `✓ API key is valid: user_id = ${data.user_id}`);
if (testResult.ok) {
updateStatusIndicator(statusIndicator, statusText, true, `✓ API key is valid: user_id = ${testResult.user_id}`);
} else {
updateStatusIndicator(statusIndicator, statusText, false, `✗ API key error: ${response.status} ${response.statusText} ${JSON.stringify(data)}`);
updateStatusIndicator(statusIndicator, statusText, false, `✗ API key error: ${testResult.error}`);
}
} catch (err) {
updateStatusIndicator(statusIndicator, statusText, false, `✗ API test failed: ${err.message}`);
Expand Down
13 changes: 11 additions & 2 deletions manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,12 @@
"bookmarks",
"tabs"
],
"optional_host_permissions": [
"host_permissions": [
"<all_urls>"
],
"content_security_policy": {
"extension_pages": "script-src 'self'; object-src 'self'"
},
"icons": {
"16": "16.png",
"32": "32.png",
Expand All @@ -36,12 +39,13 @@
},
"options_page": "options.html",
"background": {
"scripts": ["background.js"],
"service_worker": "background.js",
"type": "module"
},
"web_accessible_resources": [{
"resources": ["popup.css", "popup.js"],
"matches": ["*://*\/*"]
"matches": ["<all_urls>"]
}],
"commands": {
"save-to-archivebox-action": {
Expand All @@ -51,5 +55,10 @@
"mac": "Command+Shift+X"
}
}
},
"browser_specific_settings": {
"gecko": {
"id": "archivebox@example.com"
}
}
}
2 changes: 1 addition & 1 deletion options.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ document.addEventListener('DOMContentLoaded', () => {
var tabEls = document.querySelectorAll('a.nav-link[data-bs-toggle="tab"]')
for (const tabEl of tabEls) {
tabEl.addEventListener('shown.bs.tab', function (event) {
console.log('ArchiveBox tab switched to:', event.target);
console.debug('ArchiveBox tab switched to:', event.target);
event.target // newly activated tab
event.relatedTarget // previous active tab
// window.location.hash = event.target.id;
Expand Down
Loading