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 (4)
# v1.2 # v1.2
* Add hint to show if settings are applied in inkognito mode * Add hint to show if settings are applied in inkognito mode
* Allow fraction Token payments
* Update Anonymous Token payment to be synchronious
* Fix: Interface on permission updates * Fix: Interface on permission updates
* Fix: NetRequestRules not getting applied to Chrome startpages * Fix: NetRequestRules not getting applied to Chrome startpages
......
...@@ -35,8 +35,8 @@ ...@@ -35,8 +35,8 @@
} }
}, },
"release_notes": { "release_notes": {
"de": "", "de": "* Hinweis hinzufügen, der anzeigt, ob die Einstellungen im Inkognito-Modus angewendet werden\n* Zahlungen mit Fraktions-Token zulassen\n* Anonyme Token-Zahlungen synchronisieren\n* Fix: Schnittstelle bei Berechtigungs-Updates\n* Fix: NetRequestRules werden nicht auf Chrome-Startseiten angewendet",
"en-US": "" "en-US": "* Add hint to show if settings are applied in inkognito mode\n* Allow fraction Token payments\n* Update Anonymous Token payment to be synchronious\n* Fix: Interface on permission updates\n* Fix: NetRequestRules not getting applied to Chrome startpages"
} }
}, },
"is_disabled": false, "is_disabled": false,
......
...@@ -29,7 +29,7 @@ export class SettingsManager { ...@@ -29,7 +29,7 @@ export class SettingsManager {
browser.runtime.getManifest().host_permissions.forEach((value, index) => { browser.runtime.getManifest().host_permissions.forEach((value, index) => {
this.urls.push(value); this.urls.push(value);
let url = new URL(value); let url = new URL(value);
this.hosts.push(url.host); this.hosts.push(url.hostname);
this.origins.push(url.origin); this.origins.push(url.origin);
}); });
} }
...@@ -68,6 +68,9 @@ export class SettingsManager { ...@@ -68,6 +68,9 @@ export class SettingsManager {
async set(settings) { async set(settings) {
await this.init(); await this.init();
this.settings = { ...this.settings, ...settings }; this.settings = { ...this.settings, ...settings };
this._ignored_settings.forEach(ignored_setting => {
delete this.settings[ignored_setting];
});
return this.sync().then(() => this.updateSettingRule()); return this.sync().then(() => this.updateSettingRule());
} }
...@@ -221,7 +224,7 @@ export class SettingsManager { ...@@ -221,7 +224,7 @@ export class SettingsManager {
rules.push({ rules.push({
id: 6, id: 6,
condition: { condition: {
requestDomains: this.hosts, initiatorDomains: this.hosts,
resourceTypes: ["main_frame", "sub_frame", "xmlhttprequest"] resourceTypes: ["main_frame", "sub_frame", "xmlhttprequest"]
}, },
action: { action: {
...@@ -237,7 +240,7 @@ export class SettingsManager { ...@@ -237,7 +240,7 @@ export class SettingsManager {
rules.push({ rules.push({
id: 1, id: 1,
condition: { condition: {
requestDomains: this.hosts, initiatorDomains: this.hosts,
resourceTypes: ["main_frame", "sub_frame", "xmlhttprequest"] resourceTypes: ["main_frame", "sub_frame", "xmlhttprequest"]
}, },
action: { action: {
......
...@@ -66,7 +66,7 @@ export class TokenManager { ...@@ -66,7 +66,7 @@ export class TokenManager {
browser.runtime.getManifest().host_permissions.forEach((value, index) => { browser.runtime.getManifest().host_permissions.forEach((value, index) => {
this._urls.push(value); this._urls.push(value);
let url = new URL(value); let url = new URL(value);
this._hosts.push(url.host); this._hosts.push(url.hostname);
this._origins.push(url.origin); this._origins.push(url.origin);
}); });
if (process.env.NODE_ENV == "development") { if (process.env.NODE_ENV == "development") {
...@@ -206,7 +206,7 @@ export class TokenManager { ...@@ -206,7 +206,7 @@ export class TokenManager {
console.error(error); console.error(error);
} }
} }
await this._store_tokens(); await this.store_tokens();
} else if (parsed_cookie.key == "key") { } else if (parsed_cookie.key == "key") {
if (parsed_cookie.expired) { if (parsed_cookie.expired) {
await this.store_key(null); await this.store_key(null);
...@@ -240,6 +240,96 @@ export class TokenManager { ...@@ -240,6 +240,96 @@ export class TokenManager {
return this._fetch_key_charge(); return this._fetch_key_charge();
} }
async getTokens(cost) {
await this.init();
return this.refill(cost)
.then(() => {
let tokens = {
tokens: [],
decitokens: []
};
if (this._anonymous_tokens_count() < cost) {
throw new Error("I was not able to attach the required token amount to the request");
}
// Use up available decitoken if they are not in use anymore => Attach 10 decitoken instead of one token
if (Number.isInteger(cost) && cost >= 1 && this._deci_tokens.target_amount == 0 && this._deci_tokens.tokens.length >= 10) {
for (let i = 0; i < 10; i++) {
let token = this._deci_tokens.tokens.shift();
if (token == undefined) {
break;
}
tokens.decitokens.push(token);
cost = parseFloat((cost - 0.1).toFixed(1));
}
}
// Attach as many token as necessary
while (cost >= 1) {
let token = this._tokens.tokens.shift();
if (token == undefined) {
break;
}
tokens.tokens.push(token);
cost -= 1;
}
// Attach as many decitoken as necessary
while (cost > 0) {
let token = this._deci_tokens.tokens.shift();
if (token == undefined) {
break;
}
tokens.decitokens.push(token);
cost = parseFloat((cost - 0.1).toFixed(1));
}
// If we need more tokens attach more regular tokens
while (cost > 0) {
let token = this._tokens.tokens.shift();
if (token == undefined) {
break;
}
tokens.tokens.push(token);
cost -= 1;
}
if (cost > 0) {
tokens.tokens.forEach(token => {
this._tokens.tokens.unshift(token);
});
tokens.tokens = [];
tokens.decitokens.forEach(token => {
this._deci_tokens.tokens.unshift(token);
});
tokens.decitokens = [];
throw new Error("I was not able to attach the required token amount to the request");
}
return tokens;
});
}
async putTokens(payment_request) {
payment_request.tokens.tokens.forEach(token => {
let duplicate = false;
this._tokens.tokens.forEach(existing_token => {
if (token.token == existing_token.token) {
duplicate = true;
}
});
if (!duplicate) {
this._tokens.tokens.unshift(token);
}
});
payment_request.tokens.decitokens.forEach(token => {
let duplicate = false;
this._deci_tokens.tokens.forEach(existing_token => {
if (token.token == existing_token.token) {
duplicate = true;
}
});
if (!duplicate) {
this._deci_tokens.tokens.unshift(token);
}
});
}
async _load_key_from_browser() { async _load_key_from_browser() {
if (!this._permissions_granted) return; if (!this._permissions_granted) return;
// Consume a possible key cookie // Consume a possible key cookie
...@@ -290,7 +380,7 @@ export class TokenManager { ...@@ -290,7 +380,7 @@ export class TokenManager {
rules.push({ rules.push({
id: 2, id: 2,
condition: { condition: {
requestDomains: this._hosts, initiatorDomains: this._hosts,
urlFilter: "/keys/*", urlFilter: "/keys/*",
resourceTypes: ["main_frame", "sub_frame", "xmlhttprequest"] resourceTypes: ["main_frame", "sub_frame", "xmlhttprequest"]
}, },
...@@ -306,7 +396,7 @@ export class TokenManager { ...@@ -306,7 +396,7 @@ export class TokenManager {
rules.push({ rules.push({
id: 3, id: 3,
condition: { condition: {
requestDomains: this._hosts, initiatorDomains: this._hosts,
urlFilter: "/meta/settings*", urlFilter: "/meta/settings*",
resourceTypes: ["main_frame", "sub_frame", "xmlhttprequest"] resourceTypes: ["main_frame", "sub_frame", "xmlhttprequest"]
}, },
...@@ -324,7 +414,7 @@ export class TokenManager { ...@@ -324,7 +414,7 @@ export class TokenManager {
rules.push({ rules.push({
id: 4, id: 4,
condition: { condition: {
requestDomains: this._hosts, initiatorDomains: this._hosts,
resourceTypes: ["main_frame", "sub_frame", "xmlhttprequest"] resourceTypes: ["main_frame", "sub_frame", "xmlhttprequest"]
}, },
action: { action: {
...@@ -345,7 +435,7 @@ export class TokenManager { ...@@ -345,7 +435,7 @@ export class TokenManager {
rules.push({ rules.push({
id: 5, id: 5,
condition: { condition: {
requestDomains: this._hosts, initiatorDomains: this._hosts,
urlFilter: "/meta/meta.ger3?*", urlFilter: "/meta/meta.ger3?*",
resourceTypes: ["main_frame", "sub_frame", "xmlhttprequest"] resourceTypes: ["main_frame", "sub_frame", "xmlhttprequest"]
}, },
...@@ -362,7 +452,7 @@ export class TokenManager { ...@@ -362,7 +452,7 @@ export class TokenManager {
rules.push({ rules.push({
id: 2, id: 2,
condition: { condition: {
requestDomains: this._hosts, initiatorDomains: this._hosts,
resourceTypes: ["main_frame", "sub_frame", "xmlhttprequest"] resourceTypes: ["main_frame", "sub_frame", "xmlhttprequest"]
}, },
action: { action: {
...@@ -425,48 +515,10 @@ export class TokenManager { ...@@ -425,48 +515,10 @@ export class TokenManager {
// Attach enough anonymous token to the request to pay for // Attach enough anonymous token to the request to pay for
let cost = payment_request.missing; let cost = payment_request.missing;
// Use up available decitoken if they are not in use anymore => Attach 10 decitoken instead of one token return this.getTokens(cost).then(tokens => {
if (Number.isInteger(cost) && cost >= 1 && this._deci_tokens.target_amount == 0 && this._deci_tokens.tokens.length >= 10) { payment_request.tokens.tokens = tokens.tokens;
for (let i = 0; i < 10; i++) { payment_request.tokens.decitokens = tokens.decitokens;
let token = this._deci_tokens.tokens.shift(); });
if (token == undefined) {
break;
}
payment_request.tokens.decitokens.push(token);
cost = parseFloat((cost - 0.1).toFixed(1));
}
}
// Attach as many token as necessary
while (cost >= 1) {
let token = this._tokens.tokens.shift();
if (token == undefined) {
break;
}
payment_request.tokens.tokens.push(token);
cost -= 1;
}
// Attach as many decitoken as necessary
while (cost > 0) {
let token = this._deci_tokens.tokens.shift();
if (token == undefined) {
break;
}
payment_request.tokens.decitokens.push(token);
cost = parseFloat((cost - 0.1).toFixed(1));
}
// If we need more tokens attach more regular tokens
while (cost > 0) {
let token = this._tokens.tokens.shift();
if (token == undefined) {
break;
}
payment_request.tokens.tokens.push(token);
cost -= 1;
}
if (cost > 0) {
throw new Error("I was not able to attach the required token amount to the request");
}
} else { } else {
// Use key instead of token auth or an invalid key to make the request go forward // Use key instead of token auth or an invalid key to make the request go forward
if (this._key != null) { if (this._key != null) {
...@@ -536,7 +588,7 @@ export class TokenManager { ...@@ -536,7 +588,7 @@ export class TokenManager {
}); });
} }
}).finally(() => { }).finally(() => {
return this._store_tokens() return this.store_tokens()
.then(() => this._updateNetRequestRules()) .then(() => this._updateNetRequestRules())
.then(() => { .then(() => {
let timeout = Math.floor(Math.random() * (25 - 0 + 1) + 0); // Random number between 0 and 25 let timeout = Math.floor(Math.random() * (25 - 0 + 1) + 0); // Random number between 0 and 25
...@@ -610,7 +662,7 @@ export class TokenManager { ...@@ -610,7 +662,7 @@ export class TokenManager {
/** /**
* Persists the saved tokens * Persists the saved tokens
*/ */
async _store_tokens(key_charge = null) { async store_tokens(key_charge = null) {
let new_storage = {}; let new_storage = {};
if (key_charge != null) { if (key_charge != null) {
new_storage[this._storage_keys.key_charge] = key_charge; new_storage[this._storage_keys.key_charge] = key_charge;
...@@ -817,7 +869,7 @@ export class TokenManager { ...@@ -817,7 +869,7 @@ export class TokenManager {
return; return;
}) })
.catch(error => console.error(error)) // Log any uncaught errors .catch(error => console.error(error)) // Log any uncaught errors
.finally(() => this._store_tokens(key_charge).then(() => this._refill_promise = null)); // Always update .finally(() => this.store_tokens(key_charge).then(() => this._refill_promise = null)); // Always update
return this._refill_promise; return this._refill_promise;
} }
......
...@@ -58,6 +58,10 @@ browser.runtime.onStartup.addListener(async () => { ...@@ -58,6 +58,10 @@ browser.runtime.onStartup.addListener(async () => {
browser.runtime.onMessage.addListener((request, sender, sendResponse) => { browser.runtime.onMessage.addListener((request, sender, sendResponse) => {
if (!request.hasOwnProperty("type")) return; if (!request.hasOwnProperty("type")) return;
if (request.type == "settings_set" && request.hasOwnProperty("settings")) { if (request.type == "settings_set" && request.hasOwnProperty("settings")) {
if (request.settings.hasOwnProperty("key")) {
tokenManager.store_key(request.settings.key);
delete request.settings.key;
}
settingsManager.set(request.settings).then(() => { settingsManager.set(request.settings).then(() => {
sendResponse({ status: "ok" }); sendResponse({ status: "ok" });
}).catch(error => { }).catch(error => {
...@@ -96,13 +100,44 @@ browser.runtime.onMessage.addListener((request, sender, sendResponse) => { ...@@ -96,13 +100,44 @@ browser.runtime.onMessage.addListener((request, sender, sendResponse) => {
} }
} }
if (request.type == "tokenauthorization") { if (request.type == "tokenauthorization") {
tokenManager.pay_payment_request(request.payment_request).then(() => { if (request.hasOwnProperty("action")) {
sendResponse({ status: "ok" }); if (request.action == "pay") {
}).catch(error => { tokenManager.pay_payment_request(request.payment_request).then(() => {
console.error(error); sendResponse({ status: "ok" });
sendResponse({ status: "error", msg: error }); }).catch(error => {
}); console.error(error);
return true; sendResponse({ status: "error", msg: error });
});
return true;
} else if (request.action == "gettoken") {
tokenManager.getTokens(request.payment_request.missing).then(tokens => {
tokens.tokens.forEach(token => {
request.payment_request.tokens.tokens.push(token);
});
tokens.decitokens.forEach(token => {
request.payment_request.tokens.decitokens.push(token);
});
sendResponse(request.payment_request);
}).then(() => tokenManager.store_tokens())
.catch(error => {
console.error(error);
sendResponse(request.payment_request);
})
return true;
} else if (request.action == "puttoken") {
tokenManager.putTokens(request.payment_request)
.then(() => tokenManager.store_tokens()).then(() => {
request.payment_request.tokens.tokens = [];
request.payment_request.tokens.decitokens = [];
sendResponse(request.payment_request);
})
.catch(error => {
console.error(error);
sendResponse(request.payment_request);
})
return true;
}
}
} }
}); });
......
if (typeof browser == "undefined") {
var browser = chrome;
}
window.addEventListener("message", (event) => {
if (
event.source === window &&
event?.data?.sender === "webpage"
) {
let response_message = {
sender: "tokenmanager",
message_id: event.data.message_id,
payload: null,
error: null
};
browser.runtime.sendMessage(event.data.payload).then(response => {
response_message.payload = response;
window.postMessage(response_message);
}).catch(error => {
response_message.error = error;
window.postMessage(response_message);
});
}
});
\ No newline at end of file
...@@ -19,7 +19,7 @@ let form = document.getElementById("form"); ...@@ -19,7 +19,7 @@ let form = document.getElementById("form");
if (payment_input && form && error_url_input) { if (payment_input && form && error_url_input) {
let payment_request = JSON.parse(atob(payment_input.value)); let payment_request = JSON.parse(atob(payment_input.value));
browser.runtime.sendMessage({ type: "tokenauthorization", payment_request: payment_request }).then(answer => { browser.runtime.sendMessage({ type: "tokenauthorization", action: "pay", payment_request: payment_request }).then(answer => {
if (answer.status == "ok") { if (answer.status == "ok") {
let payment_id_input = document.createElement("input"); let payment_id_input = document.createElement("input");
payment_id_input.type = "hidden"; payment_id_input.type = "hidden";
......
...@@ -53,6 +53,15 @@ ...@@ -53,6 +53,15 @@
"js/removeUnusedContent.js" "js/removeUnusedContent.js"
] ]
}, },
{
"matches": [
"https://metager.org/*",
"https://metager.de/*"
],
"js": [
"js/messaging.js"
]
},
{ {
"matches": [ "matches": [
"https://metager.de/meta/settings", "https://metager.de/meta/settings",
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
"scripts": { "scripts": {
"dev-ff": "npm i --clean && BROWSER=FF webpack --mode=development", "dev-ff": "npm i --clean && BROWSER=FF webpack --mode=development",
"dev-ff-run": "./node_modules/web-ext/bin/web-ext.js run", "dev-ff-run": "./node_modules/web-ext/bin/web-ext.js run",
"prod-ff-watch": "npm i --clean && BROWSER=FF webpack --mode=production",
"prod-ff": "npm i --clean && BROWSER=FF webpack --mode=production --no-devtool --no-watch && node_modules/web-ext/bin/web-ext.js build -a dist/firefox --overwrite-dest --ignore-files=build dist node_modules .gitignore .gitlab-ci.yml .git *.md package* webpack.config.js", "prod-ff": "npm i --clean && BROWSER=FF webpack --mode=production --no-devtool --no-watch && node_modules/web-ext/bin/web-ext.js build -a dist/firefox --overwrite-dest --ignore-files=build dist node_modules .gitignore .gitlab-ci.yml .git *.md package* webpack.config.js",
"prod-ff-release": "export SOURCE_CODE_ARCHIVE=/tmp/metager-webextension.tar.gz && rm -f $SOURCE_CODE_ARCHIVE && npm i --clean && BROWSER=FF webpack --mode=production --no-devtool --no-watch && tar --exclude='.git' --exclude='./dist' --exclude='./js' --exclude='./node_modules' --exclude='./manifest.json' -czf $SOURCE_CODE_ARCHIVE ./ && node_modules/web-ext/bin/web-ext.js sign -a dist/firefox --channel listed --upload-source-code $SOURCE_CODE_ARCHIVE --amo-metadata ./build/firefox/metadata.json --api-key $AMO_API_KEY --api-secret $AMO_API_SECRET --ignore-files=build dist node_modules .gitignore .gitlab-ci.yml .git *.md package* webpack.config.js", "prod-ff-release": "export SOURCE_CODE_ARCHIVE=/tmp/metager-webextension.tar.gz && rm -f $SOURCE_CODE_ARCHIVE && npm i --clean && BROWSER=FF webpack --mode=production --no-devtool --no-watch && tar --exclude='.git' --exclude='./dist' --exclude='./js' --exclude='./node_modules' --exclude='./manifest.json' -czf $SOURCE_CODE_ARCHIVE ./ && node_modules/web-ext/bin/web-ext.js sign -a dist/firefox --channel listed --upload-source-code $SOURCE_CODE_ARCHIVE --amo-metadata ./build/firefox/metadata.json --api-key $AMO_API_KEY --api-secret $AMO_API_SECRET --ignore-files=build dist node_modules .gitignore .gitlab-ci.yml .git *.md package* webpack.config.js",
"dev-chrome": "npm i --clean && BROWSER=CHROME webpack --mode=development", "dev-chrome": "npm i --clean && BROWSER=CHROME webpack --mode=development",
......
...@@ -42,7 +42,6 @@ browser.storage.onChanged.addListener(async (changes, areaName) => { ...@@ -42,7 +42,6 @@ browser.storage.onChanged.addListener(async (changes, areaName) => {
update = true; update = true;
} }
if (changes.hasOwnProperty("anonymous_decitokens")) { if (changes.hasOwnProperty("anonymous_decitokens")) {
debugger;
let new_value = changes.anonymous_decitokens.newValue; let new_value = changes.anonymous_decitokens.newValue;
anonymous_decitoken = new_value.tokens.length; anonymous_decitoken = new_value.tokens.length;
update = true; update = true;
......
...@@ -15,9 +15,10 @@ module.exports = (env, argv) => ({ ...@@ -15,9 +15,10 @@ module.exports = (env, argv) => ({
}, },
entry: { entry: {
app: "./build/js/app.js", app: "./build/js/app.js",
removeUnusedContent: "./build/js/removeUnusedContent.js", removeUnusedContent: "./build/js/contentScripts/removeUnusedContent.js",
settingsPage: "./build/js/contentScripts/settings.js", settingsPage: "./build/js/contentScripts/settings.js",
tokenauthorization: "./build/js/contentScripts/tokenauthorization.js", tokenauthorization: "./build/js/contentScripts/tokenauthorization.js",
messaging: "./build/js/contentScripts/messaging.js",
keys: "./build/js/contentScripts/keys.js" keys: "./build/js/contentScripts/keys.js"
}, },
output: { output: {
...@@ -56,22 +57,23 @@ function buildManifest(content, mode = "production") { ...@@ -56,22 +57,23 @@ function buildManifest(content, mode = "production") {
if (browser_env) { if (browser_env) {
if (mode == "development") { if (mode == "development") {
// Add access to localhost for development environments // Add access to localhost for development environments
manifest.content_scripts[0].matches.push("http://localhost:8080/*"); manifest.content_scripts[0].matches.push("http://localhost/*");
manifest.content_scripts[1].matches.push( manifest.content_scripts[1].matches.push("http://localhost/*");
'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( manifest.content_scripts[2].matches.push(
'http://localhost:8080/meta/meta.ger3?*', 'http://localhost/meta/settings',
'http://localhost:8080/*/meta/meta.ger3?*' 'http://localhost/*/meta/settings',
'http://localhost/meta/settings?*',
'http://localhost/*/meta/settings?*'
); );
manifest.content_scripts[3].matches.push( manifest.content_scripts[3].matches.push(
'http://localhost:8080/keys/*', 'http://localhost/meta/meta.ger3?*',
'http://localhost:8080/*/keys/*' 'http://localhost/*/meta/meta.ger3?*'
);
manifest.content_scripts[4].matches.push(
'http://localhost/keys/*',
'http://localhost/*/keys/*'
); );
manifest.host_permissions.push("http://localhost/*", "http://localhost:8080/*"); manifest.host_permissions.push("http://localhost/*", "http://localhost/*");
} }
if (browser_env == "CHROME") { if (browser_env == "CHROME") {
......