Project

General

Profile

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

haketilo / background / page_actions_server.js @ 2bd35bc4

1
/**
2
 * This file is part of Haketilo.
3
 *
4
 * Function: Serving page actions to content scripts.
5
 *
6
 * Copyright (C) 2021 Wojtek Kosior
7
 * Redistribution terms are gathered in the `copyright' file.
8
 */
9

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

    
24
var storage;
25
var handler;
26
let policy_observable;
27

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

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

    
37
    const repos = storage.get_all(TYPE_PREFIX.REPO);
38

    
39
    port.postMessage(["settings", [pattern, settings, repos]]);
40

    
41
    const components = settings.components;
42
    const processed_bags = new Set();
43

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

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

    
58
	    var bag = storage.get(TYPE_PREFIX.BAG, name);
59

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

    
65
	    processed_bags.add(name);
66
	    await send_scripts(bag, port, processed_bags);
67

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

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

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

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

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

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

    
132
async function start_page_actions_server()
133
{
134
    storage = await get_storage();
135

    
136
    listen_for_connection(CONNECTION_TYPE.PAGE_ACTIONS, new_connection);
137

    
138
    policy_observable = await light_storage.observe_var("default_allow");
139
}
140

    
141
/*
142
 * EXPORTS_START
143
 * EXPORT start_page_actions_server
144
 * EXPORTS_END
145
 */
(3-3/7)