Skip to content
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

Adds url whitelist regex to ext options #410

Merged
merged 4 commits into from
Feb 8, 2024
Merged
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
67 changes: 59 additions & 8 deletions build/UserALEWebExtension/background.js
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,30 @@ var intervalCounter;
var intervalLog;
var cbHandlers = {};

/**
* Adds named callbacks to be executed when logging.
* @param {Object } newCallbacks An object containing named callback functions.
*/
function addCallbacks() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add some comments to this function to help describe what's happening here at a business logic level.

for (var _len = arguments.length, newCallbacks = new Array(_len), _key = 0; _key < _len; _key++) {
newCallbacks[_key] = arguments[_key];
}
newCallbacks.forEach(function (source) {
var descriptors = Object.keys(source).reduce(function (descriptors, key) {
descriptors[key] = Object.getOwnPropertyDescriptor(source, key);
return descriptors;
}, {});
Object.getOwnPropertySymbols(source).forEach(function (sym) {
var descriptor = Object.getOwnPropertyDescriptor(source, sym);
if (descriptor.enumerable) {
descriptors[sym] = descriptor;
}
});
Object.defineProperties(cbHandlers, descriptors);
});
return cbHandlers;
}

/**
* Assigns the config and log container to be used by the logging functions.
* @param {Array} newLogs Log container.
Expand Down Expand Up @@ -1131,32 +1155,59 @@ var defaultConfig = {
authHeader: null,
toolName: 'useralePlugin',
version: version
},
pluginConfig: {
// Default to a regex that will match no string
urlWhitelist: '(?!x)x'
}
};
browser.storage.local.get(defaultConfig, function (res) {
options(res.useraleConfig);
});
var urlWhitelist;
function updateConfig(config) {
console.log(config);
urlWhitelist = new RegExp(config.pluginConfig.urlWhitelist);
options(config.useraleConfig);
// TODO: tabs need a page load to apply this config change.
dispatchTabMessage(config.useraleConfig);
}
function dispatchTabMessage(message) {
browser.tabs.query({}, function (tabs) {
tabs.forEach(function (tab) {
browser.tabs.sendMessage(tab.id, message);
});
});
}

// Filter out logs with urls that do not match the regex defined in extension options.
function filterUrl(log) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code smell to have two different return types depending on conditional. Since you're not actually modifying the log, you don't need to return the log.

Better to have function name like isUrlWhitelisted which only returns bool.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is a little wonky because it has to match the pattern expected by addcallbacks(). Callbacks are called by package log functions and modify logs or drop them if given a falsey value. I've already created a ticket to change this callback functionality to match the pattern you used for modifying headers. Once the core api is changed, we can modify how we're using it here.

Here's some background on why addcallbacks is the way it is:
#312
#350

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understood.

if (urlWhitelist.test(log.pageUrl)) {
return log;
}
return false;
}
browser.storage.local.get(defaultConfig, function (res) {
// Apply url filter to logs generated by the background page.
addCallbacks({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again please add brief explanation of why we need add the filterUrl as a callback since in the lines right below we apply the function directly in the browser event handler.

filterUrl: filterUrl
});
updateConfig(res);
});
browser.runtime.onMessage.addListener(function (message, sender, sendResponse) {
switch (message.type) {
// Handles logs rerouted from content and option scripts
// Handles logs rerouted from content and option scripts.
case ADD_LOG:
var log$1 = message.payload;
if ("tab" in sender && "id" in sender.tab) {
log$1["tabId"] = sender.tab.id;
}
log(log$1);
// Apply url filter to logs generated outside the background page.
log$1 = filterUrl(log$1);
if (log$1) {
console.log("match");
log(log$1);
}
break;
case CONFIG_CHANGE:
console.log(message);
options(message.payload);
dispatchTabMessage(message);
updateConfig(message.payload);
break;
default:
console.log('got unknown message type ', message);
Expand Down
3 changes: 2 additions & 1 deletion build/UserALEWebExtension/content.js
Original file line number Diff line number Diff line change
Expand Up @@ -1100,6 +1100,7 @@ function options(newConfig) {
// browser is defined in firefox, but chrome uses the 'chrome' global.
var browser = browser || chrome;
function rerouteLog(log) {
console.log("reroute");
browser.runtime.sendMessage({
type: ADD_LOG,
payload: log
Expand Down Expand Up @@ -1129,7 +1130,7 @@ function rerouteLog(log) {
browser.storage.local.get("useraleConfig", function (res) {
options(res.useraleConfig);
addCallbacks({
reroute: rerouteLog
rerouteLog: rerouteLog
});
});
browser.runtime.onMessage.addListener(function (message) {
Expand Down
18 changes: 13 additions & 5 deletions build/UserALEWebExtension/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -1100,6 +1100,7 @@ function options(newConfig) {
// browser is defined in firefox, but chrome uses the 'chrome' global.
var browser = browser || chrome;
function rerouteLog(log) {
console.log("reroute");
browser.runtime.sendMessage({
type: ADD_LOG,
payload: log
Expand Down Expand Up @@ -1127,7 +1128,7 @@ function rerouteLog(log) {
*/

