@codemem/mcp 0.43.2 → 0.44.0-alpha.1
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/dist/content.d.ts.map +1 -1
- package/dist/http.js +1347 -601
- package/dist/http.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/oauth.d.ts.map +1 -1
- package/dist/oidc.d.ts.map +1 -1
- package/dist/provider.d.ts.map +1 -1
- package/dist/schemas.d.ts +9 -9
- package/dist/{server-Kv95NnLs.js → server-C8Yl-9J0.js} +3 -3
- package/dist/{server-Kv95NnLs.js.map → server-C8Yl-9J0.js.map} +1 -1
- package/dist/stdio.js +6 -6
- package/dist/stdio.js.map +1 -1
- package/package.json +9 -9
package/dist/http.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.js","names":["Address6","MemoryStore","Buffer","isIPv62","#clients","#codes","#deleteExpiredCodes","#tokensByHash","#tokenHashKey","#deleteInactiveTokens","#grantsById","#grantIdsByRefreshHash","#refreshHashesByGrantId","#deleteInactiveGrants","#deleteGrantRefreshHashIndexEntries","#path","#load","#deleteInactive","#save","#records","#deleteExpired","#clientsStore","#codeStore","#tokenStore","#refreshTokenStore","#publicMcpUrl","#resourceServerUrl","#oidc","#now"],"sources":["../../../node_modules/.pnpm/ip-address@10.1.1/node_modules/ip-address/dist/common.js","../../../node_modules/.pnpm/ip-address@10.1.1/node_modules/ip-address/dist/v4/constants.js","../../../node_modules/.pnpm/ip-address@10.1.1/node_modules/ip-address/dist/address-error.js","../../../node_modules/.pnpm/ip-address@10.1.1/node_modules/ip-address/dist/ipv4.js","../../../node_modules/.pnpm/ip-address@10.1.1/node_modules/ip-address/dist/v6/constants.js","../../../node_modules/.pnpm/ip-address@10.1.1/node_modules/ip-address/dist/v6/helpers.js","../../../node_modules/.pnpm/ip-address@10.1.1/node_modules/ip-address/dist/v6/regular-expressions.js","../../../node_modules/.pnpm/ip-address@10.1.1/node_modules/ip-address/dist/ipv6.js","../../../node_modules/.pnpm/ip-address@10.1.1/node_modules/ip-address/dist/ip-address.js","../../../node_modules/.pnpm/express-rate-limit@8.5.2_express@5.2.1/node_modules/express-rate-limit/dist/index.mjs","../src/audit.ts","../src/oauth.ts","../src/oidc.ts","../src/provider.ts","../src/http.ts"],"sourcesContent":["\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.isInSubnet = isInSubnet;\nexports.isCorrect = isCorrect;\nexports.numberToPaddedHex = numberToPaddedHex;\nexports.stringToPaddedHex = stringToPaddedHex;\nexports.testBit = testBit;\nfunction isInSubnet(address) {\n if (this.subnetMask < address.subnetMask) {\n return false;\n }\n if (this.mask(address.subnetMask) === address.mask()) {\n return true;\n }\n return false;\n}\nfunction isCorrect(defaultBits) {\n return function () {\n if (this.addressMinusSuffix !== this.correctForm()) {\n return false;\n }\n if (this.subnetMask === defaultBits && !this.parsedSubnet) {\n return true;\n }\n return this.parsedSubnet === String(this.subnetMask);\n };\n}\nfunction numberToPaddedHex(number) {\n return number.toString(16).padStart(2, '0');\n}\nfunction stringToPaddedHex(numberString) {\n return numberToPaddedHex(parseInt(numberString, 10));\n}\n/**\n * @param binaryValue Binary representation of a value (e.g. `10`)\n * @param position Byte position, where 0 is the least significant bit\n */\nfunction testBit(binaryValue, position) {\n const { length } = binaryValue;\n if (position > length) {\n return false;\n }\n const positionInString = length - position;\n return binaryValue.substring(positionInString, positionInString + 1) === '1';\n}\n//# sourceMappingURL=common.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.RE_SUBNET_STRING = exports.RE_ADDRESS = exports.GROUPS = exports.BITS = void 0;\nexports.BITS = 32;\nexports.GROUPS = 4;\nexports.RE_ADDRESS = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/g;\nexports.RE_SUBNET_STRING = /\\/\\d{1,2}$/;\n//# sourceMappingURL=constants.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.AddressError = void 0;\nclass AddressError extends Error {\n constructor(message, parseMessage) {\n super(message);\n this.name = 'AddressError';\n this.parseMessage = parseMessage;\n }\n}\nexports.AddressError = AddressError;\n//# sourceMappingURL=address-error.js.map","\"use strict\";\n/* eslint-disable no-param-reassign */\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.Address4 = void 0;\nconst common = __importStar(require(\"./common\"));\nconst constants = __importStar(require(\"./v4/constants\"));\nconst address_error_1 = require(\"./address-error\");\n/**\n * Represents an IPv4 address\n * @class Address4\n * @param {string} address - An IPv4 address string\n */\nclass Address4 {\n constructor(address) {\n this.groups = constants.GROUPS;\n this.parsedAddress = [];\n this.parsedSubnet = '';\n this.subnet = '/32';\n this.subnetMask = 32;\n this.v4 = true;\n /**\n * Returns true if the address is correct, false otherwise\n * @memberof Address4\n * @instance\n * @returns {Boolean}\n */\n this.isCorrect = common.isCorrect(constants.BITS);\n /**\n * Returns true if the given address is in the subnet of the current address\n * @memberof Address4\n * @instance\n * @returns {boolean}\n */\n this.isInSubnet = common.isInSubnet;\n this.address = address;\n const subnet = constants.RE_SUBNET_STRING.exec(address);\n if (subnet) {\n this.parsedSubnet = subnet[0].replace('/', '');\n this.subnetMask = parseInt(this.parsedSubnet, 10);\n this.subnet = `/${this.subnetMask}`;\n if (this.subnetMask < 0 || this.subnetMask > constants.BITS) {\n throw new address_error_1.AddressError('Invalid subnet mask.');\n }\n address = address.replace(constants.RE_SUBNET_STRING, '');\n }\n this.addressMinusSuffix = address;\n this.parsedAddress = this.parse(address);\n }\n static isValid(address) {\n try {\n // eslint-disable-next-line no-new\n new Address4(address);\n return true;\n }\n catch (e) {\n return false;\n }\n }\n /*\n * Parses a v4 address\n */\n parse(address) {\n const groups = address.split('.');\n if (!address.match(constants.RE_ADDRESS)) {\n throw new address_error_1.AddressError('Invalid IPv4 address.');\n }\n return groups;\n }\n /**\n * Returns the correct form of an address\n * @memberof Address4\n * @instance\n * @returns {String}\n */\n correctForm() {\n return this.parsedAddress.map((part) => parseInt(part, 10)).join('.');\n }\n /**\n * Converts a hex string to an IPv4 address object\n * @memberof Address4\n * @static\n * @param {string} hex - a hex string to convert\n * @returns {Address4}\n */\n static fromHex(hex) {\n const padded = hex.replace(/:/g, '').padStart(8, '0');\n const groups = [];\n let i;\n for (i = 0; i < 8; i += 2) {\n const h = padded.slice(i, i + 2);\n groups.push(parseInt(h, 16));\n }\n return new Address4(groups.join('.'));\n }\n /**\n * Converts an integer into a IPv4 address object\n * @memberof Address4\n * @static\n * @param {integer} integer - a number to convert\n * @returns {Address4}\n */\n static fromInteger(integer) {\n return Address4.fromHex(integer.toString(16));\n }\n /**\n * Return an address from in-addr.arpa form\n * @memberof Address4\n * @static\n * @param {string} arpaFormAddress - an 'in-addr.arpa' form ipv4 address\n * @returns {Adress4}\n * @example\n * var address = Address4.fromArpa(42.2.0.192.in-addr.arpa.)\n * address.correctForm(); // '192.0.2.42'\n */\n static fromArpa(arpaFormAddress) {\n // remove ending \".in-addr.arpa.\" or just \".\"\n const leader = arpaFormAddress.replace(/(\\.in-addr\\.arpa)?\\.$/, '');\n const address = leader.split('.').reverse().join('.');\n return new Address4(address);\n }\n /**\n * Converts an IPv4 address object to a hex string\n * @memberof Address4\n * @instance\n * @returns {String}\n */\n toHex() {\n return this.parsedAddress.map((part) => common.stringToPaddedHex(part)).join(':');\n }\n /**\n * Converts an IPv4 address object to an array of bytes\n * @memberof Address4\n * @instance\n * @returns {Array}\n */\n toArray() {\n return this.parsedAddress.map((part) => parseInt(part, 10));\n }\n /**\n * Converts an IPv4 address object to an IPv6 address group\n * @memberof Address4\n * @instance\n * @returns {String}\n */\n toGroup6() {\n const output = [];\n let i;\n for (i = 0; i < constants.GROUPS; i += 2) {\n output.push(`${common.stringToPaddedHex(this.parsedAddress[i])}${common.stringToPaddedHex(this.parsedAddress[i + 1])}`);\n }\n return output.join(':');\n }\n /**\n * Returns the address as a `bigint`\n * @memberof Address4\n * @instance\n * @returns {bigint}\n */\n bigInt() {\n return BigInt(`0x${this.parsedAddress.map((n) => common.stringToPaddedHex(n)).join('')}`);\n }\n /**\n * Helper function getting start address.\n * @memberof Address4\n * @instance\n * @returns {bigint}\n */\n _startAddress() {\n return BigInt(`0b${this.mask() + '0'.repeat(constants.BITS - this.subnetMask)}`);\n }\n /**\n * The first address in the range given by this address' subnet.\n * Often referred to as the Network Address.\n * @memberof Address4\n * @instance\n * @returns {Address4}\n */\n startAddress() {\n return Address4.fromBigInt(this._startAddress());\n }\n /**\n * The first host address in the range given by this address's subnet ie\n * the first address after the Network Address\n * @memberof Address4\n * @instance\n * @returns {Address4}\n */\n startAddressExclusive() {\n const adjust = BigInt('1');\n return Address4.fromBigInt(this._startAddress() + adjust);\n }\n /**\n * Helper function getting end address.\n * @memberof Address4\n * @instance\n * @returns {bigint}\n */\n _endAddress() {\n return BigInt(`0b${this.mask() + '1'.repeat(constants.BITS - this.subnetMask)}`);\n }\n /**\n * The last address in the range given by this address' subnet\n * Often referred to as the Broadcast\n * @memberof Address4\n * @instance\n * @returns {Address4}\n */\n endAddress() {\n return Address4.fromBigInt(this._endAddress());\n }\n /**\n * The last host address in the range given by this address's subnet ie\n * the last address prior to the Broadcast Address\n * @memberof Address4\n * @instance\n * @returns {Address4}\n */\n endAddressExclusive() {\n const adjust = BigInt('1');\n return Address4.fromBigInt(this._endAddress() - adjust);\n }\n /**\n * Converts a BigInt to a v4 address object\n * @memberof Address4\n * @static\n * @param {bigint} bigInt - a BigInt to convert\n * @returns {Address4}\n */\n static fromBigInt(bigInt) {\n return Address4.fromHex(bigInt.toString(16));\n }\n /**\n * Convert a byte array to an Address4 object\n * @memberof Address4\n * @static\n * @param {Array<number>} bytes - an array of 4 bytes (0-255)\n * @returns {Address4}\n */\n static fromByteArray(bytes) {\n if (bytes.length !== 4) {\n throw new address_error_1.AddressError('IPv4 addresses require exactly 4 bytes');\n }\n // Validate that all bytes are within valid range (0-255)\n for (let i = 0; i < bytes.length; i++) {\n if (!Number.isInteger(bytes[i]) || bytes[i] < 0 || bytes[i] > 255) {\n throw new address_error_1.AddressError('All bytes must be integers between 0 and 255');\n }\n }\n return this.fromUnsignedByteArray(bytes);\n }\n /**\n * Convert an unsigned byte array to an Address4 object\n * @memberof Address4\n * @static\n * @param {Array<number>} bytes - an array of 4 unsigned bytes (0-255)\n * @returns {Address4}\n */\n static fromUnsignedByteArray(bytes) {\n if (bytes.length !== 4) {\n throw new address_error_1.AddressError('IPv4 addresses require exactly 4 bytes');\n }\n const address = bytes.join('.');\n return new Address4(address);\n }\n /**\n * Returns the first n bits of the address, defaulting to the\n * subnet mask\n * @memberof Address4\n * @instance\n * @returns {String}\n */\n mask(mask) {\n if (mask === undefined) {\n mask = this.subnetMask;\n }\n return this.getBitsBase2(0, mask);\n }\n /**\n * Returns the bits in the given range as a base-2 string\n * @memberof Address4\n * @instance\n * @returns {string}\n */\n getBitsBase2(start, end) {\n return this.binaryZeroPad().slice(start, end);\n }\n /**\n * Return the reversed ip6.arpa form of the address\n * @memberof Address4\n * @param {Object} options\n * @param {boolean} options.omitSuffix - omit the \"in-addr.arpa\" suffix\n * @instance\n * @returns {String}\n */\n reverseForm(options) {\n if (!options) {\n options = {};\n }\n const reversed = this.correctForm().split('.').reverse().join('.');\n if (options.omitSuffix) {\n return reversed;\n }\n return `${reversed}.in-addr.arpa.`;\n }\n /**\n * Returns true if the given address is a multicast address\n * @memberof Address4\n * @instance\n * @returns {boolean}\n */\n isMulticast() {\n return this.isInSubnet(new Address4('224.0.0.0/4'));\n }\n /**\n * Returns a zero-padded base-2 string representation of the address\n * @memberof Address4\n * @instance\n * @returns {string}\n */\n binaryZeroPad() {\n return this.bigInt().toString(2).padStart(constants.BITS, '0');\n }\n /**\n * Groups an IPv4 address for inclusion at the end of an IPv6 address\n * @returns {String}\n */\n groupForV6() {\n const segments = this.parsedAddress;\n return this.address.replace(constants.RE_ADDRESS, `<span class=\"hover-group group-v4 group-6\">${segments\n .slice(0, 2)\n .join('.')}</span>.<span class=\"hover-group group-v4 group-7\">${segments\n .slice(2, 4)\n .join('.')}</span>`);\n }\n}\nexports.Address4 = Address4;\n//# sourceMappingURL=ipv4.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.RE_URL_WITH_PORT = exports.RE_URL = exports.RE_ZONE_STRING = exports.RE_SUBNET_STRING = exports.RE_BAD_ADDRESS = exports.RE_BAD_CHARACTERS = exports.TYPES = exports.SCOPES = exports.GROUPS = exports.BITS = void 0;\nexports.BITS = 128;\nexports.GROUPS = 8;\n/**\n * Represents IPv6 address scopes\n * @memberof Address6\n * @static\n */\nexports.SCOPES = {\n 0: 'Reserved',\n 1: 'Interface local',\n 2: 'Link local',\n 4: 'Admin local',\n 5: 'Site local',\n 8: 'Organization local',\n 14: 'Global',\n 15: 'Reserved',\n};\n/**\n * Represents IPv6 address types\n * @memberof Address6\n * @static\n */\nexports.TYPES = {\n 'ff01::1/128': 'Multicast (All nodes on this interface)',\n 'ff01::2/128': 'Multicast (All routers on this interface)',\n 'ff02::1/128': 'Multicast (All nodes on this link)',\n 'ff02::2/128': 'Multicast (All routers on this link)',\n 'ff05::2/128': 'Multicast (All routers in this site)',\n 'ff02::5/128': 'Multicast (OSPFv3 AllSPF routers)',\n 'ff02::6/128': 'Multicast (OSPFv3 AllDR routers)',\n 'ff02::9/128': 'Multicast (RIP routers)',\n 'ff02::a/128': 'Multicast (EIGRP routers)',\n 'ff02::d/128': 'Multicast (PIM routers)',\n 'ff02::16/128': 'Multicast (MLDv2 reports)',\n 'ff01::fb/128': 'Multicast (mDNSv6)',\n 'ff02::fb/128': 'Multicast (mDNSv6)',\n 'ff05::fb/128': 'Multicast (mDNSv6)',\n 'ff02::1:2/128': 'Multicast (All DHCP servers and relay agents on this link)',\n 'ff05::1:2/128': 'Multicast (All DHCP servers and relay agents in this site)',\n 'ff02::1:3/128': 'Multicast (All DHCP servers on this link)',\n 'ff05::1:3/128': 'Multicast (All DHCP servers in this site)',\n '::/128': 'Unspecified',\n '::1/128': 'Loopback',\n 'ff00::/8': 'Multicast',\n 'fe80::/10': 'Link-local unicast',\n};\n/**\n * A regular expression that matches bad characters in an IPv6 address\n * @memberof Address6\n * @static\n */\nexports.RE_BAD_CHARACTERS = /([^0-9a-f:/%])/gi;\n/**\n * A regular expression that matches an incorrect IPv6 address\n * @memberof Address6\n * @static\n */\nexports.RE_BAD_ADDRESS = /([0-9a-f]{5,}|:{3,}|[^:]:$|^:[^:]|\\/$)/gi;\n/**\n * A regular expression that matches an IPv6 subnet\n * @memberof Address6\n * @static\n */\nexports.RE_SUBNET_STRING = /\\/\\d{1,3}(?=%|$)/;\n/**\n * A regular expression that matches an IPv6 zone\n * @memberof Address6\n * @static\n */\nexports.RE_ZONE_STRING = /%.*$/;\nexports.RE_URL = /^\\[{0,1}([0-9a-f:]+)\\]{0,1}/;\nexports.RE_URL_WITH_PORT = /\\[([0-9a-f:]+)\\]:([0-9]{1,5})/;\n//# sourceMappingURL=constants.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.escapeHtml = escapeHtml;\nexports.spanAllZeroes = spanAllZeroes;\nexports.spanAll = spanAll;\nexports.spanLeadingZeroes = spanLeadingZeroes;\nexports.simpleGroup = simpleGroup;\nfunction escapeHtml(s) {\n return s\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n/**\n * @returns {String} the string with all zeroes contained in a <span>\n */\nfunction spanAllZeroes(s) {\n return escapeHtml(s).replace(/(0+)/g, '<span class=\"zero\">$1</span>');\n}\n/**\n * @returns {String} the string with each character contained in a <span>\n */\nfunction spanAll(s, offset = 0) {\n const letters = s.split('');\n return letters\n .map((n, i) => `<span class=\"digit value-${escapeHtml(n)} position-${i + offset}\">${spanAllZeroes(n)}</span>`)\n .join('');\n}\nfunction spanLeadingZeroesSimple(group) {\n return escapeHtml(group).replace(/^(0+)/, '<span class=\"zero\">$1</span>');\n}\n/**\n * @returns {String} the string with leading zeroes contained in a <span>\n */\nfunction spanLeadingZeroes(address) {\n const groups = address.split(':');\n return groups.map((g) => spanLeadingZeroesSimple(g)).join(':');\n}\n/**\n * Groups an address\n * @returns {String} a grouped address\n */\nfunction simpleGroup(addressString, offset = 0) {\n const groups = addressString.split(':');\n return groups.map((g, i) => {\n if (/group-v4/.test(g)) {\n return g;\n }\n return `<span class=\"hover-group group-${i + offset}\">${spanLeadingZeroesSimple(g)}</span>`;\n });\n}\n//# sourceMappingURL=helpers.js.map","\"use strict\";\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.ADDRESS_BOUNDARY = void 0;\nexports.groupPossibilities = groupPossibilities;\nexports.padGroup = padGroup;\nexports.simpleRegularExpression = simpleRegularExpression;\nexports.possibleElisions = possibleElisions;\nconst v6 = __importStar(require(\"./constants\"));\nfunction groupPossibilities(possibilities) {\n return `(${possibilities.join('|')})`;\n}\nfunction padGroup(group) {\n if (group.length < 4) {\n return `0{0,${4 - group.length}}${group}`;\n }\n return group;\n}\nexports.ADDRESS_BOUNDARY = '[^A-Fa-f0-9:]';\nfunction simpleRegularExpression(groups) {\n const zeroIndexes = [];\n groups.forEach((group, i) => {\n const groupInteger = parseInt(group, 16);\n if (groupInteger === 0) {\n zeroIndexes.push(i);\n }\n });\n // You can technically elide a single 0, this creates the regular expressions\n // to match that eventuality\n const possibilities = zeroIndexes.map((zeroIndex) => groups\n .map((group, i) => {\n if (i === zeroIndex) {\n const elision = i === 0 || i === v6.GROUPS - 1 ? ':' : '';\n return groupPossibilities([padGroup(group), elision]);\n }\n return padGroup(group);\n })\n .join(':'));\n // The simplest case\n possibilities.push(groups.map(padGroup).join(':'));\n return groupPossibilities(possibilities);\n}\nfunction possibleElisions(elidedGroups, moreLeft, moreRight) {\n const left = moreLeft ? '' : ':';\n const right = moreRight ? '' : ':';\n const possibilities = [];\n // 1. elision of everything (::)\n if (!moreLeft && !moreRight) {\n possibilities.push('::');\n }\n // 2. complete elision of the middle\n if (moreLeft && moreRight) {\n possibilities.push('');\n }\n if ((moreRight && !moreLeft) || (!moreRight && moreLeft)) {\n // 3. complete elision of one side\n possibilities.push(':');\n }\n // 4. elision from the left side\n possibilities.push(`${left}(:0{1,4}){1,${elidedGroups - 1}}`);\n // 5. elision from the right side\n possibilities.push(`(0{1,4}:){1,${elidedGroups - 1}}${right}`);\n // 6. no elision\n possibilities.push(`(0{1,4}:){${elidedGroups - 1}}0{1,4}`);\n // 7. elision (including sloppy elision) from the middle\n for (let groups = 1; groups < elidedGroups - 1; groups++) {\n for (let position = 1; position < elidedGroups - groups; position++) {\n possibilities.push(`(0{1,4}:){${position}}:(0{1,4}:){${elidedGroups - position - groups - 1}}0{1,4}`);\n }\n }\n return groupPossibilities(possibilities);\n}\n//# sourceMappingURL=regular-expressions.js.map","\"use strict\";\n/* eslint-disable prefer-destructuring */\n/* eslint-disable no-param-reassign */\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.Address6 = void 0;\nconst common = __importStar(require(\"./common\"));\nconst constants4 = __importStar(require(\"./v4/constants\"));\nconst constants6 = __importStar(require(\"./v6/constants\"));\nconst helpers = __importStar(require(\"./v6/helpers\"));\nconst ipv4_1 = require(\"./ipv4\");\nconst regular_expressions_1 = require(\"./v6/regular-expressions\");\nconst address_error_1 = require(\"./address-error\");\nconst common_1 = require(\"./common\");\nfunction assert(condition) {\n if (!condition) {\n throw new Error('Assertion failed.');\n }\n}\nfunction addCommas(number) {\n const r = /(\\d+)(\\d{3})/;\n while (r.test(number)) {\n number = number.replace(r, '$1,$2');\n }\n return number;\n}\nfunction spanLeadingZeroes4(n) {\n n = n.replace(/^(0{1,})([1-9]+)$/, '<span class=\"parse-error\">$1</span>$2');\n n = n.replace(/^(0{1,})(0)$/, '<span class=\"parse-error\">$1</span>$2');\n return n;\n}\n/*\n * A helper function to compact an array\n */\nfunction compact(address, slice) {\n const s1 = [];\n const s2 = [];\n let i;\n for (i = 0; i < address.length; i++) {\n if (i < slice[0]) {\n s1.push(address[i]);\n }\n else if (i > slice[1]) {\n s2.push(address[i]);\n }\n }\n return s1.concat(['compact']).concat(s2);\n}\nfunction paddedHex(octet) {\n return parseInt(octet, 16).toString(16).padStart(4, '0');\n}\nfunction unsignByte(b) {\n // eslint-disable-next-line no-bitwise\n return b & 0xff;\n}\n/**\n * Represents an IPv6 address\n * @class Address6\n * @param {string} address - An IPv6 address string\n * @param {number} [groups=8] - How many octets to parse\n * @example\n * var address = new Address6('2001::/32');\n */\nclass Address6 {\n constructor(address, optionalGroups) {\n this.addressMinusSuffix = '';\n this.parsedSubnet = '';\n this.subnet = '/128';\n this.subnetMask = 128;\n this.v4 = false;\n this.zone = '';\n // #region Attributes\n /**\n * Returns true if the given address is in the subnet of the current address\n * @memberof Address6\n * @instance\n * @returns {boolean}\n */\n this.isInSubnet = common.isInSubnet;\n /**\n * Returns true if the address is correct, false otherwise\n * @memberof Address6\n * @instance\n * @returns {boolean}\n */\n this.isCorrect = common.isCorrect(constants6.BITS);\n if (optionalGroups === undefined) {\n this.groups = constants6.GROUPS;\n }\n else {\n this.groups = optionalGroups;\n }\n this.address = address;\n const subnet = constants6.RE_SUBNET_STRING.exec(address);\n if (subnet) {\n this.parsedSubnet = subnet[0].replace('/', '');\n this.subnetMask = parseInt(this.parsedSubnet, 10);\n this.subnet = `/${this.subnetMask}`;\n if (Number.isNaN(this.subnetMask) ||\n this.subnetMask < 0 ||\n this.subnetMask > constants6.BITS) {\n throw new address_error_1.AddressError('Invalid subnet mask.');\n }\n address = address.replace(constants6.RE_SUBNET_STRING, '');\n }\n else if (/\\//.test(address)) {\n throw new address_error_1.AddressError('Invalid subnet mask.');\n }\n const zone = constants6.RE_ZONE_STRING.exec(address);\n if (zone) {\n this.zone = zone[0];\n address = address.replace(constants6.RE_ZONE_STRING, '');\n }\n this.addressMinusSuffix = address;\n this.parsedAddress = this.parse(this.addressMinusSuffix);\n }\n static isValid(address) {\n try {\n // eslint-disable-next-line no-new\n new Address6(address);\n return true;\n }\n catch (e) {\n return false;\n }\n }\n /**\n * Convert a BigInt to a v6 address object\n * @memberof Address6\n * @static\n * @param {bigint} bigInt - a BigInt to convert\n * @returns {Address6}\n * @example\n * var bigInt = BigInt('1000000000000');\n * var address = Address6.fromBigInt(bigInt);\n * address.correctForm(); // '::e8:d4a5:1000'\n */\n static fromBigInt(bigInt) {\n const hex = bigInt.toString(16).padStart(32, '0');\n const groups = [];\n let i;\n for (i = 0; i < constants6.GROUPS; i++) {\n groups.push(hex.slice(i * 4, (i + 1) * 4));\n }\n return new Address6(groups.join(':'));\n }\n /**\n * Convert a URL (with optional port number) to an address object\n * @memberof Address6\n * @static\n * @param {string} url - a URL with optional port number\n * @example\n * var addressAndPort = Address6.fromURL('http://[ffff::]:8080/foo/');\n * addressAndPort.address.correctForm(); // 'ffff::'\n * addressAndPort.port; // 8080\n */\n static fromURL(url) {\n let host;\n let port = null;\n let result;\n // If we have brackets parse them and find a port\n if (url.indexOf('[') !== -1 && url.indexOf(']:') !== -1) {\n result = constants6.RE_URL_WITH_PORT.exec(url);\n if (result === null) {\n return {\n error: 'failed to parse address with port',\n address: null,\n port: null,\n };\n }\n host = result[1];\n port = result[2];\n // If there's a URL extract the address\n }\n else if (url.indexOf('/') !== -1) {\n // Remove the protocol prefix\n url = url.replace(/^[a-z0-9]+:\\/\\//, '');\n // Parse the address\n result = constants6.RE_URL.exec(url);\n if (result === null) {\n return {\n error: 'failed to parse address from URL',\n address: null,\n port: null,\n };\n }\n host = result[1];\n // Otherwise just assign the URL to the host and let the library parse it\n }\n else {\n host = url;\n }\n // If there's a port convert it to an integer\n if (port) {\n port = parseInt(port, 10);\n // squelch out of range ports\n if (port < 0 || port > 65536) {\n port = null;\n }\n }\n else {\n // Standardize `undefined` to `null`\n port = null;\n }\n return {\n address: new Address6(host),\n port,\n };\n }\n /**\n * Create an IPv6-mapped address given an IPv4 address\n * @memberof Address6\n * @static\n * @param {string} address - An IPv4 address string\n * @returns {Address6}\n * @example\n * var address = Address6.fromAddress4('192.168.0.1');\n * address.correctForm(); // '::ffff:c0a8:1'\n * address.to4in6(); // '::ffff:192.168.0.1'\n */\n static fromAddress4(address) {\n const address4 = new ipv4_1.Address4(address);\n const mask6 = constants6.BITS - (constants4.BITS - address4.subnetMask);\n return new Address6(`::ffff:${address4.correctForm()}/${mask6}`);\n }\n /**\n * Return an address from ip6.arpa form\n * @memberof Address6\n * @static\n * @param {string} arpaFormAddress - an 'ip6.arpa' form address\n * @returns {Adress6}\n * @example\n * var address = Address6.fromArpa(e.f.f.f.3.c.2.6.f.f.f.e.6.6.8.e.1.0.6.7.9.4.e.c.0.0.0.0.1.0.0.2.ip6.arpa.)\n * address.correctForm(); // '2001:0:ce49:7601:e866:efff:62c3:fffe'\n */\n static fromArpa(arpaFormAddress) {\n // remove ending \".ip6.arpa.\" or just \".\"\n let address = arpaFormAddress.replace(/(\\.ip6\\.arpa)?\\.$/, '');\n const semicolonAmount = 7;\n // correct ip6.arpa form with ending removed will be 63 characters\n if (address.length !== 63) {\n throw new address_error_1.AddressError(\"Invalid 'ip6.arpa' form.\");\n }\n const parts = address.split('.').reverse();\n for (let i = semicolonAmount; i > 0; i--) {\n const insertIndex = i * 4;\n parts.splice(insertIndex, 0, ':');\n }\n address = parts.join('');\n return new Address6(address);\n }\n /**\n * Return the Microsoft UNC transcription of the address\n * @memberof Address6\n * @instance\n * @returns {String} the Microsoft UNC transcription of the address\n */\n microsoftTranscription() {\n return `${this.correctForm().replace(/:/g, '-')}.ipv6-literal.net`;\n }\n /**\n * Return the first n bits of the address, defaulting to the subnet mask\n * @memberof Address6\n * @instance\n * @param {number} [mask=subnet] - the number of bits to mask\n * @returns {String} the first n bits of the address as a string\n */\n mask(mask = this.subnetMask) {\n return this.getBitsBase2(0, mask);\n }\n /**\n * Return the number of possible subnets of a given size in the address\n * @memberof Address6\n * @instance\n * @param {number} [subnetSize=128] - the subnet size\n * @returns {String}\n */\n // TODO: probably useful to have a numeric version of this too\n possibleSubnets(subnetSize = 128) {\n const availableBits = constants6.BITS - this.subnetMask;\n const subnetBits = Math.abs(subnetSize - constants6.BITS);\n const subnetPowers = availableBits - subnetBits;\n if (subnetPowers < 0) {\n return '0';\n }\n return addCommas((BigInt('2') ** BigInt(subnetPowers)).toString(10));\n }\n /**\n * Helper function getting start address.\n * @memberof Address6\n * @instance\n * @returns {bigint}\n */\n _startAddress() {\n return BigInt(`0b${this.mask() + '0'.repeat(constants6.BITS - this.subnetMask)}`);\n }\n /**\n * The first address in the range given by this address' subnet\n * Often referred to as the Network Address.\n * @memberof Address6\n * @instance\n * @returns {Address6}\n */\n startAddress() {\n return Address6.fromBigInt(this._startAddress());\n }\n /**\n * The first host address in the range given by this address's subnet ie\n * the first address after the Network Address\n * @memberof Address6\n * @instance\n * @returns {Address6}\n */\n startAddressExclusive() {\n const adjust = BigInt('1');\n return Address6.fromBigInt(this._startAddress() + adjust);\n }\n /**\n * Helper function getting end address.\n * @memberof Address6\n * @instance\n * @returns {bigint}\n */\n _endAddress() {\n return BigInt(`0b${this.mask() + '1'.repeat(constants6.BITS - this.subnetMask)}`);\n }\n /**\n * The last address in the range given by this address' subnet\n * Often referred to as the Broadcast\n * @memberof Address6\n * @instance\n * @returns {Address6}\n */\n endAddress() {\n return Address6.fromBigInt(this._endAddress());\n }\n /**\n * The last host address in the range given by this address's subnet ie\n * the last address prior to the Broadcast Address\n * @memberof Address6\n * @instance\n * @returns {Address6}\n */\n endAddressExclusive() {\n const adjust = BigInt('1');\n return Address6.fromBigInt(this._endAddress() - adjust);\n }\n /**\n * Return the scope of the address\n * @memberof Address6\n * @instance\n * @returns {String}\n */\n getScope() {\n let scope = constants6.SCOPES[parseInt(this.getBits(12, 16).toString(10), 10)];\n if (this.getType() === 'Global unicast' && scope !== 'Link local') {\n scope = 'Global';\n }\n return scope || 'Unknown';\n }\n /**\n * Return the type of the address\n * @memberof Address6\n * @instance\n * @returns {String}\n */\n getType() {\n for (const subnet of Object.keys(constants6.TYPES)) {\n if (this.isInSubnet(new Address6(subnet))) {\n return constants6.TYPES[subnet];\n }\n }\n return 'Global unicast';\n }\n /**\n * Return the bits in the given range as a BigInt\n * @memberof Address6\n * @instance\n * @returns {bigint}\n */\n getBits(start, end) {\n return BigInt(`0b${this.getBitsBase2(start, end)}`);\n }\n /**\n * Return the bits in the given range as a base-2 string\n * @memberof Address6\n * @instance\n * @returns {String}\n */\n getBitsBase2(start, end) {\n return this.binaryZeroPad().slice(start, end);\n }\n /**\n * Return the bits in the given range as a base-16 string\n * @memberof Address6\n * @instance\n * @returns {String}\n */\n getBitsBase16(start, end) {\n const length = end - start;\n if (length % 4 !== 0) {\n throw new Error('Length of bits to retrieve must be divisible by four');\n }\n return this.getBits(start, end)\n .toString(16)\n .padStart(length / 4, '0');\n }\n /**\n * Return the bits that are set past the subnet mask length\n * @memberof Address6\n * @instance\n * @returns {String}\n */\n getBitsPastSubnet() {\n return this.getBitsBase2(this.subnetMask, constants6.BITS);\n }\n /**\n * Return the reversed ip6.arpa form of the address\n * @memberof Address6\n * @param {Object} options\n * @param {boolean} options.omitSuffix - omit the \"ip6.arpa\" suffix\n * @instance\n * @returns {String}\n */\n reverseForm(options) {\n if (!options) {\n options = {};\n }\n const characters = Math.floor(this.subnetMask / 4);\n const reversed = this.canonicalForm()\n .replace(/:/g, '')\n .split('')\n .slice(0, characters)\n .reverse()\n .join('.');\n if (characters > 0) {\n if (options.omitSuffix) {\n return reversed;\n }\n return `${reversed}.ip6.arpa.`;\n }\n if (options.omitSuffix) {\n return '';\n }\n return 'ip6.arpa.';\n }\n /**\n * Return the correct form of the address\n * @memberof Address6\n * @instance\n * @returns {String}\n */\n correctForm() {\n let i;\n let groups = [];\n let zeroCounter = 0;\n const zeroes = [];\n for (i = 0; i < this.parsedAddress.length; i++) {\n const value = parseInt(this.parsedAddress[i], 16);\n if (value === 0) {\n zeroCounter++;\n }\n if (value !== 0 && zeroCounter > 0) {\n if (zeroCounter > 1) {\n zeroes.push([i - zeroCounter, i - 1]);\n }\n zeroCounter = 0;\n }\n }\n // Do we end with a string of zeroes?\n if (zeroCounter > 1) {\n zeroes.push([this.parsedAddress.length - zeroCounter, this.parsedAddress.length - 1]);\n }\n const zeroLengths = zeroes.map((n) => n[1] - n[0] + 1);\n if (zeroes.length > 0) {\n const index = zeroLengths.indexOf(Math.max(...zeroLengths));\n groups = compact(this.parsedAddress, zeroes[index]);\n }\n else {\n groups = this.parsedAddress;\n }\n for (i = 0; i < groups.length; i++) {\n if (groups[i] !== 'compact') {\n groups[i] = parseInt(groups[i], 16).toString(16);\n }\n }\n let correct = groups.join(':');\n correct = correct.replace(/^compact$/, '::');\n correct = correct.replace(/(^compact)|(compact$)/, ':');\n correct = correct.replace(/compact/, '');\n return correct;\n }\n /**\n * Return a zero-padded base-2 string representation of the address\n * @memberof Address6\n * @instance\n * @returns {String}\n * @example\n * var address = new Address6('2001:4860:4001:803::1011');\n * address.binaryZeroPad();\n * // '0010000000000001010010000110000001000000000000010000100000000011\n * // 0000000000000000000000000000000000000000000000000001000000010001'\n */\n binaryZeroPad() {\n return this.bigInt().toString(2).padStart(constants6.BITS, '0');\n }\n // TODO: Improve the semantics of this helper function\n parse4in6(address) {\n const groups = address.split(':');\n const lastGroup = groups.slice(-1)[0];\n const address4 = lastGroup.match(constants4.RE_ADDRESS);\n if (address4) {\n this.parsedAddress4 = address4[0];\n this.address4 = new ipv4_1.Address4(this.parsedAddress4);\n for (let i = 0; i < this.address4.groups; i++) {\n if (/^0[0-9]+/.test(this.address4.parsedAddress[i])) {\n // The prefix groups haven't been through the bad-character check\n // yet, so escape them before including in the error HTML.\n const highlighted = this.address4.parsedAddress.map(spanLeadingZeroes4).join('.');\n const prefix = groups.slice(0, -1).map(helpers.escapeHtml).join(':');\n const separator = groups.length > 1 ? ':' : '';\n throw new address_error_1.AddressError(\"IPv4 addresses can't have leading zeroes.\", `${prefix}${separator}${highlighted}`);\n }\n }\n this.v4 = true;\n groups[groups.length - 1] = this.address4.toGroup6();\n address = groups.join(':');\n }\n return address;\n }\n // TODO: Make private?\n parse(address) {\n address = this.parse4in6(address);\n const badCharacters = address.match(constants6.RE_BAD_CHARACTERS);\n if (badCharacters) {\n throw new address_error_1.AddressError(`Bad character${badCharacters.length > 1 ? 's' : ''} detected in address: ${badCharacters.join('')}`, address.replace(constants6.RE_BAD_CHARACTERS, '<span class=\"parse-error\">$1</span>'));\n }\n const badAddress = address.match(constants6.RE_BAD_ADDRESS);\n if (badAddress) {\n throw new address_error_1.AddressError(`Address failed regex: ${badAddress.join('')}`, address.replace(constants6.RE_BAD_ADDRESS, '<span class=\"parse-error\">$1</span>'));\n }\n let groups = [];\n const halves = address.split('::');\n if (halves.length === 2) {\n let first = halves[0].split(':');\n let last = halves[1].split(':');\n if (first.length === 1 && first[0] === '') {\n first = [];\n }\n if (last.length === 1 && last[0] === '') {\n last = [];\n }\n const remaining = this.groups - (first.length + last.length);\n if (!remaining) {\n throw new address_error_1.AddressError('Error parsing groups');\n }\n this.elidedGroups = remaining;\n this.elisionBegin = first.length;\n this.elisionEnd = first.length + this.elidedGroups;\n groups = groups.concat(first);\n for (let i = 0; i < remaining; i++) {\n groups.push('0');\n }\n groups = groups.concat(last);\n }\n else if (halves.length === 1) {\n groups = address.split(':');\n this.elidedGroups = 0;\n }\n else {\n throw new address_error_1.AddressError('Too many :: groups found');\n }\n groups = groups.map((group) => parseInt(group, 16).toString(16));\n if (groups.length !== this.groups) {\n throw new address_error_1.AddressError('Incorrect number of groups found');\n }\n return groups;\n }\n /**\n * Return the canonical form of the address\n * @memberof Address6\n * @instance\n * @returns {String}\n */\n canonicalForm() {\n return this.parsedAddress.map(paddedHex).join(':');\n }\n /**\n * Return the decimal form of the address\n * @memberof Address6\n * @instance\n * @returns {String}\n */\n decimal() {\n return this.parsedAddress.map((n) => parseInt(n, 16).toString(10).padStart(5, '0')).join(':');\n }\n /**\n * Return the address as a BigInt\n * @memberof Address6\n * @instance\n * @returns {bigint}\n */\n bigInt() {\n return BigInt(`0x${this.parsedAddress.map(paddedHex).join('')}`);\n }\n /**\n * Return the last two groups of this address as an IPv4 address string\n * @memberof Address6\n * @instance\n * @returns {Address4}\n * @example\n * var address = new Address6('2001:4860:4001::1825:bf11');\n * address.to4().correctForm(); // '24.37.191.17'\n */\n to4() {\n const binary = this.binaryZeroPad().split('');\n return ipv4_1.Address4.fromHex(BigInt(`0b${binary.slice(96, 128).join('')}`).toString(16));\n }\n /**\n * Return the v4-in-v6 form of the address\n * @memberof Address6\n * @instance\n * @returns {String}\n */\n to4in6() {\n const address4 = this.to4();\n const address6 = new Address6(this.parsedAddress.slice(0, 6).join(':'), 6);\n const correct = address6.correctForm();\n let infix = '';\n if (!/:$/.test(correct)) {\n infix = ':';\n }\n return correct + infix + address4.address;\n }\n /**\n * Return an object containing the Teredo properties of the address\n * @memberof Address6\n * @instance\n * @returns {Object}\n */\n inspectTeredo() {\n /*\n - Bits 0 to 31 are set to the Teredo prefix (normally 2001:0000::/32).\n - Bits 32 to 63 embed the primary IPv4 address of the Teredo server that\n is used.\n - Bits 64 to 79 can be used to define some flags. Currently only the\n higher order bit is used; it is set to 1 if the Teredo client is\n located behind a cone NAT, 0 otherwise. For Microsoft's Windows Vista\n and Windows Server 2008 implementations, more bits are used. In those\n implementations, the format for these 16 bits is \"CRAAAAUG AAAAAAAA\",\n where \"C\" remains the \"Cone\" flag. The \"R\" bit is reserved for future\n use. The \"U\" bit is for the Universal/Local flag (set to 0). The \"G\" bit\n is Individual/Group flag (set to 0). The A bits are set to a 12-bit\n randomly generated number chosen by the Teredo client to introduce\n additional protection for the Teredo node against IPv6-based scanning\n attacks.\n - Bits 80 to 95 contains the obfuscated UDP port number. This is the\n port number that is mapped by the NAT to the Teredo client with all\n bits inverted.\n - Bits 96 to 127 contains the obfuscated IPv4 address. This is the\n public IPv4 address of the NAT with all bits inverted.\n */\n const prefix = this.getBitsBase16(0, 32);\n const bitsForUdpPort = this.getBits(80, 96);\n // eslint-disable-next-line no-bitwise\n const udpPort = (bitsForUdpPort ^ BigInt('0xffff')).toString();\n const server4 = ipv4_1.Address4.fromHex(this.getBitsBase16(32, 64));\n const bitsForClient4 = this.getBits(96, 128);\n // eslint-disable-next-line no-bitwise\n const client4 = ipv4_1.Address4.fromHex((bitsForClient4 ^ BigInt('0xffffffff')).toString(16));\n const flagsBase2 = this.getBitsBase2(64, 80);\n const coneNat = (0, common_1.testBit)(flagsBase2, 15);\n const reserved = (0, common_1.testBit)(flagsBase2, 14);\n const groupIndividual = (0, common_1.testBit)(flagsBase2, 8);\n const universalLocal = (0, common_1.testBit)(flagsBase2, 9);\n const nonce = BigInt(`0b${flagsBase2.slice(2, 6) + flagsBase2.slice(8, 16)}`).toString(10);\n return {\n prefix: `${prefix.slice(0, 4)}:${prefix.slice(4, 8)}`,\n server4: server4.address,\n client4: client4.address,\n flags: flagsBase2,\n coneNat,\n microsoft: {\n reserved,\n universalLocal,\n groupIndividual,\n nonce,\n },\n udpPort,\n };\n }\n /**\n * Return an object containing the 6to4 properties of the address\n * @memberof Address6\n * @instance\n * @returns {Object}\n */\n inspect6to4() {\n /*\n - Bits 0 to 15 are set to the 6to4 prefix (2002::/16).\n - Bits 16 to 48 embed the IPv4 address of the 6to4 gateway that is used.\n */\n const prefix = this.getBitsBase16(0, 16);\n const gateway = ipv4_1.Address4.fromHex(this.getBitsBase16(16, 48));\n return {\n prefix: prefix.slice(0, 4),\n gateway: gateway.address,\n };\n }\n /**\n * Return a v6 6to4 address from a v6 v4inv6 address\n * @memberof Address6\n * @instance\n * @returns {Address6}\n */\n to6to4() {\n if (!this.is4()) {\n return null;\n }\n const addr6to4 = [\n '2002',\n this.getBitsBase16(96, 112),\n this.getBitsBase16(112, 128),\n '',\n '/16',\n ].join(':');\n return new Address6(addr6to4);\n }\n /**\n * Return a byte array\n * @memberof Address6\n * @instance\n * @returns {Array}\n */\n toByteArray() {\n const valueWithoutPadding = this.bigInt().toString(16);\n const leadingPad = '0'.repeat(valueWithoutPadding.length % 2);\n const value = `${leadingPad}${valueWithoutPadding}`;\n const bytes = [];\n for (let i = 0, length = value.length; i < length; i += 2) {\n bytes.push(parseInt(value.substring(i, i + 2), 16));\n }\n return bytes;\n }\n /**\n * Return an unsigned byte array\n * @memberof Address6\n * @instance\n * @returns {Array}\n */\n toUnsignedByteArray() {\n return this.toByteArray().map(unsignByte);\n }\n /**\n * Convert a byte array to an Address6 object\n * @memberof Address6\n * @static\n * @returns {Address6}\n */\n static fromByteArray(bytes) {\n return this.fromUnsignedByteArray(bytes.map(unsignByte));\n }\n /**\n * Convert an unsigned byte array to an Address6 object\n * @memberof Address6\n * @static\n * @returns {Address6}\n */\n static fromUnsignedByteArray(bytes) {\n const BYTE_MAX = BigInt('256');\n let result = BigInt('0');\n let multiplier = BigInt('1');\n for (let i = bytes.length - 1; i >= 0; i--) {\n result += multiplier * BigInt(bytes[i].toString(10));\n multiplier *= BYTE_MAX;\n }\n return Address6.fromBigInt(result);\n }\n /**\n * Returns true if the address is in the canonical form, false otherwise\n * @memberof Address6\n * @instance\n * @returns {boolean}\n */\n isCanonical() {\n return this.addressMinusSuffix === this.canonicalForm();\n }\n /**\n * Returns true if the address is a link local address, false otherwise\n * @memberof Address6\n * @instance\n * @returns {boolean}\n */\n isLinkLocal() {\n // Zeroes are required, i.e. we can't check isInSubnet with 'fe80::/10'\n if (this.getBitsBase2(0, 64) ===\n '1111111010000000000000000000000000000000000000000000000000000000') {\n return true;\n }\n return false;\n }\n /**\n * Returns true if the address is a multicast address, false otherwise\n * @memberof Address6\n * @instance\n * @returns {boolean}\n */\n isMulticast() {\n return this.getType() === 'Multicast';\n }\n /**\n * Returns true if the address is a v4-in-v6 address, false otherwise\n * @memberof Address6\n * @instance\n * @returns {boolean}\n */\n is4() {\n return this.v4;\n }\n /**\n * Returns true if the address is a Teredo address, false otherwise\n * @memberof Address6\n * @instance\n * @returns {boolean}\n */\n isTeredo() {\n return this.isInSubnet(new Address6('2001::/32'));\n }\n /**\n * Returns true if the address is a 6to4 address, false otherwise\n * @memberof Address6\n * @instance\n * @returns {boolean}\n */\n is6to4() {\n return this.isInSubnet(new Address6('2002::/16'));\n }\n /**\n * Returns true if the address is a loopback address, false otherwise\n * @memberof Address6\n * @instance\n * @returns {boolean}\n */\n isLoopback() {\n return this.getType() === 'Loopback';\n }\n // #endregion\n // #region HTML\n /**\n * @returns {String} the address in link form with a default port of 80\n */\n href(optionalPort) {\n if (optionalPort === undefined) {\n optionalPort = '';\n }\n else {\n optionalPort = `:${optionalPort}`;\n }\n return `http://[${this.correctForm()}]${optionalPort}/`;\n }\n /**\n * @returns {String} a link suitable for conveying the address via a URL hash\n */\n link(options) {\n if (!options) {\n options = {};\n }\n if (options.className === undefined) {\n options.className = '';\n }\n if (options.prefix === undefined) {\n options.prefix = '/#address=';\n }\n if (options.v4 === undefined) {\n options.v4 = false;\n }\n let formFunction = this.correctForm;\n if (options.v4) {\n formFunction = this.to4in6;\n }\n const form = formFunction.call(this);\n const safeHref = helpers.escapeHtml(`${options.prefix}${form}`);\n const safeForm = helpers.escapeHtml(form);\n if (options.className) {\n const safeClass = helpers.escapeHtml(options.className);\n return `<a href=\"${safeHref}\" class=\"${safeClass}\">${safeForm}</a>`;\n }\n return `<a href=\"${safeHref}\">${safeForm}</a>`;\n }\n /**\n * Groups an address\n * @returns {String}\n */\n group() {\n if (this.elidedGroups === 0) {\n // The simple case\n return helpers.simpleGroup(this.addressMinusSuffix).join(':');\n }\n assert(typeof this.elidedGroups === 'number');\n assert(typeof this.elisionBegin === 'number');\n // The elided case\n const output = [];\n const [left, right] = this.addressMinusSuffix.split('::');\n if (left.length) {\n output.push(...helpers.simpleGroup(left));\n }\n else {\n output.push('');\n }\n const classes = ['hover-group'];\n for (let i = this.elisionBegin; i < this.elisionBegin + this.elidedGroups; i++) {\n classes.push(`group-${i}`);\n }\n output.push(`<span class=\"${classes.join(' ')}\"></span>`);\n if (right.length) {\n output.push(...helpers.simpleGroup(right, this.elisionEnd));\n }\n else {\n output.push('');\n }\n if (this.is4()) {\n assert(this.address4 instanceof ipv4_1.Address4);\n output.pop();\n output.push(this.address4.groupForV6());\n }\n return output.join(':');\n }\n // #endregion\n // #region Regular expressions\n /**\n * Generate a regular expression string that can be used to find or validate\n * all variations of this address\n * @memberof Address6\n * @instance\n * @param {boolean} substringSearch\n * @returns {string}\n */\n regularExpressionString(substringSearch = false) {\n let output = [];\n // TODO: revisit why this is necessary\n const address6 = new Address6(this.correctForm());\n if (address6.elidedGroups === 0) {\n // The simple case\n output.push((0, regular_expressions_1.simpleRegularExpression)(address6.parsedAddress));\n }\n else if (address6.elidedGroups === constants6.GROUPS) {\n // A completely elided address\n output.push((0, regular_expressions_1.possibleElisions)(constants6.GROUPS));\n }\n else {\n // A partially elided address\n const halves = address6.address.split('::');\n if (halves[0].length) {\n output.push((0, regular_expressions_1.simpleRegularExpression)(halves[0].split(':')));\n }\n assert(typeof address6.elidedGroups === 'number');\n output.push((0, regular_expressions_1.possibleElisions)(address6.elidedGroups, halves[0].length !== 0, halves[1].length !== 0));\n if (halves[1].length) {\n output.push((0, regular_expressions_1.simpleRegularExpression)(halves[1].split(':')));\n }\n output = [output.join(':')];\n }\n if (!substringSearch) {\n output = [\n '(?=^|',\n regular_expressions_1.ADDRESS_BOUNDARY,\n '|[^\\\\w\\\\:])(',\n ...output,\n ')(?=[^\\\\w\\\\:]|',\n regular_expressions_1.ADDRESS_BOUNDARY,\n '|$)',\n ];\n }\n return output.join('');\n }\n /**\n * Generate a regular expression that can be used to find or validate all\n * variations of this address.\n * @memberof Address6\n * @instance\n * @param {boolean} substringSearch\n * @returns {RegExp}\n */\n regularExpression(substringSearch = false) {\n return new RegExp(this.regularExpressionString(substringSearch), 'i');\n }\n}\nexports.Address6 = Address6;\n//# sourceMappingURL=ipv6.js.map","\"use strict\";\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.v6 = exports.AddressError = exports.Address6 = exports.Address4 = void 0;\nvar ipv4_1 = require(\"./ipv4\");\nObject.defineProperty(exports, \"Address4\", { enumerable: true, get: function () { return ipv4_1.Address4; } });\nvar ipv6_1 = require(\"./ipv6\");\nObject.defineProperty(exports, \"Address6\", { enumerable: true, get: function () { return ipv6_1.Address6; } });\nvar address_error_1 = require(\"./address-error\");\nObject.defineProperty(exports, \"AddressError\", { enumerable: true, get: function () { return address_error_1.AddressError; } });\nconst helpers = __importStar(require(\"./v6/helpers\"));\nexports.v6 = { helpers };\n//# sourceMappingURL=ip-address.js.map","// source/ip-key-generator.ts\nimport { isIPv6 } from \"node:net\";\nimport { Address6 } from \"ip-address\";\nfunction ipKeyGenerator(ip, ipv6Subnet = 56) {\n if (isIPv6(ip)) {\n const address = new Address6(ip);\n if (address.is4()) return address.to4().correctForm();\n if (ipv6Subnet) {\n const subnet = new Address6(`${ip}/${ipv6Subnet}`);\n return subnet.networkForm();\n }\n }\n return ip;\n}\n\n// source/memory-store.ts\nvar MemoryStore = class {\n constructor(validations2) {\n this.validations = validations2;\n /**\n * These two maps store usage (requests) and reset time by key (for example, IP\n * addresses or API keys).\n *\n * They are split into two to avoid having to iterate through the entire set to\n * determine which ones need reset. Instead, `Client`s are moved from `previous`\n * to `current` as they hit the endpoint. Once `windowMs` has elapsed, all clients\n * left in `previous`, i.e., those that have not made any recent requests, are\n * known to be expired and can be deleted in bulk.\n */\n this.previous = /* @__PURE__ */ new Map();\n this.current = /* @__PURE__ */ new Map();\n /**\n * Confirmation that the keys incremented in once instance of MemoryStore\n * cannot affect other instances.\n */\n this.localKeys = true;\n }\n /**\n * Method that initializes the store.\n *\n * @param options {Options} - The options used to setup the middleware.\n */\n init(options) {\n this.windowMs = options.windowMs;\n this.validations?.windowMs(this.windowMs);\n if (this.interval) clearInterval(this.interval);\n this.interval = setInterval(() => {\n this.clearExpired();\n }, this.windowMs);\n this.interval.unref?.();\n }\n /**\n * Method to fetch a client's hit count and reset time.\n *\n * @param key {string} - The identifier for a client.\n *\n * @returns {ClientRateLimitInfo | undefined} - The number of hits and reset time for that client.\n *\n * @public\n */\n async get(key) {\n return this.current.get(key) ?? this.previous.get(key);\n }\n /**\n * Method to increment a client's hit counter.\n *\n * @param key {string} - The identifier for a client.\n *\n * @returns {ClientRateLimitInfo} - The number of hits and reset time for that client.\n *\n * @public\n */\n async increment(key) {\n const client = this.getClient(key);\n const now = Date.now();\n if (client.resetTime.getTime() <= now) {\n this.resetClient(client, now);\n }\n client.totalHits++;\n return client;\n }\n /**\n * Method to decrement a client's hit counter.\n *\n * @param key {string} - The identifier for a client.\n *\n * @public\n */\n async decrement(key) {\n const client = this.getClient(key);\n if (client.totalHits > 0) client.totalHits--;\n }\n /**\n * Method to reset a client's hit counter.\n *\n * @param key {string} - The identifier for a client.\n *\n * @public\n */\n async resetKey(key) {\n this.current.delete(key);\n this.previous.delete(key);\n }\n /**\n * Method to reset everyone's hit counter.\n *\n * @public\n */\n async resetAll() {\n this.current.clear();\n this.previous.clear();\n }\n /**\n * Method to stop the timer (if currently running) and prevent any memory\n * leaks.\n *\n * @public\n */\n shutdown() {\n clearInterval(this.interval);\n void this.resetAll();\n }\n /**\n * Recycles a client by setting its hit count to zero, and reset time to\n * `windowMs` milliseconds from now.\n *\n * NOT to be confused with `#resetKey()`, which removes a client from both the\n * `current` and `previous` maps.\n *\n * @param client {Client} - The client to recycle.\n * @param now {number} - The current time, to which the `windowMs` is added to get the `resetTime` for the client.\n *\n * @return {Client} - The modified client that was passed in, to allow for chaining.\n */\n resetClient(client, now = Date.now()) {\n client.totalHits = 0;\n client.resetTime.setTime(now + this.windowMs);\n return client;\n }\n /**\n * Retrieves or creates a client, given a key. Also ensures that the client being\n * returned is in the `current` map.\n *\n * @param key {string} - The key under which the client is (or is to be) stored.\n *\n * @returns {Client} - The requested client.\n */\n getClient(key) {\n if (this.current.has(key)) return this.current.get(key);\n let client;\n if (this.previous.has(key)) {\n client = this.previous.get(key);\n this.previous.delete(key);\n } else {\n client = { totalHits: 0, resetTime: /* @__PURE__ */ new Date() };\n this.resetClient(client);\n }\n this.current.set(key, client);\n return client;\n }\n /**\n * Move current clients to previous, create a new map for current.\n *\n * This function is called every `windowMs`.\n */\n clearExpired() {\n this.previous = this.current;\n this.current = /* @__PURE__ */ new Map();\n }\n};\n\n// source/rate-limit.ts\nimport { isIPv6 as isIPv62 } from \"node:net\";\n\n// source/console-logger.ts\nvar ConsoleLogger = {\n warn(...args) {\n console.warn(...args.reverse());\n },\n error(...args) {\n console.error(...args.reverse());\n }\n};\n\n// source/headers.ts\nimport { Buffer } from \"node:buffer\";\nimport { createHash } from \"node:crypto\";\nvar SUPPORTED_DRAFT_VERSIONS = [\n \"draft-6\",\n \"draft-7\",\n \"draft-8\"\n];\nvar getResetSeconds = (windowMs, resetTime) => {\n let resetSeconds;\n if (resetTime) {\n const deltaSeconds = Math.ceil((resetTime.getTime() - Date.now()) / 1e3);\n resetSeconds = Math.max(0, deltaSeconds);\n } else {\n resetSeconds = Math.ceil(windowMs / 1e3);\n }\n return resetSeconds;\n};\nvar getPartitionKey = (key) => {\n const hash = createHash(\"sha256\");\n hash.update(key);\n const partitionKey = hash.digest(\"hex\").slice(0, 12);\n return Buffer.from(partitionKey).toString(\"base64\");\n};\nvar setLegacyHeaders = (response, info) => {\n if (response.headersSent) return;\n response.setHeader(\"X-RateLimit-Limit\", info.limit.toString());\n response.setHeader(\"X-RateLimit-Remaining\", info.remaining.toString());\n if (info.resetTime instanceof Date) {\n response.setHeader(\"Date\", (/* @__PURE__ */ new Date()).toUTCString());\n response.setHeader(\n \"X-RateLimit-Reset\",\n Math.ceil(info.resetTime.getTime() / 1e3).toString()\n );\n }\n};\nvar setDraft6Headers = (response, info, windowMs) => {\n if (response.headersSent) return;\n const windowSeconds = Math.ceil(windowMs / 1e3);\n const resetSeconds = getResetSeconds(windowMs, info.resetTime);\n response.setHeader(\"RateLimit-Policy\", `${info.limit};w=${windowSeconds}`);\n response.setHeader(\"RateLimit-Limit\", info.limit.toString());\n response.setHeader(\"RateLimit-Remaining\", info.remaining.toString());\n if (typeof resetSeconds === \"number\")\n response.setHeader(\"RateLimit-Reset\", resetSeconds.toString());\n};\nvar setDraft7Headers = (response, info, windowMs) => {\n if (response.headersSent) return;\n const windowSeconds = Math.ceil(windowMs / 1e3);\n const resetSeconds = getResetSeconds(windowMs, info.resetTime);\n response.setHeader(\"RateLimit-Policy\", `${info.limit};w=${windowSeconds}`);\n response.setHeader(\n \"RateLimit\",\n `limit=${info.limit}, remaining=${info.remaining}, reset=${resetSeconds}`\n );\n};\nvar setDraft8Headers = (response, info, windowMs, name, key) => {\n if (response.headersSent) return;\n const windowSeconds = Math.ceil(windowMs / 1e3);\n const resetSeconds = getResetSeconds(windowMs, info.resetTime);\n const partitionKey = getPartitionKey(key);\n const header = `r=${info.remaining}; t=${resetSeconds}`;\n const policy = `q=${info.limit}; w=${windowSeconds}; pk=:${partitionKey}:`;\n response.append(\"RateLimit\", `\"${name}\"; ${header}`);\n response.append(\"RateLimit-Policy\", `\"${name}\"; ${policy}`);\n};\nvar setRetryAfterHeader = (response, info, windowMs) => {\n if (response.headersSent) return;\n const resetSeconds = getResetSeconds(windowMs, info.resetTime);\n response.setHeader(\"Retry-After\", resetSeconds.toString());\n};\n\n// source/utils.ts\nvar omitUndefinedProperties = (passedOptions) => {\n const omittedOptions = {};\n for (const k of Object.keys(passedOptions)) {\n const key = k;\n if (passedOptions[key] !== void 0) {\n omittedOptions[key] = passedOptions[key];\n }\n }\n return omittedOptions;\n};\n\n// source/validations.ts\nimport { isIP } from \"node:net\";\nvar ValidationError = class extends Error {\n /**\n * The code must be a string, in snake case and all capital, that starts with\n * the substring `ERR_ERL_`.\n *\n * The message must be a string, starting with an uppercase character,\n * describing the issue in detail.\n */\n constructor(code, message) {\n const url = `https://express-rate-limit.github.io/${code}/`;\n super(`${message} See ${url} for more information.`);\n this.name = this.constructor.name;\n this.code = code;\n this.help = url;\n }\n};\nvar ChangeWarning = class extends ValidationError {\n};\nvar usedStores = /* @__PURE__ */ new Set();\nvar singleCountKeys = /* @__PURE__ */ new WeakMap();\nvar validations = {\n enabled: {\n default: true\n },\n // Should be EnabledValidations type, but that's a circular reference\n disable() {\n for (const k of Object.keys(this.enabled)) this.enabled[k] = false;\n },\n /**\n * Checks whether the IP address is valid, and that it does not have a port\n * number in it.\n *\n * See https://github.com/express-rate-limit/express-rate-limit/wiki/Error-Codes#err_erl_invalid_ip_address.\n *\n * @param ip {string | undefined} - The IP address provided by Express as request.ip.\n *\n * @returns {void}\n */\n ip(ip) {\n if (ip === void 0) {\n throw new ValidationError(\n \"ERR_ERL_UNDEFINED_IP_ADDRESS\",\n `An undefined 'request.ip' was detected. This might indicate a misconfiguration or the connection being destroyed prematurely.`\n );\n }\n if (!isIP(ip)) {\n throw new ValidationError(\n \"ERR_ERL_INVALID_IP_ADDRESS\",\n `An invalid 'request.ip' (${ip}) was detected. Consider passing a custom 'keyGenerator' function to the rate limiter.`\n );\n }\n },\n /**\n * Makes sure the trust proxy setting is not set to `true`.\n *\n * See https://github.com/express-rate-limit/express-rate-limit/wiki/Error-Codes#err_erl_permissive_trust_proxy.\n *\n * @param request {Request} - The Express request object.\n *\n * @returns {void}\n */\n trustProxy(request) {\n if (request.app.get(\"trust proxy\") === true) {\n throw new ValidationError(\n \"ERR_ERL_PERMISSIVE_TRUST_PROXY\",\n `The Express 'trust proxy' setting is true, which allows anyone to trivially bypass IP-based rate limiting.`\n );\n }\n },\n /**\n * Makes sure the trust proxy setting is set in case the `X-Forwarded-For`\n * header is present.\n *\n * See https://github.com/express-rate-limit/express-rate-limit/wiki/Error-Codes#err_erl_unset_trust_proxy.\n *\n * @param request {Request} - The Express request object.\n *\n * @returns {void}\n */\n xForwardedForHeader(request) {\n if (request.headers[\"x-forwarded-for\"] && request.app.get(\"trust proxy\") === false) {\n throw new ValidationError(\n \"ERR_ERL_UNEXPECTED_X_FORWARDED_FOR\",\n `The 'X-Forwarded-For' header is set but the Express 'trust proxy' setting is false (default). This could indicate a misconfiguration which would prevent express-rate-limit from accurately identifying users.`\n );\n }\n },\n /**\n * Alert the user if the Forwarded header is set (standardized version of X-Forwarded-For - not supported by express as of version 5.1.0)\n *\n * @param request {Request} - The Express request object.\n *\n * @returns {void}\n */\n forwardedHeader(request) {\n if (request.headers.forwarded && request.ip === request.socket?.remoteAddress) {\n throw new ValidationError(\n \"ERR_ERL_FORWARDED_HEADER\",\n `The 'Forwarded' header (standardized X-Forwarded-For) is set but currently being ignored. Add a custom keyGenerator to use a value from this header.`\n );\n }\n },\n /**\n * Ensures totalHits value from store is a positive integer.\n *\n * @param hits {any} - The `totalHits` returned by the store.\n */\n positiveHits(hits) {\n if (typeof hits !== \"number\" || hits < 1 || hits !== Math.round(hits)) {\n throw new ValidationError(\n \"ERR_ERL_INVALID_HITS\",\n `The totalHits value returned from the store must be a positive integer, got ${hits}`\n );\n }\n },\n /**\n * Ensures a single store instance is not used with multiple express-rate-limit instances\n */\n unsharedStore(store) {\n if (usedStores.has(store)) {\n const maybeUniquePrefix = store?.localKeys ? \"\" : \" (with a unique prefix)\";\n throw new ValidationError(\n \"ERR_ERL_STORE_REUSE\",\n `A Store instance must not be shared across multiple rate limiters. Create a new instance of ${store.constructor.name}${maybeUniquePrefix} for each limiter instead.`\n );\n }\n usedStores.add(store);\n },\n /**\n * Ensures a given key is incremented only once per request.\n *\n * @param request {Request} - The Express request object.\n * @param store {Store} - The store class.\n * @param key {string} - The key used to store the client's hit count.\n *\n * @returns {void}\n */\n singleCount(request, store, key) {\n let storeKeys = singleCountKeys.get(request);\n if (!storeKeys) {\n storeKeys = /* @__PURE__ */ new Map();\n singleCountKeys.set(request, storeKeys);\n }\n const storeKey = store.localKeys ? store : store.constructor.name;\n let keys = storeKeys.get(storeKey);\n if (!keys) {\n keys = [];\n storeKeys.set(storeKey, keys);\n }\n const prefixedKey = `${store.prefix ?? \"\"}${key}`;\n if (keys.includes(prefixedKey)) {\n throw new ValidationError(\n \"ERR_ERL_DOUBLE_COUNT\",\n `The hit count for ${key} was incremented more than once for a single request.`\n );\n }\n keys.push(prefixedKey);\n },\n /**\n * Warns the user that the behaviour for `max: 0` / `limit: 0` is\n * changing in the next major release.\n *\n * @param limit {number} - The maximum number of hits per client.\n *\n * @returns {void}\n */\n limit(limit) {\n if (limit === 0) {\n throw new ChangeWarning(\n \"WRN_ERL_MAX_ZERO\",\n \"Setting limit or max to 0 disables rate limiting in express-rate-limit v6 and older, but will cause all requests to be blocked in v7\"\n );\n }\n },\n /**\n * Warns the user that the `draft_polli_ratelimit_headers` option is deprecated\n * and will be removed in the next major release.\n *\n * @param draft_polli_ratelimit_headers {any | undefined} - The now-deprecated setting that was used to enable standard headers.\n *\n * @returns {void}\n */\n draftPolliHeaders(draft_polli_ratelimit_headers) {\n if (draft_polli_ratelimit_headers) {\n throw new ChangeWarning(\n \"WRN_ERL_DEPRECATED_DRAFT_POLLI_HEADERS\",\n `The draft_polli_ratelimit_headers configuration option is deprecated and has been removed in express-rate-limit v7, please set standardHeaders: 'draft-6' instead.`\n );\n }\n },\n /**\n * Warns the user that the `onLimitReached` option is deprecated and\n * will be removed in the next major release.\n *\n * @param onLimitReached {any | undefined} - The maximum number of hits per client.\n *\n * @returns {void}\n */\n onLimitReached(onLimitReached) {\n if (onLimitReached) {\n throw new ChangeWarning(\n \"WRN_ERL_DEPRECATED_ON_LIMIT_REACHED\",\n \"The onLimitReached configuration option is deprecated and has been removed in express-rate-limit v7.\"\n );\n }\n },\n /**\n * Warns the user when an invalid/unsupported version of the draft spec is passed.\n *\n * @param version {any | undefined} - The version passed by the user.\n *\n * @returns {void}\n */\n headersDraftVersion(version) {\n if (typeof version !== \"string\" || // @ts-expect-error This is fine. If version is not in the array, it will just return false.\n !SUPPORTED_DRAFT_VERSIONS.includes(version)) {\n const versionString = SUPPORTED_DRAFT_VERSIONS.join(\", \");\n throw new ValidationError(\n \"ERR_ERL_HEADERS_UNSUPPORTED_DRAFT_VERSION\",\n `standardHeaders: only the following versions of the IETF draft specification are supported: ${versionString}.`\n );\n }\n },\n /**\n * Warns the user when the selected headers option requires a reset time but\n * the store does not provide one.\n *\n * @param resetTime {Date | undefined} - The timestamp when the client's hit count will be reset.\n *\n * @returns {void}\n */\n headersResetTime(resetTime) {\n if (!resetTime) {\n throw new ValidationError(\n \"ERR_ERL_HEADERS_NO_RESET\",\n `standardHeaders: 'draft-7' requires a 'resetTime', but the store did not provide one. The 'windowMs' value will be used instead, which may cause clients to wait longer than necessary.`\n );\n }\n },\n knownOptions(passedOptions) {\n if (!passedOptions) return;\n const optionsMap = {\n windowMs: true,\n limit: true,\n message: true,\n statusCode: true,\n legacyHeaders: true,\n standardHeaders: true,\n identifier: true,\n requestPropertyName: true,\n skipFailedRequests: true,\n skipSuccessfulRequests: true,\n keyGenerator: true,\n ipv6Subnet: true,\n handler: true,\n skip: true,\n requestWasSuccessful: true,\n store: true,\n validate: true,\n headers: true,\n max: true,\n passOnStoreError: true,\n logger: true\n };\n const validOptions = Object.keys(optionsMap).concat(\n \"draft_polli_ratelimit_headers\",\n // not a valid option anymore, but we have a more specific check for this one, so don't warn for it here\n // from express-slow-down - https://github.com/express-rate-limit/express-slow-down/blob/main/source/types.ts#L65\n \"delayAfter\",\n \"delayMs\",\n \"maxDelayMs\"\n );\n for (const key of Object.keys(passedOptions)) {\n if (!validOptions.includes(key)) {\n throw new ValidationError(\n \"ERR_ERL_UNKNOWN_OPTION\",\n `Unexpected configuration option: ${key}`\n // todo: suggest a valid option with a short levenstein distance?\n );\n }\n }\n },\n /**\n * Checks the options.validate setting to ensure that only recognized\n * validations are enabled or disabled.\n *\n * If any unrecognized values are found, an error is logged that\n * includes the list of supported validations.\n */\n validationsConfig() {\n const supportedValidations = Object.keys(this).filter(\n (k) => ![\"enabled\", \"disable\"].includes(k)\n );\n supportedValidations.push(\"default\");\n for (const key of Object.keys(this.enabled)) {\n if (!supportedValidations.includes(key)) {\n throw new ValidationError(\n \"ERR_ERL_UNKNOWN_VALIDATION\",\n `options.validate.${key} is not recognized. Supported validate options are: ${supportedValidations.join(\n \", \"\n )}.`\n );\n }\n }\n },\n /**\n * Checks to see if the instance was created inside of a request handler,\n * which would prevent it from working correctly, with the default memory\n * store (or any other store with localKeys.)\n */\n creationStack(store) {\n const { stack } = new Error(\n \"express-rate-limit validation check (set options.validate.creationStack=false to disable)\"\n );\n if (stack?.includes(\"Layer.handle [as handle_request]\") || // express v4\n stack?.includes(\"Layer.handleRequest\")) {\n if (!store.localKeys) {\n throw new ValidationError(\n \"ERR_ERL_CREATED_IN_REQUEST_HANDLER\",\n \"express-rate-limit instance should *usually* be created at app initialization, not when responding to a request.\"\n );\n }\n throw new ValidationError(\n \"ERR_ERL_CREATED_IN_REQUEST_HANDLER\",\n \"express-rate-limit instance should be created at app initialization, not when responding to a request.\"\n );\n }\n },\n ipv6Subnet(ipv6Subnet) {\n if (ipv6Subnet === false) {\n return;\n }\n if (!Number.isInteger(ipv6Subnet) || ipv6Subnet < 32 || ipv6Subnet > 64) {\n throw new ValidationError(\n \"ERR_ERL_IPV6_SUBNET\",\n `Unexpected ipv6Subnet value: ${ipv6Subnet}. Expected an integer between 32 and 64 (usually 48-64).`\n );\n }\n },\n ipv6SubnetOrKeyGenerator(options) {\n if (options.ipv6Subnet !== void 0 && options.keyGenerator) {\n throw new ValidationError(\n \"ERR_ERL_IPV6SUBNET_OR_KEYGENERATOR\",\n `Incompatible options: the 'ipv6Subnet' option is ignored when a custom 'keyGenerator' function is also set.`\n );\n }\n },\n keyGeneratorIpFallback(keyGenerator) {\n if (!keyGenerator) {\n return;\n }\n const src = keyGenerator.toString();\n if ((src.includes(\"req.ip\") || src.includes(\"request.ip\")) && !src.includes(\"ipKeyGenerator\")) {\n throw new ValidationError(\n \"ERR_ERL_KEY_GEN_IPV6\",\n \"Custom keyGenerator appears to use request IP without calling the ipKeyGenerator helper function for IPv6 addresses. This could allow IPv6 users to bypass limits.\"\n );\n }\n },\n /**\n * Checks to see if the window duration is greater than 2^32 - 1. This is only\n * called by the default MemoryStore, since it uses Node's setInterval method.\n *\n * See https://nodejs.org/api/timers.html#setintervalcallback-delay-args.\n */\n windowMs(windowMs) {\n const SET_TIMEOUT_MAX = 2 ** 31 - 1;\n if (typeof windowMs !== \"number\" || Number.isNaN(windowMs) || windowMs < 1 || windowMs > SET_TIMEOUT_MAX) {\n throw new ValidationError(\n \"ERR_ERL_WINDOW_MS\",\n `Invalid windowMs value: ${windowMs}${typeof windowMs !== \"number\" ? ` (${typeof windowMs})` : \"\"}, must be a number between 1 and ${SET_TIMEOUT_MAX} when using the default MemoryStore`\n );\n }\n }\n};\nfunction validateLogger(logger) {\n if (typeof logger !== \"object\" || typeof logger.error !== \"function\" || typeof logger.warn !== \"function\") {\n throw new TypeError(\n \"Provided logger does not implement the Logger interface\"\n );\n }\n}\nvar getValidations = (_enabled, logger) => {\n validateLogger(logger);\n let enabled;\n if (typeof _enabled === \"boolean\") {\n enabled = {\n default: _enabled\n };\n } else {\n enabled = {\n default: true,\n ..._enabled\n };\n }\n const wrappedValidations = { enabled };\n for (const [name, validation] of Object.entries(validations)) {\n if (typeof validation === \"function\")\n wrappedValidations[name] = (...args) => {\n if (!(enabled[name] ?? enabled.default)) {\n return;\n }\n try {\n ;\n validation.apply(\n wrappedValidations,\n args\n );\n } catch (error) {\n if (error instanceof ChangeWarning) logger.warn(error);\n else logger.error(error);\n }\n };\n }\n return wrappedValidations;\n};\n\n// source/rate-limit.ts\nvar isLegacyStore = (store) => (\n // Check that `incr` exists but `increment` does not - store authors might want\n // to keep both around for backwards compatibility.\n typeof store.incr === \"function\" && typeof store.increment !== \"function\"\n);\nvar promisifyStore = (passedStore) => {\n if (!isLegacyStore(passedStore)) {\n return passedStore;\n }\n const legacyStore = passedStore;\n class PromisifiedStore {\n async increment(key) {\n return new Promise((resolve, reject) => {\n legacyStore.incr(\n key,\n (error, totalHits, resetTime) => {\n if (error) reject(error);\n resolve({ totalHits, resetTime });\n }\n );\n });\n }\n async decrement(key) {\n return legacyStore.decrement(key);\n }\n async resetKey(key) {\n return legacyStore.resetKey(key);\n }\n /* istanbul ignore next */\n async resetAll() {\n if (typeof legacyStore.resetAll === \"function\")\n return legacyStore.resetAll();\n }\n }\n return new PromisifiedStore();\n};\nvar getOptionsFromConfig = (config) => {\n const { validations: validations2, ...directlyPassableEntries } = config;\n return {\n ...directlyPassableEntries,\n validate: validations2.enabled\n };\n};\nvar parseOptions = (passedOptions) => {\n const notUndefinedOptions = omitUndefinedProperties(passedOptions);\n const logger = passedOptions.logger ?? ConsoleLogger;\n const validations2 = getValidations(\n notUndefinedOptions?.validate ?? true,\n logger\n );\n validations2.validationsConfig();\n validations2.knownOptions(passedOptions);\n validations2.draftPolliHeaders(\n // @ts-expect-error see the note above.\n notUndefinedOptions.draft_polli_ratelimit_headers\n );\n validations2.onLimitReached(notUndefinedOptions.onLimitReached);\n if (notUndefinedOptions.ipv6Subnet !== void 0 && typeof notUndefinedOptions.ipv6Subnet !== \"function\") {\n validations2.ipv6Subnet(notUndefinedOptions.ipv6Subnet);\n }\n validations2.keyGeneratorIpFallback(notUndefinedOptions.keyGenerator);\n validations2.ipv6SubnetOrKeyGenerator(notUndefinedOptions);\n let standardHeaders = notUndefinedOptions.standardHeaders ?? false;\n if (standardHeaders === true) standardHeaders = \"draft-6\";\n const config = {\n windowMs: 60 * 1e3,\n limit: passedOptions.max ?? 5,\n // `max` is deprecated, but support it anyways.\n message: \"Too many requests, please try again later.\",\n statusCode: 429,\n legacyHeaders: passedOptions.headers ?? true,\n identifier(request, _response) {\n let duration = \"\";\n const property = config.requestPropertyName;\n const { limit } = request[property];\n const seconds = config.windowMs / 1e3;\n const minutes = config.windowMs / (1e3 * 60);\n const hours = config.windowMs / (1e3 * 60 * 60);\n const days = config.windowMs / (1e3 * 60 * 60 * 24);\n if (seconds < 60) duration = `${seconds}sec`;\n else if (minutes < 60) duration = `${minutes}min`;\n else if (hours < 24) duration = `${hours}hr${hours > 1 ? \"s\" : \"\"}`;\n else duration = `${days}day${days > 1 ? \"s\" : \"\"}`;\n return `${limit}-in-${duration}`;\n },\n requestPropertyName: \"rateLimit\",\n skipFailedRequests: false,\n skipSuccessfulRequests: false,\n requestWasSuccessful: (_request, response) => response.statusCode < 400,\n skip: (_request, _response) => false,\n async keyGenerator(request, response) {\n validations2.ip(request.ip);\n validations2.trustProxy(request);\n validations2.xForwardedForHeader(request);\n validations2.forwardedHeader(request);\n const ip = request.ip;\n let subnet = 56;\n if (isIPv62(ip)) {\n subnet = typeof config.ipv6Subnet === \"function\" ? await config.ipv6Subnet(request, response) : config.ipv6Subnet;\n if (typeof config.ipv6Subnet === \"function\")\n validations2.ipv6Subnet(subnet);\n }\n return ipKeyGenerator(ip, subnet);\n },\n ipv6Subnet: 56,\n async handler(request, response, _next, _optionsUsed) {\n response.status(config.statusCode);\n const message = typeof config.message === \"function\" ? await config.message(\n request,\n response\n ) : config.message;\n if (!response.writableEnded) response.send(message);\n },\n passOnStoreError: false,\n // Allow the default options to be overridden by the passed options.\n ...notUndefinedOptions,\n // `standardHeaders` is resolved into a draft version above, use that.\n standardHeaders,\n // Note that this field is declared after the user's options are spread in,\n // so that this field doesn't get overridden with an un-promisified store!\n store: promisifyStore(\n notUndefinedOptions.store ?? new MemoryStore(validations2)\n ),\n // Print an error to the console if a few known misconfigurations are detected.\n validations: validations2,\n logger\n };\n if (typeof config.store.increment !== \"function\" || typeof config.store.decrement !== \"function\" || typeof config.store.resetKey !== \"function\" || config.store.resetAll !== void 0 && typeof config.store.resetAll !== \"function\" || config.store.init !== void 0 && typeof config.store.init !== \"function\") {\n throw new TypeError(\n \"An invalid store was passed. Please ensure that the store is a class that implements the `Store` interface.\"\n );\n }\n return config;\n};\nvar handleAsyncErrors = (fn) => async (request, response, next) => {\n try {\n await Promise.resolve(fn(request, response, next)).catch(next);\n } catch (error) {\n next(error);\n }\n};\nvar rateLimit = (passedOptions) => {\n const config = parseOptions(passedOptions ?? {});\n const options = getOptionsFromConfig(config);\n config.validations.creationStack(config.store);\n config.validations.unsharedStore(config.store);\n if (typeof config.store.init === \"function\") {\n try {\n const storeInit = config.store.init(options);\n if (storeInit instanceof Promise) {\n storeInit.catch(\n (error) => config.logger.error(\n error,\n \"express-rate-limit: async error during store initialization.\"\n )\n );\n }\n } catch (error) {\n config.logger.error(\n error,\n \"express-rate-limit: error during store initialization.\"\n );\n }\n }\n const middleware = handleAsyncErrors(\n async (request, response, next) => {\n const closePromise = config.skipFailedRequests && new Promise((resolve) => response.once(\"close\", resolve));\n const finishPromise = (config.skipFailedRequests || config.skipSuccessfulRequests) && new Promise((resolve) => response.once(\"finish\", resolve));\n const errorPromise = config.skipFailedRequests && new Promise((resolve) => response.once(\"error\", resolve));\n const skip = await config.skip(request, response);\n if (skip) {\n next();\n return;\n }\n const augmentedRequest = request;\n const key = await config.keyGenerator(request, response);\n let totalHits = 0;\n let resetTime;\n try {\n const incrementResult = await config.store.increment(key);\n totalHits = incrementResult.totalHits;\n resetTime = incrementResult.resetTime;\n } catch (error) {\n if (config.passOnStoreError) {\n config.logger.error(\n error,\n \"express-rate-limit: error from store, allowing request without rate-limiting.\"\n );\n next();\n return;\n }\n throw error;\n }\n config.validations.positiveHits(totalHits);\n config.validations.singleCount(request, config.store, key);\n const retrieveLimit = typeof config.limit === \"function\" ? config.limit(request, response) : config.limit;\n const limit = await retrieveLimit;\n config.validations.limit(limit);\n const info = {\n limit,\n used: totalHits,\n remaining: Math.max(limit - totalHits, 0),\n resetTime,\n key\n };\n Object.defineProperty(info, \"current\", {\n configurable: false,\n enumerable: false,\n value: totalHits\n });\n augmentedRequest[config.requestPropertyName] = info;\n if (config.legacyHeaders && !response.headersSent) {\n setLegacyHeaders(response, info);\n }\n if (config.standardHeaders && !response.headersSent) {\n switch (config.standardHeaders) {\n case \"draft-6\": {\n setDraft6Headers(response, info, config.windowMs);\n break;\n }\n case \"draft-7\": {\n config.validations.headersResetTime(info.resetTime);\n setDraft7Headers(response, info, config.windowMs);\n break;\n }\n case \"draft-8\": {\n const retrieveName = typeof config.identifier === \"function\" ? config.identifier(request, response) : config.identifier;\n const name = await retrieveName;\n config.validations.headersResetTime(info.resetTime);\n setDraft8Headers(response, info, config.windowMs, name, key);\n break;\n }\n default: {\n config.validations.headersDraftVersion(config.standardHeaders);\n break;\n }\n }\n }\n if (config.skipFailedRequests || config.skipSuccessfulRequests) {\n let decremented = false;\n const decrementKey = async () => {\n if (!decremented) {\n await config.store.decrement(key);\n decremented = true;\n }\n };\n if (config.skipFailedRequests) {\n if (finishPromise) {\n void finishPromise.then(async () => {\n if (!await config.requestWasSuccessful(request, response))\n await decrementKey();\n });\n }\n if (closePromise) {\n void closePromise.then(async () => {\n if (!response.writableEnded) await decrementKey();\n });\n }\n if (errorPromise) {\n void errorPromise.then(async () => {\n await decrementKey();\n });\n }\n }\n if (config.skipSuccessfulRequests) {\n if (finishPromise) {\n void finishPromise.then(async () => {\n if (await config.requestWasSuccessful(request, response))\n await decrementKey();\n });\n }\n }\n }\n config.validations.disable();\n if (totalHits > limit) {\n if (config.legacyHeaders || config.standardHeaders) {\n setRetryAfterHeader(response, info, config.windowMs);\n }\n config.handler(request, response, next, options);\n return;\n }\n next();\n }\n );\n const getThrowFn = () => {\n throw new Error(\"The current store does not support the get/getKey method\");\n };\n middleware.resetKey = config.store.resetKey.bind(config.store);\n middleware.getKey = typeof config.store.get === \"function\" ? config.store.get.bind(config.store) : getThrowFn;\n return middleware;\n};\nvar rate_limit_default = rateLimit;\nexport {\n MemoryStore,\n rate_limit_default as default,\n ipKeyGenerator,\n rate_limit_default as rateLimit\n};\n","/**\n * @codemem/mcp — privacy-safe OAuth audit events.\n *\n * Phase 1 single-user remote MCP needs operator-visible security events\n * (registration, authorize, OIDC callback, token issuance, revocation, bearer\n * verification) without ever logging bearer tokens, authorization codes,\n * client secrets, OIDC ID tokens, or private memory contents.\n */\n\nexport type OAuthAuditKind =\n\t| \"registration\"\n\t| \"authorize\"\n\t| \"oidc_callback\"\n\t| \"token\"\n\t| \"refresh\"\n\t| \"rotation\"\n\t| \"revocation\"\n\t| \"bearer\";\n\nexport type OAuthAuditOutcome = \"success\" | \"denied\" | \"error\";\n\nexport type BearerDenyReason =\n\t| \"missing_authorization_header\"\n\t| \"malformed_authorization_header\"\n\t| \"unknown_token\"\n\t| \"expired_token\"\n\t| \"revoked_token\";\n\nexport interface OAuthAuditEventBase {\n\ttimestamp: string;\n\toutcome: OAuthAuditOutcome;\n\treason?: string;\n\tclientId?: string;\n\tremoteAddress?: string;\n}\n\nexport type OAuthAuditEvent = OAuthAuditEventBase & { kind: OAuthAuditKind };\n\nexport type OAuthAuditEmitter = (event: OAuthAuditEvent) => void;\n\n// Canonicalized denylist — keys are compared after lowercasing and stripping\n// non-alphanumeric separators, so `access_token`, `accessToken`, `ACCESS-TOKEN`\n// and `access token` all reduce to `accesstoken` and are blocked uniformly.\n// This codebase commonly uses camelCase identifiers, so a snake_case-only\n// denylist would miss real leak vectors.\nconst FORBIDDEN_KEY_TOKENS = new Set([\n\t\"token\",\n\t\"accesstoken\",\n\t\"refreshtoken\",\n\t\"idtoken\",\n\t\"code\",\n\t\"codeverifier\",\n\t\"codechallenge\",\n\t\"clientsecret\",\n\t\"authorization\",\n\t\"password\",\n\t\"secret\",\n]);\n\nfunction canonicalizeAuditKey(key: string): string {\n\treturn key.toLowerCase().replace(/[^a-z0-9]/g, \"\");\n}\n\n/**\n * Build an audit event with redaction safety. Throws if a forbidden field\n * leaks in; callers should never need to pass token/code material here.\n */\nexport function buildOAuthAuditEvent(\n\tkind: OAuthAuditKind,\n\tfields: Omit<OAuthAuditEventBase, \"timestamp\"> & { now?: number },\n): OAuthAuditEvent {\n\tfor (const key of Object.keys(fields)) {\n\t\tif (FORBIDDEN_KEY_TOKENS.has(canonicalizeAuditKey(key))) {\n\t\t\tthrow new Error(`OAuth audit event must not carry forbidden field: ${key}`);\n\t\t}\n\t}\n\tconst { now, ...rest } = fields;\n\treturn {\n\t\tkind,\n\t\ttimestamp: new Date(now ?? Date.now()).toISOString(),\n\t\t...rest,\n\t};\n}\n\n/**\n * Wrap an audit emitter so any synchronous throw or stream-write failure stays\n * contained. Audit logging is best-effort observability and must never break\n * the OAuth/MCP request flow it observes. Failures are reported once per\n * process to `console.error` so they remain visible without flooding output.\n */\nexport function wrapAuditEmitterBestEffort(emit: OAuthAuditEmitter): OAuthAuditEmitter {\n\tlet reportedFailure = false;\n\treturn (event) => {\n\t\ttry {\n\t\t\temit(event);\n\t\t} catch (err) {\n\t\t\tif (!reportedFailure) {\n\t\t\t\treportedFailure = true;\n\t\t\t\tconsole.error(\"codemem MCP OAuth audit emitter failed (further failures suppressed):\", err);\n\t\t\t}\n\t\t}\n\t};\n}\n\n/**\n * Default audit emitter writes one JSON object per line to stderr. This keeps\n * MCP HTTP stdout reserved for protocol traffic and is greppable by operators\n * via `journalctl` or a redirected log file.\n */\nexport function createDefaultOAuthAuditEmitter(\n\tstream: NodeJS.WriteStream = process.stderr,\n): OAuthAuditEmitter {\n\treturn (event) => {\n\t\tstream.write(`${JSON.stringify({ source: \"codemem-mcp-oauth-audit\", ...event })}\\n`);\n\t};\n}\n\n/**\n * No-op emitter, used when CODEMEM_MCP_AUDIT=0 or when callers explicitly\n * want to suppress audit output (for example, embedded tests).\n */\nexport function createSilentOAuthAuditEmitter(): OAuthAuditEmitter {\n\treturn () => {};\n}\n\n/**\n * Resolve an emitter from environment configuration. `CODEMEM_MCP_AUDIT=0`,\n * `false`, or `no` disables audit logging; anything else (including unset)\n * uses the default stderr emitter.\n */\nexport function resolveOAuthAuditEmitterFromEnv(\n\tvalue = process.env.CODEMEM_MCP_AUDIT,\n): OAuthAuditEmitter {\n\tconst normalized = value?.trim().toLowerCase();\n\tif (normalized === \"0\" || normalized === \"false\" || normalized === \"no\") {\n\t\treturn createSilentOAuthAuditEmitter();\n\t}\n\treturn createDefaultOAuthAuditEmitter();\n}\n","import { createHash, createHmac, randomBytes, randomUUID, timingSafeEqual } from \"node:crypto\";\nimport { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from \"node:fs\";\nimport { chmod } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport type { OAuthRegisteredClientsStore } from \"@modelcontextprotocol/sdk/server/auth/clients.js\";\nimport { InvalidClientMetadataError } from \"@modelcontextprotocol/sdk/server/auth/errors.js\";\nimport type { OAuthServerProvider } from \"@modelcontextprotocol/sdk/server/auth/provider.js\";\nimport { createOAuthMetadata } from \"@modelcontextprotocol/sdk/server/auth/router.js\";\nimport {\n\ttype OAuthClientInformationFull,\n\ttype OAuthClientMetadata,\n\tOAuthClientMetadataSchema,\n\ttype OAuthErrorResponse,\n\ttype OAuthMetadata,\n\ttype OAuthProtectedResourceMetadata,\n\tOAuthProtectedResourceMetadataSchema,\n\ttype OAuthTokens,\n\tOAuthTokensSchema,\n} from \"@modelcontextprotocol/sdk/shared/auth.js\";\n\nexport const MCP_OAUTH_PUBLIC_URL_ENV = \"CODEMEM_MCP_HTTP_PUBLIC_URL\";\nexport const MCP_OAUTH_RESOURCE_NAME = \"codemem MCP\";\nexport const MCP_OAUTH_SCOPES_SUPPORTED = [\"memory:read\", \"memory:write\"];\nexport const MCP_OAUTH_SERVICE_DOCUMENTATION_URL = \"https://github.com/kunickiaj/codemem#readme\";\n\nconst CLAUDE_HOSTED_CALLBACK = \"https://claude.ai/api/mcp/auth_callback\";\nconst CHATGPT_LEGACY_HOSTED_CALLBACK = \"https://chatgpt.com/connector_platform_oauth_redirect\";\nconst LOCAL_CALLBACK_HOSTS = new Set([\"localhost\", \"127.0.0.1\", \"::1\"]);\nconst SUPPORTED_GRANT_TYPES = new Set([\"authorization_code\", \"refresh_token\"]);\nconst SUPPORTED_RESPONSE_TYPES = new Set([\"code\"]);\nconst AUTHORIZATION_CODE_TTL_MS = 5 * 60 * 1000;\nconst ACCESS_TOKEN_TTL_SECONDS = 60 * 60;\nconst REFRESH_TOKEN_TTL_SECONDS = 30 * 24 * 60 * 60;\nconst MAX_AUTHORIZATION_CODES = 100;\nconst MAX_ACCESS_TOKENS = 100;\nconst MAX_REFRESH_GRANTS = 100;\nconst ACCESS_TOKEN_BYTES = 32;\nconst ACCESS_TOKEN_BASE64URL_LENGTH = 43;\nconst ACCESS_TOKEN_BASE64URL = /^[A-Za-z0-9_-]{43}$/;\nconst PKCE_S256_CHALLENGE = /^[A-Za-z0-9_-]{43}$/;\nconst PKCE_VERIFIER = /^[A-Za-z0-9._~-]{43,128}$/;\nconst CHATGPT_CONNECTOR_ID = /^[A-Za-z0-9_-]{1,128}$/;\n\nexport interface McpOAuthMetadataOptions {\n\tmcpUrl: string;\n\tclientsStore: OAuthRegisteredClientsStore;\n}\n\nexport interface RegisteredMcpOAuthClient {\n\tstatus: 201;\n\tbody: OAuthClientInformationFull;\n}\n\nexport interface McpOAuthRegistrationError {\n\tstatus: 400;\n\tbody: { error: \"invalid_client_metadata\"; error_description: string };\n}\n\nexport interface AuthorizationCodeRecord {\n\tclientId: string;\n\tredirectUri: string;\n\tcodeChallenge: string;\n\tscopes: string[];\n\tresource?: string;\n\texpiresAt: number;\n\tused: boolean;\n}\n\nexport interface OAuthAuthorizationCodeStore {\n\tissueCode(record: Omit<AuthorizationCodeRecord, \"used\">, now?: number): string | undefined;\n\tpeekCode(code: string): AuthorizationCodeRecord | undefined;\n\tconsumeCode(code: string): AuthorizationCodeRecord | undefined;\n}\n\nexport interface AccessTokenRecord {\n\tclientId: string;\n\tgrantId?: string;\n\tscopes: string[];\n\tresource?: string;\n\ttokenHash: string;\n\tissuedAt: number;\n\texpiresAt: number;\n\tlastUsedAt: number | null;\n\trevokedAt: number | null;\n}\n\nexport type AccessTokenVerificationResult =\n\t| { ok: true; record: AccessTokenRecord }\n\t| { ok: false; reason: \"unknown_token\" | \"expired_token\" | \"revoked_token\" };\n\nexport interface OAuthAccessTokenStore {\n\tissueToken(\n\t\tclientId: string,\n\t\tnow?: number,\n\t\tresource?: string,\n\t\tgrantId?: string,\n\t\tscopes?: string[],\n\t): { token: string; expiresIn: number } | undefined;\n\tverifyToken(token: string, now?: number): AccessTokenVerificationResult;\n\trevokeToken(token: string, now?: number): boolean;\n\trevokeTokensForGrant?(grantId: string, now?: number): number;\n}\n\nexport interface RefreshTokenGrantRecord {\n\tgrantId: string;\n\tclientId: string;\n\tscopes: string[];\n\tresource?: string;\n\tcurrentRefreshTokenHash: string;\n\tpreviousRefreshTokenHash: string | null;\n\tissuedAt: number;\n\texpiresAt: number;\n\trotatedAt: number | null;\n\trevokedAt: number | null;\n}\n\nexport type RefreshTokenRotationResult =\n\t| { ok: true; grant: RefreshTokenGrantRecord; refreshToken: string; expiresIn: number }\n\t| {\n\t\t\tok: false;\n\t\t\treason:\n\t\t\t\t| \"unknown_refresh_token\"\n\t\t\t\t| \"expired_refresh_token\"\n\t\t\t\t| \"revoked_refresh_token\"\n\t\t\t\t| \"client_mismatch\"\n\t\t\t\t| \"scope_mismatch\"\n\t\t\t\t| \"resource_mismatch\"\n\t\t\t\t| \"refresh_token_replay\";\n\t\t\tgrantId?: string;\n\t };\n\nexport interface OAuthRefreshTokenStore {\n\tissueGrant(\n\t\trecord: { clientId: string; scopes?: string[]; resource?: string },\n\t\tnow?: number,\n\t): { grant: RefreshTokenGrantRecord; refreshToken: string; expiresIn: number } | undefined;\n\trotateRefreshToken(\n\t\tclientId: string,\n\t\trefreshToken: string,\n\t\toptions?: { scopes?: string[]; resource?: string },\n\t\tnow?: number,\n\t): RefreshTokenRotationResult;\n\trevokeRefreshToken(token: string, now?: number): string | undefined;\n\trevokeGrant(grantId: string, now?: number): boolean;\n}\n\nexport interface McpOAuthRedirectResult {\n\tstatus: 302;\n\tlocation: string;\n}\n\nexport interface McpOAuthErrorResult {\n\tstatus: 400;\n\tbody: OAuthErrorResponse;\n}\n\nexport interface McpOAuthTokenResult {\n\tstatus: 200;\n\tbody: OAuthTokens;\n}\n\nexport interface PreparedMcpOAuthAuthorizationRequest {\n\tclientId: string;\n\tredirectUri: string;\n\tcodeChallenge: string;\n\tscopes: string[];\n\tresource: string | null;\n\tstate: string | null;\n}\n\nexport class InMemoryOAuthClientsStore implements OAuthRegisteredClientsStore {\n\treadonly #clients = new Map<string, OAuthClientInformationFull>();\n\n\tgetClient(clientId: string): OAuthClientInformationFull | undefined {\n\t\treturn this.#clients.get(clientId);\n\t}\n\n\tregisterClient(\n\t\tclient: Omit<OAuthClientInformationFull, \"client_id\" | \"client_id_issued_at\">,\n\t): OAuthClientInformationFull {\n\t\tconst redirectError = validateRedirectUris(client.redirect_uris);\n\t\tif (redirectError) throw new InvalidClientMetadataError(redirectError);\n\t\tif (client.client_secret || client.token_endpoint_auth_method !== \"none\") {\n\t\t\tthrow new InvalidClientMetadataError(\n\t\t\t\t\"Only public clients with token_endpoint_auth_method=none are supported\",\n\t\t\t);\n\t\t}\n\t\tif (client.grant_types && !isSupportedList(client.grant_types, SUPPORTED_GRANT_TYPES)) {\n\t\t\tthrow new InvalidClientMetadataError(\n\t\t\t\t\"Only authorization_code and refresh_token grant_types are supported\",\n\t\t\t);\n\t\t}\n\t\tif (\n\t\t\tclient.response_types &&\n\t\t\t!isSupportedList(client.response_types, SUPPORTED_RESPONSE_TYPES)\n\t\t) {\n\t\t\tthrow new InvalidClientMetadataError(\"Only code response_type is supported\");\n\t\t}\n\t\tif (this.#clients.size >= 100) {\n\t\t\tconst oldestClientId = this.#clients.keys().next().value;\n\t\t\tif (oldestClientId) this.#clients.delete(oldestClientId);\n\t\t}\n\t\tconst registered = {\n\t\t\t...client,\n\t\t\ttoken_endpoint_auth_method: \"none\" as const,\n\t\t\tgrant_types: client.grant_types ?? [\"authorization_code\", \"refresh_token\"],\n\t\t\tresponse_types: client.response_types ?? [\"code\"],\n\t\t\tclient_id: randomUUID(),\n\t\t\tclient_id_issued_at: Math.floor(Date.now() / 1000),\n\t\t};\n\t\tthis.#clients.set(registered.client_id, registered);\n\t\treturn registered;\n\t}\n}\n\nexport class InMemoryOAuthAuthorizationCodeStore implements OAuthAuthorizationCodeStore {\n\treadonly #codes = new Map<string, AuthorizationCodeRecord>();\n\n\tissueCode(record: Omit<AuthorizationCodeRecord, \"used\">, now = Date.now()): string | undefined {\n\t\tthis.#deleteExpiredCodes(now);\n\t\tif (this.#codes.size >= MAX_AUTHORIZATION_CODES) return undefined;\n\t\tconst code = randomUUID();\n\t\tthis.#codes.set(code, { ...record, used: false });\n\t\treturn code;\n\t}\n\n\tpeekCode(code: string): AuthorizationCodeRecord | undefined {\n\t\tconst record = this.#codes.get(code);\n\t\tif (!record || record.used) return undefined;\n\t\treturn record;\n\t}\n\n\tconsumeCode(code: string): AuthorizationCodeRecord | undefined {\n\t\tconst record = this.#codes.get(code);\n\t\tif (!record || record.used) return undefined;\n\t\trecord.used = true;\n\t\treturn record;\n\t}\n\n\t#deleteExpiredCodes(now: number): void {\n\t\tfor (const [code, record] of this.#codes) {\n\t\t\tif (record.expiresAt <= now) this.#codes.delete(code);\n\t\t}\n\t}\n}\n\nexport class InMemoryOAuthAccessTokenStore implements OAuthAccessTokenStore {\n\treadonly #tokensByHash = new Map<string, AccessTokenRecord>();\n\treadonly #tokenHashKey = randomBytes(32);\n\n\tissueToken(\n\t\tclientId: string,\n\t\tnow = Date.now(),\n\t\tresource?: string,\n\t\tgrantId?: string,\n\t\tscopes: string[] = [],\n\t): { token: string; expiresIn: number } | undefined {\n\t\tthis.#deleteInactiveTokens(now);\n\t\tif (this.#tokensByHash.size >= MAX_ACCESS_TOKENS) return undefined;\n\t\tconst tokenBytes = randomBytes(ACCESS_TOKEN_BYTES);\n\t\tconst tokenHash = signOAuthAccessTokenBytes(tokenBytes, this.#tokenHashKey);\n\t\tthis.#tokensByHash.set(tokenHash, {\n\t\t\tclientId,\n\t\t\tgrantId,\n\t\t\tscopes: [...scopes],\n\t\t\tresource,\n\t\t\ttokenHash,\n\t\t\tissuedAt: now,\n\t\t\texpiresAt: now + ACCESS_TOKEN_TTL_SECONDS * 1000,\n\t\t\tlastUsedAt: null,\n\t\t\trevokedAt: null,\n\t\t});\n\t\treturn {\n\t\t\ttoken: tokenBytes.toString(\"base64url\"),\n\t\t\texpiresIn: ACCESS_TOKEN_TTL_SECONDS,\n\t\t};\n\t}\n\n\tverifyToken(token: string, now = Date.now()): AccessTokenVerificationResult {\n\t\tconst tokenBytes = decodeOAuthAccessToken(token);\n\t\tif (!tokenBytes) return { ok: false, reason: \"unknown_token\" };\n\t\tconst tokenHash = signOAuthAccessTokenBytes(tokenBytes, this.#tokenHashKey);\n\t\tconst record = this.#tokensByHash.get(tokenHash);\n\t\tif (!record || !isSameTokenHash(record.tokenHash, tokenHash)) {\n\t\t\treturn { ok: false, reason: \"unknown_token\" };\n\t\t}\n\t\tif (record.revokedAt !== null) return { ok: false, reason: \"revoked_token\" };\n\t\tif (record.expiresAt <= now) return { ok: false, reason: \"expired_token\" };\n\t\trecord.lastUsedAt = now;\n\t\treturn { ok: true, record: { ...record } };\n\t}\n\n\trevokeToken(token: string, now = Date.now()): boolean {\n\t\tconst tokenBytes = decodeOAuthAccessToken(token);\n\t\tif (!tokenBytes) return false;\n\t\tconst tokenHash = signOAuthAccessTokenBytes(tokenBytes, this.#tokenHashKey);\n\t\tconst record = this.#tokensByHash.get(tokenHash);\n\t\tif (!record || !isSameTokenHash(record.tokenHash, tokenHash)) return false;\n\t\tif (record.revokedAt !== null) return true;\n\t\trecord.revokedAt = now;\n\t\treturn true;\n\t}\n\n\trevokeTokensForGrant(grantId: string, now = Date.now()): number {\n\t\tlet revoked = 0;\n\t\tfor (const record of this.#tokensByHash.values()) {\n\t\t\tif (record.grantId !== grantId || record.revokedAt !== null) continue;\n\t\t\trecord.revokedAt = now;\n\t\t\trevoked += 1;\n\t\t}\n\t\treturn revoked;\n\t}\n\n\t#deleteInactiveTokens(now: number): void {\n\t\tfor (const [tokenHash, record] of this.#tokensByHash) {\n\t\t\tif (record.expiresAt <= now || record.revokedAt !== null)\n\t\t\t\tthis.#tokensByHash.delete(tokenHash);\n\t\t}\n\t}\n}\n\nexport class InMemoryOAuthRefreshTokenStore implements OAuthRefreshTokenStore {\n\treadonly #grantsById = new Map<string, RefreshTokenGrantRecord>();\n\treadonly #grantIdsByRefreshHash = new Map<string, string>();\n\treadonly #refreshHashesByGrantId = new Map<string, Set<string>>();\n\treadonly #tokenHashKey = randomBytes(32);\n\n\tissueGrant(\n\t\trecord: { clientId: string; scopes?: string[]; resource?: string },\n\t\tnow = Date.now(),\n\t): { grant: RefreshTokenGrantRecord; refreshToken: string; expiresIn: number } | undefined {\n\t\tthis.#deleteInactiveGrants(now);\n\t\tif (this.#grantsById.size >= MAX_REFRESH_GRANTS) return undefined;\n\t\tconst refreshToken = randomToken();\n\t\tconst refreshTokenHash = hashSerializedOAuthToken(refreshToken, this.#tokenHashKey);\n\t\tif (!refreshTokenHash) return undefined;\n\t\tconst grant: RefreshTokenGrantRecord = {\n\t\t\tgrantId: randomUUID(),\n\t\t\tclientId: record.clientId,\n\t\t\tscopes: [...(record.scopes ?? [])],\n\t\t\tresource: record.resource,\n\t\t\tcurrentRefreshTokenHash: refreshTokenHash,\n\t\t\tpreviousRefreshTokenHash: null,\n\t\t\tissuedAt: now,\n\t\t\texpiresAt: now + REFRESH_TOKEN_TTL_SECONDS * 1000,\n\t\t\trotatedAt: null,\n\t\t\trevokedAt: null,\n\t\t};\n\t\tthis.#grantsById.set(grant.grantId, grant);\n\t\tthis.#grantIdsByRefreshHash.set(refreshTokenHash, grant.grantId);\n\t\tthis.#refreshHashesByGrantId.set(grant.grantId, new Set([refreshTokenHash]));\n\t\treturn {\n\t\t\tgrant: { ...grant, scopes: [...grant.scopes] },\n\t\t\trefreshToken,\n\t\t\texpiresIn: REFRESH_TOKEN_TTL_SECONDS,\n\t\t};\n\t}\n\n\trotateRefreshToken(\n\t\tclientId: string,\n\t\trefreshToken: string,\n\t\toptions: { scopes?: string[]; resource?: string } = {},\n\t\tnow = Date.now(),\n\t): RefreshTokenRotationResult {\n\t\tconst tokenHash = hashSerializedOAuthToken(refreshToken, this.#tokenHashKey);\n\t\tif (!tokenHash) return { ok: false, reason: \"unknown_refresh_token\" };\n\t\tconst grantId = this.#grantIdsByRefreshHash.get(tokenHash);\n\t\tif (!grantId) return { ok: false, reason: \"unknown_refresh_token\" };\n\t\tconst grant = this.#grantsById.get(grantId);\n\t\tif (!grant) return { ok: false, reason: \"unknown_refresh_token\" };\n\t\tif (grant.revokedAt !== null) return { ok: false, reason: \"revoked_refresh_token\", grantId };\n\t\tif (grant.expiresAt <= now) {\n\t\t\tthis.revokeGrant(grantId, now);\n\t\t\treturn { ok: false, reason: \"expired_refresh_token\", grantId };\n\t\t}\n\t\tif (grant.clientId !== clientId) return { ok: false, reason: \"client_mismatch\", grantId };\n\t\tif (!isScopeSubset(options.scopes ?? grant.scopes, grant.scopes)) {\n\t\t\treturn { ok: false, reason: \"scope_mismatch\", grantId };\n\t\t}\n\t\tif ((grant.resource ?? null) !== (options.resource ?? grant.resource ?? null)) {\n\t\t\treturn { ok: false, reason: \"resource_mismatch\", grantId };\n\t\t}\n\n\t\tconst matchesCurrent = isSameTokenHash(grant.currentRefreshTokenHash, tokenHash);\n\t\tconst matchesPrevious =\n\t\t\tgrant.previousRefreshTokenHash !== null &&\n\t\t\tisSameTokenHash(grant.previousRefreshTokenHash, tokenHash);\n\t\tif (!matchesCurrent && !matchesPrevious) {\n\t\t\tthis.revokeGrant(grantId, now);\n\t\t\treturn { ok: false, reason: \"refresh_token_replay\", grantId };\n\t\t}\n\n\t\tconst nextRefreshToken = randomToken();\n\t\tconst nextRefreshTokenHash = hashSerializedOAuthToken(nextRefreshToken, this.#tokenHashKey);\n\t\tif (!nextRefreshTokenHash) return { ok: false, reason: \"unknown_refresh_token\" };\n\t\tgrant.scopes = [...(options.scopes ?? grant.scopes)];\n\t\tgrant.previousRefreshTokenHash = matchesCurrent ? grant.currentRefreshTokenHash : null;\n\t\tgrant.currentRefreshTokenHash = nextRefreshTokenHash;\n\t\tgrant.rotatedAt = now;\n\t\tthis.#grantIdsByRefreshHash.set(nextRefreshTokenHash, grantId);\n\t\tthis.#refreshHashesByGrantId.get(grantId)?.add(nextRefreshTokenHash);\n\t\treturn {\n\t\t\tok: true,\n\t\t\tgrant: { ...grant, scopes: [...grant.scopes] },\n\t\t\trefreshToken: nextRefreshToken,\n\t\t\texpiresIn: Math.max(0, Math.floor((grant.expiresAt - now) / 1000)),\n\t\t};\n\t}\n\n\trevokeRefreshToken(token: string, now = Date.now()): string | undefined {\n\t\tconst tokenHash = hashSerializedOAuthToken(token, this.#tokenHashKey);\n\t\tif (!tokenHash) return undefined;\n\t\tconst grantId = this.#grantIdsByRefreshHash.get(tokenHash);\n\t\tif (!grantId) return undefined;\n\t\tthis.revokeGrant(grantId, now);\n\t\treturn grantId;\n\t}\n\n\trevokeGrant(grantId: string, now = Date.now()): boolean {\n\t\tconst grant = this.#grantsById.get(grantId);\n\t\tif (!grant) return false;\n\t\tif (grant.revokedAt !== null) return true;\n\t\tgrant.revokedAt = now;\n\t\tthis.#deleteGrantRefreshHashIndexEntries(grant);\n\t\treturn true;\n\t}\n\n\t#deleteInactiveGrants(now: number): void {\n\t\tfor (const [grantId, grant] of this.#grantsById) {\n\t\t\tif (grant.expiresAt > now && grant.revokedAt === null) continue;\n\t\t\tthis.#grantsById.delete(grantId);\n\t\t\tthis.#deleteGrantRefreshHashIndexEntries(grant);\n\t\t}\n\t}\n\n\t#deleteGrantRefreshHashIndexEntries(grant: RefreshTokenGrantRecord): void {\n\t\tconst refreshHashes = this.#refreshHashesByGrantId.get(grant.grantId);\n\t\tif (refreshHashes) {\n\t\t\tfor (const refreshHash of refreshHashes) this.#grantIdsByRefreshHash.delete(refreshHash);\n\t\t\tthis.#refreshHashesByGrantId.delete(grant.grantId);\n\t\t\treturn;\n\t\t}\n\t\tthis.#grantIdsByRefreshHash.delete(grant.currentRefreshTokenHash);\n\t\tif (grant.previousRefreshTokenHash)\n\t\t\tthis.#grantIdsByRefreshHash.delete(grant.previousRefreshTokenHash);\n\t}\n}\n\ninterface OAuthStateFileData {\n\tversion: 1;\n\tclients: OAuthClientInformationFull[];\n\taccessTokens: AccessTokenRecord[];\n\trefreshGrants: RefreshTokenGrantRecord[];\n\trefreshHashesByGrantId: Record<string, string[]>;\n}\n\n/**\n * JSON-backed OAuth state for remote MCP clients.\n *\n * Claude keeps its dynamically-registered `client_id` and refresh token across\n * connector reconnects. If codemem only stores that state in memory, a package\n * upgrade or MCP process restart makes Claude's next refresh look like an\n * unknown client. This store persists client registrations, access tokens, and\n * refresh-token grants so routine restarts do not force users through OAuth\n * again.\n */\nexport class JsonFileOAuthStateStore\n\timplements\n\t\tOAuthRegisteredClientsStore,\n\t\tOAuthAuthorizationCodeStore,\n\t\tOAuthAccessTokenStore,\n\t\tOAuthRefreshTokenStore\n{\n\treadonly #path: string;\n\treadonly #codes = new Map<string, AuthorizationCodeRecord>();\n\t#clients = new Map<string, OAuthClientInformationFull>();\n\t#tokensByHash = new Map<string, AccessTokenRecord>();\n\t#grantsById = new Map<string, RefreshTokenGrantRecord>();\n\t#grantIdsByRefreshHash = new Map<string, string>();\n\t#refreshHashesByGrantId = new Map<string, Set<string>>();\n\n\tconstructor(path = getDefaultMcpOAuthStatePath()) {\n\t\tthis.#path = path;\n\t\tthis.#load();\n\t}\n\n\tgetClient(clientId: string): OAuthClientInformationFull | undefined {\n\t\treturn this.#clients.get(clientId);\n\t}\n\n\tregisterClient(\n\t\tclient: Omit<OAuthClientInformationFull, \"client_id\" | \"client_id_issued_at\">,\n\t): OAuthClientInformationFull {\n\t\tconst redirectError = validateRedirectUris(client.redirect_uris);\n\t\tif (redirectError) throw new InvalidClientMetadataError(redirectError);\n\t\tif (client.client_secret || client.token_endpoint_auth_method !== \"none\") {\n\t\t\tthrow new InvalidClientMetadataError(\n\t\t\t\t\"Only public clients with token_endpoint_auth_method=none are supported\",\n\t\t\t);\n\t\t}\n\t\tif (client.grant_types && !isSupportedList(client.grant_types, SUPPORTED_GRANT_TYPES)) {\n\t\t\tthrow new InvalidClientMetadataError(\n\t\t\t\t\"Only authorization_code and refresh_token grant_types are supported\",\n\t\t\t);\n\t\t}\n\t\tif (\n\t\t\tclient.response_types &&\n\t\t\t!isSupportedList(client.response_types, SUPPORTED_RESPONSE_TYPES)\n\t\t) {\n\t\t\tthrow new InvalidClientMetadataError(\"Only code response_type is supported\");\n\t\t}\n\t\tthis.#deleteInactive(Date.now());\n\t\tif (this.#clients.size >= 100) {\n\t\t\tconst oldestClientId = this.#clients.keys().next().value;\n\t\t\tif (oldestClientId) this.#clients.delete(oldestClientId);\n\t\t}\n\t\tconst registered = {\n\t\t\t...client,\n\t\t\ttoken_endpoint_auth_method: \"none\" as const,\n\t\t\tgrant_types: client.grant_types ?? [\"authorization_code\", \"refresh_token\"],\n\t\t\tresponse_types: client.response_types ?? [\"code\"],\n\t\t\tclient_id: randomUUID(),\n\t\t\tclient_id_issued_at: Math.floor(Date.now() / 1000),\n\t\t};\n\t\tthis.#clients.set(registered.client_id, registered);\n\t\tthis.#save();\n\t\treturn registered;\n\t}\n\n\tissueCode(record: Omit<AuthorizationCodeRecord, \"used\">, now = Date.now()): string | undefined {\n\t\tthis.#deleteExpiredCodes(now);\n\t\tif (this.#codes.size >= MAX_AUTHORIZATION_CODES) return undefined;\n\t\tconst code = randomUUID();\n\t\tthis.#codes.set(code, { ...record, used: false });\n\t\treturn code;\n\t}\n\n\tpeekCode(code: string): AuthorizationCodeRecord | undefined {\n\t\tconst record = this.#codes.get(code);\n\t\tif (!record || record.used) return undefined;\n\t\treturn record;\n\t}\n\n\tconsumeCode(code: string): AuthorizationCodeRecord | undefined {\n\t\tconst record = this.#codes.get(code);\n\t\tif (!record || record.used) return undefined;\n\t\trecord.used = true;\n\t\treturn record;\n\t}\n\n\tissueToken(\n\t\tclientId: string,\n\t\tnow = Date.now(),\n\t\tresource?: string,\n\t\tgrantId?: string,\n\t\tscopes: string[] = [],\n\t): { token: string; expiresIn: number } | undefined {\n\t\tthis.#deleteInactive(now);\n\t\tif (this.#tokensByHash.size >= MAX_ACCESS_TOKENS) return undefined;\n\t\tconst token = randomToken();\n\t\tconst tokenHash = hashOAuthTokenForStateFile(token);\n\t\tif (!tokenHash) return undefined;\n\t\tthis.#tokensByHash.set(tokenHash, {\n\t\t\tclientId,\n\t\t\tgrantId,\n\t\t\tscopes: [...scopes],\n\t\t\tresource,\n\t\t\ttokenHash,\n\t\t\tissuedAt: now,\n\t\t\texpiresAt: now + ACCESS_TOKEN_TTL_SECONDS * 1000,\n\t\t\tlastUsedAt: null,\n\t\t\trevokedAt: null,\n\t\t});\n\t\tthis.#save();\n\t\treturn { token, expiresIn: ACCESS_TOKEN_TTL_SECONDS };\n\t}\n\n\tverifyToken(token: string, now = Date.now()): AccessTokenVerificationResult {\n\t\tconst tokenHash = hashOAuthTokenForStateFile(token);\n\t\tif (!tokenHash) return { ok: false, reason: \"unknown_token\" };\n\t\tconst record = this.#tokensByHash.get(tokenHash);\n\t\tif (!record || !isSameTokenHash(record.tokenHash, tokenHash)) {\n\t\t\treturn { ok: false, reason: \"unknown_token\" };\n\t\t}\n\t\tif (record.revokedAt !== null) return { ok: false, reason: \"revoked_token\" };\n\t\tif (record.expiresAt <= now) return { ok: false, reason: \"expired_token\" };\n\t\trecord.lastUsedAt = now;\n\t\treturn { ok: true, record: { ...record, scopes: [...record.scopes] } };\n\t}\n\n\trevokeToken(token: string, now = Date.now()): boolean {\n\t\tconst tokenHash = hashOAuthTokenForStateFile(token);\n\t\tif (!tokenHash) return false;\n\t\tconst record = this.#tokensByHash.get(tokenHash);\n\t\tif (!record || !isSameTokenHash(record.tokenHash, tokenHash)) return false;\n\t\tif (record.revokedAt !== null) return true;\n\t\trecord.revokedAt = now;\n\t\tthis.#save();\n\t\treturn true;\n\t}\n\n\trevokeTokensForGrant(grantId: string, now = Date.now()): number {\n\t\tlet revoked = 0;\n\t\tfor (const record of this.#tokensByHash.values()) {\n\t\t\tif (record.grantId !== grantId || record.revokedAt !== null) continue;\n\t\t\trecord.revokedAt = now;\n\t\t\trevoked += 1;\n\t\t}\n\t\tif (revoked > 0) this.#save();\n\t\treturn revoked;\n\t}\n\n\tissueGrant(\n\t\trecord: { clientId: string; scopes?: string[]; resource?: string },\n\t\tnow = Date.now(),\n\t): { grant: RefreshTokenGrantRecord; refreshToken: string; expiresIn: number } | undefined {\n\t\tthis.#deleteInactive(now);\n\t\tif (this.#grantsById.size >= MAX_REFRESH_GRANTS) return undefined;\n\t\tconst refreshToken = randomToken();\n\t\tconst refreshTokenHash = hashOAuthTokenForStateFile(refreshToken);\n\t\tif (!refreshTokenHash) return undefined;\n\t\tconst grant: RefreshTokenGrantRecord = {\n\t\t\tgrantId: randomUUID(),\n\t\t\tclientId: record.clientId,\n\t\t\tscopes: [...(record.scopes ?? [])],\n\t\t\tresource: record.resource,\n\t\t\tcurrentRefreshTokenHash: refreshTokenHash,\n\t\t\tpreviousRefreshTokenHash: null,\n\t\t\tissuedAt: now,\n\t\t\texpiresAt: now + REFRESH_TOKEN_TTL_SECONDS * 1000,\n\t\t\trotatedAt: null,\n\t\t\trevokedAt: null,\n\t\t};\n\t\tthis.#grantsById.set(grant.grantId, grant);\n\t\tthis.#grantIdsByRefreshHash.set(refreshTokenHash, grant.grantId);\n\t\tthis.#refreshHashesByGrantId.set(grant.grantId, new Set([refreshTokenHash]));\n\t\tthis.#save();\n\t\treturn {\n\t\t\tgrant: { ...grant, scopes: [...grant.scopes] },\n\t\t\trefreshToken,\n\t\t\texpiresIn: REFRESH_TOKEN_TTL_SECONDS,\n\t\t};\n\t}\n\n\trotateRefreshToken(\n\t\tclientId: string,\n\t\trefreshToken: string,\n\t\toptions: { scopes?: string[]; resource?: string } = {},\n\t\tnow = Date.now(),\n\t): RefreshTokenRotationResult {\n\t\tconst tokenHash = hashOAuthTokenForStateFile(refreshToken);\n\t\tif (!tokenHash) return { ok: false, reason: \"unknown_refresh_token\" };\n\t\tconst grantId = this.#grantIdsByRefreshHash.get(tokenHash);\n\t\tif (!grantId) return { ok: false, reason: \"unknown_refresh_token\" };\n\t\tconst grant = this.#grantsById.get(grantId);\n\t\tif (!grant) return { ok: false, reason: \"unknown_refresh_token\" };\n\t\tif (grant.revokedAt !== null) return { ok: false, reason: \"revoked_refresh_token\", grantId };\n\t\tif (grant.expiresAt <= now) {\n\t\t\tthis.revokeGrant(grantId, now);\n\t\t\treturn { ok: false, reason: \"expired_refresh_token\", grantId };\n\t\t}\n\t\tif (grant.clientId !== clientId) return { ok: false, reason: \"client_mismatch\", grantId };\n\t\tif (!isScopeSubset(options.scopes ?? grant.scopes, grant.scopes)) {\n\t\t\treturn { ok: false, reason: \"scope_mismatch\", grantId };\n\t\t}\n\t\tif ((grant.resource ?? null) !== (options.resource ?? grant.resource ?? null)) {\n\t\t\treturn { ok: false, reason: \"resource_mismatch\", grantId };\n\t\t}\n\n\t\tconst matchesCurrent = isSameTokenHash(grant.currentRefreshTokenHash, tokenHash);\n\t\tconst matchesPrevious =\n\t\t\tgrant.previousRefreshTokenHash !== null &&\n\t\t\tisSameTokenHash(grant.previousRefreshTokenHash, tokenHash);\n\t\tif (!matchesCurrent && !matchesPrevious) {\n\t\t\tthis.revokeGrant(grantId, now);\n\t\t\treturn { ok: false, reason: \"refresh_token_replay\", grantId };\n\t\t}\n\n\t\tconst nextRefreshToken = randomToken();\n\t\tconst nextRefreshTokenHash = hashOAuthTokenForStateFile(nextRefreshToken);\n\t\tif (!nextRefreshTokenHash) return { ok: false, reason: \"unknown_refresh_token\" };\n\t\tgrant.scopes = [...(options.scopes ?? grant.scopes)];\n\t\tgrant.previousRefreshTokenHash = matchesCurrent ? grant.currentRefreshTokenHash : null;\n\t\tgrant.currentRefreshTokenHash = nextRefreshTokenHash;\n\t\tgrant.rotatedAt = now;\n\t\tthis.#grantIdsByRefreshHash.set(nextRefreshTokenHash, grantId);\n\t\tthis.#refreshHashesByGrantId.get(grantId)?.add(nextRefreshTokenHash);\n\t\tthis.#save();\n\t\treturn {\n\t\t\tok: true,\n\t\t\tgrant: { ...grant, scopes: [...grant.scopes] },\n\t\t\trefreshToken: nextRefreshToken,\n\t\t\texpiresIn: Math.max(0, Math.floor((grant.expiresAt - now) / 1000)),\n\t\t};\n\t}\n\n\trevokeRefreshToken(token: string, now = Date.now()): string | undefined {\n\t\tconst tokenHash = hashOAuthTokenForStateFile(token);\n\t\tif (!tokenHash) return undefined;\n\t\tconst grantId = this.#grantIdsByRefreshHash.get(tokenHash);\n\t\tif (!grantId) return undefined;\n\t\tthis.revokeGrant(grantId, now);\n\t\treturn grantId;\n\t}\n\n\trevokeGrant(grantId: string, now = Date.now()): boolean {\n\t\tconst grant = this.#grantsById.get(grantId);\n\t\tif (!grant) return false;\n\t\tif (grant.revokedAt !== null) return true;\n\t\tgrant.revokedAt = now;\n\t\tthis.#deleteGrantRefreshHashIndexEntries(grant);\n\t\tthis.#save();\n\t\treturn true;\n\t}\n\n\t#load(): void {\n\t\tif (!existsSync(this.#path)) return;\n\t\tlet parsed: OAuthStateFileData;\n\t\ttry {\n\t\t\tparsed = JSON.parse(readFileSync(this.#path, \"utf8\")) as OAuthStateFileData;\n\t\t} catch {\n\t\t\treturn;\n\t\t}\n\t\tif (parsed.version !== 1) return;\n\t\tthis.#clients = new Map(parsed.clients.map((client) => [client.client_id, client]));\n\t\tthis.#tokensByHash = new Map(parsed.accessTokens.map((record) => [record.tokenHash, record]));\n\t\tthis.#grantsById = new Map(parsed.refreshGrants.map((grant) => [grant.grantId, grant]));\n\t\tthis.#grantIdsByRefreshHash = new Map();\n\t\tthis.#refreshHashesByGrantId = new Map();\n\t\tfor (const grant of this.#grantsById.values()) {\n\t\t\tconst hashes = new Set(parsed.refreshHashesByGrantId[grant.grantId] ?? []);\n\t\t\thashes.add(grant.currentRefreshTokenHash);\n\t\t\tif (grant.previousRefreshTokenHash) hashes.add(grant.previousRefreshTokenHash);\n\t\t\tthis.#refreshHashesByGrantId.set(grant.grantId, hashes);\n\t\t\tfor (const hash of hashes) this.#grantIdsByRefreshHash.set(hash, grant.grantId);\n\t\t}\n\t\tthis.#deleteInactive(Date.now());\n\t}\n\n\t#save(): void {\n\t\tmkdirSync(dirname(this.#path), { recursive: true, mode: 0o700 });\n\t\tconst data: OAuthStateFileData = {\n\t\t\tversion: 1,\n\t\t\tclients: [...this.#clients.values()],\n\t\t\taccessTokens: [...this.#tokensByHash.values()],\n\t\t\trefreshGrants: [...this.#grantsById.values()],\n\t\t\trefreshHashesByGrantId: Object.fromEntries(\n\t\t\t\t[...this.#refreshHashesByGrantId.entries()].map(([grantId, hashes]) => [\n\t\t\t\t\tgrantId,\n\t\t\t\t\t[...hashes],\n\t\t\t\t]),\n\t\t\t),\n\t\t};\n\t\tconst tmpPath = `${this.#path}.${process.pid}.${Date.now()}.tmp`;\n\t\twriteFileSync(tmpPath, `${JSON.stringify(data, null, 2)}\\n`, { mode: 0o600 });\n\t\trenameSync(tmpPath, this.#path);\n\t\tvoid chmod(this.#path, 0o600).catch(() => undefined);\n\t}\n\n\t#deleteExpiredCodes(now: number): void {\n\t\tfor (const [code, record] of this.#codes) {\n\t\t\tif (record.expiresAt <= now) this.#codes.delete(code);\n\t\t}\n\t}\n\n\t#deleteInactive(now: number): void {\n\t\tlet changed = false;\n\t\tfor (const [tokenHash, record] of this.#tokensByHash) {\n\t\t\tif (record.expiresAt > now && record.revokedAt === null) continue;\n\t\t\tthis.#tokensByHash.delete(tokenHash);\n\t\t\tchanged = true;\n\t\t}\n\t\tfor (const [grantId, grant] of this.#grantsById) {\n\t\t\tif (grant.expiresAt > now && grant.revokedAt === null) continue;\n\t\t\tthis.#grantsById.delete(grantId);\n\t\t\tthis.#deleteGrantRefreshHashIndexEntries(grant);\n\t\t\tchanged = true;\n\t\t}\n\t\tif (changed) this.#save();\n\t}\n\n\t#deleteGrantRefreshHashIndexEntries(grant: RefreshTokenGrantRecord): void {\n\t\tconst refreshHashes = this.#refreshHashesByGrantId.get(grant.grantId);\n\t\tif (refreshHashes) {\n\t\t\tfor (const refreshHash of refreshHashes) this.#grantIdsByRefreshHash.delete(refreshHash);\n\t\t\tthis.#refreshHashesByGrantId.delete(grant.grantId);\n\t\t\treturn;\n\t\t}\n\t\tthis.#grantIdsByRefreshHash.delete(grant.currentRefreshTokenHash);\n\t\tif (grant.previousRefreshTokenHash)\n\t\t\tthis.#grantIdsByRefreshHash.delete(grant.previousRefreshTokenHash);\n\t}\n}\n\nexport function createInMemoryOAuthClientsStore(): OAuthRegisteredClientsStore {\n\treturn new InMemoryOAuthClientsStore();\n}\n\nexport function createInMemoryOAuthAuthorizationCodeStore(): OAuthAuthorizationCodeStore {\n\treturn new InMemoryOAuthAuthorizationCodeStore();\n}\n\nexport function createInMemoryOAuthAccessTokenStore(): OAuthAccessTokenStore {\n\treturn new InMemoryOAuthAccessTokenStore();\n}\n\nexport function createInMemoryOAuthRefreshTokenStore(): OAuthRefreshTokenStore {\n\treturn new InMemoryOAuthRefreshTokenStore();\n}\n\nexport function createJsonFileOAuthStateStore(path?: string): JsonFileOAuthStateStore {\n\treturn new JsonFileOAuthStateStore(path);\n}\n\nexport function getDefaultMcpOAuthStatePath(): string {\n\treturn join(process.env.HOME?.trim() || homedir(), \".codemem\", \"mcp-oauth-state.json\");\n}\n\nexport function createMcpOAuthMetadata(options: McpOAuthMetadataOptions): OAuthMetadata {\n\tconst mcpUrl = normalizeMcpPublicUrl(options.mcpUrl);\n\tconst issuerUrl = getOriginUrl(mcpUrl);\n\tconst provider = createMetadataOnlyProvider(options.clientsStore);\n\treturn {\n\t\t...createOAuthMetadata({\n\t\t\tprovider,\n\t\t\tissuerUrl,\n\t\t\tbaseUrl: issuerUrl,\n\t\t}),\n\t\t// Phase 1 treats claude.ai and local callback clients as public clients.\n\t\t// Do not issue or advertise client secrets until we have a concrete need.\n\t\tgrant_types_supported: [\"authorization_code\", \"refresh_token\"],\n\t\ttoken_endpoint_auth_methods_supported: [\"none\"],\n\t\tscopes_supported: MCP_OAUTH_SCOPES_SUPPORTED,\n\t\tservice_documentation: MCP_OAUTH_SERVICE_DOCUMENTATION_URL,\n\t\trevocation_endpoint: new URL(\"/revoke\", issuerUrl).href,\n\t\trevocation_endpoint_auth_methods_supported: [\"none\"],\n\t\tclient_id_metadata_document_supported: false,\n\t};\n}\n\nexport function createMcpProtectedResourceMetadata(mcpUrl: string): OAuthProtectedResourceMetadata {\n\tconst normalizedMcpUrl = normalizeMcpPublicUrl(mcpUrl);\n\tconst metadata = {\n\t\tresource: normalizedMcpUrl.href,\n\t\tauthorization_servers: [getOriginUrl(normalizedMcpUrl).href],\n\t\tscopes_supported: MCP_OAUTH_SCOPES_SUPPORTED,\n\t\tbearer_methods_supported: [\"header\"],\n\t\tresource_name: MCP_OAUTH_RESOURCE_NAME,\n\t\tresource_documentation: MCP_OAUTH_SERVICE_DOCUMENTATION_URL,\n\t};\n\treturn OAuthProtectedResourceMetadataSchema.parse(metadata);\n}\n\nexport function registerMcpOAuthClient(\n\trequestBody: unknown,\n\tclientsStore: OAuthRegisteredClientsStore,\n): RegisteredMcpOAuthClient | McpOAuthRegistrationError {\n\tif (!clientsStore.registerClient) {\n\t\treturn invalidClientMetadata(\"Dynamic client registration is not enabled\");\n\t}\n\n\tconst parseResult = OAuthClientMetadataSchema.safeParse(requestBody);\n\tif (!parseResult.success) {\n\t\treturn invalidClientMetadata(parseResult.error.message);\n\t}\n\n\tconst clientMetadata = parseResult.data;\n\tconst redirectError = validateRedirectUris(clientMetadata.redirect_uris);\n\tif (redirectError) return invalidClientMetadata(redirectError);\n\n\tif (!isSupportedTokenEndpointAuthMethod(clientMetadata.token_endpoint_auth_method)) {\n\t\treturn invalidClientMetadata(\n\t\t\t\"Only public clients with token_endpoint_auth_method=none are supported\",\n\t\t);\n\t}\n\n\tif (\n\t\tclientMetadata.grant_types &&\n\t\t!isSupportedList(clientMetadata.grant_types, SUPPORTED_GRANT_TYPES)\n\t) {\n\t\treturn invalidClientMetadata(\n\t\t\t\"Only authorization_code and refresh_token grant_types are supported\",\n\t\t);\n\t}\n\n\tif (\n\t\tclientMetadata.response_types &&\n\t\t!isSupportedList(clientMetadata.response_types, SUPPORTED_RESPONSE_TYPES)\n\t) {\n\t\treturn invalidClientMetadata(\"Only code response_type is supported\");\n\t}\n\n\tconst registered = clientsStore.registerClient({\n\t\t...clientMetadata,\n\t\ttoken_endpoint_auth_method: \"none\",\n\t\tgrant_types: clientMetadata.grant_types ?? [\"authorization_code\", \"refresh_token\"],\n\t\tresponse_types: clientMetadata.response_types ?? [\"code\"],\n\t});\n\n\tif (registered instanceof Promise) {\n\t\tthrow new Error(\n\t\t\t\"Asynchronous OAuth client stores are not supported by this HTTP bootstrap yet\",\n\t\t);\n\t}\n\n\treturn { status: 201, body: registered };\n}\n\nexport function authorizeMcpOAuthClient(\n\tparams: URLSearchParams,\n\tclientsStore: OAuthRegisteredClientsStore,\n\tcodeStore: OAuthAuthorizationCodeStore,\n\tnow = Date.now(),\n): McpOAuthRedirectResult | McpOAuthErrorResult {\n\tconst prepared = prepareMcpOAuthAuthorizationRequest(params, clientsStore);\n\tif (\"status\" in prepared) return prepared;\n\n\tconst code = codeStore.issueCode(\n\t\t{\n\t\t\tclientId: prepared.clientId,\n\t\t\tredirectUri: prepared.redirectUri,\n\t\t\tcodeChallenge: prepared.codeChallenge,\n\t\t\tscopes: prepared.scopes,\n\t\t\t...(prepared.resource ? { resource: prepared.resource } : {}),\n\t\t\texpiresAt: now + AUTHORIZATION_CODE_TTL_MS,\n\t\t},\n\t\tnow,\n\t);\n\tif (!code)\n\t\treturn invalidOAuthRequest(\"temporarily_unavailable\", \"Too many active authorization codes\");\n\tconst redirect = new URL(prepared.redirectUri);\n\tredirect.searchParams.set(\"code\", code);\n\tif (prepared.state !== null) redirect.searchParams.set(\"state\", prepared.state);\n\treturn { status: 302, location: redirect.href };\n}\n\nexport function prepareMcpOAuthAuthorizationRequest(\n\tparams: URLSearchParams,\n\tclientsStore: OAuthRegisteredClientsStore,\n): PreparedMcpOAuthAuthorizationRequest | McpOAuthErrorResult {\n\tconst clientId = params.get(\"client_id\") ?? \"\";\n\tconst redirectUri = params.get(\"redirect_uri\") ?? \"\";\n\tconst responseType = params.get(\"response_type\") ?? \"\";\n\tconst codeChallenge = params.get(\"code_challenge\") ?? \"\";\n\tconst codeChallengeMethod = params.get(\"code_challenge_method\") ?? \"\";\n\tconst resource = params.get(\"resource\");\n\tconst scopes = parseScopeList(params.get(\"scope\"));\n\tconst state = params.get(\"state\");\n\n\tif (responseType !== \"code\") return invalidOAuthRequest(\"unsupported_response_type\");\n\tif (codeChallengeMethod !== \"S256\") {\n\t\treturn invalidOAuthRequest(\"invalid_request\", \"PKCE code_challenge_method=S256 is required\");\n\t}\n\tif (!PKCE_S256_CHALLENGE.test(codeChallenge)) {\n\t\treturn invalidOAuthRequest(\"invalid_request\", \"Valid PKCE S256 code_challenge is required\");\n\t}\n\n\tconst client = getRegisteredClient(clientsStore, clientId);\n\tif (!client) return invalidOAuthRequest(\"invalid_client\", \"Unknown OAuth client_id\");\n\tif (!client.redirect_uris.includes(redirectUri)) {\n\t\treturn invalidOAuthRequest(\"invalid_request\", \"redirect_uri is not registered for this client\");\n\t}\n\n\treturn { clientId, redirectUri, codeChallenge, scopes, resource, state };\n}\n\nexport function exchangeMcpOAuthAuthorizationCode(\n\tparams: URLSearchParams,\n\tclientsStore: OAuthRegisteredClientsStore,\n\tcodeStore: OAuthAuthorizationCodeStore,\n\ttokenStore: OAuthAccessTokenStore,\n\tnow = Date.now(),\n): McpOAuthTokenResult | McpOAuthErrorResult {\n\tif ((params.get(\"grant_type\") ?? \"\") !== \"authorization_code\") {\n\t\treturn invalidOAuthRequest(\"unsupported_grant_type\", \"Only authorization_code is supported\");\n\t}\n\n\tconst clientId = params.get(\"client_id\") ?? \"\";\n\tconst code = params.get(\"code\") ?? \"\";\n\tconst redirectUri = params.get(\"redirect_uri\") ?? \"\";\n\tconst codeVerifier = params.get(\"code_verifier\") ?? \"\";\n\tconst resource = params.get(\"resource\");\n\tconst client = getRegisteredClient(clientsStore, clientId);\n\tif (!client) return invalidOAuthRequest(\"invalid_client\", \"Unknown OAuth client_id\");\n\tif (!PKCE_VERIFIER.test(codeVerifier)) {\n\t\treturn invalidOAuthRequest(\"invalid_grant\", \"Invalid PKCE code_verifier\");\n\t}\n\n\t// Peek the authorization code without consuming it so a transient token-\n\t// store overflow (`temporarily_unavailable`) leaves the code reusable; only\n\t// permanent grant failures (expiry, client/redirect mismatch, PKCE) consume\n\t// the code. The code is finally consumed atomically with token issuance.\n\tconst record = codeStore.peekCode(code);\n\tif (!record) return invalidOAuthRequest(\"invalid_grant\", \"Invalid or already used code\");\n\tif (record.expiresAt <= now) {\n\t\tcodeStore.consumeCode(code);\n\t\treturn invalidOAuthRequest(\"invalid_grant\", \"Expired code\");\n\t}\n\tif (record.clientId !== clientId || record.redirectUri !== redirectUri) {\n\t\tcodeStore.consumeCode(code);\n\t\treturn invalidOAuthRequest(\"invalid_grant\", \"Code does not match client or redirect_uri\");\n\t}\n\tif (pkceS256(codeVerifier) !== record.codeChallenge) {\n\t\tcodeStore.consumeCode(code);\n\t\treturn invalidOAuthRequest(\"invalid_grant\", \"PKCE verification failed\");\n\t}\n\tif ((record.resource ?? null) !== (resource || null)) {\n\t\tcodeStore.consumeCode(code);\n\t\treturn invalidOAuthRequest(\"invalid_grant\", \"Code does not match resource\");\n\t}\n\n\tconst issued = tokenStore.issueToken(clientId, now, record.resource, undefined, record.scopes);\n\tif (!issued) {\n\t\t// Token-store overload is transient: leave the auth code unused so the\n\t\t// client can retry token exchange without restarting the OAuth flow.\n\t\treturn invalidOAuthRequest(\"temporarily_unavailable\", \"Too many active access tokens\");\n\t}\n\n\tconst consumed = codeStore.consumeCode(code);\n\tif (!consumed) {\n\t\ttokenStore.revokeToken(issued.token, now);\n\t\t// Lost a race with another request that consumed the code in the gap\n\t\t// between peek and consume. Treat as invalid_grant rather than issuing\n\t\t// a duplicate usable token, since the code is no longer single-use atomic.\n\t\treturn invalidOAuthRequest(\"invalid_grant\", \"Authorization code already used\");\n\t}\n\n\tconst tokens = OAuthTokensSchema.parse({\n\t\taccess_token: issued.token,\n\t\ttoken_type: \"Bearer\",\n\t\texpires_in: issued.expiresIn,\n\t});\n\treturn { status: 200, body: tokens };\n}\n\nexport function revokeMcpOAuthAccessToken(\n\tparams: URLSearchParams,\n\ttokenStore: OAuthAccessTokenStore,\n): { status: 200; body: Record<string, never> } {\n\tconst token = params.get(\"token\") ?? \"\";\n\ttokenStore.revokeToken(token);\n\treturn { status: 200, body: {} };\n}\n\nexport function normalizeMcpPublicUrl(value: string): URL {\n\tlet url: URL;\n\ttry {\n\t\turl = new URL(value);\n\t} catch {\n\t\tthrow new Error(\"Invalid MCP HTTP public URL; expected an HTTPS /mcp URL\");\n\t}\n\tif (url.protocol !== \"https:\" && !isLoopbackUrl(url)) {\n\t\tthrow new Error(\"Invalid MCP HTTP public URL; use HTTPS for non-loopback URLs\");\n\t}\n\tif (url.username || url.password || url.search || url.hash) {\n\t\tthrow new Error(\n\t\t\t\"Invalid MCP HTTP public URL; credentials, query strings, and fragments are not allowed\",\n\t\t);\n\t}\n\tif (url.pathname === \"/\") url.pathname = \"/mcp\";\n\tif (url.pathname !== \"/mcp\") {\n\t\tthrow new Error(\"Invalid MCP HTTP public URL; expected /mcp path\");\n\t}\n\treturn url;\n}\n\nfunction getOriginUrl(url: URL): URL {\n\treturn new URL(url.origin);\n}\n\nfunction validateRedirectUris(redirectUris: OAuthClientMetadata[\"redirect_uris\"]): string | null {\n\tfor (const redirectUri of redirectUris) {\n\t\tconst url = new URL(redirectUri);\n\t\tif (url.username || url.password || url.hash) return \"Invalid redirect URI\";\n\t\tif (isSupportedHostedConnectorRedirectUrl(url)) continue;\n\t\tif (isLoopbackCallbackUrl(url)) continue;\n\t\treturn \"Unsupported redirect URI\";\n\t}\n\treturn null;\n}\n\nfunction isSupportedHostedConnectorRedirectUrl(url: URL): boolean {\n\tif (url.search !== \"\") return false;\n\tif (url.href === CLAUDE_HOSTED_CALLBACK) return true;\n\tif (url.href === CHATGPT_LEGACY_HOSTED_CALLBACK) return true;\n\treturn url.protocol === \"https:\" && url.hostname === \"chatgpt.com\" && isChatGptConnectorPath(url);\n}\n\nfunction isChatGptConnectorPath(url: URL): boolean {\n\tconst pathParts = url.pathname.split(\"/\").filter(Boolean);\n\treturn (\n\t\tpathParts.length === 3 &&\n\t\tpathParts[0] === \"connector\" &&\n\t\tpathParts[1] === \"oauth\" &&\n\t\tCHATGPT_CONNECTOR_ID.test(pathParts[2] ?? \"\")\n\t);\n}\n\nfunction isSupportedTokenEndpointAuthMethod(method: string | undefined): boolean {\n\treturn method === undefined || method === \"none\";\n}\n\nfunction isSupportedList(values: string[], supported: Set<string>): boolean {\n\treturn values.length > 0 && values.every((value) => supported.has(value));\n}\n\nfunction isLoopbackCallbackUrl(url: URL): boolean {\n\treturn (\n\t\turl.protocol === \"http:\" &&\n\t\tLOCAL_CALLBACK_HOSTS.has(normalizeHostname(url.hostname)) &&\n\t\t(url.pathname === \"/callback\" || url.pathname === \"/oauth/callback\") &&\n\t\turl.search === \"\"\n\t);\n}\n\nfunction isLoopbackUrl(url: URL): boolean {\n\tconst hostname = normalizeHostname(url.hostname);\n\treturn url.protocol === \"http:\" && LOCAL_CALLBACK_HOSTS.has(hostname);\n}\n\nfunction normalizeHostname(hostname: string): string {\n\treturn hostname.replace(/^\\[(.*)]$/, \"$1\").toLowerCase();\n}\n\nfunction parseScopeList(scope: string | null | undefined): string[] {\n\treturn (\n\t\tscope\n\t\t\t?.split(/\\s+/)\n\t\t\t.map((item) => item.trim())\n\t\t\t.filter(Boolean) ?? []\n\t);\n}\n\nfunction invalidClientMetadata(description: string): McpOAuthRegistrationError {\n\treturn {\n\t\tstatus: 400,\n\t\tbody: { error: \"invalid_client_metadata\", error_description: description },\n\t};\n}\n\nfunction invalidOAuthRequest(error: string, description?: string): McpOAuthErrorResult {\n\treturn {\n\t\tstatus: 400,\n\t\tbody: description ? { error, error_description: description } : { error },\n\t};\n}\n\nfunction getRegisteredClient(\n\tclientsStore: OAuthRegisteredClientsStore,\n\tclientId: string,\n): OAuthClientInformationFull | undefined {\n\tconst client = clientsStore.getClient(clientId);\n\tif (client instanceof Promise) {\n\t\tthrow new Error(\n\t\t\t\"Asynchronous OAuth client stores are not supported by this HTTP bootstrap yet\",\n\t\t);\n\t}\n\treturn client;\n}\n\nfunction pkceS256(codeVerifier: string): string {\n\treturn createHash(\"sha256\").update(codeVerifier).digest(\"base64url\");\n}\n\n// Decode an externally-supplied access-token string into the fixed-length\n// random Buffer it represents. Rejects anything that is not a base64url-encoded\n// ACCESS_TOKEN_BYTES-length value, so invalid input never reaches the HMAC\n// signer. Returns null on any decode/length mismatch.\nfunction decodeOAuthAccessToken(serialized: string): Buffer | null {\n\tif (typeof serialized !== \"string\") return null;\n\tif (serialized.length !== ACCESS_TOKEN_BASE64URL_LENGTH) return null;\n\tif (!ACCESS_TOKEN_BASE64URL.test(serialized)) return null;\n\tconst bytes = Buffer.from(serialized, \"base64url\");\n\tif (bytes.length !== ACCESS_TOKEN_BYTES) return null;\n\treturn bytes;\n}\n\nfunction randomToken(): string {\n\treturn randomBytes(ACCESS_TOKEN_BYTES).toString(\"base64url\");\n}\n\nfunction hashSerializedOAuthToken(serialized: string, key: Buffer): string | null {\n\tconst tokenBytes = decodeOAuthAccessToken(serialized);\n\tif (!tokenBytes) return null;\n\treturn signOAuthToken(tokenBytes, key);\n}\n\nfunction hashOAuthTokenForStateFile(serialized: string): string | null {\n\tconst tokenBytes = decodeOAuthAccessToken(serialized);\n\tif (!tokenBytes) return null;\n\treturn createHash(\"sha256\").update(tokenBytes).digest(\"base64url\");\n}\n\n// Compute the HMAC-SHA256 signature of the binary access-token material using\n// the per-store random key. This is an integrity signature over a random\n// 256-bit value, not password hashing; tokens are validated by re-signing the\n// presented bytes and comparing the digest to the stored signature.\nfunction signOAuthAccessTokenBytes(material: Buffer, key: Buffer): string {\n\treturn signOAuthToken(material, key);\n}\n\nfunction signOAuthToken(material: Buffer | string, key: Buffer): string {\n\treturn createHmac(\"sha256\", key).update(material).digest(\"base64url\");\n}\n\nfunction isSameTokenHash(left: string, right: string): boolean {\n\tconst leftBuffer = Buffer.from(left);\n\tconst rightBuffer = Buffer.from(right);\n\treturn leftBuffer.length === rightBuffer.length && timingSafeEqual(leftBuffer, rightBuffer);\n}\n\nfunction isScopeSubset(requested: string[], granted: string[]): boolean {\n\tconst grantedScopes = new Set(granted);\n\treturn requested.every((scope) => grantedScopes.has(scope));\n}\n\nfunction createMetadataOnlyProvider(\n\tclientsStore: OAuthRegisteredClientsStore,\n): OAuthServerProvider {\n\treturn {\n\t\tclientsStore,\n\t\tasync authorize() {\n\t\t\tthrow new Error(\"OAuth authorize is not implemented yet\");\n\t\t},\n\t\tasync challengeForAuthorizationCode() {\n\t\t\tthrow new Error(\"OAuth token exchange is not implemented yet\");\n\t\t},\n\t\tasync exchangeAuthorizationCode() {\n\t\t\tthrow new Error(\"OAuth token exchange is not implemented yet\");\n\t\t},\n\t\tasync exchangeRefreshToken() {\n\t\t\tthrow new Error(\"OAuth refresh is not implemented yet\");\n\t\t},\n\t\tasync verifyAccessToken() {\n\t\t\tthrow new Error(\"OAuth bearer verification is not implemented yet\");\n\t\t},\n\t};\n}\n","import { createPublicKey, randomUUID, verify } from \"node:crypto\";\nimport type { OAuthRegisteredClientsStore } from \"@modelcontextprotocol/sdk/server/auth/clients.js\";\nimport {\n\ttype McpOAuthErrorResult,\n\ttype McpOAuthRedirectResult,\n\tprepareMcpOAuthAuthorizationRequest,\n} from \"./oauth.js\";\n\nexport const MCP_OIDC_ISSUER_URL_ENV = \"CODEMEM_MCP_OIDC_ISSUER_URL\";\nexport const MCP_OIDC_CLIENT_ID_ENV = \"CODEMEM_MCP_OIDC_CLIENT_ID\";\nexport const MCP_OIDC_CLIENT_SECRET_ENV = \"CODEMEM_MCP_OIDC_CLIENT_SECRET\";\nexport const MCP_OAUTH_ALLOWED_SUBJECT_ENV = \"CODEMEM_MCP_OAUTH_ALLOWED_SUBJECT\";\nexport const MCP_OAUTH_ALLOWED_EMAIL_ENV = \"CODEMEM_MCP_OAUTH_ALLOWED_EMAIL\";\n\nconst PENDING_AUTH_TTL_MS = 5 * 60 * 1000;\nconst MAX_PENDING_AUTH = 100;\nconst ID_TOKEN_CLOCK_SKEW_MS = 5 * 60 * 1000;\n\ntype JsonWebKey = Record<string, unknown>;\n\nexport interface OidcConfig {\n\tissuerUrl: string;\n\tclientId: string;\n\tclientSecret: string;\n\tallowedSubject?: string;\n\tallowedEmail?: string;\n}\n\nexport interface PendingOidcAuthorization {\n\toauthParams: string;\n\tnonce: string;\n\texpiresAt: number;\n}\n\nexport interface OidcPendingAuthorizationStore {\n\tissue(record: Omit<PendingOidcAuthorization, \"expiresAt\">, now?: number): string | undefined;\n\tconsume(state: string): PendingOidcAuthorization | undefined;\n}\n\ninterface OidcDiscoveryMetadata {\n\tissuer: string;\n\tauthorization_endpoint: string;\n\ttoken_endpoint: string;\n\tjwks_uri: string;\n}\n\ninterface OidcTokensResponse {\n\tid_token?: string;\n\terror?: string;\n\terror_description?: string;\n}\n\ninterface JwtHeader {\n\talg?: string;\n\tkid?: string;\n}\n\ninterface JwtClaims {\n\tiss?: string;\n\taud?: string | string[];\n\tazp?: string;\n\texp?: number;\n\tiat?: number;\n\tnonce?: string;\n\tsub?: string;\n\temail?: string;\n\temail_verified?: boolean;\n}\n\ninterface JsonWebKeySet {\n\tkeys?: JsonWebKey[];\n}\n\nexport class InMemoryOidcPendingAuthorizationStore implements OidcPendingAuthorizationStore {\n\treadonly #records = new Map<string, PendingOidcAuthorization>();\n\n\tissue(record: Omit<PendingOidcAuthorization, \"expiresAt\">, now = Date.now()): string | undefined {\n\t\tthis.#deleteExpired(now);\n\t\tif (this.#records.size >= MAX_PENDING_AUTH) return undefined;\n\t\tconst state = randomUUID();\n\t\tthis.#records.set(state, { ...record, expiresAt: now + PENDING_AUTH_TTL_MS });\n\t\treturn state;\n\t}\n\n\tconsume(state: string): PendingOidcAuthorization | undefined {\n\t\tconst record = this.#records.get(state);\n\t\tthis.#records.delete(state);\n\t\treturn record;\n\t}\n\n\t#deleteExpired(now: number): void {\n\t\tfor (const [state, record] of this.#records) {\n\t\t\tif (record.expiresAt <= now) this.#records.delete(state);\n\t\t}\n\t}\n}\n\nexport function createInMemoryOidcPendingAuthorizationStore(): OidcPendingAuthorizationStore {\n\treturn new InMemoryOidcPendingAuthorizationStore();\n}\n\nexport function resolveOidcConfig(env: NodeJS.ProcessEnv = process.env): OidcConfig | undefined {\n\tconst issuerUrl = env[MCP_OIDC_ISSUER_URL_ENV]?.trim();\n\tconst clientId = env[MCP_OIDC_CLIENT_ID_ENV]?.trim();\n\tconst clientSecret = env[MCP_OIDC_CLIENT_SECRET_ENV]?.trim();\n\tconst allowedSubject = env[MCP_OAUTH_ALLOWED_SUBJECT_ENV]?.trim();\n\tconst allowedEmail = env[MCP_OAUTH_ALLOWED_EMAIL_ENV]?.trim().toLowerCase();\n\tif (!issuerUrl && !clientId && !clientSecret && !allowedSubject && !allowedEmail)\n\t\treturn undefined;\n\tif (!issuerUrl || !clientId || !clientSecret) {\n\t\tthrow new Error(\"Incomplete MCP OIDC configuration\");\n\t}\n\tvalidateOidcUrl(issuerUrl, \"issuer\", { allowLoopbackHttp: true });\n\tif (!allowedSubject && !allowedEmail) {\n\t\tthrow new Error(\n\t\t\t\"MCP OIDC requires CODEMEM_MCP_OAUTH_ALLOWED_SUBJECT or CODEMEM_MCP_OAUTH_ALLOWED_EMAIL\",\n\t\t);\n\t}\n\treturn { issuerUrl, clientId, clientSecret, allowedSubject, allowedEmail };\n}\n\nexport async function beginOidcAuthorization(\n\tparams: URLSearchParams,\n\tclientsStore: OAuthRegisteredClientsStore,\n\tpendingStore: OidcPendingAuthorizationStore,\n\tconfig: OidcConfig | undefined,\n\tpublicMcpUrl: string,\n\tnow = Date.now(),\n): Promise<McpOAuthRedirectResult | McpOAuthErrorResult> {\n\tif (!config) return invalidOAuthRequest(\"temporarily_unavailable\", \"OIDC is not configured\");\n\tconst prepared = prepareMcpOAuthAuthorizationRequest(params, clientsStore);\n\tif (\"status\" in prepared) return prepared;\n\n\tconst discovery = await fetchOidcDiscovery(config.issuerUrl);\n\tconst nonce = randomUUID();\n\tconst upstreamState = pendingStore.issue({ oauthParams: params.toString(), nonce }, now);\n\tif (!upstreamState)\n\t\treturn invalidOAuthRequest(\"temporarily_unavailable\", \"Too many pending OIDC authorizations\");\n\n\tconst redirectUri = getCallbackUrl(publicMcpUrl);\n\tconst upstream = new URL(discovery.authorization_endpoint);\n\tupstream.searchParams.set(\"response_type\", \"code\");\n\tupstream.searchParams.set(\"client_id\", config.clientId);\n\tupstream.searchParams.set(\"redirect_uri\", redirectUri);\n\tupstream.searchParams.set(\"scope\", \"openid email\");\n\tupstream.searchParams.set(\"state\", upstreamState);\n\tupstream.searchParams.set(\"nonce\", nonce);\n\treturn { status: 302, location: upstream.href };\n}\n\nexport async function completeOidcAuthorization(\n\tcallbackParams: URLSearchParams,\n\tpendingStore: OidcPendingAuthorizationStore,\n\tconfig: OidcConfig,\n\tpublicMcpUrl: string,\n\tnow = Date.now(),\n): Promise<{ oauthParams: URLSearchParams } | McpOAuthErrorResult> {\n\ttry {\n\t\tconst code = callbackParams.get(\"code\") ?? \"\";\n\t\tconst state = callbackParams.get(\"state\") ?? \"\";\n\t\tif (!state) return invalidOAuthRequest(\"invalid_request\", \"Missing OIDC state\");\n\t\tconst pending = pendingStore.consume(state);\n\t\tif (!pending || pending.expiresAt <= now)\n\t\t\treturn invalidOAuthRequest(\"invalid_request\", \"Expired or unknown OIDC state\");\n\t\tif (!code) return invalidOAuthRequest(\"invalid_request\", \"Missing OIDC code\");\n\n\t\tconst discovery = await fetchOidcDiscovery(config.issuerUrl);\n\t\tconst tokens = await exchangeOidcCode(\n\t\t\tdiscovery.token_endpoint,\n\t\t\tconfig,\n\t\t\tgetCallbackUrl(publicMcpUrl),\n\t\t\tcode,\n\t\t);\n\t\tif (!tokens.id_token)\n\t\t\treturn invalidOAuthRequest(\"invalid_request\", \"OIDC token exchange failed\");\n\t\tconst claims = await validateIdToken(\n\t\t\ttokens.id_token,\n\t\t\tdiscovery,\n\t\t\tconfig.clientId,\n\t\t\tpending.nonce,\n\t\t\tnow,\n\t\t);\n\t\tif (!isAllowedIdentity(claims, config))\n\t\t\treturn invalidOAuthRequest(\"access_denied\", \"OIDC identity is not allowed\");\n\n\t\treturn { oauthParams: new URLSearchParams(pending.oauthParams) };\n\t} catch {\n\t\treturn invalidOAuthRequest(\"access_denied\", \"OIDC identity verification failed\");\n\t}\n}\n\nfunction getCallbackUrl(publicMcpUrl: string): string {\n\tconst url = new URL(publicMcpUrl);\n\treturn new URL(\"/oauth/callback\", url.origin).href;\n}\n\nasync function fetchOidcDiscovery(issuerUrl: string): Promise<OidcDiscoveryMetadata> {\n\tconst issuer = new URL(issuerUrl);\n\tif (issuer.search || issuer.hash)\n\t\tthrow new Error(\"OIDC issuer must not include query or fragment\");\n\tif (issuer.username || issuer.password)\n\t\tthrow new Error(\"OIDC issuer must not include credentials\");\n\tconst discoveryUrl = new URL(\n\t\t`${issuer.pathname.replace(/\\/$/, \"\")}/.well-known/openid-configuration`,\n\t\tissuer.origin,\n\t);\n\tconst response = await fetch(discoveryUrl);\n\tif (!response.ok) throw new Error(\"OIDC discovery request failed\");\n\tconst metadata = (await response.json()) as Partial<OidcDiscoveryMetadata>;\n\tif (metadata.issuer !== issuer.href && metadata.issuer !== issuer.href.replace(/\\/$/, \"\")) {\n\t\tthrow new Error(\"OIDC discovery issuer mismatch\");\n\t}\n\tif (!metadata.authorization_endpoint || !metadata.token_endpoint || !metadata.jwks_uri) {\n\t\tthrow new Error(\"OIDC discovery metadata is incomplete\");\n\t}\n\tconst allowLoopbackHttp = issuer.protocol === \"http:\" && isLoopbackHostname(issuer.hostname);\n\tvalidateOidcUrl(metadata.authorization_endpoint, \"authorization endpoint\", { allowLoopbackHttp });\n\tvalidateOidcUrl(metadata.token_endpoint, \"token endpoint\", { allowLoopbackHttp });\n\tvalidateOidcUrl(metadata.jwks_uri, \"JWKS URI\", { allowLoopbackHttp });\n\treturn metadata as OidcDiscoveryMetadata;\n}\n\nasync function exchangeOidcCode(\n\ttokenEndpoint: string,\n\tconfig: OidcConfig,\n\tredirectUri: string,\n\tcode: string,\n): Promise<OidcTokensResponse> {\n\tconst body = new URLSearchParams({\n\t\tgrant_type: \"authorization_code\",\n\t\tcode,\n\t\tredirect_uri: redirectUri,\n\t\tclient_id: config.clientId,\n\t\tclient_secret: config.clientSecret,\n\t});\n\tconst response = await fetch(tokenEndpoint, {\n\t\tmethod: \"POST\",\n\t\theaders: { \"content-type\": \"application/x-www-form-urlencoded\" },\n\t\tbody,\n\t});\n\tif (!response.ok) throw new Error(\"OIDC token request failed\");\n\treturn (await response.json()) as OidcTokensResponse;\n}\n\nasync function validateIdToken(\n\tidToken: string,\n\tdiscovery: OidcDiscoveryMetadata,\n\tclientId: string,\n\tnonce: string,\n\tnow: number,\n): Promise<JwtClaims> {\n\tconst [encodedHeader, encodedClaims, signature] = idToken.split(\".\");\n\tif (!encodedHeader || !encodedClaims || !signature) throw new Error(\"Invalid OIDC id_token\");\n\tconst header = parseJwtPart<JwtHeader>(encodedHeader);\n\tconst claims = parseJwtPart<JwtClaims>(encodedClaims);\n\tif (header.alg !== \"RS256\" || !header.kid) throw new Error(\"Unsupported OIDC id_token signature\");\n\tif (claims.iss !== discovery.issuer) throw new Error(\"OIDC id_token issuer mismatch\");\n\tif (!audienceIncludes(claims.aud, clientId)) throw new Error(\"OIDC id_token audience mismatch\");\n\tif (!isValidAuthorizedParty(claims.aud, claims.azp, clientId))\n\t\tthrow new Error(\"OIDC id_token authorized party mismatch\");\n\tif (typeof claims.exp !== \"number\" || !Number.isFinite(claims.exp) || claims.exp * 1000 <= now)\n\t\tthrow new Error(\"OIDC id_token is expired\");\n\tif (typeof claims.iat !== \"number\" || !Number.isFinite(claims.iat))\n\t\tthrow new Error(\"OIDC id_token issued-at time is missing\");\n\tif (claims.iat * 1000 > now + ID_TOKEN_CLOCK_SKEW_MS)\n\t\tthrow new Error(\"OIDC id_token issued-at time is in the future\");\n\tif (claims.nonce !== nonce) throw new Error(\"OIDC id_token nonce mismatch\");\n\tif (!claims.sub) throw new Error(\"OIDC id_token subject is missing\");\n\n\tconst jwksResponse = await fetch(discovery.jwks_uri);\n\tif (!jwksResponse.ok) throw new Error(\"OIDC JWKS request failed\");\n\tconst jwks = (await jwksResponse.json()) as JsonWebKeySet;\n\tconst jwk = jwks.keys?.find((key) => key.kid === header.kid && key.kty === \"RSA\");\n\tif (!jwk) throw new Error(\"OIDC signing key not found\");\n\tconst key = createPublicKey({ key: jwk, format: \"jwk\" });\n\tconst signed = `${encodedHeader}.${encodedClaims}`;\n\tconst ok = verify(\"RSA-SHA256\", Buffer.from(signed), key, Buffer.from(signature, \"base64url\"));\n\tif (!ok) throw new Error(\"OIDC id_token signature verification failed\");\n\treturn claims;\n}\n\nfunction parseJwtPart<T>(encoded: string): T {\n\treturn JSON.parse(Buffer.from(encoded, \"base64url\").toString(\"utf8\")) as T;\n}\n\nfunction audienceIncludes(audience: string | string[] | undefined, clientId: string): boolean {\n\treturn Array.isArray(audience) ? audience.includes(clientId) : audience === clientId;\n}\n\nfunction isValidAuthorizedParty(\n\taudience: string | string[] | undefined,\n\tauthorizedParty: string | undefined,\n\tclientId: string,\n): boolean {\n\tif (authorizedParty && authorizedParty !== clientId) return false;\n\treturn !Array.isArray(audience) || audience.length <= 1 || authorizedParty === clientId;\n}\n\nfunction isAllowedIdentity(claims: JwtClaims, config: OidcConfig): boolean {\n\tif (config.allowedSubject && claims.sub === config.allowedSubject) return true;\n\tif (!config.allowedEmail) return false;\n\treturn claims.email_verified === true && claims.email?.toLowerCase() === config.allowedEmail;\n}\n\nfunction validateOidcUrl(\n\tvalue: string,\n\tlabel: string,\n\toptions: { allowLoopbackHttp?: boolean } = {},\n): void {\n\tconst url = new URL(value);\n\tif (url.username || url.password) throw new Error(`OIDC ${label} must not include credentials`);\n\tif (url.protocol === \"https:\") return;\n\tif (options.allowLoopbackHttp && url.protocol === \"http:\" && isLoopbackHostname(url.hostname))\n\t\treturn;\n\tthrow new Error(`OIDC ${label} must use HTTPS`);\n}\n\nfunction isLoopbackHostname(hostname: string): boolean {\n\tconst normalized = hostname.replace(/^\\[(.*)]$/, \"$1\").toLowerCase();\n\treturn normalized === \"localhost\" || normalized === \"127.0.0.1\" || normalized === \"::1\";\n}\n\nfunction invalidOAuthRequest(error: string, description?: string): McpOAuthErrorResult {\n\treturn {\n\t\tstatus: 400,\n\t\tbody: description ? { error, error_description: description } : { error },\n\t};\n}\n","import type { OAuthRegisteredClientsStore } from \"@modelcontextprotocol/sdk/server/auth/clients.js\";\nimport {\n\tAccessDeniedError,\n\tInvalidClientError,\n\tInvalidGrantError,\n\tInvalidRequestError,\n\tInvalidTokenError,\n\tServerError,\n\tTemporarilyUnavailableError,\n\tUnsupportedResponseTypeError,\n} from \"@modelcontextprotocol/sdk/server/auth/errors.js\";\nimport type {\n\tAuthorizationParams,\n\tOAuthServerProvider,\n} from \"@modelcontextprotocol/sdk/server/auth/provider.js\";\nimport type { AuthInfo } from \"@modelcontextprotocol/sdk/server/auth/types.js\";\nimport {\n\ttype OAuthClientInformationFull,\n\ttype OAuthErrorResponse,\n\ttype OAuthTokenRevocationRequest,\n\ttype OAuthTokens,\n\tOAuthTokensSchema,\n} from \"@modelcontextprotocol/sdk/shared/auth.js\";\nimport type { Response } from \"express\";\nimport {\n\tcreateInMemoryOAuthRefreshTokenStore,\n\ttype OAuthAccessTokenStore,\n\ttype OAuthAuthorizationCodeStore,\n\ttype OAuthRefreshTokenStore,\n} from \"./oauth.js\";\nimport {\n\tbeginOidcAuthorization,\n\ttype OidcConfig,\n\ttype OidcPendingAuthorizationStore,\n} from \"./oidc.js\";\n\nexport interface MemoryOAuthServerProviderOptions {\n\tclientsStore: OAuthRegisteredClientsStore;\n\tcodeStore: OAuthAuthorizationCodeStore;\n\ttokenStore: OAuthAccessTokenStore;\n\trefreshTokenStore?: OAuthRefreshTokenStore;\n\tpublicMcpUrl: string;\n\toidc?: { config: OidcConfig; pendingStore: OidcPendingAuthorizationStore };\n\tnow?: () => number;\n}\n\n/**\n * MemoryOAuthServerProvider adapts codemem's existing in-memory stores to the\n * `@modelcontextprotocol/sdk` `OAuthServerProvider` contract so the SDK's\n * `mcpAuthRouter` and `requireBearerAuth` middleware can drive the OAuth\n * lifecycle. This class is the boundary between SDK-handled HTTP and\n * codemem-owned storage / upstream-OIDC bridging.\n *\n * Conventions encoded here:\n * - `authorize()` does NOT mint the MCP authorization code itself. It\n * persists pending state and redirects the user-agent to the upstream OIDC\n * provider. The MCP code is issued later by codemem's own /oauth/callback\n * route (wired in codemem-b20m.3) after the upstream identity is validated.\n * - PKCE is validated by the SDK token handler against the challenge returned\n * from `challengeForAuthorizationCode`. We do not re-verify here.\n * - `expiresAt` returned in `AuthInfo` is epoch SECONDS per the SDK's\n * `requireBearerAuth` expectations; the underlying store records ms.\n * - Refresh-token grants use dual-token rotation: the current token and one\n * previous token are accepted to tolerate client retry races, while older\n * replayed tokens revoke the whole grant.\n */\nexport class MemoryOAuthServerProvider implements OAuthServerProvider {\n\treadonly #clientsStore: OAuthRegisteredClientsStore;\n\treadonly #codeStore: OAuthAuthorizationCodeStore;\n\treadonly #tokenStore: OAuthAccessTokenStore;\n\treadonly #refreshTokenStore: OAuthRefreshTokenStore;\n\treadonly #publicMcpUrl: string;\n\treadonly #resourceServerUrl: string;\n\treadonly #oidc?: { config: OidcConfig; pendingStore: OidcPendingAuthorizationStore };\n\treadonly #now: () => number;\n\n\tconstructor(options: MemoryOAuthServerProviderOptions) {\n\t\tthis.#clientsStore = options.clientsStore;\n\t\tthis.#codeStore = options.codeStore;\n\t\tthis.#tokenStore = options.tokenStore;\n\t\tthis.#refreshTokenStore = options.refreshTokenStore ?? createInMemoryOAuthRefreshTokenStore();\n\t\tthis.#publicMcpUrl = options.publicMcpUrl;\n\t\tthis.#resourceServerUrl = new URL(options.publicMcpUrl).href;\n\t\tthis.#oidc = options.oidc;\n\t\tthis.#now = options.now ?? Date.now;\n\t}\n\n\tget clientsStore(): OAuthRegisteredClientsStore {\n\t\treturn this.#clientsStore;\n\t}\n\n\tasync authorize(\n\t\tclient: OAuthClientInformationFull,\n\t\tparams: AuthorizationParams,\n\t\tres: Response,\n\t): Promise<void> {\n\t\tif (!this.#oidc) {\n\t\t\tthrow new TemporarilyUnavailableError(\"OIDC is not configured\");\n\t\t}\n\t\tconst upstreamParams = buildUpstreamAuthorizationParams(client, params);\n\t\tconst result = await beginOidcAuthorization(\n\t\t\tupstreamParams,\n\t\t\tthis.#clientsStore,\n\t\t\tthis.#oidc.pendingStore,\n\t\t\tthis.#oidc.config,\n\t\t\tthis.#publicMcpUrl,\n\t\t\tthis.#now(),\n\t\t);\n\t\tif (result.status === 302) {\n\t\t\tres.redirect(302, result.location);\n\t\t\treturn;\n\t\t}\n\t\tthrow mapOAuthErrorBody(result.body);\n\t}\n\n\tasync challengeForAuthorizationCode(\n\t\t_client: OAuthClientInformationFull,\n\t\tauthorizationCode: string,\n\t): Promise<string> {\n\t\tconst record = this.#codeStore.peekCode(authorizationCode);\n\t\tif (!record) throw new InvalidGrantError(\"Invalid or already used code\");\n\t\tif (record.clientId !== _client.client_id) {\n\t\t\tthrow new InvalidGrantError(\"Code does not match client\");\n\t\t}\n\t\tif (record.expiresAt <= this.#now()) {\n\t\t\tthis.#codeStore.consumeCode(authorizationCode);\n\t\t\tthrow new InvalidGrantError(\"Expired code\");\n\t\t}\n\t\treturn record.codeChallenge;\n\t}\n\n\tasync exchangeAuthorizationCode(\n\t\tclient: OAuthClientInformationFull,\n\t\tauthorizationCode: string,\n\t\t_codeVerifier?: string,\n\t\tredirectUri?: string,\n\t\tresource?: URL,\n\t): Promise<OAuthTokens> {\n\t\tconst now = this.#now();\n\t\tconst record = this.#codeStore.peekCode(authorizationCode);\n\t\tif (!record) throw new InvalidGrantError(\"Invalid or already used code\");\n\t\tif (record.expiresAt <= now) {\n\t\t\tthis.#codeStore.consumeCode(authorizationCode);\n\t\t\tthrow new InvalidGrantError(\"Expired code\");\n\t\t}\n\t\tif (record.clientId !== client.client_id) {\n\t\t\tthis.#codeStore.consumeCode(authorizationCode);\n\t\t\tthrow new InvalidGrantError(\"Code does not match client\");\n\t\t}\n\t\t// RFC 6749 §4.1.3: if the authorization request included redirect_uri,\n\t\t// the token request MUST include the same value. codemem always binds a\n\t\t// redirect_uri at /authorize, so a missing value at /token is always a\n\t\t// grant mismatch, not an optional check.\n\t\tif (redirectUri === undefined || record.redirectUri !== redirectUri) {\n\t\t\tthis.#codeStore.consumeCode(authorizationCode);\n\t\t\tthrow new InvalidGrantError(\"Code does not match redirect_uri\");\n\t\t}\n\t\tif ((record.resource ?? null) !== (resource?.href ?? null)) {\n\t\t\tthis.#codeStore.consumeCode(authorizationCode);\n\t\t\tthrow new InvalidGrantError(\"Code does not match resource\");\n\t\t}\n\n\t\tconst scopes = normalizeClientScopes(record.scopes) ?? [];\n\t\tconst grant = this.#refreshTokenStore.issueGrant(\n\t\t\t{ clientId: client.client_id, scopes, resource: record.resource },\n\t\t\tnow,\n\t\t);\n\t\tif (!grant) {\n\t\t\tthrow new TemporarilyUnavailableError(\"Too many active refresh grants\");\n\t\t}\n\t\tconst issued = this.#tokenStore.issueToken(\n\t\t\tclient.client_id,\n\t\t\tnow,\n\t\t\trecord.resource,\n\t\t\tgrant.grant.grantId,\n\t\t\tscopes,\n\t\t);\n\t\tif (!issued) {\n\t\t\t// Token-store overload is transient: leave the auth code unused so the\n\t\t\t// client can retry token exchange without restarting the OAuth flow.\n\t\t\tthis.#refreshTokenStore.revokeGrant(grant.grant.grantId, now);\n\t\t\tthrow new TemporarilyUnavailableError(\"Too many active access tokens\");\n\t\t}\n\n\t\tconst consumed = this.#codeStore.consumeCode(authorizationCode);\n\t\tif (!consumed) {\n\t\t\tthis.#tokenStore.revokeToken(issued.token, now);\n\t\t\tthis.#refreshTokenStore.revokeGrant(grant.grant.grantId, now);\n\t\t\t// Lost a race with a concurrent exchange that consumed the code in\n\t\t\t// the gap between peek and consume. Reject rather than issuing a\n\t\t\t// duplicate usable token.\n\t\t\tthrow new InvalidGrantError(\"Authorization code already used\");\n\t\t}\n\n\t\treturn OAuthTokensSchema.parse({\n\t\t\taccess_token: issued.token,\n\t\t\ttoken_type: \"Bearer\",\n\t\t\texpires_in: issued.expiresIn,\n\t\t\trefresh_token: grant.refreshToken,\n\t\t});\n\t}\n\n\tasync exchangeRefreshToken(\n\t\tclient: OAuthClientInformationFull,\n\t\trefreshToken: string,\n\t\tscopes?: string[],\n\t\tresource?: URL,\n\t): Promise<OAuthTokens> {\n\t\tconst now = this.#now();\n\t\tconst rotation = this.#refreshTokenStore.rotateRefreshToken(\n\t\t\tclient.client_id,\n\t\t\trefreshToken,\n\t\t\t{ scopes: normalizeClientScopes(scopes), ...(resource ? { resource: resource.href } : {}) },\n\t\t\tnow,\n\t\t);\n\t\tif (!rotation.ok) {\n\t\t\tif (rotation.reason === \"refresh_token_replay\" && rotation.grantId) {\n\t\t\t\tthis.#tokenStore.revokeTokensForGrant?.(rotation.grantId, now);\n\t\t\t}\n\t\t\tthrow new InvalidGrantError(refreshTokenErrorDescription(rotation.reason));\n\t\t}\n\t\tconst issued = this.#tokenStore.issueToken(\n\t\t\tclient.client_id,\n\t\t\tnow,\n\t\t\trotation.grant.resource,\n\t\t\trotation.grant.grantId,\n\t\t\trotation.grant.scopes,\n\t\t);\n\t\tif (!issued) throw new TemporarilyUnavailableError(\"Too many active access tokens\");\n\t\treturn OAuthTokensSchema.parse({\n\t\t\taccess_token: issued.token,\n\t\t\ttoken_type: \"Bearer\",\n\t\t\texpires_in: issued.expiresIn,\n\t\t\trefresh_token: rotation.refreshToken,\n\t\t});\n\t}\n\n\tasync verifyAccessToken(token: string): Promise<AuthInfo> {\n\t\tconst result = this.#tokenStore.verifyToken(token, this.#now());\n\t\tif (!result.ok) {\n\t\t\tconst reason =\n\t\t\t\tresult.reason === \"expired_token\"\n\t\t\t\t\t? \"Token has expired\"\n\t\t\t\t\t: result.reason === \"revoked_token\"\n\t\t\t\t\t\t? \"Token has been revoked\"\n\t\t\t\t\t\t: \"Token is invalid\";\n\t\t\tthrow new InvalidTokenError(reason);\n\t\t}\n\t\tconst authInfo: AuthInfo = {\n\t\t\ttoken,\n\t\t\tclientId: result.record.clientId,\n\t\t\tscopes: result.record.scopes,\n\t\t\texpiresAt: Math.floor(result.record.expiresAt / 1000),\n\t\t};\n\t\tif (result.record.resource) {\n\t\t\tif (new URL(result.record.resource).href !== this.#resourceServerUrl) {\n\t\t\t\tthrow new InvalidTokenError(\"Token audience does not match this resource server\");\n\t\t\t}\n\t\t\tauthInfo.resource = new URL(result.record.resource);\n\t\t}\n\t\treturn authInfo;\n\t}\n\n\tasync revokeToken(\n\t\t_client: OAuthClientInformationFull,\n\t\trequest: OAuthTokenRevocationRequest,\n\t): Promise<void> {\n\t\tconst now = this.#now();\n\t\tthis.#tokenStore.revokeToken(request.token, now);\n\t\tconst grantId = this.#refreshTokenStore.revokeRefreshToken(request.token, now);\n\t\tif (grantId) this.#tokenStore.revokeTokensForGrant?.(grantId, now);\n\t}\n}\n\nfunction buildUpstreamAuthorizationParams(\n\tclient: OAuthClientInformationFull,\n\tparams: AuthorizationParams,\n): URLSearchParams {\n\tconst upstream = new URLSearchParams();\n\tupstream.set(\"client_id\", client.client_id);\n\tupstream.set(\"redirect_uri\", params.redirectUri);\n\tupstream.set(\"response_type\", \"code\");\n\tupstream.set(\"code_challenge\", params.codeChallenge);\n\tupstream.set(\"code_challenge_method\", \"S256\");\n\tif (params.state) upstream.set(\"state\", params.state);\n\tif (params.scopes?.length) upstream.set(\"scope\", params.scopes.join(\" \"));\n\tif (params.resource) upstream.set(\"resource\", params.resource.href);\n\treturn upstream;\n}\n\nfunction mapOAuthErrorBody(body: OAuthErrorResponse): Error {\n\tconst description = body.error_description ?? body.error;\n\tswitch (body.error) {\n\t\tcase \"temporarily_unavailable\":\n\t\t\treturn new TemporarilyUnavailableError(description);\n\t\tcase \"invalid_request\":\n\t\t\treturn new InvalidRequestError(description);\n\t\tcase \"invalid_client\":\n\t\t\treturn new InvalidClientError(description);\n\t\tcase \"access_denied\":\n\t\t\treturn new AccessDeniedError(description);\n\t\tcase \"unsupported_response_type\":\n\t\t\treturn new UnsupportedResponseTypeError(description);\n\t\tdefault:\n\t\t\treturn new ServerError(description);\n\t}\n}\n\nfunction refreshTokenErrorDescription(reason: string): string {\n\tswitch (reason) {\n\t\tcase \"expired_refresh_token\":\n\t\t\treturn \"Refresh token has expired\";\n\t\tcase \"revoked_refresh_token\":\n\t\t\treturn \"Refresh token has been revoked\";\n\t\tcase \"client_mismatch\":\n\t\t\treturn \"Refresh token does not match client\";\n\t\tcase \"scope_mismatch\":\n\t\t\treturn \"Refresh token scope cannot be expanded\";\n\t\tcase \"resource_mismatch\":\n\t\t\treturn \"Refresh token does not match resource\";\n\t\tcase \"refresh_token_replay\":\n\t\t\treturn \"Refresh token replay detected\";\n\t\tdefault:\n\t\t\treturn \"Invalid refresh token\";\n\t}\n}\n\nfunction normalizeClientScopes(scopes: string[] | undefined): string[] | undefined {\n\tconst normalized = scopes\n\t\t?.map((scope) => scope.trim())\n\t\t.filter(Boolean)\n\t\t.map((scope) => {\n\t\t\tif (scope === \"memory:read_access\") return \"memory:read\";\n\t\t\tif (scope === \"memory:write_access\") return \"memory:write\";\n\t\t\treturn scope;\n\t\t});\n\treturn normalized && normalized.length > 0 ? normalized : undefined;\n}\n","#!/usr/bin/env node\n\n/**\n * @codemem/mcp — MCP Streamable HTTP server bootstrap.\n *\n * Local-first HTTP transport for MCP clients. OAuth metadata and Dynamic Client\n * Registration are exposed for remote MCP setup; public MCP requests require\n * OAuth bearer tokens.\n */\n\nimport { createHash, randomUUID } from \"node:crypto\";\nimport { createServer, type IncomingMessage, type Server } from \"node:http\";\nimport { isIP } from \"node:net\";\nimport { pathToFileURL } from \"node:url\";\nimport { MemoryStore, resolveDbPath } from \"@codemem/core\";\nimport { requireBearerAuth } from \"@modelcontextprotocol/sdk/server/auth/middleware/bearerAuth.js\";\nimport {\n\tgetOAuthProtectedResourceMetadataUrl,\n\tmcpAuthRouter,\n} from \"@modelcontextprotocol/sdk/server/auth/router.js\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StreamableHTTPServerTransport } from \"@modelcontextprotocol/sdk/server/streamableHttp.js\";\nimport express, { type NextFunction, type Request, type Response } from \"express\";\nimport { rateLimit } from \"express-rate-limit\";\nimport {\n\ttype BearerDenyReason,\n\tbuildOAuthAuditEvent,\n\ttype OAuthAuditEmitter,\n\tresolveOAuthAuditEmitterFromEnv,\n\twrapAuditEmitterBestEffort,\n} from \"./audit.js\";\nimport { canonicalJson } from \"./canonical-json.js\";\nimport {\n\tcreateInMemoryOAuthAccessTokenStore,\n\tcreateInMemoryOAuthAuthorizationCodeStore,\n\tcreateInMemoryOAuthClientsStore,\n\tcreateJsonFileOAuthStateStore,\n\tcreateMcpOAuthMetadata,\n\tcreateMcpProtectedResourceMetadata,\n\tMCP_OAUTH_PUBLIC_URL_ENV,\n\tMCP_OAUTH_RESOURCE_NAME,\n\tMCP_OAUTH_SCOPES_SUPPORTED,\n\tMCP_OAUTH_SERVICE_DOCUMENTATION_URL,\n\tnormalizeMcpPublicUrl,\n\ttype OAuthAccessTokenStore,\n} from \"./oauth.js\";\nimport {\n\tcompleteOidcAuthorization,\n\tcreateInMemoryOidcPendingAuthorizationStore,\n\tresolveOidcConfig,\n} from \"./oidc.js\";\nimport { MemoryOAuthServerProvider } from \"./provider.js\";\nimport { createCodememMcpServer } from \"./server.js\";\n\nexport const DEFAULT_MCP_HTTP_HOST = \"127.0.0.1\";\nexport const DEFAULT_MCP_HTTP_PORT = 38889;\nconst HTTP_DEFAULT_PORT = 80;\nconst TRUSTED_PUBLIC_BROWSER_ORIGINS = new Set([\"https://chatgpt.com\", \"https://claude.ai\"]);\nconst CORS_ALLOW_HEADERS = \"authorization,content-type,mcp-session-id\";\nconst CORS_MAX_AGE_SECONDS = \"600\";\nconst MAX_GUARD_LOG_FIELD_LENGTH = 256;\nconst PUBLIC_MCP_RATE_LIMIT_WINDOW_MS = 15 * 60 * 1000;\nconst PUBLIC_MCP_RATE_LIMIT_REQUESTS = 600;\nexport const MCP_HTTP_MAX_JSON_BODY_BYTES = 4 * 1024 * 1024;\nexport const MCP_HTTP_RETRIEVAL_RETRY_WINDOW_MS = 5 * 60 * 1000;\nconst MCP_HTTP_RETRIEVAL_RETRY_MAX_ENTRIES = 2000;\n\nconst VALID_HOSTNAME = /^[a-zA-Z0-9.-]+$/;\nconst LOOPBACK_HOSTS = new Set([\"127.0.0.1\", \"::1\", \"localhost\"]);\n\ninterface ActiveRequest {\n\tmcpServer: McpServer;\n}\n\nexport interface CodememMcpHttpOptions {\n\thost?: string;\n\tport?: number | string;\n\tdbPath?: string;\n\tallowUnsafePublic?: boolean;\n\tpublicUrl?: string;\n\toauthAccessTokenStore?: OAuthAccessTokenStore;\n\toauthStatePath?: string;\n\tauditEmitter?: OAuthAuditEmitter;\n\tretrievalLedgerNow?: () => number;\n}\n\nexport interface CodememMcpHttpServer {\n\tserver: Server;\n\tstore: MemoryStore;\n\turl: string;\n\tclose: () => Promise<void>;\n}\n\nexport function authenticatedRetrievalPrincipal(\n\tauth: { clientId?: string; token?: string; extra?: Record<string, unknown> } | undefined,\n): string | undefined {\n\tconst authSubject = auth?.extra?.sub;\n\tif (typeof authSubject === \"string\" && authSubject.trim().length > 0) {\n\t\tconst subject = authSubject.trim();\n\t\tconst clientId = auth?.clientId?.trim();\n\t\treturn clientId ? `subject-client:${canonicalJson([subject, clientId])}` : `subject:${subject}`;\n\t}\n\treturn auth?.token ? `token:${auth.token}` : undefined;\n}\n\nexport function validateMcpHttpHost(host: string | undefined, allowUnsafePublic = false): string {\n\tconst value = host?.trim() || DEFAULT_MCP_HTTP_HOST;\n\tif (value.includes(\"://\") || value.includes(\"/\") || value.includes(\"\\\\\")) {\n\t\tthrow new Error(`Invalid MCP HTTP host: ${host}`);\n\t}\n\tif (!(isIP(value) || value === \"localhost\" || VALID_HOSTNAME.test(value))) {\n\t\tthrow new Error(`Invalid MCP HTTP host: ${host}`);\n\t}\n\tif (!allowUnsafePublic && !isLoopbackHost(value)) {\n\t\tthrow new Error(\n\t\t\t`Refusing unsafe MCP HTTP host ${value}; set CODEMEM_MCP_HTTP_UNSAFE_PUBLIC=1 to allow non-loopback binding`,\n\t\t);\n\t}\n\treturn value;\n}\n\nexport function isLoopbackHost(host: string): boolean {\n\treturn LOOPBACK_HOSTS.has(normalizeHost(host));\n}\n\nexport function isUnsafePublicBindAllowed(\n\tvalue = process.env.CODEMEM_MCP_HTTP_UNSAFE_PUBLIC,\n): boolean {\n\treturn value === \"1\" || value?.toLowerCase() === \"true\" || value?.toLowerCase() === \"yes\";\n}\n\nexport function isAllowedMcpHttpRequestHost(\n\theader: string | undefined,\n\texpectedPort: number,\n): boolean {\n\tconst parsed = parseHostHeader(header);\n\tif (!parsed) return false;\n\tif (!isLoopbackHost(parsed.host)) return false;\n\tif (parsed.port === null) {\n\t\t// No `:port` in the Host header means the client is using the protocol\n\t\t// default. This server is plain HTTP, so the implied port is 80. Only\n\t\t// accept the bare-host form when the bound port is also 80.\n\t\treturn expectedPort === HTTP_DEFAULT_PORT;\n\t}\n\treturn parsed.port === expectedPort;\n}\n\nexport function isAllowedMcpHttpRequestOrigin(\n\theader: string | undefined,\n\texpectedPort: number,\n): boolean {\n\tif (!header) return true;\n\ttry {\n\t\tconst url = new URL(header);\n\t\tconst port = url.port ? Number(url.port) : url.protocol === \"https:\" ? 443 : 80;\n\t\treturn (\n\t\t\t(url.protocol === \"http:\" || url.protocol === \"https:\") &&\n\t\t\turl.username === \"\" &&\n\t\t\turl.password === \"\" &&\n\t\t\turl.pathname === \"/\" &&\n\t\t\turl.search === \"\" &&\n\t\t\turl.hash === \"\" &&\n\t\t\tisLoopbackHost(url.hostname) &&\n\t\t\tport === expectedPort\n\t\t);\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nexport function isAllowedMcpHttpRequestRemoteAddress(address: string | undefined): boolean {\n\tif (!address) return false;\n\treturn isLoopbackHost(address.replace(/^::ffff:/, \"\"));\n}\n\nfunction normalizeHost(host: string): string {\n\treturn host.replace(/^\\[(.*)]$/, \"$1\").toLowerCase();\n}\n\nfunction parseHostHeader(header: string | undefined): { host: string; port: number | null } | null {\n\tif (!header) return null;\n\tif (header.startsWith(\"[\")) {\n\t\t// Bracketed IPv6: `[::1]` or `[::1]:8080`.\n\t\tconst withPort = /^\\[([^\\]]+)]:(\\d+)$/.exec(header);\n\t\tif (withPort?.[1] && withPort[2]) {\n\t\t\treturn { host: withPort[1], port: Number(withPort[2]) };\n\t\t}\n\t\tconst bareIpv6 = /^\\[([^\\]]+)]$/.exec(header);\n\t\tif (bareIpv6?.[1]) return { host: bareIpv6[1], port: null };\n\t\treturn null;\n\t}\n\tconst lastColon = header.lastIndexOf(\":\");\n\tif (lastColon < 0) {\n\t\t// RFC-compliant clients may omit `:port` on default-port requests. Treat\n\t\t// the implied port as \"use the protocol default\" and let the caller\n\t\t// reconcile against the actually bound port.\n\t\treturn { host: header, port: null };\n\t}\n\tconst host = header.slice(0, lastColon);\n\tconst port = Number(header.slice(lastColon + 1));\n\tif (!Number.isInteger(port)) return null;\n\treturn { host, port };\n}\n\nexport function parseMcpHttpPort(port: number | string | undefined): number {\n\tif (port === undefined || port === \"\") return DEFAULT_MCP_HTTP_PORT;\n\tconst value = typeof port === \"number\" ? port : Number(port);\n\tif (!Number.isInteger(value) || value < 0 || value > 65_535) {\n\t\tthrow new Error(`Invalid MCP HTTP port: ${port}`);\n\t}\n\treturn value;\n}\n\nexport async function startCodememMcpHttpServer(\n\toptions: CodememMcpHttpOptions = {},\n): Promise<CodememMcpHttpServer> {\n\tconst host = validateMcpHttpHost(\n\t\toptions.host ?? process.env.CODEMEM_MCP_HTTP_HOST,\n\t\toptions.allowUnsafePublic ?? isUnsafePublicBindAllowed(),\n\t);\n\tconst port = parseMcpHttpPort(options.port ?? process.env.CODEMEM_MCP_HTTP_PORT);\n\tconst configuredPublicUrl = options.publicUrl ?? process.env[MCP_OAUTH_PUBLIC_URL_ENV];\n\tconst configuredPublicMcpUrl = configuredPublicUrl\n\t\t? normalizeMcpPublicUrl(configuredPublicUrl)\n\t\t: undefined;\n\tconst store = new MemoryStore(options.dbPath ?? resolveDbPath());\n\tconst oauthStateStore = options.oauthAccessTokenStore\n\t\t? undefined\n\t\t: createJsonFileOAuthStateStore(options.oauthStatePath);\n\tconst clientsStore = oauthStateStore ?? createInMemoryOAuthClientsStore();\n\tconst codeStore = oauthStateStore ?? createInMemoryOAuthAuthorizationCodeStore();\n\tconst tokenStore =\n\t\toptions.oauthAccessTokenStore ?? oauthStateStore ?? createInMemoryOAuthAccessTokenStore();\n\tconst oidcConfig = resolveOidcConfig();\n\tconst oidcPendingStore = createInMemoryOidcPendingAuthorizationStore();\n\tconst shouldRequireMcpBearer = configuredPublicMcpUrl !== undefined || oidcConfig !== undefined;\n\tconst auditEmit = wrapAuditEmitterBestEffort(\n\t\toptions.auditEmitter ?? resolveOAuthAuditEmitterFromEnv(),\n\t);\n\tconst activeRequests = new Set<ActiveRequest>();\n\tconst resolveRetrievalLedgerScopeId = createHttpRetrievalLedgerScopeResolver();\n\tlet closePromise: Promise<void> | null = null;\n\n\tconst app = express();\n\tapp.disable(\"x-powered-by\");\n\t// Tailscale Funnel and similar local ingress proxies forward from loopback and\n\t// add X-Forwarded-For. Trust only loopback proxy hops so SDK rate limiters can\n\t// key on the real client IP without making public clients spoofable.\n\tapp.set(\"trust proxy\", \"loopback\");\n\tconst server = createServer(app);\n\n\tawait new Promise<void>((resolve, reject) => {\n\t\tserver.once(\"error\", reject);\n\t\tserver.listen({ host, port }, () => {\n\t\t\tserver.off(\"error\", reject);\n\t\t\tresolve();\n\t\t});\n\t});\n\n\tconst publicMcpUrl = configuredPublicMcpUrl?.href ?? getServerUrl(server, host);\n\tconst publicMcpUrlObject = new URL(publicMcpUrl);\n\tconst issuerUrl = getSdkIssuerUrl(publicMcpUrlObject, getBoundPort(server));\n\tconst provider = new MemoryOAuthServerProvider({\n\t\tclientsStore,\n\t\tcodeStore,\n\t\ttokenStore,\n\t\tpublicMcpUrl,\n\t\t...(oauthStateStore ? { refreshTokenStore: oauthStateStore } : {}),\n\t\t...(oidcConfig ? { oidc: { config: oidcConfig, pendingStore: oidcPendingStore } } : {}),\n\t});\n\tconst resourceMetadataUrl = getOAuthProtectedResourceMetadataUrl(publicMcpUrlObject);\n\n\tapp.use(\n\t\trateLimit({\n\t\t\twindowMs: PUBLIC_MCP_RATE_LIMIT_WINDOW_MS,\n\t\t\tlimit: PUBLIC_MCP_RATE_LIMIT_REQUESTS,\n\t\t\tstandardHeaders: \"draft-8\",\n\t\t\tlegacyHeaders: false,\n\t\t\t// Avoid express-rate-limit's default IPv6 subnet helper here: its current\n\t\t\t// transitive ip-address API throws on IPv6 loopback in our Node 24 test path.\n\t\t\t// This coarse limiter is defense-in-depth before the SDK OAuth limiters and\n\t\t\t// the Host/Origin guard; it must never break local IPv6 metadata requests.\n\t\t\tipv6Subnet: false,\n\t\t}),\n\t);\n\tapp.use((req, res, next) => {\n\t\tconst boundPort = getBoundPort(server);\n\t\tconst pathname = normalizeRoutePath(req.path);\n\t\tif (pathname === \"/mcp\") {\n\t\t\tif (isAllowedMcpHttpRequest(req, boundPort, configuredPublicMcpUrl)) {\n\t\t\t\tapplyPublicCorsHeaders(req, res, configuredPublicMcpUrl);\n\t\t\t\tif (req.method === \"OPTIONS\") {\n\t\t\t\t\tres.status(204).send(\"\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\treturn next();\n\t\t\t}\n\t\t\temitHttpGuardDeny(req, pathname, configuredPublicMcpUrl);\n\t\t\tres.status(403).type(\"text/plain\").send(\"Forbidden\");\n\t\t\treturn;\n\t\t}\n\t\tif (isOAuthOrMetadataPath(pathname)) {\n\t\t\tif (isAllowedOAuthHttpRequest(req, boundPort, configuredPublicMcpUrl)) {\n\t\t\t\tapplyPublicCorsHeaders(req, res, configuredPublicMcpUrl);\n\t\t\t\tif (req.method === \"OPTIONS\") {\n\t\t\t\t\tres.status(204).send(\"\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\treturn next();\n\t\t\t}\n\t\t\temitHttpGuardDeny(req, pathname, configuredPublicMcpUrl);\n\t\t\tres.status(403).type(\"text/plain\").send(\"Forbidden\");\n\t\t\treturn;\n\t\t}\n\t\tnext();\n\t});\n\n\tapp.use(auditOAuthRouteResponses(auditEmit));\n\n\tapp.get(\"/oauth/callback\", async (req, res) => {\n\t\tconst remoteAddress = req.socket.remoteAddress ?? undefined;\n\t\tif (!oidcConfig) {\n\t\t\tauditEmit(\n\t\t\t\tbuildOAuthAuditEvent(\"oidc_callback\", {\n\t\t\t\t\toutcome: \"denied\",\n\t\t\t\t\treason: \"oidc_not_configured\",\n\t\t\t\t\tremoteAddress,\n\t\t\t\t}),\n\t\t\t);\n\t\t\tres.status(400).json({\n\t\t\t\terror: \"temporarily_unavailable\",\n\t\t\t\terror_description: \"OIDC is not configured\",\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tconst completed = await completeOidcAuthorization(\n\t\t\tnew URLSearchParams(req.query as Record<string, string>),\n\t\t\toidcPendingStore,\n\t\t\toidcConfig,\n\t\t\tpublicMcpUrl,\n\t\t);\n\t\tif (\"status\" in completed) {\n\t\t\tauditEmit(\n\t\t\t\tbuildOAuthAuditEvent(\"oidc_callback\", {\n\t\t\t\t\toutcome: \"denied\",\n\t\t\t\t\treason: completed.body.error,\n\t\t\t\t\tremoteAddress,\n\t\t\t\t}),\n\t\t\t);\n\t\t\tres.status(completed.status).json(completed.body);\n\t\t\treturn;\n\t\t}\n\t\tconst oauthClientId = completed.oauthParams.get(\"client_id\") ?? undefined;\n\t\tconst code = codeStore.issueCode({\n\t\t\tclientId: completed.oauthParams.get(\"client_id\") ?? \"\",\n\t\t\tredirectUri: completed.oauthParams.get(\"redirect_uri\") ?? \"\",\n\t\t\tcodeChallenge: completed.oauthParams.get(\"code_challenge\") ?? \"\",\n\t\t\tscopes: parseScopeList(completed.oauthParams.get(\"scope\")),\n\t\t\t...(completed.oauthParams.get(\"resource\")\n\t\t\t\t? { resource: completed.oauthParams.get(\"resource\") ?? undefined }\n\t\t\t\t: {}),\n\t\t\texpiresAt: Date.now() + 5 * 60 * 1000,\n\t\t});\n\t\tif (!code) {\n\t\t\tauditEmit(\n\t\t\t\tbuildOAuthAuditEvent(\"oidc_callback\", {\n\t\t\t\t\toutcome: \"denied\",\n\t\t\t\t\treason: \"temporarily_unavailable\",\n\t\t\t\t\tclientId: oauthClientId,\n\t\t\t\t\tremoteAddress,\n\t\t\t\t}),\n\t\t\t);\n\t\t\tres.status(400).json({\n\t\t\t\terror: \"temporarily_unavailable\",\n\t\t\t\terror_description: \"Too many active authorization codes\",\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tconst redirect = new URL(completed.oauthParams.get(\"redirect_uri\") ?? \"\");\n\t\tredirect.searchParams.set(\"code\", code);\n\t\tconst state = completed.oauthParams.get(\"state\");\n\t\tif (state) redirect.searchParams.set(\"state\", state);\n\t\tauditEmit(\n\t\t\tbuildOAuthAuditEvent(\"oidc_callback\", {\n\t\t\t\toutcome: \"success\",\n\t\t\t\treason: \"code_issued\",\n\t\t\t\tclientId: oauthClientId,\n\t\t\t\tremoteAddress,\n\t\t\t}),\n\t\t);\n\t\tres.redirect(302, redirect.href);\n\t});\n\n\tapp.get(\"/.well-known/oauth-authorization-server\", (_req, res) => {\n\t\tres.status(200).json(createMcpOAuthMetadata({ mcpUrl: publicMcpUrl, clientsStore }));\n\t});\n\tapp.get(\"/.well-known/oauth-protected-resource/mcp\", (_req, res) => {\n\t\tres.status(200).json(createMcpProtectedResourceMetadata(publicMcpUrl));\n\t});\n\n\tapp.use(\n\t\tmcpAuthRouter({\n\t\t\tprovider,\n\t\t\tissuerUrl,\n\t\t\tbaseUrl: issuerUrl,\n\t\t\tresourceServerUrl: publicMcpUrlObject,\n\t\t\tresourceName: MCP_OAUTH_RESOURCE_NAME,\n\t\t\tscopesSupported: MCP_OAUTH_SCOPES_SUPPORTED,\n\t\t\tserviceDocumentationUrl: new URL(MCP_OAUTH_SERVICE_DOCUMENTATION_URL),\n\t\t\tclientRegistrationOptions: { clientSecretExpirySeconds: 0 },\n\t\t}),\n\t);\n\n\tconst bearerMiddleware = shouldRequireMcpBearer\n\t\t? requireBearerAuth({ verifier: provider, resourceMetadataUrl })\n\t\t: (_req: Request, _res: Response, next: NextFunction) => next();\n\tconst bearerAuditMiddleware = shouldRequireMcpBearer\n\t\t? auditBearerPreflight(auditEmit, tokenStore)\n\t\t: (_req: Request, _res: Response, next: NextFunction) => next();\n\tapp.post(\n\t\t\"/mcp\",\n\t\tbearerAuditMiddleware,\n\t\tbearerMiddleware,\n\t\texpress.json({ limit: MCP_HTTP_MAX_JSON_BODY_BYTES }),\n\t\tasync (req: Request, res: Response) => {\n\t\t\tif (req.auth) {\n\t\t\t\tauditEmit(\n\t\t\t\t\tbuildOAuthAuditEvent(\"bearer\", {\n\t\t\t\t\t\toutcome: \"success\",\n\t\t\t\t\t\tclientId: req.auth.clientId,\n\t\t\t\t\t\tremoteAddress: req.socket.remoteAddress ?? undefined,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst retrievalPrincipal = authenticatedRetrievalPrincipal(req.auth);\n\t\t\tconst retrievalLedgerScopeId = resolveRetrievalLedgerScopeId({\n\t\t\t\tendpoint: publicMcpUrlObject,\n\t\t\t\tprincipal: retrievalPrincipal,\n\t\t\t\trequestBody: req.body,\n\t\t\t\tnow: options.retrievalLedgerNow?.() ?? Date.now(),\n\t\t\t});\n\t\t\tconst mcpServer = createCodememMcpServer(store, {\n\t\t\t\tretrievalLedgerScopeId,\n\t\t\t\tretrievalLedgerIdentityMode: \"stateless\",\n\t\t\t});\n\t\t\tconst transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined });\n\t\t\tconst activeRequest = { mcpServer };\n\t\t\tactiveRequests.add(activeRequest);\n\t\t\ttry {\n\t\t\t\tawait mcpServer.connect(transport);\n\t\t\t\tawait transport.handleRequest(req, res, req.body);\n\t\t\t} finally {\n\t\t\t\tactiveRequests.delete(activeRequest);\n\t\t\t\tawait mcpServer.close();\n\t\t\t}\n\t\t},\n\t\thandleMcpJsonBodyError,\n\t);\n\tapp.all(\"/mcp\", (_req, res) => {\n\t\tres.setHeader(\"Allow\", \"POST\");\n\t\tres.status(405).type(\"text/plain\").send(\"Method not allowed\");\n\t});\n\tapp.use((_req, res) => {\n\t\tres.status(404).type(\"text/plain\").send(\"Not found\");\n\t});\n\n\tconst close = () => {\n\t\tclosePromise ??= (async () => {\n\t\t\tawait Promise.allSettled([...activeRequests].map(({ mcpServer }) => mcpServer.close()));\n\t\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\t\tserver.close((err) => {\n\t\t\t\t\tif (!err || (err as NodeJS.ErrnoException).code === \"ERR_SERVER_NOT_RUNNING\") {\n\t\t\t\t\t\tresolve();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\treject(err);\n\t\t\t\t});\n\t\t\t\tserver.closeAllConnections();\n\t\t\t});\n\t\t\tstore.close();\n\t\t})();\n\t\treturn closePromise;\n\t};\n\n\treturn {\n\t\tserver,\n\t\tstore,\n\t\turl: `http://${formatHostForUrl(host)}:${getBoundPort(server)}/mcp`,\n\t\tclose,\n\t};\n}\n\nfunction isAllowedMcpHttpRequest(\n\treq: IncomingMessage,\n\texpectedPort: number,\n\tpublicMcpUrl: URL | undefined,\n): boolean {\n\tif (isAllowedLocalMcpHttpRequest(req, expectedPort)) return true;\n\tif (!publicMcpUrl) return false;\n\treturn (\n\t\tisAllowedPublicRequestHost(req.headers.host, publicMcpUrl) &&\n\t\tisAllowedPublicOrigin(req.headers.origin, publicMcpUrl)\n\t);\n}\n\nfunction isAllowedLocalMcpHttpRequest(req: IncomingMessage, expectedPort: number): boolean {\n\treturn (\n\t\tisAllowedMcpHttpRequestRemoteAddress(req.socket.remoteAddress) &&\n\t\tisAllowedMcpHttpRequestHost(req.headers.host, expectedPort) &&\n\t\tisAllowedMcpHttpRequestOrigin(req.headers.origin, expectedPort)\n\t);\n}\n\nfunction isAllowedOAuthHttpRequest(\n\treq: IncomingMessage,\n\texpectedPort: number,\n\tpublicMcpUrl: URL | undefined,\n): boolean {\n\tif (isAllowedLocalMcpHttpRequest(req, expectedPort)) return true;\n\tif (!publicMcpUrl) return false;\n\treturn (\n\t\tisAllowedPublicRequestHost(req.headers.host, publicMcpUrl) &&\n\t\tisAllowedPublicOrigin(req.headers.origin, publicMcpUrl)\n\t);\n}\n\nfunction isAllowedPublicOrigin(header: string | undefined, publicMcpUrl: URL): boolean {\n\tif (!header) return true;\n\ttry {\n\t\tconst origin = new URL(header);\n\t\treturn (\n\t\t\torigin.origin === publicMcpUrl.origin || TRUSTED_PUBLIC_BROWSER_ORIGINS.has(origin.origin)\n\t\t);\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction applyPublicCorsHeaders(\n\treq: IncomingMessage,\n\tres: Response,\n\tpublicMcpUrl: URL | undefined,\n): void {\n\tif (!publicMcpUrl) return;\n\tconst origin = getAllowedPublicCorsOrigin(req.headers.origin, publicMcpUrl);\n\tif (!origin) return;\n\tres.setHeader(\"Access-Control-Allow-Origin\", origin);\n\tres.setHeader(\"Access-Control-Allow-Methods\", \"GET,POST,OPTIONS\");\n\tres.setHeader(\n\t\t\"Access-Control-Allow-Headers\",\n\t\treq.headers[\"access-control-request-headers\"] ?? CORS_ALLOW_HEADERS,\n\t);\n\tres.setHeader(\"Access-Control-Max-Age\", CORS_MAX_AGE_SECONDS);\n\tres.setHeader(\"Vary\", \"Origin\");\n}\n\nfunction getAllowedPublicCorsOrigin(\n\theader: string | undefined,\n\tpublicMcpUrl: URL,\n): string | undefined {\n\tif (!header) return undefined;\n\ttry {\n\t\tconst origin = new URL(header).origin;\n\t\tif (origin === publicMcpUrl.origin || TRUSTED_PUBLIC_BROWSER_ORIGINS.has(origin)) {\n\t\t\treturn origin;\n\t\t}\n\t} catch {\n\t\treturn undefined;\n\t}\n\treturn undefined;\n}\n\nfunction emitHttpGuardDeny(\n\treq: IncomingMessage,\n\tpathname: string,\n\tpublicMcpUrl: URL | undefined,\n): void {\n\tconsole.warn(\n\t\tJSON.stringify({\n\t\t\tsource: \"codemem-mcp-http-guard\",\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\toutcome: \"denied\",\n\t\t\treason: \"host_or_origin_mismatch\",\n\t\t\tmethod: req.method,\n\t\t\tpath: pathname,\n\t\t\thost: truncateGuardLogField(req.headers.host),\n\t\t\torigin: truncateGuardLogField(req.headers.origin),\n\t\t\texpectedOrigin: publicMcpUrl?.origin,\n\t\t\tremoteAddress: req.socket.remoteAddress ?? undefined,\n\t\t}),\n\t);\n}\n\nfunction truncateGuardLogField(value: string | undefined): string | undefined {\n\tif (!value || value.length <= MAX_GUARD_LOG_FIELD_LENGTH) return value;\n\treturn `${value.slice(0, MAX_GUARD_LOG_FIELD_LENGTH)}…`;\n}\n\nfunction isAllowedPublicRequestHost(header: string | undefined, publicMcpUrl: URL): boolean {\n\tconst parsed = parseHostHeader(header);\n\tif (!parsed) return false;\n\tconst expectedPort = publicMcpUrl.port\n\t\t? Number(publicMcpUrl.port)\n\t\t: publicMcpUrl.protocol === \"https:\"\n\t\t\t? 443\n\t\t\t: 80;\n\tconst impliedPort = publicMcpUrl.protocol === \"https:\" ? 443 : 80;\n\tconst actualPort = parsed.port ?? impliedPort;\n\treturn (\n\t\tnormalizeHost(parsed.host) === normalizeHost(publicMcpUrl.hostname) &&\n\t\tactualPort === expectedPort\n\t);\n}\n\nfunction getBoundPort(server: Server): number {\n\tconst address = server.address();\n\tif (!address || typeof address === \"string\") return DEFAULT_MCP_HTTP_PORT;\n\treturn address.port;\n}\n\nfunction formatHostForUrl(host: string): string {\n\treturn isIP(host) === 6 ? `[${host}]` : host;\n}\n\nfunction getServerUrl(server: Server, host: string): string {\n\treturn `http://${formatHostForUrl(host)}:${getBoundPort(server)}/mcp`;\n}\n\nfunction createHttpRetrievalLedgerScopeResolver(): (input: {\n\tendpoint: URL;\n\tprincipal: string | undefined;\n\trequestBody: unknown;\n\tnow: number;\n}) => string {\n\tconst scopes = new Map<string, { scopeId: string; expiresAt: number }>();\n\n\treturn (input) => {\n\t\t// Anonymous HTTP has no stable, trustworthy caller identity. Give each POST\n\t\t// its own opaque scope rather than collapsing unrelated clients that reuse\n\t\t// the same JSON-RPC id and payload. One POST still shares this scope across\n\t\t// its server execution, preserving callback-level idempotency.\n\t\tif (!input.principal) return createOpaqueHttpRetrievalLedgerScopeId(randomUUID());\n\n\t\tfor (const [key, scope] of scopes) {\n\t\t\tif (scope.expiresAt <= input.now) scopes.delete(key);\n\t\t}\n\n\t\t// Stateless HTTP has no dispatch identity beyond the authenticated\n\t\t// principal and request bytes. Exact repeats inside this bounded window\n\t\t// are therefore treated as transport retries; an intentional repeat must\n\t\t// use a new JSON-RPC id or arrive after expiry. Keep only an opaque digest,\n\t\t// and do not slide the first-observation expiry on reads.\n\t\tconst contextDigest = createHash(\"sha256\")\n\t\t\t.update(\n\t\t\t\tJSON.stringify([input.endpoint.href, input.principal, canonicalJson(input.requestBody)]),\n\t\t\t)\n\t\t\t.digest(\"hex\");\n\t\tconst existing = scopes.get(contextDigest);\n\t\tif (existing) return existing.scopeId;\n\n\t\tconst scopeId = createOpaqueHttpRetrievalLedgerScopeId(\n\t\t\tJSON.stringify([contextDigest, input.now]),\n\t\t);\n\t\tscopes.set(contextDigest, {\n\t\t\tscopeId,\n\t\t\texpiresAt: input.now + MCP_HTTP_RETRIEVAL_RETRY_WINDOW_MS,\n\t\t});\n\t\twhile (scopes.size > MCP_HTTP_RETRIEVAL_RETRY_MAX_ENTRIES) {\n\t\t\tconst oldestKey = scopes.keys().next().value;\n\t\t\tif (oldestKey === undefined) break;\n\t\t\tscopes.delete(oldestKey);\n\t\t}\n\t\treturn scopeId;\n\t};\n}\n\nfunction createOpaqueHttpRetrievalLedgerScopeId(seed: string): string {\n\treturn `mcp-http:${createHash(\"sha256\").update(seed).digest(\"hex\")}`;\n}\n\nfunction handleMcpJsonBodyError(\n\terror: unknown,\n\t_req: Request,\n\tres: Response,\n\tnext: NextFunction,\n): void {\n\tconst status = mcpJsonBodyErrorStatus(error);\n\tif (status === null) {\n\t\tnext(error);\n\t\treturn;\n\t}\n\tres.status(status).json({\n\t\tjsonrpc: \"2.0\",\n\t\terror: {\n\t\t\tcode: status === 413 ? -32_000 : -32_700,\n\t\t\tmessage: status === 413 ? \"Request body too large\" : \"Parse error\",\n\t\t},\n\t\tid: null,\n\t});\n}\n\nfunction mcpJsonBodyErrorStatus(error: unknown): 400 | 413 | null {\n\tif (error === null || typeof error !== \"object\") return null;\n\tconst bodyError = error as { type?: unknown };\n\tif (bodyError.type === \"entity.too.large\") return 413;\n\tif (bodyError.type === \"entity.parse.failed\") return 400;\n\treturn null;\n}\n\nfunction getSdkIssuerUrl(publicMcpUrl: URL, port: number): URL {\n\tif (publicMcpUrl.protocol === \"https:\") return new URL(publicMcpUrl.origin);\n\tif (isLoopbackHost(publicMcpUrl.hostname) && normalizeHost(publicMcpUrl.hostname) !== \"::1\") {\n\t\treturn new URL(publicMcpUrl.origin);\n\t}\n\treturn new URL(`http://localhost:${port}/`);\n}\n\nfunction isOAuthOrMetadataPath(pathname: string): boolean {\n\treturn (\n\t\tpathname === \"/register\" ||\n\t\tpathname === \"/authorize\" ||\n\t\tpathname === \"/token\" ||\n\t\tpathname === \"/revoke\" ||\n\t\tpathname === \"/oauth/callback\" ||\n\t\tpathname === \"/.well-known/oauth-authorization-server\" ||\n\t\tpathname === \"/.well-known/oauth-protected-resource/mcp\"\n\t);\n}\n\nfunction normalizeRoutePath(pathname: string): string {\n\treturn pathname.length > 1 ? pathname.replace(/\\/+$/, \"\") : pathname;\n}\n\nfunction auditOAuthRouteResponses(\n\tauditEmit: (event: ReturnType<typeof buildOAuthAuditEvent>) => void,\n) {\n\treturn (req: Request, res: Response, next: NextFunction) => {\n\t\tconst pathname = req.path;\n\t\tif (!isAuditedOAuthPath(pathname)) return next();\n\t\tlet responseBody: unknown;\n\t\tconst originalJson = res.json.bind(res);\n\t\tres.json = ((body: unknown) => {\n\t\t\tresponseBody = body;\n\t\t\treturn originalJson(body);\n\t\t}) as typeof res.json;\n\t\tres.on(\"finish\", () => {\n\t\t\tif (pathname === \"/oauth/callback\") return;\n\t\t\tconst kind = oauthAuditKindForRequest(pathname, req);\n\t\t\tif (!kind) return;\n\t\t\tconst error = getOAuthResponseError(res, responseBody);\n\t\t\tconst clientId = getRequestClientId(req, responseBody);\n\t\t\tauditEmit(\n\t\t\t\tbuildOAuthAuditEvent(kind, {\n\t\t\t\t\toutcome: error ? \"denied\" : \"success\",\n\t\t\t\t\t...(error ? { reason: error } : {}),\n\t\t\t\t\t...(clientId ? { clientId } : {}),\n\t\t\t\t\tremoteAddress: req.socket.remoteAddress ?? undefined,\n\t\t\t\t}),\n\t\t\t);\n\t\t});\n\t\tnext();\n\t};\n}\n\nfunction isAuditedOAuthPath(pathname: string): boolean {\n\treturn oauthAuditKindForPath(pathname) !== null;\n}\n\nfunction oauthAuditKindForRequest(\n\tpathname: string,\n\treq: Request,\n): \"registration\" | \"authorize\" | \"token\" | \"refresh\" | \"revocation\" | null {\n\tif (pathname === \"/token\" && req.body?.grant_type === \"refresh_token\") return \"refresh\";\n\treturn oauthAuditKindForPath(pathname);\n}\n\nfunction oauthAuditKindForPath(\n\tpathname: string,\n): \"registration\" | \"authorize\" | \"token\" | \"revocation\" | null {\n\tif (pathname === \"/register\") return \"registration\";\n\tif (pathname === \"/authorize\") return \"authorize\";\n\tif (pathname === \"/token\") return \"token\";\n\tif (pathname === \"/revoke\") return \"revocation\";\n\treturn null;\n}\n\nfunction getOAuthResponseError(res: Response, body: unknown): string | undefined {\n\tconst bodyError = getOAuthBodyError(body);\n\tif (bodyError) return bodyError;\n\tconst location = res.getHeader(\"location\");\n\tif (typeof location !== \"string\") return undefined;\n\ttry {\n\t\tconst redirect = new URL(location);\n\t\treturn redirect.searchParams.get(\"error\") ?? undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction getOAuthBodyError(body: unknown): string | undefined {\n\tif (\n\t\ttypeof body === \"object\" &&\n\t\tbody !== null &&\n\t\t\"error\" in body &&\n\t\ttypeof body.error === \"string\"\n\t) {\n\t\treturn body.error;\n\t}\n\treturn undefined;\n}\n\nfunction getRequestClientId(req: Request, body: unknown): string | undefined {\n\tif (\n\t\ttypeof body === \"object\" &&\n\t\tbody !== null &&\n\t\t\"client_id\" in body &&\n\t\ttypeof body.client_id === \"string\"\n\t) {\n\t\treturn body.client_id;\n\t}\n\tconst bodyClientId = typeof req.body?.client_id === \"string\" ? req.body.client_id : undefined;\n\tif (bodyClientId) return bodyClientId;\n\tconst queryClientId = typeof req.query.client_id === \"string\" ? req.query.client_id : undefined;\n\treturn queryClientId;\n}\n\nfunction auditBearerPreflight(\n\tauditEmit: (event: ReturnType<typeof buildOAuthAuditEvent>) => void,\n\ttokenStore: OAuthAccessTokenStore,\n) {\n\treturn (req: Request, _res: Response, next: NextFunction) => {\n\t\tconst reason = getBearerPreflightDenyReason(req.headers.authorization, tokenStore);\n\t\tif (reason) {\n\t\t\tauditEmit(\n\t\t\t\tbuildOAuthAuditEvent(\"bearer\", {\n\t\t\t\t\toutcome: \"denied\",\n\t\t\t\t\treason,\n\t\t\t\t\tremoteAddress: req.socket.remoteAddress ?? undefined,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t\tnext();\n\t};\n}\n\nfunction getBearerPreflightDenyReason(\n\theader: string | undefined,\n\ttokenStore: OAuthAccessTokenStore,\n): BearerDenyReason | null {\n\tif (!header) return \"missing_authorization_header\";\n\tconst [scheme, token, extra] = header.trim().split(/\\s+/);\n\tif (!scheme || !token || extra || scheme.toLowerCase() !== \"bearer\") {\n\t\treturn \"malformed_authorization_header\";\n\t}\n\tconst verification = tokenStore.verifyToken(token);\n\tif (!verification.ok) return verification.reason;\n\treturn null;\n}\n\nfunction parseScopeList(scope: string | null | undefined): string[] {\n\treturn (\n\t\tscope\n\t\t\t?.split(/\\s+/)\n\t\t\t.map((item) => item.trim())\n\t\t\t.filter(Boolean) ?? []\n\t);\n}\n\nfunction isEntrypoint(): boolean {\n\tconst script = process.argv[1];\n\treturn script ? import.meta.url === pathToFileURL(script).href : false;\n}\n\nasync function main() {\n\tconst httpServer = await startCodememMcpHttpServer();\n\tconsole.error(`codemem MCP HTTP server listening at ${httpServer.url}`);\n\n\tconst shutdown = async () => {\n\t\ttry {\n\t\t\tawait httpServer.close();\n\t\t} catch {\n\t\t\t// Best effort — process is exiting.\n\t\t}\n\t\tprocess.exit(0);\n\t};\n\n\tprocess.on(\"SIGINT\", shutdown);\n\tprocess.on(\"SIGTERM\", shutdown);\n}\n\nif (isEntrypoint()) {\n\tmain().catch((err) => {\n\t\tconsole.error(\"codemem MCP HTTP server failed to start:\", err);\n\t\tprocess.exit(1);\n\t});\n}\n"],"x_google_ignoreList":[0,1,2,3,4,5,6,7,8,9],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"http.js","names":["Address6","MemoryStore","Buffer","isIPv62","createDebugLogger"],"sources":["../../../node_modules/.pnpm/ip-address@10.7.0/node_modules/ip-address/dist/address-error.js","../../../node_modules/.pnpm/ip-address@10.7.0/node_modules/ip-address/dist/common.js","../../../node_modules/.pnpm/ip-address@10.7.0/node_modules/ip-address/dist/v4/constants.js","../../../node_modules/.pnpm/ip-address@10.7.0/node_modules/ip-address/dist/ipv4.js","../../../node_modules/.pnpm/ip-address@10.7.0/node_modules/ip-address/dist/v6/constants.js","../../../node_modules/.pnpm/ip-address@10.7.0/node_modules/ip-address/dist/v6/helpers.js","../../../node_modules/.pnpm/ip-address@10.7.0/node_modules/ip-address/dist/v6/regular-expressions.js","../../../node_modules/.pnpm/ip-address@10.7.0/node_modules/ip-address/dist/ipv6.js","../../../node_modules/.pnpm/ip-address@10.7.0/node_modules/ip-address/dist/ip-address.js","../../../node_modules/.pnpm/ms@2.1.3/node_modules/ms/index.js","../../../node_modules/.pnpm/debug@4.4.3_supports-color@10.2.2/node_modules/debug/src/common.js","../../../node_modules/.pnpm/debug@4.4.3_supports-color@10.2.2/node_modules/debug/src/browser.js","../../../node_modules/.pnpm/express-rate-limit@8.7.0_express@5.2.1_supports-color@10.2.2__supports-color@10.2.2/node_modules/express-rate-limit/dist/index.mjs","../src/audit.ts","../src/oauth.ts","../src/oidc.ts","../src/provider.ts","../src/http.ts"],"sourcesContent":["\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.AddressError = void 0;\nclass AddressError extends Error {\n constructor(message, parseMessage) {\n super(message);\n this.name = 'AddressError';\n this.parseMessage = parseMessage;\n }\n}\nexports.AddressError = AddressError;\n//# sourceMappingURL=address-error.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.isInSubnet = isInSubnet;\nexports.isHostInSubnet = isHostInSubnet;\nexports.isGloballyReachable = isGloballyReachable;\nexports.offsetBigInt = offsetBigInt;\nexports.isCorrect = isCorrect;\nexports.prefixLengthFromMask = prefixLengthFromMask;\nexports.assertByteArray = assertByteArray;\nexports.numberToPaddedHex = numberToPaddedHex;\nexports.stringToPaddedHex = stringToPaddedHex;\nexports.testBit = testBit;\nconst address_error_1 = require(\"./address-error\");\n/**\n * Returns whether this address's *network* is contained within `address`,\n * i.e. whether every address this one can represent also falls inside\n * `address`. A network wider than `address` is not contained in it, so\n * `10.0.0.0/8` is not in `10.0.0.0/16`.\n *\n * To ask whether the address itself falls inside a range, ignoring any CIDR\n * suffix it was written with, use {@link isHostInSubnet} instead. That is the\n * question the special-use classifiers ask.\n */\nfunction isInSubnet(address) {\n if (this.subnetMask < address.subnetMask) {\n return false;\n }\n return isHostInSubnet.call(this, address);\n}\n/**\n * Returns whether this address's host bits fall inside `address`, ignoring\n * this address's own subnet mask.\n *\n * This is the primitive the special-use classifiers (`isLoopback`,\n * `isPrivate`, `isLinkLocal`, `getType`, …) are built on: they answer a\n * question about the address, so the answer must not change with the CIDR\n * suffix the caller happened to write. Use this rather than\n * {@link isInSubnet} when classifying a single address — notably when the\n * address came from untrusted input and the result backs a trust-boundary\n * decision such as an SSRF allow/deny filter.\n */\nfunction isHostInSubnet(address) {\n return this.mask(address.subnetMask) === address.mask();\n}\n/**\n * Returns whether the registry marks this address globally reachable: the\n * answer of the most specific entry containing it that has one, or `true`\n * when no entry contains it.\n */\nfunction isGloballyReachable(entries) {\n let best = null;\n for (let i = 0; i < entries.length; i++) {\n const entry = entries[i];\n if (entry.reachable !== null &&\n isHostInSubnet.call(this, entry.subnet) &&\n (best === null || entry.subnet.subnetMask > best.subnet.subnetMask)) {\n best = entry;\n }\n }\n return best === null ? true : best.reachable;\n}\n/**\n * Adds `n` to `value` and returns the result, throwing `AddressError` unless\n * `n` is an integer and the result stays within `[0, 2**bits - 1]`.\n */\nfunction offsetBigInt(value, n, bits, family) {\n if (typeof n === 'number' && !Number.isSafeInteger(n)) {\n throw new address_error_1.AddressError(`${family} offset must be an integer`);\n }\n if (typeof n !== 'number' && typeof n !== 'bigint') {\n throw new address_error_1.AddressError(`${family} offset must be an integer`);\n }\n const result = value + BigInt(n);\n if (result < BigInt(0) || result > (BigInt(1) << BigInt(bits)) - BigInt(1)) {\n throw new address_error_1.AddressError(`${family} offset leaves the address space`);\n }\n return result;\n}\nfunction isCorrect(defaultBits) {\n return function isCorrectForm() {\n if (this.addressMinusSuffix !== this.correctForm()) {\n return false;\n }\n if (this.subnetMask === defaultBits && !this.parsedSubnet) {\n return true;\n }\n return this.parsedSubnet === String(this.subnetMask);\n };\n}\n/**\n * Returns the prefix length (number of leading 1 bits) of a contiguous\n * subnet mask. Throws `AddressError` if the mask is non-contiguous (e.g.\n * `255.0.255.0`).\n */\nfunction prefixLengthFromMask(value, totalBits) {\n const binary = value.toString(2).padStart(totalBits, '0');\n if (binary.length > totalBits) {\n throw new address_error_1.AddressError('Invalid subnet mask.');\n }\n const firstZero = binary.indexOf('0');\n if (firstZero === -1) {\n return totalBits;\n }\n if (binary.slice(firstZero).includes('1')) {\n throw new address_error_1.AddressError('Invalid subnet mask.');\n }\n return firstZero;\n}\n/**\n * Throws `AddressError` unless `bytes` holds exactly `byteCount` integers,\n * each from `minimum` to 255. Pass a `minimum` of `-128` where signed bytes\n * are accepted and folded to unsigned, and `0` where they are not.\n */\nfunction assertByteArray(bytes, byteCount, family, minimum) {\n if (bytes.length !== byteCount) {\n throw new address_error_1.AddressError(`${family} addresses require exactly ${byteCount} bytes`);\n }\n for (let i = 0; i < bytes.length; i++) {\n if (!Number.isInteger(bytes[i]) || bytes[i] < minimum || bytes[i] > 255) {\n throw new address_error_1.AddressError(`All bytes must be integers between ${minimum} and 255`);\n }\n }\n}\nfunction numberToPaddedHex(number) {\n return number.toString(16).padStart(2, '0');\n}\nfunction stringToPaddedHex(numberString) {\n return numberToPaddedHex(parseInt(numberString, 10));\n}\n/**\n * @param binaryValue Binary representation of a value (e.g. `10`)\n * @param position Byte position, where 0 is the least significant bit\n */\nfunction testBit(binaryValue, position) {\n const { length } = binaryValue;\n if (position > length) {\n return false;\n }\n const positionInString = length - position;\n return binaryValue.substring(positionInString, positionInString + 1) === '1';\n}\n//# sourceMappingURL=common.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.SPECIAL_PURPOSE = exports.RE_SUBNET_STRING = exports.RE_ADDRESS = exports.GROUPS = exports.BITS = void 0;\nexports.BITS = 32;\nexports.GROUPS = 4;\n// Each octet is 0-255 written without a leading zero. A leading zero is\n// octal to the WHATWG URL parser, inet_aton, and getaddrinfo, but decimal to\n// parseInt(part, 10), so accepting the notation would make this library\n// disagree with the network stack about which host a string names.\nexports.RE_ADDRESS = /^(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])$/g;\nexports.RE_SUBNET_STRING = /\\/\\d{1,2}$/;\n/**\n * The IANA IPv4 Special-Purpose Address Registry\n * (https://www.iana.org/assignments/iana-ipv4-special-registry/), one entry\n * per block: `[cidr, name, globallyReachable]`. A `null` reachability means\n * the registry leaves the column blank and the block inherits the answer of\n * the block containing it (or is global when nothing contains it).\n *\n * `Address4.isGlobal()` answers from the most specific entry containing the\n * address. `test/data/iana-corpus.json` is generated from the registry's CSV\n * and pins this table to it.\n */\nexports.SPECIAL_PURPOSE = [\n ['0.0.0.0/8', 'This network', false],\n ['0.0.0.0/32', 'This host on this network', false],\n ['10.0.0.0/8', 'Private-Use', false],\n ['100.64.0.0/10', 'Shared Address Space', false],\n ['127.0.0.0/8', 'Loopback', false],\n ['169.254.0.0/16', 'Link Local', false],\n ['172.16.0.0/12', 'Private-Use', false],\n ['192.0.0.0/24', 'IETF Protocol Assignments', false],\n ['192.0.0.0/29', 'IPv4 Service Continuity Prefix', false],\n ['192.0.0.8/32', 'IPv4 dummy address', false],\n ['192.0.0.9/32', 'Port Control Protocol Anycast', true],\n ['192.0.0.10/32', 'Traversal Using Relays around NAT Anycast', true],\n ['192.0.0.170/32', 'NAT64/DNS64 Discovery', false],\n ['192.0.0.171/32', 'NAT64/DNS64 Discovery', false],\n ['192.0.2.0/24', 'Documentation (TEST-NET-1)', false],\n ['192.31.196.0/24', 'AS112-v4', true],\n ['192.52.193.0/24', 'AMT', true],\n ['192.88.99.0/24', 'Deprecated (6to4 Relay Anycast)', null],\n ['192.88.99.2/32', '6a44-relay anycast address', false],\n ['192.168.0.0/16', 'Private-Use', false],\n ['192.175.48.0/24', 'Direct Delegation AS112 Service', true],\n ['198.18.0.0/15', 'Benchmarking', false],\n ['198.51.100.0/24', 'Documentation (TEST-NET-2)', false],\n ['203.0.113.0/24', 'Documentation (TEST-NET-3)', false],\n ['240.0.0.0/4', 'Reserved', false],\n ['255.255.255.255/32', 'Limited Broadcast', false],\n];\n//# sourceMappingURL=constants.js.map","\"use strict\";\n/* eslint-disable no-param-reassign */\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.Address4 = void 0;\nconst common = __importStar(require(\"./common\"));\nconst constants = __importStar(require(\"./v4/constants\"));\nconst address_error_1 = require(\"./address-error\");\nconst isCorrect4 = common.isCorrect(constants.BITS);\n/**\n * Represents an IPv4 address\n * @param {string} address - An IPv4 address string\n */\nclass Address4 {\n constructor(address) {\n this.addressMinusSuffix = '';\n this.groups = constants.GROUPS;\n this.parsedAddress = [];\n this.parsedSubnet = '';\n this.subnet = '/32';\n this.subnetMask = 32;\n this.v4 = true;\n /**\n * Returns true if the address is correct, false otherwise\n * @returns {Boolean}\n */\n this.isCorrect = isCorrect4;\n /**\n * Returns true if the given address is in the subnet of the current address\n * @returns {boolean}\n */\n this.isInSubnet = common.isInSubnet;\n /**\n * Returns true if this address's host bits fall inside the given subnet,\n * ignoring this address's own subnet mask. Prefer this over `isInSubnet`\n * when classifying a single address, so the answer doesn't change with the\n * CIDR suffix the caller happened to write — notably when the address came\n * from untrusted input and the result backs a trust-boundary decision.\n * @returns {boolean}\n */\n this.isHostInSubnet = common.isHostInSubnet;\n this.address = address;\n const subnet = constants.RE_SUBNET_STRING.exec(address);\n if (subnet) {\n this.parsedSubnet = subnet[0].replace('/', '');\n this.subnetMask = parseInt(this.parsedSubnet, 10);\n this.subnet = `/${this.subnetMask}`;\n if (this.subnetMask < 0 || this.subnetMask > constants.BITS) {\n throw new address_error_1.AddressError('Invalid subnet mask.');\n }\n address = address.replace(constants.RE_SUBNET_STRING, '');\n }\n this.addressMinusSuffix = address;\n this.parsedAddress = this.parse(address);\n }\n /**\n * Returns true if the given string is a valid IPv4 address (with optional\n * CIDR subnet), false otherwise. Host bits in the subnet portion are\n * allowed (e.g. `192.168.1.5/24` is valid); for strict network-address\n * validation compare `correctForm()` to `startAddress().correctForm()`,\n * or use `networkForm()`.\n */\n static isValid(address) {\n try {\n // eslint-disable-next-line no-new\n new Address4(address);\n return true;\n }\n catch {\n return false;\n }\n }\n /**\n * Parses an IPv4 address string into its four octet groups and stores the\n * result on `this.parsedAddress`. Called automatically by the constructor;\n * you typically don't need to call it directly. Throws `AddressError` if\n * the input is not a valid IPv4 address.\n */\n parse(address) {\n const groups = address.split('.');\n // Checked before the general match so the error names the actual problem.\n // Address6 rejects the same notation on its v4-in-v6 path.\n if (groups.some((group) => /^0\\d/.test(group))) {\n throw new address_error_1.AddressError(\"IPv4 addresses can't have leading zeroes.\");\n }\n if (!address.match(constants.RE_ADDRESS)) {\n throw new address_error_1.AddressError('Invalid IPv4 address.');\n }\n return groups;\n }\n /**\n * Returns the address in correct form: octets joined with `.` and any\n * leading zeros stripped (e.g. `192.168.1.1`). For IPv4 this matches the\n * canonical dotted-decimal representation.\n */\n correctForm() {\n return this.parsedAddress.map((part) => parseInt(part, 10)).join('.');\n }\n /**\n * Construct an `Address4` from an address and a dotted-decimal subnet\n * mask given as separate strings (e.g. as returned by Node's\n * `os.networkInterfaces()`). Throws `AddressError` if the mask is\n * non-contiguous (e.g. `255.0.255.0`).\n * @example\n * var address = Address4.fromAddressAndMask('192.168.1.1', '255.255.255.0');\n * address.subnetMask; // 24\n */\n static fromAddressAndMask(address, mask) {\n const bits = common.prefixLengthFromMask(new Address4(mask).bigInt(), constants.BITS);\n return new Address4(`${address}/${bits}`);\n }\n /**\n * Construct an `Address4` from an address and a Cisco-style wildcard mask\n * given as separate strings (e.g. `0.0.0.255` for a `/24`). The wildcard\n * mask is the bitwise inverse of the subnet mask. Throws `AddressError`\n * if the mask is non-contiguous (e.g. `0.255.0.255`).\n * @example\n * var address = Address4.fromAddressAndWildcardMask('10.0.0.1', '0.0.0.255');\n * address.subnetMask; // 24\n */\n static fromAddressAndWildcardMask(address, wildcardMask) {\n const wildcard = new Address4(wildcardMask).bigInt();\n const allOnes = (BigInt(1) << BigInt(constants.BITS)) - BigInt(1);\n const mask = wildcard ^ allOnes;\n const bits = common.prefixLengthFromMask(mask, constants.BITS);\n return new Address4(`${address}/${bits}`);\n }\n /**\n * Construct an `Address4` from a wildcard pattern with trailing `*`\n * octets. The number of trailing wildcards determines the prefix\n * length: each `*` represents 8 bits.\n *\n * Only trailing whole-octet wildcards are supported. Partial-octet\n * wildcards (e.g. `192.168.0.1*`) and interior wildcards (e.g.\n * `192.*.0.1`) throw `AddressError`.\n * @example\n * Address4.fromWildcard('192.168.0.*').subnet; // '/24'\n * Address4.fromWildcard('192.168.*.*').subnet; // '/16'\n * Address4.fromWildcard('*.*.*.*').subnet; // '/0'\n */\n static fromWildcard(input) {\n const groups = input.split('.');\n if (groups.length !== constants.GROUPS) {\n throw new address_error_1.AddressError('Wildcard pattern must have 4 octets');\n }\n let firstWildcard = -1;\n for (let i = 0; i < groups.length; i++) {\n if (groups[i] === '*') {\n if (firstWildcard === -1) {\n firstWildcard = i;\n }\n }\n else if (firstWildcard !== -1) {\n throw new address_error_1.AddressError('Wildcard `*` must only appear in trailing octets (e.g. `192.168.0.*`)');\n }\n }\n const trailing = firstWildcard === -1 ? 0 : groups.length - firstWildcard;\n const replaced = groups.map((g) => (g === '*' ? '0' : g));\n const subnetBits = constants.BITS - trailing * 8;\n return new Address4(`${replaced.join('.')}/${subnetBits}`);\n }\n /**\n * Converts a hex string to an IPv4 address object. Accepts 8 hex digits\n * with optional `:` separators (e.g. `'7f000001'` or `'7f:00:00:01'`).\n * Throws `AddressError` for any other length or for non-hex characters.\n * @param {string} hex - a hex string to convert\n * @returns {Address4}\n */\n static fromHex(hex) {\n const stripped = hex.replace(/:/g, '');\n if (!/^[0-9a-fA-F]{8}$/.test(stripped)) {\n throw new address_error_1.AddressError('IPv4 hex must be exactly 8 hex digits');\n }\n const groups = [];\n for (let i = 0; i < 8; i += 2) {\n groups.push(parseInt(stripped.slice(i, i + 2), 16));\n }\n return new Address4(groups.join('.'));\n }\n /**\n * Converts an integer into a IPv4 address object. The integer must be a\n * non-negative safe integer in the range `[0, 2**32 - 1]`; otherwise\n * `AddressError` is thrown.\n * @param {integer} integer - a number to convert\n * @returns {Address4}\n */\n static fromInteger(integer) {\n if (!Number.isInteger(integer) || integer < 0 || integer > 0xffffffff) {\n throw new address_error_1.AddressError('IPv4 integer must be in the range 0 to 2**32 - 1');\n }\n return Address4.fromHex(integer.toString(16).padStart(8, '0'));\n }\n /**\n * Return an address from in-addr.arpa form\n * @param {string} arpaFormAddress - an 'in-addr.arpa' form ipv4 address\n * @returns {Adress4}\n * @example\n * var address = Address4.fromArpa(42.2.0.192.in-addr.arpa.)\n * address.correctForm(); // '192.0.2.42'\n */\n static fromArpa(arpaFormAddress) {\n // remove ending \".in-addr.arpa.\" or just \".\"\n const leader = arpaFormAddress.replace(/(\\.in-addr\\.arpa)?\\.$/, '');\n const address = leader.split('.').reverse().join('.');\n return new Address4(address);\n }\n /**\n * Converts an IPv4 address object to a hex string\n * @returns {String}\n */\n toHex() {\n return this.parsedAddress.map((part) => common.stringToPaddedHex(part)).join(':');\n }\n /**\n * Converts an IPv4 address object to an array of bytes.\n *\n * To get a Node.js `Buffer`, wrap the result: `Buffer.from(address.toArray())`.\n * @returns {Array}\n */\n toArray() {\n return this.parsedAddress.map((part) => parseInt(part, 10));\n }\n /**\n * Converts an IPv4 address object to an IPv6 address group\n * @returns {String}\n */\n toGroup6() {\n const output = [];\n let i;\n for (i = 0; i < constants.GROUPS; i += 2) {\n output.push(`${common.stringToPaddedHex(this.parsedAddress[i])}${common.stringToPaddedHex(this.parsedAddress[i + 1])}`);\n }\n return output.join(':');\n }\n /**\n * Returns the address as a `bigint`\n * @returns {bigint}\n */\n bigInt() {\n return BigInt(`0x${this.parsedAddress.map((n) => common.stringToPaddedHex(n)).join('')}`);\n }\n /**\n * Helper function getting start address.\n * @returns {bigint}\n */\n _startAddress() {\n return BigInt(`0b${this.mask() + '0'.repeat(constants.BITS - this.subnetMask)}`);\n }\n /**\n * The first address in the range given by this address' subnet.\n * Often referred to as the Network Address.\n * @returns {Address4}\n */\n startAddress() {\n return Address4.fromBigInt(this._startAddress());\n }\n /**\n * The first host address in the range given by this address's subnet ie\n * the first address after the Network Address\n * @returns {Address4}\n */\n startAddressExclusive() {\n const adjust = BigInt('1');\n return Address4.fromBigInt(this._startAddress() + adjust);\n }\n /**\n * Returns the address `n` addresses after this one (or before, when `n` is\n * negative), keeping this address's subnet mask. Throws `AddressError` when\n * the result would fall outside the IPv4 address space or `n` is not an\n * integer.\n * @param {number | bigint} n\n * @returns {Address4}\n * @example\n * new Address4('10.0.0.0/24').offset(1).correctForm(); // '10.0.0.1'\n */\n offset(n) {\n return Address4.fromBigInt(common.offsetBigInt(this.bigInt(), n, constants.BITS, 'IPv4')).withSubnetMask(this.subnetMask);\n }\n /**\n * Returns the network that follows this address's network: the address after\n * {@link endAddress}, with the same subnet mask. Throws `AddressError` when\n * this network is the last one in the address space.\n * @returns {Address4}\n * @example\n * new Address4('10.0.0.0/24').nextNetwork().networkForm(); // '10.0.1.0/24'\n */\n nextNetwork() {\n return Address4.fromBigInt(common.offsetBigInt(this._endAddress(), 1, constants.BITS, 'IPv4')).withSubnetMask(this.subnetMask);\n }\n withSubnetMask(subnetMask) {\n return new Address4(`${this.correctForm()}/${subnetMask}`);\n }\n /**\n * Helper function getting end address.\n * @returns {bigint}\n */\n _endAddress() {\n return BigInt(`0b${this.mask() + '1'.repeat(constants.BITS - this.subnetMask)}`);\n }\n /**\n * The last address in the range given by this address' subnet\n * Often referred to as the Broadcast\n * @returns {Address4}\n */\n endAddress() {\n return Address4.fromBigInt(this._endAddress());\n }\n /**\n * The last host address in the range given by this address's subnet ie\n * the last address prior to the Broadcast Address\n * @returns {Address4}\n */\n endAddressExclusive() {\n const adjust = BigInt('1');\n return Address4.fromBigInt(this._endAddress() - adjust);\n }\n /**\n * The dotted-decimal form of the subnet mask, e.g. `255.255.240.0` for\n * a `/20`. Returns an `Address4`; call `.correctForm()` for the string.\n * @returns {Address4}\n */\n subnetMaskAddress() {\n return Address4.fromBigInt(BigInt(`0b${'1'.repeat(this.subnetMask)}${'0'.repeat(constants.BITS - this.subnetMask)}`));\n }\n /**\n * The Cisco-style wildcard mask, e.g. `0.0.0.255` for a `/24`. This is\n * the bitwise inverse of `subnetMaskAddress()`. Returns an `Address4`;\n * call `.correctForm()` for the string.\n * @returns {Address4}\n */\n wildcardMask() {\n return Address4.fromBigInt(BigInt(`0b${'0'.repeat(this.subnetMask)}${'1'.repeat(constants.BITS - this.subnetMask)}`));\n }\n /**\n * The network address in CIDR string form, e.g. `192.168.1.0/24` for\n * `192.168.1.5/24`. For an address with no explicit subnet the prefix is\n * `/32`, e.g. `networkForm()` on `192.168.1.5` returns `192.168.1.5/32`.\n * @returns {string}\n */\n networkForm() {\n return `${this.startAddress().correctForm()}/${this.subnetMask}`;\n }\n /**\n * Converts a BigInt to a v4 address object. The value must be in the\n * range `[0, 2**32 - 1]`; otherwise `AddressError` is thrown.\n * @param {bigint} bigInt - a BigInt to convert\n * @returns {Address4}\n */\n static fromBigInt(bigInt) {\n if (bigInt < BigInt(0) || bigInt > BigInt(0xffffffff)) {\n throw new address_error_1.AddressError('IPv4 BigInt must be in the range 0 to 2**32 - 1');\n }\n return Address4.fromHex(bigInt.toString(16).padStart(8, '0'));\n }\n /**\n * Convert a byte array to an Address4 object. Throws `AddressError` unless\n * given exactly 4 integers from 0 to 255. Signed bytes are rejected, so\n * this differs from `Address6.fromByteArray`, which folds them; the two\n * contracts converge on this stricter form in the next major version.\n *\n * To convert from a Node.js `Buffer`, spread it: `Address4.fromByteArray([...buf])`.\n * @param {Array<number>} bytes - an array of 4 bytes (0-255)\n * @returns {Address4}\n */\n static fromByteArray(bytes) {\n common.assertByteArray(bytes, 4, 'IPv4', 0);\n return this.fromUnsignedByteArray(bytes);\n }\n /**\n * Convert an unsigned byte array to an Address4 object. Throws\n * `AddressError` unless given exactly 4 bytes, and rejects values outside\n * 0 to 255 when parsing the resulting address.\n *\n * To convert from a Node.js `Buffer`, spread it:\n * `Address4.fromUnsignedByteArray([...buf])`.\n * @param {Array<number>} bytes - an array of 4 unsigned bytes (0-255)\n * @returns {Address4}\n */\n static fromUnsignedByteArray(bytes) {\n if (bytes.length !== 4) {\n throw new address_error_1.AddressError('IPv4 addresses require exactly 4 bytes');\n }\n const address = bytes.join('.');\n return new Address4(address);\n }\n /**\n * Returns the first n bits of the address, defaulting to the\n * subnet mask\n * @returns {String}\n */\n mask(mask) {\n if (mask === undefined) {\n mask = this.subnetMask;\n }\n return this.getBitsBase2(0, mask);\n }\n /**\n * Returns the bits in the given range as a base-2 string\n * @returns {string}\n */\n getBitsBase2(start, end) {\n return this.binaryZeroPad().slice(start, end);\n }\n /**\n * Return the reversed in-addr.arpa form of the address, e.g.\n * `42.2.0.192.in-addr.arpa.` for `192.0.2.42`.\n * @param {Object} options\n * @param {boolean} options.omitSuffix - omit the \"in-addr.arpa\" suffix\n * @returns {String}\n */\n reverseForm(options) {\n if (!options) {\n options = {};\n }\n const reversed = this.correctForm().split('.').reverse().join('.');\n if (options.omitSuffix) {\n return reversed;\n }\n return `${reversed}.in-addr.arpa.`;\n }\n /**\n * Returns true if the given address is a multicast address\n * @returns {boolean}\n */\n isMulticast() {\n return this.isHostInSubnet(MULTICAST_V4);\n }\n /**\n * Returns true if the address is in one of the [RFC 1918](https://datatracker.ietf.org/doc/html/rfc1918) private address ranges (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`).\n * @returns {boolean}\n */\n isPrivate() {\n return PRIVATE_V4.some((subnet) => this.isHostInSubnet(subnet));\n }\n /**\n * Returns true if the address is in the loopback range `127.0.0.0/8` ([RFC 1122](https://datatracker.ietf.org/doc/html/rfc1122)).\n * @returns {boolean}\n */\n isLoopback() {\n return this.isHostInSubnet(LOOPBACK_V4);\n }\n /**\n * Returns true if the address is in the link-local range `169.254.0.0/16` ([RFC 3927](https://datatracker.ietf.org/doc/html/rfc3927)).\n * @returns {boolean}\n */\n isLinkLocal() {\n return this.isHostInSubnet(LINK_LOCAL_V4);\n }\n /**\n * Returns true if the address is the unspecified address `0.0.0.0`.\n * @returns {boolean}\n */\n isUnspecified() {\n return this.isHostInSubnet(UNSPECIFIED_V4);\n }\n /**\n * Returns true if the address is the limited broadcast address `255.255.255.255` ([RFC 919](https://datatracker.ietf.org/doc/html/rfc919)).\n * @returns {boolean}\n */\n isBroadcast() {\n return this.isHostInSubnet(BROADCAST_V4);\n }\n /**\n * Returns true if the address is in the carrier-grade NAT range `100.64.0.0/10` ([RFC 6598](https://datatracker.ietf.org/doc/html/rfc6598)).\n * @returns {boolean}\n */\n isCGNAT() {\n return this.isHostInSubnet(CGNAT_V4);\n }\n /**\n * Returns true if the address is in one of the documentation ranges\n * `192.0.2.0/24`, `198.51.100.0/24`, or `203.0.113.0/24` ([RFC 5737](https://datatracker.ietf.org/doc/html/rfc5737)).\n * @returns {boolean}\n */\n isDocumentation() {\n return DOCUMENTATION_V4.some((subnet) => this.isHostInSubnet(subnet));\n }\n /**\n * Returns true if the address is in the benchmarking range `198.18.0.0/15` ([RFC 2544](https://datatracker.ietf.org/doc/html/rfc2544)).\n * @returns {boolean}\n */\n isBenchmarking() {\n return this.isHostInSubnet(BENCHMARKING_V4);\n }\n /**\n * Returns true if the address is in the reserved range `240.0.0.0/4` ([RFC 1112](https://datatracker.ietf.org/doc/html/rfc1112)),\n * which includes the limited broadcast address.\n * @returns {boolean}\n */\n isReserved() {\n return this.isHostInSubnet(RESERVED_V4);\n }\n /**\n * Returns true if the address is globally reachable: not multicast, and not\n * in any block the [IANA IPv4 Special-Purpose Address Registry](https://www.iana.org/assignments/iana-ipv4-special-registry/)\n * marks as not globally reachable. That covers everything the individual\n * classifiers name (private, loopback, link-local, CGNAT, unspecified,\n * broadcast, documentation, benchmarking, reserved) and the blocks they do\n * not, such as `0.0.0.0/8` and the IETF protocol assignments in\n * `192.0.0.0/24`. This is the single predicate to use where a request must\n * not reach an internal or special-purpose destination; see SECURITY.md.\n * @returns {boolean}\n */\n isGlobal() {\n return !this.isMulticast() && common.isGloballyReachable.call(this, SPECIAL_PURPOSE_V4);\n }\n /**\n * Returns a zero-padded base-2 string representation of the address\n * @returns {string}\n */\n binaryZeroPad() {\n if (this._binaryZeroPad === undefined) {\n this._binaryZeroPad = this.bigInt().toString(2).padStart(constants.BITS, '0');\n }\n return this._binaryZeroPad;\n }\n /**\n * Groups an IPv4 address for inclusion at the end of an IPv6 address.\n *\n * Returns an HTML fragment: each half of the address is wrapped in a\n * `<span>` carrying the group classes an address-inspector UI hovers on.\n * The address content is HTML-escaped; anything you concatenate around it\n * is your responsibility.\n * @returns {String}\n */\n groupForV6() {\n const segments = this.parsedAddress;\n return this.correctForm().replace(constants.RE_ADDRESS, `<span class=\"hover-group group-v4 group-6\">${segments\n .slice(0, 2)\n .join('.')}</span>.<span class=\"hover-group group-v4 group-7\">${segments\n .slice(2, 4)\n .join('.')}</span>`);\n }\n}\nexports.Address4 = Address4;\nconst MULTICAST_V4 = new Address4('224.0.0.0/4');\nconst PRIVATE_V4 = [\n new Address4('10.0.0.0/8'),\n new Address4('172.16.0.0/12'),\n new Address4('192.168.0.0/16'),\n];\nconst LOOPBACK_V4 = new Address4('127.0.0.0/8');\nconst LINK_LOCAL_V4 = new Address4('169.254.0.0/16');\nconst UNSPECIFIED_V4 = new Address4('0.0.0.0/32');\nconst BROADCAST_V4 = new Address4('255.255.255.255/32');\nconst CGNAT_V4 = new Address4('100.64.0.0/10');\nconst DOCUMENTATION_V4 = [\n new Address4('192.0.2.0/24'),\n new Address4('198.51.100.0/24'),\n new Address4('203.0.113.0/24'),\n];\nconst BENCHMARKING_V4 = new Address4('198.18.0.0/15');\nconst RESERVED_V4 = new Address4('240.0.0.0/4');\nconst SPECIAL_PURPOSE_V4 = constants.SPECIAL_PURPOSE.map(([cidr, , reachable]) => ({\n subnet: new Address4(cidr),\n reachable,\n}));\n//# sourceMappingURL=ipv4.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.SPECIAL_PURPOSE = exports.RE_URL_WITH_PORT = exports.RE_URL = exports.RE_ZONE_STRING = exports.RE_SUBNET_STRING = exports.RE_BAD_ADDRESS = exports.RE_BAD_CHARACTERS = exports.TYPES = exports.SCOPES = exports.GROUPS = exports.BITS = void 0;\nexports.BITS = 128;\nexports.GROUPS = 8;\n/**\n * Represents IPv6 address scopes\n * @memberof Address6\n * @static\n */\nexports.SCOPES = {\n 0: 'Reserved',\n 1: 'Interface local',\n 2: 'Link local',\n 4: 'Admin local',\n 5: 'Site local',\n 8: 'Organization local',\n 14: 'Global',\n 15: 'Reserved',\n};\n/**\n * Represents IPv6 address types\n * @memberof Address6\n * @static\n */\nexports.TYPES = {\n 'ff01::1/128': 'Multicast (All nodes on this interface)',\n 'ff01::2/128': 'Multicast (All routers on this interface)',\n 'ff02::1/128': 'Multicast (All nodes on this link)',\n 'ff02::2/128': 'Multicast (All routers on this link)',\n 'ff05::2/128': 'Multicast (All routers in this site)',\n 'ff02::5/128': 'Multicast (OSPFv3 AllSPF routers)',\n 'ff02::6/128': 'Multicast (OSPFv3 AllDR routers)',\n 'ff02::9/128': 'Multicast (RIP routers)',\n 'ff02::a/128': 'Multicast (EIGRP routers)',\n 'ff02::d/128': 'Multicast (PIM routers)',\n 'ff02::16/128': 'Multicast (MLDv2 reports)',\n 'ff01::fb/128': 'Multicast (mDNSv6)',\n 'ff02::fb/128': 'Multicast (mDNSv6)',\n 'ff05::fb/128': 'Multicast (mDNSv6)',\n 'ff02::1:2/128': 'Multicast (All DHCP servers and relay agents on this link)',\n 'ff05::1:2/128': 'Multicast (All DHCP servers and relay agents in this site)',\n 'ff02::1:3/128': 'Multicast (All DHCP servers on this link)',\n 'ff05::1:3/128': 'Multicast (All DHCP servers in this site)',\n '::/128': 'Unspecified',\n '::1/128': 'Loopback',\n '::ffff:0:0/96': 'IPv4-mapped',\n 'ff00::/8': 'Multicast',\n 'fe80::/10': 'Link-local unicast',\n 'fc00::/7': 'Unique local',\n '2001::/32': 'Teredo',\n '2001:2::/48': 'Benchmarking',\n '2002::/16': '6to4',\n '2001:db8::/32': 'Documentation',\n '3fff::/20': 'Documentation',\n '100::/64': 'Discard-only',\n 'fec0::/10': 'Site-local unicast (deprecated)',\n '::/96': 'IPv4-compatible (deprecated)',\n '64:ff9b::/96': 'NAT64 (well-known)',\n '64:ff9b:1::/48': 'NAT64 (local-use)',\n};\n/**\n * A regular expression that matches bad characters in an IPv6 address\n * @memberof Address6\n * @static\n */\nexports.RE_BAD_CHARACTERS = /([^0-9a-f:/%])/gi;\n/**\n * A regular expression that matches an incorrect IPv6 address\n * @memberof Address6\n * @static\n */\nexports.RE_BAD_ADDRESS = /([0-9a-f]{5,}|:{3,}|[^:]:$|^:[^:]|\\/$)/gi;\n/**\n * A regular expression that matches an IPv6 subnet\n * @memberof Address6\n * @static\n */\nexports.RE_SUBNET_STRING = /\\/\\d{1,3}(?=%|$)/;\n/**\n * A regular expression that matches an IPv6 zone\n * @memberof Address6\n * @static\n */\nexports.RE_ZONE_STRING = /%.*$/;\nexports.RE_URL = /^(?:\\[([0-9a-f:.]+)\\]|([0-9a-f:.]+))(?:[/?#].*)?$/i;\nexports.RE_URL_WITH_PORT = /^\\[([0-9a-f:.]+)\\]:([0-9]{1,5})(?:[/?#].*)?$/i;\n/**\n * The IANA IPv6 Special-Purpose Address Registry\n * (https://www.iana.org/assignments/iana-ipv6-special-registry/), one entry\n * per block: `[cidr, name, globallyReachable]`. A `null` reachability means\n * the registry says N/A or leaves the column blank; N/A blocks (Teredo, 6to4)\n * are treated as not globally reachable, since a packet to one needs a relay,\n * and blank blocks inherit the answer of the block containing them.\n *\n * `Address6.isGlobal()` answers from the most specific entry containing the\n * address, after delegating IPv4-mapped and NAT64 well-known addresses to the\n * embedded IPv4 address. `test/data/iana-corpus.json` is generated from the\n * registry's CSV and pins this table to it.\n */\nexports.SPECIAL_PURPOSE = [\n ['::1/128', 'Loopback Address', false],\n ['::/128', 'Unspecified Address', false],\n ['::ffff:0:0/96', 'IPv4-mapped Address', false],\n ['64:ff9b::/96', 'IPv4-IPv6 Translat.', true],\n ['64:ff9b:1::/48', 'IPv4-IPv6 Translat.', false],\n ['100::/64', 'Discard-Only Address Block', false],\n ['100:0:0:1::/64', 'Dummy IPv6 Prefix', false],\n ['2001::/23', 'IETF Protocol Assignments', false],\n ['2001::/32', 'TEREDO', false],\n ['2001:1::1/128', 'Port Control Protocol Anycast', true],\n ['2001:1::2/128', 'Traversal Using Relays around NAT Anycast', true],\n ['2001:1::3/128', 'DNS-SD Service Registration Protocol Anycast', true],\n ['2001:2::/48', 'Benchmarking', false],\n ['2001:3::/32', 'AMT', true],\n ['2001:4:112::/48', 'AS112-v6', true],\n ['2001:10::/28', 'Deprecated (previously ORCHID)', null],\n ['2001:20::/28', 'ORCHIDv2', true],\n ['2001:30::/28', 'Drone Remote ID Protocol Entity Tags (DETs) Prefix', true],\n ['2001:db8::/32', 'Documentation', false],\n ['2002::/16', '6to4', false],\n ['2620:4f:8000::/48', 'Direct Delegation AS112 Service', true],\n ['3fff::/20', 'Documentation', false],\n ['5f00::/16', 'Segment Routing (SRv6) SIDs', false],\n ['fc00::/7', 'Unique-Local', false],\n ['fe80::/10', 'Link-Local Unicast', false],\n];\n//# sourceMappingURL=constants.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.escapeHtml = escapeHtml;\nexports.spanAllZeroes = spanAllZeroes;\nexports.spanAll = spanAll;\nexports.spanLeadingZeroes = spanLeadingZeroes;\nexports.simpleGroup = simpleGroup;\nfunction escapeHtml(s) {\n return s\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n/**\n * @returns {String} the string with all zeroes contained in a <span>\n */\nfunction spanAllZeroes(s) {\n return escapeHtml(s).replace(/(0+)/g, '<span class=\"zero\">$1</span>');\n}\n/**\n * @returns {String} the string with each character contained in a <span>\n */\nfunction spanAll(s, offset = 0) {\n const letters = s.split('');\n return letters\n .map((n, i) => `<span class=\"digit value-${escapeHtml(n)} position-${i + offset}\">${spanAllZeroes(n)}</span>`)\n .join('');\n}\nfunction spanLeadingZeroesSimple(group) {\n return escapeHtml(group).replace(/^(0+)/, '<span class=\"zero\">$1</span>');\n}\n/**\n * @returns {String} the string with leading zeroes contained in a <span>\n */\nfunction spanLeadingZeroes(address) {\n const groups = address.split(':');\n return groups.map((g) => spanLeadingZeroesSimple(g)).join(':');\n}\n/**\n * Groups an address\n * @returns {String} a grouped address\n */\nfunction simpleGroup(addressString, offset = 0) {\n const groups = addressString.split(':');\n return groups.map((g, i) => {\n if (/group-v4/.test(g)) {\n return g;\n }\n return `<span class=\"hover-group group-${i + offset}\">${spanLeadingZeroesSimple(g)}</span>`;\n });\n}\n//# sourceMappingURL=helpers.js.map","\"use strict\";\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.ADDRESS_BOUNDARY = void 0;\nexports.groupPossibilities = groupPossibilities;\nexports.padGroup = padGroup;\nexports.simpleRegularExpression = simpleRegularExpression;\nexports.possibleElisions = possibleElisions;\nconst v6 = __importStar(require(\"./constants\"));\nfunction groupPossibilities(possibilities) {\n return `(${possibilities.join('|')})`;\n}\nfunction padGroup(group) {\n if (group.length < 4) {\n return `0{0,${4 - group.length}}${group}`;\n }\n return group;\n}\nexports.ADDRESS_BOUNDARY = '[^A-Fa-f0-9:]';\nfunction simpleRegularExpression(groups) {\n const zeroIndexes = [];\n groups.forEach((group, i) => {\n const groupInteger = parseInt(group, 16);\n if (groupInteger === 0) {\n zeroIndexes.push(i);\n }\n });\n // You can technically elide a single 0, this creates the regular expressions\n // to match that eventuality\n const possibilities = zeroIndexes.map((zeroIndex) => groups\n .map((group, i) => {\n if (i === zeroIndex) {\n const elision = i === 0 || i === v6.GROUPS - 1 ? ':' : '';\n return groupPossibilities([padGroup(group), elision]);\n }\n return padGroup(group);\n })\n .join(':'));\n // The simplest case\n possibilities.push(groups.map(padGroup).join(':'));\n return groupPossibilities(possibilities);\n}\nfunction possibleElisions(elidedGroups, moreLeft, moreRight) {\n const left = moreLeft ? '' : ':';\n const right = moreRight ? '' : ':';\n const possibilities = [];\n // 1. elision of everything (::)\n if (!moreLeft && !moreRight) {\n possibilities.push('::');\n }\n // 2. complete elision of the middle\n if (moreLeft && moreRight) {\n possibilities.push('');\n }\n if ((moreRight && !moreLeft) || (!moreRight && moreLeft)) {\n // 3. complete elision of one side\n possibilities.push(':');\n }\n // 4. elision from the left side\n possibilities.push(`${left}(:0{1,4}){1,${elidedGroups - 1}}`);\n // 5. elision from the right side\n possibilities.push(`(0{1,4}:){1,${elidedGroups - 1}}${right}`);\n // 6. no elision\n possibilities.push(`(0{1,4}:){${elidedGroups - 1}}0{1,4}`);\n // 7. elision (including sloppy elision) from the middle\n for (let groups = 1; groups < elidedGroups - 1; groups++) {\n for (let position = 1; position < elidedGroups - groups; position++) {\n possibilities.push(`(0{1,4}:){${position}}:(0{1,4}:){${elidedGroups - position - groups - 1}}0{1,4}`);\n }\n }\n return groupPossibilities(possibilities);\n}\n//# sourceMappingURL=regular-expressions.js.map","\"use strict\";\n/* eslint-disable prefer-destructuring */\n/* eslint-disable no-param-reassign */\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.Address6 = void 0;\nconst common = __importStar(require(\"./common\"));\nconst constants4 = __importStar(require(\"./v4/constants\"));\nconst constants6 = __importStar(require(\"./v6/constants\"));\nconst helpers = __importStar(require(\"./v6/helpers\"));\nconst ipv4_1 = require(\"./ipv4\");\nconst regular_expressions_1 = require(\"./v6/regular-expressions\");\nconst address_error_1 = require(\"./address-error\");\nconst common_1 = require(\"./common\");\nconst isCorrect6 = common.isCorrect(constants6.BITS);\nfunction assert(condition) {\n if (!condition) {\n throw new Error('Assertion failed.');\n }\n}\nfunction addCommas(number) {\n const r = /(\\d+)(\\d{3})/;\n while (r.test(number)) {\n number = number.replace(r, '$1,$2');\n }\n return number;\n}\nfunction spanLeadingZeroes4(n) {\n n = n.replace(/^(0{1,})([1-9]+)$/, '<span class=\"parse-error\">$1</span>$2');\n n = n.replace(/^(0{1,})(0)$/, '<span class=\"parse-error\">$1</span>$2');\n return n;\n}\n/*\n * A helper function to compact an array\n */\nfunction compact(address, slice) {\n const s1 = [];\n const s2 = [];\n let i;\n for (i = 0; i < address.length; i++) {\n if (i < slice[0]) {\n s1.push(address[i]);\n }\n else if (i > slice[1]) {\n s2.push(address[i]);\n }\n }\n return s1.concat(['compact']).concat(s2);\n}\nfunction paddedHex(octet) {\n return parseInt(octet, 16).toString(16).padStart(4, '0');\n}\nfunction unsignByte(b) {\n return b & 0xff;\n}\n/**\n * Represents an IPv6 address\n * @param {string} address - An IPv6 address string\n * @param {number} [groups=8] - How many octets to parse\n * @example\n * var address = new Address6('2001::/32');\n */\nclass Address6 {\n constructor(address, optionalGroups) {\n this.addressMinusSuffix = '';\n this.parsedSubnet = '';\n this.subnet = '/128';\n this.subnetMask = 128;\n this.v4 = false;\n this.zone = '';\n // #region Attributes\n /**\n * Returns true if the given address is in the subnet of the current address\n * @returns {boolean}\n */\n this.isInSubnet = common.isInSubnet;\n /**\n * Returns true if this address's host bits fall inside the given subnet,\n * ignoring this address's own subnet mask. Prefer this over `isInSubnet`\n * when classifying a single address, so the answer doesn't change with the\n * CIDR suffix the caller happened to write — notably when the address came\n * from untrusted input and the result backs a trust-boundary decision.\n * @returns {boolean}\n */\n this.isHostInSubnet = common.isHostInSubnet;\n /**\n * Returns true if the address is correct, false otherwise\n * @returns {boolean}\n */\n this.isCorrect = isCorrect6;\n if (optionalGroups === undefined) {\n this.groups = constants6.GROUPS;\n }\n else {\n this.groups = optionalGroups;\n }\n this.address = address;\n const subnet = constants6.RE_SUBNET_STRING.exec(address);\n if (subnet) {\n this.parsedSubnet = subnet[0].replace('/', '');\n this.subnetMask = parseInt(this.parsedSubnet, 10);\n this.subnet = `/${this.subnetMask}`;\n if (Number.isNaN(this.subnetMask) ||\n this.subnetMask < 0 ||\n this.subnetMask > constants6.BITS) {\n throw new address_error_1.AddressError('Invalid subnet mask.');\n }\n address = address.replace(constants6.RE_SUBNET_STRING, '');\n }\n // RE_SUBNET_STRING anchors on the end of the address, so it strips only\n // the trailing suffix. A second one left behind (`::/0/1`) is malformed\n // and must be rejected rather than parsed as an address group.\n if (/\\//.test(address)) {\n throw new address_error_1.AddressError('Invalid subnet mask.');\n }\n const zone = constants6.RE_ZONE_STRING.exec(address);\n if (zone) {\n this.zone = zone[0];\n address = address.replace(constants6.RE_ZONE_STRING, '');\n }\n this.addressMinusSuffix = address;\n this.parsedAddress = this.parse(this.addressMinusSuffix);\n }\n /**\n * Returns true if the given string is a valid IPv6 address (with optional\n * CIDR subnet and zone identifier), false otherwise. Host bits in the\n * subnet portion are allowed (e.g. `2001:db8::1/32` is valid); for strict\n * network-address validation compare `correctForm()` to\n * `startAddress().correctForm()`, or use `networkForm()`.\n */\n static isValid(address) {\n try {\n // eslint-disable-next-line no-new\n new Address6(address);\n return true;\n }\n catch {\n return false;\n }\n }\n /**\n * Convert a BigInt to a v6 address object. The value must be in the\n * range `[0, 2**128 - 1]`; otherwise `AddressError` is thrown.\n * @param {bigint} bigInt - a BigInt to convert\n * @returns {Address6}\n * @example\n * var bigInt = BigInt('1000000000000');\n * var address = Address6.fromBigInt(bigInt);\n * address.correctForm(); // '::e8:d4a5:1000'\n */\n static fromBigInt(bigInt) {\n if (bigInt < BigInt(0) || bigInt > (BigInt(1) << BigInt(constants6.BITS)) - BigInt(1)) {\n throw new address_error_1.AddressError('IPv6 BigInt must be in the range 0 to 2**128 - 1');\n }\n const hex = bigInt.toString(16).padStart(32, '0');\n const groups = [];\n for (let i = 0; i < constants6.GROUPS; i++) {\n groups.push(hex.slice(i * 4, (i + 1) * 4));\n }\n return new Address6(groups.join(':'));\n }\n /**\n * Parse a URL (with optional bracketed host and port) into an address and\n * port. Returns either `{ address, port }` on success or\n * `{ error, address: null, port: null }` if the URL could not be parsed.\n * Ports are returned as numbers (or `null` if absent or out of range).\n * @example\n * var addressAndPort = Address6.fromURL('http://[ffff::]:8080/foo/');\n * addressAndPort.address.correctForm(); // 'ffff::'\n * addressAndPort.port; // 8080\n */\n static fromURL(url) {\n var _a;\n let host;\n let port = null;\n let result;\n let error;\n // Remove the protocol prefix, if any\n const stripped = url.replace(/^[a-z][a-z0-9+.-]*:\\/\\//i, '');\n // If we have brackets parse them and find a port\n if (stripped.indexOf('[') !== -1 && stripped.indexOf(']:') !== -1) {\n error = 'failed to parse address with port';\n result = constants6.RE_URL_WITH_PORT.exec(stripped);\n if (result === null) {\n return { error, address: null, port: null };\n }\n host = result[1];\n port = result[2];\n }\n else {\n error = 'failed to parse address from URL';\n result = constants6.RE_URL.exec(stripped);\n if (result === null) {\n return { error, address: null, port: null };\n }\n host = (_a = result[1]) !== null && _a !== void 0 ? _a : result[2];\n }\n // If there's a port convert it to an integer\n if (port) {\n port = parseInt(port, 10);\n // squelch out of range ports (valid ports are 0-65535)\n if (port < 0 || port > 65535) {\n port = null;\n }\n }\n else {\n // Standardize `undefined` to `null`\n port = null;\n }\n // The URL character class is a superset of valid IPv6, so a host the\n // regex accepted (an IPv4 literal, bare punctuation, too many groups)\n // can still be rejected by the parser\n let address;\n try {\n address = new Address6(host);\n }\n catch {\n return { error, address: null, port: null };\n }\n return { address, port };\n }\n /**\n * Construct an `Address6` from an address and a hex subnet mask given as\n * separate strings (e.g. as returned by Node's `os.networkInterfaces()`).\n * Throws `AddressError` if the mask is non-contiguous (e.g.\n * `ffff::ffff`).\n * @example\n * var address = Address6.fromAddressAndMask('fe80::1', 'ffff:ffff:ffff:ffff::');\n * address.subnetMask; // 64\n */\n static fromAddressAndMask(address, mask) {\n const bits = common.prefixLengthFromMask(new Address6(mask).bigInt(), constants6.BITS);\n return new Address6(`${address}/${bits}`);\n }\n /**\n * Construct an `Address6` from an address and a Cisco-style wildcard mask\n * given as separate strings (e.g. `::ffff:ffff:ffff:ffff` for a `/64`).\n * The wildcard mask is the bitwise inverse of the subnet mask. Throws\n * `AddressError` if the mask is non-contiguous.\n * @example\n * var address = Address6.fromAddressAndWildcardMask('fe80::1', '::ffff:ffff:ffff:ffff');\n * address.subnetMask; // 64\n */\n static fromAddressAndWildcardMask(address, wildcardMask) {\n const wildcard = new Address6(wildcardMask).bigInt();\n const allOnes = (BigInt(1) << BigInt(constants6.BITS)) - BigInt(1);\n const mask = wildcard ^ allOnes;\n const bits = common.prefixLengthFromMask(mask, constants6.BITS);\n return new Address6(`${address}/${bits}`);\n }\n /**\n * Construct an `Address6` from a wildcard pattern with trailing `*`\n * groups. The number of trailing wildcards determines the prefix\n * length: each `*` represents 16 bits. `::` is expanded to zero groups\n * (not wildcards) before evaluating trailing wildcards.\n *\n * Only trailing whole-group wildcards are supported. Partial-group\n * wildcards (e.g. `2001:db8::0*`) and interior wildcards (e.g.\n * `*::1`) throw `AddressError`.\n * @example\n * Address6.fromWildcard('2001:db8:*:*:*:*:*:*').subnet; // '/32'\n * Address6.fromWildcard('2001:db8::*').subnet; // '/112'\n * Address6.fromWildcard('*:*:*:*:*:*:*:*').subnet; // '/0'\n */\n static fromWildcard(input) {\n if (input.includes('%') || input.includes('/')) {\n throw new address_error_1.AddressError('Wildcard pattern must not include a zone or CIDR suffix');\n }\n const halves = input.split('::');\n if (halves.length > 2) {\n throw new address_error_1.AddressError(\"Wildcard pattern cannot contain more than one '::'\");\n }\n let groups;\n if (halves.length === 2) {\n const left = halves[0] === '' ? [] : halves[0].split(':');\n const right = halves[1] === '' ? [] : halves[1].split(':');\n const remaining = constants6.GROUPS - left.length - right.length;\n if (remaining < 1) {\n throw new address_error_1.AddressError(\"Wildcard pattern with '::' has too many groups\");\n }\n groups = [...left, ...new Array(remaining).fill('0'), ...right];\n }\n else {\n groups = input.split(':');\n }\n if (groups.length !== constants6.GROUPS) {\n throw new address_error_1.AddressError('Wildcard pattern must have 8 groups');\n }\n let firstWildcard = -1;\n for (let i = 0; i < groups.length; i++) {\n if (groups[i] === '*') {\n if (firstWildcard === -1) {\n firstWildcard = i;\n }\n }\n else if (firstWildcard !== -1) {\n throw new address_error_1.AddressError('Wildcard `*` must only appear in trailing groups (e.g. `2001:db8:*:*:*:*:*:*`)');\n }\n }\n const trailing = firstWildcard === -1 ? 0 : groups.length - firstWildcard;\n const replaced = groups.map((g) => (g === '*' ? '0' : g));\n const subnetBits = constants6.BITS - trailing * 16;\n return new Address6(`${replaced.join(':')}/${subnetBits}`);\n }\n /**\n * Create an IPv6-mapped address given an IPv4 address\n * @param {string} address - An IPv4 address string\n * @returns {Address6}\n * @example\n * var address = Address6.fromAddress4('192.168.0.1');\n * address.correctForm(); // '::ffff:c0a8:1'\n * address.to4in6(); // '::ffff:192.168.0.1'\n */\n static fromAddress4(address) {\n const address4 = new ipv4_1.Address4(address);\n const mask6 = constants6.BITS - (constants4.BITS - address4.subnetMask);\n return new Address6(`::ffff:${address4.correctForm()}/${mask6}`);\n }\n /**\n * Return an address from ip6.arpa form. A full 32-nibble name gives a /128\n * address; a shorter name, as used for a delegated reverse zone, gives the\n * network it covers, with a subnet mask of four bits per nibble, so\n * `fromArpa(x.reverseForm())` round-trips {@link reverseForm} for any prefix.\n * @param {string} arpaFormAddress - an 'ip6.arpa' form address\n * @returns {Adress6}\n * @example\n * var address = Address6.fromArpa(e.f.f.f.3.c.2.6.f.f.f.e.6.6.8.e.1.0.6.7.9.4.e.c.0.0.0.0.1.0.0.2.ip6.arpa.)\n * address.correctForm(); // '2001:0:ce49:7601:e866:efff:62c3:fffe'\n * Address6.fromArpa('8.b.d.0.1.0.0.2.ip6.arpa.').networkForm(); // '2001:db8::/32'\n */\n static fromArpa(arpaFormAddress) {\n // remove an ending \".ip6.arpa\", with or without the root dot\n const nibbles = arpaFormAddress.replace(/(\\.ip6\\.arpa)?\\.?$/, '');\n if (!/^[0-9a-f](\\.[0-9a-f]){0,31}$/i.test(nibbles)) {\n throw new address_error_1.AddressError(\"Invalid 'ip6.arpa' form.\");\n }\n const reversed = nibbles.split('.').reverse();\n const subnetMask = reversed.length * 4;\n const hex = reversed.join('').padEnd(32, '0');\n const groups = [];\n for (let i = 0; i < constants6.GROUPS; i++) {\n groups.push(hex.slice(i * 4, (i + 1) * 4));\n }\n return new Address6(`${groups.join(':')}/${subnetMask}`);\n }\n /**\n * Return the Microsoft UNC transcription of the address\n * @returns {String} the Microsoft UNC transcription of the address\n */\n microsoftTranscription() {\n return `${this.correctForm().replace(/:/g, '-')}.ipv6-literal.net`;\n }\n /**\n * Return the first n bits of the address, defaulting to the subnet mask\n * @param {number} [mask=subnet] - the number of bits to mask\n * @returns {String} the first n bits of the address as a string\n */\n mask(mask = this.subnetMask) {\n return this.getBitsBase2(0, mask);\n }\n /**\n * Return the number of possible subnets of a given size in the address\n * @param {number} [subnetSize=128] - the subnet size\n * @returns {String}\n */\n // TODO: probably useful to have a numeric version of this too\n possibleSubnets(subnetSize = 128) {\n const availableBits = constants6.BITS - this.subnetMask;\n const subnetBits = Math.abs(subnetSize - constants6.BITS);\n const subnetPowers = availableBits - subnetBits;\n if (subnetPowers < 0) {\n return '0';\n }\n return addCommas((BigInt('2') ** BigInt(subnetPowers)).toString(10));\n }\n /**\n * Helper function getting start address.\n * @returns {bigint}\n */\n _startAddress() {\n return BigInt(`0b${this.mask() + '0'.repeat(constants6.BITS - this.subnetMask)}`);\n }\n /**\n * The first address in the range given by this address' subnet\n * Often referred to as the Network Address.\n * @returns {Address6}\n */\n startAddress() {\n return Address6.fromBigInt(this._startAddress());\n }\n /**\n * The first host address in the range given by this address's subnet ie\n * the first address after the Network Address\n * @returns {Address6}\n */\n startAddressExclusive() {\n const adjust = BigInt('1');\n return Address6.fromBigInt(this._startAddress() + adjust);\n }\n /**\n * Helper function getting end address.\n * @returns {bigint}\n */\n _endAddress() {\n return BigInt(`0b${this.mask() + '1'.repeat(constants6.BITS - this.subnetMask)}`);\n }\n /**\n * The last address in the range given by this address's subnet. IPv6 has\n * no broadcast address, so this is an ordinary assignable address (in a\n * 64-bit-interface-identifier subnet it falls inside the reserved\n * subnet-anycast block of [RFC 2526](https://datatracker.ietf.org/doc/html/rfc2526)).\n * @returns {Address6}\n */\n endAddress() {\n return Address6.fromBigInt(this._endAddress());\n }\n /**\n * The address one before {@link endAddress}. This is the IPv6 counterpart\n * of the IPv4 method that skips the broadcast address; IPv6 has no broadcast,\n * so it drops exactly one address and does not model the 128 reserved\n * subnet-anycast identifiers of [RFC 2526](https://datatracker.ietf.org/doc/html/rfc2526).\n * @returns {Address6}\n */\n endAddressExclusive() {\n const adjust = BigInt('1');\n return Address6.fromBigInt(this._endAddress() - adjust);\n }\n /**\n * Returns the address `n` addresses after this one (or before, when `n` is\n * negative), keeping this address's subnet mask. Throws `AddressError` when\n * the result would fall outside the IPv6 address space or `n` is not an\n * integer.\n * @param {number | bigint} n\n * @returns {Address6}\n * @example\n * new Address6('2001:db8::/64').offset(1).correctForm(); // '2001:db8::1'\n */\n offset(n) {\n return Address6.fromBigInt(common.offsetBigInt(this.bigInt(), n, constants6.BITS, 'IPv6')).withSubnetMask(this.subnetMask);\n }\n /**\n * Returns the network that follows this address's network: the address after\n * {@link endAddress}, with the same subnet mask. Throws `AddressError` when\n * this network is the last one in the address space.\n * @returns {Address6}\n * @example\n * new Address6('2001:db8::/64').nextNetwork().networkForm(); // '2001:db8:0:1::/64'\n */\n nextNetwork() {\n return Address6.fromBigInt(common.offsetBigInt(this._endAddress(), 1, constants6.BITS, 'IPv6')).withSubnetMask(this.subnetMask);\n }\n withSubnetMask(subnetMask) {\n return new Address6(`${this.correctForm()}/${subnetMask}`);\n }\n /**\n * The hex form of the subnet mask, e.g. `ffff:ffff:ffff:ffff::` for a\n * `/64`. Returns an `Address6`; call `.correctForm()` for the string.\n * @returns {Address6}\n */\n subnetMaskAddress() {\n return Address6.fromBigInt(BigInt(`0b${'1'.repeat(this.subnetMask)}${'0'.repeat(constants6.BITS - this.subnetMask)}`));\n }\n /**\n * The Cisco-style wildcard mask, e.g. `::ffff:ffff:ffff:ffff` for a\n * `/64`. This is the bitwise inverse of `subnetMaskAddress()`. Returns\n * an `Address6`; call `.correctForm()` for the string.\n * @returns {Address6}\n */\n wildcardMask() {\n return Address6.fromBigInt(BigInt(`0b${'0'.repeat(this.subnetMask)}${'1'.repeat(constants6.BITS - this.subnetMask)}`));\n }\n /**\n * The network address in CIDR string form, e.g. `2001:db8::/32` for\n * `2001:db8::1/32`. For an address with no explicit subnet the prefix\n * is `/128`, e.g. `networkForm()` on `2001:db8::1` returns\n * `2001:db8::1/128`.\n * @returns {string}\n */\n networkForm() {\n return `${this.startAddress().correctForm()}/${this.subnetMask}`;\n }\n /**\n * Return the scope of the address. The 4-bit scope field\n * ([RFC 4291 §2.7](https://datatracker.ietf.org/doc/html/rfc4291#section-2.7))\n * is only defined for multicast addresses; for unicast addresses the scope\n * is derived from the address type per\n * [RFC 4007 §6](https://datatracker.ietf.org/doc/html/rfc4007#section-6).\n * @returns {String}\n */\n getScope() {\n const type = this.getType();\n if (type === 'Multicast' || type.startsWith('Multicast ')) {\n const scope = constants6.SCOPES[parseInt(this.getBits(12, 16).toString(10), 10)];\n return scope || 'Unknown';\n }\n // RFC 4291 §2.5.3: the loopback address is treated as having Link-Local\n // scope. (Multicast scope 1, \"Interface-Local\", is a different concept\n // used only for loopback transmission of multicast.)\n if (type === 'Link-local unicast' || type === 'Loopback') {\n return 'Link local';\n }\n // RFC 4007 §6: the unspecified address has no scope.\n if (type === 'Unspecified') {\n return 'Unknown';\n }\n return 'Global';\n }\n /**\n * Return the type of the address\n * @returns {String}\n */\n getType() {\n for (let i = 0; i < TYPE_SUBNETS.length; i++) {\n const entry = TYPE_SUBNETS[i];\n if (this.isHostInSubnet(entry[0])) {\n return entry[1];\n }\n }\n return 'Global unicast';\n }\n /**\n * Return the bits in the given range as a BigInt\n * @returns {bigint}\n */\n getBits(start, end) {\n return BigInt(`0b${this.getBitsBase2(start, end)}`);\n }\n /**\n * Return the bits in the given range as a base-2 string\n * @returns {String}\n */\n getBitsBase2(start, end) {\n return this.binaryZeroPad().slice(start, end);\n }\n /**\n * Return the bits in the given range as a base-16 string\n * @returns {String}\n */\n getBitsBase16(start, end) {\n const length = end - start;\n if (length % 4 !== 0) {\n throw new Error('Length of bits to retrieve must be divisible by four');\n }\n return this.getBits(start, end)\n .toString(16)\n .padStart(length / 4, '0');\n }\n /**\n * Return the bits that are set past the subnet mask length\n * @returns {String}\n */\n getBitsPastSubnet() {\n return this.getBitsBase2(this.subnetMask, constants6.BITS);\n }\n /**\n * Return the reversed ip6.arpa form of the address\n * @param {Object} options\n * @param {boolean} options.omitSuffix - omit the \"ip6.arpa\" suffix\n * @returns {String}\n */\n reverseForm(options) {\n if (!options) {\n options = {};\n }\n const characters = Math.floor(this.subnetMask / 4);\n const reversed = this.canonicalForm()\n .replace(/:/g, '')\n .split('')\n .slice(0, characters)\n .reverse()\n .join('.');\n if (characters > 0) {\n if (options.omitSuffix) {\n return reversed;\n }\n return `${reversed}.ip6.arpa.`;\n }\n if (options.omitSuffix) {\n return '';\n }\n return 'ip6.arpa.';\n }\n /**\n * Returns the address in correct form, per\n * [RFC 5952](https://datatracker.ietf.org/doc/html/rfc5952): leading zeros\n * stripped, the longest run of zero groups collapsed to `::`, and hex digits\n * lowercased (e.g. `2001:db8::1`). This is the recommended form for display.\n */\n correctForm() {\n let i;\n let groups = [];\n let zeroCounter = 0;\n const zeroes = [];\n for (i = 0; i < this.parsedAddress.length; i++) {\n const value = parseInt(this.parsedAddress[i], 16);\n if (value === 0) {\n zeroCounter++;\n }\n if (value !== 0 && zeroCounter > 0) {\n if (zeroCounter > 1) {\n zeroes.push([i - zeroCounter, i - 1]);\n }\n zeroCounter = 0;\n }\n }\n // Do we end with a string of zeroes?\n if (zeroCounter > 1) {\n zeroes.push([this.parsedAddress.length - zeroCounter, this.parsedAddress.length - 1]);\n }\n const zeroLengths = zeroes.map((n) => n[1] - n[0] + 1);\n if (zeroes.length > 0) {\n const index = zeroLengths.indexOf(Math.max(...zeroLengths));\n groups = compact(this.parsedAddress, zeroes[index]);\n }\n else {\n groups = this.parsedAddress;\n }\n for (i = 0; i < groups.length; i++) {\n if (groups[i] !== 'compact') {\n groups[i] = parseInt(groups[i], 16).toString(16);\n }\n }\n let correct = groups.join(':');\n correct = correct.replace(/^compact$/, '::');\n correct = correct.replace(/(^compact)|(compact$)/, ':');\n correct = correct.replace(/compact/, '');\n return correct;\n }\n /**\n * Return a zero-padded base-2 string representation of the address\n * @returns {String}\n * @example\n * var address = new Address6('2001:4860:4001:803::1011');\n * address.binaryZeroPad();\n * // '0010000000000001010010000110000001000000000000010000100000000011\n * // 0000000000000000000000000000000000000000000000000001000000010001'\n */\n binaryZeroPad() {\n if (this._binaryZeroPad === undefined) {\n this._binaryZeroPad = this.bigInt().toString(2).padStart(constants6.BITS, '0');\n }\n return this._binaryZeroPad;\n }\n /**\n * Parses a v4-in-v6 string (e.g. `::ffff:192.168.0.1`) by extracting the\n * trailing IPv4 address into `this.address4` / `this.parsedAddress4` and\n * returning the address with the v4 portion converted to two v6 groups.\n * Used internally by `parse()`.\n */\n // TODO: Improve the semantics of this helper function\n parse4in6(address) {\n if (address.indexOf('.') === -1) {\n return address;\n }\n const groups = address.split(':');\n const lastGroup = groups.slice(-1)[0];\n // RE_ADDRESS rejects octets with a leading zero, so a dotted-quad tail is\n // matched permissively first: that way this notation still gets its own\n // message with the offending octet highlighted, rather than falling\n // through as an unrecognized group.\n const v4Octets = lastGroup.split('.');\n if (v4Octets.length === constants4.GROUPS &&\n v4Octets.every((octet) => /^\\d{1,3}$/.test(octet))) {\n if (v4Octets.some((octet) => /^0\\d/.test(octet))) {\n // The prefix groups haven't been through the bad-character check\n // yet, so escape them before including in the error HTML.\n const highlighted = v4Octets.map(spanLeadingZeroes4).join('.');\n const prefix = groups.slice(0, -1).map(helpers.escapeHtml).join(':');\n const separator = groups.length > 1 ? ':' : '';\n throw new address_error_1.AddressError(\"IPv4 addresses can't have leading zeroes.\", `${prefix}${separator}${highlighted}`);\n }\n }\n const address4 = lastGroup.match(constants4.RE_ADDRESS);\n if (address4) {\n this.parsedAddress4 = address4[0];\n const v4Suffix = this.subnetMask >= 96 ? `/${this.subnetMask - 96}` : '';\n this.address4 = new ipv4_1.Address4(`${this.parsedAddress4}${v4Suffix}`);\n this.v4 = true;\n groups[groups.length - 1] = this.address4.toGroup6();\n address = groups.join(':');\n }\n return address;\n }\n /**\n * Parses an IPv6 address string into its 8 hexadecimal groups (expanding\n * any `::` elision and any trailing v4-in-v6 portion) and stores the result\n * on `this.parsedAddress`. Called automatically by the constructor; you\n * typically don't need to call it directly. Throws `AddressError` if the\n * input is malformed.\n */\n // TODO: Make private?\n parse(address) {\n address = this.parse4in6(address);\n const badCharacters = address.match(constants6.RE_BAD_CHARACTERS);\n if (badCharacters) {\n throw new address_error_1.AddressError(`Bad character${badCharacters.length > 1 ? 's' : ''} detected in address: ${badCharacters.join('')}`, address.replace(constants6.RE_BAD_CHARACTERS, '<span class=\"parse-error\">$1</span>'));\n }\n const badAddress = address.match(constants6.RE_BAD_ADDRESS);\n if (badAddress) {\n throw new address_error_1.AddressError(`Address failed regex: ${badAddress.join('')}`, address.replace(constants6.RE_BAD_ADDRESS, '<span class=\"parse-error\">$1</span>'));\n }\n let groups = [];\n const halves = address.split('::');\n if (halves.length === 2) {\n let first = halves[0].split(':');\n let last = halves[1].split(':');\n if (first.length === 1 && first[0] === '') {\n first = [];\n }\n if (last.length === 1 && last[0] === '') {\n last = [];\n }\n const remaining = this.groups - (first.length + last.length);\n if (!remaining) {\n throw new address_error_1.AddressError('Error parsing groups');\n }\n this.elidedGroups = remaining;\n this.elisionBegin = first.length;\n this.elisionEnd = first.length + this.elidedGroups;\n groups = groups.concat(first);\n for (let i = 0; i < remaining; i++) {\n groups.push('0');\n }\n groups = groups.concat(last);\n }\n else if (halves.length === 1) {\n groups = address.split(':');\n this.elidedGroups = 0;\n }\n else {\n throw new address_error_1.AddressError('Too many :: groups found');\n }\n groups = groups.map((group) => parseInt(group, 16).toString(16));\n if (groups.length !== this.groups) {\n throw new address_error_1.AddressError('Incorrect number of groups found');\n }\n return groups;\n }\n /**\n * Returns the canonical (fully expanded) form of the address: all 8 groups,\n * each padded to 4 hex digits, with no `::` collapsing\n * (e.g. `2001:0db8:0000:0000:0000:0000:0000:0001`). Useful for sorting and\n * byte-exact comparison.\n */\n canonicalForm() {\n return this.parsedAddress.map(paddedHex).join(':');\n }\n /**\n * Return the decimal form of the address\n * @returns {String}\n */\n decimal() {\n return this.parsedAddress.map((n) => parseInt(n, 16).toString(10).padStart(5, '0')).join(':');\n }\n /**\n * Return the address as a BigInt\n * @returns {bigint}\n */\n bigInt() {\n return BigInt(`0x${this.parsedAddress.map(paddedHex).join('')}`);\n }\n /**\n * Return the last two groups of this address as an IPv4 address string.\n * If this address carries a CIDR prefix that covers the trailing 32 bits\n * (i.e. `subnetMask >= 96`), the resulting `Address4` inherits the\n * corresponding v4 prefix (`subnetMask - 96`); otherwise it defaults to\n * `/32`.\n * @returns {Address4}\n * @example\n * var address = new Address6('2001:4860:4001::1825:bf11');\n * address.to4().correctForm(); // '24.37.191.17'\n */\n to4() {\n const binary = this.binaryZeroPad().split('');\n const hex = BigInt(`0b${binary.slice(96, 128).join('')}`)\n .toString(16)\n .padStart(8, '0');\n if (this.subnetMask >= 96) {\n const v4Mask = this.subnetMask - 96;\n const groups = [];\n for (let i = 0; i < 8; i += 2) {\n groups.push(parseInt(hex.slice(i, i + 2), 16));\n }\n return new ipv4_1.Address4(`${groups.join('.')}/${v4Mask}`);\n }\n return ipv4_1.Address4.fromHex(hex);\n }\n /**\n * Return the v4-in-v6 form of the address\n * @returns {String}\n */\n to4in6() {\n const address4 = this.to4();\n const address6 = new Address6(this.parsedAddress.slice(0, 6).join(':'), 6);\n const correct = address6.correctForm();\n let infix = '';\n if (!/:$/.test(correct)) {\n infix = ':';\n }\n return correct + infix + address4.correctForm();\n }\n /**\n * Decodes the Teredo tunneling fields embedded in this address. Returns the\n * Teredo prefix, server IPv4, client IPv4, raw flag bits, cone-NAT flag,\n * UDP port, and Microsoft-format flag breakdown (reserved, universal/local,\n * group/individual, nonce). Only meaningful for addresses in `2001::/32`.\n */\n inspectTeredo() {\n /*\n - Bits 0 to 31 are set to the Teredo prefix (normally 2001:0000::/32).\n - Bits 32 to 63 embed the primary IPv4 address of the Teredo server that\n is used.\n - Bits 64 to 79 can be used to define some flags. Currently only the\n higher order bit is used; it is set to 1 if the Teredo client is\n located behind a cone NAT, 0 otherwise. For Microsoft's Windows Vista\n and Windows Server 2008 implementations, more bits are used. In those\n implementations, the format for these 16 bits is \"CRAAAAUG AAAAAAAA\",\n where \"C\" remains the \"Cone\" flag. The \"R\" bit is reserved for future\n use. The \"U\" bit is for the Universal/Local flag (set to 0). The \"G\" bit\n is Individual/Group flag (set to 0). The A bits are set to a 12-bit\n randomly generated number chosen by the Teredo client to introduce\n additional protection for the Teredo node against IPv6-based scanning\n attacks.\n - Bits 80 to 95 contains the obfuscated UDP port number. This is the\n port number that is mapped by the NAT to the Teredo client with all\n bits inverted.\n - Bits 96 to 127 contains the obfuscated IPv4 address. This is the\n public IPv4 address of the NAT with all bits inverted.\n */\n const prefix = this.getBitsBase16(0, 32);\n const bitsForUdpPort = this.getBits(80, 96);\n const udpPort = (bitsForUdpPort ^ BigInt('0xffff')).toString();\n const server4 = ipv4_1.Address4.fromHex(this.getBitsBase16(32, 64));\n const bitsForClient4 = this.getBits(96, 128);\n const client4 = ipv4_1.Address4.fromHex((bitsForClient4 ^ BigInt('0xffffffff')).toString(16).padStart(8, '0'));\n const flagsBase2 = this.getBitsBase2(64, 80);\n const coneNat = (0, common_1.testBit)(flagsBase2, 15);\n const reserved = (0, common_1.testBit)(flagsBase2, 14);\n const groupIndividual = (0, common_1.testBit)(flagsBase2, 8);\n const universalLocal = (0, common_1.testBit)(flagsBase2, 9);\n const nonce = BigInt(`0b${flagsBase2.slice(2, 6) + flagsBase2.slice(8, 16)}`).toString(10);\n return {\n prefix: `${prefix.slice(0, 4)}:${prefix.slice(4, 8)}`,\n server4: server4.address,\n client4: client4.address,\n flags: flagsBase2,\n coneNat,\n microsoft: {\n reserved,\n universalLocal,\n groupIndividual,\n nonce,\n },\n udpPort,\n };\n }\n /**\n * Decodes the 6to4 tunneling fields embedded in this address. Returns the\n * 6to4 prefix and the embedded IPv4 gateway address. Only meaningful for\n * addresses in `2002::/16`.\n */\n inspect6to4() {\n /*\n - Bits 0 to 15 are set to the 6to4 prefix (2002::/16).\n - Bits 16 to 48 embed the IPv4 address of the 6to4 gateway that is used.\n */\n const prefix = this.getBitsBase16(0, 16);\n const gateway = ipv4_1.Address4.fromHex(this.getBitsBase16(16, 48));\n return {\n prefix: prefix.slice(0, 4),\n gateway: gateway.address,\n };\n }\n /**\n * Return a v6 6to4 address from a v6 v4inv6 address\n * @returns {Address6}\n */\n to6to4() {\n if (!this.is4()) {\n return null;\n }\n const addr6to4 = [\n '2002',\n this.getBitsBase16(96, 112),\n this.getBitsBase16(112, 128),\n '',\n '/16',\n ].join(':');\n return new Address6(addr6to4);\n }\n /**\n * Embed an IPv4 address into a NAT64 IPv6 address using the encoding\n * defined by [RFC 6052](https://datatracker.ietf.org/doc/html/rfc6052).\n * The default prefix is the well-known prefix `64:ff9b::/96`. The prefix\n * length must be one of 32, 40, 48, 56, 64, or 96; for prefixes shorter\n * than /64 the IPv4 octets are split around the reserved bits 64–71.\n * @example\n * Address6.fromAddress4Nat64('192.0.2.33').correctForm(); // '64:ff9b::c000:221'\n * Address6.fromAddress4Nat64('192.0.2.33', '2001:db8::/32').correctForm(); // '2001:db8:c000:221::'\n */\n static fromAddress4Nat64(address, prefix = '64:ff9b::/96') {\n const v4 = new ipv4_1.Address4(address);\n const prefix6 = new Address6(prefix);\n const pl = prefix6.subnetMask;\n if (pl !== 32 && pl !== 40 && pl !== 48 && pl !== 56 && pl !== 64 && pl !== 96) {\n throw new address_error_1.AddressError('NAT64 prefix length must be 32, 40, 48, 56, 64, or 96');\n }\n const prefixBits = prefix6.binaryZeroPad();\n const v4Bits = v4.binaryZeroPad();\n let bits;\n if (pl === 96) {\n bits = prefixBits.slice(0, 96) + v4Bits;\n }\n else {\n const beforeU = 64 - pl;\n bits = [\n prefixBits.slice(0, pl),\n v4Bits.slice(0, beforeU),\n // Bits 64 to 71 are the reserved u octet and are always zero.\n '00000000',\n v4Bits.slice(beforeU),\n '0'.repeat(128 - 72 - (32 - beforeU)),\n ].join('');\n }\n const hex = BigInt(`0b${bits}`).toString(16).padStart(32, '0');\n const groups = [];\n for (let i = 0; i < 8; i++) {\n groups.push(hex.slice(i * 4, (i + 1) * 4));\n }\n return new Address6(groups.join(':'));\n }\n /**\n * Extract the embedded IPv4 address from a NAT64 IPv6 address using the\n * encoding defined by [RFC 6052](https://datatracker.ietf.org/doc/html/rfc6052).\n * The default prefix is the well-known prefix `64:ff9b::/96`. Returns\n * `null` if this address is not contained within the given prefix.\n * @example\n * new Address6('64:ff9b::c000:221').toAddress4Nat64()!.correctForm(); // '192.0.2.33'\n */\n toAddress4Nat64(prefix = '64:ff9b::/96') {\n const prefix6 = new Address6(prefix);\n const pl = prefix6.subnetMask;\n if (pl !== 32 && pl !== 40 && pl !== 48 && pl !== 56 && pl !== 64 && pl !== 96) {\n throw new address_error_1.AddressError('NAT64 prefix length must be 32, 40, 48, 56, 64, or 96');\n }\n if (!this.isHostInSubnet(prefix6)) {\n return null;\n }\n const bits = this.binaryZeroPad();\n let v4Bits;\n if (pl === 96) {\n v4Bits = bits.slice(96, 128);\n }\n else {\n const beforeU = 64 - pl;\n v4Bits = bits.slice(pl, pl + beforeU) + bits.slice(72, 72 + (32 - beforeU));\n }\n const octets = [];\n for (let i = 0; i < 4; i++) {\n octets.push(parseInt(v4Bits.slice(i * 8, (i + 1) * 8), 2).toString());\n }\n return new ipv4_1.Address4(octets.join('.'));\n }\n /**\n * Return a byte array.\n *\n * To get a Node.js `Buffer`, wrap the result: `Buffer.from(address.toByteArray())`.\n * @returns {Array}\n */\n toByteArray() {\n const value = this.bigInt()\n .toString(16)\n .padStart(constants6.BITS / 4, '0');\n const bytes = [];\n for (let i = 0, length = value.length; i < length; i += 2) {\n bytes.push(parseInt(value.substring(i, i + 2), 16));\n }\n return bytes;\n }\n /**\n * Return an unsigned byte array.\n *\n * To get a Node.js `Buffer`, wrap the result: `Buffer.from(address.toUnsignedByteArray())`.\n * @returns {Array}\n */\n toUnsignedByteArray() {\n // toByteArray() emits 0 to 255, so unsigning it is an identity mapping and\n // the two methods return equal arrays. 11.0.0 keeps one of them and makes\n // this a deprecated alias; test/common-test.ts fails at that version.\n return this.toByteArray().map(unsignByte);\n }\n /**\n * Convert a byte array to an Address6 object.\n *\n * Accepts unsigned bytes (0 to 255) or signed bytes (-128 to 127, as an\n * `Int8Array` or a Java `byte[]` holds them), folding signed values to their\n * unsigned equivalent. Throws `AddressError` unless given exactly 16\n * integers from -128 to 255.\n *\n * To convert from a Node.js `Buffer`, spread it: `Address6.fromByteArray([...buf])`.\n * @returns {Address6}\n */\n static fromByteArray(bytes) {\n // Address4.fromByteArray takes unsigned bytes only. 11.0.0 aligns this\n // method with it, at which point the -128 floor here, unsignByte, and the\n // mapping below all go; test/common-test.ts fails at that version.\n common.assertByteArray(bytes, 16, 'IPv6', -128);\n return this.fromUnsignedByteArray(bytes.map(unsignByte));\n }\n /**\n * Convert an unsigned byte array to an Address6 object.\n *\n * Throws `AddressError` unless given exactly 16 integers from 0 to 255.\n *\n * To convert from a Node.js `Buffer`, spread it: `Address6.fromUnsignedByteArray([...buf])`.\n * @returns {Address6}\n */\n static fromUnsignedByteArray(bytes) {\n common.assertByteArray(bytes, 16, 'IPv6', 0);\n const BYTE_MAX = BigInt('256');\n let result = BigInt('0');\n let multiplier = BigInt('1');\n for (let i = bytes.length - 1; i >= 0; i--) {\n result += multiplier * BigInt(bytes[i].toString(10));\n multiplier *= BYTE_MAX;\n }\n return Address6.fromBigInt(result);\n }\n /**\n * Returns true if the address is in the canonical form, false otherwise\n * @returns {boolean}\n */\n isCanonical() {\n return this.addressMinusSuffix === this.canonicalForm();\n }\n /**\n * Returns true if the address is a link-local unicast address in `fe80::/10`\n * ([RFC 4291 §2.4](https://datatracker.ietf.org/doc/html/rfc4291#section-2.4))\n * or an IPv4-mapped / NAT64 address whose embedded IPv4 address is link-local\n * (`169.254.0.0/16`, e.g. `::ffff:169.254.169.254`), false otherwise.\n * @returns {boolean}\n */\n isLinkLocal() {\n const embedded = this.embeddedIPv4();\n if (embedded) {\n return embedded.isLinkLocal();\n }\n return this.isHostInSubnet(LINK_LOCAL_SUBNET);\n }\n /**\n * Returns true if the address is a multicast address, false otherwise\n * @returns {boolean}\n */\n isMulticast() {\n const embedded = this.embeddedIPv4();\n if (embedded) {\n return embedded.isMulticast();\n }\n const type = this.getType();\n return type === 'Multicast' || type.startsWith('Multicast ');\n }\n /**\n * Returns true if the address was written in v4-in-v6 dotted-quad notation\n * (e.g. `::ffff:127.0.0.1`), false otherwise. This is a notation-level flag\n * and does not reflect whether the address bits lie in the IPv4-mapped\n * (`::ffff:0:0/96`) subnet — for that, see {@link isMapped4}.\n * @returns {boolean}\n */\n is4() {\n return this.v4;\n }\n /**\n * Returns true if the address is an IPv4-mapped IPv6 address in\n * `::ffff:0:0/96` ([RFC 4291 §2.5.5.2](https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.5.2)),\n * false otherwise. Unlike {@link is4}, this checks the underlying address\n * bits rather than the textual notation, so `::ffff:127.0.0.1` and\n * `::ffff:7f00:1` both return true.\n * @returns {boolean}\n */\n isMapped4() {\n return this.isHostInSubnet(IPV4_MAPPED_SUBNET);\n }\n /**\n * If this address embeds a routable IPv4 address — i.e. it is IPv4-mapped\n * (`::ffff:0:0/96`) or sits in the NAT64 well-known prefix (`64:ff9b::/96`,\n * [RFC 6052](https://datatracker.ietf.org/doc/html/rfc6052)) — return that\n * embedded address as an {@link Address4}; otherwise return null.\n *\n * The special-property checks (`isLoopback`, `isLinkLocal`, `isMulticast`,\n * `isUnspecified`, `isPrivate`, `isCGNAT`, `isBroadcast`) call this first and\n * delegate to the embedded {@link Address4} when present, so a literal such as\n * `::ffff:127.0.0.1` is classified by what it actually reaches (loopback)\n * rather than by its IPv6 wrapper (which `getType()` reports as IPv4-mapped).\n * This matters wherever the checks back a trust-boundary decision (e.g. an\n * SSRF allow/deny filter): without normalization, `::ffff:10.0.0.1`,\n * `::ffff:169.254.169.254`, `64:ff9b::7f00:1`, etc. would all read as\n * non-internal.\n * @returns {Address4 | null}\n */\n embeddedIPv4() {\n if (this.isMapped4() || this.isHostInSubnet(NAT64_WELL_KNOWN_SUBNET)) {\n return this.to4();\n }\n return null;\n }\n /**\n * Returns true if the address is a Teredo address, false otherwise\n * @returns {boolean}\n */\n isTeredo() {\n return this.isHostInSubnet(TEREDO_SUBNET);\n }\n /**\n * Returns true if the address is a 6to4 address, false otherwise\n * @returns {boolean}\n */\n is6to4() {\n return this.isHostInSubnet(SIX_TO_FOUR_SUBNET);\n }\n /**\n * Returns true if the address is a loopback address, false otherwise\n * @returns {boolean}\n */\n isLoopback() {\n const embedded = this.embeddedIPv4();\n if (embedded) {\n return embedded.isLoopback();\n }\n return this.getType() === 'Loopback';\n }\n /**\n * Returns true if the address is a Unique Local Address in `fc00::/7` ([RFC 4193](https://datatracker.ietf.org/doc/html/rfc4193)). ULAs are the IPv6 equivalent of IPv4 [RFC 1918](https://datatracker.ietf.org/doc/html/rfc1918) private addresses.\n * @returns {boolean}\n */\n isULA() {\n return this.isHostInSubnet(ULA_SUBNET);\n }\n /**\n * Returns true if the address is private, i.e. a Unique Local Address in\n * `fc00::/7` ([RFC 4193](https://datatracker.ietf.org/doc/html/rfc4193)), an\n * address in the NAT64 local-use range `64:ff9b:1::/48`\n * ([RFC 8215](https://datatracker.ietf.org/doc/html/rfc8215)), or an\n * IPv4-mapped / NAT64 well-known address whose embedded IPv4 address is in\n * one of the [RFC 1918](https://datatracker.ietf.org/doc/html/rfc1918)\n * private ranges (e.g. `::ffff:10.0.0.1`). This is the IPv6 counterpart to\n * {@link Address4.isPrivate}; use it instead of {@link isULA} when you need to\n * catch mapped RFC 1918 addresses as well as native ULAs.\n *\n * The local-use NAT64 range is reported private as a whole rather than by\n * its embedded IPv4 address: an operator may carve a prefix of any RFC 6052\n * length out of `64:ff9b:1::/48`, so the same bits decode to different IPv4\n * addresses under different deployments and no single decoding is correct.\n * Use {@link toAddress4Nat64} with the deployment's prefix to decode one.\n * @returns {boolean}\n */\n isPrivate() {\n const embedded = this.embeddedIPv4();\n if (embedded) {\n return embedded.isPrivate();\n }\n return this.isULA() || this.isHostInSubnet(NAT64_LOCAL_USE_SUBNET);\n }\n /**\n * Returns true if the address is an IPv4-mapped / NAT64 address whose embedded\n * IPv4 address is in the carrier-grade NAT range `100.64.0.0/10`\n * ([RFC 6598](https://datatracker.ietf.org/doc/html/rfc6598)), false\n * otherwise. There is no native IPv6 CGNAT range, so this only ever returns\n * true for an embedded IPv4 address (e.g. `::ffff:100.64.0.1`).\n * @returns {boolean}\n */\n isCGNAT() {\n const embedded = this.embeddedIPv4();\n if (embedded) {\n return embedded.isCGNAT();\n }\n return false;\n }\n /**\n * Returns true if the address is an IPv4-mapped / NAT64 address whose embedded\n * IPv4 address is the limited broadcast address `255.255.255.255`\n * ([RFC 919](https://datatracker.ietf.org/doc/html/rfc919)), false otherwise.\n * There is no IPv6 broadcast, so this only ever returns true for an embedded\n * IPv4 address (e.g. `::ffff:255.255.255.255`).\n * @returns {boolean}\n */\n isBroadcast() {\n const embedded = this.embeddedIPv4();\n if (embedded) {\n return embedded.isBroadcast();\n }\n return false;\n }\n /**\n * Returns true if the address is the unspecified address `::`.\n * @returns {boolean}\n */\n isUnspecified() {\n const embedded = this.embeddedIPv4();\n if (embedded) {\n return embedded.isUnspecified();\n }\n return this.getType() === 'Unspecified';\n }\n /**\n * Returns true if the address is in the documentation prefix `2001:db8::/32` ([RFC 3849](https://datatracker.ietf.org/doc/html/rfc3849)).\n * @returns {boolean}\n */\n isDocumentation() {\n return DOCUMENTATION_SUBNETS.some((subnet) => this.isHostInSubnet(subnet));\n }\n /**\n * Returns true if the address is in the benchmarking range `2001:2::/48`\n * ([RFC 5180](https://datatracker.ietf.org/doc/html/rfc5180)) or is an\n * IPv4-mapped / NAT64 address whose embedded IPv4 address is in\n * `198.18.0.0/15`, false otherwise.\n * @returns {boolean}\n */\n isBenchmarking() {\n const embedded = this.embeddedIPv4();\n if (embedded) {\n return embedded.isBenchmarking();\n }\n return this.isHostInSubnet(BENCHMARKING_SUBNET);\n }\n /**\n * Returns true if the address is globally reachable: inside the global\n * unicast allocation `2000::/3` (the only range the [IANA IPv6 Address Space\n * Registry](https://www.iana.org/assignments/ipv6-address-space/) assigns\n * for global unicast; everything else is reserved, ULA, link-local, or\n * multicast) and not in any block the [IANA IPv6 Special-Purpose Address Registry](https://www.iana.org/assignments/iana-ipv6-special-registry/)\n * marks as not globally reachable. An IPv4-mapped or NAT64 well-known\n * address answers for its embedded IPv4 address, so `::ffff:10.0.0.1` and\n * `64:ff9b::7f00:1` are not global. Teredo (`2001::/32`) and 6to4\n * (`2002::/16`) are not global either: the registry lists them as N/A and a\n * packet to one needs a relay.\n *\n * This covers everything the individual classifiers name and the blocks they\n * do not: the discard-only prefix `100::/64`, the IETF protocol assignments\n * in `2001::/23`, the deprecated site-local `fec0::/10` and IPv4-compatible\n * `::/96` ranges, and unallocated space such as `4000::/3`. It is the single\n * predicate to use where a request must not reach an internal or\n * special-purpose destination; see SECURITY.md.\n * @returns {boolean}\n */\n isGlobal() {\n const embedded = this.embeddedIPv4();\n if (embedded) {\n return embedded.isGlobal();\n }\n return (this.isHostInSubnet(GLOBAL_UNICAST_SUBNET) &&\n common.isGloballyReachable.call(this, SPECIAL_PURPOSE_V6));\n }\n // #endregion\n // #region HTML\n /**\n * Returns the address as an HTTP URL with the host bracketed, e.g.\n * `http://[2001:db8::1]/`. If `optionalPort` is provided it is appended,\n * e.g. `http://[2001:db8::1]:8080/`.\n */\n href(optionalPort) {\n if (optionalPort === undefined) {\n optionalPort = '';\n }\n else {\n optionalPort = `:${optionalPort}`;\n }\n return `http://[${this.correctForm()}]${optionalPort}/`;\n }\n /**\n * Returns an HTML `<a>` element whose `href` encodes the address in a URL\n * hash fragment (default prefix `/#address=`). Useful for linking between\n * pages of an address-inspector UI.\n * @param options.className - CSS class for the rendered `<a>` element\n * @param options.prefix - hash prefix prepended to the address (default `/#address=`)\n * @param options.v4 - when true, render the address in v4-in-v6 form\n */\n link(options) {\n if (!options) {\n options = {};\n }\n if (options.className === undefined) {\n options.className = '';\n }\n if (options.prefix === undefined) {\n options.prefix = '/#address=';\n }\n if (options.v4 === undefined) {\n options.v4 = false;\n }\n let formFunction = this.correctForm;\n if (options.v4) {\n formFunction = this.to4in6;\n }\n const form = formFunction.call(this);\n const safeHref = helpers.escapeHtml(`${options.prefix}${form}`);\n const safeForm = helpers.escapeHtml(form);\n if (options.className) {\n const safeClass = helpers.escapeHtml(options.className);\n return `<a href=\"${safeHref}\" class=\"${safeClass}\">${safeForm}</a>`;\n }\n return `<a href=\"${safeHref}\">${safeForm}</a>`;\n }\n /**\n * Groups an address.\n *\n * Returns an HTML fragment: each group is wrapped in a `<span>` carrying\n * the group classes an address-inspector UI hovers on. The address content\n * is HTML-escaped; anything you concatenate around it is your\n * responsibility.\n * @returns {String}\n */\n group() {\n if (this.elidedGroups === 0) {\n // The simple case\n return helpers.simpleGroup(this.addressMinusSuffix).join(':');\n }\n assert(typeof this.elidedGroups === 'number');\n assert(typeof this.elisionBegin === 'number');\n // The elided case\n const output = [];\n const [left, right] = this.addressMinusSuffix.split('::');\n if (left.length) {\n output.push(...helpers.simpleGroup(left));\n }\n else {\n output.push('');\n }\n const classes = ['hover-group'];\n for (let i = this.elisionBegin; i < this.elisionBegin + this.elidedGroups; i++) {\n classes.push(`group-${i}`);\n }\n output.push(`<span class=\"${classes.join(' ')}\"></span>`);\n if (right.length) {\n output.push(...helpers.simpleGroup(right, this.elisionEnd));\n }\n else {\n output.push('');\n }\n if (this.is4()) {\n assert(this.address4 instanceof ipv4_1.Address4);\n output.pop();\n output.push(this.address4.groupForV6());\n }\n return output.join(':');\n }\n // #endregion\n // #region Regular expressions\n /**\n * Generate a regular expression string that can be used to find or validate\n * all variations of this address\n * @param {boolean} substringSearch\n * @returns {string}\n */\n regularExpressionString(substringSearch = false) {\n let output = [];\n // TODO: revisit why this is necessary\n const address6 = new Address6(this.correctForm());\n if (address6.elidedGroups === 0) {\n // The simple case\n output.push((0, regular_expressions_1.simpleRegularExpression)(address6.parsedAddress));\n }\n else if (address6.elidedGroups === constants6.GROUPS) {\n // A completely elided address\n output.push((0, regular_expressions_1.possibleElisions)(constants6.GROUPS));\n }\n else {\n // A partially elided address\n const halves = address6.address.split('::');\n if (halves[0].length) {\n output.push((0, regular_expressions_1.simpleRegularExpression)(halves[0].split(':')));\n }\n assert(typeof address6.elidedGroups === 'number');\n output.push((0, regular_expressions_1.possibleElisions)(address6.elidedGroups, halves[0].length !== 0, halves[1].length !== 0));\n if (halves[1].length) {\n output.push((0, regular_expressions_1.simpleRegularExpression)(halves[1].split(':')));\n }\n output = [output.join(':')];\n }\n if (!substringSearch) {\n output = [\n '(?=^|',\n regular_expressions_1.ADDRESS_BOUNDARY,\n '|[^\\\\w\\\\:])(',\n ...output,\n ')(?=[^\\\\w\\\\:]|',\n regular_expressions_1.ADDRESS_BOUNDARY,\n '|$)',\n ];\n }\n return output.join('');\n }\n /**\n * Generate a regular expression that can be used to find or validate all\n * variations of this address.\n * @param {boolean} substringSearch\n * @returns {RegExp}\n */\n regularExpression(substringSearch = false) {\n return new RegExp(this.regularExpressionString(substringSearch), 'i');\n }\n}\nexports.Address6 = Address6;\nconst TYPE_SUBNETS = Object.keys(constants6.TYPES).map((subnet) => [\n new Address6(subnet),\n constants6.TYPES[subnet],\n]);\nconst TEREDO_SUBNET = new Address6('2001::/32');\nconst SIX_TO_FOUR_SUBNET = new Address6('2002::/16');\nconst ULA_SUBNET = new Address6('fc00::/7');\nconst LINK_LOCAL_SUBNET = new Address6('fe80::/10');\nconst DOCUMENTATION_SUBNETS = [new Address6('2001:db8::/32'), new Address6('3fff::/20')];\nconst BENCHMARKING_SUBNET = new Address6('2001:2::/48');\nconst GLOBAL_UNICAST_SUBNET = new Address6('2000::/3');\nconst SPECIAL_PURPOSE_V6 = constants6.SPECIAL_PURPOSE.map(([cidr, , reachable]) => ({\n subnet: new Address6(cidr),\n reachable,\n}));\nconst IPV4_MAPPED_SUBNET = new Address6('::ffff:0:0/96');\nconst NAT64_WELL_KNOWN_SUBNET = new Address6('64:ff9b::/96');\nconst NAT64_LOCAL_USE_SUBNET = new Address6('64:ff9b:1::/48');\n//# sourceMappingURL=ipv6.js.map","\"use strict\";\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.v6 = exports.AddressError = exports.Address6 = exports.Address4 = void 0;\nvar ipv4_1 = require(\"./ipv4\");\nObject.defineProperty(exports, \"Address4\", { enumerable: true, get: function () { return ipv4_1.Address4; } });\nvar ipv6_1 = require(\"./ipv6\");\nObject.defineProperty(exports, \"Address6\", { enumerable: true, get: function () { return ipv6_1.Address6; } });\nvar address_error_1 = require(\"./address-error\");\nObject.defineProperty(exports, \"AddressError\", { enumerable: true, get: function () { return address_error_1.AddressError; } });\nconst helpers = __importStar(require(\"./v6/helpers\"));\nexports.v6 = { helpers };\n//# sourceMappingURL=ip-address.js.map","/**\n * Helpers.\n */\n\nvar s = 1000;\nvar m = s * 60;\nvar h = m * 60;\nvar d = h * 24;\nvar w = d * 7;\nvar y = d * 365.25;\n\n/**\n * Parse or format the given `val`.\n *\n * Options:\n *\n * - `long` verbose formatting [false]\n *\n * @param {String|Number} val\n * @param {Object} [options]\n * @throws {Error} throw an error if val is not a non-empty string or a number\n * @return {String|Number}\n * @api public\n */\n\nmodule.exports = function (val, options) {\n options = options || {};\n var type = typeof val;\n if (type === 'string' && val.length > 0) {\n return parse(val);\n } else if (type === 'number' && isFinite(val)) {\n return options.long ? fmtLong(val) : fmtShort(val);\n }\n throw new Error(\n 'val is not a non-empty string or a valid number. val=' +\n JSON.stringify(val)\n );\n};\n\n/**\n * Parse the given `str` and return milliseconds.\n *\n * @param {String} str\n * @return {Number}\n * @api private\n */\n\nfunction parse(str) {\n str = String(str);\n if (str.length > 100) {\n return;\n }\n var match = /^(-?(?:\\d+)?\\.?\\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(\n str\n );\n if (!match) {\n return;\n }\n var n = parseFloat(match[1]);\n var type = (match[2] || 'ms').toLowerCase();\n switch (type) {\n case 'years':\n case 'year':\n case 'yrs':\n case 'yr':\n case 'y':\n return n * y;\n case 'weeks':\n case 'week':\n case 'w':\n return n * w;\n case 'days':\n case 'day':\n case 'd':\n return n * d;\n case 'hours':\n case 'hour':\n case 'hrs':\n case 'hr':\n case 'h':\n return n * h;\n case 'minutes':\n case 'minute':\n case 'mins':\n case 'min':\n case 'm':\n return n * m;\n case 'seconds':\n case 'second':\n case 'secs':\n case 'sec':\n case 's':\n return n * s;\n case 'milliseconds':\n case 'millisecond':\n case 'msecs':\n case 'msec':\n case 'ms':\n return n;\n default:\n return undefined;\n }\n}\n\n/**\n * Short format for `ms`.\n *\n * @param {Number} ms\n * @return {String}\n * @api private\n */\n\nfunction fmtShort(ms) {\n var msAbs = Math.abs(ms);\n if (msAbs >= d) {\n return Math.round(ms / d) + 'd';\n }\n if (msAbs >= h) {\n return Math.round(ms / h) + 'h';\n }\n if (msAbs >= m) {\n return Math.round(ms / m) + 'm';\n }\n if (msAbs >= s) {\n return Math.round(ms / s) + 's';\n }\n return ms + 'ms';\n}\n\n/**\n * Long format for `ms`.\n *\n * @param {Number} ms\n * @return {String}\n * @api private\n */\n\nfunction fmtLong(ms) {\n var msAbs = Math.abs(ms);\n if (msAbs >= d) {\n return plural(ms, msAbs, d, 'day');\n }\n if (msAbs >= h) {\n return plural(ms, msAbs, h, 'hour');\n }\n if (msAbs >= m) {\n return plural(ms, msAbs, m, 'minute');\n }\n if (msAbs >= s) {\n return plural(ms, msAbs, s, 'second');\n }\n return ms + ' ms';\n}\n\n/**\n * Pluralization helper.\n */\n\nfunction plural(ms, msAbs, n, name) {\n var isPlural = msAbs >= n * 1.5;\n return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : '');\n}\n","\n/**\n * This is the common logic for both the Node.js and web browser\n * implementations of `debug()`.\n */\n\nfunction setup(env) {\n\tcreateDebug.debug = createDebug;\n\tcreateDebug.default = createDebug;\n\tcreateDebug.coerce = coerce;\n\tcreateDebug.disable = disable;\n\tcreateDebug.enable = enable;\n\tcreateDebug.enabled = enabled;\n\tcreateDebug.humanize = require('ms');\n\tcreateDebug.destroy = destroy;\n\n\tObject.keys(env).forEach(key => {\n\t\tcreateDebug[key] = env[key];\n\t});\n\n\t/**\n\t* The currently active debug mode names, and names to skip.\n\t*/\n\n\tcreateDebug.names = [];\n\tcreateDebug.skips = [];\n\n\t/**\n\t* Map of special \"%n\" handling functions, for the debug \"format\" argument.\n\t*\n\t* Valid key names are a single, lower or upper-case letter, i.e. \"n\" and \"N\".\n\t*/\n\tcreateDebug.formatters = {};\n\n\t/**\n\t* Selects a color for a debug namespace\n\t* @param {String} namespace The namespace string for the debug instance to be colored\n\t* @return {Number|String} An ANSI color code for the given namespace\n\t* @api private\n\t*/\n\tfunction selectColor(namespace) {\n\t\tlet hash = 0;\n\n\t\tfor (let i = 0; i < namespace.length; i++) {\n\t\t\thash = ((hash << 5) - hash) + namespace.charCodeAt(i);\n\t\t\thash |= 0; // Convert to 32bit integer\n\t\t}\n\n\t\treturn createDebug.colors[Math.abs(hash) % createDebug.colors.length];\n\t}\n\tcreateDebug.selectColor = selectColor;\n\n\t/**\n\t* Create a debugger with the given `namespace`.\n\t*\n\t* @param {String} namespace\n\t* @return {Function}\n\t* @api public\n\t*/\n\tfunction createDebug(namespace) {\n\t\tlet prevTime;\n\t\tlet enableOverride = null;\n\t\tlet namespacesCache;\n\t\tlet enabledCache;\n\n\t\tfunction debug(...args) {\n\t\t\t// Disabled?\n\t\t\tif (!debug.enabled) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst self = debug;\n\n\t\t\t// Set `diff` timestamp\n\t\t\tconst curr = Number(new Date());\n\t\t\tconst ms = curr - (prevTime || curr);\n\t\t\tself.diff = ms;\n\t\t\tself.prev = prevTime;\n\t\t\tself.curr = curr;\n\t\t\tprevTime = curr;\n\n\t\t\targs[0] = createDebug.coerce(args[0]);\n\n\t\t\tif (typeof args[0] !== 'string') {\n\t\t\t\t// Anything else let's inspect with %O\n\t\t\t\targs.unshift('%O');\n\t\t\t}\n\n\t\t\t// Apply any `formatters` transformations\n\t\t\tlet index = 0;\n\t\t\targs[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format) => {\n\t\t\t\t// If we encounter an escaped % then don't increase the array index\n\t\t\t\tif (match === '%%') {\n\t\t\t\t\treturn '%';\n\t\t\t\t}\n\t\t\t\tindex++;\n\t\t\t\tconst formatter = createDebug.formatters[format];\n\t\t\t\tif (typeof formatter === 'function') {\n\t\t\t\t\tconst val = args[index];\n\t\t\t\t\tmatch = formatter.call(self, val);\n\n\t\t\t\t\t// Now we need to remove `args[index]` since it's inlined in the `format`\n\t\t\t\t\targs.splice(index, 1);\n\t\t\t\t\tindex--;\n\t\t\t\t}\n\t\t\t\treturn match;\n\t\t\t});\n\n\t\t\t// Apply env-specific formatting (colors, etc.)\n\t\t\tcreateDebug.formatArgs.call(self, args);\n\n\t\t\tconst logFn = self.log || createDebug.log;\n\t\t\tlogFn.apply(self, args);\n\t\t}\n\n\t\tdebug.namespace = namespace;\n\t\tdebug.useColors = createDebug.useColors();\n\t\tdebug.color = createDebug.selectColor(namespace);\n\t\tdebug.extend = extend;\n\t\tdebug.destroy = createDebug.destroy; // XXX Temporary. Will be removed in the next major release.\n\n\t\tObject.defineProperty(debug, 'enabled', {\n\t\t\tenumerable: true,\n\t\t\tconfigurable: false,\n\t\t\tget: () => {\n\t\t\t\tif (enableOverride !== null) {\n\t\t\t\t\treturn enableOverride;\n\t\t\t\t}\n\t\t\t\tif (namespacesCache !== createDebug.namespaces) {\n\t\t\t\t\tnamespacesCache = createDebug.namespaces;\n\t\t\t\t\tenabledCache = createDebug.enabled(namespace);\n\t\t\t\t}\n\n\t\t\t\treturn enabledCache;\n\t\t\t},\n\t\t\tset: v => {\n\t\t\t\tenableOverride = v;\n\t\t\t}\n\t\t});\n\n\t\t// Env-specific initialization logic for debug instances\n\t\tif (typeof createDebug.init === 'function') {\n\t\t\tcreateDebug.init(debug);\n\t\t}\n\n\t\treturn debug;\n\t}\n\n\tfunction extend(namespace, delimiter) {\n\t\tconst newDebug = createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace);\n\t\tnewDebug.log = this.log;\n\t\treturn newDebug;\n\t}\n\n\t/**\n\t* Enables a debug mode by namespaces. This can include modes\n\t* separated by a colon and wildcards.\n\t*\n\t* @param {String} namespaces\n\t* @api public\n\t*/\n\tfunction enable(namespaces) {\n\t\tcreateDebug.save(namespaces);\n\t\tcreateDebug.namespaces = namespaces;\n\n\t\tcreateDebug.names = [];\n\t\tcreateDebug.skips = [];\n\n\t\tconst split = (typeof namespaces === 'string' ? namespaces : '')\n\t\t\t.trim()\n\t\t\t.replace(/\\s+/g, ',')\n\t\t\t.split(',')\n\t\t\t.filter(Boolean);\n\n\t\tfor (const ns of split) {\n\t\t\tif (ns[0] === '-') {\n\t\t\t\tcreateDebug.skips.push(ns.slice(1));\n\t\t\t} else {\n\t\t\t\tcreateDebug.names.push(ns);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Checks if the given string matches a namespace template, honoring\n\t * asterisks as wildcards.\n\t *\n\t * @param {String} search\n\t * @param {String} template\n\t * @return {Boolean}\n\t */\n\tfunction matchesTemplate(search, template) {\n\t\tlet searchIndex = 0;\n\t\tlet templateIndex = 0;\n\t\tlet starIndex = -1;\n\t\tlet matchIndex = 0;\n\n\t\twhile (searchIndex < search.length) {\n\t\t\tif (templateIndex < template.length && (template[templateIndex] === search[searchIndex] || template[templateIndex] === '*')) {\n\t\t\t\t// Match character or proceed with wildcard\n\t\t\t\tif (template[templateIndex] === '*') {\n\t\t\t\t\tstarIndex = templateIndex;\n\t\t\t\t\tmatchIndex = searchIndex;\n\t\t\t\t\ttemplateIndex++; // Skip the '*'\n\t\t\t\t} else {\n\t\t\t\t\tsearchIndex++;\n\t\t\t\t\ttemplateIndex++;\n\t\t\t\t}\n\t\t\t} else if (starIndex !== -1) { // eslint-disable-line no-negated-condition\n\t\t\t\t// Backtrack to the last '*' and try to match more characters\n\t\t\t\ttemplateIndex = starIndex + 1;\n\t\t\t\tmatchIndex++;\n\t\t\t\tsearchIndex = matchIndex;\n\t\t\t} else {\n\t\t\t\treturn false; // No match\n\t\t\t}\n\t\t}\n\n\t\t// Handle trailing '*' in template\n\t\twhile (templateIndex < template.length && template[templateIndex] === '*') {\n\t\t\ttemplateIndex++;\n\t\t}\n\n\t\treturn templateIndex === template.length;\n\t}\n\n\t/**\n\t* Disable debug output.\n\t*\n\t* @return {String} namespaces\n\t* @api public\n\t*/\n\tfunction disable() {\n\t\tconst namespaces = [\n\t\t\t...createDebug.names,\n\t\t\t...createDebug.skips.map(namespace => '-' + namespace)\n\t\t].join(',');\n\t\tcreateDebug.enable('');\n\t\treturn namespaces;\n\t}\n\n\t/**\n\t* Returns true if the given mode name is enabled, false otherwise.\n\t*\n\t* @param {String} name\n\t* @return {Boolean}\n\t* @api public\n\t*/\n\tfunction enabled(name) {\n\t\tfor (const skip of createDebug.skips) {\n\t\t\tif (matchesTemplate(name, skip)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tfor (const ns of createDebug.names) {\n\t\t\tif (matchesTemplate(name, ns)) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t* Coerce `val`.\n\t*\n\t* @param {Mixed} val\n\t* @return {Mixed}\n\t* @api private\n\t*/\n\tfunction coerce(val) {\n\t\tif (val instanceof Error) {\n\t\t\treturn val.stack || val.message;\n\t\t}\n\t\treturn val;\n\t}\n\n\t/**\n\t* XXX DO NOT USE. This is a temporary stub function.\n\t* XXX It WILL be removed in the next major release.\n\t*/\n\tfunction destroy() {\n\t\tconsole.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.');\n\t}\n\n\tcreateDebug.enable(createDebug.load());\n\n\treturn createDebug;\n}\n\nmodule.exports = setup;\n","/* eslint-env browser */\n\n/**\n * This is the web browser implementation of `debug()`.\n */\n\nexports.formatArgs = formatArgs;\nexports.save = save;\nexports.load = load;\nexports.useColors = useColors;\nexports.storage = localstorage();\nexports.destroy = (() => {\n\tlet warned = false;\n\n\treturn () => {\n\t\tif (!warned) {\n\t\t\twarned = true;\n\t\t\tconsole.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.');\n\t\t}\n\t};\n})();\n\n/**\n * Colors.\n */\n\nexports.colors = [\n\t'#0000CC',\n\t'#0000FF',\n\t'#0033CC',\n\t'#0033FF',\n\t'#0066CC',\n\t'#0066FF',\n\t'#0099CC',\n\t'#0099FF',\n\t'#00CC00',\n\t'#00CC33',\n\t'#00CC66',\n\t'#00CC99',\n\t'#00CCCC',\n\t'#00CCFF',\n\t'#3300CC',\n\t'#3300FF',\n\t'#3333CC',\n\t'#3333FF',\n\t'#3366CC',\n\t'#3366FF',\n\t'#3399CC',\n\t'#3399FF',\n\t'#33CC00',\n\t'#33CC33',\n\t'#33CC66',\n\t'#33CC99',\n\t'#33CCCC',\n\t'#33CCFF',\n\t'#6600CC',\n\t'#6600FF',\n\t'#6633CC',\n\t'#6633FF',\n\t'#66CC00',\n\t'#66CC33',\n\t'#9900CC',\n\t'#9900FF',\n\t'#9933CC',\n\t'#9933FF',\n\t'#99CC00',\n\t'#99CC33',\n\t'#CC0000',\n\t'#CC0033',\n\t'#CC0066',\n\t'#CC0099',\n\t'#CC00CC',\n\t'#CC00FF',\n\t'#CC3300',\n\t'#CC3333',\n\t'#CC3366',\n\t'#CC3399',\n\t'#CC33CC',\n\t'#CC33FF',\n\t'#CC6600',\n\t'#CC6633',\n\t'#CC9900',\n\t'#CC9933',\n\t'#CCCC00',\n\t'#CCCC33',\n\t'#FF0000',\n\t'#FF0033',\n\t'#FF0066',\n\t'#FF0099',\n\t'#FF00CC',\n\t'#FF00FF',\n\t'#FF3300',\n\t'#FF3333',\n\t'#FF3366',\n\t'#FF3399',\n\t'#FF33CC',\n\t'#FF33FF',\n\t'#FF6600',\n\t'#FF6633',\n\t'#FF9900',\n\t'#FF9933',\n\t'#FFCC00',\n\t'#FFCC33'\n];\n\n/**\n * Currently only WebKit-based Web Inspectors, Firefox >= v31,\n * and the Firebug extension (any Firefox version) are known\n * to support \"%c\" CSS customizations.\n *\n * TODO: add a `localStorage` variable to explicitly enable/disable colors\n */\n\n// eslint-disable-next-line complexity\nfunction useColors() {\n\t// NB: In an Electron preload script, document will be defined but not fully\n\t// initialized. Since we know we're in Chrome, we'll just detect this case\n\t// explicitly\n\tif (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) {\n\t\treturn true;\n\t}\n\n\t// Internet Explorer and Edge do not support colors.\n\tif (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\\/(\\d+)/)) {\n\t\treturn false;\n\t}\n\n\tlet m;\n\n\t// Is webkit? http://stackoverflow.com/a/16459606/376773\n\t// document is undefined in react-native: https://github.com/facebook/react-native/pull/1632\n\t// eslint-disable-next-line no-return-assign\n\treturn (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||\n\t\t// Is firebug? http://stackoverflow.com/a/398120/376773\n\t\t(typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||\n\t\t// Is firefox >= v31?\n\t\t// https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages\n\t\t(typeof navigator !== 'undefined' && navigator.userAgent && (m = navigator.userAgent.toLowerCase().match(/firefox\\/(\\d+)/)) && parseInt(m[1], 10) >= 31) ||\n\t\t// Double check webkit in userAgent just in case we are in a worker\n\t\t(typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\\/(\\d+)/));\n}\n\n/**\n * Colorize log arguments if enabled.\n *\n * @api public\n */\n\nfunction formatArgs(args) {\n\targs[0] = (this.useColors ? '%c' : '') +\n\t\tthis.namespace +\n\t\t(this.useColors ? ' %c' : ' ') +\n\t\targs[0] +\n\t\t(this.useColors ? '%c ' : ' ') +\n\t\t'+' + module.exports.humanize(this.diff);\n\n\tif (!this.useColors) {\n\t\treturn;\n\t}\n\n\tconst c = 'color: ' + this.color;\n\targs.splice(1, 0, c, 'color: inherit');\n\n\t// The final \"%c\" is somewhat tricky, because there could be other\n\t// arguments passed either before or after the %c, so we need to\n\t// figure out the correct index to insert the CSS into\n\tlet index = 0;\n\tlet lastC = 0;\n\targs[0].replace(/%[a-zA-Z%]/g, match => {\n\t\tif (match === '%%') {\n\t\t\treturn;\n\t\t}\n\t\tindex++;\n\t\tif (match === '%c') {\n\t\t\t// We only are interested in the *last* %c\n\t\t\t// (the user may have provided their own)\n\t\t\tlastC = index;\n\t\t}\n\t});\n\n\targs.splice(lastC, 0, c);\n}\n\n/**\n * Invokes `console.debug()` when available.\n * No-op when `console.debug` is not a \"function\".\n * If `console.debug` is not available, falls back\n * to `console.log`.\n *\n * @api public\n */\nexports.log = console.debug || console.log || (() => {});\n\n/**\n * Save `namespaces`.\n *\n * @param {String} namespaces\n * @api private\n */\nfunction save(namespaces) {\n\ttry {\n\t\tif (namespaces) {\n\t\t\texports.storage.setItem('debug', namespaces);\n\t\t} else {\n\t\t\texports.storage.removeItem('debug');\n\t\t}\n\t} catch (error) {\n\t\t// Swallow\n\t\t// XXX (@Qix-) should we be logging these?\n\t}\n}\n\n/**\n * Load `namespaces`.\n *\n * @return {String} returns the previously persisted debug modes\n * @api private\n */\nfunction load() {\n\tlet r;\n\ttry {\n\t\tr = exports.storage.getItem('debug') || exports.storage.getItem('DEBUG') ;\n\t} catch (error) {\n\t\t// Swallow\n\t\t// XXX (@Qix-) should we be logging these?\n\t}\n\n\t// If debug isn't set in LS, and we're in Electron, try to load $DEBUG\n\tif (!r && typeof process !== 'undefined' && 'env' in process) {\n\t\tr = process.env.DEBUG;\n\t}\n\n\treturn r;\n}\n\n/**\n * Localstorage attempts to return the localstorage.\n *\n * This is necessary because safari throws\n * when a user disables cookies/localstorage\n * and you attempt to access it.\n *\n * @return {LocalStorage}\n * @api private\n */\n\nfunction localstorage() {\n\ttry {\n\t\t// TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context\n\t\t// The Browser also has localStorage in the global context.\n\t\treturn localStorage;\n\t} catch (error) {\n\t\t// Swallow\n\t\t// XXX (@Qix-) should we be logging these?\n\t}\n}\n\nmodule.exports = require('./common')(exports);\n\nconst {formatters} = module.exports;\n\n/**\n * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.\n */\n\nformatters.j = function (v) {\n\ttry {\n\t\treturn JSON.stringify(v);\n\t} catch (error) {\n\t\treturn '[UnexpectedJSONParseError]: ' + error.message;\n\t}\n};\n","// source/ip-key-generator.ts\nimport { isIPv6 } from \"node:net\";\nimport { Address6 } from \"ip-address\";\nvar ipv4CompatibleSubnet = new Address6(\"::/96\");\nfunction ipKeyGenerator(ip, ipv6Subnet = 56) {\n if (isIPv6(ip)) {\n const address = new Address6(ip);\n if (address.isMapped4() || // The deprecated IPv4-compatible notation keeps its existing behavior.\n // Its range is shared with addresses that embed no IPv4 address at all\n // (`::`, `::1`), so here the notation is what tells them apart.\n address.is4() && address.isInSubnet(ipv4CompatibleSubnet))\n return address.to4().correctForm();\n if (ipv6Subnet) {\n const subnet = new Address6(`${ip}/${ipv6Subnet}`);\n return subnet.networkForm();\n }\n }\n return ip;\n}\n\n// source/memory-store.ts\nvar MemoryStore = class {\n constructor(validations2) {\n this.validations = validations2;\n /**\n * These two maps store usage (requests) and reset time by key (for example, IP\n * addresses or API keys).\n *\n * They are split into two to avoid having to iterate through the entire set to\n * determine which ones need reset. Instead, `Client`s are moved from `previous`\n * to `current` as they hit the endpoint. Once `windowMs` has elapsed, all clients\n * left in `previous`, i.e., those that have not made any recent requests, are\n * known to be expired and can be deleted in bulk.\n */\n this.previous = /* @__PURE__ */ new Map();\n this.current = /* @__PURE__ */ new Map();\n /**\n * Confirmation that the keys incremented in once instance of MemoryStore\n * cannot affect other instances.\n */\n this.localKeys = true;\n }\n /**\n * Method that initializes the store.\n *\n * @param options {Options} - The options used to setup the middleware.\n */\n init(options) {\n this.windowMs = options.windowMs;\n this.validations?.windowMs(this.windowMs);\n if (this.interval) clearInterval(this.interval);\n this.interval = setInterval(() => {\n this.clearExpired();\n }, this.windowMs);\n this.interval.unref?.();\n }\n /**\n * Method to fetch a client's hit count and reset time.\n *\n * @param key {string} - The identifier for a client.\n *\n * @returns {ClientRateLimitInfo | undefined} - The number of hits and reset time for that client.\n *\n * @public\n */\n async get(key) {\n return this.current.get(key) ?? this.previous.get(key);\n }\n /**\n * Method to increment a client's hit counter.\n *\n * @param key {string} - The identifier for a client.\n *\n * @returns {ClientRateLimitInfo} - The number of hits and reset time for that client.\n *\n * @public\n */\n async increment(key) {\n const client = this.getClient(key);\n const now = Date.now();\n if (client.resetTime.getTime() <= now) {\n this.resetClient(client, now);\n }\n client.totalHits++;\n return client;\n }\n /**\n * Method to decrement a client's hit counter.\n *\n * @param key {string} - The identifier for a client.\n *\n * @public\n */\n async decrement(key) {\n const client = this.getClient(key);\n if (client.totalHits > 0) client.totalHits--;\n }\n /**\n * Method to reset a client's hit counter.\n *\n * @param key {string} - The identifier for a client.\n *\n * @public\n */\n async resetKey(key) {\n this.current.delete(key);\n this.previous.delete(key);\n }\n /**\n * Method to reset everyone's hit counter.\n *\n * @public\n */\n async resetAll() {\n this.current.clear();\n this.previous.clear();\n }\n /**\n * Method to stop the timer (if currently running) and prevent any memory\n * leaks.\n *\n * @public\n */\n shutdown() {\n clearInterval(this.interval);\n void this.resetAll();\n }\n /**\n * Recycles a client by setting its hit count to zero, and reset time to\n * `windowMs` milliseconds from now.\n *\n * NOT to be confused with `#resetKey()`, which removes a client from both the\n * `current` and `previous` maps.\n *\n * @param client {Client} - The client to recycle.\n * @param now {number} - The current time, to which the `windowMs` is added to get the `resetTime` for the client.\n *\n * @return {Client} - The modified client that was passed in, to allow for chaining.\n */\n resetClient(client, now = Date.now()) {\n client.totalHits = 0;\n client.resetTime.setTime(now + this.windowMs);\n return client;\n }\n /**\n * Retrieves or creates a client, given a key. Also ensures that the client being\n * returned is in the `current` map.\n *\n * @param key {string} - The key under which the client is (or is to be) stored.\n *\n * @returns {Client} - The requested client.\n */\n getClient(key) {\n if (this.current.has(key)) return this.current.get(key);\n let client;\n if (this.previous.has(key)) {\n client = this.previous.get(key);\n this.previous.delete(key);\n } else {\n client = { totalHits: 0, resetTime: /* @__PURE__ */ new Date() };\n this.resetClient(client);\n }\n this.current.set(key, client);\n return client;\n }\n /**\n * Move current clients to previous, create a new map for current.\n *\n * This function is called every `windowMs`.\n */\n clearExpired() {\n this.previous = this.current;\n this.current = /* @__PURE__ */ new Map();\n }\n};\n\n// source/rate-limit.ts\nimport { isIPv6 as isIPv62 } from \"node:net\";\nimport createDebugLogger from \"debug\";\n\n// source/console-logger.ts\nvar ConsoleLogger = {\n warn(...args) {\n console.warn(...args.reverse());\n },\n error(...args) {\n console.error(...args.reverse());\n }\n};\n\n// source/headers.ts\nimport { Buffer } from \"node:buffer\";\nimport { createHash } from \"node:crypto\";\nvar SUPPORTED_DRAFT_VERSIONS = [\n \"draft-6\",\n \"draft-7\",\n \"draft-8\"\n];\nvar getResetSeconds = (windowMs, resetTime) => {\n let resetSeconds;\n if (resetTime) {\n const deltaSeconds = Math.ceil((resetTime.getTime() - Date.now()) / 1e3);\n resetSeconds = Math.max(0, deltaSeconds);\n } else {\n resetSeconds = Math.ceil(windowMs / 1e3);\n }\n return resetSeconds;\n};\nvar getPartitionKey = (key) => {\n const hash = createHash(\"sha256\");\n hash.update(key);\n const partitionKey = hash.digest(\"hex\").slice(0, 12);\n return Buffer.from(partitionKey).toString(\"base64\");\n};\nvar setLegacyHeaders = (response, info) => {\n if (response.headersSent) return;\n response.setHeader(\"X-RateLimit-Limit\", info.limit.toString());\n response.setHeader(\"X-RateLimit-Remaining\", info.remaining.toString());\n if (info.resetTime instanceof Date) {\n response.setHeader(\"Date\", (/* @__PURE__ */ new Date()).toUTCString());\n response.setHeader(\n \"X-RateLimit-Reset\",\n Math.ceil(info.resetTime.getTime() / 1e3).toString()\n );\n }\n};\nvar setDraft6Headers = (response, info, windowMs) => {\n if (response.headersSent) return;\n const windowSeconds = Math.ceil(windowMs / 1e3);\n const resetSeconds = getResetSeconds(windowMs, info.resetTime);\n response.setHeader(\"RateLimit-Policy\", `${info.limit};w=${windowSeconds}`);\n response.setHeader(\"RateLimit-Limit\", info.limit.toString());\n response.setHeader(\"RateLimit-Remaining\", info.remaining.toString());\n if (typeof resetSeconds === \"number\")\n response.setHeader(\"RateLimit-Reset\", resetSeconds.toString());\n};\nvar setDraft7Headers = (response, info, windowMs) => {\n if (response.headersSent) return;\n const windowSeconds = Math.ceil(windowMs / 1e3);\n const resetSeconds = getResetSeconds(windowMs, info.resetTime);\n response.setHeader(\"RateLimit-Policy\", `${info.limit};w=${windowSeconds}`);\n response.setHeader(\n \"RateLimit\",\n `limit=${info.limit}, remaining=${info.remaining}, reset=${resetSeconds}`\n );\n};\nvar setDraft8Headers = (response, info, windowMs, name, key) => {\n if (response.headersSent) return;\n const windowSeconds = Math.ceil(windowMs / 1e3);\n const resetSeconds = getResetSeconds(windowMs, info.resetTime);\n const partitionKey = getPartitionKey(key);\n const header = `r=${info.remaining}; t=${resetSeconds}`;\n const policy = `q=${info.limit}; w=${windowSeconds}; pk=:${partitionKey}:`;\n response.append(\"RateLimit\", `\"${name}\"; ${header}`);\n response.append(\"RateLimit-Policy\", `\"${name}\"; ${policy}`);\n};\nvar setRetryAfterHeader = (response, info, windowMs, retryAfter) => {\n if (response.headersSent) return;\n const resetSeconds = retryAfter ?? getResetSeconds(windowMs, info.resetTime);\n response.setHeader(\"Retry-After\", resetSeconds.toString());\n};\n\n// source/utils.ts\nvar omitUndefinedProperties = (passedOptions) => {\n const omittedOptions = {};\n for (const k of Object.keys(passedOptions)) {\n const key = k;\n if (passedOptions[key] !== void 0) {\n omittedOptions[key] = passedOptions[key];\n }\n }\n return omittedOptions;\n};\n\n// source/validations.ts\nimport { isIP } from \"node:net\";\nvar ValidationError = class extends Error {\n /**\n * The code must be a string, in snake case and all capital, that starts with\n * the substring `ERR_ERL_`.\n *\n * The message must be a string, starting with an uppercase character,\n * describing the issue in detail.\n */\n constructor(code, message) {\n const url = `https://express-rate-limit.github.io/${code}/`;\n super(`${message} See ${url} for more information.`);\n this.name = this.constructor.name;\n this.code = code;\n this.help = url;\n }\n};\nvar ChangeWarning = class extends ValidationError {\n};\nvar usedStores = /* @__PURE__ */ new Set();\nvar singleCountKeys = /* @__PURE__ */ new WeakMap();\nvar validations = {\n enabled: {\n default: true\n },\n // Should be EnabledValidations type, but that's a circular reference\n disable() {\n for (const k of Object.keys(this.enabled)) this.enabled[k] = false;\n },\n /**\n * Checks whether the IP address is valid, and that it does not have a port\n * number in it.\n *\n * See https://github.com/express-rate-limit/express-rate-limit/wiki/Error-Codes#err_erl_invalid_ip_address.\n *\n * @param ip {string | undefined} - The IP address provided by Express as request.ip.\n *\n * @returns {void}\n */\n ip(ip) {\n if (ip === void 0) {\n throw new ValidationError(\n \"ERR_ERL_UNDEFINED_IP_ADDRESS\",\n `An undefined 'request.ip' was detected. This might indicate a misconfiguration or the connection being destroyed prematurely.`\n );\n }\n if (!isIP(ip)) {\n throw new ValidationError(\n \"ERR_ERL_INVALID_IP_ADDRESS\",\n `An invalid 'request.ip' (${ip}) was detected. Consider passing a custom 'keyGenerator' function to the rate limiter.`\n );\n }\n },\n /**\n * Makes sure the trust proxy setting is not set to `true`.\n *\n * See https://github.com/express-rate-limit/express-rate-limit/wiki/Error-Codes#err_erl_permissive_trust_proxy.\n *\n * @param request {Request} - The Express request object.\n *\n * @returns {void}\n */\n trustProxy(request) {\n if (request.app.get(\"trust proxy\") === true) {\n throw new ValidationError(\n \"ERR_ERL_PERMISSIVE_TRUST_PROXY\",\n `The Express 'trust proxy' setting is true, which allows anyone to trivially bypass IP-based rate limiting.`\n );\n }\n },\n /**\n * Makes sure the trust proxy setting is set in case the `X-Forwarded-For`\n * header is present.\n *\n * See https://github.com/express-rate-limit/express-rate-limit/wiki/Error-Codes#err_erl_unset_trust_proxy.\n *\n * @param request {Request} - The Express request object.\n *\n * @returns {void}\n */\n xForwardedForHeader(request) {\n if (request.headers[\"x-forwarded-for\"] && request.app.get(\"trust proxy\") === false) {\n throw new ValidationError(\n \"ERR_ERL_UNEXPECTED_X_FORWARDED_FOR\",\n `The 'X-Forwarded-For' header is set but the Express 'trust proxy' setting is false (default). This could indicate a misconfiguration which would prevent express-rate-limit from accurately identifying users.`\n );\n }\n },\n /**\n * Alert the user if the Forwarded header is set (standardized version of X-Forwarded-For - not supported by express as of version 5.1.0)\n *\n * @param request {Request} - The Express request object.\n *\n * @returns {void}\n */\n forwardedHeader(request) {\n if (request.headers.forwarded && request.ip === request.socket?.remoteAddress) {\n throw new ValidationError(\n \"ERR_ERL_FORWARDED_HEADER\",\n `The 'Forwarded' header (standardized X-Forwarded-For) is set but currently being ignored. Add a custom keyGenerator to use a value from this header.`\n );\n }\n },\n /**\n * Ensures totalHits value from store is a positive integer.\n *\n * @param hits {any} - The `totalHits` returned by the store.\n */\n positiveHits(hits) {\n if (typeof hits !== \"number\" || hits < 1 || hits !== Math.round(hits)) {\n throw new ValidationError(\n \"ERR_ERL_INVALID_HITS\",\n `The totalHits value returned from the store must be a positive integer, got ${hits}`\n );\n }\n },\n /**\n * Ensures a single store instance is not used with multiple express-rate-limit instances\n */\n unsharedStore(store) {\n if (usedStores.has(store)) {\n const maybeUniquePrefix = store?.localKeys ? \"\" : \" (with a unique prefix)\";\n throw new ValidationError(\n \"ERR_ERL_STORE_REUSE\",\n `A Store instance must not be shared across multiple rate limiters. Create a new instance of ${store.constructor.name}${maybeUniquePrefix} for each limiter instead.`\n );\n }\n usedStores.add(store);\n },\n /**\n * Ensures a given key is incremented only once per request.\n *\n * @param request {Request} - The Express request object.\n * @param store {Store} - The store class.\n * @param key {string} - The key used to store the client's hit count.\n *\n * @returns {void}\n */\n singleCount(request, store, key) {\n let storeKeys = singleCountKeys.get(request);\n if (!storeKeys) {\n storeKeys = /* @__PURE__ */ new Map();\n singleCountKeys.set(request, storeKeys);\n }\n const storeKey = store.localKeys ? store : store.constructor.name;\n let keys = storeKeys.get(storeKey);\n if (!keys) {\n keys = [];\n storeKeys.set(storeKey, keys);\n }\n const prefixedKey = `${store.prefix ?? \"\"}${key}`;\n if (keys.includes(prefixedKey)) {\n throw new ValidationError(\n \"ERR_ERL_DOUBLE_COUNT\",\n `The hit count for ${key} was incremented more than once for a single request.`\n );\n }\n keys.push(prefixedKey);\n },\n /**\n * Warns the user that the behaviour for `max: 0` / `limit: 0` is\n * changing in the next major release.\n *\n * @param limit {number} - The maximum number of hits per client.\n *\n * @returns {void}\n */\n limit(limit) {\n if (limit === 0) {\n throw new ChangeWarning(\n \"WRN_ERL_MAX_ZERO\",\n \"Setting limit or max to 0 disables rate limiting in express-rate-limit v6 and older, but will cause all requests to be blocked in v7\"\n );\n }\n },\n /**\n * Warns the user that the `draft_polli_ratelimit_headers` option is deprecated\n * and will be removed in the next major release.\n *\n * @param draft_polli_ratelimit_headers {any | undefined} - The now-deprecated setting that was used to enable standard headers.\n *\n * @returns {void}\n */\n draftPolliHeaders(draft_polli_ratelimit_headers) {\n if (draft_polli_ratelimit_headers) {\n throw new ChangeWarning(\n \"WRN_ERL_DEPRECATED_DRAFT_POLLI_HEADERS\",\n `The draft_polli_ratelimit_headers configuration option is deprecated and has been removed in express-rate-limit v7, please set standardHeaders: 'draft-6' instead.`\n );\n }\n },\n /**\n * Warns the user that the `onLimitReached` option is deprecated and\n * will be removed in the next major release.\n *\n * @param onLimitReached {any | undefined} - The maximum number of hits per client.\n *\n * @returns {void}\n */\n onLimitReached(onLimitReached) {\n if (onLimitReached) {\n throw new ChangeWarning(\n \"WRN_ERL_DEPRECATED_ON_LIMIT_REACHED\",\n \"The onLimitReached configuration option is deprecated and has been removed in express-rate-limit v7.\"\n );\n }\n },\n /**\n * Warns the user when an invalid/unsupported version of the draft spec is passed.\n *\n * @param version {any | undefined} - The version passed by the user.\n *\n * @returns {void}\n */\n headersDraftVersion(version) {\n if (typeof version !== \"string\" || // @ts-expect-error This is fine. If version is not in the array, it will just return false.\n !SUPPORTED_DRAFT_VERSIONS.includes(version)) {\n const versionString = SUPPORTED_DRAFT_VERSIONS.join(\", \");\n throw new ValidationError(\n \"ERR_ERL_HEADERS_UNSUPPORTED_DRAFT_VERSION\",\n `standardHeaders: only the following versions of the IETF draft specification are supported: ${versionString}.`\n );\n }\n },\n /**\n * Warns the user when the selected headers option requires a reset time but\n * the store does not provide one.\n *\n * @param resetTime {Date | undefined} - The timestamp when the client's hit count will be reset.\n *\n * @returns {void}\n */\n headersResetTime(resetTime) {\n if (!resetTime) {\n throw new ValidationError(\n \"ERR_ERL_HEADERS_NO_RESET\",\n `standardHeaders: 'draft-7' requires a 'resetTime', but the store did not provide one. The 'windowMs' value will be used instead, which may cause clients to wait longer than necessary.`\n );\n }\n },\n knownOptions(passedOptions) {\n if (!passedOptions) return;\n const optionsMap = {\n windowMs: true,\n limit: true,\n message: true,\n statusCode: true,\n legacyHeaders: true,\n standardHeaders: true,\n identifier: true,\n retryAfter: true,\n requestPropertyName: true,\n skipFailedRequests: true,\n skipSuccessfulRequests: true,\n keyGenerator: true,\n ipv6Subnet: true,\n handler: true,\n skip: true,\n requestWasSuccessful: true,\n store: true,\n validate: true,\n headers: true,\n max: true,\n passOnStoreError: true,\n logger: true\n };\n const validOptions = Object.keys(optionsMap).concat(\n \"draft_polli_ratelimit_headers\",\n // not a valid option anymore, but we have a more specific check for this one, so don't warn for it here\n // from express-slow-down - https://github.com/express-rate-limit/express-slow-down/blob/main/source/types.ts#L65\n \"delayAfter\",\n \"delayMs\",\n \"maxDelayMs\"\n );\n for (const key of Object.keys(passedOptions)) {\n if (!validOptions.includes(key)) {\n throw new ValidationError(\n \"ERR_ERL_UNKNOWN_OPTION\",\n `Unexpected configuration option: ${key}`\n // todo: suggest a valid option with a short levenstein distance?\n );\n }\n }\n },\n /**\n * Checks the options.validate setting to ensure that only recognized\n * validations are enabled or disabled.\n *\n * If any unrecognized values are found, an error is logged that\n * includes the list of supported validations.\n */\n validationsConfig() {\n const supportedValidations = Object.keys(this).filter(\n (k) => ![\"enabled\", \"disable\"].includes(k)\n );\n supportedValidations.push(\"default\");\n for (const key of Object.keys(this.enabled)) {\n if (!supportedValidations.includes(key)) {\n throw new ValidationError(\n \"ERR_ERL_UNKNOWN_VALIDATION\",\n `options.validate.${key} is not recognized. Supported validate options are: ${supportedValidations.join(\n \", \"\n )}.`\n );\n }\n }\n },\n /**\n * Checks to see if the instance was created inside of a request handler,\n * which would prevent it from working correctly, with the default memory\n * store (or any other store with localKeys.)\n */\n creationStack(store) {\n const { stack } = new Error(\n \"express-rate-limit validation check (set options.validate.creationStack=false to disable)\"\n );\n if (stack?.includes(\"Layer.handle [as handle_request]\") || // express v4\n stack?.includes(\"Layer.handleRequest\")) {\n if (!store.localKeys) {\n throw new ValidationError(\n \"ERR_ERL_CREATED_IN_REQUEST_HANDLER\",\n \"express-rate-limit instance should *usually* be created at app initialization, not when responding to a request.\"\n );\n }\n throw new ValidationError(\n \"ERR_ERL_CREATED_IN_REQUEST_HANDLER\",\n \"express-rate-limit instance should be created at app initialization, not when responding to a request.\"\n );\n }\n },\n ipv6Subnet(ipv6Subnet) {\n if (ipv6Subnet === false) {\n return;\n }\n if (!Number.isInteger(ipv6Subnet) || ipv6Subnet < 32 || ipv6Subnet > 64) {\n throw new ValidationError(\n \"ERR_ERL_IPV6_SUBNET\",\n `Unexpected ipv6Subnet value: ${ipv6Subnet}. Expected an integer between 32 and 64 (usually 48-64).`\n );\n }\n },\n ipv6SubnetOrKeyGenerator(options) {\n if (options.ipv6Subnet !== void 0 && options.keyGenerator) {\n throw new ValidationError(\n \"ERR_ERL_IPV6SUBNET_OR_KEYGENERATOR\",\n `Incompatible options: the 'ipv6Subnet' option is ignored when a custom 'keyGenerator' function is also set.`\n );\n }\n },\n keyGeneratorIpFallback(keyGenerator) {\n if (!keyGenerator) {\n return;\n }\n const src = keyGenerator.toString();\n if ((src.includes(\"req.ip\") || src.includes(\"request.ip\")) && !src.includes(\"ipKeyGenerator\")) {\n throw new ValidationError(\n \"ERR_ERL_KEY_GEN_IPV6\",\n \"Custom keyGenerator appears to use request IP without calling the ipKeyGenerator helper function for IPv6 addresses. This could allow IPv6 users to bypass limits.\"\n );\n }\n },\n /**\n * Checks to see if the window duration is greater than 2^32 - 1. This is only\n * called by the default MemoryStore, since it uses Node's setInterval method.\n *\n * See https://nodejs.org/api/timers.html#setintervalcallback-delay-args.\n */\n windowMs(windowMs) {\n const SET_TIMEOUT_MAX = 2 ** 31 - 1;\n if (typeof windowMs !== \"number\" || Number.isNaN(windowMs) || windowMs < 1 || windowMs > SET_TIMEOUT_MAX) {\n throw new ValidationError(\n \"ERR_ERL_WINDOW_MS\",\n `Invalid windowMs value: ${windowMs}${typeof windowMs !== \"number\" ? ` (${typeof windowMs})` : \"\"}, must be a number between 1 and ${SET_TIMEOUT_MAX} when using the default MemoryStore`\n );\n }\n }\n};\nfunction validateLogger(logger) {\n if (typeof logger !== \"object\" || typeof logger.error !== \"function\" || typeof logger.warn !== \"function\") {\n throw new TypeError(\n \"Provided logger does not implement the Logger interface\"\n );\n }\n}\nvar getValidations = (_enabled, logger) => {\n validateLogger(logger);\n let enabled;\n if (typeof _enabled === \"boolean\") {\n enabled = {\n default: _enabled\n };\n } else {\n enabled = {\n default: true,\n ..._enabled\n };\n }\n const wrappedValidations = { enabled };\n for (const [name, validation] of Object.entries(validations)) {\n if (typeof validation === \"function\")\n wrappedValidations[name] = (...args) => {\n if (!(enabled[name] ?? enabled.default)) {\n return;\n }\n enabled[name] = false;\n try {\n ;\n validation.apply(\n wrappedValidations,\n args\n );\n } catch (error) {\n if (error instanceof ChangeWarning) logger.warn(error);\n else logger.error(error);\n }\n };\n }\n const inspect = /* @__PURE__ */ Symbol.for(\"nodejs.util.inspect.custom\");\n if (inspect)\n wrappedValidations[inspect] = () => wrappedValidations.enabled;\n return wrappedValidations;\n};\n\n// source/rate-limit.ts\nvar isLegacyStore = (store) => (\n // Check that `incr` exists but `increment` does not - store authors might want\n // to keep both around for backwards compatibility.\n typeof store.incr === \"function\" && typeof store.increment !== \"function\"\n);\nvar promisifyStore = (passedStore) => {\n if (!isLegacyStore(passedStore)) {\n return passedStore;\n }\n const legacyStore = passedStore;\n class PromisifiedStore {\n async increment(key) {\n return new Promise((resolve, reject) => {\n legacyStore.incr(\n key,\n (error, totalHits, resetTime) => {\n if (error) reject(error);\n resolve({ totalHits, resetTime });\n }\n );\n });\n }\n async decrement(key) {\n return legacyStore.decrement(key);\n }\n async resetKey(key) {\n return legacyStore.resetKey(key);\n }\n /* istanbul ignore next */\n async resetAll() {\n if (typeof legacyStore.resetAll === \"function\")\n return legacyStore.resetAll();\n }\n }\n return new PromisifiedStore();\n};\nvar getOptionsFromConfig = (config) => {\n const { validations: validations2, ...directlyPassableEntries } = config;\n return {\n ...directlyPassableEntries,\n validate: validations2.enabled\n };\n};\nvar parseOptions = (passedOptions) => {\n const notUndefinedOptions = omitUndefinedProperties(passedOptions);\n const logger = passedOptions.logger ?? ConsoleLogger;\n const validations2 = getValidations(\n notUndefinedOptions?.validate ?? true,\n logger\n );\n validations2.validationsConfig();\n validations2.knownOptions(passedOptions);\n validations2.draftPolliHeaders(\n // @ts-expect-error see the note above.\n notUndefinedOptions.draft_polli_ratelimit_headers\n );\n validations2.onLimitReached(notUndefinedOptions.onLimitReached);\n if (notUndefinedOptions.ipv6Subnet !== void 0 && typeof notUndefinedOptions.ipv6Subnet !== \"function\") {\n validations2.ipv6Subnet(notUndefinedOptions.ipv6Subnet);\n }\n validations2.keyGeneratorIpFallback(notUndefinedOptions.keyGenerator);\n validations2.ipv6SubnetOrKeyGenerator(notUndefinedOptions);\n let standardHeaders = notUndefinedOptions.standardHeaders ?? false;\n if (standardHeaders === true) standardHeaders = \"draft-6\";\n const config = {\n windowMs: 60 * 1e3,\n limit: passedOptions.max ?? 5,\n // `max` is deprecated, but support it anyways.\n message: \"Too many requests, please try again later.\",\n statusCode: 429,\n legacyHeaders: passedOptions.headers ?? true,\n identifier(request, _response) {\n let duration = \"\";\n const property = config.requestPropertyName;\n const { limit } = request[property];\n const seconds = config.windowMs / 1e3;\n const minutes = config.windowMs / (1e3 * 60);\n const hours = config.windowMs / (1e3 * 60 * 60);\n const days = config.windowMs / (1e3 * 60 * 60 * 24);\n if (seconds < 60) duration = `${seconds}sec`;\n else if (minutes < 60) duration = `${minutes}min`;\n else if (hours < 24) duration = `${hours}hr${hours > 1 ? \"s\" : \"\"}`;\n else duration = `${days}day${days > 1 ? \"s\" : \"\"}`;\n return `${limit}-in-${duration}`;\n },\n requestPropertyName: \"rateLimit\",\n skipFailedRequests: false,\n skipSuccessfulRequests: false,\n requestWasSuccessful: (_request, response) => response.statusCode < 400,\n skip: (_request, _response) => false,\n async keyGenerator(request, response) {\n validations2.ip(request.ip);\n validations2.trustProxy(request);\n validations2.xForwardedForHeader(request);\n validations2.forwardedHeader(request);\n const ip = request.ip;\n let subnet = 56;\n if (isIPv62(ip)) {\n subnet = typeof config.ipv6Subnet === \"function\" ? await config.ipv6Subnet(request, response) : config.ipv6Subnet;\n if (typeof config.ipv6Subnet === \"function\")\n validations2.ipv6Subnet(subnet);\n }\n return ipKeyGenerator(ip, subnet);\n },\n ipv6Subnet: 56,\n async handler(request, response, _next, _optionsUsed) {\n response.status(config.statusCode);\n const message = typeof config.message === \"function\" ? await config.message(\n request,\n response\n ) : config.message;\n if (!response.writableEnded) response.send(message);\n },\n passOnStoreError: false,\n // Allow the default options to be overridden by the passed options.\n ...notUndefinedOptions,\n // `standardHeaders` is resolved into a draft version above, use that.\n standardHeaders,\n // Note that this field is declared after the user's options are spread in,\n // so that this field doesn't get overridden with an un-promisified store!\n store: promisifyStore(\n notUndefinedOptions.store ?? new MemoryStore(validations2)\n ),\n // Print an error to the console if a few known misconfigurations are detected.\n validations: validations2,\n logger\n };\n if (typeof config.store.increment !== \"function\" || typeof config.store.decrement !== \"function\" || typeof config.store.resetKey !== \"function\" || config.store.resetAll !== void 0 && typeof config.store.resetAll !== \"function\" || config.store.init !== void 0 && typeof config.store.init !== \"function\") {\n throw new TypeError(\n \"An invalid store was passed. Please ensure that the store is a class that implements the `Store` interface.\"\n );\n }\n return config;\n};\nvar handleAsyncErrors = (fn) => async (request, response, next) => {\n try {\n await Promise.resolve(fn(request, response, next)).catch(next);\n } catch (error) {\n next(error);\n }\n};\nvar rateLimit = (passedOptions) => {\n const config = parseOptions(passedOptions ?? {});\n const options = getOptionsFromConfig(config);\n const debug = createDebugLogger(\"express-rate-limit\");\n debug(\"creating new rate limiter with %o\", config.store.constructor.name);\n for (const [key, val] of Object.entries(config))\n debug(\"set %s to %o\", key, val);\n config.validations.creationStack(config.store);\n config.validations.unsharedStore(config.store);\n if (typeof config.store.init === \"function\") {\n debug(\"executing init for store\");\n try {\n const storeInit = config.store.init(options);\n if (storeInit instanceof Promise) {\n storeInit.catch(\n (error) => config.logger.error(\n error,\n \"express-rate-limit: async error during store initialization.\"\n )\n );\n }\n } catch (error) {\n config.logger.error(\n error,\n \"express-rate-limit: error during store initialization.\"\n );\n }\n }\n const middleware = handleAsyncErrors(\n async (request, response, next) => {\n const closePromise = config.skipFailedRequests && new Promise((resolve) => response.once(\"close\", resolve));\n const finishPromise = (config.skipFailedRequests || config.skipSuccessfulRequests) && new Promise((resolve) => response.once(\"finish\", resolve));\n const errorPromise = config.skipFailedRequests && new Promise((resolve) => response.once(\"error\", resolve));\n debug(\"requested %o\", request.originalUrl);\n debug(\"request from ip %o\", request.ip);\n const skip = await config.skip(request, response);\n if (skip) {\n debug(\"skipping request\");\n next();\n return;\n }\n const augmentedRequest = request;\n const key = await config.keyGenerator(request, response);\n debug(\"computed key %o\", key);\n debug(\"incrementing count\");\n let totalHits = 0;\n let resetTime;\n try {\n const incrementResult = await config.store.increment(key);\n totalHits = incrementResult.totalHits;\n resetTime = incrementResult.resetTime;\n } catch (error) {\n if (config.passOnStoreError) {\n config.logger.error(\n error,\n \"express-rate-limit: error from store, allowing request without rate-limiting.\"\n );\n next();\n return;\n }\n throw error;\n }\n config.validations.positiveHits(totalHits);\n config.validations.singleCount(request, config.store, key);\n const retrieveLimit = typeof config.limit === \"function\" ? config.limit(request, response) : config.limit;\n const limit = await retrieveLimit;\n config.validations.limit(limit);\n const info = {\n limit,\n used: totalHits,\n remaining: Math.max(limit - totalHits, 0),\n resetTime,\n key\n };\n for (const [key2, val] of Object.entries(info))\n debug(\n \"set request.%s.%s to be %o\",\n config.requestPropertyName,\n key2,\n val\n );\n Object.defineProperty(info, \"current\", {\n configurable: false,\n enumerable: false,\n value: totalHits\n });\n augmentedRequest[config.requestPropertyName] = info;\n if (config.legacyHeaders && !response.headersSent) {\n debug(\"set legacy headers\");\n setLegacyHeaders(response, info);\n }\n if (config.standardHeaders && !response.headersSent) {\n switch (config.standardHeaders) {\n case \"draft-6\": {\n debug(\"set ietf draft 6 headers\");\n setDraft6Headers(response, info, config.windowMs);\n break;\n }\n case \"draft-7\": {\n debug(\"set ietf draft 7 headers\");\n config.validations.headersResetTime(info.resetTime);\n setDraft7Headers(response, info, config.windowMs);\n break;\n }\n case \"draft-8\": {\n const retrieveName = typeof config.identifier === \"function\" ? config.identifier(request, response) : config.identifier;\n const name = await retrieveName;\n debug(\"set ietf draft 8 headers\");\n debug(\"set name to %o\", name);\n config.validations.headersResetTime(info.resetTime);\n setDraft8Headers(response, info, config.windowMs, name, key);\n break;\n }\n default: {\n config.validations.headersDraftVersion(config.standardHeaders);\n break;\n }\n }\n }\n if (config.skipFailedRequests || config.skipSuccessfulRequests) {\n let decremented = false;\n const decrementKey = async () => {\n if (!decremented) {\n if (resetTime && Date.now() >= resetTime.getTime()) {\n return;\n }\n debug(\"decrementing count\");\n await config.store.decrement(key);\n decremented = true;\n }\n };\n if (config.skipFailedRequests) {\n if (finishPromise) {\n void finishPromise.then(async () => {\n const success = await config.requestWasSuccessful(\n request,\n response\n );\n debug(\"computed requestWasSuccessful as %o\", success);\n if (!success) await decrementKey();\n });\n }\n if (closePromise) {\n void closePromise.then(async () => {\n if (!response.writableEnded) await decrementKey();\n });\n }\n if (errorPromise) {\n void errorPromise.then(async () => {\n await decrementKey();\n });\n }\n }\n if (config.skipSuccessfulRequests) {\n if (finishPromise) {\n void finishPromise.then(async () => {\n const success = await config.requestWasSuccessful(\n request,\n response\n );\n debug(\"computed requestWasSuccessful as %o\", success);\n if (success) await decrementKey();\n });\n }\n }\n }\n if (totalHits > limit) {\n debug(\"limit exceeded\");\n if (config.legacyHeaders || config.standardHeaders) {\n debug(\"set retry-after header\");\n const retrieveRetryAfter = typeof config.retryAfter === \"function\" ? config.retryAfter(request, response) : config.retryAfter;\n const retryAfter = await retrieveRetryAfter;\n setRetryAfterHeader(response, info, config.windowMs, retryAfter);\n }\n config.handler(request, response, next, options);\n return;\n }\n next();\n }\n );\n const getThrowFn = () => {\n throw new Error(\"The current store does not support the get/getKey method\");\n };\n middleware.resetKey = config.store.resetKey.bind(config.store);\n middleware.getKey = typeof config.store.get === \"function\" ? config.store.get.bind(config.store) : getThrowFn;\n return middleware;\n};\nvar rate_limit_default = rateLimit;\n\n// source/time-constants.ts\nvar SECOND = 1e3;\nvar MINUTE = 60 * SECOND;\nvar HOUR = 60 * MINUTE;\nvar DAY = 24 * HOUR;\nexport {\n DAY,\n HOUR,\n MINUTE,\n MemoryStore,\n SECOND,\n rate_limit_default as default,\n ipKeyGenerator,\n rate_limit_default as rateLimit\n};\n","/**\n * @codemem/mcp — privacy-safe OAuth audit events.\n *\n * Phase 1 single-user remote MCP needs operator-visible security events\n * (registration, authorize, OIDC callback, token issuance, revocation, bearer\n * verification) without ever logging bearer tokens, authorization codes,\n * client secrets, OIDC ID tokens, or private memory contents.\n */\n\nexport type OAuthAuditKind =\n\t| \"registration\"\n\t| \"authorize\"\n\t| \"oidc_callback\"\n\t| \"token\"\n\t| \"refresh\"\n\t| \"rotation\"\n\t| \"revocation\"\n\t| \"bearer\";\n\nexport type OAuthAuditOutcome = \"success\" | \"denied\" | \"error\";\n\nexport type BearerDenyReason =\n\t| \"missing_authorization_header\"\n\t| \"malformed_authorization_header\"\n\t| \"unknown_token\"\n\t| \"expired_token\"\n\t| \"revoked_token\";\n\nexport interface OAuthAuditEventBase {\n\ttimestamp: string;\n\toutcome: OAuthAuditOutcome;\n\treason?: string;\n\tclientId?: string;\n\tremoteAddress?: string;\n}\n\nexport type OAuthAuditEvent = OAuthAuditEventBase & { kind: OAuthAuditKind };\n\nexport type OAuthAuditEmitter = (event: OAuthAuditEvent) => void;\n\n// Canonicalized denylist — keys are compared after lowercasing and stripping\n// non-alphanumeric separators, so `access_token`, `accessToken`, `ACCESS-TOKEN`\n// and `access token` all reduce to `accesstoken` and are blocked uniformly.\n// This codebase commonly uses camelCase identifiers, so a snake_case-only\n// denylist would miss real leak vectors.\nconst FORBIDDEN_KEY_TOKENS = new Set([\n\t\"token\",\n\t\"accesstoken\",\n\t\"refreshtoken\",\n\t\"idtoken\",\n\t\"code\",\n\t\"codeverifier\",\n\t\"codechallenge\",\n\t\"clientsecret\",\n\t\"authorization\",\n\t\"password\",\n\t\"secret\",\n]);\n\nfunction canonicalizeAuditKey(key: string): string {\n\treturn key.toLowerCase().replace(/[^a-z0-9]/g, \"\");\n}\n\n/**\n * Build an audit event with redaction safety. Throws if a forbidden field\n * leaks in; callers should never need to pass token/code material here.\n */\nexport function buildOAuthAuditEvent(\n\tkind: OAuthAuditKind,\n\tfields: Omit<OAuthAuditEventBase, \"timestamp\"> & { now?: number },\n): OAuthAuditEvent {\n\tfor (const key of Object.keys(fields)) {\n\t\tif (FORBIDDEN_KEY_TOKENS.has(canonicalizeAuditKey(key))) {\n\t\t\tthrow new Error(`OAuth audit event must not carry forbidden field: ${key}`);\n\t\t}\n\t}\n\tconst { now, ...rest } = fields;\n\treturn {\n\t\tkind,\n\t\ttimestamp: new Date(now ?? Date.now()).toISOString(),\n\t\t...rest,\n\t};\n}\n\n/**\n * Wrap an audit emitter so any synchronous throw or stream-write failure stays\n * contained. Audit logging is best-effort observability and must never break\n * the OAuth/MCP request flow it observes. Failures are reported once per\n * process to `console.error` so they remain visible without flooding output.\n */\nexport function wrapAuditEmitterBestEffort(emit: OAuthAuditEmitter): OAuthAuditEmitter {\n\tlet reportedFailure = false;\n\treturn (event) => {\n\t\ttry {\n\t\t\temit(event);\n\t\t} catch (err) {\n\t\t\tif (!reportedFailure) {\n\t\t\t\treportedFailure = true;\n\t\t\t\tconsole.error(\"codemem MCP OAuth audit emitter failed (further failures suppressed):\", err);\n\t\t\t}\n\t\t}\n\t};\n}\n\n/**\n * Default audit emitter writes one JSON object per line to stderr. This keeps\n * MCP HTTP stdout reserved for protocol traffic and is greppable by operators\n * via `journalctl` or a redirected log file.\n */\nexport function createDefaultOAuthAuditEmitter(\n\tstream: NodeJS.WriteStream = process.stderr,\n): OAuthAuditEmitter {\n\treturn (event) => {\n\t\tstream.write(`${JSON.stringify({ source: \"codemem-mcp-oauth-audit\", ...event })}\\n`);\n\t};\n}\n\n/**\n * No-op emitter, used when CODEMEM_MCP_AUDIT=0 or when callers explicitly\n * want to suppress audit output (for example, embedded tests).\n */\nexport function createSilentOAuthAuditEmitter(): OAuthAuditEmitter {\n\treturn () => {};\n}\n\n/**\n * Resolve an emitter from environment configuration. `CODEMEM_MCP_AUDIT=0`,\n * `false`, or `no` disables audit logging; anything else (including unset)\n * uses the default stderr emitter.\n */\nexport function resolveOAuthAuditEmitterFromEnv(\n\tvalue = process.env.CODEMEM_MCP_AUDIT,\n): OAuthAuditEmitter {\n\tconst normalized = value?.trim().toLowerCase();\n\tif (normalized === \"0\" || normalized === \"false\" || normalized === \"no\") {\n\t\treturn createSilentOAuthAuditEmitter();\n\t}\n\treturn createDefaultOAuthAuditEmitter();\n}\n","import { createHash, createHmac, randomBytes, randomUUID, timingSafeEqual } from \"node:crypto\";\nimport { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from \"node:fs\";\nimport { chmod } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport type { OAuthRegisteredClientsStore } from \"@modelcontextprotocol/sdk/server/auth/clients.js\";\nimport { InvalidClientMetadataError } from \"@modelcontextprotocol/sdk/server/auth/errors.js\";\nimport type { OAuthServerProvider } from \"@modelcontextprotocol/sdk/server/auth/provider.js\";\nimport { createOAuthMetadata } from \"@modelcontextprotocol/sdk/server/auth/router.js\";\nimport {\n\ttype OAuthClientInformationFull,\n\ttype OAuthClientMetadata,\n\tOAuthClientMetadataSchema,\n\ttype OAuthErrorResponse,\n\ttype OAuthMetadata,\n\ttype OAuthProtectedResourceMetadata,\n\tOAuthProtectedResourceMetadataSchema,\n\ttype OAuthTokens,\n\tOAuthTokensSchema,\n} from \"@modelcontextprotocol/sdk/shared/auth.js\";\n\nexport const MCP_OAUTH_PUBLIC_URL_ENV = \"CODEMEM_MCP_HTTP_PUBLIC_URL\";\nexport const MCP_OAUTH_RESOURCE_NAME = \"codemem MCP\";\nexport const MCP_OAUTH_SCOPES_SUPPORTED = [\"memory:read\", \"memory:write\"];\nexport const MCP_OAUTH_SERVICE_DOCUMENTATION_URL = \"https://github.com/kunickiaj/codemem#readme\";\n\nconst CLAUDE_HOSTED_CALLBACK = \"https://claude.ai/api/mcp/auth_callback\";\nconst CHATGPT_LEGACY_HOSTED_CALLBACK = \"https://chatgpt.com/connector_platform_oauth_redirect\";\nconst LOCAL_CALLBACK_HOSTS = new Set([\"localhost\", \"127.0.0.1\", \"::1\"]);\nconst SUPPORTED_GRANT_TYPES = new Set([\"authorization_code\", \"refresh_token\"]);\nconst SUPPORTED_RESPONSE_TYPES = new Set([\"code\"]);\nconst AUTHORIZATION_CODE_TTL_MS = 5 * 60 * 1000;\nconst ACCESS_TOKEN_TTL_SECONDS = 60 * 60;\nconst REFRESH_TOKEN_TTL_SECONDS = 30 * 24 * 60 * 60;\nconst MAX_AUTHORIZATION_CODES = 100;\nconst MAX_ACCESS_TOKENS = 100;\nconst MAX_REFRESH_GRANTS = 100;\nconst ACCESS_TOKEN_BYTES = 32;\nconst ACCESS_TOKEN_BASE64URL_LENGTH = 43;\nconst ACCESS_TOKEN_BASE64URL = /^[A-Za-z0-9_-]{43}$/;\nconst PKCE_S256_CHALLENGE = /^[A-Za-z0-9_-]{43}$/;\nconst PKCE_VERIFIER = /^[A-Za-z0-9._~-]{43,128}$/;\nconst CHATGPT_CONNECTOR_ID = /^[A-Za-z0-9_-]{1,128}$/;\n\nexport interface McpOAuthMetadataOptions {\n\tmcpUrl: string;\n\tclientsStore: OAuthRegisteredClientsStore;\n}\n\nexport interface RegisteredMcpOAuthClient {\n\tstatus: 201;\n\tbody: OAuthClientInformationFull;\n}\n\nexport interface McpOAuthRegistrationError {\n\tstatus: 400;\n\tbody: { error: \"invalid_client_metadata\"; error_description: string };\n}\n\nexport interface AuthorizationCodeRecord {\n\tclientId: string;\n\tredirectUri: string;\n\tcodeChallenge: string;\n\tscopes: string[];\n\tresource?: string;\n\texpiresAt: number;\n\tused: boolean;\n}\n\nexport interface OAuthAuthorizationCodeStore {\n\tissueCode(record: Omit<AuthorizationCodeRecord, \"used\">, now?: number): string | undefined;\n\tpeekCode(code: string): AuthorizationCodeRecord | undefined;\n\tconsumeCode(code: string): AuthorizationCodeRecord | undefined;\n}\n\nexport interface AccessTokenRecord {\n\tclientId: string;\n\tgrantId?: string;\n\tscopes: string[];\n\tresource?: string;\n\ttokenHash: string;\n\tissuedAt: number;\n\texpiresAt: number;\n\tlastUsedAt: number | null;\n\trevokedAt: number | null;\n}\n\nexport type AccessTokenVerificationResult =\n\t| { ok: true; record: AccessTokenRecord }\n\t| { ok: false; reason: \"unknown_token\" | \"expired_token\" | \"revoked_token\" };\n\nexport interface OAuthAccessTokenStore {\n\tissueToken(\n\t\tclientId: string,\n\t\tnow?: number,\n\t\tresource?: string,\n\t\tgrantId?: string,\n\t\tscopes?: string[],\n\t): { token: string; expiresIn: number } | undefined;\n\tverifyToken(token: string, now?: number): AccessTokenVerificationResult;\n\trevokeToken(token: string, now?: number): boolean;\n\trevokeTokensForGrant?(grantId: string, now?: number): number;\n}\n\nexport interface RefreshTokenGrantRecord {\n\tgrantId: string;\n\tclientId: string;\n\tscopes: string[];\n\tresource?: string;\n\tcurrentRefreshTokenHash: string;\n\tpreviousRefreshTokenHash: string | null;\n\tissuedAt: number;\n\texpiresAt: number;\n\trotatedAt: number | null;\n\trevokedAt: number | null;\n}\n\nexport type RefreshTokenRotationResult =\n\t| { ok: true; grant: RefreshTokenGrantRecord; refreshToken: string; expiresIn: number }\n\t| {\n\t\t\tok: false;\n\t\t\treason:\n\t\t\t\t| \"unknown_refresh_token\"\n\t\t\t\t| \"expired_refresh_token\"\n\t\t\t\t| \"revoked_refresh_token\"\n\t\t\t\t| \"client_mismatch\"\n\t\t\t\t| \"scope_mismatch\"\n\t\t\t\t| \"resource_mismatch\"\n\t\t\t\t| \"refresh_token_replay\";\n\t\t\tgrantId?: string;\n\t };\n\nexport interface OAuthRefreshTokenStore {\n\tissueGrant(\n\t\trecord: { clientId: string; scopes?: string[]; resource?: string },\n\t\tnow?: number,\n\t): { grant: RefreshTokenGrantRecord; refreshToken: string; expiresIn: number } | undefined;\n\trotateRefreshToken(\n\t\tclientId: string,\n\t\trefreshToken: string,\n\t\toptions?: { scopes?: string[]; resource?: string },\n\t\tnow?: number,\n\t): RefreshTokenRotationResult;\n\trevokeRefreshToken(token: string, now?: number): string | undefined;\n\trevokeGrant(grantId: string, now?: number): boolean;\n}\n\nexport interface McpOAuthRedirectResult {\n\tstatus: 302;\n\tlocation: string;\n}\n\nexport interface McpOAuthErrorResult {\n\tstatus: 400;\n\tbody: OAuthErrorResponse;\n}\n\nexport interface McpOAuthTokenResult {\n\tstatus: 200;\n\tbody: OAuthTokens;\n}\n\nexport interface PreparedMcpOAuthAuthorizationRequest {\n\tclientId: string;\n\tredirectUri: string;\n\tcodeChallenge: string;\n\tscopes: string[];\n\tresource: string | null;\n\tstate: string | null;\n}\n\nexport class InMemoryOAuthClientsStore implements OAuthRegisteredClientsStore {\n\treadonly #clients = new Map<string, OAuthClientInformationFull>();\n\n\tgetClient(clientId: string): OAuthClientInformationFull | undefined {\n\t\treturn this.#clients.get(clientId);\n\t}\n\n\tregisterClient(\n\t\tclient: Omit<OAuthClientInformationFull, \"client_id\" | \"client_id_issued_at\">,\n\t): OAuthClientInformationFull {\n\t\tconst redirectError = validateRedirectUris(client.redirect_uris);\n\t\tif (redirectError) throw new InvalidClientMetadataError(redirectError);\n\t\tif (client.client_secret || client.token_endpoint_auth_method !== \"none\") {\n\t\t\tthrow new InvalidClientMetadataError(\n\t\t\t\t\"Only public clients with token_endpoint_auth_method=none are supported\",\n\t\t\t);\n\t\t}\n\t\tif (client.grant_types && !isSupportedList(client.grant_types, SUPPORTED_GRANT_TYPES)) {\n\t\t\tthrow new InvalidClientMetadataError(\n\t\t\t\t\"Only authorization_code and refresh_token grant_types are supported\",\n\t\t\t);\n\t\t}\n\t\tif (\n\t\t\tclient.response_types &&\n\t\t\t!isSupportedList(client.response_types, SUPPORTED_RESPONSE_TYPES)\n\t\t) {\n\t\t\tthrow new InvalidClientMetadataError(\"Only code response_type is supported\");\n\t\t}\n\t\tif (this.#clients.size >= 100) {\n\t\t\tconst oldestClientId = this.#clients.keys().next().value;\n\t\t\tif (oldestClientId) this.#clients.delete(oldestClientId);\n\t\t}\n\t\tconst registered = {\n\t\t\t...client,\n\t\t\ttoken_endpoint_auth_method: \"none\" as const,\n\t\t\tgrant_types: client.grant_types ?? [\"authorization_code\", \"refresh_token\"],\n\t\t\tresponse_types: client.response_types ?? [\"code\"],\n\t\t\tclient_id: randomUUID(),\n\t\t\tclient_id_issued_at: Math.floor(Date.now() / 1000),\n\t\t};\n\t\tthis.#clients.set(registered.client_id, registered);\n\t\treturn registered;\n\t}\n}\n\nexport class InMemoryOAuthAuthorizationCodeStore implements OAuthAuthorizationCodeStore {\n\treadonly #codes = new Map<string, AuthorizationCodeRecord>();\n\n\tissueCode(record: Omit<AuthorizationCodeRecord, \"used\">, now = Date.now()): string | undefined {\n\t\tthis.#deleteExpiredCodes(now);\n\t\tif (this.#codes.size >= MAX_AUTHORIZATION_CODES) return undefined;\n\t\tconst code = randomUUID();\n\t\tthis.#codes.set(code, { ...record, used: false });\n\t\treturn code;\n\t}\n\n\tpeekCode(code: string): AuthorizationCodeRecord | undefined {\n\t\tconst record = this.#codes.get(code);\n\t\tif (!record || record.used) return undefined;\n\t\treturn record;\n\t}\n\n\tconsumeCode(code: string): AuthorizationCodeRecord | undefined {\n\t\tconst record = this.#codes.get(code);\n\t\tif (!record || record.used) return undefined;\n\t\trecord.used = true;\n\t\treturn record;\n\t}\n\n\t#deleteExpiredCodes(now: number): void {\n\t\tfor (const [code, record] of this.#codes) {\n\t\t\tif (record.expiresAt <= now) this.#codes.delete(code);\n\t\t}\n\t}\n}\n\nexport class InMemoryOAuthAccessTokenStore implements OAuthAccessTokenStore {\n\treadonly #tokensByHash = new Map<string, AccessTokenRecord>();\n\treadonly #tokenHashKey = randomBytes(32);\n\n\tissueToken(\n\t\tclientId: string,\n\t\tnow = Date.now(),\n\t\tresource?: string,\n\t\tgrantId?: string,\n\t\tscopes: string[] = [],\n\t): { token: string; expiresIn: number } | undefined {\n\t\tthis.#deleteInactiveTokens(now);\n\t\tif (this.#tokensByHash.size >= MAX_ACCESS_TOKENS) return undefined;\n\t\tconst tokenBytes = randomBytes(ACCESS_TOKEN_BYTES);\n\t\tconst tokenHash = signOAuthAccessTokenBytes(tokenBytes, this.#tokenHashKey);\n\t\tthis.#tokensByHash.set(tokenHash, {\n\t\t\tclientId,\n\t\t\tgrantId,\n\t\t\tscopes: [...scopes],\n\t\t\tresource,\n\t\t\ttokenHash,\n\t\t\tissuedAt: now,\n\t\t\texpiresAt: now + ACCESS_TOKEN_TTL_SECONDS * 1000,\n\t\t\tlastUsedAt: null,\n\t\t\trevokedAt: null,\n\t\t});\n\t\treturn {\n\t\t\ttoken: tokenBytes.toString(\"base64url\"),\n\t\t\texpiresIn: ACCESS_TOKEN_TTL_SECONDS,\n\t\t};\n\t}\n\n\tverifyToken(token: string, now = Date.now()): AccessTokenVerificationResult {\n\t\tconst tokenBytes = decodeOAuthAccessToken(token);\n\t\tif (!tokenBytes) return { ok: false, reason: \"unknown_token\" };\n\t\tconst tokenHash = signOAuthAccessTokenBytes(tokenBytes, this.#tokenHashKey);\n\t\tconst record = this.#tokensByHash.get(tokenHash);\n\t\tif (!record || !isSameTokenHash(record.tokenHash, tokenHash)) {\n\t\t\treturn { ok: false, reason: \"unknown_token\" };\n\t\t}\n\t\tif (record.revokedAt !== null) return { ok: false, reason: \"revoked_token\" };\n\t\tif (record.expiresAt <= now) return { ok: false, reason: \"expired_token\" };\n\t\trecord.lastUsedAt = now;\n\t\treturn { ok: true, record: { ...record } };\n\t}\n\n\trevokeToken(token: string, now = Date.now()): boolean {\n\t\tconst tokenBytes = decodeOAuthAccessToken(token);\n\t\tif (!tokenBytes) return false;\n\t\tconst tokenHash = signOAuthAccessTokenBytes(tokenBytes, this.#tokenHashKey);\n\t\tconst record = this.#tokensByHash.get(tokenHash);\n\t\tif (!record || !isSameTokenHash(record.tokenHash, tokenHash)) return false;\n\t\tif (record.revokedAt !== null) return true;\n\t\trecord.revokedAt = now;\n\t\treturn true;\n\t}\n\n\trevokeTokensForGrant(grantId: string, now = Date.now()): number {\n\t\tlet revoked = 0;\n\t\tfor (const record of this.#tokensByHash.values()) {\n\t\t\tif (record.grantId !== grantId || record.revokedAt !== null) continue;\n\t\t\trecord.revokedAt = now;\n\t\t\trevoked += 1;\n\t\t}\n\t\treturn revoked;\n\t}\n\n\t#deleteInactiveTokens(now: number): void {\n\t\tfor (const [tokenHash, record] of this.#tokensByHash) {\n\t\t\tif (record.expiresAt <= now || record.revokedAt !== null)\n\t\t\t\tthis.#tokensByHash.delete(tokenHash);\n\t\t}\n\t}\n}\n\nexport class InMemoryOAuthRefreshTokenStore implements OAuthRefreshTokenStore {\n\treadonly #grantsById = new Map<string, RefreshTokenGrantRecord>();\n\treadonly #grantIdsByRefreshHash = new Map<string, string>();\n\treadonly #refreshHashesByGrantId = new Map<string, Set<string>>();\n\treadonly #tokenHashKey = randomBytes(32);\n\n\tissueGrant(\n\t\trecord: { clientId: string; scopes?: string[]; resource?: string },\n\t\tnow = Date.now(),\n\t): { grant: RefreshTokenGrantRecord; refreshToken: string; expiresIn: number } | undefined {\n\t\tthis.#deleteInactiveGrants(now);\n\t\tif (this.#grantsById.size >= MAX_REFRESH_GRANTS) return undefined;\n\t\tconst refreshToken = randomToken();\n\t\tconst refreshTokenHash = hashSerializedOAuthToken(refreshToken, this.#tokenHashKey);\n\t\tif (!refreshTokenHash) return undefined;\n\t\tconst grant: RefreshTokenGrantRecord = {\n\t\t\tgrantId: randomUUID(),\n\t\t\tclientId: record.clientId,\n\t\t\tscopes: [...(record.scopes ?? [])],\n\t\t\tresource: record.resource,\n\t\t\tcurrentRefreshTokenHash: refreshTokenHash,\n\t\t\tpreviousRefreshTokenHash: null,\n\t\t\tissuedAt: now,\n\t\t\texpiresAt: now + REFRESH_TOKEN_TTL_SECONDS * 1000,\n\t\t\trotatedAt: null,\n\t\t\trevokedAt: null,\n\t\t};\n\t\tthis.#grantsById.set(grant.grantId, grant);\n\t\tthis.#grantIdsByRefreshHash.set(refreshTokenHash, grant.grantId);\n\t\tthis.#refreshHashesByGrantId.set(grant.grantId, new Set([refreshTokenHash]));\n\t\treturn {\n\t\t\tgrant: { ...grant, scopes: [...grant.scopes] },\n\t\t\trefreshToken,\n\t\t\texpiresIn: REFRESH_TOKEN_TTL_SECONDS,\n\t\t};\n\t}\n\n\trotateRefreshToken(\n\t\tclientId: string,\n\t\trefreshToken: string,\n\t\toptions: { scopes?: string[]; resource?: string } = {},\n\t\tnow = Date.now(),\n\t): RefreshTokenRotationResult {\n\t\tconst tokenHash = hashSerializedOAuthToken(refreshToken, this.#tokenHashKey);\n\t\tif (!tokenHash) return { ok: false, reason: \"unknown_refresh_token\" };\n\t\tconst grantId = this.#grantIdsByRefreshHash.get(tokenHash);\n\t\tif (!grantId) return { ok: false, reason: \"unknown_refresh_token\" };\n\t\tconst grant = this.#grantsById.get(grantId);\n\t\tif (!grant) return { ok: false, reason: \"unknown_refresh_token\" };\n\t\tif (grant.revokedAt !== null) return { ok: false, reason: \"revoked_refresh_token\", grantId };\n\t\tif (grant.expiresAt <= now) {\n\t\t\tthis.revokeGrant(grantId, now);\n\t\t\treturn { ok: false, reason: \"expired_refresh_token\", grantId };\n\t\t}\n\t\tif (grant.clientId !== clientId) return { ok: false, reason: \"client_mismatch\", grantId };\n\t\tif (!isScopeSubset(options.scopes ?? grant.scopes, grant.scopes)) {\n\t\t\treturn { ok: false, reason: \"scope_mismatch\", grantId };\n\t\t}\n\t\tif ((grant.resource ?? null) !== (options.resource ?? grant.resource ?? null)) {\n\t\t\treturn { ok: false, reason: \"resource_mismatch\", grantId };\n\t\t}\n\n\t\tconst matchesCurrent = isSameTokenHash(grant.currentRefreshTokenHash, tokenHash);\n\t\tconst matchesPrevious =\n\t\t\tgrant.previousRefreshTokenHash !== null &&\n\t\t\tisSameTokenHash(grant.previousRefreshTokenHash, tokenHash);\n\t\tif (!matchesCurrent && !matchesPrevious) {\n\t\t\tthis.revokeGrant(grantId, now);\n\t\t\treturn { ok: false, reason: \"refresh_token_replay\", grantId };\n\t\t}\n\n\t\tconst nextRefreshToken = randomToken();\n\t\tconst nextRefreshTokenHash = hashSerializedOAuthToken(nextRefreshToken, this.#tokenHashKey);\n\t\tif (!nextRefreshTokenHash) return { ok: false, reason: \"unknown_refresh_token\" };\n\t\tgrant.scopes = [...(options.scopes ?? grant.scopes)];\n\t\tgrant.previousRefreshTokenHash = matchesCurrent ? grant.currentRefreshTokenHash : null;\n\t\tgrant.currentRefreshTokenHash = nextRefreshTokenHash;\n\t\tgrant.rotatedAt = now;\n\t\tthis.#grantIdsByRefreshHash.set(nextRefreshTokenHash, grantId);\n\t\tthis.#refreshHashesByGrantId.get(grantId)?.add(nextRefreshTokenHash);\n\t\treturn {\n\t\t\tok: true,\n\t\t\tgrant: { ...grant, scopes: [...grant.scopes] },\n\t\t\trefreshToken: nextRefreshToken,\n\t\t\texpiresIn: Math.max(0, Math.floor((grant.expiresAt - now) / 1000)),\n\t\t};\n\t}\n\n\trevokeRefreshToken(token: string, now = Date.now()): string | undefined {\n\t\tconst tokenHash = hashSerializedOAuthToken(token, this.#tokenHashKey);\n\t\tif (!tokenHash) return undefined;\n\t\tconst grantId = this.#grantIdsByRefreshHash.get(tokenHash);\n\t\tif (!grantId) return undefined;\n\t\tthis.revokeGrant(grantId, now);\n\t\treturn grantId;\n\t}\n\n\trevokeGrant(grantId: string, now = Date.now()): boolean {\n\t\tconst grant = this.#grantsById.get(grantId);\n\t\tif (!grant) return false;\n\t\tif (grant.revokedAt !== null) return true;\n\t\tgrant.revokedAt = now;\n\t\tthis.#deleteGrantRefreshHashIndexEntries(grant);\n\t\treturn true;\n\t}\n\n\t#deleteInactiveGrants(now: number): void {\n\t\tfor (const [grantId, grant] of this.#grantsById) {\n\t\t\tif (grant.expiresAt > now && grant.revokedAt === null) continue;\n\t\t\tthis.#grantsById.delete(grantId);\n\t\t\tthis.#deleteGrantRefreshHashIndexEntries(grant);\n\t\t}\n\t}\n\n\t#deleteGrantRefreshHashIndexEntries(grant: RefreshTokenGrantRecord): void {\n\t\tconst refreshHashes = this.#refreshHashesByGrantId.get(grant.grantId);\n\t\tif (refreshHashes) {\n\t\t\tfor (const refreshHash of refreshHashes) this.#grantIdsByRefreshHash.delete(refreshHash);\n\t\t\tthis.#refreshHashesByGrantId.delete(grant.grantId);\n\t\t\treturn;\n\t\t}\n\t\tthis.#grantIdsByRefreshHash.delete(grant.currentRefreshTokenHash);\n\t\tif (grant.previousRefreshTokenHash)\n\t\t\tthis.#grantIdsByRefreshHash.delete(grant.previousRefreshTokenHash);\n\t}\n}\n\ninterface OAuthStateFileData {\n\tversion: 1;\n\tclients: OAuthClientInformationFull[];\n\taccessTokens: AccessTokenRecord[];\n\trefreshGrants: RefreshTokenGrantRecord[];\n\trefreshHashesByGrantId: Record<string, string[]>;\n}\n\n/**\n * JSON-backed OAuth state for remote MCP clients.\n *\n * Claude keeps its dynamically-registered `client_id` and refresh token across\n * connector reconnects. If codemem only stores that state in memory, a package\n * upgrade or MCP process restart makes Claude's next refresh look like an\n * unknown client. This store persists client registrations, access tokens, and\n * refresh-token grants so routine restarts do not force users through OAuth\n * again.\n */\nexport class JsonFileOAuthStateStore\n\timplements\n\t\tOAuthRegisteredClientsStore,\n\t\tOAuthAuthorizationCodeStore,\n\t\tOAuthAccessTokenStore,\n\t\tOAuthRefreshTokenStore\n{\n\treadonly #path: string;\n\treadonly #codes = new Map<string, AuthorizationCodeRecord>();\n\t#clients = new Map<string, OAuthClientInformationFull>();\n\t#tokensByHash = new Map<string, AccessTokenRecord>();\n\t#grantsById = new Map<string, RefreshTokenGrantRecord>();\n\t#grantIdsByRefreshHash = new Map<string, string>();\n\t#refreshHashesByGrantId = new Map<string, Set<string>>();\n\n\tconstructor(path = getDefaultMcpOAuthStatePath()) {\n\t\tthis.#path = path;\n\t\tthis.#load();\n\t}\n\n\tgetClient(clientId: string): OAuthClientInformationFull | undefined {\n\t\treturn this.#clients.get(clientId);\n\t}\n\n\tregisterClient(\n\t\tclient: Omit<OAuthClientInformationFull, \"client_id\" | \"client_id_issued_at\">,\n\t): OAuthClientInformationFull {\n\t\tconst redirectError = validateRedirectUris(client.redirect_uris);\n\t\tif (redirectError) throw new InvalidClientMetadataError(redirectError);\n\t\tif (client.client_secret || client.token_endpoint_auth_method !== \"none\") {\n\t\t\tthrow new InvalidClientMetadataError(\n\t\t\t\t\"Only public clients with token_endpoint_auth_method=none are supported\",\n\t\t\t);\n\t\t}\n\t\tif (client.grant_types && !isSupportedList(client.grant_types, SUPPORTED_GRANT_TYPES)) {\n\t\t\tthrow new InvalidClientMetadataError(\n\t\t\t\t\"Only authorization_code and refresh_token grant_types are supported\",\n\t\t\t);\n\t\t}\n\t\tif (\n\t\t\tclient.response_types &&\n\t\t\t!isSupportedList(client.response_types, SUPPORTED_RESPONSE_TYPES)\n\t\t) {\n\t\t\tthrow new InvalidClientMetadataError(\"Only code response_type is supported\");\n\t\t}\n\t\tthis.#deleteInactive(Date.now());\n\t\tif (this.#clients.size >= 100) {\n\t\t\tconst oldestClientId = this.#clients.keys().next().value;\n\t\t\tif (oldestClientId) this.#clients.delete(oldestClientId);\n\t\t}\n\t\tconst registered = {\n\t\t\t...client,\n\t\t\ttoken_endpoint_auth_method: \"none\" as const,\n\t\t\tgrant_types: client.grant_types ?? [\"authorization_code\", \"refresh_token\"],\n\t\t\tresponse_types: client.response_types ?? [\"code\"],\n\t\t\tclient_id: randomUUID(),\n\t\t\tclient_id_issued_at: Math.floor(Date.now() / 1000),\n\t\t};\n\t\tthis.#clients.set(registered.client_id, registered);\n\t\tthis.#save();\n\t\treturn registered;\n\t}\n\n\tissueCode(record: Omit<AuthorizationCodeRecord, \"used\">, now = Date.now()): string | undefined {\n\t\tthis.#deleteExpiredCodes(now);\n\t\tif (this.#codes.size >= MAX_AUTHORIZATION_CODES) return undefined;\n\t\tconst code = randomUUID();\n\t\tthis.#codes.set(code, { ...record, used: false });\n\t\treturn code;\n\t}\n\n\tpeekCode(code: string): AuthorizationCodeRecord | undefined {\n\t\tconst record = this.#codes.get(code);\n\t\tif (!record || record.used) return undefined;\n\t\treturn record;\n\t}\n\n\tconsumeCode(code: string): AuthorizationCodeRecord | undefined {\n\t\tconst record = this.#codes.get(code);\n\t\tif (!record || record.used) return undefined;\n\t\trecord.used = true;\n\t\treturn record;\n\t}\n\n\tissueToken(\n\t\tclientId: string,\n\t\tnow = Date.now(),\n\t\tresource?: string,\n\t\tgrantId?: string,\n\t\tscopes: string[] = [],\n\t): { token: string; expiresIn: number } | undefined {\n\t\tthis.#deleteInactive(now);\n\t\tif (this.#tokensByHash.size >= MAX_ACCESS_TOKENS) return undefined;\n\t\tconst token = randomToken();\n\t\tconst tokenHash = hashOAuthTokenForStateFile(token);\n\t\tif (!tokenHash) return undefined;\n\t\tthis.#tokensByHash.set(tokenHash, {\n\t\t\tclientId,\n\t\t\tgrantId,\n\t\t\tscopes: [...scopes],\n\t\t\tresource,\n\t\t\ttokenHash,\n\t\t\tissuedAt: now,\n\t\t\texpiresAt: now + ACCESS_TOKEN_TTL_SECONDS * 1000,\n\t\t\tlastUsedAt: null,\n\t\t\trevokedAt: null,\n\t\t});\n\t\tthis.#save();\n\t\treturn { token, expiresIn: ACCESS_TOKEN_TTL_SECONDS };\n\t}\n\n\tverifyToken(token: string, now = Date.now()): AccessTokenVerificationResult {\n\t\tconst tokenHash = hashOAuthTokenForStateFile(token);\n\t\tif (!tokenHash) return { ok: false, reason: \"unknown_token\" };\n\t\tconst record = this.#tokensByHash.get(tokenHash);\n\t\tif (!record || !isSameTokenHash(record.tokenHash, tokenHash)) {\n\t\t\treturn { ok: false, reason: \"unknown_token\" };\n\t\t}\n\t\tif (record.revokedAt !== null) return { ok: false, reason: \"revoked_token\" };\n\t\tif (record.expiresAt <= now) return { ok: false, reason: \"expired_token\" };\n\t\trecord.lastUsedAt = now;\n\t\treturn { ok: true, record: { ...record, scopes: [...record.scopes] } };\n\t}\n\n\trevokeToken(token: string, now = Date.now()): boolean {\n\t\tconst tokenHash = hashOAuthTokenForStateFile(token);\n\t\tif (!tokenHash) return false;\n\t\tconst record = this.#tokensByHash.get(tokenHash);\n\t\tif (!record || !isSameTokenHash(record.tokenHash, tokenHash)) return false;\n\t\tif (record.revokedAt !== null) return true;\n\t\trecord.revokedAt = now;\n\t\tthis.#save();\n\t\treturn true;\n\t}\n\n\trevokeTokensForGrant(grantId: string, now = Date.now()): number {\n\t\tlet revoked = 0;\n\t\tfor (const record of this.#tokensByHash.values()) {\n\t\t\tif (record.grantId !== grantId || record.revokedAt !== null) continue;\n\t\t\trecord.revokedAt = now;\n\t\t\trevoked += 1;\n\t\t}\n\t\tif (revoked > 0) this.#save();\n\t\treturn revoked;\n\t}\n\n\tissueGrant(\n\t\trecord: { clientId: string; scopes?: string[]; resource?: string },\n\t\tnow = Date.now(),\n\t): { grant: RefreshTokenGrantRecord; refreshToken: string; expiresIn: number } | undefined {\n\t\tthis.#deleteInactive(now);\n\t\tif (this.#grantsById.size >= MAX_REFRESH_GRANTS) return undefined;\n\t\tconst refreshToken = randomToken();\n\t\tconst refreshTokenHash = hashOAuthTokenForStateFile(refreshToken);\n\t\tif (!refreshTokenHash) return undefined;\n\t\tconst grant: RefreshTokenGrantRecord = {\n\t\t\tgrantId: randomUUID(),\n\t\t\tclientId: record.clientId,\n\t\t\tscopes: [...(record.scopes ?? [])],\n\t\t\tresource: record.resource,\n\t\t\tcurrentRefreshTokenHash: refreshTokenHash,\n\t\t\tpreviousRefreshTokenHash: null,\n\t\t\tissuedAt: now,\n\t\t\texpiresAt: now + REFRESH_TOKEN_TTL_SECONDS * 1000,\n\t\t\trotatedAt: null,\n\t\t\trevokedAt: null,\n\t\t};\n\t\tthis.#grantsById.set(grant.grantId, grant);\n\t\tthis.#grantIdsByRefreshHash.set(refreshTokenHash, grant.grantId);\n\t\tthis.#refreshHashesByGrantId.set(grant.grantId, new Set([refreshTokenHash]));\n\t\tthis.#save();\n\t\treturn {\n\t\t\tgrant: { ...grant, scopes: [...grant.scopes] },\n\t\t\trefreshToken,\n\t\t\texpiresIn: REFRESH_TOKEN_TTL_SECONDS,\n\t\t};\n\t}\n\n\trotateRefreshToken(\n\t\tclientId: string,\n\t\trefreshToken: string,\n\t\toptions: { scopes?: string[]; resource?: string } = {},\n\t\tnow = Date.now(),\n\t): RefreshTokenRotationResult {\n\t\tconst tokenHash = hashOAuthTokenForStateFile(refreshToken);\n\t\tif (!tokenHash) return { ok: false, reason: \"unknown_refresh_token\" };\n\t\tconst grantId = this.#grantIdsByRefreshHash.get(tokenHash);\n\t\tif (!grantId) return { ok: false, reason: \"unknown_refresh_token\" };\n\t\tconst grant = this.#grantsById.get(grantId);\n\t\tif (!grant) return { ok: false, reason: \"unknown_refresh_token\" };\n\t\tif (grant.revokedAt !== null) return { ok: false, reason: \"revoked_refresh_token\", grantId };\n\t\tif (grant.expiresAt <= now) {\n\t\t\tthis.revokeGrant(grantId, now);\n\t\t\treturn { ok: false, reason: \"expired_refresh_token\", grantId };\n\t\t}\n\t\tif (grant.clientId !== clientId) return { ok: false, reason: \"client_mismatch\", grantId };\n\t\tif (!isScopeSubset(options.scopes ?? grant.scopes, grant.scopes)) {\n\t\t\treturn { ok: false, reason: \"scope_mismatch\", grantId };\n\t\t}\n\t\tif ((grant.resource ?? null) !== (options.resource ?? grant.resource ?? null)) {\n\t\t\treturn { ok: false, reason: \"resource_mismatch\", grantId };\n\t\t}\n\n\t\tconst matchesCurrent = isSameTokenHash(grant.currentRefreshTokenHash, tokenHash);\n\t\tconst matchesPrevious =\n\t\t\tgrant.previousRefreshTokenHash !== null &&\n\t\t\tisSameTokenHash(grant.previousRefreshTokenHash, tokenHash);\n\t\tif (!matchesCurrent && !matchesPrevious) {\n\t\t\tthis.revokeGrant(grantId, now);\n\t\t\treturn { ok: false, reason: \"refresh_token_replay\", grantId };\n\t\t}\n\n\t\tconst nextRefreshToken = randomToken();\n\t\tconst nextRefreshTokenHash = hashOAuthTokenForStateFile(nextRefreshToken);\n\t\tif (!nextRefreshTokenHash) return { ok: false, reason: \"unknown_refresh_token\" };\n\t\tgrant.scopes = [...(options.scopes ?? grant.scopes)];\n\t\tgrant.previousRefreshTokenHash = matchesCurrent ? grant.currentRefreshTokenHash : null;\n\t\tgrant.currentRefreshTokenHash = nextRefreshTokenHash;\n\t\tgrant.rotatedAt = now;\n\t\tthis.#grantIdsByRefreshHash.set(nextRefreshTokenHash, grantId);\n\t\tthis.#refreshHashesByGrantId.get(grantId)?.add(nextRefreshTokenHash);\n\t\tthis.#save();\n\t\treturn {\n\t\t\tok: true,\n\t\t\tgrant: { ...grant, scopes: [...grant.scopes] },\n\t\t\trefreshToken: nextRefreshToken,\n\t\t\texpiresIn: Math.max(0, Math.floor((grant.expiresAt - now) / 1000)),\n\t\t};\n\t}\n\n\trevokeRefreshToken(token: string, now = Date.now()): string | undefined {\n\t\tconst tokenHash = hashOAuthTokenForStateFile(token);\n\t\tif (!tokenHash) return undefined;\n\t\tconst grantId = this.#grantIdsByRefreshHash.get(tokenHash);\n\t\tif (!grantId) return undefined;\n\t\tthis.revokeGrant(grantId, now);\n\t\treturn grantId;\n\t}\n\n\trevokeGrant(grantId: string, now = Date.now()): boolean {\n\t\tconst grant = this.#grantsById.get(grantId);\n\t\tif (!grant) return false;\n\t\tif (grant.revokedAt !== null) return true;\n\t\tgrant.revokedAt = now;\n\t\tthis.#deleteGrantRefreshHashIndexEntries(grant);\n\t\tthis.#save();\n\t\treturn true;\n\t}\n\n\t#load(): void {\n\t\tif (!existsSync(this.#path)) return;\n\t\tlet parsed: OAuthStateFileData;\n\t\ttry {\n\t\t\tparsed = JSON.parse(readFileSync(this.#path, \"utf8\")) as OAuthStateFileData;\n\t\t} catch {\n\t\t\treturn;\n\t\t}\n\t\tif (parsed.version !== 1) return;\n\t\tthis.#clients = new Map(parsed.clients.map((client) => [client.client_id, client]));\n\t\tthis.#tokensByHash = new Map(parsed.accessTokens.map((record) => [record.tokenHash, record]));\n\t\tthis.#grantsById = new Map(parsed.refreshGrants.map((grant) => [grant.grantId, grant]));\n\t\tthis.#grantIdsByRefreshHash = new Map();\n\t\tthis.#refreshHashesByGrantId = new Map();\n\t\tfor (const grant of this.#grantsById.values()) {\n\t\t\tconst hashes = new Set(parsed.refreshHashesByGrantId[grant.grantId] ?? []);\n\t\t\thashes.add(grant.currentRefreshTokenHash);\n\t\t\tif (grant.previousRefreshTokenHash) hashes.add(grant.previousRefreshTokenHash);\n\t\t\tthis.#refreshHashesByGrantId.set(grant.grantId, hashes);\n\t\t\tfor (const hash of hashes) this.#grantIdsByRefreshHash.set(hash, grant.grantId);\n\t\t}\n\t\tthis.#deleteInactive(Date.now());\n\t}\n\n\t#save(): void {\n\t\tmkdirSync(dirname(this.#path), { recursive: true, mode: 0o700 });\n\t\tconst data: OAuthStateFileData = {\n\t\t\tversion: 1,\n\t\t\tclients: [...this.#clients.values()],\n\t\t\taccessTokens: [...this.#tokensByHash.values()],\n\t\t\trefreshGrants: [...this.#grantsById.values()],\n\t\t\trefreshHashesByGrantId: Object.fromEntries(\n\t\t\t\t[...this.#refreshHashesByGrantId.entries()].map(([grantId, hashes]) => [\n\t\t\t\t\tgrantId,\n\t\t\t\t\t[...hashes],\n\t\t\t\t]),\n\t\t\t),\n\t\t};\n\t\tconst tmpPath = `${this.#path}.${process.pid}.${Date.now()}.tmp`;\n\t\twriteFileSync(tmpPath, `${JSON.stringify(data, null, 2)}\\n`, { mode: 0o600 });\n\t\trenameSync(tmpPath, this.#path);\n\t\tvoid chmod(this.#path, 0o600).catch(() => undefined);\n\t}\n\n\t#deleteExpiredCodes(now: number): void {\n\t\tfor (const [code, record] of this.#codes) {\n\t\t\tif (record.expiresAt <= now) this.#codes.delete(code);\n\t\t}\n\t}\n\n\t#deleteInactive(now: number): void {\n\t\tlet changed = false;\n\t\tfor (const [tokenHash, record] of this.#tokensByHash) {\n\t\t\tif (record.expiresAt > now && record.revokedAt === null) continue;\n\t\t\tthis.#tokensByHash.delete(tokenHash);\n\t\t\tchanged = true;\n\t\t}\n\t\tfor (const [grantId, grant] of this.#grantsById) {\n\t\t\tif (grant.expiresAt > now && grant.revokedAt === null) continue;\n\t\t\tthis.#grantsById.delete(grantId);\n\t\t\tthis.#deleteGrantRefreshHashIndexEntries(grant);\n\t\t\tchanged = true;\n\t\t}\n\t\tif (changed) this.#save();\n\t}\n\n\t#deleteGrantRefreshHashIndexEntries(grant: RefreshTokenGrantRecord): void {\n\t\tconst refreshHashes = this.#refreshHashesByGrantId.get(grant.grantId);\n\t\tif (refreshHashes) {\n\t\t\tfor (const refreshHash of refreshHashes) this.#grantIdsByRefreshHash.delete(refreshHash);\n\t\t\tthis.#refreshHashesByGrantId.delete(grant.grantId);\n\t\t\treturn;\n\t\t}\n\t\tthis.#grantIdsByRefreshHash.delete(grant.currentRefreshTokenHash);\n\t\tif (grant.previousRefreshTokenHash)\n\t\t\tthis.#grantIdsByRefreshHash.delete(grant.previousRefreshTokenHash);\n\t}\n}\n\nexport function createInMemoryOAuthClientsStore(): OAuthRegisteredClientsStore {\n\treturn new InMemoryOAuthClientsStore();\n}\n\nexport function createInMemoryOAuthAuthorizationCodeStore(): OAuthAuthorizationCodeStore {\n\treturn new InMemoryOAuthAuthorizationCodeStore();\n}\n\nexport function createInMemoryOAuthAccessTokenStore(): OAuthAccessTokenStore {\n\treturn new InMemoryOAuthAccessTokenStore();\n}\n\nexport function createInMemoryOAuthRefreshTokenStore(): OAuthRefreshTokenStore {\n\treturn new InMemoryOAuthRefreshTokenStore();\n}\n\nexport function createJsonFileOAuthStateStore(path?: string): JsonFileOAuthStateStore {\n\treturn new JsonFileOAuthStateStore(path);\n}\n\nexport function getDefaultMcpOAuthStatePath(): string {\n\treturn join(process.env.HOME?.trim() || homedir(), \".codemem\", \"mcp-oauth-state.json\");\n}\n\nexport function createMcpOAuthMetadata(options: McpOAuthMetadataOptions): OAuthMetadata {\n\tconst mcpUrl = normalizeMcpPublicUrl(options.mcpUrl);\n\tconst issuerUrl = getOriginUrl(mcpUrl);\n\tconst provider = createMetadataOnlyProvider(options.clientsStore);\n\treturn {\n\t\t...createOAuthMetadata({\n\t\t\tprovider,\n\t\t\tissuerUrl,\n\t\t\tbaseUrl: issuerUrl,\n\t\t}),\n\t\t// Phase 1 treats claude.ai and local callback clients as public clients.\n\t\t// Do not issue or advertise client secrets until we have a concrete need.\n\t\tgrant_types_supported: [\"authorization_code\", \"refresh_token\"],\n\t\ttoken_endpoint_auth_methods_supported: [\"none\"],\n\t\tscopes_supported: MCP_OAUTH_SCOPES_SUPPORTED,\n\t\tservice_documentation: MCP_OAUTH_SERVICE_DOCUMENTATION_URL,\n\t\trevocation_endpoint: new URL(\"/revoke\", issuerUrl).href,\n\t\trevocation_endpoint_auth_methods_supported: [\"none\"],\n\t\tclient_id_metadata_document_supported: false,\n\t};\n}\n\nexport function createMcpProtectedResourceMetadata(mcpUrl: string): OAuthProtectedResourceMetadata {\n\tconst normalizedMcpUrl = normalizeMcpPublicUrl(mcpUrl);\n\tconst metadata = {\n\t\tresource: normalizedMcpUrl.href,\n\t\tauthorization_servers: [getOriginUrl(normalizedMcpUrl).href],\n\t\tscopes_supported: MCP_OAUTH_SCOPES_SUPPORTED,\n\t\tbearer_methods_supported: [\"header\"],\n\t\tresource_name: MCP_OAUTH_RESOURCE_NAME,\n\t\tresource_documentation: MCP_OAUTH_SERVICE_DOCUMENTATION_URL,\n\t};\n\treturn OAuthProtectedResourceMetadataSchema.parse(metadata);\n}\n\nexport function registerMcpOAuthClient(\n\trequestBody: unknown,\n\tclientsStore: OAuthRegisteredClientsStore,\n): RegisteredMcpOAuthClient | McpOAuthRegistrationError {\n\tif (!clientsStore.registerClient) {\n\t\treturn invalidClientMetadata(\"Dynamic client registration is not enabled\");\n\t}\n\n\tconst parseResult = OAuthClientMetadataSchema.safeParse(requestBody);\n\tif (!parseResult.success) {\n\t\treturn invalidClientMetadata(parseResult.error.message);\n\t}\n\n\tconst clientMetadata = parseResult.data;\n\tconst redirectError = validateRedirectUris(clientMetadata.redirect_uris);\n\tif (redirectError) return invalidClientMetadata(redirectError);\n\n\tif (!isSupportedTokenEndpointAuthMethod(clientMetadata.token_endpoint_auth_method)) {\n\t\treturn invalidClientMetadata(\n\t\t\t\"Only public clients with token_endpoint_auth_method=none are supported\",\n\t\t);\n\t}\n\n\tif (\n\t\tclientMetadata.grant_types &&\n\t\t!isSupportedList(clientMetadata.grant_types, SUPPORTED_GRANT_TYPES)\n\t) {\n\t\treturn invalidClientMetadata(\n\t\t\t\"Only authorization_code and refresh_token grant_types are supported\",\n\t\t);\n\t}\n\n\tif (\n\t\tclientMetadata.response_types &&\n\t\t!isSupportedList(clientMetadata.response_types, SUPPORTED_RESPONSE_TYPES)\n\t) {\n\t\treturn invalidClientMetadata(\"Only code response_type is supported\");\n\t}\n\n\tconst registered = clientsStore.registerClient({\n\t\t...clientMetadata,\n\t\ttoken_endpoint_auth_method: \"none\",\n\t\tgrant_types: clientMetadata.grant_types ?? [\"authorization_code\", \"refresh_token\"],\n\t\tresponse_types: clientMetadata.response_types ?? [\"code\"],\n\t});\n\n\tif (registered instanceof Promise) {\n\t\tthrow new Error(\n\t\t\t\"Asynchronous OAuth client stores are not supported by this HTTP bootstrap yet\",\n\t\t);\n\t}\n\n\treturn { status: 201, body: registered };\n}\n\nexport function authorizeMcpOAuthClient(\n\tparams: URLSearchParams,\n\tclientsStore: OAuthRegisteredClientsStore,\n\tcodeStore: OAuthAuthorizationCodeStore,\n\tnow = Date.now(),\n): McpOAuthRedirectResult | McpOAuthErrorResult {\n\tconst prepared = prepareMcpOAuthAuthorizationRequest(params, clientsStore);\n\tif (\"status\" in prepared) return prepared;\n\n\tconst code = codeStore.issueCode(\n\t\t{\n\t\t\tclientId: prepared.clientId,\n\t\t\tredirectUri: prepared.redirectUri,\n\t\t\tcodeChallenge: prepared.codeChallenge,\n\t\t\tscopes: prepared.scopes,\n\t\t\t...(prepared.resource ? { resource: prepared.resource } : {}),\n\t\t\texpiresAt: now + AUTHORIZATION_CODE_TTL_MS,\n\t\t},\n\t\tnow,\n\t);\n\tif (!code)\n\t\treturn invalidOAuthRequest(\"temporarily_unavailable\", \"Too many active authorization codes\");\n\tconst redirect = new URL(prepared.redirectUri);\n\tredirect.searchParams.set(\"code\", code);\n\tif (prepared.state !== null) redirect.searchParams.set(\"state\", prepared.state);\n\treturn { status: 302, location: redirect.href };\n}\n\nexport function prepareMcpOAuthAuthorizationRequest(\n\tparams: URLSearchParams,\n\tclientsStore: OAuthRegisteredClientsStore,\n): PreparedMcpOAuthAuthorizationRequest | McpOAuthErrorResult {\n\tconst clientId = params.get(\"client_id\") ?? \"\";\n\tconst redirectUri = params.get(\"redirect_uri\") ?? \"\";\n\tconst responseType = params.get(\"response_type\") ?? \"\";\n\tconst codeChallenge = params.get(\"code_challenge\") ?? \"\";\n\tconst codeChallengeMethod = params.get(\"code_challenge_method\") ?? \"\";\n\tconst resource = params.get(\"resource\");\n\tconst scopes = parseScopeList(params.get(\"scope\"));\n\tconst state = params.get(\"state\");\n\n\tif (responseType !== \"code\") return invalidOAuthRequest(\"unsupported_response_type\");\n\tif (codeChallengeMethod !== \"S256\") {\n\t\treturn invalidOAuthRequest(\"invalid_request\", \"PKCE code_challenge_method=S256 is required\");\n\t}\n\tif (!PKCE_S256_CHALLENGE.test(codeChallenge)) {\n\t\treturn invalidOAuthRequest(\"invalid_request\", \"Valid PKCE S256 code_challenge is required\");\n\t}\n\n\tconst client = getRegisteredClient(clientsStore, clientId);\n\tif (!client) return invalidOAuthRequest(\"invalid_client\", \"Unknown OAuth client_id\");\n\tif (!client.redirect_uris.includes(redirectUri)) {\n\t\treturn invalidOAuthRequest(\"invalid_request\", \"redirect_uri is not registered for this client\");\n\t}\n\n\treturn { clientId, redirectUri, codeChallenge, scopes, resource, state };\n}\n\nexport function exchangeMcpOAuthAuthorizationCode(\n\tparams: URLSearchParams,\n\tclientsStore: OAuthRegisteredClientsStore,\n\tcodeStore: OAuthAuthorizationCodeStore,\n\ttokenStore: OAuthAccessTokenStore,\n\tnow = Date.now(),\n): McpOAuthTokenResult | McpOAuthErrorResult {\n\tif ((params.get(\"grant_type\") ?? \"\") !== \"authorization_code\") {\n\t\treturn invalidOAuthRequest(\"unsupported_grant_type\", \"Only authorization_code is supported\");\n\t}\n\n\tconst clientId = params.get(\"client_id\") ?? \"\";\n\tconst code = params.get(\"code\") ?? \"\";\n\tconst redirectUri = params.get(\"redirect_uri\") ?? \"\";\n\tconst codeVerifier = params.get(\"code_verifier\") ?? \"\";\n\tconst resource = params.get(\"resource\");\n\tconst client = getRegisteredClient(clientsStore, clientId);\n\tif (!client) return invalidOAuthRequest(\"invalid_client\", \"Unknown OAuth client_id\");\n\tif (!PKCE_VERIFIER.test(codeVerifier)) {\n\t\treturn invalidOAuthRequest(\"invalid_grant\", \"Invalid PKCE code_verifier\");\n\t}\n\n\t// Peek the authorization code without consuming it so a transient token-\n\t// store overflow (`temporarily_unavailable`) leaves the code reusable; only\n\t// permanent grant failures (expiry, client/redirect mismatch, PKCE) consume\n\t// the code. The code is finally consumed atomically with token issuance.\n\tconst record = codeStore.peekCode(code);\n\tif (!record) return invalidOAuthRequest(\"invalid_grant\", \"Invalid or already used code\");\n\tif (record.expiresAt <= now) {\n\t\tcodeStore.consumeCode(code);\n\t\treturn invalidOAuthRequest(\"invalid_grant\", \"Expired code\");\n\t}\n\tif (record.clientId !== clientId || record.redirectUri !== redirectUri) {\n\t\tcodeStore.consumeCode(code);\n\t\treturn invalidOAuthRequest(\"invalid_grant\", \"Code does not match client or redirect_uri\");\n\t}\n\tif (pkceS256(codeVerifier) !== record.codeChallenge) {\n\t\tcodeStore.consumeCode(code);\n\t\treturn invalidOAuthRequest(\"invalid_grant\", \"PKCE verification failed\");\n\t}\n\tif ((record.resource ?? null) !== (resource || null)) {\n\t\tcodeStore.consumeCode(code);\n\t\treturn invalidOAuthRequest(\"invalid_grant\", \"Code does not match resource\");\n\t}\n\n\tconst issued = tokenStore.issueToken(clientId, now, record.resource, undefined, record.scopes);\n\tif (!issued) {\n\t\t// Token-store overload is transient: leave the auth code unused so the\n\t\t// client can retry token exchange without restarting the OAuth flow.\n\t\treturn invalidOAuthRequest(\"temporarily_unavailable\", \"Too many active access tokens\");\n\t}\n\n\tconst consumed = codeStore.consumeCode(code);\n\tif (!consumed) {\n\t\ttokenStore.revokeToken(issued.token, now);\n\t\t// Lost a race with another request that consumed the code in the gap\n\t\t// between peek and consume. Treat as invalid_grant rather than issuing\n\t\t// a duplicate usable token, since the code is no longer single-use atomic.\n\t\treturn invalidOAuthRequest(\"invalid_grant\", \"Authorization code already used\");\n\t}\n\n\tconst tokens = OAuthTokensSchema.parse({\n\t\taccess_token: issued.token,\n\t\ttoken_type: \"Bearer\",\n\t\texpires_in: issued.expiresIn,\n\t});\n\treturn { status: 200, body: tokens };\n}\n\nexport function revokeMcpOAuthAccessToken(\n\tparams: URLSearchParams,\n\ttokenStore: OAuthAccessTokenStore,\n): { status: 200; body: Record<string, never> } {\n\tconst token = params.get(\"token\") ?? \"\";\n\ttokenStore.revokeToken(token);\n\treturn { status: 200, body: {} };\n}\n\nexport function normalizeMcpPublicUrl(value: string): URL {\n\tlet url: URL;\n\ttry {\n\t\turl = new URL(value);\n\t} catch {\n\t\tthrow new Error(\"Invalid MCP HTTP public URL; expected an HTTPS /mcp URL\");\n\t}\n\tif (url.protocol !== \"https:\" && !isLoopbackUrl(url)) {\n\t\tthrow new Error(\"Invalid MCP HTTP public URL; use HTTPS for non-loopback URLs\");\n\t}\n\tif (url.username || url.password || url.search || url.hash) {\n\t\tthrow new Error(\n\t\t\t\"Invalid MCP HTTP public URL; credentials, query strings, and fragments are not allowed\",\n\t\t);\n\t}\n\tif (url.pathname === \"/\") url.pathname = \"/mcp\";\n\tif (url.pathname !== \"/mcp\") {\n\t\tthrow new Error(\"Invalid MCP HTTP public URL; expected /mcp path\");\n\t}\n\treturn url;\n}\n\nfunction getOriginUrl(url: URL): URL {\n\treturn new URL(url.origin);\n}\n\nfunction validateRedirectUris(redirectUris: OAuthClientMetadata[\"redirect_uris\"]): string | null {\n\tfor (const redirectUri of redirectUris) {\n\t\tconst url = new URL(redirectUri);\n\t\tif (url.username || url.password || url.hash) return \"Invalid redirect URI\";\n\t\tif (isSupportedHostedConnectorRedirectUrl(url)) continue;\n\t\tif (isLoopbackCallbackUrl(url)) continue;\n\t\treturn \"Unsupported redirect URI\";\n\t}\n\treturn null;\n}\n\nfunction isSupportedHostedConnectorRedirectUrl(url: URL): boolean {\n\tif (url.search !== \"\") return false;\n\tif (url.href === CLAUDE_HOSTED_CALLBACK) return true;\n\tif (url.href === CHATGPT_LEGACY_HOSTED_CALLBACK) return true;\n\treturn url.protocol === \"https:\" && url.hostname === \"chatgpt.com\" && isChatGptConnectorPath(url);\n}\n\nfunction isChatGptConnectorPath(url: URL): boolean {\n\tconst pathParts = url.pathname.split(\"/\").filter(Boolean);\n\treturn (\n\t\tpathParts.length === 3 &&\n\t\tpathParts[0] === \"connector\" &&\n\t\tpathParts[1] === \"oauth\" &&\n\t\tCHATGPT_CONNECTOR_ID.test(pathParts[2] ?? \"\")\n\t);\n}\n\nfunction isSupportedTokenEndpointAuthMethod(method: string | undefined): boolean {\n\treturn method === undefined || method === \"none\";\n}\n\nfunction isSupportedList(values: string[], supported: Set<string>): boolean {\n\treturn values.length > 0 && values.every((value) => supported.has(value));\n}\n\nfunction isLoopbackCallbackUrl(url: URL): boolean {\n\treturn (\n\t\turl.protocol === \"http:\" &&\n\t\tLOCAL_CALLBACK_HOSTS.has(normalizeHostname(url.hostname)) &&\n\t\t(url.pathname === \"/callback\" || url.pathname === \"/oauth/callback\") &&\n\t\turl.search === \"\"\n\t);\n}\n\nfunction isLoopbackUrl(url: URL): boolean {\n\tconst hostname = normalizeHostname(url.hostname);\n\treturn url.protocol === \"http:\" && LOCAL_CALLBACK_HOSTS.has(hostname);\n}\n\nfunction normalizeHostname(hostname: string): string {\n\treturn hostname.replace(/^\\[(.*)]$/, \"$1\").toLowerCase();\n}\n\nfunction parseScopeList(scope: string | null | undefined): string[] {\n\treturn (\n\t\tscope\n\t\t\t?.split(/\\s+/)\n\t\t\t.map((item) => item.trim())\n\t\t\t.filter(Boolean) ?? []\n\t);\n}\n\nfunction invalidClientMetadata(description: string): McpOAuthRegistrationError {\n\treturn {\n\t\tstatus: 400,\n\t\tbody: { error: \"invalid_client_metadata\", error_description: description },\n\t};\n}\n\nfunction invalidOAuthRequest(error: string, description?: string): McpOAuthErrorResult {\n\treturn {\n\t\tstatus: 400,\n\t\tbody: description ? { error, error_description: description } : { error },\n\t};\n}\n\nfunction getRegisteredClient(\n\tclientsStore: OAuthRegisteredClientsStore,\n\tclientId: string,\n): OAuthClientInformationFull | undefined {\n\tconst client = clientsStore.getClient(clientId);\n\tif (client instanceof Promise) {\n\t\tthrow new Error(\n\t\t\t\"Asynchronous OAuth client stores are not supported by this HTTP bootstrap yet\",\n\t\t);\n\t}\n\treturn client;\n}\n\nfunction pkceS256(codeVerifier: string): string {\n\treturn createHash(\"sha256\").update(codeVerifier).digest(\"base64url\");\n}\n\n// Decode an externally-supplied access-token string into the fixed-length\n// random Buffer it represents. Rejects anything that is not a base64url-encoded\n// ACCESS_TOKEN_BYTES-length value, so invalid input never reaches the HMAC\n// signer. Returns null on any decode/length mismatch.\nfunction decodeOAuthAccessToken(serialized: string): Buffer | null {\n\tif (typeof serialized !== \"string\") return null;\n\tif (serialized.length !== ACCESS_TOKEN_BASE64URL_LENGTH) return null;\n\tif (!ACCESS_TOKEN_BASE64URL.test(serialized)) return null;\n\tconst bytes = Buffer.from(serialized, \"base64url\");\n\tif (bytes.length !== ACCESS_TOKEN_BYTES) return null;\n\treturn bytes;\n}\n\nfunction randomToken(): string {\n\treturn randomBytes(ACCESS_TOKEN_BYTES).toString(\"base64url\");\n}\n\nfunction hashSerializedOAuthToken(serialized: string, key: Buffer): string | null {\n\tconst tokenBytes = decodeOAuthAccessToken(serialized);\n\tif (!tokenBytes) return null;\n\treturn signOAuthToken(tokenBytes, key);\n}\n\nfunction hashOAuthTokenForStateFile(serialized: string): string | null {\n\tconst tokenBytes = decodeOAuthAccessToken(serialized);\n\tif (!tokenBytes) return null;\n\treturn createHash(\"sha256\").update(tokenBytes).digest(\"base64url\");\n}\n\n// Compute the HMAC-SHA256 signature of the binary access-token material using\n// the per-store random key. This is an integrity signature over a random\n// 256-bit value, not password hashing; tokens are validated by re-signing the\n// presented bytes and comparing the digest to the stored signature.\nfunction signOAuthAccessTokenBytes(material: Buffer, key: Buffer): string {\n\treturn signOAuthToken(material, key);\n}\n\nfunction signOAuthToken(material: Buffer | string, key: Buffer): string {\n\treturn createHmac(\"sha256\", key).update(material).digest(\"base64url\");\n}\n\nfunction isSameTokenHash(left: string, right: string): boolean {\n\tconst leftBuffer = Buffer.from(left);\n\tconst rightBuffer = Buffer.from(right);\n\treturn leftBuffer.length === rightBuffer.length && timingSafeEqual(leftBuffer, rightBuffer);\n}\n\nfunction isScopeSubset(requested: string[], granted: string[]): boolean {\n\tconst grantedScopes = new Set(granted);\n\treturn requested.every((scope) => grantedScopes.has(scope));\n}\n\nfunction createMetadataOnlyProvider(\n\tclientsStore: OAuthRegisteredClientsStore,\n): OAuthServerProvider {\n\treturn {\n\t\tclientsStore,\n\t\tasync authorize() {\n\t\t\tthrow new Error(\"OAuth authorize is not implemented yet\");\n\t\t},\n\t\tasync challengeForAuthorizationCode() {\n\t\t\tthrow new Error(\"OAuth token exchange is not implemented yet\");\n\t\t},\n\t\tasync exchangeAuthorizationCode() {\n\t\t\tthrow new Error(\"OAuth token exchange is not implemented yet\");\n\t\t},\n\t\tasync exchangeRefreshToken() {\n\t\t\tthrow new Error(\"OAuth refresh is not implemented yet\");\n\t\t},\n\t\tasync verifyAccessToken() {\n\t\t\tthrow new Error(\"OAuth bearer verification is not implemented yet\");\n\t\t},\n\t};\n}\n","import { createPublicKey, randomUUID, verify } from \"node:crypto\";\nimport type { OAuthRegisteredClientsStore } from \"@modelcontextprotocol/sdk/server/auth/clients.js\";\nimport {\n\ttype McpOAuthErrorResult,\n\ttype McpOAuthRedirectResult,\n\tprepareMcpOAuthAuthorizationRequest,\n} from \"./oauth.js\";\n\nexport const MCP_OIDC_ISSUER_URL_ENV = \"CODEMEM_MCP_OIDC_ISSUER_URL\";\nexport const MCP_OIDC_CLIENT_ID_ENV = \"CODEMEM_MCP_OIDC_CLIENT_ID\";\nexport const MCP_OIDC_CLIENT_SECRET_ENV = \"CODEMEM_MCP_OIDC_CLIENT_SECRET\";\nexport const MCP_OAUTH_ALLOWED_SUBJECT_ENV = \"CODEMEM_MCP_OAUTH_ALLOWED_SUBJECT\";\nexport const MCP_OAUTH_ALLOWED_EMAIL_ENV = \"CODEMEM_MCP_OAUTH_ALLOWED_EMAIL\";\n\nconst PENDING_AUTH_TTL_MS = 5 * 60 * 1000;\nconst MAX_PENDING_AUTH = 100;\nconst ID_TOKEN_CLOCK_SKEW_MS = 5 * 60 * 1000;\n\ntype JsonWebKey = Record<string, unknown>;\n\nexport interface OidcConfig {\n\tissuerUrl: string;\n\tclientId: string;\n\tclientSecret: string;\n\tallowedSubject?: string;\n\tallowedEmail?: string;\n}\n\nexport interface PendingOidcAuthorization {\n\toauthParams: string;\n\tnonce: string;\n\texpiresAt: number;\n}\n\nexport interface OidcPendingAuthorizationStore {\n\tissue(record: Omit<PendingOidcAuthorization, \"expiresAt\">, now?: number): string | undefined;\n\tconsume(state: string): PendingOidcAuthorization | undefined;\n}\n\ninterface OidcDiscoveryMetadata {\n\tissuer: string;\n\tauthorization_endpoint: string;\n\ttoken_endpoint: string;\n\tjwks_uri: string;\n}\n\ninterface OidcTokensResponse {\n\tid_token?: string;\n\terror?: string;\n\terror_description?: string;\n}\n\ninterface JwtHeader {\n\talg?: string;\n\tkid?: string;\n}\n\ninterface JwtClaims {\n\tiss?: string;\n\taud?: string | string[];\n\tazp?: string;\n\texp?: number;\n\tiat?: number;\n\tnonce?: string;\n\tsub?: string;\n\temail?: string;\n\temail_verified?: boolean;\n}\n\ninterface JsonWebKeySet {\n\tkeys?: JsonWebKey[];\n}\n\nexport class InMemoryOidcPendingAuthorizationStore implements OidcPendingAuthorizationStore {\n\treadonly #records = new Map<string, PendingOidcAuthorization>();\n\n\tissue(record: Omit<PendingOidcAuthorization, \"expiresAt\">, now = Date.now()): string | undefined {\n\t\tthis.#deleteExpired(now);\n\t\tif (this.#records.size >= MAX_PENDING_AUTH) return undefined;\n\t\tconst state = randomUUID();\n\t\tthis.#records.set(state, { ...record, expiresAt: now + PENDING_AUTH_TTL_MS });\n\t\treturn state;\n\t}\n\n\tconsume(state: string): PendingOidcAuthorization | undefined {\n\t\tconst record = this.#records.get(state);\n\t\tthis.#records.delete(state);\n\t\treturn record;\n\t}\n\n\t#deleteExpired(now: number): void {\n\t\tfor (const [state, record] of this.#records) {\n\t\t\tif (record.expiresAt <= now) this.#records.delete(state);\n\t\t}\n\t}\n}\n\nexport function createInMemoryOidcPendingAuthorizationStore(): OidcPendingAuthorizationStore {\n\treturn new InMemoryOidcPendingAuthorizationStore();\n}\n\nexport function resolveOidcConfig(env: NodeJS.ProcessEnv = process.env): OidcConfig | undefined {\n\tconst issuerUrl = env[MCP_OIDC_ISSUER_URL_ENV]?.trim();\n\tconst clientId = env[MCP_OIDC_CLIENT_ID_ENV]?.trim();\n\tconst clientSecret = env[MCP_OIDC_CLIENT_SECRET_ENV]?.trim();\n\tconst allowedSubject = env[MCP_OAUTH_ALLOWED_SUBJECT_ENV]?.trim();\n\tconst allowedEmail = env[MCP_OAUTH_ALLOWED_EMAIL_ENV]?.trim().toLowerCase();\n\tif (!issuerUrl && !clientId && !clientSecret && !allowedSubject && !allowedEmail)\n\t\treturn undefined;\n\tif (!issuerUrl || !clientId || !clientSecret) {\n\t\tthrow new Error(\"Incomplete MCP OIDC configuration\");\n\t}\n\tvalidateOidcUrl(issuerUrl, \"issuer\", { allowLoopbackHttp: true });\n\tif (!allowedSubject && !allowedEmail) {\n\t\tthrow new Error(\n\t\t\t\"MCP OIDC requires CODEMEM_MCP_OAUTH_ALLOWED_SUBJECT or CODEMEM_MCP_OAUTH_ALLOWED_EMAIL\",\n\t\t);\n\t}\n\treturn { issuerUrl, clientId, clientSecret, allowedSubject, allowedEmail };\n}\n\nexport async function beginOidcAuthorization(\n\tparams: URLSearchParams,\n\tclientsStore: OAuthRegisteredClientsStore,\n\tpendingStore: OidcPendingAuthorizationStore,\n\tconfig: OidcConfig | undefined,\n\tpublicMcpUrl: string,\n\tnow = Date.now(),\n): Promise<McpOAuthRedirectResult | McpOAuthErrorResult> {\n\tif (!config) return invalidOAuthRequest(\"temporarily_unavailable\", \"OIDC is not configured\");\n\tconst prepared = prepareMcpOAuthAuthorizationRequest(params, clientsStore);\n\tif (\"status\" in prepared) return prepared;\n\n\tconst discovery = await fetchOidcDiscovery(config.issuerUrl);\n\tconst nonce = randomUUID();\n\tconst upstreamState = pendingStore.issue({ oauthParams: params.toString(), nonce }, now);\n\tif (!upstreamState)\n\t\treturn invalidOAuthRequest(\"temporarily_unavailable\", \"Too many pending OIDC authorizations\");\n\n\tconst redirectUri = getCallbackUrl(publicMcpUrl);\n\tconst upstream = new URL(discovery.authorization_endpoint);\n\tupstream.searchParams.set(\"response_type\", \"code\");\n\tupstream.searchParams.set(\"client_id\", config.clientId);\n\tupstream.searchParams.set(\"redirect_uri\", redirectUri);\n\tupstream.searchParams.set(\"scope\", \"openid email\");\n\tupstream.searchParams.set(\"state\", upstreamState);\n\tupstream.searchParams.set(\"nonce\", nonce);\n\treturn { status: 302, location: upstream.href };\n}\n\nexport async function completeOidcAuthorization(\n\tcallbackParams: URLSearchParams,\n\tpendingStore: OidcPendingAuthorizationStore,\n\tconfig: OidcConfig,\n\tpublicMcpUrl: string,\n\tnow = Date.now(),\n): Promise<{ oauthParams: URLSearchParams } | McpOAuthErrorResult> {\n\ttry {\n\t\tconst code = callbackParams.get(\"code\") ?? \"\";\n\t\tconst state = callbackParams.get(\"state\") ?? \"\";\n\t\tif (!state) return invalidOAuthRequest(\"invalid_request\", \"Missing OIDC state\");\n\t\tconst pending = pendingStore.consume(state);\n\t\tif (!pending || pending.expiresAt <= now)\n\t\t\treturn invalidOAuthRequest(\"invalid_request\", \"Expired or unknown OIDC state\");\n\t\tif (!code) return invalidOAuthRequest(\"invalid_request\", \"Missing OIDC code\");\n\n\t\tconst discovery = await fetchOidcDiscovery(config.issuerUrl);\n\t\tconst tokens = await exchangeOidcCode(\n\t\t\tdiscovery.token_endpoint,\n\t\t\tconfig,\n\t\t\tgetCallbackUrl(publicMcpUrl),\n\t\t\tcode,\n\t\t);\n\t\tif (!tokens.id_token)\n\t\t\treturn invalidOAuthRequest(\"invalid_request\", \"OIDC token exchange failed\");\n\t\tconst claims = await validateIdToken(\n\t\t\ttokens.id_token,\n\t\t\tdiscovery,\n\t\t\tconfig.clientId,\n\t\t\tpending.nonce,\n\t\t\tnow,\n\t\t);\n\t\tif (!isAllowedIdentity(claims, config))\n\t\t\treturn invalidOAuthRequest(\"access_denied\", \"OIDC identity is not allowed\");\n\n\t\treturn { oauthParams: new URLSearchParams(pending.oauthParams) };\n\t} catch {\n\t\treturn invalidOAuthRequest(\"access_denied\", \"OIDC identity verification failed\");\n\t}\n}\n\nfunction getCallbackUrl(publicMcpUrl: string): string {\n\tconst url = new URL(publicMcpUrl);\n\treturn new URL(\"/oauth/callback\", url.origin).href;\n}\n\nasync function fetchOidcDiscovery(issuerUrl: string): Promise<OidcDiscoveryMetadata> {\n\tconst issuer = new URL(issuerUrl);\n\tif (issuer.search || issuer.hash)\n\t\tthrow new Error(\"OIDC issuer must not include query or fragment\");\n\tif (issuer.username || issuer.password)\n\t\tthrow new Error(\"OIDC issuer must not include credentials\");\n\tconst discoveryUrl = new URL(\n\t\t`${issuer.pathname.replace(/\\/$/, \"\")}/.well-known/openid-configuration`,\n\t\tissuer.origin,\n\t);\n\tconst response = await fetch(discoveryUrl);\n\tif (!response.ok) throw new Error(\"OIDC discovery request failed\");\n\tconst metadata = (await response.json()) as Partial<OidcDiscoveryMetadata>;\n\tif (metadata.issuer !== issuer.href && metadata.issuer !== issuer.href.replace(/\\/$/, \"\")) {\n\t\tthrow new Error(\"OIDC discovery issuer mismatch\");\n\t}\n\tif (!metadata.authorization_endpoint || !metadata.token_endpoint || !metadata.jwks_uri) {\n\t\tthrow new Error(\"OIDC discovery metadata is incomplete\");\n\t}\n\tconst allowLoopbackHttp = issuer.protocol === \"http:\" && isLoopbackHostname(issuer.hostname);\n\tvalidateOidcUrl(metadata.authorization_endpoint, \"authorization endpoint\", { allowLoopbackHttp });\n\tvalidateOidcUrl(metadata.token_endpoint, \"token endpoint\", { allowLoopbackHttp });\n\tvalidateOidcUrl(metadata.jwks_uri, \"JWKS URI\", { allowLoopbackHttp });\n\treturn metadata as OidcDiscoveryMetadata;\n}\n\nasync function exchangeOidcCode(\n\ttokenEndpoint: string,\n\tconfig: OidcConfig,\n\tredirectUri: string,\n\tcode: string,\n): Promise<OidcTokensResponse> {\n\tconst body = new URLSearchParams({\n\t\tgrant_type: \"authorization_code\",\n\t\tcode,\n\t\tredirect_uri: redirectUri,\n\t\tclient_id: config.clientId,\n\t\tclient_secret: config.clientSecret,\n\t});\n\tconst response = await fetch(tokenEndpoint, {\n\t\tmethod: \"POST\",\n\t\theaders: { \"content-type\": \"application/x-www-form-urlencoded\" },\n\t\tbody,\n\t});\n\tif (!response.ok) throw new Error(\"OIDC token request failed\");\n\treturn (await response.json()) as OidcTokensResponse;\n}\n\nasync function validateIdToken(\n\tidToken: string,\n\tdiscovery: OidcDiscoveryMetadata,\n\tclientId: string,\n\tnonce: string,\n\tnow: number,\n): Promise<JwtClaims> {\n\tconst [encodedHeader, encodedClaims, signature] = idToken.split(\".\");\n\tif (!encodedHeader || !encodedClaims || !signature) throw new Error(\"Invalid OIDC id_token\");\n\tconst header = parseJwtPart<JwtHeader>(encodedHeader);\n\tconst claims = parseJwtPart<JwtClaims>(encodedClaims);\n\tif (header.alg !== \"RS256\" || !header.kid) throw new Error(\"Unsupported OIDC id_token signature\");\n\tif (claims.iss !== discovery.issuer) throw new Error(\"OIDC id_token issuer mismatch\");\n\tif (!audienceIncludes(claims.aud, clientId)) throw new Error(\"OIDC id_token audience mismatch\");\n\tif (!isValidAuthorizedParty(claims.aud, claims.azp, clientId))\n\t\tthrow new Error(\"OIDC id_token authorized party mismatch\");\n\tif (typeof claims.exp !== \"number\" || !Number.isFinite(claims.exp) || claims.exp * 1000 <= now)\n\t\tthrow new Error(\"OIDC id_token is expired\");\n\tif (typeof claims.iat !== \"number\" || !Number.isFinite(claims.iat))\n\t\tthrow new Error(\"OIDC id_token issued-at time is missing\");\n\tif (claims.iat * 1000 > now + ID_TOKEN_CLOCK_SKEW_MS)\n\t\tthrow new Error(\"OIDC id_token issued-at time is in the future\");\n\tif (claims.nonce !== nonce) throw new Error(\"OIDC id_token nonce mismatch\");\n\tif (!claims.sub) throw new Error(\"OIDC id_token subject is missing\");\n\n\tconst jwksResponse = await fetch(discovery.jwks_uri);\n\tif (!jwksResponse.ok) throw new Error(\"OIDC JWKS request failed\");\n\tconst jwks = (await jwksResponse.json()) as JsonWebKeySet;\n\tconst jwk = jwks.keys?.find((key) => key.kid === header.kid && key.kty === \"RSA\");\n\tif (!jwk) throw new Error(\"OIDC signing key not found\");\n\tconst key = createPublicKey({ key: jwk, format: \"jwk\" });\n\tconst signed = `${encodedHeader}.${encodedClaims}`;\n\tconst ok = verify(\"RSA-SHA256\", Buffer.from(signed), key, Buffer.from(signature, \"base64url\"));\n\tif (!ok) throw new Error(\"OIDC id_token signature verification failed\");\n\treturn claims;\n}\n\nfunction parseJwtPart<T>(encoded: string): T {\n\treturn JSON.parse(Buffer.from(encoded, \"base64url\").toString(\"utf8\")) as T;\n}\n\nfunction audienceIncludes(audience: string | string[] | undefined, clientId: string): boolean {\n\treturn Array.isArray(audience) ? audience.includes(clientId) : audience === clientId;\n}\n\nfunction isValidAuthorizedParty(\n\taudience: string | string[] | undefined,\n\tauthorizedParty: string | undefined,\n\tclientId: string,\n): boolean {\n\tif (authorizedParty && authorizedParty !== clientId) return false;\n\treturn !Array.isArray(audience) || audience.length <= 1 || authorizedParty === clientId;\n}\n\nfunction isAllowedIdentity(claims: JwtClaims, config: OidcConfig): boolean {\n\tif (config.allowedSubject && claims.sub === config.allowedSubject) return true;\n\tif (!config.allowedEmail) return false;\n\treturn claims.email_verified === true && claims.email?.toLowerCase() === config.allowedEmail;\n}\n\nfunction validateOidcUrl(\n\tvalue: string,\n\tlabel: string,\n\toptions: { allowLoopbackHttp?: boolean } = {},\n): void {\n\tconst url = new URL(value);\n\tif (url.username || url.password) throw new Error(`OIDC ${label} must not include credentials`);\n\tif (url.protocol === \"https:\") return;\n\tif (options.allowLoopbackHttp && url.protocol === \"http:\" && isLoopbackHostname(url.hostname))\n\t\treturn;\n\tthrow new Error(`OIDC ${label} must use HTTPS`);\n}\n\nfunction isLoopbackHostname(hostname: string): boolean {\n\tconst normalized = hostname.replace(/^\\[(.*)]$/, \"$1\").toLowerCase();\n\treturn normalized === \"localhost\" || normalized === \"127.0.0.1\" || normalized === \"::1\";\n}\n\nfunction invalidOAuthRequest(error: string, description?: string): McpOAuthErrorResult {\n\treturn {\n\t\tstatus: 400,\n\t\tbody: description ? { error, error_description: description } : { error },\n\t};\n}\n","import type { OAuthRegisteredClientsStore } from \"@modelcontextprotocol/sdk/server/auth/clients.js\";\nimport {\n\tAccessDeniedError,\n\tInvalidClientError,\n\tInvalidGrantError,\n\tInvalidRequestError,\n\tInvalidTokenError,\n\tServerError,\n\tTemporarilyUnavailableError,\n\tUnsupportedResponseTypeError,\n} from \"@modelcontextprotocol/sdk/server/auth/errors.js\";\nimport type {\n\tAuthorizationParams,\n\tOAuthServerProvider,\n} from \"@modelcontextprotocol/sdk/server/auth/provider.js\";\nimport type { AuthInfo } from \"@modelcontextprotocol/sdk/server/auth/types.js\";\nimport {\n\ttype OAuthClientInformationFull,\n\ttype OAuthErrorResponse,\n\ttype OAuthTokenRevocationRequest,\n\ttype OAuthTokens,\n\tOAuthTokensSchema,\n} from \"@modelcontextprotocol/sdk/shared/auth.js\";\nimport type { Response } from \"express\";\nimport {\n\tcreateInMemoryOAuthRefreshTokenStore,\n\ttype OAuthAccessTokenStore,\n\ttype OAuthAuthorizationCodeStore,\n\ttype OAuthRefreshTokenStore,\n} from \"./oauth.js\";\nimport {\n\tbeginOidcAuthorization,\n\ttype OidcConfig,\n\ttype OidcPendingAuthorizationStore,\n} from \"./oidc.js\";\n\nexport interface MemoryOAuthServerProviderOptions {\n\tclientsStore: OAuthRegisteredClientsStore;\n\tcodeStore: OAuthAuthorizationCodeStore;\n\ttokenStore: OAuthAccessTokenStore;\n\trefreshTokenStore?: OAuthRefreshTokenStore;\n\tpublicMcpUrl: string;\n\toidc?: { config: OidcConfig; pendingStore: OidcPendingAuthorizationStore };\n\tnow?: () => number;\n}\n\n/**\n * MemoryOAuthServerProvider adapts codemem's existing in-memory stores to the\n * `@modelcontextprotocol/sdk` `OAuthServerProvider` contract so the SDK's\n * `mcpAuthRouter` and `requireBearerAuth` middleware can drive the OAuth\n * lifecycle. This class is the boundary between SDK-handled HTTP and\n * codemem-owned storage / upstream-OIDC bridging.\n *\n * Conventions encoded here:\n * - `authorize()` does NOT mint the MCP authorization code itself. It\n * persists pending state and redirects the user-agent to the upstream OIDC\n * provider. The MCP code is issued later by codemem's own /oauth/callback\n * route (wired in codemem-b20m.3) after the upstream identity is validated.\n * - PKCE is validated by the SDK token handler against the challenge returned\n * from `challengeForAuthorizationCode`. We do not re-verify here.\n * - `expiresAt` returned in `AuthInfo` is epoch SECONDS per the SDK's\n * `requireBearerAuth` expectations; the underlying store records ms.\n * - Refresh-token grants use dual-token rotation: the current token and one\n * previous token are accepted to tolerate client retry races, while older\n * replayed tokens revoke the whole grant.\n */\nexport class MemoryOAuthServerProvider implements OAuthServerProvider {\n\treadonly #clientsStore: OAuthRegisteredClientsStore;\n\treadonly #codeStore: OAuthAuthorizationCodeStore;\n\treadonly #tokenStore: OAuthAccessTokenStore;\n\treadonly #refreshTokenStore: OAuthRefreshTokenStore;\n\treadonly #publicMcpUrl: string;\n\treadonly #resourceServerUrl: string;\n\treadonly #oidc?: { config: OidcConfig; pendingStore: OidcPendingAuthorizationStore };\n\treadonly #now: () => number;\n\n\tconstructor(options: MemoryOAuthServerProviderOptions) {\n\t\tthis.#clientsStore = options.clientsStore;\n\t\tthis.#codeStore = options.codeStore;\n\t\tthis.#tokenStore = options.tokenStore;\n\t\tthis.#refreshTokenStore = options.refreshTokenStore ?? createInMemoryOAuthRefreshTokenStore();\n\t\tthis.#publicMcpUrl = options.publicMcpUrl;\n\t\tthis.#resourceServerUrl = new URL(options.publicMcpUrl).href;\n\t\tthis.#oidc = options.oidc;\n\t\tthis.#now = options.now ?? Date.now;\n\t}\n\n\tget clientsStore(): OAuthRegisteredClientsStore {\n\t\treturn this.#clientsStore;\n\t}\n\n\tasync authorize(\n\t\tclient: OAuthClientInformationFull,\n\t\tparams: AuthorizationParams,\n\t\tres: Response,\n\t): Promise<void> {\n\t\tif (!this.#oidc) {\n\t\t\tthrow new TemporarilyUnavailableError(\"OIDC is not configured\");\n\t\t}\n\t\tconst upstreamParams = buildUpstreamAuthorizationParams(client, params);\n\t\tconst result = await beginOidcAuthorization(\n\t\t\tupstreamParams,\n\t\t\tthis.#clientsStore,\n\t\t\tthis.#oidc.pendingStore,\n\t\t\tthis.#oidc.config,\n\t\t\tthis.#publicMcpUrl,\n\t\t\tthis.#now(),\n\t\t);\n\t\tif (result.status === 302) {\n\t\t\tres.redirect(302, result.location);\n\t\t\treturn;\n\t\t}\n\t\tthrow mapOAuthErrorBody(result.body);\n\t}\n\n\tasync challengeForAuthorizationCode(\n\t\t_client: OAuthClientInformationFull,\n\t\tauthorizationCode: string,\n\t): Promise<string> {\n\t\tconst record = this.#codeStore.peekCode(authorizationCode);\n\t\tif (!record) throw new InvalidGrantError(\"Invalid or already used code\");\n\t\tif (record.clientId !== _client.client_id) {\n\t\t\tthrow new InvalidGrantError(\"Code does not match client\");\n\t\t}\n\t\tif (record.expiresAt <= this.#now()) {\n\t\t\tthis.#codeStore.consumeCode(authorizationCode);\n\t\t\tthrow new InvalidGrantError(\"Expired code\");\n\t\t}\n\t\treturn record.codeChallenge;\n\t}\n\n\tasync exchangeAuthorizationCode(\n\t\tclient: OAuthClientInformationFull,\n\t\tauthorizationCode: string,\n\t\t_codeVerifier?: string,\n\t\tredirectUri?: string,\n\t\tresource?: URL,\n\t): Promise<OAuthTokens> {\n\t\tconst now = this.#now();\n\t\tconst record = this.#codeStore.peekCode(authorizationCode);\n\t\tif (!record) throw new InvalidGrantError(\"Invalid or already used code\");\n\t\tif (record.expiresAt <= now) {\n\t\t\tthis.#codeStore.consumeCode(authorizationCode);\n\t\t\tthrow new InvalidGrantError(\"Expired code\");\n\t\t}\n\t\tif (record.clientId !== client.client_id) {\n\t\t\tthis.#codeStore.consumeCode(authorizationCode);\n\t\t\tthrow new InvalidGrantError(\"Code does not match client\");\n\t\t}\n\t\t// RFC 6749 §4.1.3: if the authorization request included redirect_uri,\n\t\t// the token request MUST include the same value. codemem always binds a\n\t\t// redirect_uri at /authorize, so a missing value at /token is always a\n\t\t// grant mismatch, not an optional check.\n\t\tif (redirectUri === undefined || record.redirectUri !== redirectUri) {\n\t\t\tthis.#codeStore.consumeCode(authorizationCode);\n\t\t\tthrow new InvalidGrantError(\"Code does not match redirect_uri\");\n\t\t}\n\t\tif ((record.resource ?? null) !== (resource?.href ?? null)) {\n\t\t\tthis.#codeStore.consumeCode(authorizationCode);\n\t\t\tthrow new InvalidGrantError(\"Code does not match resource\");\n\t\t}\n\n\t\tconst scopes = normalizeClientScopes(record.scopes) ?? [];\n\t\tconst grant = this.#refreshTokenStore.issueGrant(\n\t\t\t{ clientId: client.client_id, scopes, resource: record.resource },\n\t\t\tnow,\n\t\t);\n\t\tif (!grant) {\n\t\t\tthrow new TemporarilyUnavailableError(\"Too many active refresh grants\");\n\t\t}\n\t\tconst issued = this.#tokenStore.issueToken(\n\t\t\tclient.client_id,\n\t\t\tnow,\n\t\t\trecord.resource,\n\t\t\tgrant.grant.grantId,\n\t\t\tscopes,\n\t\t);\n\t\tif (!issued) {\n\t\t\t// Token-store overload is transient: leave the auth code unused so the\n\t\t\t// client can retry token exchange without restarting the OAuth flow.\n\t\t\tthis.#refreshTokenStore.revokeGrant(grant.grant.grantId, now);\n\t\t\tthrow new TemporarilyUnavailableError(\"Too many active access tokens\");\n\t\t}\n\n\t\tconst consumed = this.#codeStore.consumeCode(authorizationCode);\n\t\tif (!consumed) {\n\t\t\tthis.#tokenStore.revokeToken(issued.token, now);\n\t\t\tthis.#refreshTokenStore.revokeGrant(grant.grant.grantId, now);\n\t\t\t// Lost a race with a concurrent exchange that consumed the code in\n\t\t\t// the gap between peek and consume. Reject rather than issuing a\n\t\t\t// duplicate usable token.\n\t\t\tthrow new InvalidGrantError(\"Authorization code already used\");\n\t\t}\n\n\t\treturn OAuthTokensSchema.parse({\n\t\t\taccess_token: issued.token,\n\t\t\ttoken_type: \"Bearer\",\n\t\t\texpires_in: issued.expiresIn,\n\t\t\trefresh_token: grant.refreshToken,\n\t\t});\n\t}\n\n\tasync exchangeRefreshToken(\n\t\tclient: OAuthClientInformationFull,\n\t\trefreshToken: string,\n\t\tscopes?: string[],\n\t\tresource?: URL,\n\t): Promise<OAuthTokens> {\n\t\tconst now = this.#now();\n\t\tconst rotation = this.#refreshTokenStore.rotateRefreshToken(\n\t\t\tclient.client_id,\n\t\t\trefreshToken,\n\t\t\t{ scopes: normalizeClientScopes(scopes), ...(resource ? { resource: resource.href } : {}) },\n\t\t\tnow,\n\t\t);\n\t\tif (!rotation.ok) {\n\t\t\tif (rotation.reason === \"refresh_token_replay\" && rotation.grantId) {\n\t\t\t\tthis.#tokenStore.revokeTokensForGrant?.(rotation.grantId, now);\n\t\t\t}\n\t\t\tthrow new InvalidGrantError(refreshTokenErrorDescription(rotation.reason));\n\t\t}\n\t\tconst issued = this.#tokenStore.issueToken(\n\t\t\tclient.client_id,\n\t\t\tnow,\n\t\t\trotation.grant.resource,\n\t\t\trotation.grant.grantId,\n\t\t\trotation.grant.scopes,\n\t\t);\n\t\tif (!issued) throw new TemporarilyUnavailableError(\"Too many active access tokens\");\n\t\treturn OAuthTokensSchema.parse({\n\t\t\taccess_token: issued.token,\n\t\t\ttoken_type: \"Bearer\",\n\t\t\texpires_in: issued.expiresIn,\n\t\t\trefresh_token: rotation.refreshToken,\n\t\t});\n\t}\n\n\tasync verifyAccessToken(token: string): Promise<AuthInfo> {\n\t\tconst result = this.#tokenStore.verifyToken(token, this.#now());\n\t\tif (!result.ok) {\n\t\t\tconst reason =\n\t\t\t\tresult.reason === \"expired_token\"\n\t\t\t\t\t? \"Token has expired\"\n\t\t\t\t\t: result.reason === \"revoked_token\"\n\t\t\t\t\t\t? \"Token has been revoked\"\n\t\t\t\t\t\t: \"Token is invalid\";\n\t\t\tthrow new InvalidTokenError(reason);\n\t\t}\n\t\tconst authInfo: AuthInfo = {\n\t\t\ttoken,\n\t\t\tclientId: result.record.clientId,\n\t\t\tscopes: result.record.scopes,\n\t\t\texpiresAt: Math.floor(result.record.expiresAt / 1000),\n\t\t};\n\t\tif (result.record.resource) {\n\t\t\tif (new URL(result.record.resource).href !== this.#resourceServerUrl) {\n\t\t\t\tthrow new InvalidTokenError(\"Token audience does not match this resource server\");\n\t\t\t}\n\t\t\tauthInfo.resource = new URL(result.record.resource);\n\t\t}\n\t\treturn authInfo;\n\t}\n\n\tasync revokeToken(\n\t\t_client: OAuthClientInformationFull,\n\t\trequest: OAuthTokenRevocationRequest,\n\t): Promise<void> {\n\t\tconst now = this.#now();\n\t\tthis.#tokenStore.revokeToken(request.token, now);\n\t\tconst grantId = this.#refreshTokenStore.revokeRefreshToken(request.token, now);\n\t\tif (grantId) this.#tokenStore.revokeTokensForGrant?.(grantId, now);\n\t}\n}\n\nfunction buildUpstreamAuthorizationParams(\n\tclient: OAuthClientInformationFull,\n\tparams: AuthorizationParams,\n): URLSearchParams {\n\tconst upstream = new URLSearchParams();\n\tupstream.set(\"client_id\", client.client_id);\n\tupstream.set(\"redirect_uri\", params.redirectUri);\n\tupstream.set(\"response_type\", \"code\");\n\tupstream.set(\"code_challenge\", params.codeChallenge);\n\tupstream.set(\"code_challenge_method\", \"S256\");\n\tif (params.state) upstream.set(\"state\", params.state);\n\tif (params.scopes?.length) upstream.set(\"scope\", params.scopes.join(\" \"));\n\tif (params.resource) upstream.set(\"resource\", params.resource.href);\n\treturn upstream;\n}\n\nfunction mapOAuthErrorBody(body: OAuthErrorResponse): Error {\n\tconst description = body.error_description ?? body.error;\n\tswitch (body.error) {\n\t\tcase \"temporarily_unavailable\":\n\t\t\treturn new TemporarilyUnavailableError(description);\n\t\tcase \"invalid_request\":\n\t\t\treturn new InvalidRequestError(description);\n\t\tcase \"invalid_client\":\n\t\t\treturn new InvalidClientError(description);\n\t\tcase \"access_denied\":\n\t\t\treturn new AccessDeniedError(description);\n\t\tcase \"unsupported_response_type\":\n\t\t\treturn new UnsupportedResponseTypeError(description);\n\t\tdefault:\n\t\t\treturn new ServerError(description);\n\t}\n}\n\nfunction refreshTokenErrorDescription(reason: string): string {\n\tswitch (reason) {\n\t\tcase \"expired_refresh_token\":\n\t\t\treturn \"Refresh token has expired\";\n\t\tcase \"revoked_refresh_token\":\n\t\t\treturn \"Refresh token has been revoked\";\n\t\tcase \"client_mismatch\":\n\t\t\treturn \"Refresh token does not match client\";\n\t\tcase \"scope_mismatch\":\n\t\t\treturn \"Refresh token scope cannot be expanded\";\n\t\tcase \"resource_mismatch\":\n\t\t\treturn \"Refresh token does not match resource\";\n\t\tcase \"refresh_token_replay\":\n\t\t\treturn \"Refresh token replay detected\";\n\t\tdefault:\n\t\t\treturn \"Invalid refresh token\";\n\t}\n}\n\nfunction normalizeClientScopes(scopes: string[] | undefined): string[] | undefined {\n\tconst normalized = scopes\n\t\t?.map((scope) => scope.trim())\n\t\t.filter(Boolean)\n\t\t.map((scope) => {\n\t\t\tif (scope === \"memory:read_access\") return \"memory:read\";\n\t\t\tif (scope === \"memory:write_access\") return \"memory:write\";\n\t\t\treturn scope;\n\t\t});\n\treturn normalized && normalized.length > 0 ? normalized : undefined;\n}\n","#!/usr/bin/env node\n\n/**\n * @codemem/mcp — MCP Streamable HTTP server bootstrap.\n *\n * Local-first HTTP transport for MCP clients. OAuth metadata and Dynamic Client\n * Registration are exposed for remote MCP setup; public MCP requests require\n * OAuth bearer tokens.\n */\n\nimport { createHash, randomUUID } from \"node:crypto\";\nimport { createServer, type IncomingMessage, type Server } from \"node:http\";\nimport { isIP } from \"node:net\";\nimport { pathToFileURL } from \"node:url\";\nimport { MemoryStore, resolveDbPath } from \"@codemem/core\";\nimport { requireBearerAuth } from \"@modelcontextprotocol/sdk/server/auth/middleware/bearerAuth.js\";\nimport {\n\tgetOAuthProtectedResourceMetadataUrl,\n\tmcpAuthRouter,\n} from \"@modelcontextprotocol/sdk/server/auth/router.js\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StreamableHTTPServerTransport } from \"@modelcontextprotocol/sdk/server/streamableHttp.js\";\nimport express, { type NextFunction, type Request, type Response } from \"express\";\nimport { rateLimit } from \"express-rate-limit\";\nimport {\n\ttype BearerDenyReason,\n\tbuildOAuthAuditEvent,\n\ttype OAuthAuditEmitter,\n\tresolveOAuthAuditEmitterFromEnv,\n\twrapAuditEmitterBestEffort,\n} from \"./audit.js\";\nimport { canonicalJson } from \"./canonical-json.js\";\nimport {\n\tcreateInMemoryOAuthAccessTokenStore,\n\tcreateInMemoryOAuthAuthorizationCodeStore,\n\tcreateInMemoryOAuthClientsStore,\n\tcreateJsonFileOAuthStateStore,\n\tcreateMcpOAuthMetadata,\n\tcreateMcpProtectedResourceMetadata,\n\tMCP_OAUTH_PUBLIC_URL_ENV,\n\tMCP_OAUTH_RESOURCE_NAME,\n\tMCP_OAUTH_SCOPES_SUPPORTED,\n\tMCP_OAUTH_SERVICE_DOCUMENTATION_URL,\n\tnormalizeMcpPublicUrl,\n\ttype OAuthAccessTokenStore,\n} from \"./oauth.js\";\nimport {\n\tcompleteOidcAuthorization,\n\tcreateInMemoryOidcPendingAuthorizationStore,\n\tresolveOidcConfig,\n} from \"./oidc.js\";\nimport { MemoryOAuthServerProvider } from \"./provider.js\";\nimport { createCodememMcpServer } from \"./server.js\";\n\nexport const DEFAULT_MCP_HTTP_HOST = \"127.0.0.1\";\nexport const DEFAULT_MCP_HTTP_PORT = 38889;\nconst HTTP_DEFAULT_PORT = 80;\nconst TRUSTED_PUBLIC_BROWSER_ORIGINS = new Set([\"https://chatgpt.com\", \"https://claude.ai\"]);\nconst CORS_ALLOW_HEADERS = \"authorization,content-type,mcp-session-id\";\nconst CORS_MAX_AGE_SECONDS = \"600\";\nconst MAX_GUARD_LOG_FIELD_LENGTH = 256;\nconst PUBLIC_MCP_RATE_LIMIT_WINDOW_MS = 15 * 60 * 1000;\nconst PUBLIC_MCP_RATE_LIMIT_REQUESTS = 600;\nexport const MCP_HTTP_MAX_JSON_BODY_BYTES = 4 * 1024 * 1024;\nexport const MCP_HTTP_RETRIEVAL_RETRY_WINDOW_MS = 5 * 60 * 1000;\nconst MCP_HTTP_RETRIEVAL_RETRY_MAX_ENTRIES = 2000;\n\nconst VALID_HOSTNAME = /^[a-zA-Z0-9.-]+$/;\nconst LOOPBACK_HOSTS = new Set([\"127.0.0.1\", \"::1\", \"localhost\"]);\n\ninterface ActiveRequest {\n\tmcpServer: McpServer;\n}\n\nexport interface CodememMcpHttpOptions {\n\thost?: string;\n\tport?: number | string;\n\tdbPath?: string;\n\tallowUnsafePublic?: boolean;\n\tpublicUrl?: string;\n\toauthAccessTokenStore?: OAuthAccessTokenStore;\n\toauthStatePath?: string;\n\tauditEmitter?: OAuthAuditEmitter;\n\tretrievalLedgerNow?: () => number;\n}\n\nexport interface CodememMcpHttpServer {\n\tserver: Server;\n\tstore: MemoryStore;\n\turl: string;\n\tclose: () => Promise<void>;\n}\n\nexport function authenticatedRetrievalPrincipal(\n\tauth: { clientId?: string; token?: string; extra?: Record<string, unknown> } | undefined,\n): string | undefined {\n\tconst authSubject = auth?.extra?.sub;\n\tif (typeof authSubject === \"string\" && authSubject.trim().length > 0) {\n\t\tconst subject = authSubject.trim();\n\t\tconst clientId = auth?.clientId?.trim();\n\t\treturn clientId ? `subject-client:${canonicalJson([subject, clientId])}` : `subject:${subject}`;\n\t}\n\treturn auth?.token ? `token:${auth.token}` : undefined;\n}\n\nexport function validateMcpHttpHost(host: string | undefined, allowUnsafePublic = false): string {\n\tconst value = host?.trim() || DEFAULT_MCP_HTTP_HOST;\n\tif (value.includes(\"://\") || value.includes(\"/\") || value.includes(\"\\\\\")) {\n\t\tthrow new Error(`Invalid MCP HTTP host: ${host}`);\n\t}\n\tif (!(isIP(value) || value === \"localhost\" || VALID_HOSTNAME.test(value))) {\n\t\tthrow new Error(`Invalid MCP HTTP host: ${host}`);\n\t}\n\tif (!allowUnsafePublic && !isLoopbackHost(value)) {\n\t\tthrow new Error(\n\t\t\t`Refusing unsafe MCP HTTP host ${value}; set CODEMEM_MCP_HTTP_UNSAFE_PUBLIC=1 to allow non-loopback binding`,\n\t\t);\n\t}\n\treturn value;\n}\n\nexport function isLoopbackHost(host: string): boolean {\n\treturn LOOPBACK_HOSTS.has(normalizeHost(host));\n}\n\nexport function isUnsafePublicBindAllowed(\n\tvalue = process.env.CODEMEM_MCP_HTTP_UNSAFE_PUBLIC,\n): boolean {\n\treturn value === \"1\" || value?.toLowerCase() === \"true\" || value?.toLowerCase() === \"yes\";\n}\n\nexport function isAllowedMcpHttpRequestHost(\n\theader: string | undefined,\n\texpectedPort: number,\n): boolean {\n\tconst parsed = parseHostHeader(header);\n\tif (!parsed) return false;\n\tif (!isLoopbackHost(parsed.host)) return false;\n\tif (parsed.port === null) {\n\t\t// No `:port` in the Host header means the client is using the protocol\n\t\t// default. This server is plain HTTP, so the implied port is 80. Only\n\t\t// accept the bare-host form when the bound port is also 80.\n\t\treturn expectedPort === HTTP_DEFAULT_PORT;\n\t}\n\treturn parsed.port === expectedPort;\n}\n\nexport function isAllowedMcpHttpRequestOrigin(\n\theader: string | undefined,\n\texpectedPort: number,\n): boolean {\n\tif (!header) return true;\n\ttry {\n\t\tconst url = new URL(header);\n\t\tconst port = url.port ? Number(url.port) : url.protocol === \"https:\" ? 443 : 80;\n\t\treturn (\n\t\t\t(url.protocol === \"http:\" || url.protocol === \"https:\") &&\n\t\t\turl.username === \"\" &&\n\t\t\turl.password === \"\" &&\n\t\t\turl.pathname === \"/\" &&\n\t\t\turl.search === \"\" &&\n\t\t\turl.hash === \"\" &&\n\t\t\tisLoopbackHost(url.hostname) &&\n\t\t\tport === expectedPort\n\t\t);\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nexport function isAllowedMcpHttpRequestRemoteAddress(address: string | undefined): boolean {\n\tif (!address) return false;\n\treturn isLoopbackHost(address.replace(/^::ffff:/, \"\"));\n}\n\nfunction normalizeHost(host: string): string {\n\treturn host.replace(/^\\[(.*)]$/, \"$1\").toLowerCase();\n}\n\nfunction parseHostHeader(header: string | undefined): { host: string; port: number | null } | null {\n\tif (!header) return null;\n\tif (header.startsWith(\"[\")) {\n\t\t// Bracketed IPv6: `[::1]` or `[::1]:8080`.\n\t\tconst withPort = /^\\[([^\\]]+)]:(\\d+)$/.exec(header);\n\t\tif (withPort?.[1] && withPort[2]) {\n\t\t\treturn { host: withPort[1], port: Number(withPort[2]) };\n\t\t}\n\t\tconst bareIpv6 = /^\\[([^\\]]+)]$/.exec(header);\n\t\tif (bareIpv6?.[1]) return { host: bareIpv6[1], port: null };\n\t\treturn null;\n\t}\n\tconst lastColon = header.lastIndexOf(\":\");\n\tif (lastColon < 0) {\n\t\t// RFC-compliant clients may omit `:port` on default-port requests. Treat\n\t\t// the implied port as \"use the protocol default\" and let the caller\n\t\t// reconcile against the actually bound port.\n\t\treturn { host: header, port: null };\n\t}\n\tconst host = header.slice(0, lastColon);\n\tconst port = Number(header.slice(lastColon + 1));\n\tif (!Number.isInteger(port)) return null;\n\treturn { host, port };\n}\n\nexport function parseMcpHttpPort(port: number | string | undefined): number {\n\tif (port === undefined || port === \"\") return DEFAULT_MCP_HTTP_PORT;\n\tconst value = typeof port === \"number\" ? port : Number(port);\n\tif (!Number.isInteger(value) || value < 0 || value > 65_535) {\n\t\tthrow new Error(`Invalid MCP HTTP port: ${port}`);\n\t}\n\treturn value;\n}\n\nexport async function startCodememMcpHttpServer(\n\toptions: CodememMcpHttpOptions = {},\n): Promise<CodememMcpHttpServer> {\n\tconst host = validateMcpHttpHost(\n\t\toptions.host ?? process.env.CODEMEM_MCP_HTTP_HOST,\n\t\toptions.allowUnsafePublic ?? isUnsafePublicBindAllowed(),\n\t);\n\tconst port = parseMcpHttpPort(options.port ?? process.env.CODEMEM_MCP_HTTP_PORT);\n\tconst configuredPublicUrl = options.publicUrl ?? process.env[MCP_OAUTH_PUBLIC_URL_ENV];\n\tconst configuredPublicMcpUrl = configuredPublicUrl\n\t\t? normalizeMcpPublicUrl(configuredPublicUrl)\n\t\t: undefined;\n\tconst store = new MemoryStore(options.dbPath ?? resolveDbPath());\n\tconst oauthStateStore = options.oauthAccessTokenStore\n\t\t? undefined\n\t\t: createJsonFileOAuthStateStore(options.oauthStatePath);\n\tconst clientsStore = oauthStateStore ?? createInMemoryOAuthClientsStore();\n\tconst codeStore = oauthStateStore ?? createInMemoryOAuthAuthorizationCodeStore();\n\tconst tokenStore =\n\t\toptions.oauthAccessTokenStore ?? oauthStateStore ?? createInMemoryOAuthAccessTokenStore();\n\tconst oidcConfig = resolveOidcConfig();\n\tconst oidcPendingStore = createInMemoryOidcPendingAuthorizationStore();\n\tconst shouldRequireMcpBearer = configuredPublicMcpUrl !== undefined || oidcConfig !== undefined;\n\tconst auditEmit = wrapAuditEmitterBestEffort(\n\t\toptions.auditEmitter ?? resolveOAuthAuditEmitterFromEnv(),\n\t);\n\tconst activeRequests = new Set<ActiveRequest>();\n\tconst resolveRetrievalLedgerScopeId = createHttpRetrievalLedgerScopeResolver();\n\tlet closePromise: Promise<void> | null = null;\n\n\tconst app = express();\n\tapp.disable(\"x-powered-by\");\n\t// Tailscale Funnel and similar local ingress proxies forward from loopback and\n\t// add X-Forwarded-For. Trust only loopback proxy hops so SDK rate limiters can\n\t// key on the real client IP without making public clients spoofable.\n\tapp.set(\"trust proxy\", \"loopback\");\n\tconst server = createServer(app);\n\n\tawait new Promise<void>((resolve, reject) => {\n\t\tserver.once(\"error\", reject);\n\t\tserver.listen({ host, port }, () => {\n\t\t\tserver.off(\"error\", reject);\n\t\t\tresolve();\n\t\t});\n\t});\n\n\tconst publicMcpUrl = configuredPublicMcpUrl?.href ?? getServerUrl(server, host);\n\tconst publicMcpUrlObject = new URL(publicMcpUrl);\n\tconst issuerUrl = getSdkIssuerUrl(publicMcpUrlObject, getBoundPort(server));\n\tconst provider = new MemoryOAuthServerProvider({\n\t\tclientsStore,\n\t\tcodeStore,\n\t\ttokenStore,\n\t\tpublicMcpUrl,\n\t\t...(oauthStateStore ? { refreshTokenStore: oauthStateStore } : {}),\n\t\t...(oidcConfig ? { oidc: { config: oidcConfig, pendingStore: oidcPendingStore } } : {}),\n\t});\n\tconst resourceMetadataUrl = getOAuthProtectedResourceMetadataUrl(publicMcpUrlObject);\n\n\tapp.use(\n\t\trateLimit({\n\t\t\twindowMs: PUBLIC_MCP_RATE_LIMIT_WINDOW_MS,\n\t\t\tlimit: PUBLIC_MCP_RATE_LIMIT_REQUESTS,\n\t\t\tstandardHeaders: \"draft-8\",\n\t\t\tlegacyHeaders: false,\n\t\t\t// Avoid express-rate-limit's default IPv6 subnet helper here: its current\n\t\t\t// transitive ip-address API throws on IPv6 loopback in our Node 24 test path.\n\t\t\t// This coarse limiter is defense-in-depth before the SDK OAuth limiters and\n\t\t\t// the Host/Origin guard; it must never break local IPv6 metadata requests.\n\t\t\tipv6Subnet: false,\n\t\t}),\n\t);\n\tapp.use((req, res, next) => {\n\t\tconst boundPort = getBoundPort(server);\n\t\tconst pathname = normalizeRoutePath(req.path);\n\t\tif (pathname === \"/mcp\") {\n\t\t\tif (isAllowedMcpHttpRequest(req, boundPort, configuredPublicMcpUrl)) {\n\t\t\t\tapplyPublicCorsHeaders(req, res, configuredPublicMcpUrl);\n\t\t\t\tif (req.method === \"OPTIONS\") {\n\t\t\t\t\tres.status(204).send(\"\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\treturn next();\n\t\t\t}\n\t\t\temitHttpGuardDeny(req, pathname, configuredPublicMcpUrl);\n\t\t\tres.status(403).type(\"text/plain\").send(\"Forbidden\");\n\t\t\treturn;\n\t\t}\n\t\tif (isOAuthOrMetadataPath(pathname)) {\n\t\t\tif (isAllowedOAuthHttpRequest(req, boundPort, configuredPublicMcpUrl)) {\n\t\t\t\tapplyPublicCorsHeaders(req, res, configuredPublicMcpUrl);\n\t\t\t\tif (req.method === \"OPTIONS\") {\n\t\t\t\t\tres.status(204).send(\"\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\treturn next();\n\t\t\t}\n\t\t\temitHttpGuardDeny(req, pathname, configuredPublicMcpUrl);\n\t\t\tres.status(403).type(\"text/plain\").send(\"Forbidden\");\n\t\t\treturn;\n\t\t}\n\t\tnext();\n\t});\n\n\tapp.use(auditOAuthRouteResponses(auditEmit));\n\n\tapp.get(\"/oauth/callback\", async (req, res) => {\n\t\tconst remoteAddress = req.socket.remoteAddress ?? undefined;\n\t\tif (!oidcConfig) {\n\t\t\tauditEmit(\n\t\t\t\tbuildOAuthAuditEvent(\"oidc_callback\", {\n\t\t\t\t\toutcome: \"denied\",\n\t\t\t\t\treason: \"oidc_not_configured\",\n\t\t\t\t\tremoteAddress,\n\t\t\t\t}),\n\t\t\t);\n\t\t\tres.status(400).json({\n\t\t\t\terror: \"temporarily_unavailable\",\n\t\t\t\terror_description: \"OIDC is not configured\",\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tconst completed = await completeOidcAuthorization(\n\t\t\tnew URLSearchParams(req.query as Record<string, string>),\n\t\t\toidcPendingStore,\n\t\t\toidcConfig,\n\t\t\tpublicMcpUrl,\n\t\t);\n\t\tif (\"status\" in completed) {\n\t\t\tauditEmit(\n\t\t\t\tbuildOAuthAuditEvent(\"oidc_callback\", {\n\t\t\t\t\toutcome: \"denied\",\n\t\t\t\t\treason: completed.body.error,\n\t\t\t\t\tremoteAddress,\n\t\t\t\t}),\n\t\t\t);\n\t\t\tres.status(completed.status).json(completed.body);\n\t\t\treturn;\n\t\t}\n\t\tconst oauthClientId = completed.oauthParams.get(\"client_id\") ?? undefined;\n\t\tconst code = codeStore.issueCode({\n\t\t\tclientId: completed.oauthParams.get(\"client_id\") ?? \"\",\n\t\t\tredirectUri: completed.oauthParams.get(\"redirect_uri\") ?? \"\",\n\t\t\tcodeChallenge: completed.oauthParams.get(\"code_challenge\") ?? \"\",\n\t\t\tscopes: parseScopeList(completed.oauthParams.get(\"scope\")),\n\t\t\t...(completed.oauthParams.get(\"resource\")\n\t\t\t\t? { resource: completed.oauthParams.get(\"resource\") ?? undefined }\n\t\t\t\t: {}),\n\t\t\texpiresAt: Date.now() + 5 * 60 * 1000,\n\t\t});\n\t\tif (!code) {\n\t\t\tauditEmit(\n\t\t\t\tbuildOAuthAuditEvent(\"oidc_callback\", {\n\t\t\t\t\toutcome: \"denied\",\n\t\t\t\t\treason: \"temporarily_unavailable\",\n\t\t\t\t\tclientId: oauthClientId,\n\t\t\t\t\tremoteAddress,\n\t\t\t\t}),\n\t\t\t);\n\t\t\tres.status(400).json({\n\t\t\t\terror: \"temporarily_unavailable\",\n\t\t\t\terror_description: \"Too many active authorization codes\",\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tconst redirect = new URL(completed.oauthParams.get(\"redirect_uri\") ?? \"\");\n\t\tredirect.searchParams.set(\"code\", code);\n\t\tconst state = completed.oauthParams.get(\"state\");\n\t\tif (state) redirect.searchParams.set(\"state\", state);\n\t\tauditEmit(\n\t\t\tbuildOAuthAuditEvent(\"oidc_callback\", {\n\t\t\t\toutcome: \"success\",\n\t\t\t\treason: \"code_issued\",\n\t\t\t\tclientId: oauthClientId,\n\t\t\t\tremoteAddress,\n\t\t\t}),\n\t\t);\n\t\tres.redirect(302, redirect.href);\n\t});\n\n\tapp.get(\"/.well-known/oauth-authorization-server\", (_req, res) => {\n\t\tres.status(200).json(createMcpOAuthMetadata({ mcpUrl: publicMcpUrl, clientsStore }));\n\t});\n\tapp.get(\"/.well-known/oauth-protected-resource/mcp\", (_req, res) => {\n\t\tres.status(200).json(createMcpProtectedResourceMetadata(publicMcpUrl));\n\t});\n\n\tapp.use(\n\t\tmcpAuthRouter({\n\t\t\tprovider,\n\t\t\tissuerUrl,\n\t\t\tbaseUrl: issuerUrl,\n\t\t\tresourceServerUrl: publicMcpUrlObject,\n\t\t\tresourceName: MCP_OAUTH_RESOURCE_NAME,\n\t\t\tscopesSupported: MCP_OAUTH_SCOPES_SUPPORTED,\n\t\t\tserviceDocumentationUrl: new URL(MCP_OAUTH_SERVICE_DOCUMENTATION_URL),\n\t\t\tclientRegistrationOptions: { clientSecretExpirySeconds: 0 },\n\t\t}),\n\t);\n\n\tconst bearerMiddleware = shouldRequireMcpBearer\n\t\t? requireBearerAuth({ verifier: provider, resourceMetadataUrl })\n\t\t: (_req: Request, _res: Response, next: NextFunction) => next();\n\tconst bearerAuditMiddleware = shouldRequireMcpBearer\n\t\t? auditBearerPreflight(auditEmit, tokenStore)\n\t\t: (_req: Request, _res: Response, next: NextFunction) => next();\n\tapp.post(\n\t\t\"/mcp\",\n\t\tbearerAuditMiddleware,\n\t\tbearerMiddleware,\n\t\texpress.json({ limit: MCP_HTTP_MAX_JSON_BODY_BYTES }),\n\t\tasync (req: Request, res: Response) => {\n\t\t\tif (req.auth) {\n\t\t\t\tauditEmit(\n\t\t\t\t\tbuildOAuthAuditEvent(\"bearer\", {\n\t\t\t\t\t\toutcome: \"success\",\n\t\t\t\t\t\tclientId: req.auth.clientId,\n\t\t\t\t\t\tremoteAddress: req.socket.remoteAddress ?? undefined,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst retrievalPrincipal = authenticatedRetrievalPrincipal(req.auth);\n\t\t\tconst retrievalLedgerScopeId = resolveRetrievalLedgerScopeId({\n\t\t\t\tendpoint: publicMcpUrlObject,\n\t\t\t\tprincipal: retrievalPrincipal,\n\t\t\t\trequestBody: req.body,\n\t\t\t\tnow: options.retrievalLedgerNow?.() ?? Date.now(),\n\t\t\t});\n\t\t\tconst mcpServer = createCodememMcpServer(store, {\n\t\t\t\tretrievalLedgerScopeId,\n\t\t\t\tretrievalLedgerIdentityMode: \"stateless\",\n\t\t\t});\n\t\t\tconst transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined });\n\t\t\tconst activeRequest = { mcpServer };\n\t\t\tactiveRequests.add(activeRequest);\n\t\t\ttry {\n\t\t\t\tawait mcpServer.connect(transport);\n\t\t\t\tawait transport.handleRequest(req, res, req.body);\n\t\t\t} finally {\n\t\t\t\tactiveRequests.delete(activeRequest);\n\t\t\t\tawait mcpServer.close();\n\t\t\t}\n\t\t},\n\t\thandleMcpJsonBodyError,\n\t);\n\tapp.all(\"/mcp\", (_req, res) => {\n\t\tres.setHeader(\"Allow\", \"POST\");\n\t\tres.status(405).type(\"text/plain\").send(\"Method not allowed\");\n\t});\n\tapp.use((_req, res) => {\n\t\tres.status(404).type(\"text/plain\").send(\"Not found\");\n\t});\n\n\tconst close = () => {\n\t\tclosePromise ??= (async () => {\n\t\t\tawait Promise.allSettled([...activeRequests].map(({ mcpServer }) => mcpServer.close()));\n\t\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\t\tserver.close((err) => {\n\t\t\t\t\tif (!err || (err as NodeJS.ErrnoException).code === \"ERR_SERVER_NOT_RUNNING\") {\n\t\t\t\t\t\tresolve();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\treject(err);\n\t\t\t\t});\n\t\t\t\tserver.closeAllConnections();\n\t\t\t});\n\t\t\tstore.close();\n\t\t})();\n\t\treturn closePromise;\n\t};\n\n\treturn {\n\t\tserver,\n\t\tstore,\n\t\turl: `http://${formatHostForUrl(host)}:${getBoundPort(server)}/mcp`,\n\t\tclose,\n\t};\n}\n\nfunction isAllowedMcpHttpRequest(\n\treq: IncomingMessage,\n\texpectedPort: number,\n\tpublicMcpUrl: URL | undefined,\n): boolean {\n\tif (isAllowedLocalMcpHttpRequest(req, expectedPort)) return true;\n\tif (!publicMcpUrl) return false;\n\treturn (\n\t\tisAllowedPublicRequestHost(req.headers.host, publicMcpUrl) &&\n\t\tisAllowedPublicOrigin(req.headers.origin, publicMcpUrl)\n\t);\n}\n\nfunction isAllowedLocalMcpHttpRequest(req: IncomingMessage, expectedPort: number): boolean {\n\treturn (\n\t\tisAllowedMcpHttpRequestRemoteAddress(req.socket.remoteAddress) &&\n\t\tisAllowedMcpHttpRequestHost(req.headers.host, expectedPort) &&\n\t\tisAllowedMcpHttpRequestOrigin(req.headers.origin, expectedPort)\n\t);\n}\n\nfunction isAllowedOAuthHttpRequest(\n\treq: IncomingMessage,\n\texpectedPort: number,\n\tpublicMcpUrl: URL | undefined,\n): boolean {\n\tif (isAllowedLocalMcpHttpRequest(req, expectedPort)) return true;\n\tif (!publicMcpUrl) return false;\n\treturn (\n\t\tisAllowedPublicRequestHost(req.headers.host, publicMcpUrl) &&\n\t\tisAllowedPublicOrigin(req.headers.origin, publicMcpUrl)\n\t);\n}\n\nfunction isAllowedPublicOrigin(header: string | undefined, publicMcpUrl: URL): boolean {\n\tif (!header) return true;\n\ttry {\n\t\tconst origin = new URL(header);\n\t\treturn (\n\t\t\torigin.origin === publicMcpUrl.origin || TRUSTED_PUBLIC_BROWSER_ORIGINS.has(origin.origin)\n\t\t);\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction applyPublicCorsHeaders(\n\treq: IncomingMessage,\n\tres: Response,\n\tpublicMcpUrl: URL | undefined,\n): void {\n\tif (!publicMcpUrl) return;\n\tconst origin = getAllowedPublicCorsOrigin(req.headers.origin, publicMcpUrl);\n\tif (!origin) return;\n\tres.setHeader(\"Access-Control-Allow-Origin\", origin);\n\tres.setHeader(\"Access-Control-Allow-Methods\", \"GET,POST,OPTIONS\");\n\tres.setHeader(\n\t\t\"Access-Control-Allow-Headers\",\n\t\treq.headers[\"access-control-request-headers\"] ?? CORS_ALLOW_HEADERS,\n\t);\n\tres.setHeader(\"Access-Control-Max-Age\", CORS_MAX_AGE_SECONDS);\n\tres.setHeader(\"Vary\", \"Origin\");\n}\n\nfunction getAllowedPublicCorsOrigin(\n\theader: string | undefined,\n\tpublicMcpUrl: URL,\n): string | undefined {\n\tif (!header) return undefined;\n\ttry {\n\t\tconst origin = new URL(header).origin;\n\t\tif (origin === publicMcpUrl.origin || TRUSTED_PUBLIC_BROWSER_ORIGINS.has(origin)) {\n\t\t\treturn origin;\n\t\t}\n\t} catch {\n\t\treturn undefined;\n\t}\n\treturn undefined;\n}\n\nfunction emitHttpGuardDeny(\n\treq: IncomingMessage,\n\tpathname: string,\n\tpublicMcpUrl: URL | undefined,\n): void {\n\tconsole.warn(\n\t\tJSON.stringify({\n\t\t\tsource: \"codemem-mcp-http-guard\",\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\toutcome: \"denied\",\n\t\t\treason: \"host_or_origin_mismatch\",\n\t\t\tmethod: req.method,\n\t\t\tpath: pathname,\n\t\t\thost: truncateGuardLogField(req.headers.host),\n\t\t\torigin: truncateGuardLogField(req.headers.origin),\n\t\t\texpectedOrigin: publicMcpUrl?.origin,\n\t\t\tremoteAddress: req.socket.remoteAddress ?? undefined,\n\t\t}),\n\t);\n}\n\nfunction truncateGuardLogField(value: string | undefined): string | undefined {\n\tif (!value || value.length <= MAX_GUARD_LOG_FIELD_LENGTH) return value;\n\treturn `${value.slice(0, MAX_GUARD_LOG_FIELD_LENGTH)}…`;\n}\n\nfunction isAllowedPublicRequestHost(header: string | undefined, publicMcpUrl: URL): boolean {\n\tconst parsed = parseHostHeader(header);\n\tif (!parsed) return false;\n\tconst expectedPort = publicMcpUrl.port\n\t\t? Number(publicMcpUrl.port)\n\t\t: publicMcpUrl.protocol === \"https:\"\n\t\t\t? 443\n\t\t\t: 80;\n\tconst impliedPort = publicMcpUrl.protocol === \"https:\" ? 443 : 80;\n\tconst actualPort = parsed.port ?? impliedPort;\n\treturn (\n\t\tnormalizeHost(parsed.host) === normalizeHost(publicMcpUrl.hostname) &&\n\t\tactualPort === expectedPort\n\t);\n}\n\nfunction getBoundPort(server: Server): number {\n\tconst address = server.address();\n\tif (!address || typeof address === \"string\") return DEFAULT_MCP_HTTP_PORT;\n\treturn address.port;\n}\n\nfunction formatHostForUrl(host: string): string {\n\treturn isIP(host) === 6 ? `[${host}]` : host;\n}\n\nfunction getServerUrl(server: Server, host: string): string {\n\treturn `http://${formatHostForUrl(host)}:${getBoundPort(server)}/mcp`;\n}\n\nfunction createHttpRetrievalLedgerScopeResolver(): (input: {\n\tendpoint: URL;\n\tprincipal: string | undefined;\n\trequestBody: unknown;\n\tnow: number;\n}) => string {\n\tconst scopes = new Map<string, { scopeId: string; expiresAt: number }>();\n\n\treturn (input) => {\n\t\t// Anonymous HTTP has no stable, trustworthy caller identity. Give each POST\n\t\t// its own opaque scope rather than collapsing unrelated clients that reuse\n\t\t// the same JSON-RPC id and payload. One POST still shares this scope across\n\t\t// its server execution, preserving callback-level idempotency.\n\t\tif (!input.principal) return createOpaqueHttpRetrievalLedgerScopeId(randomUUID());\n\n\t\tfor (const [key, scope] of scopes) {\n\t\t\tif (scope.expiresAt <= input.now) scopes.delete(key);\n\t\t}\n\n\t\t// Stateless HTTP has no dispatch identity beyond the authenticated\n\t\t// principal and request bytes. Exact repeats inside this bounded window\n\t\t// are therefore treated as transport retries; an intentional repeat must\n\t\t// use a new JSON-RPC id or arrive after expiry. Keep only an opaque digest,\n\t\t// and do not slide the first-observation expiry on reads.\n\t\tconst contextDigest = createHash(\"sha256\")\n\t\t\t.update(\n\t\t\t\tJSON.stringify([input.endpoint.href, input.principal, canonicalJson(input.requestBody)]),\n\t\t\t)\n\t\t\t.digest(\"hex\");\n\t\tconst existing = scopes.get(contextDigest);\n\t\tif (existing) return existing.scopeId;\n\n\t\tconst scopeId = createOpaqueHttpRetrievalLedgerScopeId(\n\t\t\tJSON.stringify([contextDigest, input.now]),\n\t\t);\n\t\tscopes.set(contextDigest, {\n\t\t\tscopeId,\n\t\t\texpiresAt: input.now + MCP_HTTP_RETRIEVAL_RETRY_WINDOW_MS,\n\t\t});\n\t\twhile (scopes.size > MCP_HTTP_RETRIEVAL_RETRY_MAX_ENTRIES) {\n\t\t\tconst oldestKey = scopes.keys().next().value;\n\t\t\tif (oldestKey === undefined) break;\n\t\t\tscopes.delete(oldestKey);\n\t\t}\n\t\treturn scopeId;\n\t};\n}\n\nfunction createOpaqueHttpRetrievalLedgerScopeId(seed: string): string {\n\treturn `mcp-http:${createHash(\"sha256\").update(seed).digest(\"hex\")}`;\n}\n\nfunction handleMcpJsonBodyError(\n\terror: unknown,\n\t_req: Request,\n\tres: Response,\n\tnext: NextFunction,\n): void {\n\tconst status = mcpJsonBodyErrorStatus(error);\n\tif (status === null) {\n\t\tnext(error);\n\t\treturn;\n\t}\n\tres.status(status).json({\n\t\tjsonrpc: \"2.0\",\n\t\terror: {\n\t\t\tcode: status === 413 ? -32_000 : -32_700,\n\t\t\tmessage: status === 413 ? \"Request body too large\" : \"Parse error\",\n\t\t},\n\t\tid: null,\n\t});\n}\n\nfunction mcpJsonBodyErrorStatus(error: unknown): 400 | 413 | null {\n\tif (error === null || typeof error !== \"object\") return null;\n\tconst bodyError = error as { type?: unknown };\n\tif (bodyError.type === \"entity.too.large\") return 413;\n\tif (bodyError.type === \"entity.parse.failed\") return 400;\n\treturn null;\n}\n\nfunction getSdkIssuerUrl(publicMcpUrl: URL, port: number): URL {\n\tif (publicMcpUrl.protocol === \"https:\") return new URL(publicMcpUrl.origin);\n\tif (isLoopbackHost(publicMcpUrl.hostname) && normalizeHost(publicMcpUrl.hostname) !== \"::1\") {\n\t\treturn new URL(publicMcpUrl.origin);\n\t}\n\treturn new URL(`http://localhost:${port}/`);\n}\n\nfunction isOAuthOrMetadataPath(pathname: string): boolean {\n\treturn (\n\t\tpathname === \"/register\" ||\n\t\tpathname === \"/authorize\" ||\n\t\tpathname === \"/token\" ||\n\t\tpathname === \"/revoke\" ||\n\t\tpathname === \"/oauth/callback\" ||\n\t\tpathname === \"/.well-known/oauth-authorization-server\" ||\n\t\tpathname === \"/.well-known/oauth-protected-resource/mcp\"\n\t);\n}\n\nfunction normalizeRoutePath(pathname: string): string {\n\treturn pathname.length > 1 ? pathname.replace(/\\/+$/, \"\") : pathname;\n}\n\nfunction auditOAuthRouteResponses(\n\tauditEmit: (event: ReturnType<typeof buildOAuthAuditEvent>) => void,\n) {\n\treturn (req: Request, res: Response, next: NextFunction) => {\n\t\tconst pathname = req.path;\n\t\tif (!isAuditedOAuthPath(pathname)) return next();\n\t\tlet responseBody: unknown;\n\t\tconst originalJson = res.json.bind(res);\n\t\tres.json = ((body: unknown) => {\n\t\t\tresponseBody = body;\n\t\t\treturn originalJson(body);\n\t\t}) as typeof res.json;\n\t\tres.on(\"finish\", () => {\n\t\t\tif (pathname === \"/oauth/callback\") return;\n\t\t\tconst kind = oauthAuditKindForRequest(pathname, req);\n\t\t\tif (!kind) return;\n\t\t\tconst error = getOAuthResponseError(res, responseBody);\n\t\t\tconst clientId = getRequestClientId(req, responseBody);\n\t\t\tauditEmit(\n\t\t\t\tbuildOAuthAuditEvent(kind, {\n\t\t\t\t\toutcome: error ? \"denied\" : \"success\",\n\t\t\t\t\t...(error ? { reason: error } : {}),\n\t\t\t\t\t...(clientId ? { clientId } : {}),\n\t\t\t\t\tremoteAddress: req.socket.remoteAddress ?? undefined,\n\t\t\t\t}),\n\t\t\t);\n\t\t});\n\t\tnext();\n\t};\n}\n\nfunction isAuditedOAuthPath(pathname: string): boolean {\n\treturn oauthAuditKindForPath(pathname) !== null;\n}\n\nfunction oauthAuditKindForRequest(\n\tpathname: string,\n\treq: Request,\n): \"registration\" | \"authorize\" | \"token\" | \"refresh\" | \"revocation\" | null {\n\tif (pathname === \"/token\" && req.body?.grant_type === \"refresh_token\") return \"refresh\";\n\treturn oauthAuditKindForPath(pathname);\n}\n\nfunction oauthAuditKindForPath(\n\tpathname: string,\n): \"registration\" | \"authorize\" | \"token\" | \"revocation\" | null {\n\tif (pathname === \"/register\") return \"registration\";\n\tif (pathname === \"/authorize\") return \"authorize\";\n\tif (pathname === \"/token\") return \"token\";\n\tif (pathname === \"/revoke\") return \"revocation\";\n\treturn null;\n}\n\nfunction getOAuthResponseError(res: Response, body: unknown): string | undefined {\n\tconst bodyError = getOAuthBodyError(body);\n\tif (bodyError) return bodyError;\n\tconst location = res.getHeader(\"location\");\n\tif (typeof location !== \"string\") return undefined;\n\ttry {\n\t\tconst redirect = new URL(location);\n\t\treturn redirect.searchParams.get(\"error\") ?? undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction getOAuthBodyError(body: unknown): string | undefined {\n\tif (\n\t\ttypeof body === \"object\" &&\n\t\tbody !== null &&\n\t\t\"error\" in body &&\n\t\ttypeof body.error === \"string\"\n\t) {\n\t\treturn body.error;\n\t}\n\treturn undefined;\n}\n\nfunction getRequestClientId(req: Request, body: unknown): string | undefined {\n\tif (\n\t\ttypeof body === \"object\" &&\n\t\tbody !== null &&\n\t\t\"client_id\" in body &&\n\t\ttypeof body.client_id === \"string\"\n\t) {\n\t\treturn body.client_id;\n\t}\n\tconst bodyClientId = typeof req.body?.client_id === \"string\" ? req.body.client_id : undefined;\n\tif (bodyClientId) return bodyClientId;\n\tconst queryClientId = typeof req.query.client_id === \"string\" ? req.query.client_id : undefined;\n\treturn queryClientId;\n}\n\nfunction auditBearerPreflight(\n\tauditEmit: (event: ReturnType<typeof buildOAuthAuditEvent>) => void,\n\ttokenStore: OAuthAccessTokenStore,\n) {\n\treturn (req: Request, _res: Response, next: NextFunction) => {\n\t\tconst reason = getBearerPreflightDenyReason(req.headers.authorization, tokenStore);\n\t\tif (reason) {\n\t\t\tauditEmit(\n\t\t\t\tbuildOAuthAuditEvent(\"bearer\", {\n\t\t\t\t\toutcome: \"denied\",\n\t\t\t\t\treason,\n\t\t\t\t\tremoteAddress: req.socket.remoteAddress ?? undefined,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t\tnext();\n\t};\n}\n\nfunction getBearerPreflightDenyReason(\n\theader: string | undefined,\n\ttokenStore: OAuthAccessTokenStore,\n): BearerDenyReason | null {\n\tif (!header) return \"missing_authorization_header\";\n\tconst [scheme, token, extra] = header.trim().split(/\\s+/);\n\tif (!scheme || !token || extra || scheme.toLowerCase() !== \"bearer\") {\n\t\treturn \"malformed_authorization_header\";\n\t}\n\tconst verification = tokenStore.verifyToken(token);\n\tif (!verification.ok) return verification.reason;\n\treturn null;\n}\n\nfunction parseScopeList(scope: string | null | undefined): string[] {\n\treturn (\n\t\tscope\n\t\t\t?.split(/\\s+/)\n\t\t\t.map((item) => item.trim())\n\t\t\t.filter(Boolean) ?? []\n\t);\n}\n\nfunction isEntrypoint(): boolean {\n\tconst script = process.argv[1];\n\treturn script ? import.meta.url === pathToFileURL(script).href : false;\n}\n\nasync function main() {\n\tconst httpServer = await startCodememMcpHttpServer();\n\tconsole.error(`codemem MCP HTTP server listening at ${httpServer.url}`);\n\n\tconst shutdown = async () => {\n\t\ttry {\n\t\t\tawait httpServer.close();\n\t\t} catch {\n\t\t\t// Best effort — process is exiting.\n\t\t}\n\t\tprocess.exit(0);\n\t};\n\n\tprocess.on(\"SIGINT\", shutdown);\n\tprocess.on(\"SIGTERM\", shutdown);\n}\n\nif (isEntrypoint()) {\n\tmain().catch((err) => {\n\t\tconsole.error(\"codemem MCP HTTP server failed to start:\", err);\n\t\tprocess.exit(1);\n\t});\n}\n"],"x_google_ignoreList":[0,1,2,3,4,5,6,7,8,9,10,11,12],"mappings":"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"}
|