tickcli-js 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/README.md +12 -2
- package/dist/hub.d.ts +12 -1
- package/dist/hub.js +42 -6
- package/dist/hub.js.map +1 -1
- package/dist/node.d.ts +11 -0
- package/dist/node.js +10 -1
- package/dist/node.js.map +1 -1
- package/dist/remote.d.ts +6 -0
- package/dist/remote.js +47 -9
- package/dist/remote.js.map +1 -1
- package/dist/serve.js +7 -4
- package/dist/serve.js.map +1 -1
- package/package.json +3 -3
- package/src/hub.ts +35 -4
- package/src/node.ts +14 -1
- package/src/remote.ts +38 -9
- package/src/serve.ts +6 -4
package/dist/remote.js
CHANGED
|
@@ -18,9 +18,13 @@ import http from "node:http";
|
|
|
18
18
|
import crypto from "node:crypto";
|
|
19
19
|
import { fileURLToPath } from "node:url";
|
|
20
20
|
import { WebSocketServer } from "ws";
|
|
21
|
-
import { CLOSE, RoomHub } from "./hub.js";
|
|
22
|
-
import { GuestPasses, Heartbeat, WS_OPTIONS, attach, clientAddress, fileSaves, gameHash } from "./node.js";
|
|
21
|
+
import { CLOSE, RoomHub, addressKey } from "./hub.js";
|
|
22
|
+
import { GuestPasses, Heartbeat, WS_OPTIONS, attach, clientAddress, fileSaves, gameHash, hardenServer } from "./node.js";
|
|
23
23
|
const ID_RE = /^[A-Za-z0-9_-]{3,64}$/;
|
|
24
|
+
/** A deployment (found or not) is asked for again after this long; call forget(id) to make an edit count at once. */
|
|
25
|
+
export const LOOKUP_MS = 15_000;
|
|
26
|
+
/** Fresh lookups one client address (IPv6: /64) may cause per 10 s. */
|
|
27
|
+
export const LOOKUPS_PER_ADDRESS = 20;
|
|
24
28
|
const GAME_RE = /^[A-Za-z0-9_-]{1,60}$/;
|
|
25
29
|
const VER_RE = /^[A-Za-z0-9._-]{1,40}$/;
|
|
26
30
|
const KEY_RE = /^[A-Za-z0-9_-]{22,64}$/;
|
|
@@ -95,9 +99,33 @@ export function createRemote(o) {
|
|
|
95
99
|
const sources = { relay: src("relay"), room: src("room"), game: src("game") };
|
|
96
100
|
const files = { relay: sources.relay, room: sources.room, game: sources.game, game3d: src("game3d") };
|
|
97
101
|
const scope = (id) => `dep:${id}`;
|
|
98
|
-
|
|
102
|
+
// Deployments are looked up at most once per LOOKUP_MS per id (found or not), and an address may cause at most LOOKUPS_PER_ADDRESS fresh lookups
|
|
103
|
+
// per 10 s: a flood of sockets or boot scripts with random ids costs a map hit, not a query on your table per request.
|
|
104
|
+
const seen = new Map(); // id -> when it was last looked up
|
|
105
|
+
const misses = new Map();
|
|
106
|
+
const lookupAllowed = (addr) => {
|
|
107
|
+
const k = addressKey(addr), now = Date.now();
|
|
108
|
+
let w = misses.get(k);
|
|
109
|
+
if (!w || now - w.at >= 10_000) {
|
|
110
|
+
if (misses.size >= 50_000)
|
|
111
|
+
for (const [x, v] of misses)
|
|
112
|
+
if (now - v.at >= 10_000)
|
|
113
|
+
misses.delete(x);
|
|
114
|
+
if (misses.size >= 50_000)
|
|
115
|
+
return false;
|
|
116
|
+
w = { at: now, n: 0 };
|
|
117
|
+
misses.set(k, w);
|
|
118
|
+
}
|
|
119
|
+
return ++w.n <= LOOKUPS_PER_ADDRESS;
|
|
120
|
+
};
|
|
121
|
+
const lookup = async (id, addr) => {
|
|
99
122
|
if (!ID_RE.test(id))
|
|
100
123
|
return null;
|
|
124
|
+
const at = seen.get(id);
|
|
125
|
+
if (at !== undefined && Date.now() - at < LOOKUP_MS)
|
|
126
|
+
return cache.get(id) ?? null;
|
|
127
|
+
if (!lookupAllowed(addr))
|
|
128
|
+
return cache.get(id) ?? null;
|
|
101
129
|
let dep = null;
|
|
102
130
|
try {
|
|
103
131
|
dep = await o.deployment(id);
|
|
@@ -105,19 +133,24 @@ export function createRemote(o) {
|
|
|
105
133
|
catch {
|
|
106
134
|
dep = null;
|
|
107
135
|
}
|
|
136
|
+
if (seen.size >= 100_000)
|
|
137
|
+
seen.clear();
|
|
138
|
+
seen.set(id, Date.now());
|
|
108
139
|
if (dep && dep.id === id)
|
|
109
140
|
cache.set(id, dep);
|
|
110
141
|
else
|
|
111
142
|
cache.delete(id);
|
|
112
143
|
return dep && dep.id === id ? dep : null;
|
|
113
144
|
};
|
|
145
|
+
const addrOf = (req) => (o.address ? o.address(req) : req.socket.remoteAddress || "?");
|
|
114
146
|
// refused sockets are still accepted, then closed with a code the page shows (4001 is final: the page stops trying; 1013 busy: it retries)
|
|
115
147
|
const closeWith = (req, socket, head, code, reason) => wss.handleUpgrade(req, socket, head, (ws) => ws.close(code, reason));
|
|
116
148
|
return {
|
|
117
149
|
scope,
|
|
118
150
|
sockets: (id) => live.get(id) || 0,
|
|
119
151
|
roomsPerScope: (sc) => (sc.startsWith("dep:") ? cache.get(sc.slice(4))?.caps?.rooms : undefined),
|
|
120
|
-
revoke(id) { cache.delete(id); o.hub.closeScope(scope(id), "this game was turned off by its owner"); },
|
|
152
|
+
revoke(id) { cache.delete(id); seen.delete(id); o.hub.closeScope(scope(id), "this game was turned off by its owner"); },
|
|
153
|
+
forget(id) { cache.delete(id); seen.delete(id); },
|
|
121
154
|
upgrade(req, socket, head) {
|
|
122
155
|
const url = new URL(req.url || "/", "http://localhost");
|
|
123
156
|
if (url.pathname !== path)
|
|
@@ -133,7 +166,12 @@ export function createRemote(o) {
|
|
|
133
166
|
return true;
|
|
134
167
|
}
|
|
135
168
|
socket.on("error", () => { });
|
|
136
|
-
|
|
169
|
+
const addr = addrOf(req);
|
|
170
|
+
if (!o.hub.allowAddress(addr)) {
|
|
171
|
+
closeWith(req, socket, head, CLOSE.busy, "too many new connections, try again");
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
174
|
+
void lookup(id, addr).then((dep) => {
|
|
137
175
|
if (socket.destroyed)
|
|
138
176
|
return;
|
|
139
177
|
if (!dep || dep.revoked)
|
|
@@ -152,7 +190,7 @@ export function createRemote(o) {
|
|
|
152
190
|
else
|
|
153
191
|
live.delete(id); });
|
|
154
192
|
attach(ws, {
|
|
155
|
-
hub: o.hub, heartbeat: o.heartbeat, address:
|
|
193
|
+
hub: o.hub, heartbeat: o.heartbeat, address: addr, counted: true,
|
|
156
194
|
// the guest key is the page's own random 128-bit value: unguessable, so nobody can take another player's seat; it names a seat in
|
|
157
195
|
// this deployment only (the hub shows others a short HMAC of it, never the key)
|
|
158
196
|
authenticate: (ticket) => typeof ticket === "string" && KEY_RE.test(ticket)
|
|
@@ -179,7 +217,7 @@ export function createRemote(o) {
|
|
|
179
217
|
const b = /^\/c\/([^/]+)\.js$/.exec(url.pathname);
|
|
180
218
|
if (!b)
|
|
181
219
|
return false;
|
|
182
|
-
void lookup(b[1]).then((dep) => {
|
|
220
|
+
void lookup(b[1], addrOf(req)).then((dep) => {
|
|
183
221
|
if (!dep || dep.revoked)
|
|
184
222
|
return js(404, `console.error(${JSON.stringify(`tickcli: no deployment ${b[1].slice(0, 64)} (unknown or turned off)`)});`);
|
|
185
223
|
js(200, bootScript(dep.id, sources), "public, max-age=300");
|
|
@@ -196,12 +234,12 @@ export function createRemoteServer(o) {
|
|
|
196
234
|
hub.start();
|
|
197
235
|
const heartbeat = new Heartbeat();
|
|
198
236
|
remote = createRemote({ hub, deployment: o.deployment, heartbeat, address: o.address ?? (o.trustProxy ? (req) => clientAddress(req, true) : undefined) });
|
|
199
|
-
const server = http.createServer((req, res) => {
|
|
237
|
+
const server = hardenServer(http.createServer((req, res) => {
|
|
200
238
|
if (remote.request(req, res))
|
|
201
239
|
return;
|
|
202
240
|
res.writeHead(404, { "Content-Type": "text/plain" });
|
|
203
241
|
res.end("not found");
|
|
204
|
-
});
|
|
242
|
+
}));
|
|
205
243
|
server.on("upgrade", (req, socket, head) => { if (!remote.upgrade(req, socket, head))
|
|
206
244
|
socket.destroy(); });
|
|
207
245
|
const listen = (port = 8080, host) => new Promise((resolve, reject) => {
|
package/dist/remote.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remote.js","sourceRoot":"","sources":["../src/remote.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"remote.js","sourceRoot":"","sources":["../src/remote.ts"],"names":[],"mappings":"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"}
|
package/dist/serve.js
CHANGED
|
@@ -18,7 +18,7 @@ import { createRequire } from "node:module";
|
|
|
18
18
|
import { fileURLToPath } from "node:url";
|
|
19
19
|
import { WebSocketServer } from "ws";
|
|
20
20
|
import { RoomHub } from "./hub.js";
|
|
21
|
-
import { GuestPasses, Heartbeat, WS_OPTIONS, attach, clientAddress, fileSaves, gameHash, sameSite } from "./node.js";
|
|
21
|
+
import { GuestPasses, Heartbeat, WS_OPTIONS, attach, clientAddress, fileSaves, gameHash, hardenServer, sameSite } from "./node.js";
|
|
22
22
|
const CLIENT = fileURLToPath(new URL("../client/", import.meta.url));
|
|
23
23
|
const PASS = "cw_pass";
|
|
24
24
|
const SCOPE = "play";
|
|
@@ -171,7 +171,7 @@ export function createGameServer(o = {}) {
|
|
|
171
171
|
return got;
|
|
172
172
|
};
|
|
173
173
|
const title = o.title ?? "tickcli games";
|
|
174
|
-
const server = http.createServer((req, res) => {
|
|
174
|
+
const server = hardenServer(http.createServer((req, res) => {
|
|
175
175
|
const url = new URL(req.url || "/", "http://localhost");
|
|
176
176
|
const send = (code, type, body, headers = {}) => { res.writeHead(code, { "Content-Type": type, "Cache-Control": "no-store", "X-Content-Type-Options": "nosniff", ...headers }); res.end(body); };
|
|
177
177
|
if (req.method !== "GET" && req.method !== "HEAD")
|
|
@@ -199,12 +199,15 @@ export function createGameServer(o = {}) {
|
|
|
199
199
|
if (!passes.check(SCOPE, cookie(req, PASS)))
|
|
200
200
|
headers["Set-Cookie"] = GuestPasses.cookie(PASS, passes.issue(SCOPE), "/", !!o.secure);
|
|
201
201
|
return send(200, "text/html; charset=utf-8", playPage(html, g[1]), headers);
|
|
202
|
-
});
|
|
202
|
+
}));
|
|
203
203
|
server.on("upgrade", (req, socket, head) => {
|
|
204
204
|
const url = new URL(req.url || "/", "http://localhost");
|
|
205
205
|
const refuse = (code) => { socket.end(`HTTP/1.1 ${code} ${http.STATUS_CODES[code]}\r\nConnection: close\r\nContent-Length: 0\r\n\r\n`); };
|
|
206
206
|
if (url.pathname !== "/room")
|
|
207
207
|
return refuse(404);
|
|
208
|
+
const address = clientAddress(req, !!o.trustProxy);
|
|
209
|
+
if (!hub.allowAddress(address))
|
|
210
|
+
return refuse(429);
|
|
208
211
|
if (!sameSite((n) => req.headers[n]))
|
|
209
212
|
return refuse(403);
|
|
210
213
|
const pass = passes.check(SCOPE, cookie(req, PASS));
|
|
@@ -215,7 +218,7 @@ export function createGameServer(o = {}) {
|
|
|
215
218
|
if (!game)
|
|
216
219
|
return refuse(404);
|
|
217
220
|
const identity = { scope: `${SCOPE}:${name}`, game: game.hash, slot: name, who: { seat: `g:${pass}`, name: GuestPasses.defaultName(pass), guest: true } };
|
|
218
|
-
wss.handleUpgrade(req, socket, head, (ws) => attach(ws, { hub, heartbeat, address:
|
|
221
|
+
wss.handleUpgrade(req, socket, head, (ws) => attach(ws, { hub, heartbeat, address, counted: true, identity }));
|
|
219
222
|
});
|
|
220
223
|
const listen = (port = 8080, host) => new Promise((resolve, reject) => {
|
|
221
224
|
server.once("error", reject);
|
package/dist/serve.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serve.js","sourceRoot":"","sources":["../src/serve.ts"],"names":[],"mappings":"AAAA,4IAA4I;AAC5I,8GAA8G;AAC9G,EAAE;AACF,yDAAyD;AACzD,0EAA0E;AAC1E,iFAAiF;AACjF,EAAE;AACF,iJAAiJ;AACjJ,8IAA8I;AAC9I,2FAA2F;AAC3F,oIAAoI;AACpI,0IAA0I;AAC1I,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,IAAI,CAAC;AACrC,OAAO,EAAE,OAAO,EAA8B,MAAM,UAAU,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AA6BrH,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,YAAY,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AACrE,MAAM,IAAI,GAAG,SAAS,CAAC;AACvB,MAAM,KAAK,GAAG,MAAM,CAAC;AACrB,MAAM,OAAO,GAAG,qBAAqB,CAAC;AACtC,0EAA0E;AAC1E,MAAM,OAAO,GAAG,2HAA2H,CAAC;AAC5I;6FAC6F;AAC7F,MAAM,OAAO,GAAqD;IAChE,KAAK,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE;IAClC,MAAM,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,oBAAoB,CAAC,EAAE;IACxD,gIAAgI;IAChI,IAAI,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,kBAAkB,EAAE,kCAAkC,CAAC,EAAE;CAC1F,CAAC;AACF,MAAM,UAAU,GAAG,2EAA2E,CAAC;AAC/F,uGAAuG;AACvG,SAAS,MAAM,CAAC,IAAY;IAC1B,KAAK,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC;QACvE,IAAI,IAAY,CAAC;QACjB,IAAI,CAAC;YAAC,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC;YAAC,SAAS;QAAC,CAAC;QACrE,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;YAC5E,IAAI,CAAC;gBAAC,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI;oBAAE,OAAO,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,qBAAqB,CAAC,CAAC;QACxI,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AACD,sHAAsH;AACtH,MAAM,WAAW,GAAG,IAAI,GAAG,EAAyB,CAAC;AACrD,SAAS,YAAY,CAAC,IAAY;IAChC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3B,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACxD,IAAI,GAAG,GAAkB,IAAI,CAAC;QAC9B,IAAI,GAAG;YAAE,GAAG,GAAG,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;gBACpE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,+BAA+B,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC9L,WAAW,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAC7B,CAAC;IACD,OAAO,WAAW,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC;AAChC,CAAC;AACD,gFAAgF;AAChF,SAAS,KAAK,CAAC,IAAY;IACzB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,MAAM,CAAC,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC1J,CAAC;AACD;sJACsJ;AACtJ,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,MAAM,IAAI,GAAG,CAAC,CAAS,EAAE,EAAE,GAAG,IAAI,CAAC;QAAC,OAAO,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,IAAI,CAAC;IAAC,CAAC,CAAC,CAAC,CAAC;IAClH,IAAI,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC,iBAAiB,CAAC,CAAC;IAChE,IAAI,IAAI,KAAK,IAAI,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAC/C,MAAM,IAAI,GAAG,iCAAiC,CAAC;IAC/C,MAAM,OAAO,GAAG,IAAI,MAAM,CAAC,iCAAiC,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9E,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACpC,MAAM,GAAG,GAAG,IAAI,MAAM,CAAC,8BAA8B,IAAI,YAAY,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACtF,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,8BAA8B,IAAI,YAAY,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACxF,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IAChC,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACpD,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,iCAAiC,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC5E,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACjC,IAAI,wBAAwB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,wBAAwB,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,gCAAgC,CAAC,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAChJ,MAAM,GAAG,GAAG,CAAC,KAAyB,EAAE,IAA+B,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClJ,OAAO,8HAA8H;QACnI,2EAA2E,IAAI,eAAe,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe;QAC7I,+BAA+B,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,GAAG,IAAI;QAC5H,2BAA2B,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,uBAAuB,CAAC;AACvJ,CAAC;AAED;yHACyH;AACzH,MAAM,SAAS,GAAG,CAAC,GAAyB,EAAE,EAAE;IAC9C,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IACzC,OAAO,iCAAiC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,oCAAoC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AAClI,CAAC,CAAC;AACF,MAAM,GAAG,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;AAChF,MAAM,MAAM,GAAG,CAAC,GAAyB,EAAE,IAAY,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAE7J,2HAA2H;AAC3H,MAAM,UAAU,QAAQ,CAAC,IAAY,EAAE,IAAY,EAAE,QAAQ,GAAG,OAAO;IACrE,MAAM,IAAI,GAAG,0HAA0H;QACrI,yOAAyO;QACzO,kDAAkD,IAAI,CAAC,SAAS,CAAC,GAAG,QAAQ,SAAS,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC,gBAAgB,CAAC;IACnI,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,EAAE,EAAE,CAAS,EAAE,EAAE,CAAC,wBAAwB,CAAC,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAS,EAAE,EAAE,CAAC,wBAAwB,CAAC,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC;IAC9M,IAAI,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,GAAG,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAClF,0EAA0E;IAC1E,OAAO,sBAAsB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,sBAAsB,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,GAAG,CAAC;AAC9G,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAuB,EAAE;IACxD,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IACvF,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,CAAC,CAAC;IAC3C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,KAAK,EAAE,CAAC,CAAC;IACxH,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IACvF,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IAC3F,GAAG,CAAC,KAAK,EAAE,CAAC;IACZ,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,MAAM,CAAC,CAAC;IACvC,MAAM,SAAS,GAAG,IAAI,SAAS,EAAE,CAAC;IAClC,MAAM,GAAG,GAAG,IAAI,eAAe,CAAC,EAAE,GAAG,UAAU,EAAE,CAAC,CAAC;IACnD,yIAAyI;IACzI,sGAAsG;IACtG,MAAM,KAAK,GAAG,IAAI,GAAG,EAAsD,CAAC;IAC5E,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,EAAE;QAC5B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QACrC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACpC,IAAI,EAAY,CAAC;QACjB,IAAI,CAAC;YAAC,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC;YAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAAC,OAAO,IAAI,CAAC;QAAC,CAAC;QAC1E,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE;YAAE,OAAO,IAAI,CAAC;QAC9B,MAAM,EAAE,GAAG,GAAG,EAAE,CAAC,OAAO,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;QACtC,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC5B,IAAI,GAAG,IAAI,GAAG,CAAC,EAAE,KAAK,EAAE;YAAE,OAAO,GAAG,CAAC;QACrC,MAAM,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC3C,MAAM,GAAG,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/C,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QACrB,OAAO,GAAG,CAAC;IACb,CAAC,CAAC;IACF,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,IAAI,eAAe,CAAC;IAEzC,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QAC5C,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,EAAE,kBAAkB,CAAC,CAAC;QACxD,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,IAAY,EAAE,IAAY,EAAE,UAAkC,EAAE,EAAE,EAAE,GAAG,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE,eAAe,EAAE,UAAU,EAAE,wBAAwB,EAAE,SAAS,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QACjP,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM;YAAE,OAAO,IAAI,CAAC,GAAG,EAAE,YAAY,EAAE,oBAAoB,CAAC,CAAC;QACxG,IAAI,GAAG,CAAC,QAAQ,KAAK,GAAG,EAAE,CAAC;YACzB,MAAM,IAAI,GAAG,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,sBAAsB,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACnK,OAAO,IAAI,CAAC,GAAG,EAAE,0BAA0B,EAAE,kHAAkH,GAAG,CAAC,KAAK,CAAC,eAAe,GAAG,CAAC,KAAK,CAAC,YAAY,IAAI,IAAI,6CAA6C,6EAA6E,CAAC,CAAC;QACpV,CAAC;QACD,MAAM,CAAC,GAAG,0CAA0C,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACxE,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC,GAAG,EAAE,gCAAgC,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;QACpH,MAAM,CAAC,GAAG,qCAAqC,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACnE,IAAI,CAAC,EAAE,CAAC;YACN,MAAM,GAAG,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC/B,IAAI,CAAC,GAAG;gBAAE,OAAO,IAAI,CAAC,GAAG,EAAE,gCAAgC,EAAE,iBAAiB,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,6CAA6C,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;YAC/K,OAAO,IAAI,CAAC,GAAG,EAAE,gCAAgC,EAAE,GAAG,EAAE,EAAE,eAAe,EAAE,sBAAsB,EAAE,CAAC,CAAC;QACvG,CAAC;QACD,MAAM,CAAC,GAAG,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACjD,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;QACzC,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAC,GAAG,EAAE,YAAY,EAAE,WAAW,CAAC,CAAC;QACvD,qHAAqH;QACrH,MAAM,OAAO,GAA2B,EAAE,yBAAyB,EAAE,4HAA4H,SAAS,CAAC,GAAG,CAAC,0BAA0B,EAAE,CAAC;QAC5O,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YAAE,OAAO,CAAC,YAAY,CAAC,GAAG,WAAW,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QACpI,OAAO,IAAI,CAAC,GAAG,EAAE,0BAA0B,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAE,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IAC/E,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE;QACzC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,EAAE,kBAAkB,CAAC,CAAC;QACxD,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,YAAY,IAAI,IAAI,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,oDAAoD,CAAC,CAAC,CAAC,CAAC,CAAC;QAClJ,IAAI,GAAG,CAAC,QAAQ,KAAK,OAAO;YAAE,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;QACjD,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAuB,CAAC;YAAE,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;QAC/E,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;QACpD,IAAI,CAAC,IAAI;YAAE,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;QAC9B,MAAM,IAAI,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QAChD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI;YAAE,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;QAC9B,MAAM,QAAQ,GAAG,EAAE,KAAK,EAAE,GAAG,KAAK,IAAI,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,KAAK,IAAI,EAAE,EAAE,IAAI,EAAE,WAAW,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC;QAC1J,GAAG,CAAC,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,OAAO,EAAE,aAAa,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;IACtI,CAAC,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,CAAC,IAAI,GAAG,IAAI,EAAE,IAAa,EAAE,EAAE,CAAC,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrF,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC7B,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE;YAC7B,MAAM,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;YAC3B,MAAM,CAAC,GAAG,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;YACrD,OAAO,CAAC,UAAU,CAAC,IAAI,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;QAC/F,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IACH,MAAM,KAAK,GAAG,KAAK,IAAI,EAAE,GAAG,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC;IACtH,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AACxC,CAAC"}
|
|
1
|
+
{"version":3,"file":"serve.js","sourceRoot":"","sources":["../src/serve.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tickcli-js",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Live rooms for browser games: one player's browser runs the rules, a small Node hub keeps the shared state, membership and order. No game code on the server.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
},
|
|
73
73
|
"peerDependencies": {
|
|
74
74
|
"three": ">=0.171.0",
|
|
75
|
-
"ws": "^8.
|
|
75
|
+
"ws": "^8.23.0",
|
|
76
76
|
"phaser": ">=4.0.0",
|
|
77
77
|
"pixi.js": ">=8.0.0"
|
|
78
78
|
},
|
|
@@ -98,6 +98,6 @@
|
|
|
98
98
|
"playwright": "1.64.0",
|
|
99
99
|
"three": "0.186.1",
|
|
100
100
|
"typescript": "5.9.3",
|
|
101
|
-
"ws": "8.
|
|
101
|
+
"ws": "8.23.0"
|
|
102
102
|
}
|
|
103
103
|
}
|
package/src/hub.ts
CHANGED
|
@@ -27,7 +27,8 @@ export interface Limits {
|
|
|
27
27
|
maxRoomsPerScope: number; // per namespace (scope)
|
|
28
28
|
maxConnections: number; // whole server, signed in or not
|
|
29
29
|
maxPending: number; // whole server: sockets that have not proven who they are yet
|
|
30
|
-
maxPerAddress: number; // open sockets per client address
|
|
30
|
+
maxPerAddress: number; // open sockets per client address (an IPv6 address counts by its /64: one home or server gets a whole /64)
|
|
31
|
+
connectsPerAddress: number; // new sockets per client address (IPv6: /64) per 10 s; over it: 1013 busy, before the server-wide acceptRate is spent
|
|
31
32
|
joinsPerMinute: number; // per client address
|
|
32
33
|
messageBytes: number; // one message
|
|
33
34
|
playerStateBytes: number; // one player's state, as JSON
|
|
@@ -62,12 +63,23 @@ export interface Limits {
|
|
|
62
63
|
}
|
|
63
64
|
|
|
64
65
|
export const DEFAULT_LIMITS: Limits = {
|
|
65
|
-
maxPlayers: 16, maxRooms: 500, maxRoomsPerScope: 50, maxConnections: 2000, maxPending: 200, maxPerAddress: 20, joinsPerMinute: 30,
|
|
66
|
+
maxPlayers: 16, maxRooms: 500, maxRoomsPerScope: 50, maxConnections: 2000, maxPending: 200, maxPerAddress: 20, connectsPerAddress: 40, joinsPerMinute: 30,
|
|
66
67
|
messageBytes: 16 * 1024, playerStateBytes: 2048, sharedStateBytes: 64 * 1024, stateRate: 50, sharedRate: 20, actionRate: 5, timeRate: 2,
|
|
67
68
|
pendingMs: 5000, seatHoldMs: 30_000, evictAfterMs: 10_000, awayHoldMs: 300_000, hostSilenceMs: 5000, silentMs: 15_000, acceptRate: 200, roomOutBytes: 250 * 1024, maxOutMbit: 100, actionTimeoutMs: 5000, slowBytes: 64 * 1024, dropBytes: 256 * 1024, rateBytes: 16 * 1024, rateUpMs: 10_000, listRate: 1, idleMs: 15 * 60_000, idleWarnMs: 60_000, listIdleMs: 5 * 60_000, tickMs: 50,
|
|
68
69
|
profileBytes: 16 * 1024, profileEveryMs: 3000, worldEveryMs: 5000, saveDays: 90,
|
|
69
70
|
};
|
|
70
71
|
|
|
72
|
+
/** The key one client is counted by: an IPv4 address as is, an IPv6 address by its first 64 bits (a home, phone or server is handed a whole /64,
|
|
73
|
+
* so per-address limits on full IPv6 addresses would not hold anyone). IPv4-mapped IPv6 counts as the IPv4 address. */
|
|
74
|
+
export function addressKey(addr: string): string {
|
|
75
|
+
const a = String(addr || "?").toLowerCase().replace(/^::ffff:(?=\d+\.)/, "").replace(/%.*$/, "");
|
|
76
|
+
if (!a.includes(":")) return a;
|
|
77
|
+
const [head, tail = ""] = a.split("::");
|
|
78
|
+
const h = head ? head.split(":") : [], t = tail ? tail.split(":") : [];
|
|
79
|
+
const groups = a.includes("::") ? [...h, ...Array(Math.max(0, 8 - h.length - t.length)).fill("0"), ...t] : h;
|
|
80
|
+
return `${groups.slice(0, 4).map((g) => (g || "0").replace(/^0+(?=.)/, "")).join(":")}::/64`;
|
|
81
|
+
}
|
|
82
|
+
|
|
71
83
|
/** One open socket, as the hub sees it. */
|
|
72
84
|
export interface Conn {
|
|
73
85
|
send(data: string): void;
|
|
@@ -486,6 +498,7 @@ export class RoomHub {
|
|
|
486
498
|
private sessions = new Set<Session>();
|
|
487
499
|
pending = 0;
|
|
488
500
|
private perAddr = new Map<string, number>();
|
|
501
|
+
private addrHits = new Map<string, { at: number; n: number }>();
|
|
489
502
|
private joins = new Map<string, number[]>();
|
|
490
503
|
private refused: Record<string, number> = {};
|
|
491
504
|
private timer: ReturnType<typeof setInterval> | null = null;
|
|
@@ -551,16 +564,20 @@ export class RoomHub {
|
|
|
551
564
|
private count(what: string, n = 1) { this.counts[what] = (this.counts[what] || 0) + n; }
|
|
552
565
|
|
|
553
566
|
/** A new socket. Null = refused (the caller closes it with the code given). */
|
|
554
|
-
|
|
567
|
+
/** `counted`: the adapter already spent this socket's allowAddress before its upgrade, so it is not counted twice. */
|
|
568
|
+
connect(conn: Conn, address: string, o: { counted?: boolean } = {}): Session | { refused: number; reason: string } {
|
|
555
569
|
const L = this.limits;
|
|
570
|
+
const addr = addressKey(address);
|
|
556
571
|
if (this.closing) return { refused: CLOSE.restart, reason: "server restarting" };
|
|
557
572
|
if (this.sessions.size >= L.maxConnections) { this.refuse("connections"); return { refused: CLOSE.full, reason: "server is full" }; }
|
|
573
|
+
// one address first: a single client flooding new sockets is cut here and never spends the server-wide budgets below that everyone shares
|
|
574
|
+
if ((this.perAddr.get(addr) || 0) >= L.maxPerAddress) { this.refuse("address"); return { refused: CLOSE.tooFast, reason: "too many connections" }; }
|
|
575
|
+
if (!o.counted && !this.allowAddress(addr)) { this.refuse("address_rate"); return { refused: CLOSE.busy, reason: "too many new connections, try again" }; }
|
|
558
576
|
// busy (not full): the page tries again with its normal backoff, so a reconnect wave after a restart spreads out instead of ending on a "full" screen
|
|
559
577
|
if (this.pending >= L.maxPending) { this.refuse("pending"); return { refused: CLOSE.busy, reason: "server is busy, try again" }; }
|
|
560
578
|
const now = this.now();
|
|
561
579
|
if (now - this.acceptAt >= 1000) { this.acceptAt = now; this.accepted = 0; }
|
|
562
580
|
if (++this.accepted > L.acceptRate) { this.refuse("accept_rate"); return { refused: CLOSE.busy, reason: "server is busy, try again" }; }
|
|
563
|
-
if ((this.perAddr.get(addr) || 0) >= L.maxPerAddress) { this.refuse("address"); return { refused: CLOSE.tooFast, reason: "too many connections" }; }
|
|
564
581
|
const s = new Session(this, conn, addr);
|
|
565
582
|
this.sessions.add(s);
|
|
566
583
|
this.pending++;
|
|
@@ -568,6 +585,20 @@ export class RoomHub {
|
|
|
568
585
|
return s;
|
|
569
586
|
}
|
|
570
587
|
|
|
588
|
+
/** New-socket budget of one address (addressKey), connectsPerAddress per 10 s. Adapters may call it before costly work on an upgrade (a lookup):
|
|
589
|
+
* false = refuse now. The window map is pruned when it grows, so random addresses cannot grow it without end. */
|
|
590
|
+
allowAddress(address: string): boolean {
|
|
591
|
+
const key = addressKey(address), now = this.now();
|
|
592
|
+
let w = this.addrHits.get(key);
|
|
593
|
+
if (!w || now - w.at >= 10_000) {
|
|
594
|
+
if (this.addrHits.size >= 50_000) for (const [k, v] of this.addrHits) if (now - v.at >= 10_000) this.addrHits.delete(k);
|
|
595
|
+
if (this.addrHits.size >= 50_000) return false; // 50,000 addresses inside 10 s: refuse newcomers until the window turns
|
|
596
|
+
w = { at: now, n: 0 };
|
|
597
|
+
this.addrHits.set(key, w);
|
|
598
|
+
}
|
|
599
|
+
return ++w.n <= this.limits.connectsPerAddress;
|
|
600
|
+
}
|
|
601
|
+
|
|
571
602
|
/** Meter: `n` copies of a text of `len` bytes (UTF-8, as on the wire) went out (to one room's sockets when given). */
|
|
572
603
|
sent(len: number, n: number, room?: Room | null) {
|
|
573
604
|
this.meter.framesOut += n; this.meter.bytesOut += len * n;
|
package/src/node.ts
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
// passes - for anonymous visitors: the app sets a pass cookie (HttpOnly, SameSite=Strict, scoped to one path) and checks it at the upgrade.
|
|
8
8
|
// Plus: the Origin header must be present and name the site itself (sameSite()).
|
|
9
9
|
import crypto from "node:crypto";
|
|
10
|
+
import type http from "node:http";
|
|
10
11
|
import type { WebSocket } from "ws";
|
|
11
12
|
import fs from "node:fs";
|
|
12
13
|
import path from "node:path";
|
|
@@ -141,6 +142,8 @@ export interface Identity {
|
|
|
141
142
|
|
|
142
143
|
export interface SocketOptions {
|
|
143
144
|
hub: RoomHub;
|
|
145
|
+
/** true when the upgrade handler already called hub.allowAddress for this socket */
|
|
146
|
+
counted?: boolean;
|
|
144
147
|
heartbeat?: Heartbeat;
|
|
145
148
|
/** client address, for the per-address caps (after your trusted-proxy rule) */
|
|
146
149
|
address: string;
|
|
@@ -162,7 +165,7 @@ export function socketEvents(o: SocketOptions) {
|
|
|
162
165
|
open(ws: WebSocket) {
|
|
163
166
|
raw = ws;
|
|
164
167
|
o.heartbeat?.add(ws);
|
|
165
|
-
const r = o.hub.connect(connOf(ws), o.address);
|
|
168
|
+
const r = o.hub.connect(connOf(ws), o.address, { counted: o.counted });
|
|
166
169
|
if ("refused" in r) { ws.close(r.refused, r.reason); return; }
|
|
167
170
|
session = r;
|
|
168
171
|
if (o.identity) session.identify(o.identity.scope, o.identity.game, o.identity.who, o.identity.slot);
|
|
@@ -201,6 +204,16 @@ export function attach(ws: WebSocket, o: SocketOptions) {
|
|
|
201
204
|
ws.on("error", () => { /* close follows */ });
|
|
202
205
|
}
|
|
203
206
|
|
|
207
|
+
/** Tighter HTTP timeouts than Node's defaults (headers 60 s, whole request 300 s, 2000 headers) for a server that only serves small pages and
|
|
208
|
+
* socket upgrades: a client that sends its request headers slowly (slowloris) is cut after `headersMs`, an idle keep-alive after 5 s. */
|
|
209
|
+
export function hardenServer<S extends http.Server>(server: S, o: { headersMs?: number; requestMs?: number; keepAliveMs?: number; maxHeaders?: number } = {}): S {
|
|
210
|
+
server.headersTimeout = o.headersMs ?? 10_000;
|
|
211
|
+
server.requestTimeout = o.requestMs ?? 15_000;
|
|
212
|
+
server.keepAliveTimeout = o.keepAliveMs ?? 5_000;
|
|
213
|
+
server.maxHeadersCount = o.maxHeaders ?? 100;
|
|
214
|
+
return server;
|
|
215
|
+
}
|
|
216
|
+
|
|
204
217
|
/** Options for a ws WebSocketServer that fit the hub: no own size default of 100 MiB, no compression, no client list (the hub tracks sockets). */
|
|
205
218
|
export const WS_OPTIONS = { noServer: true, maxPayload: 16 * 1024, perMessageDeflate: false, clientTracking: false } as const;
|
|
206
219
|
|
package/src/remote.ts
CHANGED
|
@@ -19,8 +19,8 @@ import crypto from "node:crypto";
|
|
|
19
19
|
import type { Duplex } from "node:stream";
|
|
20
20
|
import { fileURLToPath } from "node:url";
|
|
21
21
|
import { WebSocketServer, type WebSocket } from "ws";
|
|
22
|
-
import { CLOSE, RoomHub, type Limits, type SavePort } from "./hub.ts";
|
|
23
|
-
import { GuestPasses, Heartbeat, WS_OPTIONS, attach, clientAddress, fileSaves, gameHash } from "./node.ts";
|
|
22
|
+
import { CLOSE, RoomHub, addressKey, type Limits, type SavePort } from "./hub.ts";
|
|
23
|
+
import { GuestPasses, Heartbeat, WS_OPTIONS, attach, clientAddress, fileSaves, gameHash, hardenServer } from "./node.ts";
|
|
24
24
|
|
|
25
25
|
export interface Deployment {
|
|
26
26
|
/** public id, as in the page's script tag: letters, digits, "_" and "-", 3 to 64 */
|
|
@@ -59,6 +59,8 @@ export interface Remote {
|
|
|
59
59
|
request(req: http.IncomingMessage, res: http.ServerResponse): boolean;
|
|
60
60
|
/** Turn a deployment off now: its open rooms close (saves are written first) and its cached settings are dropped. */
|
|
61
61
|
revoke(id: string): void;
|
|
62
|
+
/** Drop the cached settings of one deployment (after its sites or caps changed) without closing its rooms. Unchanged ones refresh every LOOKUP_MS. */
|
|
63
|
+
forget(id: string): void;
|
|
62
64
|
/** The hub namespace of a deployment (for hub.scopeStats, hub.closeScope). */
|
|
63
65
|
scope(id: string): string;
|
|
64
66
|
/** The rooms cap the hub should use for a namespace (pass to new RoomHub({ roomsPerScope })). */
|
|
@@ -68,6 +70,10 @@ export interface Remote {
|
|
|
68
70
|
}
|
|
69
71
|
|
|
70
72
|
const ID_RE = /^[A-Za-z0-9_-]{3,64}$/;
|
|
73
|
+
/** A deployment (found or not) is asked for again after this long; call forget(id) to make an edit count at once. */
|
|
74
|
+
export const LOOKUP_MS = 15_000;
|
|
75
|
+
/** Fresh lookups one client address (IPv6: /64) may cause per 10 s. */
|
|
76
|
+
export const LOOKUPS_PER_ADDRESS = 20;
|
|
71
77
|
const GAME_RE = /^[A-Za-z0-9_-]{1,60}$/;
|
|
72
78
|
const VER_RE = /^[A-Za-z0-9._-]{1,40}$/;
|
|
73
79
|
const KEY_RE = /^[A-Za-z0-9_-]{22,64}$/;
|
|
@@ -134,13 +140,33 @@ export function createRemote(o: RemoteOptions): Remote {
|
|
|
134
140
|
const sources = { relay: src("relay"), room: src("room"), game: src("game") };
|
|
135
141
|
const files: Record<string, string> = { relay: sources.relay, room: sources.room, game: sources.game, game3d: src("game3d") };
|
|
136
142
|
const scope = (id: string) => `dep:${id}`;
|
|
137
|
-
|
|
143
|
+
// Deployments are looked up at most once per LOOKUP_MS per id (found or not), and an address may cause at most LOOKUPS_PER_ADDRESS fresh lookups
|
|
144
|
+
// per 10 s: a flood of sockets or boot scripts with random ids costs a map hit, not a query on your table per request.
|
|
145
|
+
const seen = new Map<string, number>(); // id -> when it was last looked up
|
|
146
|
+
const misses = new Map<string, { at: number; n: number }>();
|
|
147
|
+
const lookupAllowed = (addr: string) => {
|
|
148
|
+
const k = addressKey(addr), now = Date.now();
|
|
149
|
+
let w = misses.get(k);
|
|
150
|
+
if (!w || now - w.at >= 10_000) {
|
|
151
|
+
if (misses.size >= 50_000) for (const [x, v] of misses) if (now - v.at >= 10_000) misses.delete(x);
|
|
152
|
+
if (misses.size >= 50_000) return false;
|
|
153
|
+
w = { at: now, n: 0 }; misses.set(k, w);
|
|
154
|
+
}
|
|
155
|
+
return ++w.n <= LOOKUPS_PER_ADDRESS;
|
|
156
|
+
};
|
|
157
|
+
const lookup = async (id: string, addr: string) => {
|
|
138
158
|
if (!ID_RE.test(id)) return null;
|
|
159
|
+
const at = seen.get(id);
|
|
160
|
+
if (at !== undefined && Date.now() - at < LOOKUP_MS) return cache.get(id) ?? null;
|
|
161
|
+
if (!lookupAllowed(addr)) return cache.get(id) ?? null;
|
|
139
162
|
let dep: Deployment | null | undefined = null;
|
|
140
163
|
try { dep = await o.deployment(id); } catch { dep = null; }
|
|
164
|
+
if (seen.size >= 100_000) seen.clear();
|
|
165
|
+
seen.set(id, Date.now());
|
|
141
166
|
if (dep && dep.id === id) cache.set(id, dep); else cache.delete(id);
|
|
142
167
|
return dep && dep.id === id ? dep : null;
|
|
143
168
|
};
|
|
169
|
+
const addrOf = (req: http.IncomingMessage) => (o.address ? o.address(req) : req.socket.remoteAddress || "?");
|
|
144
170
|
// refused sockets are still accepted, then closed with a code the page shows (4001 is final: the page stops trying; 1013 busy: it retries)
|
|
145
171
|
const closeWith = (req: http.IncomingMessage, socket: Duplex, head: Buffer, code: number, reason: string) =>
|
|
146
172
|
wss.handleUpgrade(req, socket, head, (ws: WebSocket) => ws.close(code, reason));
|
|
@@ -149,7 +175,8 @@ export function createRemote(o: RemoteOptions): Remote {
|
|
|
149
175
|
scope,
|
|
150
176
|
sockets: (id) => live.get(id) || 0,
|
|
151
177
|
roomsPerScope: (sc) => (sc.startsWith("dep:") ? cache.get(sc.slice(4))?.caps?.rooms : undefined),
|
|
152
|
-
revoke(id) { cache.delete(id); o.hub.closeScope(scope(id), "this game was turned off by its owner"); },
|
|
178
|
+
revoke(id) { cache.delete(id); seen.delete(id); o.hub.closeScope(scope(id), "this game was turned off by its owner"); },
|
|
179
|
+
forget(id) { cache.delete(id); seen.delete(id); },
|
|
153
180
|
|
|
154
181
|
upgrade(req, socket, head) {
|
|
155
182
|
const url = new URL(req.url || "/", "http://localhost");
|
|
@@ -159,7 +186,9 @@ export function createRemote(o: RemoteOptions): Remote {
|
|
|
159
186
|
const id = url.searchParams.get("d") || "", game = url.searchParams.get("game") || "", ver = url.searchParams.get("v") || "1";
|
|
160
187
|
if (!GAME_RE.test(game) || !VER_RE.test(ver)) { closeWith(req, socket, head, CLOSE.badMessage, "bad game name or version"); return true; }
|
|
161
188
|
socket.on("error", () => { /* closed early */ });
|
|
162
|
-
|
|
189
|
+
const addr = addrOf(req);
|
|
190
|
+
if (!o.hub.allowAddress(addr)) { closeWith(req, socket, head, CLOSE.busy, "too many new connections, try again"); return true; }
|
|
191
|
+
void lookup(id, addr).then((dep) => {
|
|
163
192
|
if (socket.destroyed) return;
|
|
164
193
|
if (!dep || dep.revoked) return closeWith(req, socket, head, CLOSE.notAllowed, "this game's deployment is unknown or turned off");
|
|
165
194
|
if (!originAllowed(dep, origin)) return closeWith(req, socket, head, CLOSE.notAllowed, `this site is not allowed for deployment ${id}`);
|
|
@@ -170,7 +199,7 @@ export function createRemote(o: RemoteOptions): Remote {
|
|
|
170
199
|
live.set(id, (live.get(id) || 0) + 1);
|
|
171
200
|
ws.on("close", () => { const left = (live.get(id) || 1) - 1; if (left > 0) live.set(id, left); else live.delete(id); });
|
|
172
201
|
attach(ws, {
|
|
173
|
-
hub: o.hub, heartbeat: o.heartbeat, address:
|
|
202
|
+
hub: o.hub, heartbeat: o.heartbeat, address: addr, counted: true,
|
|
174
203
|
// the guest key is the page's own random 128-bit value: unguessable, so nobody can take another player's seat; it names a seat in
|
|
175
204
|
// this deployment only (the hub shows others a short HMAC of it, never the key)
|
|
176
205
|
authenticate: (ticket) => typeof ticket === "string" && KEY_RE.test(ticket)
|
|
@@ -193,7 +222,7 @@ export function createRemote(o: RemoteOptions): Remote {
|
|
|
193
222
|
if (c) { js(200, files[c[1]], "public, max-age=300"); return true; }
|
|
194
223
|
const b = /^\/c\/([^/]+)\.js$/.exec(url.pathname);
|
|
195
224
|
if (!b) return false;
|
|
196
|
-
void lookup(b[1]).then((dep) => {
|
|
225
|
+
void lookup(b[1], addrOf(req)).then((dep) => {
|
|
197
226
|
if (!dep || dep.revoked) return js(404, `console.error(${JSON.stringify(`tickcli: no deployment ${b[1].slice(0, 64)} (unknown or turned off)`)});`);
|
|
198
227
|
js(200, bootScript(dep.id, sources), "public, max-age=300");
|
|
199
228
|
});
|
|
@@ -222,10 +251,10 @@ export function createRemoteServer(o: RemoteServerOptions) {
|
|
|
222
251
|
hub.start();
|
|
223
252
|
const heartbeat = new Heartbeat();
|
|
224
253
|
remote = createRemote({ hub, deployment: o.deployment, heartbeat, address: o.address ?? (o.trustProxy ? (req) => clientAddress(req, true) : undefined) });
|
|
225
|
-
const server = http.createServer((req, res) => {
|
|
254
|
+
const server = hardenServer(http.createServer((req, res) => {
|
|
226
255
|
if (remote!.request(req, res)) return;
|
|
227
256
|
res.writeHead(404, { "Content-Type": "text/plain" }); res.end("not found");
|
|
228
|
-
});
|
|
257
|
+
}));
|
|
229
258
|
server.on("upgrade", (req, socket, head) => { if (!remote!.upgrade(req, socket, head)) socket.destroy(); });
|
|
230
259
|
const listen = (port = 8080, host?: string) => new Promise<string>((resolve, reject) => {
|
|
231
260
|
server.once("error", reject);
|
package/src/serve.ts
CHANGED
|
@@ -18,7 +18,7 @@ import { createRequire } from "node:module";
|
|
|
18
18
|
import { fileURLToPath } from "node:url";
|
|
19
19
|
import { WebSocketServer } from "ws";
|
|
20
20
|
import { RoomHub, type Limits, type SavePort } from "./hub.ts";
|
|
21
|
-
import { GuestPasses, Heartbeat, WS_OPTIONS, attach, clientAddress, fileSaves, gameHash, sameSite } from "./node.ts";
|
|
21
|
+
import { GuestPasses, Heartbeat, WS_OPTIONS, attach, clientAddress, fileSaves, gameHash, hardenServer, sameSite } from "./node.ts";
|
|
22
22
|
|
|
23
23
|
export interface GameServerOptions {
|
|
24
24
|
/** Folder of games, one .html file each (names: letters, digits, "-" and "_"). Default: the current folder. */
|
|
@@ -172,7 +172,7 @@ export function createGameServer(o: GameServerOptions = {}): GameServer {
|
|
|
172
172
|
};
|
|
173
173
|
const title = o.title ?? "tickcli games";
|
|
174
174
|
|
|
175
|
-
const server = http.createServer((req, res) => {
|
|
175
|
+
const server = hardenServer(http.createServer((req, res) => {
|
|
176
176
|
const url = new URL(req.url || "/", "http://localhost");
|
|
177
177
|
const send = (code: number, type: string, body: string, headers: Record<string, string> = {}) => { res.writeHead(code, { "Content-Type": type, "Cache-Control": "no-store", "X-Content-Type-Options": "nosniff", ...headers }); res.end(body); };
|
|
178
178
|
if (req.method !== "GET" && req.method !== "HEAD") return send(405, "text/plain", "method not allowed");
|
|
@@ -195,12 +195,14 @@ export function createGameServer(o: GameServerOptions = {}): GameServer {
|
|
|
195
195
|
const headers: Record<string, string> = { "Content-Security-Policy": `default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'unsafe-inline'; img-src data: blob:; connect-src 'self'${wsOrigins(req)}; frame-ancestors 'none'` };
|
|
196
196
|
if (!passes.check(SCOPE, cookie(req, PASS))) headers["Set-Cookie"] = GuestPasses.cookie(PASS, passes.issue(SCOPE), "/", !!o.secure);
|
|
197
197
|
return send(200, "text/html; charset=utf-8", playPage(html, g![1]), headers);
|
|
198
|
-
});
|
|
198
|
+
}));
|
|
199
199
|
|
|
200
200
|
server.on("upgrade", (req, socket, head) => {
|
|
201
201
|
const url = new URL(req.url || "/", "http://localhost");
|
|
202
202
|
const refuse = (code: number) => { socket.end(`HTTP/1.1 ${code} ${http.STATUS_CODES[code]}\r\nConnection: close\r\nContent-Length: 0\r\n\r\n`); };
|
|
203
203
|
if (url.pathname !== "/room") return refuse(404);
|
|
204
|
+
const address = clientAddress(req, !!o.trustProxy);
|
|
205
|
+
if (!hub.allowAddress(address)) return refuse(429);
|
|
204
206
|
if (!sameSite((n) => req.headers[n] as string | undefined)) return refuse(403);
|
|
205
207
|
const pass = passes.check(SCOPE, cookie(req, PASS));
|
|
206
208
|
if (!pass) return refuse(403);
|
|
@@ -208,7 +210,7 @@ export function createGameServer(o: GameServerOptions = {}): GameServer {
|
|
|
208
210
|
const game = read(name);
|
|
209
211
|
if (!game) return refuse(404);
|
|
210
212
|
const identity = { scope: `${SCOPE}:${name}`, game: game.hash, slot: name, who: { seat: `g:${pass}`, name: GuestPasses.defaultName(pass), guest: true } };
|
|
211
|
-
wss.handleUpgrade(req, socket, head, (ws) => attach(ws, { hub, heartbeat, address:
|
|
213
|
+
wss.handleUpgrade(req, socket, head, (ws) => attach(ws, { hub, heartbeat, address, counted: true, identity }));
|
|
212
214
|
});
|
|
213
215
|
|
|
214
216
|
const listen = (port = 8080, host?: string) => new Promise<string>((resolve, reject) => {
|