Project

General

Profile

Download (3.34 KB) Statistics
| Branch: | Tag: | Revision:

haketilo / background / page_actions_server.js @ 5c75d744

1
/**
2
 * Hachette serving of page actions to content scripts
3
 *
4
 * Copyright (C) 2021 Wojtek Kosior
5
 * Redistribution terms are gathered in the `copyright' file.
6
 */
7

    
8
/*
9
 * IMPORTS_START
10
 * IMPORT get_storage
11
 * IMPORT light_storage
12
 * IMPORT TYPE_PREFIX
13
 * IMPORT CONNECTION_TYPE
14
 * IMPORT browser
15
 * IMPORT listen_for_connection
16
 * IMPORT sha256
17
 * IMPORT query_best
18
 * IMPORT make_ajax_request
19
 * IMPORTS_END
20
 */
21

    
22
var storage;
23
var handler;
24
let policy_observable;
25

    
26
function send_actions(url, port)
27
{
28
    const [pattern, queried_settings] = query_best(storage, url);
29

    
30
    const settings = {allow: policy_observable && policy_observable.value};
31
    Object.assign(settings, queried_settings);
32
    if (settings.components)
33
	settings.allow = false;
34

    
35
    const repos = storage.get_all(TYPE_PREFIX.REPO);
36

    
37
    port.postMessage(["settings", [pattern, settings, repos]]);
38

    
39
    const components = settings.components;
40
    const processed_bags = new Set();
41

    
42
    if (components !== undefined)
43
	send_scripts([components], port, processed_bags);
44
}
45

    
46
// TODO: parallelize script fetching
47
async function send_scripts(components, port, processed_bags)
48
{
49
    for (let [prefix, name] of components) {
50
	if (prefix === TYPE_PREFIX.BAG) {
51
	    if (processed_bags.has(name)) {
52
		console.log(`preventing recursive inclusion of bag ${name}`);
53
		continue;
54
	    }
55

    
56
	    var bag = storage.get(TYPE_PREFIX.BAG, name);
57

    
58
	    if (bag === undefined) {
59
		console.log(`no bag in storage for key ${name}`);
60
		continue;
61
	    }
62

    
63
	    processed_bags.add(name);
64
	    await send_scripts(bag, port, processed_bags);
65

    
66
	    processed_bags.delete(name);
67
	} else {
68
	    let script_text = await get_script_text(name);
69
	    if (script_text === undefined)
70
		continue;
71

    
72
	    port.postMessage(["inject", [script_text]]);
73
	}
74
    }
75
}
76

    
77
async function get_script_text(script_name)
78
{
79
    try {
80
	let script_data = storage.get(TYPE_PREFIX.SCRIPT, script_name);
81
	if (script_data === undefined) {
82
	    console.log(`missing data for ${script_name}`);
83
	    return;
84
	}
85
	let script_text = script_data.text;
86
	if (!script_text)
87
	    script_text = await fetch_remote_script(script_data);
88
	return script_text;
89
    } catch (e) {
90
	console.log(e);
91
    }
92
}
93

    
94
async function fetch_remote_script(script_data)
95
{
96
    try {
97
	let xhttp = await make_ajax_request("GET", script_data.url);
98
	if (xhttp.status === 200) {
99
	    let computed_hash = sha256(xhttp.responseText);
100
	    if (computed_hash !== script_data.hash) {
101
		console.log(`Bad hash for ${script_data.url}\n    got ${computed_hash} instead of ${script_data.hash}`);
102
		return;
103
	    }
104
	    return xhttp.responseText;
105
	} else {
106
	    console.log("script not fetched: " + script_data.url);
107
	    return;
108
	}
109
    } catch (e) {
110
	console.log(e);
111
    }
112
}
113

    
114
function handle_message(port, message, handler)
115
{
116
    port.onMessage.removeListener(handler[0]);
117
    let url = message.url;
118
    console.log({url});
119
    send_actions(url, port);
120
}
121

    
122
function new_connection(port)
123
{
124
    console.log("new page actions connection!");
125
    let handler = [];
126
    handler.push(m => handle_message(port, m, handler));
127
    port.onMessage.addListener(handler[0]);
128
}
129

    
130
async function start_page_actions_server()
131
{
132
    storage = await get_storage();
133

    
134
    listen_for_connection(CONNECTION_TYPE.PAGE_ACTIONS, new_connection);
135

    
136
    policy_observable = await light_storage.observe_var("default_allow");
137
}
138

    
139
/*
140
 * EXPORTS_START
141
 * EXPORT start_page_actions_server
142
 * EXPORTS_END
143
 */
(3-3/7)