Skip to content

Commit

Permalink
Merge pull request #14 from wsg-ariadne/v0.1.2
Browse files Browse the repository at this point in the history
v0.1.2
  • Loading branch information
jareddantis authored May 13, 2023
2 parents d540dc0 + 2d7ac77 commit 41304ae
Show file tree
Hide file tree
Showing 19 changed files with 262 additions and 82 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ npm run dev
npm run dev:v3
```

Vite will automatically rebuild the extension when you make changes to the source code. You will need to reload the extension in your browser to see the changes.

In development mode, the extension will attempt to contact [Dionysus](https://github.com/wsg-ariadne/dionysus) at `http://localhost:5000` for the data. Make sure to run Dionysus locally before running the extension in this mode. You can change this by setting the `VITE_API_URL` environment variable in the `.env.development` file.

To build the extension **in production mode**, run:
Expand Down
12 changes: 7 additions & 5 deletions background/api/stats.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,17 @@ import { ApiPost } from './request';
import { updateBadgeText } from '../browser/badge';
import { setTransaction } from '../browser/storage';

export const getStats = (tabUrl, successCallback, errorCallback) => {
export const getStats = (tabUrl, successCallback, errorCallback, willUpdateBadge) => {
ApiPost('/reports/by-url', {'page_url': tabUrl}, (data) => {
console.log('api/stats: Got stats for URL ' + tabUrl + ':', data);
console.log('api/stats: Got stats for URL ' + tabUrl, data);
setTransaction('stats', {
url: tabUrl,
stats: data
}).then(() => {
updateBadgeText(data);
if (successCallback !== undefined) successCallback(data);
}).catch((e) => errorCallback(e))
if (willUpdateBadge === true) updateBadgeText(data);
if (typeof successCallback === 'function') successCallback(data);
}).catch((e) => {
if (typeof errorCallback === 'function') errorCallback(e);
});
}, errorCallback);
}
21 changes: 17 additions & 4 deletions background/background.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,22 @@ import * as browser from 'webextension-polyfill';
import {
messageListener,
tabChangeListener,
tabUrlChangeListener
tabCloseListener,
tabUpdateListener
} from './listeners';

browser.runtime.onMessage.addListener(messageListener);
browser.tabs.onActivated.addListener(tabChangeListener);
browser.tabs.onUpdated.addListener(tabUrlChangeListener);
browser.runtime.onInstalled.addListener((details) => {
console.log('Extension installed', details);
});

// Delete IndexedDB database on load
const deleteDatabase = indexedDB.deleteDatabase('ariadne');
deleteDatabase.onsuccess = () => {
console.log('Database deleted');

// Register listeners
browser.runtime.onMessage.addListener(messageListener);
browser.tabs.onActivated.addListener(tabChangeListener);
browser.tabs.onRemoved.addListener(tabCloseListener);
browser.tabs.onUpdated.addListener(tabUpdateListener);
}
15 changes: 6 additions & 9 deletions background/browser/badge.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,16 @@ export const toggleBadge = (state) => {
}

