Switch to httptoolkit
Summary: switch to httptoolkit Reviewers: kuba-orlik Reviewed By: kuba-orlik Differential Revision: https://hub.sealcode.org/D1578
This commit is contained in:
parent
ff7e32a3d5
commit
18541a6647
5
.gitignore
vendored
5
.gitignore
vendored
@ -6,4 +6,7 @@ images
|
||||
*.png
|
||||
bundleTrafficLog.js
|
||||
/http_server/code/dist/
|
||||
log
|
||||
log
|
||||
dist
|
||||
/httptoolkit_server/proxy_thing/dist/
|
||||
shared_buffer
|
||||
|
@ -1,5 +1,30 @@
|
||||
FROM pre_android/ready
|
||||
|
||||
EXPOSE 3000
|
||||
# Set up node
|
||||
RUN npm install -g n && n install 22.14.0 && n use 22.14.0 && hash -r
|
||||
|
||||
CMD bash /conf/docker-entrypoint.sh
|
||||
# Set up httptoolkit-server
|
||||
RUN git clone https://github.com/httptoolkit/httptoolkit-server /httptoolkit-server
|
||||
|
||||
WORKDIR /httptoolkit-server
|
||||
RUN git checkout 5c60a70b08d30126639484314f5b5619a388b026 \
|
||||
&& npm i && npm run build:src
|
||||
|
||||
# Set up proxy_cache_thing
|
||||
ADD proxy_cache_thing /proxy_cache_thing
|
||||
WORKDIR /proxy_cache_thing
|
||||
RUN npm i && npm run build
|
||||
|
||||
ADD entrypoint.sh /entrypoint.sh
|
||||
|
||||
ARG PROXY_PORT
|
||||
ARG SERVER_PORT
|
||||
ARG MONITORING_API_PORT
|
||||
ARG LOOPBACK_PORT
|
||||
|
||||
ENV PROXY_PORT=${PROXY_PORT}
|
||||
ENV SERVER_PORT=${SERVER_PORT}
|
||||
ENV MONITORING_API_PORT=${MONITORING_API_PORT}
|
||||
ENV LOOPBACK_PORT=${LOOPBACK_PORT}
|
||||
|
||||
ENTRYPOINT /entrypoint.sh
|
||||
|
@ -31,6 +31,8 @@ wss.on("connection", (ws) => {
|
||||
await spawnPromise("bash", ["/conf/back.sh"]);
|
||||
} else if (data === "home") {
|
||||
await spawnPromise("bash", ["/conf/home.sh"]);
|
||||
} else if (data === "install") {
|
||||
await spawnPromise("bash", ["/conf/install.sh"]);
|
||||
} else if (data.includes("drag")) {
|
||||
const dataSplit = data.split(" ");
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
bash /conf/start_culebra.sh
|
||||
npm i -C /code
|
||||
bash /conf/iptables_conf.sh
|
||||
redsocks -c /conf/redsocks.conf &
|
||||
bash /conf/wait_for_sd.sh
|
||||
node /code/index.mjs
|
||||
|
||||
|
4
android/conf/install.sh
Normal file
4
android/conf/install.sh
Normal file
@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
# -r to replace an existing application if any
|
||||
/opt/android-sdk-linux/platform-tools/adb install -r /shared_buffer/app.apk
|
@ -1,42 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
#reserved ip addresses taken from https://en.wikipedia.org/wiki/Reserved_IP_addresses#Reserved_IPv4_addresses
|
||||
|
||||
iptables -t nat -N REDSOCKS
|
||||
|
||||
iptables -t nat -A REDSOCKS -d 0.0.0.0/8 -j RETURN
|
||||
iptables -t nat -A REDSOCKS -d 0.0.0.0/32 -j RETURN
|
||||
iptables -t nat -A REDSOCKS -d 10.0.0.0/8 -j RETURN
|
||||
iptables -t nat -A REDSOCKS -d 100.64.0.0/10 -j RETURN
|
||||
iptables -t nat -A REDSOCKS -d 127.0.0.0/8 -j RETURN
|
||||
iptables -t nat -A REDSOCKS -d 169.254.0.0/16 -j RETURN
|
||||
iptables -t nat -A REDSOCKS -d 172.16.0.0/12 -j RETURN
|
||||
iptables -t nat -A REDSOCKS -d 192.0.0.0/24 -j RETURN
|
||||
iptables -t nat -A REDSOCKS -d 192.0.2.0/24 -j RETURN
|
||||
iptables -t nat -A REDSOCKS -d 192.168.0.0/16 -j RETURN
|
||||
iptables -t nat -A REDSOCKS -d 198.18.0.0/15 -j RETURN
|
||||
iptables -t nat -A REDSOCKS -d 198.51.100.0/24 -j RETURN
|
||||
iptables -t nat -A REDSOCKS -d 203.0.113.0/24 -j RETURN
|
||||
iptables -t nat -A REDSOCKS -d 224.0.0.0/4 -j RETURN
|
||||
iptables -t nat -A REDSOCKS -d 233.252.0.0/24 -j RETURN
|
||||
iptables -t nat -A REDSOCKS -d 240.0.0.0/4 -j RETURN
|
||||
iptables -t nat -A REDSOCKS -d 255.255.255.255/32 -j RETURN
|
||||
iptables -t nat -A REDSOCKS -p tcp -j REDIRECT --to-ports 12345
|
||||
|
||||
iptables -t nat -A OUTPUT -p tcp -j REDSOCKS
|
||||
|
||||
# iptables -t nat -N UDPSOCKS
|
||||
|
||||
# iptables -t nat -A UDPSOCKS -d 0.0.0.0/8 -j RETURN
|
||||
# iptables -t nat -A UDPSOCKS -d 10.0.0.0/8 -j RETURN
|
||||
# iptables -t nat -A UDPSOCKS -d 100.64.0.0/10 -j RETURN
|
||||
# iptables -t nat -A UDPSOCKS -d 127.0.0.0/8 -j RETURN
|
||||
# iptables -t nat -A UDPSOCKS -d 169.254.0.0/16 -j RETURN
|
||||
# iptables -t nat -A UDPSOCKS -d 172.16.0.0/12 -j RETURN
|
||||
# iptables -t nat -A UDPSOCKS -d 192.168.0.0/16 -j RETURN
|
||||
# iptables -t nat -A UDPSOCKS -d 198.18.0.0/15 -j RETURN
|
||||
# iptables -t nat -A UDPSOCKS -d 224.0.0.0/4 -j RETURN
|
||||
# iptables -t nat -A UDPSOCKS -d 240.0.0.0/4 -j RETURN
|
||||
# iptables -t nat -A UDPSOCKS -p udp -j REDIRECT --to-ports 12346
|
||||
|
||||
# iptables -t nat -A OUTPUT -p udp -j UDPSOCKS
|
@ -1,22 +0,0 @@
|
||||
base {
|
||||
log_debug = off;
|
||||
|
||||
log_info = on;
|
||||
|
||||
log = "syslog:daemon";
|
||||
|
||||
daemon = off;
|
||||
|
||||
redirector = iptables;
|
||||
}
|
||||
|
||||
redsocks {
|
||||
local_ip = 0.0.0.0;
|
||||
local_port = 12345;
|
||||
|
||||
ip = proxy;
|
||||
port = 1080;
|
||||
|
||||
type = socks5;
|
||||
}
|
||||
|
31
android/entrypoint.sh
Executable file
31
android/entrypoint.sh
Executable file
@ -0,0 +1,31 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
node /proxy_cache_thing/dist/index.js &
|
||||
CACHE_PID=$!
|
||||
|
||||
/httptoolkit-server/bin/run start -c /certificates &
|
||||
HTTPTOOLKIT_SERVER_PID=$!
|
||||
|
||||
bash /conf/docker-entrypoint.sh &
|
||||
ANDROID_PID=$!
|
||||
|
||||
function check_dead() {
|
||||
if ! ps -p $CACHE_PID > /dev/null; then
|
||||
echo "[ERROR] The proxy cache died, exiting...";
|
||||
exit 1;
|
||||
fi
|
||||
if ! ps -p $HTTPTOOLKIT_SERVER_PID > /dev/null; then
|
||||
echo "[ERROR] The httptoolkit_server died, exiting...";
|
||||
exit 1;
|
||||
fi
|
||||
if ! ps -p $ANDROID_PID > /dev/null; then
|
||||
echo "[ERROR] The android emulator died, exiting...";
|
||||
exit 1;
|
||||
fi
|
||||
}
|
||||
|
||||
# Exit on error
|
||||
while true; do
|
||||
check_dead;
|
||||
sleep 1;
|
||||
done
|
2665
android/proxy_cache_thing/package-lock.json
generated
Normal file
2665
android/proxy_cache_thing/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
35
android/proxy_cache_thing/package.json
Normal file
35
android/proxy_cache_thing/package.json
Normal file
@ -0,0 +1,35 @@
|
||||
{
|
||||
"name": "proxy_thing",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"license": "ISC",
|
||||
"author": "",
|
||||
"type": "commonjs",
|
||||
"main": "./lib/index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"build": "tsc",
|
||||
"start": "tsc && node dist/index.js",
|
||||
"lint": "tslint -c tslint.json src/**/*.ts",
|
||||
"prepublish": "npm run build"
|
||||
},
|
||||
"dependencies": {
|
||||
"express": "^4.21.2",
|
||||
"mockttp": "^3.16.0",
|
||||
"ts-node": "^10.9.2",
|
||||
"tslint": "^5.20.1",
|
||||
"ws": "^8.18.1"
|
||||
},
|
||||
"files": [
|
||||
"./bin/*",
|
||||
"./lib/*"
|
||||
],
|
||||
"typings": "./lib/index.d.ts",
|
||||
"directories": {
|
||||
"lib": "lib"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5.8.2"
|
||||
},
|
||||
"keywords": []
|
||||
}
|
188
android/proxy_cache_thing/src/index.ts
Normal file
188
android/proxy_cache_thing/src/index.ts
Normal file
@ -0,0 +1,188 @@
|
||||
import { getLocal } from "mockttp";
|
||||
import * as WebSock from "ws";
|
||||
|
||||
const mockServer = getLocal();
|
||||
|
||||
const wait_for_open = (socket: WebSock) => {
|
||||
if (socket.readyState === socket.OPEN) return;
|
||||
return new Promise((resolve, reject) => {
|
||||
const maxNumberOfAttempts = 20;
|
||||
const intervalTime = 100; //ms
|
||||
|
||||
let currentAttempt = 0;
|
||||
const interval = setInterval(() => {
|
||||
if (currentAttempt > maxNumberOfAttempts - 1) {
|
||||
clearInterval(interval);
|
||||
reject(new Error("Maximum number of attempts exceeded"));
|
||||
} else if (socket.readyState === socket.OPEN) {
|
||||
clearInterval(interval);
|
||||
resolve(undefined);
|
||||
} else if (socket.readyState == socket.CLOSED) {
|
||||
console.log(socket.url);
|
||||
reject(new Error("The server socket closed"));
|
||||
}
|
||||
currentAttempt++;
|
||||
}, intervalTime);
|
||||
});
|
||||
};
|
||||
|
||||
const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));
|
||||
function waitforhost(
|
||||
url: string,
|
||||
expected_status = 200,
|
||||
interval = 1000,
|
||||
attempts = 10
|
||||
): Promise<void> {
|
||||
let count = 1;
|
||||
|
||||
return new Promise(async (resolve, reject) => {
|
||||
while (count < attempts) {
|
||||
await sleep(interval);
|
||||
|
||||
try {
|
||||
const response = await fetch(url);
|
||||
if (response.status === expected_status) {
|
||||
resolve();
|
||||
break;
|
||||
} else {
|
||||
count++;
|
||||
}
|
||||
} catch {
|
||||
count++;
|
||||
console.log(`Still down, trying ${count} of ${attempts}`);
|
||||
}
|
||||
}
|
||||
|
||||
reject(new Error(`Server is down: ${count} attempts tried`));
|
||||
});
|
||||
}
|
||||
|
||||
(async () => {
|
||||
const proxy_port = process.env.PROXY_PORT;
|
||||
const server_port = process.env.SERVER_PORT;
|
||||
const loopback_port = process.env.LOOPBACK_PORT; // internal only
|
||||
const monitoring_api_port = process.env.MONITORING_API_PORT;
|
||||
if (!proxy_port || !server_port || !monitoring_api_port || !loopback_port) {
|
||||
throw Error("Configuration env variables not set");
|
||||
}
|
||||
|
||||
// Expect 403 forbidden
|
||||
await waitforhost("http://127.0.0.1:" + server_port, 403);
|
||||
mockServer.start(+proxy_port);
|
||||
|
||||
let cached_resp: undefined | string = undefined;
|
||||
|
||||
const cors_headers = {
|
||||
"access-control-allow-origin": "*",
|
||||
"access-control-allow-methods": "GET, POST, PUT, DELETE, OPTIONS",
|
||||
"access-control-allow-headers": "Content-Type, Authorization",
|
||||
"access-control-max-age": "86400",
|
||||
"access-control-allow-credentials": "true",
|
||||
Origin: "http://127.0.0.1:8080", // Trick the server into thinking that it is accessed through localhost
|
||||
};
|
||||
await mockServer.forOptions().thenReply(200, "", cors_headers);
|
||||
|
||||
await mockServer.forPost("/start").thenPassThrough({
|
||||
beforeRequest: async (req) => {
|
||||
if (cached_resp) {
|
||||
return {
|
||||
response: { body: cached_resp, headers: cors_headers },
|
||||
};
|
||||
}
|
||||
// forward the request to the real server
|
||||
return {
|
||||
url: req.url,
|
||||
headers: req.headers,
|
||||
body: await req.body.getDecodedBuffer(),
|
||||
};
|
||||
},
|
||||
beforeResponse: async (resp, _req) => {
|
||||
// cache the response
|
||||
cached_resp = (await resp.body.getText()) as string;
|
||||
// set the cors headers, overwriting the prohibitive ones
|
||||
return { headers: { ...resp.headers, ...cors_headers } };
|
||||
},
|
||||
});
|
||||
|
||||
await mockServer.forPost("/stop").thenReply(200);
|
||||
|
||||
// forward everything to the real server
|
||||
await mockServer.forUnmatchedRequest().thenPassThrough({
|
||||
beforeRequest: async (req) => {
|
||||
return { url: req.url };
|
||||
},
|
||||
beforeResponse: async (resp, _req) => {
|
||||
return { headers: { ...resp.headers, ...cors_headers } };
|
||||
},
|
||||
});
|
||||
|
||||
await mockServer
|
||||
.forAnyWebSocket()
|
||||
.thenForwardTo("ws://127.0.0.1:" + loopback_port);
|
||||
|
||||
let wss = new WebSock.Server({ port: +loopback_port });
|
||||
|
||||
// this is append only
|
||||
let httptoolkit_server_messages: String[] = [];
|
||||
|
||||
let api_server = new WebSock.Server({ port: +monitoring_api_port });
|
||||
|
||||
api_server.on("connection", (ws) => {
|
||||
let curr_idx_to_send = 0;
|
||||
const interval = setInterval(() => {
|
||||
while (httptoolkit_server_messages[curr_idx_to_send] != undefined) {
|
||||
if (ws.readyState != ws.OPEN) {
|
||||
clearInterval(interval);
|
||||
ws.close();
|
||||
break;
|
||||
}
|
||||
ws.send(httptoolkit_server_messages[curr_idx_to_send]);
|
||||
curr_idx_to_send++;
|
||||
}
|
||||
}, 100);
|
||||
});
|
||||
wss.on("connection", (ws, req) => {
|
||||
let server_session_url = "ws://127.0.0.1:" + server_port + req.url;
|
||||
let httptoolkit_server_session: WebSock;
|
||||
console.log("ws connection:", ws.protocol, typeof ws.protocol);
|
||||
if (ws.protocol) {
|
||||
httptoolkit_server_session = new WebSock(
|
||||
server_session_url,
|
||||
ws.protocol,
|
||||
{ joinDuplicateHeaders: true, headers: req.headers }
|
||||
);
|
||||
} else {
|
||||
httptoolkit_server_session = new WebSock(server_session_url, {
|
||||
joinDuplicateHeaders: true,
|
||||
headers: req.headers,
|
||||
});
|
||||
}
|
||||
httptoolkit_server_session.onerror = (_) => {
|
||||
ws.close();
|
||||
httptoolkit_server_session.close();
|
||||
return;
|
||||
};
|
||||
httptoolkit_server_session.onopen = () => {
|
||||
console.log("ws connected to the server");
|
||||
};
|
||||
|
||||
httptoolkit_server_session.onmessage = (msg) => {
|
||||
httptoolkit_server_messages.push(msg.data.toString());
|
||||
ws.send(msg.data);
|
||||
};
|
||||
|
||||
// Listening for messages from the client
|
||||
ws.on("message", async (message) => {
|
||||
await wait_for_open(httptoolkit_server_session);
|
||||
httptoolkit_server_session.send(message.toString());
|
||||
});
|
||||
|
||||
// Handling client disconnection
|
||||
ws.on("close", () => {
|
||||
httptoolkit_server_session.close();
|
||||
});
|
||||
});
|
||||
|
||||
console.log("WS Proxy started");
|
||||
console.log(mockServer.proxyEnv);
|
||||
})();
|
38
android/proxy_cache_thing/tsconfig.json
Normal file
38
android/proxy_cache_thing/tsconfig.json
Normal file
@ -0,0 +1,38 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"lib": [
|
||||
"es2015"
|
||||
],
|
||||
|
||||
"rootDir": "src",
|
||||
"outDir": "dist",
|
||||
|
||||
"strict": true,
|
||||
"alwaysStrict": true,
|
||||
"strictFunctionTypes": true,
|
||||
"strictNullChecks": true,
|
||||
"strictPropertyInitialization": true,
|
||||
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noImplicitAny": true,
|
||||
"noImplicitReturns": true,
|
||||
"noImplicitThis": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noUnusedLocals": false,
|
||||
"noUnusedParameters": false,
|
||||
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"downlevelIteration": true,
|
||||
"declaration": true,
|
||||
|
||||
"pretty": true
|
||||
},
|
||||
"include": [
|
||||
"typings/**/*",
|
||||
"src/**/*"
|
||||
]
|
||||
}
|
3
android/proxy_cache_thing/tslint.json
Normal file
3
android/proxy_cache_thing/tslint.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"extends": "tslint:latest"
|
||||
}
|
9
certgen/Dockerfile
Normal file
9
certgen/Dockerfile
Normal file
@ -0,0 +1,9 @@
|
||||
FROM node:22.14.0
|
||||
|
||||
RUN git clone https://github.com/httptoolkit/httptoolkit-server
|
||||
|
||||
WORKDIR /httptoolkit-server
|
||||
RUN git checkout 5c60a70b08d30126639484314f5b5619a388b026 \
|
||||
&& npm i && npm run build:src
|
||||
|
||||
CMD /httptoolkit-server/bin/run start -c /certificates
|
@ -1,14 +1,13 @@
|
||||
services:
|
||||
proxy:
|
||||
build: ./proxy/
|
||||
container_name: proxy
|
||||
networks:
|
||||
- rent_gen_android
|
||||
volumes:
|
||||
- $PWD/certificates:/root/.mitmproxy
|
||||
- $PWD/log:/log
|
||||
android:
|
||||
build: ./android/
|
||||
build:
|
||||
context: ./android/
|
||||
args:
|
||||
PROXY_PORT: "45459"
|
||||
SERVER_PORT: "45456"
|
||||
LOOPBACK_PORT: "10000"
|
||||
MONITORING_API_PORT: "10001"
|
||||
container_name: httptoolkit_server
|
||||
container_name: android
|
||||
sysctls:
|
||||
- net.ipv6.conf.all.disable_ipv6=1
|
||||
@ -18,9 +17,29 @@ services:
|
||||
- /dev/kvm
|
||||
networks:
|
||||
- rent_gen_android
|
||||
ports:
|
||||
- 45456:45459 # This cannot change
|
||||
- 45457:45459 # This cannot change
|
||||
- 10001:10001 # api port
|
||||
- 3000:3000 # android server port
|
||||
volumes:
|
||||
- $PWD/shared_buffer:/shared_buffer
|
||||
- $PWD/android/conf:/conf
|
||||
- $PWD/certificates:/certificates
|
||||
- $PWD/android/code:/code
|
||||
|
||||
httptoolkit_ui:
|
||||
build:
|
||||
context: ./httptoolkit_ui/
|
||||
args:
|
||||
# The ip / hostname using which,
|
||||
# the browser can reach this docker session
|
||||
DOCKER_HOST: "127.0.0.1"
|
||||
container_name: httptoolkit_ui
|
||||
networks:
|
||||
- rent_gen_android
|
||||
ports:
|
||||
- 9080:9080
|
||||
http_server:
|
||||
build: ./http_server/
|
||||
container_name: http_server
|
||||
@ -28,10 +47,11 @@ services:
|
||||
- rent_gen_android
|
||||
volumes:
|
||||
- $PWD/http_server/code:/code
|
||||
- $PWD/shared_buffer:/shared_buffer
|
||||
- $PWD/log:/log
|
||||
ports:
|
||||
- 8080:8080
|
||||
|
||||
networks:
|
||||
rent_gen_android:
|
||||
driver: bridge
|
||||
driver: bridge
|
||||
|
@ -3,6 +3,6 @@
|
||||
npm i
|
||||
npm run build
|
||||
node waitSocket.mjs
|
||||
node index.mjs
|
||||
node --watch index.mjs
|
||||
|
||||
#tail -f /dev/null
|
||||
|
@ -1,17 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<head style="height: 100vh">
|
||||
<meta charset="UTF-8" />
|
||||
<title>Rentgen android</title>
|
||||
<script src="/htmx.js"></script>
|
||||
<style>
|
||||
main {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.log-section {
|
||||
height: 600px;
|
||||
width: 480px;
|
||||
overflow-y: auto;
|
||||
height: auto;
|
||||
width: 400px;
|
||||
overflow: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-left: 20px;
|
||||
@ -41,30 +42,159 @@
|
||||
background-color: aqua;
|
||||
}
|
||||
|
||||
#clicks-log {
|
||||
font-family: Menlo, Consolas, Monaco, Liberation Mono, Lucida Console,
|
||||
monospace;
|
||||
}
|
||||
#clicks-log {
|
||||
font-family: Menlo, Consolas, Monaco, Liberation Mono, Lucida Console,
|
||||
monospace;
|
||||
}
|
||||
|
||||
.tab {
|
||||
border: 1px solid #ccc;
|
||||
background-color: #f1f1f1;
|
||||
}
|
||||
|
||||
/* Style the buttons that are used to open the tab content */
|
||||
.tab button {
|
||||
background-color: inherit;
|
||||
float: left;
|
||||
border: none;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
padding: 14px 16px;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
/* Change background color of buttons on hover */
|
||||
.tab button:hover {
|
||||
background-color: #ddd;
|
||||
}
|
||||
|
||||
/* Create an active/current tablink class */
|
||||
.tab button.active {
|
||||
background-color: #ccc;
|
||||
}
|
||||
.tabcontent.active {
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
/* Style the tab content */
|
||||
.tabcontent {
|
||||
display: none;
|
||||
padding: 6px 12px;
|
||||
border: 1px solid #ccc;
|
||||
border-top: none;
|
||||
}
|
||||
html,
|
||||
body, main{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
}
|
||||
main {
|
||||
display:flex;
|
||||
flex-direction: row;
|
||||
align-items: stretch;
|
||||
}
|
||||
#logs-tab {
|
||||
overflow: auto;
|
||||
text-wrap: wrap;
|
||||
}
|
||||
.screen-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.screen-section #screen, .screen-section.screen_buttons {
|
||||
flex-grow: 0;
|
||||
}
|
||||
.tab-section {
|
||||
display: flex; flex-direction: column; flex-grow: 1;
|
||||
}
|
||||
<!-- TODO: A notification system -->
|
||||
#resp {
|
||||
display: none;
|
||||
}
|
||||
#upload_form {
|
||||
display:flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
#upload_form button, #upload_form label {
|
||||
border: 2px solid #ccc;
|
||||
background-color: #f1f1f1;
|
||||
cursor: pointer;
|
||||
padding: 3px 10px;
|
||||
transition: 0.3s;
|
||||
}
|
||||
#upload_form button:hover, #upload_form label:hover {
|
||||
background-color: #ddd;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="resp"></div>
|
||||
<main>
|
||||
<section class="screen-section">
|
||||
<section class="screen-section" >
|
||||
<img
|
||||
id="screen"
|
||||
alt="android screen"
|
||||
src=""
|
||||
draggable="false"
|
||||
class="screen"
|
||||
style="flex-grow: 0"
|
||||
/>
|
||||
<div class="screen-buttons">
|
||||
<div class="screen-buttons" style="flex-grow: 0">
|
||||
<button class="screen-buttons-home">home</button>
|
||||
<button class="screen-buttons-back">back</button>
|
||||
</div>
|
||||
</section>
|
||||
<p id="clicks-log" class="log-section"></p>
|
||||
<p id="traffic-log" class="log-section"></p>
|
||||
<form id="upload_form" hx-post="/upload_apk" enctype="multipart/form-data" hx-target="#resp">
|
||||
<label id="upload_input" for="app">Select file
|
||||
<input type="file" id="app" name="app" accept=".apk" required/>
|
||||
</label>
|
||||
<button type="submit">Install the app</button>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
<div class="tab-section" >
|
||||
<div class="tab">
|
||||
<button class="tablinks active" onclick="open_tab(event, 'httptoolkit-tab')">HttpToolkit UI</button>
|
||||
<button class="tablinks" onclick="open_tab(event, 'logs-tab')">Logs</button>
|
||||
</div>
|
||||
|
||||
<div class="tabcontent" id="logs-tab">
|
||||
<p id="clicks-log" class="log-section" ></p>
|
||||
<p id="traffic-log" class="log-section"></p>
|
||||
</div>
|
||||
|
||||
<div class="tabcontent active" id="httptoolkit-tab">
|
||||
<iframe id="httptoolkit-frame" style="flex-grow: 1;" src="http://localhost:9080/" title="httptoolkit"></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</main>
|
||||
<script>
|
||||
function open_tab(evt, tab_name) {
|
||||
let i, tabcontent, tablinks;
|
||||
|
||||
// Get all elements with class="tabcontent" and hide them
|
||||
tabcontent = document.getElementsByClassName("tabcontent");
|
||||
for (i = 0; i < tabcontent.length; i++) {
|
||||
if (tabcontent[i].id != tab_name) {
|
||||
tabcontent[i].classList.remove("active");
|
||||
} else {
|
||||
tabcontent[i].classList.add("active");
|
||||
}
|
||||
}
|
||||
|
||||
// Get all elements with class="tablinks" and remove the class "active"
|
||||
tablinks = document.getElementsByClassName("tablinks");
|
||||
for (i = 0; i < tablinks.length; i++) {
|
||||
tablinks[i].classList.remove("active")
|
||||
}
|
||||
|
||||
// Show the current tab, and add an "active" class to the button that opened the tab
|
||||
evt.currentTarget.classList.add("active");
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
var screen = document.getElementById("screen");
|
||||
var clicksLog = document.getElementById("clicks-log");
|
||||
|
@ -6,6 +6,8 @@ import {
|
||||
waitFullBoot,
|
||||
} from "./screenshot.mjs";
|
||||
|
||||
import fileUpload from 'express-fileupload';
|
||||
|
||||
const device_size_x = 320;
|
||||
const device_size_y = 640;
|
||||
|
||||
@ -25,6 +27,10 @@ app.get("/trafficLog.js", function (req, res) {
|
||||
res.sendFile("/code/dist/trafficLog.js");
|
||||
});
|
||||
|
||||
app.get("/htmx.js", function (req, res) {
|
||||
res.sendFile("/code/node_modules/htmx.org/dist/htmx.min.js");
|
||||
});
|
||||
|
||||
app.get("/trafficLog", async function (req, res) {
|
||||
res.sendFile("/log/trafficLog");
|
||||
});
|
||||
@ -54,6 +60,23 @@ app.post("/back", function (req, res) {
|
||||
res.sendStatus(200);
|
||||
});
|
||||
|
||||
// default options
|
||||
app.use(fileUpload());
|
||||
app.post('/upload_apk',function (req, res) {
|
||||
if (!req.files || Object.keys(req.files).length === 0) {
|
||||
return res.status(400).send('No files were uploaded.');
|
||||
}
|
||||
let file = req.files.app;
|
||||
let uploadPath = '/shared_buffer/app.apk';
|
||||
|
||||
file.mv(uploadPath, function(err) {
|
||||
if (err)
|
||||
return res.status(500).send(err);
|
||||
android_websocket.send(`install`);
|
||||
res.send('File uploaded!');
|
||||
});
|
||||
})
|
||||
|
||||
app.post("/home", function (req, res) {
|
||||
android_websocket.send(`home`);
|
||||
res.sendStatus(200);
|
||||
@ -84,4 +107,4 @@ app.post("/drag", function (req, res) {
|
||||
});
|
||||
|
||||
app.listen(8080, () => console.log("Listening in port 8080"));
|
||||
|
||||
|
||||
|
39
http_server/code/package-lock.json
generated
39
http_server/code/package-lock.json
generated
@ -6,6 +6,8 @@
|
||||
"": {
|
||||
"dependencies": {
|
||||
"express": "^4.18.2",
|
||||
"express-fileupload": "^1.5.1",
|
||||
"htmx.org": "^1.9.12",
|
||||
"preact": "^10.18.1",
|
||||
"ws": "^8.18.0"
|
||||
},
|
||||
@ -405,6 +407,17 @@
|
||||
"npm": "1.2.8000 || >= 1.4.16"
|
||||
}
|
||||
},
|
||||
"node_modules/busboy": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz",
|
||||
"integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==",
|
||||
"dependencies": {
|
||||
"streamsearch": "^1.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.16.0"
|
||||
}
|
||||
},
|
||||
"node_modules/bytes": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
||||
@ -586,6 +599,18 @@
|
||||
"node": ">= 0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/express-fileupload": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/express-fileupload/-/express-fileupload-1.5.1.tgz",
|
||||
"integrity": "sha512-LsYG1ALXEB7vlmjuSw8ABeOctMp8a31aUC5ZF55zuz7O2jLFnmJYrCv10py357ky48aEoBQ/9bVXgFynjvaPmA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"busboy": "^1.6.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/finalhandler": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
|
||||
@ -671,6 +696,12 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/htmx.org": {
|
||||
"version": "1.9.12",
|
||||
"resolved": "https://registry.npmjs.org/htmx.org/-/htmx.org-1.9.12.tgz",
|
||||
"integrity": "sha512-VZAohXyF7xPGS52IM8d1T1283y+X4D+Owf3qY1NZ9RuBypyu9l8cGsxUMAG5fEAb/DhT7rDoJ9Hpu5/HxFD3cw==",
|
||||
"license": "0BSD"
|
||||
},
|
||||
"node_modules/http-errors": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
|
||||
@ -955,6 +986,14 @@
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/streamsearch": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz",
|
||||
"integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/toidentifier": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
|
||||
|
@ -4,6 +4,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"express": "^4.18.2",
|
||||
"express-fileupload": "^1.5.1",
|
||||
"htmx.org": "^1.9.12",
|
||||
"preact": "^10.18.1",
|
||||
"ws": "^8.18.0"
|
||||
},
|
||||
|
@ -9,8 +9,17 @@ let screenshotPromise = null;
|
||||
|
||||
async function screenshot() {
|
||||
const time_start = Date.now();
|
||||
let retries = 0;
|
||||
while (android_websocket.readyState != WebSocket.OPEN) {
|
||||
await sleep(15);
|
||||
retries++;
|
||||
if (retries > 50)
|
||||
{
|
||||
console.error("Screenshot ws timeout");
|
||||
doneWrite = 0;
|
||||
screenshotPromise = null;
|
||||
return ;
|
||||
}
|
||||
}
|
||||
android_websocket.send("screenshot");
|
||||
while (!doneWrite) {
|
||||
|
@ -1,18 +1,21 @@
|
||||
import { h, render, Component } from "preact";
|
||||
|
||||
const refreshRate = 1000;
|
||||
|
||||
class TrafficLog extends Component {
|
||||
constructor() {
|
||||
super();
|
||||
this.state = { content: "" };
|
||||
this.state = { content: [] };
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.intervalSetter = setInterval(async () => {
|
||||
var log = await (await fetch("trafficLog")).text();
|
||||
this.setState({ content: log });
|
||||
}, refreshRate);
|
||||
// This should also be dynamic
|
||||
this.connection = new WebSocket("ws://localhost:10001");
|
||||
this.connection.onmessage = (msg) => {
|
||||
this.setState({ content: [...this.state.content, msg.data] });
|
||||
};
|
||||
this.connection.onclose = this.connection.onerror = () => {
|
||||
var element = document.getElementById("httptoolkit-frame");
|
||||
element.parentNode.removeChild(element);
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
@ -21,11 +24,10 @@ class TrafficLog extends Component {
|
||||
|
||||
render() {
|
||||
const contentWithLineBreaks = this.state.content
|
||||
.split("\n")
|
||||
.map((line, _) => {
|
||||
.map((text) => {
|
||||
return (
|
||||
<span>
|
||||
{line}
|
||||
{text.substring(0, 100)}
|
||||
<br />
|
||||
</span>
|
||||
);
|
||||
|
20
httptoolkit_ui/Dockerfile
Normal file
20
httptoolkit_ui/Dockerfile
Normal file
@ -0,0 +1,20 @@
|
||||
FROM node:20.18.1
|
||||
|
||||
# If iproute2 is not installed,
|
||||
# node can't figure out what address to bind 0.0.0.0 to
|
||||
RUN apt-get update && apt-get install iproute2 python3 --yes \
|
||||
&& git clone https://github.com/httptoolkit/httptoolkit-ui
|
||||
|
||||
WORKDIR httptoolkit-ui
|
||||
RUN git checkout a0dbb8e1cd38b346fe411b03de0c5191ff06c669 \
|
||||
&& npm i && npm run server:setup
|
||||
|
||||
ARG DOCKER_HOST=localhost
|
||||
|
||||
# This gets sent to the browser as a server URL,
|
||||
# so it is important that it is set to the domain / ip of the server.
|
||||
|
||||
RUN sed -i "s/127.0.0.1/${DOCKER_HOST}/" src/model/proxy-store.ts \
|
||||
&& npm run build:default # Can take a long time
|
||||
|
||||
CMD npm exec static-server ./dist -o
|
218
package-lock.json
generated
218
package-lock.json
generated
@ -12,6 +12,7 @@
|
||||
"version": "2.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
||||
"integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@nodelib/fs.stat": "2.0.5",
|
||||
"run-parallel": "^1.1.9"
|
||||
@ -24,6 +25,7 @@
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
|
||||
"integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
@ -32,6 +34,7 @@
|
||||
"version": "1.2.8",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
|
||||
"integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@nodelib/fs.scandir": "2.1.5",
|
||||
"fastq": "^1.6.0"
|
||||
@ -41,57 +44,68 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@types/fs-extra": {
|
||||
"version": "11.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-11.0.1.tgz",
|
||||
"integrity": "sha512-MxObHvNl4A69ofaTRU8DFqvgzzv8s9yRtaPPm5gud9HDNvpB3GPQFvNuTWAI59B9huVGV5jXYJwbCsmBsOGYWA==",
|
||||
"version": "11.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-11.0.4.tgz",
|
||||
"integrity": "sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/jsonfile": "*",
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/jsonfile": {
|
||||
"version": "6.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/jsonfile/-/jsonfile-6.1.1.tgz",
|
||||
"integrity": "sha512-GSgiRCVeapDN+3pqA35IkQwasaCh/0YFH5dEF6S88iDvEn901DjOeH3/QPY+XYP1DFzDZPvIvfeEgk+7br5png==",
|
||||
"version": "6.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/jsonfile/-/jsonfile-6.1.4.tgz",
|
||||
"integrity": "sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/minimist": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz",
|
||||
"integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ=="
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz",
|
||||
"integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "18.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.7.tgz",
|
||||
"integrity": "sha512-MFg7ua/bRtnA1hYE3pVyWxGd/r7aMqjNOdHvlSsXV3n8iaeGKkOaPzpJh6/ovf4bEXWcojkeMJpTsq3mzXW4IQ=="
|
||||
"version": "18.19.80",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.80.tgz",
|
||||
"integrity": "sha512-kEWeMwMeIvxYkeg1gTc01awpwLbfMRZXdIhwRcakd/KlK53jmRC26LqcbIt7fnAQTu5GzlnWmzA3H6+l1u6xxQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"undici-types": "~5.26.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/ps-tree": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/ps-tree/-/ps-tree-1.1.2.tgz",
|
||||
"integrity": "sha512-ZREFYlpUmPQJ0esjxoG1fMvB2HNaD3z+mjqdSosZvd3RalncI9NEur73P8ZJz4YQdL64CmV1w0RuqoRUlhQRBw=="
|
||||
"version": "1.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/ps-tree/-/ps-tree-1.1.6.tgz",
|
||||
"integrity": "sha512-PtrlVaOaI44/3pl3cvnlK+GxOM3re2526TJvPvh7W+keHIXdV4TE0ylpPBAcvFQCbGitaTXwL9u+RF7qtVeazQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/which": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/which/-/which-3.0.0.tgz",
|
||||
"integrity": "sha512-ASCxdbsrwNfSMXALlC3Decif9rwDMu+80KGp5zI2RLRotfMsTv7fHL8W8VDp24wymzDyIFudhUeSCugrgRFfHQ=="
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/which/-/which-3.0.4.tgz",
|
||||
"integrity": "sha512-liyfuo/106JdlgSchJzXEQCVArk0CvevqPote8F8HgWgJ3dRCcTHgJIsLDuee0kxk/mhbInzIZk3QWSZJ8R+2w==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/braces": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
|
||||
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fill-range": "^7.0.1"
|
||||
"fill-range": "^7.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/chalk": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.2.0.tgz",
|
||||
"integrity": "sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==",
|
||||
"version": "5.4.1",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz",
|
||||
"integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^12.17.0 || ^14.13 || >=16.0.0"
|
||||
},
|
||||
@ -103,6 +117,7 @@
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz",
|
||||
"integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 12"
|
||||
}
|
||||
@ -111,6 +126,7 @@
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
|
||||
"integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"path-type": "^4.0.0"
|
||||
},
|
||||
@ -121,12 +137,14 @@
|
||||
"node_modules/duplexer": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
|
||||
"integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg=="
|
||||
"integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/event-stream": {
|
||||
"version": "3.3.4",
|
||||
"resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz",
|
||||
"integrity": "sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"duplexer": "~0.1.1",
|
||||
"from": "~0",
|
||||
@ -138,24 +156,26 @@
|
||||
}
|
||||
},
|
||||
"node_modules/fast-glob": {
|
||||
"version": "3.2.12",
|
||||
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz",
|
||||
"integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==",
|
||||
"version": "3.3.3",
|
||||
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
|
||||
"integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@nodelib/fs.stat": "^2.0.2",
|
||||
"@nodelib/fs.walk": "^1.2.3",
|
||||
"glob-parent": "^5.1.2",
|
||||
"merge2": "^1.3.0",
|
||||
"micromatch": "^4.0.4"
|
||||
"micromatch": "^4.0.8"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/fastq": {
|
||||
"version": "1.15.0",
|
||||
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz",
|
||||
"integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==",
|
||||
"version": "1.19.1",
|
||||
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz",
|
||||
"integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"reusify": "^1.0.4"
|
||||
}
|
||||
@ -174,6 +194,7 @@
|
||||
"url": "https://paypal.me/jimmywarting"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"node-domexception": "^1.0.0",
|
||||
"web-streams-polyfill": "^3.0.3"
|
||||
@ -183,9 +204,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/fill-range": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
||||
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"to-regex-range": "^5.0.1"
|
||||
},
|
||||
@ -197,6 +219,7 @@
|
||||
"version": "4.0.10",
|
||||
"resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
|
||||
"integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fetch-blob": "^3.1.2"
|
||||
},
|
||||
@ -207,12 +230,14 @@
|
||||
"node_modules/from": {
|
||||
"version": "0.1.7",
|
||||
"resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz",
|
||||
"integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g=="
|
||||
"integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/fs-extra": {
|
||||
"version": "11.1.1",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.1.tgz",
|
||||
"integrity": "sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==",
|
||||
"version": "11.3.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz",
|
||||
"integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^6.0.1",
|
||||
@ -223,9 +248,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/fx": {
|
||||
"version": "28.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fx/-/fx-28.0.0.tgz",
|
||||
"integrity": "sha512-vKQDA9g868cZiW8ulgs2uN1yx1i7/nsS33jTMOxekk0Z03BJLffVcdW6AVD32fWb3E6RtmWWuBXBZOk8cLXFNQ==",
|
||||
"version": "35.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fx/-/fx-35.0.0.tgz",
|
||||
"integrity": "sha512-O07q+Lknrom5RUX/u53tjo2KTTLUnL0K703JbqMYb19ORijfJNvijzFqqYXEjdk25T9R14S6t6wHD8fCWXCM0g==",
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"fx": "index.js"
|
||||
}
|
||||
@ -234,6 +260,7 @@
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
|
||||
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"is-glob": "^4.0.1"
|
||||
},
|
||||
@ -242,13 +269,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/globby": {
|
||||
"version": "13.1.4",
|
||||
"resolved": "https://registry.npmjs.org/globby/-/globby-13.1.4.tgz",
|
||||
"integrity": "sha512-iui/IiiW+QrJ1X1hKH5qwlMQyv34wJAYwH1vrf8b9kBA4sNiif3gKsMHa+BrdnOpEudWjpotfa7LrTzB1ERS/g==",
|
||||
"version": "13.2.2",
|
||||
"resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz",
|
||||
"integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"dir-glob": "^3.0.1",
|
||||
"fast-glob": "^3.2.11",
|
||||
"ignore": "^5.2.0",
|
||||
"fast-glob": "^3.3.0",
|
||||
"ignore": "^5.2.4",
|
||||
"merge2": "^1.4.1",
|
||||
"slash": "^4.0.0"
|
||||
},
|
||||
@ -262,12 +290,14 @@
|
||||
"node_modules/graceful-fs": {
|
||||
"version": "4.2.11",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
|
||||
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="
|
||||
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/ignore": {
|
||||
"version": "5.2.4",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
|
||||
"integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==",
|
||||
"version": "5.3.2",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
|
||||
"integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 4"
|
||||
}
|
||||
@ -276,6 +306,7 @@
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
||||
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
@ -284,6 +315,7 @@
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
|
||||
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-extglob": "^2.1.1"
|
||||
},
|
||||
@ -295,6 +327,7 @@
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.12.0"
|
||||
}
|
||||
@ -302,12 +335,14 @@
|
||||
"node_modules/isexe": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
|
||||
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/jsonfile": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
|
||||
"integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
@ -324,16 +359,18 @@
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
|
||||
"integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/micromatch": {
|
||||
"version": "4.0.5",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
|
||||
"integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
|
||||
"version": "4.0.8",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
|
||||
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"braces": "^3.0.2",
|
||||
"braces": "^3.0.3",
|
||||
"picomatch": "^2.3.1"
|
||||
},
|
||||
"engines": {
|
||||
@ -344,6 +381,7 @@
|
||||
"version": "1.2.8",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
|
||||
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
@ -362,6 +400,7 @@
|
||||
"url": "https://paypal.me/jimmywarting"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10.5.0"
|
||||
}
|
||||
@ -370,6 +409,7 @@
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.1.tgz",
|
||||
"integrity": "sha512-cRVc/kyto/7E5shrWca1Wsea4y6tL9iYJE5FBCius3JQfb/4P4I295PfhgbJQBLTx6lATE4z+wK0rPM4VS2uow==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"data-uri-to-buffer": "^4.0.0",
|
||||
"fetch-blob": "^3.1.4",
|
||||
@ -387,6 +427,7 @@
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
|
||||
"integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
@ -395,6 +436,10 @@
|
||||
"version": "0.0.11",
|
||||
"resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz",
|
||||
"integrity": "sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==",
|
||||
"license": [
|
||||
"MIT",
|
||||
"Apache2"
|
||||
],
|
||||
"dependencies": {
|
||||
"through": "~2.3"
|
||||
}
|
||||
@ -403,6 +448,7 @@
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
|
||||
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8.6"
|
||||
},
|
||||
@ -414,6 +460,7 @@
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.2.0.tgz",
|
||||
"integrity": "sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"event-stream": "=3.3.4"
|
||||
},
|
||||
@ -441,12 +488,14 @@
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
]
|
||||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/reusify": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
|
||||
"integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
|
||||
"integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"iojs": ">=1.0.0",
|
||||
"node": ">=0.10.0"
|
||||
@ -470,6 +519,7 @@
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"queue-microtask": "^1.2.2"
|
||||
}
|
||||
@ -478,6 +528,7 @@
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz",
|
||||
"integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
@ -489,6 +540,7 @@
|
||||
"version": "0.3.3",
|
||||
"resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz",
|
||||
"integrity": "sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"through": "2"
|
||||
},
|
||||
@ -500,6 +552,7 @@
|
||||
"version": "0.0.4",
|
||||
"resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz",
|
||||
"integrity": "sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"duplexer": "~0.1.1"
|
||||
}
|
||||
@ -507,12 +560,14 @@
|
||||
"node_modules/through": {
|
||||
"version": "2.3.8",
|
||||
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
|
||||
"integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg=="
|
||||
"integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/to-regex-range": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-number": "^7.0.0"
|
||||
},
|
||||
@ -520,18 +575,26 @@
|
||||
"node": ">=8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "5.26.5",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
||||
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/universalify": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
|
||||
"integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
|
||||
"integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/web-streams-polyfill": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz",
|
||||
"integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==",
|
||||
"version": "3.3.3",
|
||||
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz",
|
||||
"integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
@ -540,6 +603,7 @@
|
||||
"version": "0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/webpod/-/webpod-0.0.2.tgz",
|
||||
"integrity": "sha512-cSwwQIeg8v4i3p4ajHhwgR7N6VyxAf+KYSSsY6Pd3aETE+xEU4vbitz7qQkB0I321xnhDdgtxuiSfk5r/FVtjg==",
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"webpod": "dist/index.js"
|
||||
}
|
||||
@ -548,6 +612,7 @@
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz",
|
||||
"integrity": "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"isexe": "^2.0.0"
|
||||
},
|
||||
@ -559,17 +624,22 @@
|
||||
}
|
||||
},
|
||||
"node_modules/yaml": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.2.2.tgz",
|
||||
"integrity": "sha512-CBKFWExMn46Foo4cldiChEzn7S7SRV+wqiluAb6xmueD/fGyRHIhX8m14vVGgeFWjN540nKCNVj6P21eQjgTuA==",
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz",
|
||||
"integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==",
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"yaml": "bin.mjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
}
|
||||
},
|
||||
"node_modules/zx": {
|
||||
"version": "7.2.2",
|
||||
"resolved": "https://registry.npmjs.org/zx/-/zx-7.2.2.tgz",
|
||||
"integrity": "sha512-50Gjicd6ijTt7Zcz5fNX+rHrmE0uVqC+X6lYKhf2Cu8wIxDpNIzXwTmzchNdW+JY3LFsRcU43B1lHE4HBMmKgQ==",
|
||||
"version": "7.2.3",
|
||||
"resolved": "https://registry.npmjs.org/zx/-/zx-7.2.3.tgz",
|
||||
"integrity": "sha512-QODu38nLlYXg/B/Gw7ZKiZrvPkEsjPN3LQ5JFXM7h0JvwhEdPNNl+4Ao1y4+o3CLNiDUNcwzQYZ4/Ko7kKzCMA==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@types/fs-extra": "^11.0.1",
|
||||
"@types/minimist": "^1.2.2",
|
||||
|
@ -1,8 +1,8 @@
|
||||
hashed_name=`openssl x509 -inform PEM -subject_hash_old -in /ca-cert.cer | head -1`
|
||||
hashed_name=`openssl x509 -inform PEM -subject_hash_old -in /ca-cert.pem | head -1`
|
||||
|
||||
adb start-server
|
||||
emulator -avd virtual_dev -writable-system -no-window -no-audio &
|
||||
cp /ca-cert.cer /$hashed_name.0
|
||||
cp /ca-cert.pem /$hashed_name.0
|
||||
bash /preconf/install_cert.sh $hashed_name.0
|
||||
bash /preconf/install_culebra.sh
|
||||
|
||||
@ -12,4 +12,4 @@ adb emu kill
|
||||
#to let the host know it finished installing
|
||||
install -m 777 /dev/null /preconf/finished
|
||||
|
||||
tail -f /dev/null
|
||||
tail -f /dev/null
|
||||
|
@ -1,3 +0,0 @@
|
||||
FROM mitmproxy/mitmproxy:9.0.1
|
||||
|
||||
CMD mitmdump --mode socks5 > /log/trafficLog
|
21
start.mjs
21
start.mjs
@ -6,12 +6,8 @@ async function sleep(time) {
|
||||
|
||||
async function checkCertExistance() {
|
||||
return await Promise.all([
|
||||
fs.access("./certificates/mitmproxy-ca-cert.cer", fs.constants.R_OK),
|
||||
fs.access("./certificates/mitmproxy-ca-cert.p12", fs.constants.R_OK),
|
||||
fs.access("./certificates/mitmproxy-ca-cert.pem", fs.constants.R_OK),
|
||||
fs.access("./certificates/mitmproxy-ca.p12"),
|
||||
fs.access("./certificates/mitmproxy-ca.pem"),
|
||||
fs.access("./certificates/mitmproxy-dhparam.pem", fs.constants.R_OK),
|
||||
fs.access("./certificates/ca.key"),
|
||||
fs.access("./certificates/ca.pem", fs.constants.R_OK),
|
||||
]);
|
||||
}
|
||||
|
||||
@ -19,31 +15,35 @@ async function generateCert() {
|
||||
//remove certs if they exist
|
||||
try {
|
||||
await $`rm -rf certificates`;
|
||||
await $`mkdir certificates`;
|
||||
} catch {
|
||||
throw new Error(
|
||||
"To remove certificates, and create new ones, this command must be run with sudo"
|
||||
);
|
||||
}
|
||||
|
||||
//iniciate docker which will create certs
|
||||
$`docker run --rm -v $PWD/certificates:/home/mitmproxy/.mitmproxy --name certGenerator mitmproxy/mitmproxy:9.0.1 mitmdump &`;
|
||||
await $`docker build --tag certgen $PWD/certgen`
|
||||
// iniciate docker which will create certs
|
||||
$`docker run --rm -v $PWD/certificates:/certificates --name certGenerator certgen &`;
|
||||
|
||||
//wait for certs to generate
|
||||
let generated = false;
|
||||
while (!generated) {
|
||||
try {
|
||||
await checkCertExistance();
|
||||
await $`sleep 1`;
|
||||
generated = true;
|
||||
} catch {}
|
||||
}
|
||||
|
||||
//kill docker container
|
||||
$`docker stop certGenerator`;
|
||||
await $`docker stop certGenerator`;
|
||||
await $`docker rmi certgen`
|
||||
}
|
||||
|
||||
async function generatePreAndroid() {
|
||||
await $`docker build -t pre_android pre_android`;
|
||||
$`docker run --sysctl net.ipv6.conf.all.disable_ipv6=1 --rm -v $PWD/certificates/mitmproxy-ca-cert.cer:/ca-cert.cer -v $PWD/pre_android/preconf:/preconf --device=/dev/kvm --name pre_android_cont pre_android &`;
|
||||
$`docker run --sysctl net.ipv6.conf.all.disable_ipv6=1 --rm -v $PWD/certificates/ca.pem:/ca-cert.pem -v $PWD/pre_android/preconf:/preconf --device=/dev/kvm --name pre_android_cont pre_android &`;
|
||||
|
||||
console.log(
|
||||
"Installing tls certificate and culebra into the android pre-image..."
|
||||
@ -73,6 +73,7 @@ else if (process.argv[3] === "up") {
|
||||
await checkCertExistance();
|
||||
} catch {
|
||||
await generateCert();
|
||||
await generatePreAndroid(); // if the certs are new, the android should be regenerated
|
||||
}
|
||||
|
||||
try {
|
||||
|
Loading…
x
Reference in New Issue
Block a user