From 37526a2b6aaecd9f625446366d495bc7b354829b Mon Sep 17 00:00:00 2001 From: bia-pain-bache Date: Sat, 12 Oct 2024 16:26:39 +0330 Subject: [PATCH] Revised authentication. --- _worker.js | 1360 ++++++++++++++++++++++++++++++++++++++++++++++--- src/worker.js | 66 +-- 2 files changed, 1300 insertions(+), 126 deletions(-) diff --git a/_worker.js b/_worker.js index 170c90f7f..484b4fd9b 100644 --- a/_worker.js +++ b/_worker.js @@ -2447,8 +2447,8 @@ var require_sha256 = __commonJS({ }; } var createOutputMethod = function(outputType, is224) { - return function(message) { - return new Sha256(is224, true).update(message)[outputType](); + return function(message2) { + return new Sha256(is224, true).update(message2)[outputType](); }; }; var createMethod = function(is224) { @@ -2459,8 +2459,8 @@ var require_sha256 = __commonJS({ method.create = function() { return new Sha256(is224); }; - method.update = function(message) { - return method.create().update(message); + method.update = function(message2) { + return method.create().update(message2); }; for (var i = 0; i < OUTPUT_TYPES.length; ++i) { var type = OUTPUT_TYPES[i]; @@ -2476,31 +2476,31 @@ var require_sha256 = __commonJS({ if (Buffer2.from && !root.JS_SHA256_NO_BUFFER_FROM) { bufferFrom = Buffer2.from; } else { - bufferFrom = function(message) { - return new Buffer2(message); + bufferFrom = function(message2) { + return new Buffer2(message2); }; } - var nodeMethod = function(message) { - if (typeof message === "string") { - return crypto2.createHash(algorithm).update(message, "utf8").digest("hex"); + var nodeMethod = function(message2) { + if (typeof message2 === "string") { + return crypto2.createHash(algorithm).update(message2, "utf8").digest("hex"); } else { - if (message === null || message === void 0) { + if (message2 === null || message2 === void 0) { throw new Error(ERROR); - } else if (message.constructor === ArrayBuffer) { - message = new Uint8Array(message); + } else if (message2.constructor === ArrayBuffer) { + message2 = new Uint8Array(message2); } } - if (Array.isArray(message) || ArrayBuffer.isView(message) || message.constructor === Buffer2) { - return crypto2.createHash(algorithm).update(bufferFrom(message)).digest("hex"); + if (Array.isArray(message2) || ArrayBuffer.isView(message2) || message2.constructor === Buffer2) { + return crypto2.createHash(algorithm).update(bufferFrom(message2)).digest("hex"); } else { - return method(message); + return method(message2); } }; return nodeMethod; }; var createHmacOutputMethod = function(outputType, is224) { - return function(key, message) { - return new HmacSha256(key, is224, true).update(message)[outputType](); + return function(key, message2) { + return new HmacSha256(key, is224, true).update(message2)[outputType](); }; }; var createHmacMethod = function(is224) { @@ -2508,8 +2508,8 @@ var require_sha256 = __commonJS({ method.create = function(key) { return new HmacSha256(key, is224); }; - method.update = function(key, message) { - return method.create(key).update(message); + method.update = function(key, message2) { + return method.create(key).update(message2); }; for (var i = 0; i < OUTPUT_TYPES.length; ++i) { var type = OUTPUT_TYPES[i]; @@ -2548,19 +2548,19 @@ var require_sha256 = __commonJS({ this.first = true; this.is224 = is224; } - Sha256.prototype.update = function(message) { + Sha256.prototype.update = function(message2) { if (this.finalized) { return; } - var notString, type = typeof message; + var notString, type = typeof message2; if (type !== "string") { if (type === "object") { - if (message === null) { + if (message2 === null) { throw new Error(ERROR); - } else if (ARRAY_BUFFER && message.constructor === ArrayBuffer) { - message = new Uint8Array(message); - } else if (!Array.isArray(message)) { - if (!ARRAY_BUFFER || !ArrayBuffer.isView(message)) { + } else if (ARRAY_BUFFER && message2.constructor === ArrayBuffer) { + message2 = new Uint8Array(message2); + } else if (!Array.isArray(message2)) { + if (!ARRAY_BUFFER || !ArrayBuffer.isView(message2)) { throw new Error(ERROR); } } @@ -2569,7 +2569,7 @@ var require_sha256 = __commonJS({ } notString = true; } - var code, index = 0, i, length = message.length, blocks2 = this.blocks; + var code, index = 0, i, length = message2.length, blocks2 = this.blocks; while (index < length) { if (this.hashed) { this.hashed = false; @@ -2578,11 +2578,11 @@ var require_sha256 = __commonJS({ } if (notString) { for (i = this.start; index < length && i < 64; ++index) { - blocks2[i >>> 2] |= message[index] << SHIFT[i++ & 3]; + blocks2[i >>> 2] |= message2[index] << SHIFT[i++ & 3]; } } else { for (i = this.start; index < length && i < 64; ++index) { - code = message.charCodeAt(index); + code = message2.charCodeAt(index); if (code < 128) { blocks2[i >>> 2] |= code << SHIFT[i++ & 3]; } else if (code < 2048) { @@ -2593,7 +2593,7 @@ var require_sha256 = __commonJS({ blocks2[i >>> 2] |= (128 | code >>> 6 & 63) << SHIFT[i++ & 3]; blocks2[i >>> 2] |= (128 | code & 63) << SHIFT[i++ & 3]; } else { - code = 65536 + ((code & 1023) << 10 | message.charCodeAt(++index) & 1023); + code = 65536 + ((code & 1023) << 10 | message2.charCodeAt(++index) & 1023); blocks2[i >>> 2] |= (240 | code >>> 18) << SHIFT[i++ & 3]; blocks2[i >>> 2] |= (128 | code >>> 12 & 63) << SHIFT[i++ & 3]; blocks2[i >>> 2] |= (128 | code >>> 6 & 63) << SHIFT[i++ & 3]; @@ -2866,6 +2866,1225 @@ var require_sha256 = __commonJS({ var import_tweetnacl = __toESM(require_nacl_fast()); var import_js_sha256 = __toESM(require_sha256()); import { connect } from "cloudflare:sockets"; + +// node_modules/jose/dist/browser/runtime/webcrypto.js +var webcrypto_default = crypto; +var isCryptoKey = (key) => key instanceof CryptoKey; + +// node_modules/jose/dist/browser/lib/buffer_utils.js +var encoder = new TextEncoder(); +var decoder = new TextDecoder(); +var MAX_INT32 = 2 ** 32; +function concat(...buffers) { + const size = buffers.reduce((acc, { length }) => acc + length, 0); + const buf = new Uint8Array(size); + let i = 0; + for (const buffer of buffers) { + buf.set(buffer, i); + i += buffer.length; + } + return buf; +} + +// node_modules/jose/dist/browser/runtime/base64url.js +var encodeBase64 = (input) => { + let unencoded = input; + if (typeof unencoded === "string") { + unencoded = encoder.encode(unencoded); + } + const CHUNK_SIZE = 32768; + const arr = []; + for (let i = 0; i < unencoded.length; i += CHUNK_SIZE) { + arr.push(String.fromCharCode.apply(null, unencoded.subarray(i, i + CHUNK_SIZE))); + } + return btoa(arr.join("")); +}; +var encode = (input) => { + return encodeBase64(input).replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_"); +}; +var decodeBase64 = (encoded) => { + const binary = atob(encoded); + const bytes = new Uint8Array(binary.length); + for (let i = 0; i < binary.length; i++) { + bytes[i] = binary.charCodeAt(i); + } + return bytes; +}; +var decode = (input) => { + let encoded = input; + if (encoded instanceof Uint8Array) { + encoded = decoder.decode(encoded); + } + encoded = encoded.replace(/-/g, "+").replace(/_/g, "/").replace(/\s/g, ""); + try { + return decodeBase64(encoded); + } catch { + throw new TypeError("The input to be decoded is not correctly encoded."); + } +}; + +// node_modules/jose/dist/browser/util/errors.js +var JOSEError = class extends Error { + constructor(message2, options) { + super(message2, options); + this.code = "ERR_JOSE_GENERIC"; + this.name = this.constructor.name; + Error.captureStackTrace?.(this, this.constructor); + } +}; +JOSEError.code = "ERR_JOSE_GENERIC"; +var JWTClaimValidationFailed = class extends JOSEError { + constructor(message2, payload, claim = "unspecified", reason = "unspecified") { + super(message2, { cause: { claim, reason, payload } }); + this.code = "ERR_JWT_CLAIM_VALIDATION_FAILED"; + this.claim = claim; + this.reason = reason; + this.payload = payload; + } +}; +JWTClaimValidationFailed.code = "ERR_JWT_CLAIM_VALIDATION_FAILED"; +var JWTExpired = class extends JOSEError { + constructor(message2, payload, claim = "unspecified", reason = "unspecified") { + super(message2, { cause: { claim, reason, payload } }); + this.code = "ERR_JWT_EXPIRED"; + this.claim = claim; + this.reason = reason; + this.payload = payload; + } +}; +JWTExpired.code = "ERR_JWT_EXPIRED"; +var JOSEAlgNotAllowed = class extends JOSEError { + constructor() { + super(...arguments); + this.code = "ERR_JOSE_ALG_NOT_ALLOWED"; + } +}; +JOSEAlgNotAllowed.code = "ERR_JOSE_ALG_NOT_ALLOWED"; +var JOSENotSupported = class extends JOSEError { + constructor() { + super(...arguments); + this.code = "ERR_JOSE_NOT_SUPPORTED"; + } +}; +JOSENotSupported.code = "ERR_JOSE_NOT_SUPPORTED"; +var JWEDecryptionFailed = class extends JOSEError { + constructor(message2 = "decryption operation failed", options) { + super(message2, options); + this.code = "ERR_JWE_DECRYPTION_FAILED"; + } +}; +JWEDecryptionFailed.code = "ERR_JWE_DECRYPTION_FAILED"; +var JWEInvalid = class extends JOSEError { + constructor() { + super(...arguments); + this.code = "ERR_JWE_INVALID"; + } +}; +JWEInvalid.code = "ERR_JWE_INVALID"; +var JWSInvalid = class extends JOSEError { + constructor() { + super(...arguments); + this.code = "ERR_JWS_INVALID"; + } +}; +JWSInvalid.code = "ERR_JWS_INVALID"; +var JWTInvalid = class extends JOSEError { + constructor() { + super(...arguments); + this.code = "ERR_JWT_INVALID"; + } +}; +JWTInvalid.code = "ERR_JWT_INVALID"; +var JWKInvalid = class extends JOSEError { + constructor() { + super(...arguments); + this.code = "ERR_JWK_INVALID"; + } +}; +JWKInvalid.code = "ERR_JWK_INVALID"; +var JWKSInvalid = class extends JOSEError { + constructor() { + super(...arguments); + this.code = "ERR_JWKS_INVALID"; + } +}; +JWKSInvalid.code = "ERR_JWKS_INVALID"; +var JWKSNoMatchingKey = class extends JOSEError { + constructor(message2 = "no applicable key found in the JSON Web Key Set", options) { + super(message2, options); + this.code = "ERR_JWKS_NO_MATCHING_KEY"; + } +}; +JWKSNoMatchingKey.code = "ERR_JWKS_NO_MATCHING_KEY"; +var JWKSMultipleMatchingKeys = class extends JOSEError { + constructor(message2 = "multiple matching keys found in the JSON Web Key Set", options) { + super(message2, options); + this.code = "ERR_JWKS_MULTIPLE_MATCHING_KEYS"; + } +}; +JWKSMultipleMatchingKeys.code = "ERR_JWKS_MULTIPLE_MATCHING_KEYS"; +var JWKSTimeout = class extends JOSEError { + constructor(message2 = "request timed out", options) { + super(message2, options); + this.code = "ERR_JWKS_TIMEOUT"; + } +}; +JWKSTimeout.code = "ERR_JWKS_TIMEOUT"; +var JWSSignatureVerificationFailed = class extends JOSEError { + constructor(message2 = "signature verification failed", options) { + super(message2, options); + this.code = "ERR_JWS_SIGNATURE_VERIFICATION_FAILED"; + } +}; +JWSSignatureVerificationFailed.code = "ERR_JWS_SIGNATURE_VERIFICATION_FAILED"; + +// node_modules/jose/dist/browser/lib/crypto_key.js +function unusable(name, prop = "algorithm.name") { + return new TypeError(`CryptoKey does not support this operation, its ${prop} must be ${name}`); +} +function isAlgorithm(algorithm, name) { + return algorithm.name === name; +} +function getHashLength(hash) { + return parseInt(hash.name.slice(4), 10); +} +function getNamedCurve(alg) { + switch (alg) { + case "ES256": + return "P-256"; + case "ES384": + return "P-384"; + case "ES512": + return "P-521"; + default: + throw new Error("unreachable"); + } +} +function checkUsage(key, usages) { + if (usages.length && !usages.some((expected) => key.usages.includes(expected))) { + let msg = "CryptoKey does not support this operation, its usages must include "; + if (usages.length > 2) { + const last = usages.pop(); + msg += `one of ${usages.join(", ")}, or ${last}.`; + } else if (usages.length === 2) { + msg += `one of ${usages[0]} or ${usages[1]}.`; + } else { + msg += `${usages[0]}.`; + } + throw new TypeError(msg); + } +} +function checkSigCryptoKey(key, alg, ...usages) { + switch (alg) { + case "HS256": + case "HS384": + case "HS512": { + if (!isAlgorithm(key.algorithm, "HMAC")) + throw unusable("HMAC"); + const expected = parseInt(alg.slice(2), 10); + const actual = getHashLength(key.algorithm.hash); + if (actual !== expected) + throw unusable(`SHA-${expected}`, "algorithm.hash"); + break; + } + case "RS256": + case "RS384": + case "RS512": { + if (!isAlgorithm(key.algorithm, "RSASSA-PKCS1-v1_5")) + throw unusable("RSASSA-PKCS1-v1_5"); + const expected = parseInt(alg.slice(2), 10); + const actual = getHashLength(key.algorithm.hash); + if (actual !== expected) + throw unusable(`SHA-${expected}`, "algorithm.hash"); + break; + } + case "PS256": + case "PS384": + case "PS512": { + if (!isAlgorithm(key.algorithm, "RSA-PSS")) + throw unusable("RSA-PSS"); + const expected = parseInt(alg.slice(2), 10); + const actual = getHashLength(key.algorithm.hash); + if (actual !== expected) + throw unusable(`SHA-${expected}`, "algorithm.hash"); + break; + } + case "EdDSA": { + if (key.algorithm.name !== "Ed25519" && key.algorithm.name !== "Ed448") { + throw unusable("Ed25519 or Ed448"); + } + break; + } + case "ES256": + case "ES384": + case "ES512": { + if (!isAlgorithm(key.algorithm, "ECDSA")) + throw unusable("ECDSA"); + const expected = getNamedCurve(alg); + const actual = key.algorithm.namedCurve; + if (actual !== expected) + throw unusable(expected, "algorithm.namedCurve"); + break; + } + default: + throw new TypeError("CryptoKey does not support this operation"); + } + checkUsage(key, usages); +} + +// node_modules/jose/dist/browser/lib/invalid_key_input.js +function message(msg, actual, ...types2) { + types2 = types2.filter(Boolean); + if (types2.length > 2) { + const last = types2.pop(); + msg += `one of type ${types2.join(", ")}, or ${last}.`; + } else if (types2.length === 2) { + msg += `one of type ${types2[0]} or ${types2[1]}.`; + } else { + msg += `of type ${types2[0]}.`; + } + if (actual == null) { + msg += ` Received ${actual}`; + } else if (typeof actual === "function" && actual.name) { + msg += ` Received function ${actual.name}`; + } else if (typeof actual === "object" && actual != null) { + if (actual.constructor?.name) { + msg += ` Received an instance of ${actual.constructor.name}`; + } + } + return msg; +} +var invalid_key_input_default = (actual, ...types2) => { + return message("Key must be ", actual, ...types2); +}; +function withAlg(alg, actual, ...types2) { + return message(`Key for the ${alg} algorithm must be `, actual, ...types2); +} + +// node_modules/jose/dist/browser/runtime/is_key_like.js +var is_key_like_default = (key) => { + if (isCryptoKey(key)) { + return true; + } + return key?.[Symbol.toStringTag] === "KeyObject"; +}; +var types = ["CryptoKey"]; + +// node_modules/jose/dist/browser/lib/is_disjoint.js +var isDisjoint = (...headers) => { + const sources = headers.filter(Boolean); + if (sources.length === 0 || sources.length === 1) { + return true; + } + let acc; + for (const header of sources) { + const parameters = Object.keys(header); + if (!acc || acc.size === 0) { + acc = new Set(parameters); + continue; + } + for (const parameter of parameters) { + if (acc.has(parameter)) { + return false; + } + acc.add(parameter); + } + } + return true; +}; +var is_disjoint_default = isDisjoint; + +// node_modules/jose/dist/browser/lib/is_object.js +function isObjectLike(value) { + return typeof value === "object" && value !== null; +} +function isObject(input) { + if (!isObjectLike(input) || Object.prototype.toString.call(input) !== "[object Object]") { + return false; + } + if (Object.getPrototypeOf(input) === null) { + return true; + } + let proto = input; + while (Object.getPrototypeOf(proto) !== null) { + proto = Object.getPrototypeOf(proto); + } + return Object.getPrototypeOf(input) === proto; +} + +// node_modules/jose/dist/browser/runtime/check_key_length.js +var check_key_length_default = (alg, key) => { + if (alg.startsWith("RS") || alg.startsWith("PS")) { + const { modulusLength } = key.algorithm; + if (typeof modulusLength !== "number" || modulusLength < 2048) { + throw new TypeError(`${alg} requires key modulusLength to be 2048 bits or larger`); + } + } +}; + +// node_modules/jose/dist/browser/lib/is_jwk.js +function isJWK(key) { + return isObject(key) && typeof key.kty === "string"; +} +function isPrivateJWK(key) { + return key.kty !== "oct" && typeof key.d === "string"; +} +function isPublicJWK(key) { + return key.kty !== "oct" && typeof key.d === "undefined"; +} +function isSecretJWK(key) { + return isJWK(key) && key.kty === "oct" && typeof key.k === "string"; +} + +// node_modules/jose/dist/browser/runtime/jwk_to_key.js +function subtleMapping(jwk) { + let algorithm; + let keyUsages; + switch (jwk.kty) { + case "RSA": { + switch (jwk.alg) { + case "PS256": + case "PS384": + case "PS512": + algorithm = { name: "RSA-PSS", hash: `SHA-${jwk.alg.slice(-3)}` }; + keyUsages = jwk.d ? ["sign"] : ["verify"]; + break; + case "RS256": + case "RS384": + case "RS512": + algorithm = { name: "RSASSA-PKCS1-v1_5", hash: `SHA-${jwk.alg.slice(-3)}` }; + keyUsages = jwk.d ? ["sign"] : ["verify"]; + break; + case "RSA-OAEP": + case "RSA-OAEP-256": + case "RSA-OAEP-384": + case "RSA-OAEP-512": + algorithm = { + name: "RSA-OAEP", + hash: `SHA-${parseInt(jwk.alg.slice(-3), 10) || 1}` + }; + keyUsages = jwk.d ? ["decrypt", "unwrapKey"] : ["encrypt", "wrapKey"]; + break; + default: + throw new JOSENotSupported('Invalid or unsupported JWK "alg" (Algorithm) Parameter value'); + } + break; + } + case "EC": { + switch (jwk.alg) { + case "ES256": + algorithm = { name: "ECDSA", namedCurve: "P-256" }; + keyUsages = jwk.d ? ["sign"] : ["verify"]; + break; + case "ES384": + algorithm = { name: "ECDSA", namedCurve: "P-384" }; + keyUsages = jwk.d ? ["sign"] : ["verify"]; + break; + case "ES512": + algorithm = { name: "ECDSA", namedCurve: "P-521" }; + keyUsages = jwk.d ? ["sign"] : ["verify"]; + break; + case "ECDH-ES": + case "ECDH-ES+A128KW": + case "ECDH-ES+A192KW": + case "ECDH-ES+A256KW": + algorithm = { name: "ECDH", namedCurve: jwk.crv }; + keyUsages = jwk.d ? ["deriveBits"] : []; + break; + default: + throw new JOSENotSupported('Invalid or unsupported JWK "alg" (Algorithm) Parameter value'); + } + break; + } + case "OKP": { + switch (jwk.alg) { + case "EdDSA": + algorithm = { name: jwk.crv }; + keyUsages = jwk.d ? ["sign"] : ["verify"]; + break; + case "ECDH-ES": + case "ECDH-ES+A128KW": + case "ECDH-ES+A192KW": + case "ECDH-ES+A256KW": + algorithm = { name: jwk.crv }; + keyUsages = jwk.d ? ["deriveBits"] : []; + break; + default: + throw new JOSENotSupported('Invalid or unsupported JWK "alg" (Algorithm) Parameter value'); + } + break; + } + default: + throw new JOSENotSupported('Invalid or unsupported JWK "kty" (Key Type) Parameter value'); + } + return { algorithm, keyUsages }; +} +var parse = async (jwk) => { + if (!jwk.alg) { + throw new TypeError('"alg" argument is required when "jwk.alg" is not present'); + } + const { algorithm, keyUsages } = subtleMapping(jwk); + const rest = [ + algorithm, + jwk.ext ?? false, + jwk.key_ops ?? keyUsages + ]; + const keyData = { ...jwk }; + delete keyData.alg; + delete keyData.use; + return webcrypto_default.subtle.importKey("jwk", keyData, ...rest); +}; +var jwk_to_key_default = parse; + +// node_modules/jose/dist/browser/runtime/normalize_key.js +var exportKeyValue = (k) => decode(k); +var privCache; +var pubCache; +var isKeyObject = (key) => { + return key?.[Symbol.toStringTag] === "KeyObject"; +}; +var importAndCache = async (cache, key, jwk, alg, freeze = false) => { + let cached = cache.get(key); + if (cached?.[alg]) { + return cached[alg]; + } + const cryptoKey = await jwk_to_key_default({ ...jwk, alg }); + if (freeze) + Object.freeze(key); + if (!cached) { + cache.set(key, { [alg]: cryptoKey }); + } else { + cached[alg] = cryptoKey; + } + return cryptoKey; +}; +var normalizePublicKey = (key, alg) => { + if (isKeyObject(key)) { + let jwk = key.export({ format: "jwk" }); + delete jwk.d; + delete jwk.dp; + delete jwk.dq; + delete jwk.p; + delete jwk.q; + delete jwk.qi; + if (jwk.k) { + return exportKeyValue(jwk.k); + } + pubCache || (pubCache = /* @__PURE__ */ new WeakMap()); + return importAndCache(pubCache, key, jwk, alg); + } + if (isJWK(key)) { + if (key.k) + return decode(key.k); + pubCache || (pubCache = /* @__PURE__ */ new WeakMap()); + const cryptoKey = importAndCache(pubCache, key, key, alg, true); + return cryptoKey; + } + return key; +}; +var normalizePrivateKey = (key, alg) => { + if (isKeyObject(key)) { + let jwk = key.export({ format: "jwk" }); + if (jwk.k) { + return exportKeyValue(jwk.k); + } + privCache || (privCache = /* @__PURE__ */ new WeakMap()); + return importAndCache(privCache, key, jwk, alg); + } + if (isJWK(key)) { + if (key.k) + return decode(key.k); + privCache || (privCache = /* @__PURE__ */ new WeakMap()); + const cryptoKey = importAndCache(privCache, key, key, alg, true); + return cryptoKey; + } + return key; +}; +var normalize_key_default = { normalizePublicKey, normalizePrivateKey }; + +// node_modules/jose/dist/browser/key/import.js +async function importJWK(jwk, alg) { + if (!isObject(jwk)) { + throw new TypeError("JWK must be an object"); + } + alg || (alg = jwk.alg); + switch (jwk.kty) { + case "oct": + if (typeof jwk.k !== "string" || !jwk.k) { + throw new TypeError('missing "k" (Key Value) Parameter value'); + } + return decode(jwk.k); + case "RSA": + if (jwk.oth !== void 0) { + throw new JOSENotSupported('RSA JWK "oth" (Other Primes Info) Parameter value is not supported'); + } + case "EC": + case "OKP": + return jwk_to_key_default({ ...jwk, alg }); + default: + throw new JOSENotSupported('Unsupported "kty" (Key Type) Parameter value'); + } +} + +// node_modules/jose/dist/browser/lib/check_key_type.js +var tag = (key) => key?.[Symbol.toStringTag]; +var jwkMatchesOp = (alg, key, usage) => { + if (key.use !== void 0 && key.use !== "sig") { + throw new TypeError("Invalid key for this operation, when present its use must be sig"); + } + if (key.key_ops !== void 0 && key.key_ops.includes?.(usage) !== true) { + throw new TypeError(`Invalid key for this operation, when present its key_ops must include ${usage}`); + } + if (key.alg !== void 0 && key.alg !== alg) { + throw new TypeError(`Invalid key for this operation, when present its alg must be ${alg}`); + } + return true; +}; +var symmetricTypeCheck = (alg, key, usage, allowJwk) => { + if (key instanceof Uint8Array) + return; + if (allowJwk && isJWK(key)) { + if (isSecretJWK(key) && jwkMatchesOp(alg, key, usage)) + return; + throw new TypeError(`JSON Web Key for symmetric algorithms must have JWK "kty" (Key Type) equal to "oct" and the JWK "k" (Key Value) present`); + } + if (!is_key_like_default(key)) { + throw new TypeError(withAlg(alg, key, ...types, "Uint8Array", allowJwk ? "JSON Web Key" : null)); + } + if (key.type !== "secret") { + throw new TypeError(`${tag(key)} instances for symmetric algorithms must be of type "secret"`); + } +}; +var asymmetricTypeCheck = (alg, key, usage, allowJwk) => { + if (allowJwk && isJWK(key)) { + switch (usage) { + case "sign": + if (isPrivateJWK(key) && jwkMatchesOp(alg, key, usage)) + return; + throw new TypeError(`JSON Web Key for this operation be a private JWK`); + case "verify": + if (isPublicJWK(key) && jwkMatchesOp(alg, key, usage)) + return; + throw new TypeError(`JSON Web Key for this operation be a public JWK`); + } + } + if (!is_key_like_default(key)) { + throw new TypeError(withAlg(alg, key, ...types, allowJwk ? "JSON Web Key" : null)); + } + if (key.type === "secret") { + throw new TypeError(`${tag(key)} instances for asymmetric algorithms must not be of type "secret"`); + } + if (usage === "sign" && key.type === "public") { + throw new TypeError(`${tag(key)} instances for asymmetric algorithm signing must be of type "private"`); + } + if (usage === "decrypt" && key.type === "public") { + throw new TypeError(`${tag(key)} instances for asymmetric algorithm decryption must be of type "private"`); + } + if (key.algorithm && usage === "verify" && key.type === "private") { + throw new TypeError(`${tag(key)} instances for asymmetric algorithm verifying must be of type "public"`); + } + if (key.algorithm && usage === "encrypt" && key.type === "private") { + throw new TypeError(`${tag(key)} instances for asymmetric algorithm encryption must be of type "public"`); + } +}; +function checkKeyType(allowJwk, alg, key, usage) { + const symmetric = alg.startsWith("HS") || alg === "dir" || alg.startsWith("PBES2") || /^A\d{3}(?:GCM)?KW$/.test(alg); + if (symmetric) { + symmetricTypeCheck(alg, key, usage, allowJwk); + } else { + asymmetricTypeCheck(alg, key, usage, allowJwk); + } +} +var check_key_type_default = checkKeyType.bind(void 0, false); +var checkKeyTypeWithJwk = checkKeyType.bind(void 0, true); + +// node_modules/jose/dist/browser/lib/validate_crit.js +function validateCrit(Err, recognizedDefault, recognizedOption, protectedHeader, joseHeader) { + if (joseHeader.crit !== void 0 && protectedHeader?.crit === void 0) { + throw new Err('"crit" (Critical) Header Parameter MUST be integrity protected'); + } + if (!protectedHeader || protectedHeader.crit === void 0) { + return /* @__PURE__ */ new Set(); + } + if (!Array.isArray(protectedHeader.crit) || protectedHeader.crit.length === 0 || protectedHeader.crit.some((input) => typeof input !== "string" || input.length === 0)) { + throw new Err('"crit" (Critical) Header Parameter MUST be an array of non-empty strings when present'); + } + let recognized; + if (recognizedOption !== void 0) { + recognized = new Map([...Object.entries(recognizedOption), ...recognizedDefault.entries()]); + } else { + recognized = recognizedDefault; + } + for (const parameter of protectedHeader.crit) { + if (!recognized.has(parameter)) { + throw new JOSENotSupported(`Extension Header Parameter "${parameter}" is not recognized`); + } + if (joseHeader[parameter] === void 0) { + throw new Err(`Extension Header Parameter "${parameter}" is missing`); + } + if (recognized.get(parameter) && protectedHeader[parameter] === void 0) { + throw new Err(`Extension Header Parameter "${parameter}" MUST be integrity protected`); + } + } + return new Set(protectedHeader.crit); +} +var validate_crit_default = validateCrit; + +// node_modules/jose/dist/browser/lib/validate_algorithms.js +var validateAlgorithms = (option, algorithms) => { + if (algorithms !== void 0 && (!Array.isArray(algorithms) || algorithms.some((s) => typeof s !== "string"))) { + throw new TypeError(`"${option}" option must be an array of strings`); + } + if (!algorithms) { + return void 0; + } + return new Set(algorithms); +}; +var validate_algorithms_default = validateAlgorithms; + +// node_modules/jose/dist/browser/runtime/subtle_dsa.js +function subtleDsa(alg, algorithm) { + const hash = `SHA-${alg.slice(-3)}`; + switch (alg) { + case "HS256": + case "HS384": + case "HS512": + return { hash, name: "HMAC" }; + case "PS256": + case "PS384": + case "PS512": + return { hash, name: "RSA-PSS", saltLength: alg.slice(-3) >> 3 }; + case "RS256": + case "RS384": + case "RS512": + return { hash, name: "RSASSA-PKCS1-v1_5" }; + case "ES256": + case "ES384": + case "ES512": + return { hash, name: "ECDSA", namedCurve: algorithm.namedCurve }; + case "EdDSA": + return { name: algorithm.name }; + default: + throw new JOSENotSupported(`alg ${alg} is not supported either by JOSE or your javascript runtime`); + } +} + +// node_modules/jose/dist/browser/runtime/get_sign_verify_key.js +async function getCryptoKey(alg, key, usage) { + if (usage === "sign") { + key = await normalize_key_default.normalizePrivateKey(key, alg); + } + if (usage === "verify") { + key = await normalize_key_default.normalizePublicKey(key, alg); + } + if (isCryptoKey(key)) { + checkSigCryptoKey(key, alg, usage); + return key; + } + if (key instanceof Uint8Array) { + if (!alg.startsWith("HS")) { + throw new TypeError(invalid_key_input_default(key, ...types)); + } + return webcrypto_default.subtle.importKey("raw", key, { hash: `SHA-${alg.slice(-3)}`, name: "HMAC" }, false, [usage]); + } + throw new TypeError(invalid_key_input_default(key, ...types, "Uint8Array", "JSON Web Key")); +} + +// node_modules/jose/dist/browser/runtime/verify.js +var verify = async (alg, key, signature, data) => { + const cryptoKey = await getCryptoKey(alg, key, "verify"); + check_key_length_default(alg, cryptoKey); + const algorithm = subtleDsa(alg, cryptoKey.algorithm); + try { + return await webcrypto_default.subtle.verify(algorithm, cryptoKey, signature, data); + } catch { + return false; + } +}; +var verify_default = verify; + +// node_modules/jose/dist/browser/jws/flattened/verify.js +async function flattenedVerify(jws, key, options) { + if (!isObject(jws)) { + throw new JWSInvalid("Flattened JWS must be an object"); + } + if (jws.protected === void 0 && jws.header === void 0) { + throw new JWSInvalid('Flattened JWS must have either of the "protected" or "header" members'); + } + if (jws.protected !== void 0 && typeof jws.protected !== "string") { + throw new JWSInvalid("JWS Protected Header incorrect type"); + } + if (jws.payload === void 0) { + throw new JWSInvalid("JWS Payload missing"); + } + if (typeof jws.signature !== "string") { + throw new JWSInvalid("JWS Signature missing or incorrect type"); + } + if (jws.header !== void 0 && !isObject(jws.header)) { + throw new JWSInvalid("JWS Unprotected Header incorrect type"); + } + let parsedProt = {}; + if (jws.protected) { + try { + const protectedHeader = decode(jws.protected); + parsedProt = JSON.parse(decoder.decode(protectedHeader)); + } catch { + throw new JWSInvalid("JWS Protected Header is invalid"); + } + } + if (!is_disjoint_default(parsedProt, jws.header)) { + throw new JWSInvalid("JWS Protected and JWS Unprotected Header Parameter names must be disjoint"); + } + const joseHeader = { + ...parsedProt, + ...jws.header + }; + const extensions = validate_crit_default(JWSInvalid, /* @__PURE__ */ new Map([["b64", true]]), options?.crit, parsedProt, joseHeader); + let b64 = true; + if (extensions.has("b64")) { + b64 = parsedProt.b64; + if (typeof b64 !== "boolean") { + throw new JWSInvalid('The "b64" (base64url-encode payload) Header Parameter must be a boolean'); + } + } + const { alg } = joseHeader; + if (typeof alg !== "string" || !alg) { + throw new JWSInvalid('JWS "alg" (Algorithm) Header Parameter missing or invalid'); + } + const algorithms = options && validate_algorithms_default("algorithms", options.algorithms); + if (algorithms && !algorithms.has(alg)) { + throw new JOSEAlgNotAllowed('"alg" (Algorithm) Header Parameter value not allowed'); + } + if (b64) { + if (typeof jws.payload !== "string") { + throw new JWSInvalid("JWS Payload must be a string"); + } + } else if (typeof jws.payload !== "string" && !(jws.payload instanceof Uint8Array)) { + throw new JWSInvalid("JWS Payload must be a string or an Uint8Array instance"); + } + let resolvedKey = false; + if (typeof key === "function") { + key = await key(parsedProt, jws); + resolvedKey = true; + checkKeyTypeWithJwk(alg, key, "verify"); + if (isJWK(key)) { + key = await importJWK(key, alg); + } + } else { + checkKeyTypeWithJwk(alg, key, "verify"); + } + const data = concat(encoder.encode(jws.protected ?? ""), encoder.encode("."), typeof jws.payload === "string" ? encoder.encode(jws.payload) : jws.payload); + let signature; + try { + signature = decode(jws.signature); + } catch { + throw new JWSInvalid("Failed to base64url decode the signature"); + } + const verified = await verify_default(alg, key, signature, data); + if (!verified) { + throw new JWSSignatureVerificationFailed(); + } + let payload; + if (b64) { + try { + payload = decode(jws.payload); + } catch { + throw new JWSInvalid("Failed to base64url decode the payload"); + } + } else if (typeof jws.payload === "string") { + payload = encoder.encode(jws.payload); + } else { + payload = jws.payload; + } + const result = { payload }; + if (jws.protected !== void 0) { + result.protectedHeader = parsedProt; + } + if (jws.header !== void 0) { + result.unprotectedHeader = jws.header; + } + if (resolvedKey) { + return { ...result, key }; + } + return result; +} + +// node_modules/jose/dist/browser/jws/compact/verify.js +async function compactVerify(jws, key, options) { + if (jws instanceof Uint8Array) { + jws = decoder.decode(jws); + } + if (typeof jws !== "string") { + throw new JWSInvalid("Compact JWS must be a string or Uint8Array"); + } + const { 0: protectedHeader, 1: payload, 2: signature, length } = jws.split("."); + if (length !== 3) { + throw new JWSInvalid("Invalid Compact JWS"); + } + const verified = await flattenedVerify({ payload, protected: protectedHeader, signature }, key, options); + const result = { payload: verified.payload, protectedHeader: verified.protectedHeader }; + if (typeof key === "function") { + return { ...result, key: verified.key }; + } + return result; +} + +// node_modules/jose/dist/browser/lib/epoch.js +var epoch_default = (date) => Math.floor(date.getTime() / 1e3); + +// node_modules/jose/dist/browser/lib/secs.js +var minute = 60; +var hour = minute * 60; +var day = hour * 24; +var week = day * 7; +var year = day * 365.25; +var REGEX = /^(\+|\-)? ?(\d+|\d+\.\d+) ?(seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)(?: (ago|from now))?$/i; +var secs_default = (str) => { + const matched = REGEX.exec(str); + if (!matched || matched[4] && matched[1]) { + throw new TypeError("Invalid time period format"); + } + const value = parseFloat(matched[2]); + const unit = matched[3].toLowerCase(); + let numericDate; + switch (unit) { + case "sec": + case "secs": + case "second": + case "seconds": + case "s": + numericDate = Math.round(value); + break; + case "minute": + case "minutes": + case "min": + case "mins": + case "m": + numericDate = Math.round(value * minute); + break; + case "hour": + case "hours": + case "hr": + case "hrs": + case "h": + numericDate = Math.round(value * hour); + break; + case "day": + case "days": + case "d": + numericDate = Math.round(value * day); + break; + case "week": + case "weeks": + case "w": + numericDate = Math.round(value * week); + break; + default: + numericDate = Math.round(value * year); + break; + } + if (matched[1] === "-" || matched[4] === "ago") { + return -numericDate; + } + return numericDate; +}; + +// node_modules/jose/dist/browser/lib/jwt_claims_set.js +var normalizeTyp = (value) => value.toLowerCase().replace(/^application\//, ""); +var checkAudiencePresence = (audPayload, audOption) => { + if (typeof audPayload === "string") { + return audOption.includes(audPayload); + } + if (Array.isArray(audPayload)) { + return audOption.some(Set.prototype.has.bind(new Set(audPayload))); + } + return false; +}; +var jwt_claims_set_default = (protectedHeader, encodedPayload, options = {}) => { + let payload; + try { + payload = JSON.parse(decoder.decode(encodedPayload)); + } catch { + } + if (!isObject(payload)) { + throw new JWTInvalid("JWT Claims Set must be a top-level JSON object"); + } + const { typ } = options; + if (typ && (typeof protectedHeader.typ !== "string" || normalizeTyp(protectedHeader.typ) !== normalizeTyp(typ))) { + throw new JWTClaimValidationFailed('unexpected "typ" JWT header value', payload, "typ", "check_failed"); + } + const { requiredClaims = [], issuer, subject, audience, maxTokenAge } = options; + const presenceCheck = [...requiredClaims]; + if (maxTokenAge !== void 0) + presenceCheck.push("iat"); + if (audience !== void 0) + presenceCheck.push("aud"); + if (subject !== void 0) + presenceCheck.push("sub"); + if (issuer !== void 0) + presenceCheck.push("iss"); + for (const claim of new Set(presenceCheck.reverse())) { + if (!(claim in payload)) { + throw new JWTClaimValidationFailed(`missing required "${claim}" claim`, payload, claim, "missing"); + } + } + if (issuer && !(Array.isArray(issuer) ? issuer : [issuer]).includes(payload.iss)) { + throw new JWTClaimValidationFailed('unexpected "iss" claim value', payload, "iss", "check_failed"); + } + if (subject && payload.sub !== subject) { + throw new JWTClaimValidationFailed('unexpected "sub" claim value', payload, "sub", "check_failed"); + } + if (audience && !checkAudiencePresence(payload.aud, typeof audience === "string" ? [audience] : audience)) { + throw new JWTClaimValidationFailed('unexpected "aud" claim value', payload, "aud", "check_failed"); + } + let tolerance; + switch (typeof options.clockTolerance) { + case "string": + tolerance = secs_default(options.clockTolerance); + break; + case "number": + tolerance = options.clockTolerance; + break; + case "undefined": + tolerance = 0; + break; + default: + throw new TypeError("Invalid clockTolerance option type"); + } + const { currentDate } = options; + const now = epoch_default(currentDate || /* @__PURE__ */ new Date()); + if ((payload.iat !== void 0 || maxTokenAge) && typeof payload.iat !== "number") { + throw new JWTClaimValidationFailed('"iat" claim must be a number', payload, "iat", "invalid"); + } + if (payload.nbf !== void 0) { + if (typeof payload.nbf !== "number") { + throw new JWTClaimValidationFailed('"nbf" claim must be a number', payload, "nbf", "invalid"); + } + if (payload.nbf > now + tolerance) { + throw new JWTClaimValidationFailed('"nbf" claim timestamp check failed', payload, "nbf", "check_failed"); + } + } + if (payload.exp !== void 0) { + if (typeof payload.exp !== "number") { + throw new JWTClaimValidationFailed('"exp" claim must be a number', payload, "exp", "invalid"); + } + if (payload.exp <= now - tolerance) { + throw new JWTExpired('"exp" claim timestamp check failed', payload, "exp", "check_failed"); + } + } + if (maxTokenAge) { + const age = now - payload.iat; + const max = typeof maxTokenAge === "number" ? maxTokenAge : secs_default(maxTokenAge); + if (age - tolerance > max) { + throw new JWTExpired('"iat" claim timestamp check failed (too far in the past)', payload, "iat", "check_failed"); + } + if (age < 0 - tolerance) { + throw new JWTClaimValidationFailed('"iat" claim timestamp check failed (it should be in the past)', payload, "iat", "check_failed"); + } + } + return payload; +}; + +// node_modules/jose/dist/browser/jwt/verify.js +async function jwtVerify(jwt, key, options) { + const verified = await compactVerify(jwt, key, options); + if (verified.protectedHeader.crit?.includes("b64") && verified.protectedHeader.b64 === false) { + throw new JWTInvalid("JWTs MUST NOT use unencoded payload"); + } + const payload = jwt_claims_set_default(verified.protectedHeader, verified.payload, options); + const result = { payload, protectedHeader: verified.protectedHeader }; + if (typeof key === "function") { + return { ...result, key: verified.key }; + } + return result; +} + +// node_modules/jose/dist/browser/runtime/sign.js +var sign = async (alg, key, data) => { + const cryptoKey = await getCryptoKey(alg, key, "sign"); + check_key_length_default(alg, cryptoKey); + const signature = await webcrypto_default.subtle.sign(subtleDsa(alg, cryptoKey.algorithm), cryptoKey, data); + return new Uint8Array(signature); +}; +var sign_default = sign; + +// node_modules/jose/dist/browser/jws/flattened/sign.js +var FlattenedSign = class { + constructor(payload) { + if (!(payload instanceof Uint8Array)) { + throw new TypeError("payload must be an instance of Uint8Array"); + } + this._payload = payload; + } + setProtectedHeader(protectedHeader) { + if (this._protectedHeader) { + throw new TypeError("setProtectedHeader can only be called once"); + } + this._protectedHeader = protectedHeader; + return this; + } + setUnprotectedHeader(unprotectedHeader) { + if (this._unprotectedHeader) { + throw new TypeError("setUnprotectedHeader can only be called once"); + } + this._unprotectedHeader = unprotectedHeader; + return this; + } + async sign(key, options) { + if (!this._protectedHeader && !this._unprotectedHeader) { + throw new JWSInvalid("either setProtectedHeader or setUnprotectedHeader must be called before #sign()"); + } + if (!is_disjoint_default(this._protectedHeader, this._unprotectedHeader)) { + throw new JWSInvalid("JWS Protected and JWS Unprotected Header Parameter names must be disjoint"); + } + const joseHeader = { + ...this._protectedHeader, + ...this._unprotectedHeader + }; + const extensions = validate_crit_default(JWSInvalid, /* @__PURE__ */ new Map([["b64", true]]), options?.crit, this._protectedHeader, joseHeader); + let b64 = true; + if (extensions.has("b64")) { + b64 = this._protectedHeader.b64; + if (typeof b64 !== "boolean") { + throw new JWSInvalid('The "b64" (base64url-encode payload) Header Parameter must be a boolean'); + } + } + const { alg } = joseHeader; + if (typeof alg !== "string" || !alg) { + throw new JWSInvalid('JWS "alg" (Algorithm) Header Parameter missing or invalid'); + } + checkKeyTypeWithJwk(alg, key, "sign"); + let payload = this._payload; + if (b64) { + payload = encoder.encode(encode(payload)); + } + let protectedHeader; + if (this._protectedHeader) { + protectedHeader = encoder.encode(encode(JSON.stringify(this._protectedHeader))); + } else { + protectedHeader = encoder.encode(""); + } + const data = concat(protectedHeader, encoder.encode("."), payload); + const signature = await sign_default(alg, key, data); + const jws = { + signature: encode(signature), + payload: "" + }; + if (b64) { + jws.payload = decoder.decode(payload); + } + if (this._unprotectedHeader) { + jws.header = this._unprotectedHeader; + } + if (this._protectedHeader) { + jws.protected = decoder.decode(protectedHeader); + } + return jws; + } +}; + +// node_modules/jose/dist/browser/jws/compact/sign.js +var CompactSign = class { + constructor(payload) { + this._flattened = new FlattenedSign(payload); + } + setProtectedHeader(protectedHeader) { + this._flattened.setProtectedHeader(protectedHeader); + return this; + } + async sign(key, options) { + const jws = await this._flattened.sign(key, options); + if (jws.payload === void 0) { + throw new TypeError("use the flattened module for creating JWS with b64: false"); + } + return `${jws.protected}.${jws.payload}.${jws.signature}`; + } +}; + +// node_modules/jose/dist/browser/jwt/produce.js +function validateInput(label, input) { + if (!Number.isFinite(input)) { + throw new TypeError(`Invalid ${label} input`); + } + return input; +} +var ProduceJWT = class { + constructor(payload = {}) { + if (!isObject(payload)) { + throw new TypeError("JWT Claims Set MUST be an object"); + } + this._payload = payload; + } + setIssuer(issuer) { + this._payload = { ...this._payload, iss: issuer }; + return this; + } + setSubject(subject) { + this._payload = { ...this._payload, sub: subject }; + return this; + } + setAudience(audience) { + this._payload = { ...this._payload, aud: audience }; + return this; + } + setJti(jwtId) { + this._payload = { ...this._payload, jti: jwtId }; + return this; + } + setNotBefore(input) { + if (typeof input === "number") { + this._payload = { ...this._payload, nbf: validateInput("setNotBefore", input) }; + } else if (input instanceof Date) { + this._payload = { ...this._payload, nbf: validateInput("setNotBefore", epoch_default(input)) }; + } else { + this._payload = { ...this._payload, nbf: epoch_default(/* @__PURE__ */ new Date()) + secs_default(input) }; + } + return this; + } + setExpirationTime(input) { + if (typeof input === "number") { + this._payload = { ...this._payload, exp: validateInput("setExpirationTime", input) }; + } else if (input instanceof Date) { + this._payload = { ...this._payload, exp: validateInput("setExpirationTime", epoch_default(input)) }; + } else { + this._payload = { ...this._payload, exp: epoch_default(/* @__PURE__ */ new Date()) + secs_default(input) }; + } + return this; + } + setIssuedAt(input) { + if (typeof input === "undefined") { + this._payload = { ...this._payload, iat: epoch_default(/* @__PURE__ */ new Date()) }; + } else if (input instanceof Date) { + this._payload = { ...this._payload, iat: validateInput("setIssuedAt", epoch_default(input)) }; + } else if (typeof input === "string") { + this._payload = { + ...this._payload, + iat: validateInput("setIssuedAt", epoch_default(/* @__PURE__ */ new Date()) + secs_default(input)) + }; + } else { + this._payload = { ...this._payload, iat: validateInput("setIssuedAt", input) }; + } + return this; + } +}; + +// node_modules/jose/dist/browser/jwt/sign.js +var SignJWT = class extends ProduceJWT { + setProtectedHeader(protectedHeader) { + this._protectedHeader = protectedHeader; + return this; + } + async sign(key, options) { + const sig = new CompactSign(encoder.encode(JSON.stringify(this._payload))); + sig.setProtectedHeader(this._protectedHeader); + if (Array.isArray(this._protectedHeader?.crit) && this._protectedHeader.crit.includes("b64") && this._protectedHeader.b64 === false) { + throw new JWTInvalid("JWTs MUST NOT use unencoded payload"); + } + return sig.sign(key, options); + } +}; + +// src/worker.js var userID = "89b3cbba-e6ac-485a-9481-976a0415eab9"; var trojanPassword = `bpb-trojan`; var proxyIPs = ["bpb.yousef.isegaro.com"]; @@ -2874,7 +4093,7 @@ var defaultHttpsPorts = ["443", "8443", "2053", "2083", "2087", "2096"]; var proxyIP = proxyIPs[Math.floor(Math.random() * proxyIPs.length)]; var dohURL = "https://cloudflare-dns.com/dns-query"; var hashPassword; -var panelVersion = "2.6.7"; +var panelVersion = "2.6.8"; var worker_default = { /** * @param {import("@cloudflare/workers-types").Request} request @@ -3019,7 +4238,7 @@ var worker_default = { const isAuth = await Authenticate(request, env); if (request.method === "POST") { if (!isAuth) - return new Response("Unauthorized", { status: 401 }); + return new Response("Unauthorized or expired session!", { status: 401 }); const formData = await request.formData(); const isReset = formData.get("resetSettings") === "true"; isReset ? await updateDataset(env, null, true) : await updateDataset(env, formData); @@ -3057,7 +4276,7 @@ var worker_default = { const password = await request.text(); const savedPass = await env.bpb.get("pwd"); if (password === savedPass) { - const jwtToken = generateJWTToken(password, secretKey); + const jwtToken = await generateJWTToken(secretKey); const cookieHeader = `jwtToken=${jwtToken}; HttpOnly; Secure; Max-Age=${7 * 24 * 60 * 60}; Path=/; SameSite=Strict`; return new Response("Success", { status: 200, @@ -3152,7 +4371,7 @@ async function vlessOverWSHandler(request) { } const { hasError, - message, + message: message2, portRemote = 443, addressRemote = "", rawDataIndex, @@ -3162,7 +4381,7 @@ async function vlessOverWSHandler(request) { address = addressRemote; portWithRandomLog = `${portRemote}--${Math.random()} ${isUDP ? "udp " : "tcp "} `; if (hasError) { - throw new Error(message); + throw new Error(message2); return; } if (isUDP) { @@ -3250,7 +4469,7 @@ async function trojanOverWSHandler(request) { } const { hasError, - message, + message: message2, portRemote = 443, addressRemote = "", rawClientData @@ -3258,7 +4477,7 @@ async function trojanOverWSHandler(request) { address = addressRemote; portWithRandomLog = `${portRemote}--${Math.random()} tcp`; if (hasError) { - throw new Error(message); + throw new Error(message2); return; } handleTCPOutBound(request, remoteSocketWapper, addressRemote, portRemote, rawClientData, webSocket, false, log); @@ -3398,8 +4617,8 @@ function makeReadableWebSocketStream(webSocketServer, earlyDataHeader, log) { if (readableStreamCancel) { return; } - const message = event.data; - controller.enqueue(message); + const message2 = event.data; + controller.enqueue(message2); }); webSocketServer.addEventListener("close", () => { safeCloseWebSocket(webSocketServer); @@ -3597,8 +4816,8 @@ function base64ToArrayBuffer(base64Str) { } try { base64Str = base64Str.replace(/-/g, "+").replace(/_/g, "/"); - const decode = atob(base64Str); - const arryBuffer = Uint8Array.from(decode, (c) => c.charCodeAt(0)); + const decode2 = atob(base64Str); + const arryBuffer = Uint8Array.from(decode2, (c) => c.charCodeAt(0)); return { earlyData: arryBuffer.buffer, error: null }; } catch (error) { return { earlyData: null, error }; @@ -3899,54 +5118,33 @@ async function getConfigAddresses(hostName, cleanIPs, enableIPv6) { ...cleanIPs ? cleanIPs.split(",") : [] ]; } -function generateJWTToken(password, secretKey) { - const header = { - alg: "HS256", - typ: "JWT" - }; - const payload = { - exp: Math.floor(Date.now() / 1e3) + 24 * 60 * 60, - data: { password } - }; - const encodedHeader = btoa(JSON.stringify(header)); - const encodedPayload = btoa(JSON.stringify(payload)); - const signature = btoa(crypto.subtle.digest("SHA-256", new TextEncoder().encode(`${encodedHeader}.${encodedPayload}.${secretKey}`))); - return `Bearer ${encodedHeader}.${encodedPayload}.${signature}`; +async function generateJWTToken(secretKey) { + const secret = new TextEncoder().encode(secretKey); + return await new SignJWT({ userID }).setProtectedHeader({ alg: "HS256" }).setIssuedAt().setExpirationTime("24h").sign(secret); } function generateSecretKey() { - const bytes = new Uint8Array(32); - crypto.getRandomValues(bytes); - return Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join(""); + const key = import_tweetnacl.default.randomBytes(32); + return Array.from(key, (byte) => byte.toString(16).padStart(2, "0")).join(""); } async function Authenticate(request, env) { try { const secretKey = await env.bpb.get("secretKey"); - const cookie = request.headers.get("Cookie"); - const cookieMatch = cookie ? cookie.match(/(^|;\s*)jwtToken=([^;]*)/) : null; - const token = cookieMatch ? cookieMatch.pop() : null; + const secret = new TextEncoder().encode(secretKey); + const cookie = request.headers.get("Cookie")?.match(/(^|;\s*)jwtToken=([^;]*)/); + const token = cookie ? cookie[2] : null; if (!token) { - console.log("token"); + console.log("Unauthorized: Token not available!"); return false; } - const tokenWithoutBearer = token.startsWith("Bearer ") ? token.slice(7) : token; - const [encodedHeader, encodedPayload, signature] = tokenWithoutBearer.split("."); - const payload = JSON.parse(atob(encodedPayload)); - const expectedSignature = btoa(crypto.subtle.digest( - "SHA-256", - new TextEncoder().encode(`${encodedHeader}.${encodedPayload}.${secretKey}`) - )); - if (signature !== expectedSignature) - return false; - const now = Math.floor(Date.now() / 1e3); - if (payload.exp < now) - return false; + const { payload } = await jwtVerify(token, secret); + console.log(`Successfully logined, User ID: ${payload.userID}`); return true; } catch (error) { console.log(error); - throw new Error(`An error occurred while authentication - ${error}`); + return false; } } -async function renderHomePage(proxySettings, warpConfigs, hostName, password) { +async function renderHomePage(proxySettings, hostName, password) { const { remoteDNS, localDNS, @@ -5541,7 +6739,7 @@ async function renderLoginPage() { `; return html; } -function renderErrorPage(message, error, refer) { +function renderErrorPage(message2, error, refer) { return ` @@ -5582,7 +6780,7 @@ function renderErrorPage(message, error, refer) {

BPB Panel ${panelVersion} \u{1F4A6}

-

${message} ${refer ? 'Please try again or refer to documents' : ""} +

${message2} ${refer ? 'Please try again or refer to documents' : ""}

${error ? `\u26A0\uFE0F ${error.stack.toString()}` : ""}

@@ -5928,7 +7126,7 @@ function buildXrayRoutingRules(proxySettings, isChain, isBalancer, isWorkerLess, } return rules; } -function buildXrayVLESSOutbound(tag, address, port, host, sni, proxyIP2, isFragment, allowInsecure) { +function buildXrayVLESSOutbound(tag2, address, port, host, sni, proxyIP2, isFragment, allowInsecure) { let outbound = { protocol: "vless", settings: { @@ -5962,7 +7160,7 @@ function buildXrayVLESSOutbound(tag, address, port, host, sni, proxyIP2, isFragm path: `/${getRandomPath(16)}${proxyIP2 ? `/${btoa(proxyIP2)}` : ""}?ed=2560` } }, - tag + tag: tag2 }; if (defaultHttpsPorts.includes(port)) { outbound.streamSettings.security = "tls"; @@ -5976,7 +7174,7 @@ function buildXrayVLESSOutbound(tag, address, port, host, sni, proxyIP2, isFragm isFragment ? outbound.streamSettings.sockopt.dialerProxy = "fragment" : outbound.streamSettings.sockopt.tcpKeepAliveIdle = 100; return outbound; } -function buildXrayTrojanOutbound(tag, address, port, host, sni, proxyIP2, isFragment, allowInsecure) { +function buildXrayTrojanOutbound(tag2, address, port, host, sni, proxyIP2, isFragment, allowInsecure) { let outbound = { protocol: "trojan", settings: { @@ -6002,7 +7200,7 @@ function buildXrayTrojanOutbound(tag, address, port, host, sni, proxyIP2, isFrag path: `/tr${getRandomPath(16)}${proxyIP2 ? `/${btoa(proxyIP2)}` : ""}?ed=2560` } }, - tag + tag: tag2 }; if (defaultHttpsPorts.includes(port)) { outbound.streamSettings.security = "tls"; diff --git a/src/worker.js b/src/worker.js index df7ed0230..91316f75d 100644 --- a/src/worker.js +++ b/src/worker.js @@ -2,6 +2,7 @@ import { connect } from 'cloudflare:sockets'; import nacl from 'tweetnacl'; import sha256 from 'js-sha256'; +import { SignJWT, jwtVerify } from 'jose'; // How to generate your own UUID: // https://www.uuidgenerator.net/ @@ -15,7 +16,7 @@ const defaultHttpsPorts = ['443', '8443', '2053', '2083', '2087', '2096']; let proxyIP = proxyIPs[Math.floor(Math.random() * proxyIPs.length)]; let dohURL = 'https://cloudflare-dns.com/dns-query'; let hashPassword; -let panelVersion = '2.6.7'; +let panelVersion = '2.6.8'; export default { /** @@ -59,7 +60,6 @@ export default { case '/update-warp': const Auth = await Authenticate(request, env); if (!Auth) return new Response('Unauthorized', { status: 401 }); - if (request.method === 'POST') { try { const { error: warpPlusError } = await fetchWgConfig(env, settings); @@ -176,9 +176,8 @@ export default { case '/panel': const pwd = await env.bpb.get('pwd'); const isAuth = await Authenticate(request, env); - if (request.method === 'POST') { - if (!isAuth) return new Response('Unauthorized', { status: 401 }); + if (!isAuth) return new Response('Unauthorized or expired session!', { status: 401 }); const formData = await request.formData(); const isReset = formData.get('resetSettings') === 'true'; isReset @@ -211,7 +210,6 @@ export default { const loginAuth = await Authenticate(request, env); if (loginAuth) return Response.redirect(`${url.origin}/panel`, 302); - let secretKey = await env.bpb.get('secretKey'); if (!secretKey) { secretKey = generateSecretKey(); @@ -223,7 +221,7 @@ export default { const savedPass = await env.bpb.get('pwd'); if (password === savedPass) { - const jwtToken = generateJWTToken(password, secretKey); + const jwtToken = await generateJWTToken(secretKey); const cookieHeader = `jwtToken=${jwtToken}; HttpOnly; Secure; Max-Age=${7 * 24 * 60 * 60}; Path=/; SameSite=Strict`; return new Response('Success', { status: 200, @@ -1348,64 +1346,42 @@ async function getConfigAddresses(hostName, cleanIPs, enableIPv6) { ]; } -function generateJWTToken (password, secretKey) { - const header = { - alg: 'HS256', - typ: 'JWT' - }; - - const payload = { - exp: Math.floor(Date.now() / 1000) + (24 * 60 * 60), - data: { password } - }; - const encodedHeader = btoa(JSON.stringify(header)); - const encodedPayload = btoa(JSON.stringify(payload)); - const signature = btoa(crypto.subtle.digest('SHA-256', new TextEncoder().encode(`${encodedHeader}.${encodedPayload}.${secretKey}`))); - - return `Bearer ${encodedHeader}.${encodedPayload}.${signature}`; +async function generateJWTToken (secretKey) { + const secret = new TextEncoder().encode(secretKey); + return await new SignJWT({ userID }) + .setProtectedHeader({ alg: 'HS256' }) + .setIssuedAt() + .setExpirationTime('24h') + .sign(secret); } function generateSecretKey () { - const bytes = new Uint8Array(32); - crypto.getRandomValues(bytes); - return Array.from(bytes, byte => byte.toString(16).padStart(2, '0')).join(''); + const key = nacl.randomBytes(32); + return Array.from(key, byte => byte.toString(16).padStart(2, '0')).join(''); } async function Authenticate (request, env) { - try { const secretKey = await env.bpb.get('secretKey'); - const cookie = request.headers.get('Cookie'); - const cookieMatch = cookie ? cookie.match(/(^|;\s*)jwtToken=([^;]*)/) : null; - const token = cookieMatch ? cookieMatch.pop() : null; + const secret = new TextEncoder().encode(secretKey); + const cookie = request.headers.get('Cookie')?.match(/(^|;\s*)jwtToken=([^;]*)/); + const token = cookie ? cookie[2] : null; if (!token) { - console.log('token'); + console.log('Unauthorized: Token not available!'); return false; } - const tokenWithoutBearer = token.startsWith('Bearer ') ? token.slice(7) : token; - const [encodedHeader, encodedPayload, signature] = tokenWithoutBearer.split('.'); - const payload = JSON.parse(atob(encodedPayload)); - - const expectedSignature = btoa(crypto.subtle.digest( - 'SHA-256', - new TextEncoder().encode(`${encodedHeader}.${encodedPayload}.${secretKey}`) - )); - - if (signature !== expectedSignature) return false; - - const now = Math.floor(Date.now() / 1000); - if (payload.exp < now) return false; - + const { payload } = await jwtVerify(token, secret); + console.log(`Successfully logined, User ID: ${payload.userID}`); return true; } catch (error) { console.log(error); - throw new Error(`An error occurred while authentication - ${error}`); + return false; } } -async function renderHomePage (proxySettings, warpConfigs, hostName, password) { +async function renderHomePage (proxySettings, hostName, password) { const { remoteDNS, localDNS,