Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • weblate/metager-webextension
  • open-source/metager-webextension
2 results
Show changes
Commits on Source (7)
# v1.2
* Add hint to show if settings are applied in inkognito mode
* Fix: Interface on permission updates
* Fix: NetRequestRules not getting applied to Chrome startpages
# v0.1.0.3 # v0.1.0.3
* Fix: Broken link to help page for homomorphic encryption * Fix: Broken link to help page for homomorphic encryption
......
...@@ -49,5 +49,8 @@ ...@@ -49,5 +49,8 @@
}, },
"settings_anonymous_tokens_setup_key": { "settings_anonymous_tokens_setup_key": {
"message": "Setup your MetaGer key" "message": "Setup your MetaGer key"
},
"settings_inkognito": {
"message": "Your MetaGer settings will not be applied in inkognito tabs. If you want to change this you can allow this extension to run in in those."
} }
} }
\ No newline at end of file
...@@ -35,8 +35,8 @@ ...@@ -35,8 +35,8 @@
} }
}, },
"release_notes": { "release_notes": {
"de": "Fix: Schlüssel wurde beim Abmelden nicht richtig entfernt\nFix: Token-Auffüllung, wenn Erweiterungsspeicher beschädigt war\nFix: Schlüssel bei Installation richtig importieren", "de": "",
"en-US": "Fix: key wasn't properly removed on logout\nFix: Token refill when extension storage was corrupted\nFix: properly import key on installation" "en-US": ""
} }
}, },
"is_disabled": false, "is_disabled": false,
......
...@@ -21,7 +21,18 @@ export class SettingsManager { ...@@ -21,7 +21,18 @@ export class SettingsManager {
store_settings = true; store_settings = true;
settings = {}; settings = {};
constructor() { } urls = [];
origins = [];
hosts = [];
constructor() {
browser.runtime.getManifest().host_permissions.forEach((value, index) => {
this.urls.push(value);
let url = new URL(value);
this.hosts.push(url.host);
this.origins.push(url.origin);
});
}
async init() { async init() {
if (this.initialized != null) return this.initialized; if (this.initialized != null) return this.initialized;
...@@ -85,21 +96,11 @@ export class SettingsManager { ...@@ -85,21 +96,11 @@ export class SettingsManager {
if (changeInfo.removed) return; // Do not handle removed cookies if (changeInfo.removed) return; // Do not handle removed cookies
if (!this.store_settings) return; // Do not handle cookies if we're currently not storing settings in extension if (!this.store_settings) return; // Do not handle cookies if we're currently not storing settings in extension
if (this._ignored_settings.includes(changeInfo.cookie.name)) return; // Do not handle ignored settings if (this._ignored_settings.includes(changeInfo.cookie.name)) return; // Do not handle ignored settings
let protocol = changeInfo.cookie.secure ? "https" : "http";
return browser.cookies.remove({ return browser.cookies.remove({
name: changeInfo.cookie.name, name: changeInfo.cookie.name,
url: `https://${changeInfo.cookie.domain}${changeInfo.cookie.path}` url: `${protocol}://${changeInfo.cookie.domain}${changeInfo.cookie.path}`
});
}
async handlePermissionsChange(permissions) {
await this.init();
this.initialized = false;
return this.init().then(() => {
if (this.store_settings) {
return this._enable();
} else {
return this._disable();
}
}); });
} }
...@@ -215,14 +216,12 @@ export class SettingsManager { ...@@ -215,14 +216,12 @@ export class SettingsManager {
}); });
} }
let rules = []; let rules = [];
// Add Rule for web extension version // Add Rule for web extension version
rules.push({ rules.push({
id: 6, id: 6,
condition: { condition: {
requestDomains: [ requestDomains: this.hosts,
"metager.de",
"metager.org"
],
resourceTypes: ["main_frame", "sub_frame", "xmlhttprequest"] resourceTypes: ["main_frame", "sub_frame", "xmlhttprequest"]
}, },
action: { action: {
...@@ -238,10 +237,7 @@ export class SettingsManager { ...@@ -238,10 +237,7 @@ export class SettingsManager {
rules.push({ rules.push({
id: 1, id: 1,
condition: { condition: {
requestDomains: [ requestDomains: this.hosts,
"metager.de",
"metager.org"
],
resourceTypes: ["main_frame", "sub_frame", "xmlhttprequest"] resourceTypes: ["main_frame", "sub_frame", "xmlhttprequest"]
}, },
action: { action: {
...@@ -260,25 +256,23 @@ export class SettingsManager { ...@@ -260,25 +256,23 @@ export class SettingsManager {
this.store_settings = true; this.store_settings = true;
if (!browser.cookies) return; if (!browser.cookies) return;
// First fetch all cookies from metager.org // First fetch all cookies from metager.org
await browser.cookies.getAll({ url: "https://metager.org/" }).then(async cookies => {
let cookie_promises = []; // Fetch cookies from all origins
for (let cookie of cookies) { let cookie_promises = [];
if (this._ignored_settings.includes(cookie.name)) continue; this.origins.forEach(origin => {
this.settings[cookie.name] = cookie.value; let origin_url = new URL(origin);
cookie_promises.push(browser.cookies.remove({ name: cookie.name, url: "https://metager.org/" })); cookie_promises.push(browser.cookies.getAll({ url: origin }).then(cookies => {
} let cookie_delete_promises = [];
return Promise.all(cookie_promises); for (let cookie of cookies) {
}).catch(error => console.error(error)); if (this._ignored_settings.includes(cookie.name)) continue;
await browser.cookies.getAll({ url: "https://metager.de/" }).then(async cookies => { this.settings[cookie.name] = cookie.value;
let cookie_promises = []; cookie_delete_promises.push(browser.cookies.remove({ name: cookie.name, url: origin }));
for (let cookie of cookies) { }
if (this._ignored_settings.includes(cookie.name)) continue; return Promise.all(cookie_delete_promises);
this.settings[cookie.name] = cookie.value; }).catch(error => console.error(error)));
cookie_promises.push(browser.cookies.remove({ name: cookie.name, url: "https://metager.de/" })); });
}
return Promise.all(cookie_promises); return Promise.all(cookie_promises).then(() => this.sync());
}).catch(error => console.error(error));
return this.sync();
} }
async _disable() { async _disable() {
...@@ -289,21 +283,18 @@ export class SettingsManager { ...@@ -289,21 +283,18 @@ export class SettingsManager {
let expiration = new Date(); let expiration = new Date();
expiration.setFullYear(expiration.getFullYear() + 1); expiration.setFullYear(expiration.getFullYear() + 1);
for (let setting_key in this.settings) { for (let setting_key in this.settings) {
create_cookies_promises.push(browser.cookies.set({ this.origins.forEach(origin => {
url: "https://metager.de/", let origin_url = new URL(origin);
name: setting_key, create_cookies_promises.push(browser.cookies.set({
value: this.settings[setting_key], url: origin,
expirationDate: Math.round(expiration.getTime() / 1000), name: setting_key,
secure: true value: this.settings[setting_key],
}).catch(error => console.error(error))); expirationDate: Math.round(expiration.getTime() / 1000),
create_cookies_promises.push(browser.cookies.set({ secure: origin_url.protocol != "http:"
url: "https://metager.org/", }).catch(error => console.error(error)));
name: setting_key, });
value: this.settings[setting_key],
expirationDate: Math.round(expiration.getTime() / 1000),
secure: true
}).catch(error => console.error(error)));
} }
return Promise.all(create_cookies_promises).then(async () => this.updateSettingRule()); return Promise.all(create_cookies_promises).then(async () => this.updateSettingRule());
} }
} }
......
...@@ -32,6 +32,7 @@ export class TokenManager { ...@@ -32,6 +32,7 @@ export class TokenManager {
}; };
_handled_cookies = ["key", "cost", "tokens"] _handled_cookies = ["key", "cost", "tokens"]
_permissions_granted = false;
_initialized = null; _initialized = null;
_anonymous_tokens_enabled = false; _anonymous_tokens_enabled = false;
...@@ -49,7 +50,20 @@ export class TokenManager { ...@@ -49,7 +50,20 @@ export class TokenManager {
_recent_costs = []; // The latest cost for the last few MetaGer searches _recent_costs = []; // The latest cost for the last few MetaGer searches
_recent_costs_number = 3; // How many recent costs to account for in calculation _recent_costs_number = 3; // How many recent costs to account for in calculation
_urls = [];
_origins = [];
_hosts = [];
constructor() { constructor() {
browser.runtime.getManifest().host_permissions.forEach((value, index) => {
this._urls.push(value);
let url = new URL(value);
this._hosts.push(url.host);
this._origins.push(url.origin);
});
if (process.env.NODE_ENV == "development") {
this._api_base = "http://localhost:8080/keys/api/json";
}
this.init(); this.init();
} }
...@@ -63,8 +77,8 @@ export class TokenManager { ...@@ -63,8 +77,8 @@ export class TokenManager {
this._initialized = browser.storage.sync this._initialized = browser.storage.sync
.get(settings) .get(settings)
.then(async (storage) => { .then(async (storage) => {
let permissions_granted = await this._checkPermissions(); this._permissions_granted = await this._checkPermissions();
if (permissions_granted == false) { if (this._permissions_granted == false) {
this._anonymous_tokens_enabled = false; this._anonymous_tokens_enabled = false;
} else if (storage[this._storage_keys.anonymous_tokens_enabled] == null) { } else if (storage[this._storage_keys.anonymous_tokens_enabled] == null) {
this._anonymous_tokens_enabled = true; this._anonymous_tokens_enabled = true;
...@@ -91,9 +105,9 @@ export class TokenManager { ...@@ -91,9 +105,9 @@ export class TokenManager {
this._recent_costs = storage[this._storage_keys.tokens_recent_costs]; this._recent_costs = storage[this._storage_keys.tokens_recent_costs];
this._key_charge = storage[this._storage_keys.key_charge]; this._key_charge = storage[this._storage_keys.key_charge];
this._key_charge_check = storage[this._storage_keys.key_charge_check]; this._key_charge_check = storage[this._storage_keys.key_charge_check];
setInterval(this.refill.bind(this), 15000);
return this.refill(); return this.refill();
}).then(() => this._updateNetRequestRules()); }).then(() => this._updateNetRequestRules());
return this._initialized;
} }
async handleStorageChange(changes) { async handleStorageChange(changes) {
...@@ -183,58 +197,49 @@ export class TokenManager { ...@@ -183,58 +197,49 @@ export class TokenManager {
return; return;
} }
/**
* When Extension permission change try to load key from cookie in browser
* and reinitialize Tokenmanager
*
* @param {*} permissions
* @returns
*/
async handlePermissionsChange(permissions) {
await this.init();
this._initialized = null;
return this._checkPermissions().then(async granted => {
if (granted) {
return this._load_key_from_browser().then(() => this.init());
} else {
return this.init();
}
});
}
async handleCookieChange(changeInfo) { async handleCookieChange(changeInfo) {
await this.init(); await this.init();
if (changeInfo.removed) return; // Do not handle removed cookies if (changeInfo.removed) return; // Do not handle removed cookies
if (!this._handled_cookies.includes(changeInfo.cookie.name)) return; // Do not handle unspecified cookies if (!this._handled_cookies.includes(changeInfo.cookie.name)) return; // Do not handle unspecified cookies
let protocol = changeInfo.cookie.secure ? "https" : "http";
return browser.cookies.remove({ return browser.cookies.remove({
name: changeInfo.cookie.name, name: changeInfo.cookie.name,
url: `https://${changeInfo.cookie.domain}${changeInfo.cookie.path}` url: `${protocol}://${changeInfo.cookie.domain}${changeInfo.cookie.path}`
}); });
} }
/**
* Returns the current key charge
*/
async getKeyCharge() {
return this._fetch_key_charge();
}
async _load_key_from_browser() { async _load_key_from_browser() {
if (!this._permissions_granted) return;
// Consume a possible key cookie // Consume a possible key cookie
await browser.cookies.get({ name: "key", url: "https://metager.org/" }).then(async key_cookie => { let key = "";
if (key_cookie == null) { let cookie_promises = [];
return; for (let i = 0; i < this._origins.length; i++) {
let origin = this._origins[i];
let key_cookie = await browser.cookies.get({ name: "key", url: origin });
if (key_cookie != null) {
key = key_cookie.value;
cookie_promises.push(browser.cookies.remove({ name: "key", url: origin }));
} }
return this.store_key(key_cookie.value).then(async () => { }
return browser.cookies.remove({ name: "key", url: "https://metager.org/" }); return Promise.all(cookie_promises).then(() => {
}); if (key.length > 0) {
}).catch(error => console.error(error)); return this.store_key(key);
await browser.cookies.get({ name: "key", url: "https://metager.de/" }).then(async key_cookie => {
if (key_cookie == null) {
return;
} }
return this.store_key(key_cookie.value).then(async () => {
return browser.cookies.remove({ name: "key", url: "https://metager.de/" });
});
}).catch(error => console.error(error)); }).catch(error => console.error(error));
} }
async _fetch_key_charge() { async _fetch_key_charge() {
if (this._key == null) return 0; if (this._key == null) return 0;
return fetch("https://metager.de/keys/api/json/key/" + encodeURIComponent(this._key), {
return fetch(`${this._api_base}/key/` + encodeURIComponent(this._key), {
headers: { headers: {
"Cache-Control": "no-cache", "Cache-Control": "no-cache",
} }
...@@ -258,10 +263,7 @@ export class TokenManager { ...@@ -258,10 +263,7 @@ export class TokenManager {
rules.push({ rules.push({
id: 2, id: 2,
condition: { condition: {
requestDomains: [ requestDomains: this._hosts,
"metager.de",
"metager.org"
],
urlFilter: "/keys/*", urlFilter: "/keys/*",
resourceTypes: ["main_frame", "sub_frame", "xmlhttprequest"] resourceTypes: ["main_frame", "sub_frame", "xmlhttprequest"]
}, },
...@@ -277,10 +279,7 @@ export class TokenManager { ...@@ -277,10 +279,7 @@ export class TokenManager {
rules.push({ rules.push({
id: 3, id: 3,
condition: { condition: {
requestDomains: [ requestDomains: this._hosts,
"metager.de",
"metager.org"
],
urlFilter: "/meta/settings*", urlFilter: "/meta/settings*",
resourceTypes: ["main_frame", "sub_frame", "xmlhttprequest"] resourceTypes: ["main_frame", "sub_frame", "xmlhttprequest"]
}, },
...@@ -299,10 +298,7 @@ export class TokenManager { ...@@ -299,10 +298,7 @@ export class TokenManager {
rules.push({ rules.push({
id: 4, id: 4,
condition: { condition: {
requestDomains: [ requestDomains: this._hosts,
"metager.de",
"metager.org"
],
resourceTypes: ["main_frame", "sub_frame", "xmlhttprequest"] resourceTypes: ["main_frame", "sub_frame", "xmlhttprequest"]
}, },
action: { action: {
...@@ -323,10 +319,7 @@ export class TokenManager { ...@@ -323,10 +319,7 @@ export class TokenManager {
rules.push({ rules.push({
id: 2, id: 2,
condition: { condition: {
requestDomains: [ requestDomains: this._hosts,
"metager.de",
"metager.org"
],
resourceTypes: ["main_frame", "sub_frame", "xmlhttprequest"] resourceTypes: ["main_frame", "sub_frame", "xmlhttprequest"]
}, },
action: { action: {
...@@ -476,10 +469,7 @@ export class TokenManager { ...@@ -476,10 +469,7 @@ export class TokenManager {
*/ */
async _checkPermissions() { async _checkPermissions() {
let permissionsToRequest = { let permissionsToRequest = {
origins: [ origins: this._urls
"https://metager.org/*",
"https://metager.de/*",
]
}; };
return browser.permissions.contains(permissionsToRequest); return browser.permissions.contains(permissionsToRequest);
...@@ -506,7 +496,7 @@ export class TokenManager { ...@@ -506,7 +496,7 @@ export class TokenManager {
if (this._key_charge == 0) { if (this._key_charge == 0) {
// If the key is empty there is no need to try to generate signed tokens on each request // If the key is empty there is no need to try to generate signed tokens on each request
// Instead we will regulary check if the key was charged // Instead we will regulary check if the key was charged
if ((this._key_charge_check + 15 * 60 * 1000) < (new Date()).getTime()) { if ((this._key_charge_check + 1 * 60 * 1000) < (new Date()).getTime()) {
// Check key charge // Check key charge
return this._fetch_key_charge().then(async charge => { return this._fetch_key_charge().then(async charge => {
let settings = {}; let settings = {};
......
...@@ -8,6 +8,34 @@ if (typeof browser == "undefined") { ...@@ -8,6 +8,34 @@ if (typeof browser == "undefined") {
var browser = chrome; var browser = chrome;
} }
urls = [];
origins = [];
hosts = [];
browser.runtime.getManifest().host_permissions.forEach((value, index) => {
urls.push(value);
let url = new URL(value);
hosts.push(url.host);
origins.push(url.origin);
});
/**
* Execute things when a new browser profile is created
*/
browser.runtime.onStartup.addListener(async () => {
// Initialize our settings managers
let init_promises = [settingsManager.init(), tokenManager.init()];
return Promise.all(init_promises).then(() => {
if (BROWSER != "CHROME") return;
/** Chrome currently does not apply NetRequestRules to startpages. But they will be applied after a reload */
browser.tabs.query({}).then(tabs => {
let reloads = [];
tabs.forEach(tab => reloads.push(browser.tabs.reload(tab.id)));
return Promise.all(reloads);
})
});
});
/** /**
* Handle messages between content scripts and background script: * Handle messages between content scripts and background script:
...@@ -54,6 +82,17 @@ browser.runtime.onMessage.addListener((request, sender, sendResponse) => { ...@@ -54,6 +82,17 @@ browser.runtime.onMessage.addListener((request, sender, sendResponse) => {
}); });
return true; return true;
} }
if (request.type == "key") {
if (request.hasOwnProperty("action") && request.action == "getcharge") {
tokenManager.getKeyCharge().then(charge => {
sendResponse({ status: "ok", data: { charge: charge } });
}).catch(error => {
console.trace(error);
sendResponse({ status: "error" });
});
return true;
}
}
}); });
/** /**
...@@ -69,12 +108,12 @@ browser.storage.onChanged.addListener(async (changes, areaName) => { ...@@ -69,12 +108,12 @@ browser.storage.onChanged.addListener(async (changes, areaName) => {
tokenManager.handleStorageChange(changes); tokenManager.handleStorageChange(changes);
}); });
browser.permissions.onAdded.addListener(async (permissions) => { browser.permissions.onAdded.addListener(async (permissions) => {
await settingsManager.handlePermissionsChange(permissions); browser.runtime.reload();
await tokenManager.handlePermissionsChange(permissions); return;
}); });
browser.permissions.onRemoved.addListener(async (permissions) => { browser.permissions.onRemoved.addListener(async (permissions) => {
await settingsManager.handlePermissionsChange(permissions); browser.runtime.reload();
await tokenManager.handlePermissionsChange(permissions); return;
}); });
/** /**
...@@ -105,7 +144,7 @@ browser.webRequest.onBeforeSendHeaders.addListener( ...@@ -105,7 +144,7 @@ browser.webRequest.onBeforeSendHeaders.addListener(
return { requestHeaders: headers }; return { requestHeaders: headers };
}, },
{ {
urls: ["https://metager.org/*", "https://metager.de/*"], urls: origins.map(origin => origin + "/*"),
}, },
extraInfoSpecRequest extraInfoSpecRequest
); );
...@@ -116,12 +155,11 @@ if (BROWSER == "CHROME") { ...@@ -116,12 +155,11 @@ if (BROWSER == "CHROME") {
} }
browser.webRequest.onHeadersReceived.addListener( browser.webRequest.onHeadersReceived.addListener(
(details) => { (details) => {
settingsManager.handleResponseHeaders(details); settingsManager.handleResponseHeaders(details);
tokenManager.handleResponseHeaders(details); tokenManager.handleResponseHeaders(details);
}, },
{ {
urls: ["https://metager.org/*", "https://metager.de/*"], urls: origins.map(origin => origin + "/*"),
}, },
extraInfoSpecResponse extraInfoSpecResponse
); );
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
"author": "SUMA-EV", "author": "SUMA-EV",
"manifest_version": 3, "manifest_version": 3,
"name": "__MSG_searchProviderName__", "name": "__MSG_searchProviderName__",
"version": "1.1", "version": "1.2",
"description": "__MSG_extensionDescription__", "description": "__MSG_extensionDescription__",
"default_locale": "en", "default_locale": "en",
"browser_specific_settings": { "browser_specific_settings": {
...@@ -83,9 +83,7 @@ ...@@ -83,9 +83,7 @@
{ {
"matches": [ "matches": [
"https://metager.org/keys/*", "https://metager.org/keys/*",
"https://metager.org/*/keys/*", "https://metager.org/*/keys/*"
"https://metager.de/keys/*",
"https://metager.de/*/keys/*"
], ],
"run_at": "document_idle", "run_at": "document_idle",
"js": [ "js": [
......
...@@ -53,6 +53,9 @@ ...@@ -53,6 +53,9 @@
</div> </div>
</div> </div>
</div> </div>
<div class="setting" id="inkognito">
<p data-text="settings_inkognito"></p>
</div>
<script src="strings.js"></script> <script src="strings.js"></script>
<script src="index.js" async></script> <script src="index.js" async></script>
<script src="tokenstatus.js" async></script> <script src="tokenstatus.js" async></script>
......
...@@ -6,8 +6,27 @@ if (typeof browser == "undefined") { ...@@ -6,8 +6,27 @@ if (typeof browser == "undefined") {
(async () => { (async () => {
let store_settings = null; let store_settings = null;
let use_anonymous_tokens = null; let use_anonymous_tokens = null;
let permissions_granted = false;
let inkognito_allowed = false;
let checkbox_store_settings = document.querySelector("#store-settings-switch"); let checkbox_store_settings = document.querySelector("#store-settings-switch");
let checkbox_anonymous_tokens = document.querySelector("#anonymous-tokens-switch"); let checkbox_anonymous_tokens = document.querySelector("#anonymous-tokens-switch");
let inkognito_settings_container = document.querySelector("#inkognito");
let urls = [];
let origins = [];
let hosts = [];
browser.runtime.getManifest().host_permissions.forEach((value, index) => {
urls.push(value);
let url = new URL(value);
hosts.push(url.host);
origins.push(url.origin);
});
let permissions = [
"storage",
"cookies",
"webRequest",
"declarativeNetRequestWithHostAccess"
];
await initializeSettingsState(); await initializeSettingsState();
...@@ -54,10 +73,14 @@ if (typeof browser == "undefined") { ...@@ -54,10 +73,14 @@ if (typeof browser == "undefined") {
* change * change
*/ */
browser.permissions.onAdded.addListener(async (permissions) => { browser.permissions.onAdded.addListener(async (permissions) => {
return initializeSettingsState(); permissions_granted = await verifyPermissions();
showSettingsState();
return;
}); });
browser.permissions.onRemoved.addListener(async (permissions) => { browser.permissions.onRemoved.addListener(async (permissions) => {
return initializeSettingsState(); permissions_granted = await verifyPermissions();
showSettingsState();
return;
}); });
/** /**
...@@ -68,12 +91,9 @@ if (typeof browser == "undefined") { ...@@ -68,12 +91,9 @@ if (typeof browser == "undefined") {
*/ */
async function verifyPermissions(request = false) { async function verifyPermissions(request = false) {
let permissionsToRequest = { let permissionsToRequest = {
origins: [ origins: urls,
"https://metager.org/*", permissions: permissions
"https://metager.de/*",
]
}; };
if (request) { if (request) {
return browser.permissions.request(permissionsToRequest); return browser.permissions.request(permissionsToRequest);
} else { } else {
...@@ -83,32 +103,20 @@ if (typeof browser == "undefined") { ...@@ -83,32 +103,20 @@ if (typeof browser == "undefined") {
/** /**
* Loads the current settings from browser storage and * Loads the current settings from browser storage and
* cross checks those settings with the app permissions. * verifies current permission state
* If permissions are missing all features will be turned off
* regardless of the setting state and can be turned on again
* by the user
*/ */
async function initializeSettingsState() { async function initializeSettingsState() {
// Update permissions state
permissions_granted = await verifyPermissions();
// Initialize stored settings // Initialize stored settings
let synced_settings = await browser.storage.sync.get({ let synced_settings = await browser.storage.sync.get({
settings_store: true, settings_store: true,
use_anonymous_tokens: true, use_anonymous_tokens: true,
}); });
if (synced_settings.settings_store == true || synced_settings.use_anonymous_tokens == true) { store_settings = synced_settings.settings_store;
await verifyPermissions().then(granted => { use_anonymous_tokens = synced_settings.use_anonymous_tokens;
if (granted) { inkognito_allowed = await browser.extension.isAllowedIncognitoAccess();
store_settings = synced_settings.settings_store;
use_anonymous_tokens = synced_settings.use_anonymous_tokens;
} else {
store_settings = false;
use_anonymous_tokens = false;
}
});
} else {
store_settings = false;
use_anonymous_tokens = false;
}
showSettingsState(); showSettingsState();
} }
...@@ -118,8 +126,13 @@ if (typeof browser == "undefined") { ...@@ -118,8 +126,13 @@ if (typeof browser == "undefined") {
* which is stored in local variables. * which is stored in local variables.
*/ */
function showSettingsState() { function showSettingsState() {
checkbox_store_settings.checked = store_settings; checkbox_store_settings.checked = store_settings && permissions_granted;
checkbox_anonymous_tokens.checked = use_anonymous_tokens; checkbox_anonymous_tokens.checked = use_anonymous_tokens && permissions_granted;
if (inkognito_allowed) {
inkognito_settings_container.style.display = "none";
} else {
inkognito_settings_container.style.display = null;
}
} }
/** /**
...@@ -135,21 +148,18 @@ if (typeof browser == "undefined") { ...@@ -135,21 +148,18 @@ if (typeof browser == "undefined") {
let new_settings = {}; let new_settings = {};
if (store_settings != null) new_settings["settings_store"] = store_settings; if (store_settings != null) new_settings["settings_store"] = store_settings;
if (use_anonymous_tokens != null) new_settings["use_anonymous_tokens"] = use_anonymous_tokens; if (use_anonymous_tokens != null) new_settings["use_anonymous_tokens"] = use_anonymous_tokens;
inkognito_allowed = await browser.extension.isAllowedIncognitoAccess();
if (store_settings == true || use_anonymous_tokens == true) { if (store_settings == true || use_anonymous_tokens == true) {
return verifyPermissions(true).then(permission_granted => { return verifyPermissions(true).then(granted => {
if (permission_granted) { permissions_granted = granted;
if (permissions_granted) {
return browser.storage.sync.set(new_settings); return browser.storage.sync.set(new_settings);
} else {
checkbox_store_settings.checked = false;
checkbox_anonymous_tokens.checked = false;
return;
} }
}) })
} else { } else {
return browser.storage.sync.set(new_settings); return browser.storage.sync.set(new_settings);
} }
} }
})(); })();
...@@ -2,10 +2,27 @@ let permissions_granted = null; ...@@ -2,10 +2,27 @@ let permissions_granted = null;
let key = null; let key = null;
let charge = 0; let charge = 0;
let anonymous_token = 0; let anonymous_token = 0;
let urls = [];
let origins = [];
let hosts = [];
let permissions = [
"storage",
"cookies",
"webRequest",
"declarativeNetRequestWithHostAccess"
];
if (typeof browser == "undefined") { if (typeof browser == "undefined") {
var browser = chrome; var browser = chrome;
} }
(() => { (() => {
browser.runtime.getManifest().host_permissions.forEach((value, index) => {
urls.push(value);
let url = new URL(value);
hosts.push(url.host);
origins.push(url.origin);
});
initialize(); initialize();
})(); })();
...@@ -20,7 +37,7 @@ browser.storage.onChanged.addListener(async (changes, areaName) => { ...@@ -20,7 +37,7 @@ browser.storage.onChanged.addListener(async (changes, areaName) => {
key = new_value; key = new_value;
await fetch_key_charge().then(key_charge => { await fetch_key_charge().then(key_charge => {
charge = key_charge; charge = key_charge;
}).catch(error => { }); // The request might fail when }).catch(error => { }); // The request might fail when permissions are missing
update = true; update = true;
} }
if (changes.hasOwnProperty("anonymous_tokens")) { if (changes.hasOwnProperty("anonymous_tokens")) {
...@@ -54,20 +71,12 @@ browser.permissions.onRemoved.addListener(async (permissions) => { ...@@ -54,20 +71,12 @@ browser.permissions.onRemoved.addListener(async (permissions) => {
* @returns {Promise<number>} * @returns {Promise<number>}
*/ */
async function fetch_key_charge() { async function fetch_key_charge() {
if (key == null) return 0; return browser.runtime.sendMessage({ type: "key", action: "getcharge" }).then(response => {
return fetch("https://metager.de/keys/api/json/key/" + encodeURIComponent(key), { if (response && response.status == "ok") {
headers: { return response.data.charge;
"Cache-Control": "no-cache",
}
}).then(async response => {
if (response.ok) {
return response.json();
} else { } else {
throw new Error("Couldn't fetch key status"); return 0;
} }
}).then(async response => {
charge = response.charge;
return charge;
}); });
} }
...@@ -81,10 +90,8 @@ async function fetch_key_charge() { ...@@ -81,10 +90,8 @@ async function fetch_key_charge() {
*/ */
async function initialize() { async function initialize() {
let permissionsToRequest = { let permissionsToRequest = {
origins: [ origins: urls,
"https://metager.org/*", permissions: permissions
"https://metager.de/*",
]
}; };
// Initialize state // Initialize state
return browser.permissions.contains(permissionsToRequest) return browser.permissions.contains(permissionsToRequest)
......
...@@ -2,7 +2,7 @@ const CopyPlugin = require("copy-webpack-plugin"); ...@@ -2,7 +2,7 @@ const CopyPlugin = require("copy-webpack-plugin");
const path = require("path"); const path = require("path");
const { ProvidePlugin, DefinePlugin } = require("webpack"); const { ProvidePlugin, DefinePlugin } = require("webpack");
module.exports = { module.exports = (env, argv) => ({
resolve: { resolve: {
fallback: { fallback: {
assert: false, assert: false,
...@@ -39,7 +39,7 @@ module.exports = { ...@@ -39,7 +39,7 @@ module.exports = {
from: __dirname + "/build/manifest.json", from: __dirname + "/build/manifest.json",
to: __dirname + "/manifest.json", to: __dirname + "/manifest.json",
transform(content, path) { transform(content, path) {
return buildManifest(content); return buildManifest(content, argv.mode);
} }
}] }]
}), }),
...@@ -47,13 +47,33 @@ module.exports = { ...@@ -47,13 +47,33 @@ module.exports = {
BROWSER: JSON.stringify(process.env.BROWSER) BROWSER: JSON.stringify(process.env.BROWSER)
}), }),
] ]
}; });
function buildManifest(content) { function buildManifest(content, mode = "production") {
let manifest = JSON.parse(content); let manifest = JSON.parse(content);
let browser_env = process.env.BROWSER; let browser_env = process.env.BROWSER;
if (browser_env) { if (browser_env) {
if (mode == "development") {
// Add access to localhost for development environments
manifest.content_scripts[0].matches.push("http://localhost:8080/*");
manifest.content_scripts[1].matches.push(
'http://localhost:8080/meta/settings',
'http://localhost:8080/*/meta/settings',
'http://localhost:8080/meta/settings?*',
'http://localhost:8080/*/meta/settings?*'
);
manifest.content_scripts[2].matches.push(
'http://localhost:8080/meta/meta.ger3?*',
'http://localhost:8080/*/meta/meta.ger3?*'
);
manifest.content_scripts[3].matches.push(
'http://localhost:8080/keys/*',
'http://localhost:8080/*/keys/*'
);
manifest.host_permissions.push("http://localhost/*", "http://localhost:8080/*");
}
if (browser_env == "CHROME") { if (browser_env == "CHROME") {
// Chrome does not support background_scripts // Chrome does not support background_scripts
// We need to convert to service_worker // We need to convert to service_worker
......