diff --git a/index.html b/index.html index 1d5175a..df42369 100644 --- a/index.html +++ b/index.html @@ -5,6 +5,7 @@ + diff --git a/package.json b/package.json index ef5a8ed..3c8af91 100644 --- a/package.json +++ b/package.json @@ -14,9 +14,9 @@ "@fastify/compress": "^6.5.0", "@fastify/cookie": "^9.3.1", "@fastify/static": "^6.12.0", - "@mercuryworkshop/bare-mux": "^1.0.4", - "@mercuryworkshop/epoxy-transport": "^1.0.2", - "@mercuryworkshop/libcurl-transport": "^1.2.0", + "@mercuryworkshop/bare-mux": "^1.0.5", + "@mercuryworkshop/epoxy-transport": "^1.1.0", + "@mercuryworkshop/libcurl-transport": "^1.2.1", "@nebula-services/dynamic": "0.7.2-patch.2", "@titaniumnetwork-dev/ultraviolet": "^3.0.0", "@tomphttp/bare-server-node": "2.0.3", @@ -46,7 +46,7 @@ "react-icons": "^4.12.0", "react-toastify": "^9.1.3", "tsx": "^4.7.1", - "wisp-server-node": "^1.0.1", + "wisp-server-node": "^1.0.2", "ws": "^8.16.0" }, "devDependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9cf4954..b4ebb29 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,14 +15,14 @@ dependencies: specifier: ^6.12.0 version: 6.12.0 '@mercuryworkshop/bare-mux': - specifier: ^1.0.4 - version: 1.0.4 + specifier: ^1.0.5 + version: 1.0.5 '@mercuryworkshop/epoxy-transport': - specifier: ^1.0.2 - version: 1.0.2(typescript@5.4.2) + specifier: ^1.1.0 + version: 1.1.0(typescript@5.4.2) '@mercuryworkshop/libcurl-transport': - specifier: ^1.2.0 - version: 1.2.0(typescript@5.4.2) + specifier: ^1.2.1 + version: 1.2.1(typescript@5.4.2) '@nebula-services/dynamic': specifier: 0.7.2-patch.2 version: 0.7.2-patch.2 @@ -111,8 +111,8 @@ dependencies: specifier: ^4.7.1 version: 4.7.1 wisp-server-node: - specifier: ^1.0.1 - version: 1.0.1 + specifier: ^1.0.2 + version: 1.0.2 ws: specifier: ^8.16.0 version: 8.16.0 @@ -828,21 +828,21 @@ packages: uuid: 9.0.1 dev: false - /@mercuryworkshop/bare-mux@1.0.4: - resolution: {integrity: sha512-u9vtjc9Gp4G6UO7NYB1SphEiNIZtHuwI7/wxebbeKJ+GegmogxFodXF0ZYsQl7AY0fo3RqQs4odex9pYPHDkgQ==} + /@mercuryworkshop/bare-mux@1.0.5: + resolution: {integrity: sha512-5czcsWISUCrN49diTuF/8WXZUCyoWHn90Ea+gLhVWKGUTyJzPAG5gTVZ77rMcQYewSuSDA1WVPaF0n79ciL5Gg==} dependencies: '@types/uuid': 9.0.8 uuid: 9.0.1 dev: false - /@mercuryworkshop/epoxy-tls@1.3.0: - resolution: {integrity: sha512-aqa+6Sm7weAtSwuWrVZIlqabIvzb60NxebAm1gf9Haulviz0NCMTO1sCGQ2JJrgWAmzGp63PQ4CeB9ZvKq9odw==} + /@mercuryworkshop/epoxy-tls@1.4.1: + resolution: {integrity: sha512-g4vuP25F+RUz2l46y0WJ6mm9p7GDJEwEsgtQn5SzsXgnS1iKstE8bHAtqIfEf6njs4kRZs9Lxkj2UwHw2y+S7g==} dev: false - /@mercuryworkshop/epoxy-transport@1.0.2(typescript@5.4.2): - resolution: {integrity: sha512-phd8dlaSZqOt1/suNShdBFf1dlXyYGVXYEjAX7vg0pW4cWN1kgJvpq58a/LZwNlIqb2vkFp6pXUXq7w/RW70vQ==} + /@mercuryworkshop/epoxy-transport@1.1.0(typescript@5.4.2): + resolution: {integrity: sha512-JVdKr+u53qu3GQyehZDWRfWV1UWct2fAtU2/50plFl9TLzy2rPLUHqyHTmyAuErNS6SP2uZ9BlgMz6FN4PlpVg==} dependencies: - '@mercuryworkshop/epoxy-tls': 1.3.0 + '@mercuryworkshop/epoxy-tls': 1.4.1 esbuild-plugin-umd-wrapper: 2.0.0 rollup: 4.12.1 rollup-plugin-node-resolve: 5.2.0(rollup@4.12.1) @@ -854,11 +854,11 @@ packages: - utf-8-validate dev: false - /@mercuryworkshop/libcurl-transport@1.2.0(typescript@5.4.2): - resolution: {integrity: sha512-jONOZ/jbLAuSd+m0d1Z4JAnB08VbyYf1or8nKFdyNn4TudDnu0yDQnRYuD/nELUXnOJNT7WnjEGIpaeLcNdXCg==} + /@mercuryworkshop/libcurl-transport@1.2.1(typescript@5.4.2): + resolution: {integrity: sha512-HwlC36KSMoUHQmZ8y2EkF57oV6UfLrg6rUbdniMQqWw2HEDBT5Ua+gcyQybjW6pNMqvneqnOWLJFF9LwZzGHoA==} dependencies: esbuild-plugin-umd-wrapper: 2.0.0 - libcurl.js: 0.4.2 + libcurl.js: 0.5.1 rollup: 4.12.1 rollup-plugin-node-resolve: 5.2.0(rollup@4.12.1) rollup-plugin-typescript2: 0.36.0(rollup@4.12.1)(typescript@5.4.2) @@ -2109,7 +2109,7 @@ packages: es-errors: 1.3.0 function-bind: 1.1.2 get-intrinsic: 1.2.4 - set-function-length: 1.2.1 + set-function-length: 1.2.2 /callsite@1.0.0: resolution: {integrity: sha512-0vdNRFXn5q+dtOqjfFtmtlI9N2eVZ7LMyEV2iKC5mEEFvSg/69Ml6b/WU2qF8W1nLRa0wiSrDT3Y5jOHZCwKPQ==} @@ -2680,7 +2680,7 @@ packages: has-property-descriptors: 1.0.2 has-proto: 1.0.3 has-symbols: 1.0.3 - hasown: 2.0.1 + hasown: 2.0.2 internal-slot: 1.0.7 is-array-buffer: 3.0.4 is-callable: 1.2.7 @@ -2694,7 +2694,7 @@ packages: object-keys: 1.1.1 object.assign: 4.1.5 regexp.prototype.flags: 1.5.2 - safe-array-concat: 1.1.0 + safe-array-concat: 1.1.2 safe-regex-test: 1.0.3 string.prototype.trim: 1.2.8 string.prototype.trimend: 1.0.7 @@ -2704,7 +2704,7 @@ packages: typed-array-byte-offset: 1.0.2 typed-array-length: 1.0.5 unbox-primitive: 1.0.2 - which-typed-array: 1.1.14 + which-typed-array: 1.1.15 dev: true /es-define-property@1.0.0: @@ -2735,7 +2735,7 @@ packages: has-symbols: 1.0.3 internal-slot: 1.0.7 iterator.prototype: 1.1.2 - safe-array-concat: 1.1.0 + safe-array-concat: 1.1.2 dev: true /es-set-tostringtag@2.0.3: @@ -2744,13 +2744,13 @@ packages: dependencies: get-intrinsic: 1.2.4 has-tostringtag: 1.0.2 - hasown: 2.0.1 + hasown: 2.0.2 dev: true /es-shim-unscopables@1.0.2: resolution: {integrity: sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==} dependencies: - hasown: 2.0.1 + hasown: 2.0.2 dev: true /es-to-primitive@1.2.1: @@ -3463,7 +3463,7 @@ packages: function-bind: 1.1.2 has-proto: 1.0.3 has-symbols: 1.0.3 - hasown: 2.0.1 + hasown: 2.0.2 /get-stream@3.0.0: resolution: {integrity: sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==} @@ -3635,8 +3635,8 @@ packages: dev: false optional: true - /hasown@2.0.1: - resolution: {integrity: sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==} + /hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} dependencies: function-bind: 1.1.2 @@ -3810,7 +3810,7 @@ packages: engines: {node: '>= 0.4'} dependencies: es-errors: 1.3.0 - hasown: 2.0.1 + hasown: 2.0.2 side-channel: 1.0.6 dev: true @@ -3885,7 +3885,7 @@ packages: /is-core-module@2.13.1: resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} dependencies: - hasown: 2.0.1 + hasown: 2.0.2 /is-date-object@1.0.5: resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} @@ -4037,7 +4037,7 @@ packages: resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} engines: {node: '>= 0.4'} dependencies: - which-typed-array: 1.1.14 + which-typed-array: 1.1.15 dev: true /is-weakmap@2.0.2: @@ -4188,8 +4188,8 @@ packages: type-check: 0.4.0 dev: true - /libcurl.js@0.4.2: - resolution: {integrity: sha512-WuL2EgeYVuSsHFeJhpq83pOMX8+ei1E4Vpym7SKz6vPvuOEK9TBDCZRXDN/zr9o4T9UIy0FXxwpIEyHvSBNGmA==} + /libcurl.js@0.5.1: + resolution: {integrity: sha512-tO6WLAQHt/4JWpGCxoaLd+C5lG2MVYM7Df7E68ElEO9YWxPNO0f4lEdy+NS6KyxfvVP0Il4PYlFnyXnoYvVWZA==} dev: false /lie@3.1.1: @@ -5649,8 +5649,8 @@ packages: tslib: 2.6.2 dev: true - /safe-array-concat@1.1.0: - resolution: {integrity: sha512-ZdQ0Jeb9Ofti4hbt5lX3T2JcAamT9hfzYU1MNB+z/jaEbB6wfFfPIR/zEORmZqobkCCJhSjodobH6WHNmJ97dg==} + /safe-array-concat@1.1.2: + resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==} engines: {node: '>=0.4'} dependencies: call-bind: 1.0.7 @@ -5760,8 +5760,8 @@ packages: resolution: {integrity: sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==} dev: false - /set-function-length@1.2.1: - resolution: {integrity: sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==} + /set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} engines: {node: '>= 0.4'} dependencies: define-data-property: 1.1.4 @@ -6599,7 +6599,7 @@ packages: isarray: 2.0.5 which-boxed-primitive: 1.0.2 which-collection: 1.0.2 - which-typed-array: 1.1.14 + which-typed-array: 1.1.15 dev: true /which-collection@1.0.2: @@ -6612,8 +6612,8 @@ packages: is-weakset: 2.0.3 dev: true - /which-typed-array@1.1.14: - resolution: {integrity: sha512-VnXFiIW8yNn9kIHN88xvZ4yOWchftKDsRJ8fEPacX/wl1lOvBrhsJ/OeJCXq7B0AaijRuqgzSKalJoPk+D8MPg==} + /which-typed-array@1.1.15: + resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} engines: {node: '>= 0.4'} dependencies: available-typed-arrays: 1.0.7 @@ -6645,8 +6645,13 @@ packages: dev: false optional: true - /wisp-server-node@1.0.1: - resolution: {integrity: sha512-RPid1o/q8NWE0zVFmMIUBIWS7WnUeHmfzrxaNeFsWKXYKD5RO74qYnDLbXSKFDCTSrPQ+uXtRI2I/EpunXfAvw==} + /wisp-server-node@1.0.2: + resolution: {integrity: sha512-a48BYDSaGljTV54OtDjdkTYGbqehEfuNhSMZ9ZHIqtFSesMBi84WmyPYSZ9IgJUenw5p8iR0xjbcx9/nVJWJ+A==} + dependencies: + ws: 8.16.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate dev: false /wrap-ansi@7.0.0: diff --git a/public/libcurl.wasm b/public/libcurl.wasm deleted file mode 100644 index 487884d..0000000 Binary files a/public/libcurl.wasm and /dev/null differ diff --git a/public/sw.js b/public/sw.js index 663d20e..12b8636 100644 --- a/public/sw.js +++ b/public/sw.js @@ -1,5 +1,6 @@ importScripts("/epoxy/index.js"); importScripts("/libcurl/index.cjs"); +importScripts("/transports/bareTransport.js"); importScripts("/uv/uv.bundle.js"); importScripts("/uv/uv.config.js"); importScripts(__uv$config.sw || "/uv/uv.sw.js"); @@ -15,6 +16,7 @@ localforage.config({ description: "Nebula Config for things reliant on IndexedDB" }); +const uv = new UVServiceWorker(); const dynPromise = new Promise(async (resolve) => { try { const bare = @@ -27,22 +29,6 @@ const dynPromise = new Promise(async (resolve) => { resolve(); }); -const uvPromise = new Promise(async (resolve) => { - try { - const bare = - (await localforage.getItem("bare")) || location.origin + "/bare/"; - const proxyUrl = (await localforage.getItem("HTTPProxy")) || ""; - const [proxyIP, proxyPort] = proxyUrl.split(":"); - self.__uv$config.bare = bare; - self.__uv$config.proxyPort = proxyPort; - self.__uv$config.proxyIp = proxyIP; - self.uv = new UVServiceWorker(self.__uv$config); - } catch (error) { - console.log(error); - } - resolve(); -}); - self.addEventListener("fetch", (event) => { if ( event.request.url.startsWith(location.origin + self.__dynamic$config.prefix) @@ -59,14 +45,17 @@ self.addEventListener("fetch", (event) => { })() ); } else if ( - event.request.url.startsWith(location.origin + self.__uv$config.prefix) + event.request.url.startsWith(location.origin + __uv$config.prefix) ) { event.respondWith( (async function () { - try { - await uvPromise; - } catch (error) {} - return await self.uv.fetch(event); + return await uv.fetch(event); + })() + ); + } else { + event.respondWith( + (async function () { + return await fetch(event.request); })() ); } diff --git a/public/transports/bareTransport.js b/public/transports/bareTransport.js new file mode 100644 index 0000000..0107ef9 --- /dev/null +++ b/public/transports/bareTransport.js @@ -0,0 +1,612 @@ +//Built from: https://github.com/motortruck1221/bare-as-module3 (commit: 36759f801e0009027878edecff156408b06404c6) +(function (global, factory) { + typeof exports === "object" && typeof module !== "undefined" + ? factory(exports) + : typeof define === "function" && define.amd + ? define(["exports"], factory) + : ((global = + typeof globalThis !== "undefined" ? globalThis : global || self), + factory((global.BareMod = {}))); +})(this, function (exports) { + "use strict"; + + // The user likely has overwritten all networking functions after importing bare-client + // It is our responsibility to make sure components of Bare-Client are using native networking functions + // These exports are provided to plugins by @rollup/plugin-inject + const fetch = globalThis.fetch; + const WebSocket = globalThis.WebSocket; + const WebSocketFields = { + prototype: { + send: WebSocket.prototype.send + }, + CLOSED: WebSocket.CLOSED, + CLOSING: WebSocket.CLOSING, + CONNECTING: WebSocket.CONNECTING, + OPEN: WebSocket.OPEN + }; + + class BareError extends Error { + status; + body; + constructor(status, body) { + super(body.message || body.code); + this.status = status; + this.body = body; + } + } + class Client { + base; + /** + * + * @param version Version provided by extension + * @param server Bare Server URL provided by BareClient + */ + constructor(version, server) { + this.base = new URL(`./v${version}/`, server); + } + } + + /* + * JavaScript MD5 + * Adopted from https://github.com/blueimp/JavaScript-MD5 + * + * Copyright 2011, Sebastian Tschan + * https://blueimp.net + * + * Licensed under the MIT license: + * https://opensource.org/licenses/MIT + * + * Based on + * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message + * Digest Algorithm, as defined in RFC 1321. + * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009 + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet + * Distributed under the BSD License + * See http://pajhome.org.uk/crypt/md5 for more info. + */ + /** + * Add integers, wrapping at 2^32. + * This uses 16-bit operations internally to work around bugs in interpreters. + * + * @param x First integer + * @param y Second integer + * @returns Sum + */ + function safeAdd(x, y) { + const lsw = (x & 0xffff) + (y & 0xffff); + const msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return (msw << 16) | (lsw & 0xffff); + } + /** + * Bitwise rotate a 32-bit number to the left. + * + * @param num 32-bit number + * @param cnt Rotation count + * @returns Rotated number + */ + function bitRotateLeft(num, cnt) { + return (num << cnt) | (num >>> (32 - cnt)); + } + /** + * Basic operation the algorithm uses. + * + * @param q q + * @param a a + * @param b b + * @param x x + * @param s s + * @param t t + * @returns Result + */ + function md5cmn(q, a, b, x, s, t) { + return safeAdd(bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), b); + } + /** + * Basic operation the algorithm uses. + * + * @param a a + * @param b b + * @param c c + * @param d d + * @param x x + * @param s s + * @param t t + * @returns Result + */ + function md5ff(a, b, c, d, x, s, t) { + return md5cmn((b & c) | (~b & d), a, b, x, s, t); + } + /** + * Basic operation the algorithm uses. + * + * @param a a + * @param b b + * @param c c + * @param d d + * @param x x + * @param s s + * @param t t + * @returns Result + */ + function md5gg(a, b, c, d, x, s, t) { + return md5cmn((b & d) | (c & ~d), a, b, x, s, t); + } + /** + * Basic operation the algorithm uses. + * + * @param a a + * @param b b + * @param c c + * @param d d + * @param x x + * @param s s + * @param t t + * @returns Result + */ + function md5hh(a, b, c, d, x, s, t) { + return md5cmn(b ^ c ^ d, a, b, x, s, t); + } + /** + * Basic operation the algorithm uses. + * + * @param a a + * @param b b + * @param c c + * @param d d + * @param x x + * @param s s + * @param t t + * @returns Result + */ + function md5ii(a, b, c, d, x, s, t) { + return md5cmn(c ^ (b | ~d), a, b, x, s, t); + } + /** + * Calculate the MD5 of an array of little-endian words, and a bit length. + * + * @param x Array of little-endian words + * @param len Bit length + * @returns MD5 Array + */ + function binlMD5(x, len) { + /* append padding */ + x[len >> 5] |= 0x80 << len % 32; + x[(((len + 64) >>> 9) << 4) + 14] = len; + let a = 1732584193; + let b = -271733879; + let c = -1732584194; + let d = 271733878; + for (let i = 0; i < x.length; i += 16) { + const olda = a; + const oldb = b; + const oldc = c; + const oldd = d; + a = md5ff(a, b, c, d, x[i], 7, -680876936); + d = md5ff(d, a, b, c, x[i + 1], 12, -389564586); + c = md5ff(c, d, a, b, x[i + 2], 17, 606105819); + b = md5ff(b, c, d, a, x[i + 3], 22, -1044525330); + a = md5ff(a, b, c, d, x[i + 4], 7, -176418897); + d = md5ff(d, a, b, c, x[i + 5], 12, 1200080426); + c = md5ff(c, d, a, b, x[i + 6], 17, -1473231341); + b = md5ff(b, c, d, a, x[i + 7], 22, -45705983); + a = md5ff(a, b, c, d, x[i + 8], 7, 1770035416); + d = md5ff(d, a, b, c, x[i + 9], 12, -1958414417); + c = md5ff(c, d, a, b, x[i + 10], 17, -42063); + b = md5ff(b, c, d, a, x[i + 11], 22, -1990404162); + a = md5ff(a, b, c, d, x[i + 12], 7, 1804603682); + d = md5ff(d, a, b, c, x[i + 13], 12, -40341101); + c = md5ff(c, d, a, b, x[i + 14], 17, -1502002290); + b = md5ff(b, c, d, a, x[i + 15], 22, 1236535329); + a = md5gg(a, b, c, d, x[i + 1], 5, -165796510); + d = md5gg(d, a, b, c, x[i + 6], 9, -1069501632); + c = md5gg(c, d, a, b, x[i + 11], 14, 643717713); + b = md5gg(b, c, d, a, x[i], 20, -373897302); + a = md5gg(a, b, c, d, x[i + 5], 5, -701558691); + d = md5gg(d, a, b, c, x[i + 10], 9, 38016083); + c = md5gg(c, d, a, b, x[i + 15], 14, -660478335); + b = md5gg(b, c, d, a, x[i + 4], 20, -405537848); + a = md5gg(a, b, c, d, x[i + 9], 5, 568446438); + d = md5gg(d, a, b, c, x[i + 14], 9, -1019803690); + c = md5gg(c, d, a, b, x[i + 3], 14, -187363961); + b = md5gg(b, c, d, a, x[i + 8], 20, 1163531501); + a = md5gg(a, b, c, d, x[i + 13], 5, -1444681467); + d = md5gg(d, a, b, c, x[i + 2], 9, -51403784); + c = md5gg(c, d, a, b, x[i + 7], 14, 1735328473); + b = md5gg(b, c, d, a, x[i + 12], 20, -1926607734); + a = md5hh(a, b, c, d, x[i + 5], 4, -378558); + d = md5hh(d, a, b, c, x[i + 8], 11, -2022574463); + c = md5hh(c, d, a, b, x[i + 11], 16, 1839030562); + b = md5hh(b, c, d, a, x[i + 14], 23, -35309556); + a = md5hh(a, b, c, d, x[i + 1], 4, -1530992060); + d = md5hh(d, a, b, c, x[i + 4], 11, 1272893353); + c = md5hh(c, d, a, b, x[i + 7], 16, -155497632); + b = md5hh(b, c, d, a, x[i + 10], 23, -1094730640); + a = md5hh(a, b, c, d, x[i + 13], 4, 681279174); + d = md5hh(d, a, b, c, x[i], 11, -358537222); + c = md5hh(c, d, a, b, x[i + 3], 16, -722521979); + b = md5hh(b, c, d, a, x[i + 6], 23, 76029189); + a = md5hh(a, b, c, d, x[i + 9], 4, -640364487); + d = md5hh(d, a, b, c, x[i + 12], 11, -421815835); + c = md5hh(c, d, a, b, x[i + 15], 16, 530742520); + b = md5hh(b, c, d, a, x[i + 2], 23, -995338651); + a = md5ii(a, b, c, d, x[i], 6, -198630844); + d = md5ii(d, a, b, c, x[i + 7], 10, 1126891415); + c = md5ii(c, d, a, b, x[i + 14], 15, -1416354905); + b = md5ii(b, c, d, a, x[i + 5], 21, -57434055); + a = md5ii(a, b, c, d, x[i + 12], 6, 1700485571); + d = md5ii(d, a, b, c, x[i + 3], 10, -1894986606); + c = md5ii(c, d, a, b, x[i + 10], 15, -1051523); + b = md5ii(b, c, d, a, x[i + 1], 21, -2054922799); + a = md5ii(a, b, c, d, x[i + 8], 6, 1873313359); + d = md5ii(d, a, b, c, x[i + 15], 10, -30611744); + c = md5ii(c, d, a, b, x[i + 6], 15, -1560198380); + b = md5ii(b, c, d, a, x[i + 13], 21, 1309151649); + a = md5ii(a, b, c, d, x[i + 4], 6, -145523070); + d = md5ii(d, a, b, c, x[i + 11], 10, -1120210379); + c = md5ii(c, d, a, b, x[i + 2], 15, 718787259); + b = md5ii(b, c, d, a, x[i + 9], 21, -343485551); + a = safeAdd(a, olda); + b = safeAdd(b, oldb); + c = safeAdd(c, oldc); + d = safeAdd(d, oldd); + } + return [a, b, c, d]; + } + /** + * Convert an array of little-endian words to a string + * + * @param input MD5 Array + * @returns MD5 string + */ + function binl2rstr(input) { + let output = ""; + const length32 = input.length * 32; + for (let i = 0; i < length32; i += 8) { + output += String.fromCharCode((input[i >> 5] >>> i % 32) & 0xff); + } + return output; + } + /** + * Convert a raw string to an array of little-endian words + * Characters >255 have their high-byte silently ignored. + * + * @param input Raw input string + * @returns Array of little-endian words + */ + function rstr2binl(input) { + const output = []; + const outputLen = input.length >> 2; + for (let i = 0; i < outputLen; i += 1) { + output[i] = 0; + } + const length8 = input.length * 8; + for (let i = 0; i < length8; i += 8) { + output[i >> 5] |= (input.charCodeAt(i / 8) & 0xff) << i % 32; + } + return output; + } + /** + * Calculate the MD5 of a raw string + * + * @param s Input string + * @returns Raw MD5 string + */ + function rstrMD5(s) { + return binl2rstr(binlMD5(rstr2binl(s), s.length * 8)); + } + /** + * Calculates the HMAC-MD5 of a key and some data (raw strings) + * + * @param key HMAC key + * @param data Raw input string + * @returns Raw MD5 string + */ + function rstrHMACMD5(key, data) { + let bkey = rstr2binl(key); + const ipad = []; + const opad = []; + if (bkey.length > 16) { + bkey = binlMD5(bkey, key.length * 8); + } + for (let i = 0; i < 16; i += 1) { + ipad[i] = bkey[i] ^ 0x36363636; + opad[i] = bkey[i] ^ 0x5c5c5c5c; + } + const hash = binlMD5(ipad.concat(rstr2binl(data)), 512 + data.length * 8); + return binl2rstr(binlMD5(opad.concat(hash), 512 + 128)); + } + /** + * Convert a raw string to a hex string + * + * @param input Raw input string + * @returns Hex encoded string + */ + function rstr2hex(input) { + const hexTab = "0123456789abcdef"; + let output = ""; + for (let i = 0; i < input.length; i += 1) { + const x = input.charCodeAt(i); + output += hexTab.charAt((x >>> 4) & 0x0f) + hexTab.charAt(x & 0x0f); + } + return output; + } + /** + * Encode a string as UTF-8 + * + * @param input Input string + * @returns UTF8 string + */ + function str2rstrUTF8(input) { + return unescape(encodeURIComponent(input)); + } + /** + * Encodes input string as raw MD5 string + * + * @param s Input string + * @returns Raw MD5 string + */ + function rawMD5(s) { + return rstrMD5(str2rstrUTF8(s)); + } + /** + * Encodes input string as Hex encoded string + * + * @param s Input string + * @returns Hex encoded string + */ + function hexMD5(s) { + return rstr2hex(rawMD5(s)); + } + /** + * Calculates the raw HMAC-MD5 for the given key and data + * + * @param k HMAC key + * @param d Input string + * @returns Raw MD5 string + */ + function rawHMACMD5(k, d) { + return rstrHMACMD5(str2rstrUTF8(k), str2rstrUTF8(d)); + } + /** + * Calculates the Hex encoded HMAC-MD5 for the given key and data + * + * @param k HMAC key + * @param d Input string + * @returns Raw MD5 string + */ + function hexHMACMD5(k, d) { + return rstr2hex(rawHMACMD5(k, d)); + } + /** + * Calculates MD5 value for a given string. + * If a key is provided, calculates the HMAC-MD5 value. + * Returns a Hex encoded string unless the raw argument is given. + * + * @param string Input string + * @param key HMAC key + * @param raw Raw output switch + * @returns MD5 output + */ + function md5(string, key, raw) { + if (!key) { + if (!raw) { + return hexMD5(string); + } + return rawMD5(string); + } + if (!raw) { + return hexHMACMD5(key, string); + } + return rawHMACMD5(key, string); + } + + const MAX_HEADER_VALUE = 3072; + /** + * + * Splits headers according to spec + * @param headers + * @returns Split headers + */ + function splitHeaders(headers) { + const output = new Headers(headers); + if (headers.has("x-bare-headers")) { + const value = headers.get("x-bare-headers"); + if (value.length > MAX_HEADER_VALUE) { + output.delete("x-bare-headers"); + let split = 0; + for (let i = 0; i < value.length; i += MAX_HEADER_VALUE) { + const part = value.slice(i, i + MAX_HEADER_VALUE); + const id = split++; + output.set(`x-bare-headers-${id}`, `;${part}`); + } + } + } + return output; + } + /** + * Joins headers according to spec + * @param headers + * @returns Joined headers + */ + function joinHeaders(headers) { + const output = new Headers(headers); + const prefix = "x-bare-headers"; + if (headers.has(`${prefix}-0`)) { + const join = []; + for (const [header, value] of headers) { + if (!header.startsWith(prefix)) { + continue; + } + if (!value.startsWith(";")) { + throw new BareError(400, { + code: "INVALID_BARE_HEADER", + id: `request.headers.${header}`, + message: `Value didn't begin with semi-colon.` + }); + } + const id = parseInt(header.slice(prefix.length + 1)); + join[id] = value.slice(1); + output.delete(header); + } + output.set(prefix, join.join("")); + } + return output; + } + + class ClientV3 extends Client { + ws; + http; + meta() { + return {}; + } + constructor(server) { + super(3, server); + this.ws = new URL(this.base); + this.http = new URL(this.base); + if (this.ws.protocol === "https:") { + this.ws.protocol = "wss:"; + } else { + this.ws.protocol = "ws:"; + } + } + ready = true; + async init() { + this.ready = true; + } + connect( + url, + origin, + protocols, + requestHeaders, + onopen, + onmessage, + onclose, + onerror + ) { + const ws = new WebSocket(this.ws); + const cleanup = () => { + ws.removeEventListener("close", closeListener); + ws.removeEventListener("message", messageListener); + }; + const closeListener = () => { + cleanup(); + }; + const messageListener = (event) => { + cleanup(); + // ws.binaryType is irrelevant when sending text + if (typeof event.data !== "string") + throw new TypeError( + "the first websocket message was not a text frame" + ); + const message = JSON.parse(event.data); + // finally + if (message.type !== "open") + throw new TypeError("message was not of open type"); + // onMeta({ + // protocol: message.protocol, + // setCookies: message.setCookies, + // }); + onopen(message.protocol); + // TODO + ws.addEventListener("message", (ev) => { + onmessage(ev.data); + }); + }; + ws.addEventListener("close", closeListener); + ws.addEventListener("message", messageListener); + // CONNECTED TO THE BARE SERVER, NOT THE REMOTE + ws.addEventListener( + "open", + (event) => { + // getRequestHeaders().then((headers:any) => + WebSocketFields.prototype.send.call( + ws, + JSON.stringify({ + type: "connect", + remote: url.toString(), + protocols, + headers: requestHeaders, + forwardHeaders: [] + }) + ); + // ); + }, + // only block the open event once + { once: true } + ); + return ws.send.bind(ws); + } + async request(remote, method, body, headers, signal) { + const options = { + credentials: "omit", + method: method, + signal + }; + if (body !== undefined) { + options.body = body; + } + options.headers = this.createBareHeaders(remote, headers); + const response = await fetch( + this.http + "?cache=" + md5(remote.toString()), + options + ); + const readResponse = await this.readBareResponse(response); + // const result: Response & Partial = new Response( + // statusEmpty.includes(readResponse.status!) ? undefined : response.body, + // { + // status: readResponse.status, + // statusText: readResponse.statusText ?? undefined, + // headers: new Headers(readResponse.headers as HeadersInit), + // } + // ); + // + // result.rawHeaders = readResponse.headers; + // result.rawResponse = response; + return { + body: response.body, + headers: readResponse.headers, + status: readResponse.status, + statusText: readResponse.statusText + }; + } + async readBareResponse(response) { + if (!response.ok) { + throw new BareError(response.status, await response.json()); + } + const responseHeaders = joinHeaders(response.headers); + const result = {}; + const xBareStatus = responseHeaders.get("x-bare-status"); + if (xBareStatus !== null) result.status = parseInt(xBareStatus); + const xBareStatusText = responseHeaders.get("x-bare-status-text"); + if (xBareStatusText !== null) result.statusText = xBareStatusText; + const xBareHeaders = responseHeaders.get("x-bare-headers"); + if (xBareHeaders !== null) result.headers = JSON.parse(xBareHeaders); + return result; + } + createBareHeaders( + remote, + bareHeaders, + forwardHeaders = [], + passHeaders = [], + passStatus = [] + ) { + const headers = new Headers(); + headers.set("x-bare-url", remote.toString()); + headers.set("x-bare-headers", JSON.stringify(bareHeaders)); + for (const header of forwardHeaders) { + headers.append("x-bare-forward-headers", header); + } + for (const header of passHeaders) { + headers.append("x-bare-pass-headers", header); + } + for (const status of passStatus) { + headers.append("x-bare-pass-status", status.toString()); + } + splitHeaders(headers); + return headers; + } + } + + exports.BareClient = ClientV3; +}); +//# sourceMappingURL=bare.cjs.map diff --git a/src/pages/Settings/Proxy.tsx b/src/pages/Settings/Proxy.tsx index 8a59804..451eb0b 100644 --- a/src/pages/Settings/Proxy.tsx +++ b/src/pages/Settings/Proxy.tsx @@ -9,6 +9,8 @@ import { useTranslation } from "react-i18next"; const Proxy = ({ id, active }) => { const { t } = useTranslation(); + const transport = localStorage.getItem("transport") || "libcurl"; + const proccy = localStorage.getItem("proxy") || "automatic"; const engines = [ { id: "automatic", label: t("settings.proxy.automatic") }, @@ -34,8 +36,9 @@ const Proxy = ({ id, active }) => { location.host + "/wisp/"; const transports = [ - { id: "epoxy", label: "Epoxy" }, - { id: "libcurl", label: "Libcurl" } + { id: "libcurl", label: "Libcurl" }, + { id: "bare", label: "Bare Server" }, + { id: "epoxy", label: "Epoxy" } ]; return ( @@ -86,24 +89,28 @@ const Proxy = ({ id, active }) => { refresh={false} /> -
-
- {t("settings.bare.title")} + {transport === "bare" && ( +
+
+ {t("settings.bare.title")} +
+
+ {t("settings.bare.subtitle")} +
+
-
- {t("settings.bare.subtitle")} + )} + {transport !== "bare" && ( +
+
+ Wisp Server +
+
+ Enter the url of a Wisp server +
+
- -
-
-
- Wisp Server -
-
- Enter the url of a Wisp server -
- -
+ )}
Transport @@ -114,8 +121,7 @@ const Proxy = ({ id, active }) => { changeTransport(value, wispUrl)} + refresh={true} />
diff --git a/src/util/transports.ts b/src/util/transports.ts index bcf41b1..e7efefd 100644 --- a/src/util/transports.ts +++ b/src/util/transports.ts @@ -3,13 +3,6 @@ import { registerRemoteListener } from "@mercuryworkshop/bare-mux"; -declare global { - interface Window { - BareMux: any; - p: any; - } -} - function changeTransport(transport: string, wispUrl: string) { switch (transport) { case "epoxy": @@ -22,12 +15,22 @@ function changeTransport(transport: string, wispUrl: string) { console.log("Setting transport to Libcurl"); SetTransport("CurlMod.LibcurlClient", { wisp: wispUrl, - wasm: "/libcurl.wasm" + wasm: "https://cdn.jsdelivr.net/npm/libcurl.js@v0.5.2/libcurl.wasm" }); break; - //stuff like bare-as-module3 COULD also be added + case "bare": + localStorage.setItem("transport", "bare"); + console.log("Setting transport to Bare"); + const bare = + localStorage.getItem("bare") || window.location.origin + "/bare/"; + console.log("Bare URL: " + bare); + SetTransport("BareMod.BareClient", bare); + break; default: - SetTransport("EpxMod.EpoxyClient", { wisp: wispUrl }); + SetTransport("CurlMod.LibcurlClient", { + wisp: wispUrl, + wasm: "/libcurl.wasm" + }); break; } } @@ -42,7 +45,7 @@ const wispUrl = "/wisp/"; registerRemoteListener(navigator.serviceWorker.controller!); changeTransport( - localStorage.getItem("transport") || "epoxy", + localStorage.getItem("transport") || "libcurl", localStorage.getItem("wispUrl") || wispUrl );