-
Notifications
You must be signed in to change notification settings - Fork 137
Expand file tree
/
Copy pathwebextension.ts
More file actions
95 lines (79 loc) · 3.38 KB
/
Copy pathwebextension.ts
File metadata and controls
95 lines (79 loc) · 3.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import * as path from 'path';
import * as os from 'os';
import { deleteFile, mkDir, writeFile, copyRecursive, deleteFolder } from "./util/fs";
import { addShutdownHandler } from './shutdown';
import { OVERRIDES_DIR } from './interceptors/terminal/terminal-env-overrides';
const WEBEXTENSION_BASE_PATH = path.join(OVERRIDES_DIR, 'webextension');
// We copy the WebExtension to a temp directory the first time it's activated, so that we can
// modify the config folder within to easily inject config into the extension. Without this,
// the extension is usually in the app install directory, which is often not user-writable.
// We only make one copy for all sessions, but we later inject independent per-session
// config files, so they can behave independently.
export let WEBEXTENSION_INSTALL: {
path: string;
configPath: string;
} | undefined;
async function ensureWebExtensionInstalled() {
if (WEBEXTENSION_INSTALL) return; // No-op after the first install
else {
const tmpDir = os.tmpdir();
const webExtensionPath = path.join(tmpDir, 'httptoolkit-webextension');
const configPath = path.join(webExtensionPath, 'config');
await copyRecursive(WEBEXTENSION_BASE_PATH, webExtensionPath);
await mkDir(configPath).catch((e: any) => {
if (e.code === 'EEXIST') return; // Already exists, no problem
else throw e;
});
WEBEXTENSION_INSTALL = { path: webExtensionPath, configPath };
console.log(`Webextension installed at ${WEBEXTENSION_INSTALL.path}`);
}
}
// On shutdown, we delete the webextension install again.
addShutdownHandler(async () => {
if (WEBEXTENSION_INSTALL) {
console.log(`Uninstalling webextension from ${WEBEXTENSION_INSTALL.path}`);
await deleteFolder(WEBEXTENSION_INSTALL.path);
WEBEXTENSION_INSTALL = undefined;
}
});
interface WebExtensionConfig { // Should match config in the WebExtension itself
mockRtc: {
peerId: string;
adminBaseUrl: string;
} | false;
}
const getConfigKey = (proxyPort: number) =>
`127_0_0_1.${proxyPort}`; // Filename-safe proxy address
const getConfigPath = (proxyPort: number) =>
path.join(WEBEXTENSION_INSTALL!.configPath, getConfigKey(proxyPort));
export function clearWebExtensionConfig(httpProxyPort: number) {
if (!WEBEXTENSION_INSTALL) return;
return deleteFile(getConfigPath(httpProxyPort))
.catch(() => {}); // We ignore errors - nothing we can do, not very important.
}
export async function updateWebExtensionConfig(
sessionId: string,
httpProxyPort: number,
webRTCEnabled: boolean,
mockttpPort: number
) {
if (webRTCEnabled) {
await ensureWebExtensionInstalled();
const adminBaseUrl = `http://internal.httptoolkit.localhost:${mockttpPort}/session/${sessionId}`;
await writeConfig(httpProxyPort, {
mockRtc: {
peerId: 'matching-peer',
adminBaseUrl
}
});
} else {
if (WEBEXTENSION_INSTALL) {
// If the extension is set up, but this specific session has it disabled, we
// make the config explicitly disable it, just to be clear:
await writeConfig(httpProxyPort, { mockRtc: false });
}
}
}
async function writeConfig(proxyPort: number, config: WebExtensionConfig) {
return writeFile(getConfigPath(proxyPort), JSON.stringify(config));
}