addCallbacks({
reroute: rerouteLog
rerouteLog: rerouteLog
});
function setConfig() {
var config = {
Expand All @@ -1142,13 +1143,17 @@ function setConfig() {
if (config.userId && password) {
config.authHeader = "Basic " + btoa("".concat(config.userId, ":").concat(password));
}
browser.storage.local.set({
useraleConfig: config
}, function () {
var payload = {
useraleConfig: config,
pluginConfig: {
urlWhitelist: document.getElementById("filter").value
}
};
browser.storage.local.set(payload, function () {
options(config);
browser.runtime.sendMessage({
type: CONFIG_CHANGE,
payload: config
payload: payload
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI: JS will automatically infer the key if your value of the same name.

So {type: CONFIG_CHANGE, payload } is perfectly valid. Saves you a few characters of typing.

});
});
}
Expand All @@ -1161,6 +1166,9 @@ function getConfig() {
document.getElementById("tool").value = config.toolName;
document.getElementById("version").value = config.version;
});
browser.storage.local.get("pluginConfig", function (res) {
document.getElementById("filter").value = res.pluginConfig.urlWhitelist;
});
}
document.addEventListener("DOMContentLoaded", getConfig);
document.addEventListener("submit", setConfig);
Expand Down
4 changes: 4 additions & 0 deletions build/UserALEWebExtension/optionsPage.html
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ <h1>Options</h1>
<input id="version"/>
<br/>

<label>URL whitelist regex:</label>
<input id="filter"/>
<br/>

<div align="right">
<button type="submit">Save</button>
</div>
Expand Down
57 changes: 42 additions & 15 deletions src/UserALEWebExtension/background.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,28 @@ import * as userale from '../main.js';
import { browser } from './globals.js';

// Initalize userale plugin options
const defaultConfig = {useraleConfig: {
url: 'http://localhost:8000',
userId: 'pluginUser',
authHeader: null,
toolName: 'useralePlugin',
version: userale.version,
}};
const defaultConfig = {
useraleConfig: {
url: 'http://localhost:8000',
userId: 'pluginUser',
authHeader: null,
toolName: 'useralePlugin',
version: userale.version,
},
pluginConfig: {
// Default to a regex that will match no string
urlWhitelist: '(?!x)x'
}
};

browser.storage.local.get(defaultConfig, (res) => {
userale.options(res.useraleConfig);
});
var urlWhitelist;

function updateConfig(config) {
urlWhitelist = new RegExp(config.pluginConfig.urlWhitelist);
userale.options(config.useraleConfig);
// TODO: tabs need a page load to apply this config change.
dispatchTabMessage(config.useraleConfig);
}

function dispatchTabMessage(message) {
browser.tabs.query({}, function (tabs) {
Expand All @@ -44,21 +55,37 @@ function dispatchTabMessage(message) {
});
}

// Filter out logs with urls that do not match the regex defined in extension options.
function filterUrl(log) {
if(urlWhitelist.test(log.pageUrl)) {
return log
}
return false;
}

browser.storage.local.get(defaultConfig, (res) => {
// Apply url filter to logs generated by the background page.
userale.addCallbacks({filterUrl});
updateConfig(res);
});

browser.runtime.onMessage.addListener(function (message, sender, sendResponse) {
switch (message.type) {
// Handles logs rerouted from content and option scripts
// Handles logs rerouted from content and option scripts.
case MessageTypes.ADD_LOG:
let log = message.payload;
if("tab" in sender && "id" in sender.tab) {
log["tabId"] = sender.tab.id;
}
userale.log(log);
// Apply url filter to logs generated outside the background page.
log = filterUrl(log);
if(log) {
userale.log(log);
}
break;

case MessageTypes.CONFIG_CHANGE:
console.log(message);
userale.options(message.payload);
dispatchTabMessage(message);
updateConfig(message.payload);
break;

default:
Expand Down
2 changes: 1 addition & 1 deletion src/UserALEWebExtension/content.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { rerouteLog, browser } from './globals.js';

browser.storage.local.get("useraleConfig", (res) => {
userale.options(res.useraleConfig);
userale.addCallbacks({reroute: rerouteLog});
userale.addCallbacks({rerouteLog});
});

browser.runtime.onMessage.addListener(function (message) {
Expand Down
14 changes: 11 additions & 3 deletions src/UserALEWebExtension/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import * as MessageTypes from './messageTypes.js';
import * as userale from '../main.js'
import { rerouteLog, browser } from './globals.js';

userale.addCallbacks({reroute: rerouteLog});
userale.addCallbacks({rerouteLog});

// TODO: Warn users when setting credentials with unsecured connection.
const mitmWarning = "Setting credentials with http will expose you to a MITM attack. Are you sure you want to continue?";
Expand All @@ -39,9 +39,14 @@ function setConfig() {
config.authHeader = "Basic " + btoa(`${config.userId}:${password}`);
}

browser.storage.local.set({useraleConfig: config}, () => {
let payload = {
useraleConfig: config,
pluginConfig: {urlWhitelist: document.getElementById("filter").value}
};

browser.storage.local.set(payload, () => {
userale.options(config);
browser.runtime.sendMessage({ type: MessageTypes.CONFIG_CHANGE, payload: config });
browser.runtime.sendMessage({ type: MessageTypes.CONFIG_CHANGE, payload });
});
}

Expand All @@ -55,6 +60,9 @@ function getConfig() {
document.getElementById("tool").value = config.toolName;
document.getElementById("version").value = config.version;
});
browser.storage.local.get("pluginConfig", (res) => {
document.getElementById("filter").value = res.pluginConfig.urlWhitelist;
});
}

document.addEventListener("DOMContentLoaded", getConfig);
Expand Down
4 changes: 4 additions & 0 deletions src/UserALEWebExtension/optionsPage.html
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ <h1>Options</h1>
<input id="version"/>
<br/>

<label>URL whitelist regex:</label>
<input id="filter"/>
<br/>

<div align="right">
<button type="submit">Save</button>
</div>
Expand Down
Loading