export const updateBadgeText = (stats) => {
console.log('browser/badge: Updating badge text with stats:', stats);
if (stats !== undefined && stats.hasOwnProperty("success") &&
stats.hasOwnProperty("specific_reports") && stats["success"]) {
const count = stats.specific_reports.count;
console.log('browser/badge: Badge count:', count)
if (count > 0) {
action.setBadgeText({
text: count.toString(),
});
return;
}
console.log('browser/badge: Setting badge text to', count)
action.setBadgeText({
text: count.toString(),
});
return;
}
action.setBadgeText({
text: "0",
text: "",
});
}
25 changes: 10 additions & 15 deletions background/browser/storage.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const openDatabase = () => new Promise((res, rej) => {
const request = indexedDB.open('ariadne', 1);
const request = indexedDB.open('ariadne');
request.onerror = (event) => {
console.error(`browser/storage: Error ${event.target.errorCode}`)
console.error(`storage: Error ${event.target.errorCode}`)
rej();
};

Expand All @@ -16,6 +16,10 @@ const openDatabase = () => new Promise((res, rej) => {
// Create storage for badge states per tab
const badgeStateStore = db.createObjectStore('badgeStates', { keyPath: 'tabId' })
badgeStateStore.createIndex('tabId', 'tabId', { unique: true })

// Create storage for URLs per tab
const tabUrlStore = db.createObjectStore('tabUrls', { keyPath: 'tabId' })
tabUrlStore.createIndex('tabId', 'tabId', { unique: true })

// Create storage for Calliope results per URL
const calliopeStore = db.createObjectStore('calliope', { keyPath: 'url' })
Expand All @@ -26,21 +30,16 @@ const openDatabase = () => new Promise((res, rej) => {
janusStore.createIndex('url', 'url', { unique: true })
}

request.onsuccess = (event) => {
console.log('browser/storage: Database ready');
res(event.target.result);
}
request.onsuccess = (event) => res(event.target.result);
});


export const setTransaction = async (store, data) => {
console.log('browser/storage(set): Opening DB');

const db = await openDatabase();
const t = db.transaction(store, 'readwrite');
const s = t.objectStore(store);
return await new Promise((res, rej) => {
t.oncomplete = () => console.log('browser/storage(set): Complete');
t.oncomplete = () => console.log(`storage(set): Saved to ${store}:`, data);
t.onerror = (e) => rej(e);

const r = s.put(data);
Expand All @@ -49,13 +48,11 @@ export const setTransaction = async (store, data) => {
}

export const getTransaction = async (store, key) => {
console.log('browser/storage(get): Opening DB');

const db = await openDatabase();
const t = db.transaction(store, 'readonly');
const s = t.objectStore(store);
return await new Promise((res, rej) => {
t.oncomplete = () => console.log('browser/storage(get): Complete');
t.oncomplete = () => console.log(`storage(get): Got "${key}" from ${store}`);
t.onerror = (ev) => rej(ev);

const r = s.get(key);
Expand All @@ -64,14 +61,12 @@ export const getTransaction = async (store, key) => {
}

export const deleteTransaction = async (store, key) => {
console.log('browser/storage(delete): Opening DB');

const db = await openDatabase();
const t = db.transaction(store, 'readwrite');
const s = t.objectStore(store);
return await new Promise((res, rej) => {
t.oncomplete = () => {
console.log('browser/storage(delete): Complete');
console.log(`storage(delete): Deleted "${key}" from ${store}`);
res();
};
t.onerror = (e) => rej(e);
Expand Down
6 changes: 4 additions & 2 deletions background/listeners/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import messageListener from './message';
import tabChangeListener from './tabChange';
import tabUrlChangeListener from './tabUrlChange';
import tabCloseListener from './tabClose';
import tabUpdateListener from './tabUpdate';

export {
messageListener,
tabChangeListener,
tabUrlChangeListener
tabCloseListener,
tabUpdateListener
}
16 changes: 6 additions & 10 deletions background/listeners/message.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default (request, sender, sendResponse) => {
} else if (request.action === "detection") {
// Listen to detection requests from content scripts
const cookieBannerText = request.args.body;
console.log('listeners/message: Calliope request received from tab', sender.tab.id, 'with body:', cookieBannerText);
console.log('listeners/message: Calliope request received from tab', sender.tab.id);

// POST to API
classifyText(cookieBannerText, (data) => {
Expand Down Expand Up @@ -50,7 +50,7 @@ export default (request, sender, sendResponse) => {
.then(() => sendResponse(data));
});
} else if (request.action === "requestStats") {
console.log("listeners/message: Received stats request from popup", request, sender);
console.log('listeners/message: Received stats request from', sender);

(async () => {
const tabUrl = request.args.url;
Expand Down Expand Up @@ -80,26 +80,22 @@ export default (request, sender, sendResponse) => {
let stats = { calliopeResult, janusResult, cookieBannerText, imageData };
try {
stats = { ...stats, ...await getTransaction('stats', tabUrl) };
console.log('listeners/message: Sending stats to tab', tabUrl, stats)
console.log('listeners/message: Sending stats to', sender)
sendResponse(stats);
deferSending = true;
} catch (e) {
console.error(e);
} finally {
getStats(tabUrl, (newStats) => {
stats = { ...stats, ...newStats };
if (!deferSending) {
console.log('listeners/message: Sending stats to tab', tabUrl, stats)
sendResponse(stats);
} else {
console.log('listeners/message: Revalidated cache for tab', tabUrl)
}
console.log('listeners/message: Refreshed stats for', sender)
if (!deferSending) sendResponse(stats);
}, (error) => {
sendResponse({
success: false,
error
});
})
}, true);
}
})();
}
Expand Down
39 changes: 22 additions & 17 deletions background/listeners/tabChange.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,28 @@ export default (activeInfo) => {
// Get URL of active tab
browser.tabs.get(activeInfo.tabId)
.then((tab) => {
console.log('listeners/tabChange: Tab changed to', tab.url);
console.log('listeners/tabChange: Tab changed to', activeInfo.tabId);

// Fetch latest stats
return new Promise((res, rej) => {
getStats(tab.url, () => res(tab.url), rej);
})
})
.then(async (url) => {
console.log('listeners/tabChange: Stats refreshed');
let enabled = false;
try {
enabled = (await getTransaction('badgeStates', activeInfo.tabId)).enabled;
} catch (_) {
// do nothing
// Fetch latest stats if URL does not start with chrome://
if (tab.url.startsWith('chrome://')) {
return Promise.reject('listeners/tabChange: Ignoring chrome:// URL');
}
const { stats } = await getTransaction('stats', url);
toggleBadge(enabled);
updateBadgeText(stats);
});
return new Promise((res, rej) => getStats(tab.url, () => res(tab.url), rej, false));
})
.then(async (url) => {
console.log('listeners/tabChange: Stats refreshed');
let enabled = false;
try {
enabled = (await getTransaction('badgeStates', activeInfo.tabId)).enabled;
} catch (_) {
// do nothing
}
const { stats } = await getTransaction('stats', url);
toggleBadge(enabled);
updateBadgeText(stats);
})
.catch((err) => {
console.log(err);
updateBadgeText(); // Set badge text to empty
});
}
19 changes: 19 additions & 0 deletions background/listeners/tabClose.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { getTransaction, deleteTransaction } from '../browser/storage';

export default (tabId, _) => {
console.log('listeners/tabClose: Tab closed', tabId);

// Delete badge state and Dionysus stats
deleteTransaction('badgeStates', tabId);
deleteTransaction('stats', tabId);

// Get URL of closed tab
getTransaction('tabUrls', tabId)
.then((url) => {
// Delete Calliope and Janus results
deleteTransaction('calliope', url)
.catch((err) => console.log('listeners/tabClose: No Calliope results to delete', err));
deleteTransaction('janus', url)
.catch((err) => console.log('listeners/tabClose: No Janus results to delete', err));
})
}
17 changes: 17 additions & 0 deletions background/listeners/tabUpdate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { getStats } from "../api/stats";
import { setTransaction } from "../browser/storage";

export default (tabId, changeInfo, _) => {
if (changeInfo.url) {
console.log('listeners/tabUpdate: Tab ' + tabId + ' changed to', changeInfo.url);

// Save URL to IndexedDB
setTransaction('tabUrls', { tabId, url: changeInfo.url });

// Request fresh stats if not a chrome:// URL
if (changeInfo.url.startsWith('chrome://')) {
return;
}
getStats(changeInfo.url, () => {}, () => {}, false);
}
}
9 changes: 0 additions & 9 deletions background/listeners/tabUrlChange.js

This file was deleted.

Loading

0 comments on commit 41304ae

Please sign in to comment.