Skip to content

Commit f916bc6

Browse files
Enforced maintainability.
1 parent d9b8f1b commit f916bc6

File tree

3 files changed

+50
-51
lines changed

3 files changed

+50
-51
lines changed

transport/internet/browser_dialer/client/index.mjs

Lines changed: 0 additions & 35 deletions
This file was deleted.
Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,47 @@
11
<!DOCTYPE html>
2-
<html>
3-
<head>
4-
<meta http-equiv="200" charset="utf-8" />
5-
<meta content="true" name="HandheldFriendly" />
6-
<title>Browser Dialer</title>
7-
<script>
8-
// client.mjs, Appat 0.0.2, MIT License
9-
"use strict";let u=self.Deno?.createHttpClient({allowHost:!0}),i=class{report=!0;instanceId;#i=!0;#d=!0;#n=2;#c;#s;#r;#l;#e;#o;#t=new Map;#a=new Set;constructor(e,o){if(!Request.prototype.hasOwnProperty("body"))throw this.#d=!1,new Error("Fetch requests do not support streamable bodies");if(typeof self?.WebSocketStream!="function")throw this.#i=!1,new Error("WebSocket does not support streaming");typeof self?.Deno<"u"&&(this.#n=0),this.#s=o,this.#c=e}async start(){let e=this;if(e.#e)switch(e.#e.readyState){case WebSocket.CLOSING:case WebSocket.CLOSED:throw new Error("Attempted reconnection for an active dialer")}e.instanceId=self.crypto?.randomUUID(),e.#r=`${e.#c}/ws/${e.instanceId}`,e.#l=e.#r.replace("http","ws"),e.#e=new WebSocket(`${e.#r}/ctrl?token=${e.#s}`),e.#e.addEventListener("error",o=>{console.warn("Control socket has errored out:",o.error)}),e.#e.addEventListener("close",o=>{console.warn("Control socket closed."),e.#o?.abort()}),e.#e.addEventListener("opened",o=>{console.warn("Control socket is now ready."),e.#o=new AbortController}),e.#e.addEventListener("message",async o=>{let t=JSON.parse(o.data);switch(console.debug(t),t.m){case"PING":{console.debug("Pong!");break}case"APPAT":{switch(t.e?.appat){case"requestEnd":{e.#t.has(t.c)?(e.#t.get(t.c)[2](),console.info("Closed an ongoing upload.")):(e.#a.add(t.c),console.info("Closed a future upload."));break}}break}case"WS":break;case"WT":break;case"HEAD":case"GET":case"POST":case"PUT":case"DELETE":case"OPTIONS":case"PATCH":{let s={method:t.m,signal:e.#o};if(t.hasOwnProperty("e")){if(t.e.hasOwnProperty("r")){s.referrerPolicy="unsafe-url";let r=new URL(t.e.r);s.referrer=t.e.r.replace(`${r.protocol}//${r.hostname}`)}t.e.hasOwnProperty("h")&&(s.headers=t.e.h)}try{let c=await new WebSocketStream(`${e.#l}/${t.c}?token=${e.#s}`).opened;switch(t.m){case"POST":case"PUT":case"DELETE":case"OPTIONS":case"PATCH":{let l=c.readable.getReader();s.body=new ReadableStream({queueingStrategy:new ByteLengthQueuingStrategy({highWaterMark:65536}),start:async a=>{e.#t.set(t.c,[a,l,()=>{a.close(),e.#t.delete(t.c)}])},pull:async a=>{if(e.#a.has(t.c))e.#t.get(t.c)[2]();else if(e.#t.has(t.c)){let{value:p,done:h}=await l.read();p!==void 0&&a.enqueue(p),(h||e.#a.has(t.c))&&e.#t.get(t.c)[2]()}}}),e.#n>1?(s.duplex="half",e.#e.send(`{"c":"${t.c}","s":1,"t":"AppatError","e":"appat.halfDuplex"}`)):s.duplex="full";break}}u&&(s.client=u);let f=await fetch(t.u,s);if(e.report){let l={c:t.c,s:f.status,t:f.statusText,h:{}};for(let[a,p]of f.headers.entries())l.h[a]=p;e.#e.send(JSON.stringify(l))}t.m==="HEAD"?c.close():await f.body.pipeTo(c.writable)}catch(r){if(console.warn(r),e.report){let c={c:t.c,s:0,t:r.name,e:`${r.message}
10-
${r.stack}`};e.#e.send(JSON.stringify(c))}}break}default:console.warn(`Unsupported method: ${t.m}`)}})}};let d;self.location?.href?d=`${location.protocol}//${location.host}`:self.Deno?.args[0]?.length>0?d=`http://${self.Deno.args[0]}`:d="http://127.0.0.1:5779";console.debug(`Received dialer prefix: ${d}`);let w=atob("X19DU1JGX1RPS0VOX18"),n="__CSRF_TOKEN__";n===w&&(self.location?.search?.indexOf("?token=")===0?n=self.location.search.substring(7):self.Deno?.args[1]?.length>0?n=self.Deno.args[1]:n="00000000-0000-0000-0000-000000000000");console.debug(`Received CSRF token: ${n}`);let g=new i(d,n);g.start();
11-
</script>
12-
</head>
13-
<body>
14-
</body>
15-
</html>
2+
<head>
3+
<meta http-equiv="200" charset="utf-8" />
4+
<meta content="true" name="HandheldFriendly" />
5+
<title>Browser Dialer</title>
6+
<script type="module">
7+
8+
// 2025 (C) Team Cloudchaser
9+
// Licensed under MIT License
10+
11+
"use strict";
12+
13+
import AppatDialer from "../dialer.mjs";
14+
15+
let pagePrefix;
16+
if (self.location?.href) {
17+
pagePrefix = location.origin;
18+
} else if (self.Deno?.args[0]?.length > 0) {
19+
pagePrefix = `http://${self.Deno.args[0]}`;
20+
} else {
21+
// Port 5779 should never be used for browser dialer controllers
22+
pagePrefix = `http://127.0.0.1:5779`;
23+
};
24+
console.debug(`Received dialer prefix: ${pagePrefix}`);
25+
26+
const nullCSRF = atob("X19DU1JGX1RPS0VOX18");
27+
let pageCSRF = "__CSRF_TOKEN__"; // Replaced with a valid token dynamically
28+
if (pageCSRF === nullCSRF) {
29+
// The CSRF token must be a valid UUID
30+
if (self.location?.search?.indexOf("?token=") === 0) {
31+
// Only a single query parameter is expected
32+
pageCSRF = self.location.search.substring(7);
33+
} else if (self.Deno?.args[1]?.length > 0) {
34+
pageCSRF = self.Deno.args[1];
35+
} else {
36+
pageCSRF = "00000000-0000-0000-0000-000000000000";
37+
};
38+
};
39+
console.debug(`Received CSRF token: ${pageCSRF}`);
40+
41+
let dialer = new AppatDialer(pagePrefix, pageCSRF);
42+
dialer.start();
43+
44+
</script>
45+
</head>
46+
<body>
47+
</body>

transport/internet/browser_dialer/dialer/index.mjs renamed to transport/internet/browser_dialer/dialer.mjs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ const denoClient = self.Deno?.createHttpClient({
2222
"allowHost": true
2323
});
2424

25-
export default class AppatController {
25+
export default class AppatDialer {
2626
report = true; // Set to false to disable response status reporting
2727
instanceId;
2828
#wsNext = true; // Set to true to trigger WS fallback
@@ -123,7 +123,7 @@ export default class AppatController {
123123
opt.referrerPolicy = "unsafe-url";
124124
// Would this change when web safety gets disabled?
125125
let rUrl = new URL(data.e.r);
126-
opt.referrer = data.e.r.replace(`${rUrl.protocol}//${rUrl.hostname}`);
126+
opt.referrer = data.e.r.replace(`${rUrl.protocol}//${rUrl.hostname}`, "");
127127
};
128128
if (data.e.hasOwnProperty("h")) {
129129
opt.headers = data.e.h;
@@ -157,6 +157,7 @@ export default class AppatController {
157157
"pull": async (controller) => {
158158
if (upThis.#uploadDeny.has(data.c)) {
159159
upThis.#uploader.get(data.c)[2]();
160+
upThis.#uploadDeny.delete(data.c);
160161
} else if (upThis.#uploader.has(data.c)) {
161162
// Only pipe when still active
162163
let {value, done} = await sourceReader.read();
@@ -165,6 +166,7 @@ export default class AppatController {
165166
};
166167
if (done || upThis.#uploadDeny.has(data.c)) {
167168
upThis.#uploader.get(data.c)[2]();
169+
upThis.#uploadDeny.delete(data.c);
168170
};
169171
};
170172
}

0 commit comments

Comments
 (0)