From 01937dc9d5215ef96ce756e3ccda51bf29032f58 Mon Sep 17 00:00:00 2001 From: Wojtek Kosior Date: Mon, 10 May 2021 18:07:05 +0200 Subject: initial commit --- background/page_actions_server.mjs | 145 +++++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 background/page_actions_server.mjs (limited to 'background/page_actions_server.mjs') diff --git a/background/page_actions_server.mjs b/background/page_actions_server.mjs new file mode 100644 index 0000000..5fb4924 --- /dev/null +++ b/background/page_actions_server.mjs @@ -0,0 +1,145 @@ +/** +* Myext serving of page actions to content scripts +* +* Copyright (C) 2021 Wojtek Kosior +* +* Dual-licensed under: +* - 0BSD license +* - GPLv3 or (at your option) any later version +*/ + +import get_storage from './storage.mjs'; +import {TYPE_PREFIX} from '/common/stored_types.mjs'; +import CONNECTION_TYPE from '/common/connection_types.mjs'; +import browser from '/common/browser.mjs'; +import listen_for_connection from './message_server.mjs'; +import url_item from './url_item.mjs'; +import sha256 from './sha256.mjs'; + +"use strict"; + +var storage; +var handler; + +function send_scripts(url, port) +{ + let settings = storage.get(TYPE_PREFIX.PAGE, url_item(url)); + if (settings === undefined) + return; + + let components = settings.components; + let processed_bundles = new Set(); + + send_scripts_rec(components, port, processed_bundles); +} + +// TODO: parallelize script fetching +async function send_scripts_rec(components, port, processed_bundles) +{ + for (let [prefix, name] of components) { + if (prefix === TYPE_PREFIX.BUNDLE) { + if (processed_bundles.has(name)) { + console.log(`preventing recursive inclusion of bundle ${name}`); + continue; + } + + var bundle = storage.get(TYPE_PREFIX.BUNDLE, name); + + if (bundle === undefined) { + console.log(`no bundle in storage for key ${name}`); + continue; + } + + processed_bundles.add(name); + await send_scripts_rec(bundle, port, processed_bundles); + processed_bundles.delete(name); + } else { + let script_text = await get_script_text(name); + if (script_text === undefined) + continue; + + port.postMessage({inject : [script_text]}); + } + } +} + +async function get_script_text(script_name) +{ + try { + let script_data = storage.get(TYPE_PREFIX.SCRIPT, script_name); + if (script_data === undefined) { + console.log(`missing data for ${script_name}`); + return; + } + let script_text = script_data.text; + if (!script_text) + script_text = await fetch_remote_script(script_data); + return script_text; + } catch (e) { + console.log(e); + } +} + +function ajax_callback() +{ + if (this.readyState == 4) + this.resolve_callback(this); +} + +function initiate_ajax_request(resolve, method, url) +{ + var xhttp = new XMLHttpRequest(); + xhttp.resolve_callback = resolve; + xhttp.onreadystatechange = ajax_callback; + xhttp.open(method, url, true); + xhttp.send(); +} + +function make_ajax_request(method, url) +{ + return new Promise((resolve, reject) => + initiate_ajax_request(resolve, method, url)); +} + +async function fetch_remote_script(script_data) +{ + try { + let xhttp = await make_ajax_request("GET", script_data.url); + if (xhttp.status === 200) { + let computed_hash = sha256(xhttp.responseText); + if (computed_hash !== script_data.hash) { + console.log(`Bad hash for ${script_data.url}\n got ${computed_hash} instead of ${script_data.hash}`); + return; + } + return xhttp.responseText; + } else { + console.log("script not fetched: " + script_data.url); + return; + } + } catch (e) { + console.log(e); + } +} + +function handle_message(port, message, handler) +{ + port.onMessage.removeListener(handler[0]); + let url = message.url; + console.log({url}); + send_scripts(url, port); +} + +function new_connection(port) +{ + console.log("new page actions connection!"); + let handler = []; + handler.push(m => handle_message(port, m, handler)); + port.onMessage.addListener(handler[0]); +} + +export default async function start() +{ + storage = await get_storage(); + + listen_for_connection(CONNECTION_TYPE.PAGE_ACTIONS, new_connection); +} -- cgit v1.2.3