diff --git a/.github/workflows/autofix.yml b/.github/workflows/autofix.yml index a6844df60..17a2275c5 100644 --- a/.github/workflows/autofix.yml +++ b/.github/workflows/autofix.yml @@ -30,6 +30,10 @@ jobs: - name: Install dependencies run: npm ci + - name: Update RDAP DNS data from IANA + run: wget -O server/model/rdap-dns.json https://data.iana.org/rdap/dns.json + continue-on-error: true + - name: Auto-fix JavaScript/Vue linting issues run: npm run lint-fix:js continue-on-error: true diff --git a/db/knex_migrations/2025-12-31-2143-add-snmp-v3-username.js b/db/knex_migrations/2025-12-31-2143-add-snmp-v3-username.js new file mode 100644 index 000000000..9304ebea2 --- /dev/null +++ b/db/knex_migrations/2025-12-31-2143-add-snmp-v3-username.js @@ -0,0 +1,11 @@ +exports.up = async function (knex) { + await knex.schema.alterTable("monitor", (table) => { + table.string("snmp_v3_username", 255); + }); +}; + +exports.down = async function (knex) { + await knex.schema.alterTable("monitor", (table) => { + table.dropColumn("snmp_v3_username"); + }); +}; diff --git a/package-lock.json b/package-lock.json index db0a67846..352bb3c96 100644 --- a/package-lock.json +++ b/package-lock.json @@ -60,7 +60,6 @@ "nanoid": "~3.3.4", "net-snmp": "^3.11.2", "node-cloudflared-tunnel": "~1.0.9", - "node-fetch-cache": "^5.1.0", "node-radius-utils": "~1.2.0", "nodemailer": "~7.0.12", "nostr-tools": "^2.17.0", @@ -145,7 +144,7 @@ "stylelint-config-standard": "~25.0.0", "terser": "~5.15.0", "test": "~3.3.0", - "testcontainers": "^10.13.1", + "testcontainers": "^11.5.0", "typescript": "~4.4.4", "v-pagination-3": "~0.1.7", "vite": "~5.4.15", @@ -361,571 +360,571 @@ } }, "node_modules/@aws-sdk/client-cognito-identity": { - "version": "3.967.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.967.0.tgz", - "integrity": "sha512-nVC/GpKTkBm9+lCZl40DbzBuqJIi5tJosZHSjnc7GavRJOZvFIX8XE5db81+zi+FqVTDrhPPaKpdAeoE9qYHAw==", + "version": "3.971.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.971.0.tgz", + "integrity": "sha512-JK1H3EXpm+z2qrfaM56ohx6wfibuF9+Kis4nGxQgitZjKhtZRysIkV7EBoeRGXXutESAumSV+DYSuFHU9n4Pzw==", "license": "Apache-2.0", "optional": true, "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.967.0", - "@aws-sdk/credential-provider-node": "3.967.0", - "@aws-sdk/middleware-host-header": "3.965.0", - "@aws-sdk/middleware-logger": "3.965.0", - "@aws-sdk/middleware-recursion-detection": "3.965.0", - "@aws-sdk/middleware-user-agent": "3.967.0", - "@aws-sdk/region-config-resolver": "3.965.0", - "@aws-sdk/types": "3.965.0", - "@aws-sdk/util-endpoints": "3.965.0", - "@aws-sdk/util-user-agent-browser": "3.965.0", - "@aws-sdk/util-user-agent-node": "3.967.0", - "@smithy/config-resolver": "^4.4.5", - "@smithy/core": "^3.20.2", - "@smithy/fetch-http-handler": "^5.3.8", - "@smithy/hash-node": "^4.2.7", - "@smithy/invalid-dependency": "^4.2.7", - "@smithy/middleware-content-length": "^4.2.7", - "@smithy/middleware-endpoint": "^4.4.3", - "@smithy/middleware-retry": "^4.4.19", - "@smithy/middleware-serde": "^4.2.8", - "@smithy/middleware-stack": "^4.2.7", - "@smithy/node-config-provider": "^4.3.7", - "@smithy/node-http-handler": "^4.4.7", - "@smithy/protocol-http": "^5.3.7", - "@smithy/smithy-client": "^4.10.4", - "@smithy/types": "^4.11.0", - "@smithy/url-parser": "^4.2.7", + "@aws-sdk/core": "3.970.0", + "@aws-sdk/credential-provider-node": "3.971.0", + "@aws-sdk/middleware-host-header": "3.969.0", + "@aws-sdk/middleware-logger": "3.969.0", + "@aws-sdk/middleware-recursion-detection": "3.969.0", + "@aws-sdk/middleware-user-agent": "3.970.0", + "@aws-sdk/region-config-resolver": "3.969.0", + "@aws-sdk/types": "3.969.0", + "@aws-sdk/util-endpoints": "3.970.0", + "@aws-sdk/util-user-agent-browser": "3.969.0", + "@aws-sdk/util-user-agent-node": "3.971.0", + "@smithy/config-resolver": "^4.4.6", + "@smithy/core": "^3.20.6", + "@smithy/fetch-http-handler": "^5.3.9", + "@smithy/hash-node": "^4.2.8", + "@smithy/invalid-dependency": "^4.2.8", + "@smithy/middleware-content-length": "^4.2.8", + "@smithy/middleware-endpoint": "^4.4.7", + "@smithy/middleware-retry": "^4.4.23", + "@smithy/middleware-serde": "^4.2.9", + "@smithy/middleware-stack": "^4.2.8", + "@smithy/node-config-provider": "^4.3.8", + "@smithy/node-http-handler": "^4.4.8", + "@smithy/protocol-http": "^5.3.8", + "@smithy/smithy-client": "^4.10.8", + "@smithy/types": "^4.12.0", + "@smithy/url-parser": "^4.2.8", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", - "@smithy/util-defaults-mode-browser": "^4.3.18", - "@smithy/util-defaults-mode-node": "^4.2.21", - "@smithy/util-endpoints": "^3.2.7", - "@smithy/util-middleware": "^4.2.7", - "@smithy/util-retry": "^4.2.7", + "@smithy/util-defaults-mode-browser": "^4.3.22", + "@smithy/util-defaults-mode-node": "^4.2.25", + "@smithy/util-endpoints": "^3.2.8", + "@smithy/util-middleware": "^4.2.8", + "@smithy/util-retry": "^4.2.8", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@aws-sdk/client-sso": { - "version": "3.967.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.967.0.tgz", - "integrity": "sha512-7RgUwHcRMJtWme6kCHGUVT+Rn9GmNH+FHm34N9UgMXzUqQlzFMweE7T5E9O8nv3wIp7xFNB20ADaCw9Xdnox1Q==", + "version": "3.971.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.971.0.tgz", + "integrity": "sha512-Xx+w6DQqJxDdymYyIxyKJnRzPvVJ4e/Aw0czO7aC9L/iraaV7AG8QtRe93OGW6aoHSh72CIiinnpJJfLsQqP4g==", "license": "Apache-2.0", "optional": true, "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.967.0", - "@aws-sdk/middleware-host-header": "3.965.0", - "@aws-sdk/middleware-logger": "3.965.0", - "@aws-sdk/middleware-recursion-detection": "3.965.0", - "@aws-sdk/middleware-user-agent": "3.967.0", - "@aws-sdk/region-config-resolver": "3.965.0", - "@aws-sdk/types": "3.965.0", - "@aws-sdk/util-endpoints": "3.965.0", - "@aws-sdk/util-user-agent-browser": "3.965.0", - "@aws-sdk/util-user-agent-node": "3.967.0", - "@smithy/config-resolver": "^4.4.5", - "@smithy/core": "^3.20.2", - "@smithy/fetch-http-handler": "^5.3.8", - "@smithy/hash-node": "^4.2.7", - "@smithy/invalid-dependency": "^4.2.7", - "@smithy/middleware-content-length": "^4.2.7", - "@smithy/middleware-endpoint": "^4.4.3", - "@smithy/middleware-retry": "^4.4.19", - "@smithy/middleware-serde": "^4.2.8", - "@smithy/middleware-stack": "^4.2.7", - "@smithy/node-config-provider": "^4.3.7", - "@smithy/node-http-handler": "^4.4.7", - "@smithy/protocol-http": "^5.3.7", - "@smithy/smithy-client": "^4.10.4", - "@smithy/types": "^4.11.0", - "@smithy/url-parser": "^4.2.7", + "@aws-sdk/core": "3.970.0", + "@aws-sdk/middleware-host-header": "3.969.0", + "@aws-sdk/middleware-logger": "3.969.0", + "@aws-sdk/middleware-recursion-detection": "3.969.0", + "@aws-sdk/middleware-user-agent": "3.970.0", + "@aws-sdk/region-config-resolver": "3.969.0", + "@aws-sdk/types": "3.969.0", + "@aws-sdk/util-endpoints": "3.970.0", + "@aws-sdk/util-user-agent-browser": "3.969.0", + "@aws-sdk/util-user-agent-node": "3.971.0", + "@smithy/config-resolver": "^4.4.6", + "@smithy/core": "^3.20.6", + "@smithy/fetch-http-handler": "^5.3.9", + "@smithy/hash-node": "^4.2.8", + "@smithy/invalid-dependency": "^4.2.8", + "@smithy/middleware-content-length": "^4.2.8", + "@smithy/middleware-endpoint": "^4.4.7", + "@smithy/middleware-retry": "^4.4.23", + "@smithy/middleware-serde": "^4.2.9", + "@smithy/middleware-stack": "^4.2.8", + "@smithy/node-config-provider": "^4.3.8", + "@smithy/node-http-handler": "^4.4.8", + "@smithy/protocol-http": "^5.3.8", + "@smithy/smithy-client": "^4.10.8", + "@smithy/types": "^4.12.0", + "@smithy/url-parser": "^4.2.8", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", - "@smithy/util-defaults-mode-browser": "^4.3.18", - "@smithy/util-defaults-mode-node": "^4.2.21", - "@smithy/util-endpoints": "^3.2.7", - "@smithy/util-middleware": "^4.2.7", - "@smithy/util-retry": "^4.2.7", + "@smithy/util-defaults-mode-browser": "^4.3.22", + "@smithy/util-defaults-mode-node": "^4.2.25", + "@smithy/util-endpoints": "^3.2.8", + "@smithy/util-middleware": "^4.2.8", + "@smithy/util-retry": "^4.2.8", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@aws-sdk/core": { - "version": "3.967.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.967.0.tgz", - "integrity": "sha512-sJmuP7GrVmlbO6DpXkuf9Mbn6jGNNvy6PLawvaxVF150c8bpNk3w39rerRls6q1dot1dBFV2D29hBXMY1agNMg==", + "version": "3.970.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.970.0.tgz", + "integrity": "sha512-klpzObldOq8HXzDjDlY6K8rMhYZU6mXRz6P9F9N+tWnjoYFfeBMra8wYApydElTUYQKP1O7RLHwH1OKFfKcqIA==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@aws-sdk/types": "3.965.0", - "@aws-sdk/xml-builder": "3.965.0", - "@smithy/core": "^3.20.2", - "@smithy/node-config-provider": "^4.3.7", - "@smithy/property-provider": "^4.2.7", - "@smithy/protocol-http": "^5.3.7", - "@smithy/signature-v4": "^5.3.7", - "@smithy/smithy-client": "^4.10.4", - "@smithy/types": "^4.11.0", + "@aws-sdk/types": "3.969.0", + "@aws-sdk/xml-builder": "3.969.0", + "@smithy/core": "^3.20.6", + "@smithy/node-config-provider": "^4.3.8", + "@smithy/property-provider": "^4.2.8", + "@smithy/protocol-http": "^5.3.8", + "@smithy/signature-v4": "^5.3.8", + "@smithy/smithy-client": "^4.10.8", + "@smithy/types": "^4.12.0", "@smithy/util-base64": "^4.3.0", - "@smithy/util-middleware": "^4.2.7", + "@smithy/util-middleware": "^4.2.8", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@aws-sdk/credential-provider-cognito-identity": { - "version": "3.967.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.967.0.tgz", - "integrity": "sha512-kps8eC/ARt1f40ZJO4yCiFvhESLZ7zI2i1HMyNvA2f2mBmYszaqyAZoFwr7pBbqTuLmL4NWNcakONBOhho+6RA==", + "version": "3.971.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.971.0.tgz", + "integrity": "sha512-NsFmrFoBPqLUYCmLoRpi1MUB5Jw4txk9+eV8xn4NArGB89WiZXqrupvHOPra0uLEDVwuwvg7eWOvdex03aV3nA==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@aws-sdk/client-cognito-identity": "3.967.0", - "@aws-sdk/types": "3.965.0", - "@smithy/property-provider": "^4.2.7", - "@smithy/types": "^4.11.0", + "@aws-sdk/client-cognito-identity": "3.971.0", + "@aws-sdk/types": "3.969.0", + "@smithy/property-provider": "^4.2.8", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@aws-sdk/credential-provider-env": { - "version": "3.967.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.967.0.tgz", - "integrity": "sha512-+XWw0+f/txeMbEVRtTFZhgSw1ymH1ffaVKkdMBSnw48rfSohJElKmitCqdihagRTZpzh7m8qI6tIQ5t3OUqugw==", + "version": "3.970.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.970.0.tgz", + "integrity": "sha512-rtVzXzEtAfZBfh+lq3DAvRar4c3jyptweOAJR2DweyXx71QSMY+O879hjpMwES7jl07a3O1zlnFIDo4KP/96kQ==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@aws-sdk/core": "3.967.0", - "@aws-sdk/types": "3.965.0", - "@smithy/property-provider": "^4.2.7", - "@smithy/types": "^4.11.0", + "@aws-sdk/core": "3.970.0", + "@aws-sdk/types": "3.969.0", + "@smithy/property-provider": "^4.2.8", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@aws-sdk/credential-provider-http": { - "version": "3.967.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.967.0.tgz", - "integrity": "sha512-0/GIAEv5pY5htg6IBMuYccBgzz3oS2DqHjHi396ziTrwlhbrCNX96AbNhQhzAx3LBZUk13sPfeapjyQ7G57Ekg==", + "version": "3.970.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.970.0.tgz", + "integrity": "sha512-CjDbWL7JxjLc9ZxQilMusWSw05yRvUJKRpz59IxDpWUnSMHC9JMMUUkOy5Izk8UAtzi6gupRWArp4NG4labt9Q==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@aws-sdk/core": "3.967.0", - "@aws-sdk/types": "3.965.0", - "@smithy/fetch-http-handler": "^5.3.8", - "@smithy/node-http-handler": "^4.4.7", - "@smithy/property-provider": "^4.2.7", - "@smithy/protocol-http": "^5.3.7", - "@smithy/smithy-client": "^4.10.4", - "@smithy/types": "^4.11.0", - "@smithy/util-stream": "^4.5.8", + "@aws-sdk/core": "3.970.0", + "@aws-sdk/types": "3.969.0", + "@smithy/fetch-http-handler": "^5.3.9", + "@smithy/node-http-handler": "^4.4.8", + "@smithy/property-provider": "^4.2.8", + "@smithy/protocol-http": "^5.3.8", + "@smithy/smithy-client": "^4.10.8", + "@smithy/types": "^4.12.0", + "@smithy/util-stream": "^4.5.10", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.967.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.967.0.tgz", - "integrity": "sha512-U8dMpaM6Qf6+2Qvp1uG6OcWv1RlrZW7tQkpmzEVWH8HZTGrVHIXXju64NMtIOr7yOnNwd0CKcytuD1QG+phCwQ==", + "version": "3.971.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.971.0.tgz", + "integrity": "sha512-c0TGJG4xyfTZz3SInXfGU8i5iOFRrLmy4Bo7lMyH+IpngohYMYGYl61omXqf2zdwMbDv+YJ9AviQTcCaEUKi8w==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@aws-sdk/core": "3.967.0", - "@aws-sdk/credential-provider-env": "3.967.0", - "@aws-sdk/credential-provider-http": "3.967.0", - "@aws-sdk/credential-provider-login": "3.967.0", - "@aws-sdk/credential-provider-process": "3.967.0", - "@aws-sdk/credential-provider-sso": "3.967.0", - "@aws-sdk/credential-provider-web-identity": "3.967.0", - "@aws-sdk/nested-clients": "3.967.0", - "@aws-sdk/types": "3.965.0", - "@smithy/credential-provider-imds": "^4.2.7", - "@smithy/property-provider": "^4.2.7", - "@smithy/shared-ini-file-loader": "^4.4.2", - "@smithy/types": "^4.11.0", + "@aws-sdk/core": "3.970.0", + "@aws-sdk/credential-provider-env": "3.970.0", + "@aws-sdk/credential-provider-http": "3.970.0", + "@aws-sdk/credential-provider-login": "3.971.0", + "@aws-sdk/credential-provider-process": "3.970.0", + "@aws-sdk/credential-provider-sso": "3.971.0", + "@aws-sdk/credential-provider-web-identity": "3.971.0", + "@aws-sdk/nested-clients": "3.971.0", + "@aws-sdk/types": "3.969.0", + "@smithy/credential-provider-imds": "^4.2.8", + "@smithy/property-provider": "^4.2.8", + "@smithy/shared-ini-file-loader": "^4.4.3", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@aws-sdk/credential-provider-login": { - "version": "3.967.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.967.0.tgz", - "integrity": "sha512-kbvZsZL6CBlfnb71zuJdJmBUFZN5utNrcziZr/DZ2olEOkA9vlmizE8i9BUIbmS7ptjgvRnmcY1A966yfhiblw==", + "version": "3.971.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.971.0.tgz", + "integrity": "sha512-yhbzmDOsk0RXD3rTPhZra4AWVnVAC4nFWbTp+sUty1hrOPurUmhuz8bjpLqYTHGnlMbJp+UqkQONhS2+2LzW2g==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@aws-sdk/core": "3.967.0", - "@aws-sdk/nested-clients": "3.967.0", - "@aws-sdk/types": "3.965.0", - "@smithy/property-provider": "^4.2.7", - "@smithy/protocol-http": "^5.3.7", - "@smithy/shared-ini-file-loader": "^4.4.2", - "@smithy/types": "^4.11.0", + "@aws-sdk/core": "3.970.0", + "@aws-sdk/nested-clients": "3.971.0", + "@aws-sdk/types": "3.969.0", + "@smithy/property-provider": "^4.2.8", + "@smithy/protocol-http": "^5.3.8", + "@smithy/shared-ini-file-loader": "^4.4.3", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.967.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.967.0.tgz", - "integrity": "sha512-WuNbHs9rfKKSVok4+OBrZf0AHfzDgFYYMxN2G/q6ZfUmY4QmiPyxV5HkNFh1rqDxS9VV6kAZPo0EBmry10idSg==", + "version": "3.971.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.971.0.tgz", + "integrity": "sha512-epUJBAKivtJqalnEBRsYIULKYV063o/5mXNJshZfyvkAgNIzc27CmmKRXTN4zaNOZg8g/UprFp25BGsi19x3nQ==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@aws-sdk/credential-provider-env": "3.967.0", - "@aws-sdk/credential-provider-http": "3.967.0", - "@aws-sdk/credential-provider-ini": "3.967.0", - "@aws-sdk/credential-provider-process": "3.967.0", - "@aws-sdk/credential-provider-sso": "3.967.0", - "@aws-sdk/credential-provider-web-identity": "3.967.0", - "@aws-sdk/types": "3.965.0", - "@smithy/credential-provider-imds": "^4.2.7", - "@smithy/property-provider": "^4.2.7", - "@smithy/shared-ini-file-loader": "^4.4.2", - "@smithy/types": "^4.11.0", + "@aws-sdk/credential-provider-env": "3.970.0", + "@aws-sdk/credential-provider-http": "3.970.0", + "@aws-sdk/credential-provider-ini": "3.971.0", + "@aws-sdk/credential-provider-process": "3.970.0", + "@aws-sdk/credential-provider-sso": "3.971.0", + "@aws-sdk/credential-provider-web-identity": "3.971.0", + "@aws-sdk/types": "3.969.0", + "@smithy/credential-provider-imds": "^4.2.8", + "@smithy/property-provider": "^4.2.8", + "@smithy/shared-ini-file-loader": "^4.4.3", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@aws-sdk/credential-provider-process": { - "version": "3.967.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.967.0.tgz", - "integrity": "sha512-sNCY5JDV0whsfsZ6c2+6eUwH33H7UhKbqvCPbEYlIIa8wkGjCtCyFI3zZIJHVcMKJJ3117vSUFHEkNA7g+8rtw==", + "version": "3.970.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.970.0.tgz", + "integrity": "sha512-0XeT8OaT9iMA62DFV9+m6mZfJhrD0WNKf4IvsIpj2Z7XbaYfz3CoDDvNoALf3rPY9NzyMHgDxOspmqdvXP00mw==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@aws-sdk/core": "3.967.0", - "@aws-sdk/types": "3.965.0", - "@smithy/property-provider": "^4.2.7", - "@smithy/shared-ini-file-loader": "^4.4.2", - "@smithy/types": "^4.11.0", + "@aws-sdk/core": "3.970.0", + "@aws-sdk/types": "3.969.0", + "@smithy/property-provider": "^4.2.8", + "@smithy/shared-ini-file-loader": "^4.4.3", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.967.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.967.0.tgz", - "integrity": "sha512-0K6kITKNytFjk1UYabYUsTThgU6TQkyW6Wmt8S5zd1A/up7NSQGpp58Rpg9GIf4amQDQwb+p9FGG7emmV8FEeA==", + "version": "3.971.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.971.0.tgz", + "integrity": "sha512-dY0hMQ7dLVPQNJ8GyqXADxa9w5wNfmukgQniLxGVn+dMRx3YLViMp5ZpTSQpFhCWNF0oKQrYAI5cHhUJU1hETw==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@aws-sdk/client-sso": "3.967.0", - "@aws-sdk/core": "3.967.0", - "@aws-sdk/token-providers": "3.967.0", - "@aws-sdk/types": "3.965.0", - "@smithy/property-provider": "^4.2.7", - "@smithy/shared-ini-file-loader": "^4.4.2", - "@smithy/types": "^4.11.0", + "@aws-sdk/client-sso": "3.971.0", + "@aws-sdk/core": "3.970.0", + "@aws-sdk/token-providers": "3.971.0", + "@aws-sdk/types": "3.969.0", + "@smithy/property-provider": "^4.2.8", + "@smithy/shared-ini-file-loader": "^4.4.3", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.967.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.967.0.tgz", - "integrity": "sha512-Vkr7S2ec7q/v8i/MzkHcBEdqqfWz3lyb8FDjb+NjslEwdxC3f6XwADRZzWwV1pChfx6SbsvJXKfkcF/pKAelhA==", + "version": "3.971.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.971.0.tgz", + "integrity": "sha512-F1AwfNLr7H52T640LNON/h34YDiMuIqW/ZreGzhRR6vnFGaSPtNSKAKB2ssAMkLM8EVg8MjEAYD3NCUiEo+t/w==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@aws-sdk/core": "3.967.0", - "@aws-sdk/nested-clients": "3.967.0", - "@aws-sdk/types": "3.965.0", - "@smithy/property-provider": "^4.2.7", - "@smithy/shared-ini-file-loader": "^4.4.2", - "@smithy/types": "^4.11.0", + "@aws-sdk/core": "3.970.0", + "@aws-sdk/nested-clients": "3.971.0", + "@aws-sdk/types": "3.969.0", + "@smithy/property-provider": "^4.2.8", + "@smithy/shared-ini-file-loader": "^4.4.3", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@aws-sdk/credential-providers": { - "version": "3.967.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.967.0.tgz", - "integrity": "sha512-AvpnwjzRw+R1XU5cqb5sIgK6zqounXCa41wXTK158oQQSDIxfEvghOZ43Mk8K9lpdpfJ9fWMW7kESqzUGzgn3A==", + "version": "3.971.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.971.0.tgz", + "integrity": "sha512-778AT0QSdwUOqsVCrNNRHUiA/yNTvjGMIC1rUGcZGqJQmt7jTQq5W+1nHxcCy9zQkk9N9eUNx7tSCbvbyYoyVA==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@aws-sdk/client-cognito-identity": "3.967.0", - "@aws-sdk/core": "3.967.0", - "@aws-sdk/credential-provider-cognito-identity": "3.967.0", - "@aws-sdk/credential-provider-env": "3.967.0", - "@aws-sdk/credential-provider-http": "3.967.0", - "@aws-sdk/credential-provider-ini": "3.967.0", - "@aws-sdk/credential-provider-login": "3.967.0", - "@aws-sdk/credential-provider-node": "3.967.0", - "@aws-sdk/credential-provider-process": "3.967.0", - "@aws-sdk/credential-provider-sso": "3.967.0", - "@aws-sdk/credential-provider-web-identity": "3.967.0", - "@aws-sdk/nested-clients": "3.967.0", - "@aws-sdk/types": "3.965.0", - "@smithy/config-resolver": "^4.4.5", - "@smithy/core": "^3.20.2", - "@smithy/credential-provider-imds": "^4.2.7", - "@smithy/node-config-provider": "^4.3.7", - "@smithy/property-provider": "^4.2.7", - "@smithy/types": "^4.11.0", + "@aws-sdk/client-cognito-identity": "3.971.0", + "@aws-sdk/core": "3.970.0", + "@aws-sdk/credential-provider-cognito-identity": "3.971.0", + "@aws-sdk/credential-provider-env": "3.970.0", + "@aws-sdk/credential-provider-http": "3.970.0", + "@aws-sdk/credential-provider-ini": "3.971.0", + "@aws-sdk/credential-provider-login": "3.971.0", + "@aws-sdk/credential-provider-node": "3.971.0", + "@aws-sdk/credential-provider-process": "3.970.0", + "@aws-sdk/credential-provider-sso": "3.971.0", + "@aws-sdk/credential-provider-web-identity": "3.971.0", + "@aws-sdk/nested-clients": "3.971.0", + "@aws-sdk/types": "3.969.0", + "@smithy/config-resolver": "^4.4.6", + "@smithy/core": "^3.20.6", + "@smithy/credential-provider-imds": "^4.2.8", + "@smithy/node-config-provider": "^4.3.8", + "@smithy/property-provider": "^4.2.8", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@aws-sdk/middleware-host-header": { - "version": "3.965.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.965.0.tgz", - "integrity": "sha512-SfpSYqoPOAmdb3DBsnNsZ0vix+1VAtkUkzXM79JL3R5IfacpyKE2zytOgVAQx/FjhhlpSTwuXd+LRhUEVb3MaA==", + "version": "3.969.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.969.0.tgz", + "integrity": "sha512-AWa4rVsAfBR4xqm7pybQ8sUNJYnjyP/bJjfAw34qPuh3M9XrfGbAHG0aiAfQGrBnmS28jlO6Kz69o+c6PRw1dw==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@aws-sdk/types": "3.965.0", - "@smithy/protocol-http": "^5.3.7", - "@smithy/types": "^4.11.0", + "@aws-sdk/types": "3.969.0", + "@smithy/protocol-http": "^5.3.8", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@aws-sdk/middleware-logger": { - "version": "3.965.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.965.0.tgz", - "integrity": "sha512-gjUvJRZT1bUABKewnvkj51LAynFrfz2h5DYAg5/2F4Utx6UOGByTSr9Rq8JCLbURvvzAbCtcMkkIJRxw+8Zuzw==", + "version": "3.969.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.969.0.tgz", + "integrity": "sha512-xwrxfip7Y2iTtCMJ+iifN1E1XMOuhxIHY9DreMCvgdl4r7+48x2S1bCYPWH3eNY85/7CapBWdJ8cerpEl12sQQ==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@aws-sdk/types": "3.965.0", - "@smithy/types": "^4.11.0", + "@aws-sdk/types": "3.969.0", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@aws-sdk/middleware-recursion-detection": { - "version": "3.965.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.965.0.tgz", - "integrity": "sha512-6dvD+18Ni14KCRu+tfEoNxq1sIGVp9tvoZDZ7aMvpnA7mDXuRLrOjRQ/TAZqXwr9ENKVGyxcPl0cRK8jk1YWjA==", + "version": "3.969.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.969.0.tgz", + "integrity": "sha512-2r3PuNquU3CcS1Am4vn/KHFwLi8QFjMdA/R+CRDXT4AFO/0qxevF/YStW3gAKntQIgWgQV8ZdEtKAoJvLI4UWg==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@aws-sdk/types": "3.965.0", + "@aws-sdk/types": "3.969.0", "@aws/lambda-invoke-store": "^0.2.2", - "@smithy/protocol-http": "^5.3.7", - "@smithy/types": "^4.11.0", + "@smithy/protocol-http": "^5.3.8", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.967.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.967.0.tgz", - "integrity": "sha512-2qzJzZj5u+cZiG7kz3XJPaTH4ssUY/aet1kwJsUTFKrWeHUf7mZZkDFfkXP5cOffgiOyR5ZkrmJoLKAde9hshg==", + "version": "3.970.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.970.0.tgz", + "integrity": "sha512-dnSJGGUGSFGEX2NzvjwSefH+hmZQ347AwbLhAsi0cdnISSge+pcGfOFrJt2XfBIypwFe27chQhlfuf/gWdzpZg==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@aws-sdk/core": "3.967.0", - "@aws-sdk/types": "3.965.0", - "@aws-sdk/util-endpoints": "3.965.0", - "@smithy/core": "^3.20.2", - "@smithy/protocol-http": "^5.3.7", - "@smithy/types": "^4.11.0", + "@aws-sdk/core": "3.970.0", + "@aws-sdk/types": "3.969.0", + "@aws-sdk/util-endpoints": "3.970.0", + "@smithy/core": "^3.20.6", + "@smithy/protocol-http": "^5.3.8", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@aws-sdk/nested-clients": { - "version": "3.967.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.967.0.tgz", - "integrity": "sha512-PYa7V8w0gaNux6Sz/Z7zrHmPloEE+EKpRxQIOG/D0askTr5Yd4oO2KGgcInf65uHK3f0Z9U4CTUGHZvQvABypA==", + "version": "3.971.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.971.0.tgz", + "integrity": "sha512-TWaILL8GyYlhGrxxnmbkazM4QsXatwQgoWUvo251FXmUOsiXDFDVX3hoGIfB3CaJhV2pJPfebHUNJtY6TjZ11g==", "license": "Apache-2.0", "optional": true, "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.967.0", - "@aws-sdk/middleware-host-header": "3.965.0", - "@aws-sdk/middleware-logger": "3.965.0", - "@aws-sdk/middleware-recursion-detection": "3.965.0", - "@aws-sdk/middleware-user-agent": "3.967.0", - "@aws-sdk/region-config-resolver": "3.965.0", - "@aws-sdk/types": "3.965.0", - "@aws-sdk/util-endpoints": "3.965.0", - "@aws-sdk/util-user-agent-browser": "3.965.0", - "@aws-sdk/util-user-agent-node": "3.967.0", - "@smithy/config-resolver": "^4.4.5", - "@smithy/core": "^3.20.2", - "@smithy/fetch-http-handler": "^5.3.8", - "@smithy/hash-node": "^4.2.7", - "@smithy/invalid-dependency": "^4.2.7", - "@smithy/middleware-content-length": "^4.2.7", - "@smithy/middleware-endpoint": "^4.4.3", - "@smithy/middleware-retry": "^4.4.19", - "@smithy/middleware-serde": "^4.2.8", - "@smithy/middleware-stack": "^4.2.7", - "@smithy/node-config-provider": "^4.3.7", - "@smithy/node-http-handler": "^4.4.7", - "@smithy/protocol-http": "^5.3.7", - "@smithy/smithy-client": "^4.10.4", - "@smithy/types": "^4.11.0", - "@smithy/url-parser": "^4.2.7", + "@aws-sdk/core": "3.970.0", + "@aws-sdk/middleware-host-header": "3.969.0", + "@aws-sdk/middleware-logger": "3.969.0", + "@aws-sdk/middleware-recursion-detection": "3.969.0", + "@aws-sdk/middleware-user-agent": "3.970.0", + "@aws-sdk/region-config-resolver": "3.969.0", + "@aws-sdk/types": "3.969.0", + "@aws-sdk/util-endpoints": "3.970.0", + "@aws-sdk/util-user-agent-browser": "3.969.0", + "@aws-sdk/util-user-agent-node": "3.971.0", + "@smithy/config-resolver": "^4.4.6", + "@smithy/core": "^3.20.6", + "@smithy/fetch-http-handler": "^5.3.9", + "@smithy/hash-node": "^4.2.8", + "@smithy/invalid-dependency": "^4.2.8", + "@smithy/middleware-content-length": "^4.2.8", + "@smithy/middleware-endpoint": "^4.4.7", + "@smithy/middleware-retry": "^4.4.23", + "@smithy/middleware-serde": "^4.2.9", + "@smithy/middleware-stack": "^4.2.8", + "@smithy/node-config-provider": "^4.3.8", + "@smithy/node-http-handler": "^4.4.8", + "@smithy/protocol-http": "^5.3.8", + "@smithy/smithy-client": "^4.10.8", + "@smithy/types": "^4.12.0", + "@smithy/url-parser": "^4.2.8", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", - "@smithy/util-defaults-mode-browser": "^4.3.18", - "@smithy/util-defaults-mode-node": "^4.2.21", - "@smithy/util-endpoints": "^3.2.7", - "@smithy/util-middleware": "^4.2.7", - "@smithy/util-retry": "^4.2.7", + "@smithy/util-defaults-mode-browser": "^4.3.22", + "@smithy/util-defaults-mode-node": "^4.2.25", + "@smithy/util-endpoints": "^3.2.8", + "@smithy/util-middleware": "^4.2.8", + "@smithy/util-retry": "^4.2.8", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@aws-sdk/region-config-resolver": { - "version": "3.965.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.965.0.tgz", - "integrity": "sha512-RoMhu9ly2B0coxn8ctXosPP2WmDD0MkQlZGLjoYHQUOCBmty5qmCxOqBmBDa6wbWbB8xKtMQ/4VXloQOgzjHXg==", + "version": "3.969.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.969.0.tgz", + "integrity": "sha512-scj9OXqKpcjJ4jsFLtqYWz3IaNvNOQTFFvEY8XMJXTv+3qF5I7/x9SJtKzTRJEBF3spjzBUYPtGFbs9sj4fisQ==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@aws-sdk/types": "3.965.0", - "@smithy/config-resolver": "^4.4.5", - "@smithy/node-config-provider": "^4.3.7", - "@smithy/types": "^4.11.0", + "@aws-sdk/types": "3.969.0", + "@smithy/config-resolver": "^4.4.6", + "@smithy/node-config-provider": "^4.3.8", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@aws-sdk/token-providers": { - "version": "3.967.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.967.0.tgz", - "integrity": "sha512-Qnd/nJ0CgeUa7zQczgmdQm0vYUF7pD1G0C+dR1T7huHQHRIsgCWIsCV9wNKzOFluqtcr6YAeuTwvY0+l8XWxnA==", + "version": "3.971.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.971.0.tgz", + "integrity": "sha512-4hKGWZbmuDdONMJV0HJ+9jwTDb0zLfKxcCLx2GEnBY31Gt9GeyIQ+DZ97Bb++0voawj6pnZToFikXTyrEq2x+w==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@aws-sdk/core": "3.967.0", - "@aws-sdk/nested-clients": "3.967.0", - "@aws-sdk/types": "3.965.0", - "@smithy/property-provider": "^4.2.7", - "@smithy/shared-ini-file-loader": "^4.4.2", - "@smithy/types": "^4.11.0", + "@aws-sdk/core": "3.970.0", + "@aws-sdk/nested-clients": "3.971.0", + "@aws-sdk/types": "3.969.0", + "@smithy/property-provider": "^4.2.8", + "@smithy/shared-ini-file-loader": "^4.4.3", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@aws-sdk/types": { - "version": "3.965.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.965.0.tgz", - "integrity": "sha512-jvodoJdMavvg8faN7co58vVJRO5MVep4JFPRzUNCzpJ98BDqWDk/ad045aMJcmxkLzYLS2UAnUmqjJ/tUPNlzQ==", + "version": "3.969.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.969.0.tgz", + "integrity": "sha512-7IIzM5TdiXn+VtgPdVLjmE6uUBUtnga0f4RiSEI1WW10RPuNvZ9U+pL3SwDiRDAdoGrOF9tSLJOFZmfuwYuVYQ==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@smithy/types": "^4.11.0", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@aws-sdk/util-endpoints": { - "version": "3.965.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.965.0.tgz", - "integrity": "sha512-WqSCB0XIsGUwZWvrYkuoofi2vzoVHqyeJ2kN+WyoOsxPLTiQSBIoqm/01R/qJvoxwK/gOOF7su9i84Vw2NQQpQ==", + "version": "3.970.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.970.0.tgz", + "integrity": "sha512-TZNZqFcMUtjvhZoZRtpEGQAdULYiy6rcGiXAbLU7e9LSpIYlRqpLa207oMNfgbzlL2PnHko+eVg8rajDiSOYCg==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@aws-sdk/types": "3.965.0", - "@smithy/types": "^4.11.0", - "@smithy/url-parser": "^4.2.7", - "@smithy/util-endpoints": "^3.2.7", + "@aws-sdk/types": "3.969.0", + "@smithy/types": "^4.12.0", + "@smithy/url-parser": "^4.2.8", + "@smithy/util-endpoints": "^3.2.8", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@aws-sdk/util-locate-window": { - "version": "3.965.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.965.0.tgz", - "integrity": "sha512-9LJFand4bIoOjOF4x3wx0UZYiFZRo4oUauxQSiEX2dVg+5qeBOJSjp2SeWykIE6+6frCZ5wvWm2fGLK8D32aJw==", + "version": "3.965.2", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.965.2.tgz", + "integrity": "sha512-qKgO7wAYsXzhwCHhdbaKFyxd83Fgs8/1Ka+jjSPrv2Ll7mB55Wbwlo0kkfMLh993/yEc8aoDIAc1Fz9h4Spi4Q==", "license": "Apache-2.0", "optional": true, "dependencies": { "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@aws-sdk/util-user-agent-browser": { - "version": "3.965.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.965.0.tgz", - "integrity": "sha512-Xiza/zMntQGpkd2dETQeAK8So1pg5+STTzpcdGWxj5q0jGO5ayjqT/q1Q7BrsX5KIr6PvRkl9/V7lLCv04wGjQ==", + "version": "3.969.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.969.0.tgz", + "integrity": "sha512-bpJGjuKmFr0rA6UKUCmN8D19HQFMLXMx5hKBXqBlPFdalMhxJSjcxzX9DbQh0Fn6bJtxCguFmRGOBdQqNOt49g==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@aws-sdk/types": "3.965.0", - "@smithy/types": "^4.11.0", + "@aws-sdk/types": "3.969.0", + "@smithy/types": "^4.12.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.967.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.967.0.tgz", - "integrity": "sha512-yUz6pCGxyG4+QaDg0dkdIBphjQp8A9rrbZa/+U3RJgRrW47hy64clFQUROzj5Poy1Ur8ICVXEUpBsSqRuYEU2g==", + "version": "3.971.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.971.0.tgz", + "integrity": "sha512-Eygjo9mFzQYjbGY3MYO6CsIhnTwAMd3WmuFalCykqEmj2r5zf0leWrhPaqvA5P68V5JdGfPYgj7vhNOd6CtRBQ==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@aws-sdk/middleware-user-agent": "3.967.0", - "@aws-sdk/types": "3.965.0", - "@smithy/node-config-provider": "^4.3.7", - "@smithy/types": "^4.11.0", + "@aws-sdk/middleware-user-agent": "3.970.0", + "@aws-sdk/types": "3.969.0", + "@smithy/node-config-provider": "^4.3.8", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" }, "peerDependencies": { "aws-crt": ">=1.0.0" @@ -937,18 +936,18 @@ } }, "node_modules/@aws-sdk/xml-builder": { - "version": "3.965.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.965.0.tgz", - "integrity": "sha512-Tcod25/BTupraQwtb+Q+GX8bmEZfxIFjjJ/AvkhUZsZlkPeVluzq1uu3Oeqf145DCdMjzLIN6vab5MrykbDP+g==", + "version": "3.969.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.969.0.tgz", + "integrity": "sha512-BSe4Lx/qdRQQdX8cSSI7Et20vqBspzAjBy8ZmXVoyLkol3y4sXBXzn+BiLtR+oh60ExQn6o2DU4QjdOZbXaKIQ==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@smithy/types": "^4.11.0", + "@smithy/types": "^4.12.0", "fast-xml-parser": "5.2.5", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@aws/lambda-invoke-store": { @@ -1215,33 +1214,33 @@ } }, "node_modules/@azure/msal-browser": { - "version": "4.27.0", - "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-4.27.0.tgz", - "integrity": "sha512-bZ8Pta6YAbdd0o0PEaL1/geBsPrLEnyY/RDWqvF1PP9RUH8EMLvUMGoZFYS6jSlUan6KZ9IMTLCnwpWWpQRK/w==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-4.28.1.tgz", + "integrity": "sha512-al2u2fTchbClq3L4C1NlqLm+vwKfhYCPtZN2LR/9xJVaQ4Mnrwf5vANvuyPSJHcGvw50UBmhuVmYUAhTEetTpA==", "license": "MIT", "dependencies": { - "@azure/msal-common": "15.13.3" + "@azure/msal-common": "15.14.1" }, "engines": { "node": ">=0.8.0" } }, "node_modules/@azure/msal-common": { - "version": "15.13.3", - "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-15.13.3.tgz", - "integrity": "sha512-shSDU7Ioecya+Aob5xliW9IGq1Ui8y4EVSdWGyI1Gbm4Vg61WpP95LuzcY214/wEjSn6w4PZYD4/iVldErHayQ==", + "version": "15.14.1", + "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-15.14.1.tgz", + "integrity": "sha512-IkzF7Pywt6QKTS0kwdCv/XV8x8JXknZDvSjj/IccooxnP373T5jaadO3FnOrbWo3S0UqkfIDyZNTaQ/oAgRdXw==", "license": "MIT", "engines": { "node": ">=0.8.0" } }, "node_modules/@azure/msal-node": { - "version": "3.8.4", - "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-3.8.4.tgz", - "integrity": "sha512-lvuAwsDpPDE/jSuVQOBMpLbXuVuLsPNRwWCyK3/6bPlBk0fGWegqoZ0qjZclMWyQ2JNvIY3vHY7hoFmFmFQcOw==", + "version": "3.8.6", + "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-3.8.6.tgz", + "integrity": "sha512-XTmhdItcBckcVVTy65Xp+42xG4LX5GK+9AqAsXPXk4IqUNv+LyQo5TMwNjuFYBfAB2GTG9iSQGk+QLc03vhf3w==", "license": "MIT", "dependencies": { - "@azure/msal-common": "15.13.3", + "@azure/msal-common": "15.14.1", "jsonwebtoken": "^9.0.0", "uuid": "^8.3.0" }, @@ -3655,6 +3654,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", + "dev": true, "license": "MIT", "engines": { "node": "20 || >=22" @@ -3664,6 +3664,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", + "dev": true, "license": "MIT", "dependencies": { "@isaacs/balanced-match": "^4.0.1" @@ -4027,18 +4028,6 @@ "node": ">= 8" } }, - "node_modules/@npmcli/fs": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-5.0.0.tgz", - "integrity": "sha512-7OsC1gNORBEawOa5+j2pXN9vsicaIOH5cPXxoR6fJOmH6/EXpJB2CajXOu1fPRFun2m1lktEFX11+P89hqO/og==", - "license": "ISC", - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, "node_modules/@npmcli/move-file": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz", @@ -4528,9 +4517,9 @@ "license": "MIT" }, "node_modules/@rollup/plugin-terser/node_modules/terser": { - "version": "5.44.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.44.1.tgz", - "integrity": "sha512-t/R3R/n0MSwnnazuPpPNVO60LX0SKL45pyl9YlvxIdkH0Of7D5qM2EVe+yASRIlY5pZ73nclYJfNANGWPwFDZw==", + "version": "5.46.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.0.tgz", + "integrity": "sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -5016,13 +5005,13 @@ } }, "node_modules/@smithy/abort-controller": { - "version": "4.2.7", - "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.2.7.tgz", - "integrity": "sha512-rzMY6CaKx2qxrbYbqjXWS0plqEy7LOdKHS0bg4ixJ6aoGDPNUcLWk/FRNuCILh7GKLG9TFUXYYeQQldMBBwuyw==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.2.8.tgz", + "integrity": "sha512-peuVfkYHAmS5ybKxWcfraK7WBBP0J+rkfUcbHJJKQ4ir3UAUNQI+Y4Vt/PqSzGqgloJ5O1dk7+WzNL8wcCSXbw==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@smithy/types": "^4.11.0", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -5030,17 +5019,17 @@ } }, "node_modules/@smithy/config-resolver": { - "version": "4.4.5", - "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.4.5.tgz", - "integrity": "sha512-HAGoUAFYsUkoSckuKbCPayECeMim8pOu+yLy1zOxt1sifzEbrsRpYa+mKcMdiHKMeiqOibyPG0sFJnmaV/OGEg==", + "version": "4.4.6", + "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.4.6.tgz", + "integrity": "sha512-qJpzYC64kaj3S0fueiu3kXm8xPrR3PcXDPEgnaNMRn0EjNSZFoFjvbUp0YUDsRhN1CB90EnHJtbxWKevnH99UQ==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@smithy/node-config-provider": "^4.3.7", - "@smithy/types": "^4.11.0", + "@smithy/node-config-provider": "^4.3.8", + "@smithy/types": "^4.12.0", "@smithy/util-config-provider": "^4.2.0", - "@smithy/util-endpoints": "^3.2.7", - "@smithy/util-middleware": "^4.2.7", + "@smithy/util-endpoints": "^3.2.8", + "@smithy/util-middleware": "^4.2.8", "tslib": "^2.6.2" }, "engines": { @@ -5048,19 +5037,19 @@ } }, "node_modules/@smithy/core": { - "version": "3.20.3", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.20.3.tgz", - "integrity": "sha512-iwF1e0+H9vX+4reUA0WjKnc5ueg0Leinl5kI7wsie5bVXoYdzkpINz6NPYhpr/5InOv332a7wNV5AxJyFoVUsQ==", + "version": "3.20.7", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.20.7.tgz", + "integrity": "sha512-aO7jmh3CtrmPsIJxUwYIzI5WVlMK8BMCPQ4D4nTzqTqBhbzvxHNzBMGcEg13yg/z9R2Qsz49NUFl0F0lVbTVFw==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@smithy/middleware-serde": "^4.2.8", - "@smithy/protocol-http": "^5.3.7", - "@smithy/types": "^4.11.0", + "@smithy/middleware-serde": "^4.2.9", + "@smithy/protocol-http": "^5.3.8", + "@smithy/types": "^4.12.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", - "@smithy/util-middleware": "^4.2.7", - "@smithy/util-stream": "^4.5.8", + "@smithy/util-middleware": "^4.2.8", + "@smithy/util-stream": "^4.5.10", "@smithy/util-utf8": "^4.2.0", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" @@ -5070,16 +5059,16 @@ } }, "node_modules/@smithy/credential-provider-imds": { - "version": "4.2.7", - "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.2.7.tgz", - "integrity": "sha512-CmduWdCiILCRNbQWFR0OcZlUPVtyE49Sr8yYL0rZQ4D/wKxiNzBNS/YHemvnbkIWj623fplgkexUd/c9CAKdoA==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.2.8.tgz", + "integrity": "sha512-FNT0xHS1c/CPN8upqbMFP83+ul5YgdisfCfkZ86Jh2NSmnqw/AJ6x5pEogVCTVvSm7j9MopRU89bmDelxuDMYw==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@smithy/node-config-provider": "^4.3.7", - "@smithy/property-provider": "^4.2.7", - "@smithy/types": "^4.11.0", - "@smithy/url-parser": "^4.2.7", + "@smithy/node-config-provider": "^4.3.8", + "@smithy/property-provider": "^4.2.8", + "@smithy/types": "^4.12.0", + "@smithy/url-parser": "^4.2.8", "tslib": "^2.6.2" }, "engines": { @@ -5087,15 +5076,15 @@ } }, "node_modules/@smithy/fetch-http-handler": { - "version": "5.3.8", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.3.8.tgz", - "integrity": "sha512-h/Fi+o7mti4n8wx1SR6UHWLaakwHRx29sizvp8OOm7iqwKGFneT06GCSFhml6Bha5BT6ot5pj3CYZnCHhGC2Rg==", + "version": "5.3.9", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.3.9.tgz", + "integrity": "sha512-I4UhmcTYXBrct03rwzQX1Y/iqQlzVQaPxWjCjula++5EmWq9YGBrx6bbGqluGc1f0XEfhSkiY4jhLgbsJUMKRA==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@smithy/protocol-http": "^5.3.7", - "@smithy/querystring-builder": "^4.2.7", - "@smithy/types": "^4.11.0", + "@smithy/protocol-http": "^5.3.8", + "@smithy/querystring-builder": "^4.2.8", + "@smithy/types": "^4.12.0", "@smithy/util-base64": "^4.3.0", "tslib": "^2.6.2" }, @@ -5104,13 +5093,13 @@ } }, "node_modules/@smithy/hash-node": { - "version": "4.2.7", - "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-4.2.7.tgz", - "integrity": "sha512-PU/JWLTBCV1c8FtB8tEFnY4eV1tSfBc7bDBADHfn1K+uRbPgSJ9jnJp0hyjiFN2PMdPzxsf1Fdu0eo9fJ760Xw==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-4.2.8.tgz", + "integrity": "sha512-7ZIlPbmaDGxVoxErDZnuFG18WekhbA/g2/i97wGj+wUBeS6pcUeAym8u4BXh/75RXWhgIJhyC11hBzig6MljwA==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@smithy/types": "^4.11.0", + "@smithy/types": "^4.12.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" @@ -5120,13 +5109,13 @@ } }, "node_modules/@smithy/invalid-dependency": { - "version": "4.2.7", - "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-4.2.7.tgz", - "integrity": "sha512-ncvgCr9a15nPlkhIUx3CU4d7E7WEuVJOV7fS7nnK2hLtPK9tYRBkMHQbhXU1VvvKeBm/O0x26OEoBq+ngFpOEQ==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-4.2.8.tgz", + "integrity": "sha512-N9iozRybwAQ2dn9Fot9kI6/w9vos2oTXLhtK7ovGqwZjlOcxu6XhPlpLpC+INsxktqHinn5gS2DXDjDF2kG5sQ==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@smithy/types": "^4.11.0", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -5147,14 +5136,14 @@ } }, "node_modules/@smithy/middleware-content-length": { - "version": "4.2.7", - "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-4.2.7.tgz", - "integrity": "sha512-GszfBfCcvt7kIbJ41LuNa5f0wvQCHhnGx/aDaZJCCT05Ld6x6U2s0xsc/0mBFONBZjQJp2U/0uSJ178OXOwbhg==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-4.2.8.tgz", + "integrity": "sha512-RO0jeoaYAB1qBRhfVyq0pMgBoUK34YEJxVxyjOWYZiOKOq2yMZ4MnVXMZCUDenpozHue207+9P5ilTV1zeda0A==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@smithy/protocol-http": "^5.3.7", - "@smithy/types": "^4.11.0", + "@smithy/protocol-http": "^5.3.8", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -5162,19 +5151,19 @@ } }, "node_modules/@smithy/middleware-endpoint": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.4.4.tgz", - "integrity": "sha512-TFxS6C5bGSc4djD1SLVmstCpfYDjmMnBR4KRDge5HEEtgSINGPKuxLvaAGfSPx5FFoMaTJkj4jJLNFggeWpRoQ==", + "version": "4.4.8", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.4.8.tgz", + "integrity": "sha512-TV44qwB/T0OMMzjIuI+JeS0ort3bvlPJ8XIH0MSlGADraXpZqmyND27ueuAL3E14optleADWqtd7dUgc2w+qhQ==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@smithy/core": "^3.20.3", - "@smithy/middleware-serde": "^4.2.8", - "@smithy/node-config-provider": "^4.3.7", - "@smithy/shared-ini-file-loader": "^4.4.2", - "@smithy/types": "^4.11.0", - "@smithy/url-parser": "^4.2.7", - "@smithy/util-middleware": "^4.2.7", + "@smithy/core": "^3.20.7", + "@smithy/middleware-serde": "^4.2.9", + "@smithy/node-config-provider": "^4.3.8", + "@smithy/shared-ini-file-loader": "^4.4.3", + "@smithy/types": "^4.12.0", + "@smithy/url-parser": "^4.2.8", + "@smithy/util-middleware": "^4.2.8", "tslib": "^2.6.2" }, "engines": { @@ -5182,19 +5171,19 @@ } }, "node_modules/@smithy/middleware-retry": { - "version": "4.4.20", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.4.20.tgz", - "integrity": "sha512-+UvEn/8HGzh/6zpe9xFGZe7go4/fzflggfeRG/TvdGLoUY7Gw+4RgzKJEPU2NvPo0k/j/o7vvx25ZWyOXeGoxw==", + "version": "4.4.24", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.4.24.tgz", + "integrity": "sha512-yiUY1UvnbUFfP5izoKLtfxDSTRv724YRRwyiC/5HYY6vdsVDcDOXKSXmkJl/Hovcxt5r+8tZEUAdrOaCJwrl9Q==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@smithy/node-config-provider": "^4.3.7", - "@smithy/protocol-http": "^5.3.7", - "@smithy/service-error-classification": "^4.2.7", - "@smithy/smithy-client": "^4.10.5", - "@smithy/types": "^4.11.0", - "@smithy/util-middleware": "^4.2.7", - "@smithy/util-retry": "^4.2.7", + "@smithy/node-config-provider": "^4.3.8", + "@smithy/protocol-http": "^5.3.8", + "@smithy/service-error-classification": "^4.2.8", + "@smithy/smithy-client": "^4.10.9", + "@smithy/types": "^4.12.0", + "@smithy/util-middleware": "^4.2.8", + "@smithy/util-retry": "^4.2.8", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" }, @@ -5203,14 +5192,14 @@ } }, "node_modules/@smithy/middleware-serde": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.2.8.tgz", - "integrity": "sha512-8rDGYen5m5+NV9eHv9ry0sqm2gI6W7mc1VSFMtn6Igo25S507/HaOX9LTHAS2/J32VXD0xSzrY0H5FJtOMS4/w==", + "version": "4.2.9", + "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.2.9.tgz", + "integrity": "sha512-eMNiej0u/snzDvlqRGSN3Vl0ESn3838+nKyVfF2FKNXFbi4SERYT6PR392D39iczngbqqGG0Jl1DlCnp7tBbXQ==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@smithy/protocol-http": "^5.3.7", - "@smithy/types": "^4.11.0", + "@smithy/protocol-http": "^5.3.8", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -5218,13 +5207,13 @@ } }, "node_modules/@smithy/middleware-stack": { - "version": "4.2.7", - "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.2.7.tgz", - "integrity": "sha512-bsOT0rJ+HHlZd9crHoS37mt8qRRN/h9jRve1SXUhVbkRzu0QaNYZp1i1jha4n098tsvROjcwfLlfvcFuJSXEsw==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.2.8.tgz", + "integrity": "sha512-w6LCfOviTYQjBctOKSwy6A8FIkQy7ICvglrZFl6Bw4FmcQ1Z420fUtIhxaUZZshRe0VCq4kvDiPiXrPZAe8oRA==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@smithy/types": "^4.11.0", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -5232,15 +5221,15 @@ } }, "node_modules/@smithy/node-config-provider": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.3.7.tgz", - "integrity": "sha512-7r58wq8sdOcrwWe+klL9y3bc4GW1gnlfnFOuL7CXa7UzfhzhxKuzNdtqgzmTV+53lEp9NXh5hY/S4UgjLOzPfw==", + "version": "4.3.8", + "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.3.8.tgz", + "integrity": "sha512-aFP1ai4lrbVlWjfpAfRSL8KFcnJQYfTl5QxLJXY32vghJrDuFyPZ6LtUL+JEGYiFRG1PfPLHLoxj107ulncLIg==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@smithy/property-provider": "^4.2.7", - "@smithy/shared-ini-file-loader": "^4.4.2", - "@smithy/types": "^4.11.0", + "@smithy/property-provider": "^4.2.8", + "@smithy/shared-ini-file-loader": "^4.4.3", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -5248,16 +5237,16 @@ } }, "node_modules/@smithy/node-http-handler": { - "version": "4.4.7", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.4.7.tgz", - "integrity": "sha512-NELpdmBOO6EpZtWgQiHjoShs1kmweaiNuETUpuup+cmm/xJYjT4eUjfhrXRP4jCOaAsS3c3yPsP3B+K+/fyPCQ==", + "version": "4.4.8", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.4.8.tgz", + "integrity": "sha512-q9u+MSbJVIJ1QmJ4+1u+cERXkrhuILCBDsJUBAW1MPE6sFonbCNaegFuwW9ll8kh5UdyY3jOkoOGlc7BesoLpg==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@smithy/abort-controller": "^4.2.7", - "@smithy/protocol-http": "^5.3.7", - "@smithy/querystring-builder": "^4.2.7", - "@smithy/types": "^4.11.0", + "@smithy/abort-controller": "^4.2.8", + "@smithy/protocol-http": "^5.3.8", + "@smithy/querystring-builder": "^4.2.8", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -5265,13 +5254,13 @@ } }, "node_modules/@smithy/property-provider": { - "version": "4.2.7", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.2.7.tgz", - "integrity": "sha512-jmNYKe9MGGPoSl/D7JDDs1C8b3dC8f/w78LbaVfoTtWy4xAd5dfjaFG9c9PWPihY4ggMQNQSMtzU77CNgAJwmA==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.2.8.tgz", + "integrity": "sha512-EtCTbyIveCKeOXDSWSdze3k612yCPq1YbXsbqX3UHhkOSW8zKsM9NOJG5gTIya0vbY2DIaieG8pKo1rITHYL0w==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@smithy/types": "^4.11.0", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -5279,13 +5268,13 @@ } }, "node_modules/@smithy/protocol-http": { - "version": "5.3.7", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.3.7.tgz", - "integrity": "sha512-1r07pb994I20dD/c2seaZhoCuNYm0rWrvBxhCQ70brNh11M5Ml2ew6qJVo0lclB3jMIXirD4s2XRXRe7QEi0xA==", + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.3.8.tgz", + "integrity": "sha512-QNINVDhxpZ5QnP3aviNHQFlRogQZDfYlCkQT+7tJnErPQbDhysondEjhikuANxgMsZrkGeiAxXy4jguEGsDrWQ==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@smithy/types": "^4.11.0", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -5293,13 +5282,13 @@ } }, "node_modules/@smithy/querystring-builder": { - "version": "4.2.7", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.2.7.tgz", - "integrity": "sha512-eKONSywHZxK4tBxe2lXEysh8wbBdvDWiA+RIuaxZSgCMmA0zMgoDpGLJhnyj+c0leOQprVnXOmcB4m+W9Rw7sg==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.2.8.tgz", + "integrity": "sha512-Xr83r31+DrE8CP3MqPgMJl+pQlLLmOfiEUnoyAlGzzJIrEsbKsPy1hqH0qySaQm4oWrCBlUqRt+idEgunKB+iw==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@smithy/types": "^4.11.0", + "@smithy/types": "^4.12.0", "@smithy/util-uri-escape": "^4.2.0", "tslib": "^2.6.2" }, @@ -5308,13 +5297,13 @@ } }, "node_modules/@smithy/querystring-parser": { - "version": "4.2.7", - "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.2.7.tgz", - "integrity": "sha512-3X5ZvzUHmlSTHAXFlswrS6EGt8fMSIxX/c3Rm1Pni3+wYWB6cjGocmRIoqcQF9nU5OgGmL0u7l9m44tSUpfj9w==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.2.8.tgz", + "integrity": "sha512-vUurovluVy50CUlazOiXkPq40KGvGWSdmusa3130MwrR1UNnNgKAlj58wlOe61XSHRpUfIIh6cE0zZ8mzKaDPA==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@smithy/types": "^4.11.0", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -5322,26 +5311,26 @@ } }, "node_modules/@smithy/service-error-classification": { - "version": "4.2.7", - "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.2.7.tgz", - "integrity": "sha512-YB7oCbukqEb2Dlh3340/8g8vNGbs/QsNNRms+gv3N2AtZz9/1vSBx6/6tpwQpZMEJFs7Uq8h4mmOn48ZZ72MkA==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.2.8.tgz", + "integrity": "sha512-mZ5xddodpJhEt3RkCjbmUQuXUOaPNTkbMGR0bcS8FE0bJDLMZlhmpgrvPNCYglVw5rsYTpSnv19womw9WWXKQQ==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@smithy/types": "^4.11.0" + "@smithy/types": "^4.12.0" }, "engines": { "node": ">=18.0.0" } }, "node_modules/@smithy/shared-ini-file-loader": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.4.2.tgz", - "integrity": "sha512-M7iUUff/KwfNunmrgtqBfvZSzh3bmFgv/j/t1Y1dQ+8dNo34br1cqVEqy6v0mYEgi0DkGO7Xig0AnuOaEGVlcg==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.4.3.tgz", + "integrity": "sha512-DfQjxXQnzC5UbCUPeC3Ie8u+rIWZTvuDPAGU/BxzrOGhRvgUanaP68kDZA+jaT3ZI+djOf+4dERGlm9mWfFDrg==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@smithy/types": "^4.11.0", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -5349,17 +5338,17 @@ } }, "node_modules/@smithy/signature-v4": { - "version": "5.3.7", - "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.3.7.tgz", - "integrity": "sha512-9oNUlqBlFZFOSdxgImA6X5GFuzE7V2H7VG/7E70cdLhidFbdtvxxt81EHgykGK5vq5D3FafH//X+Oy31j3CKOg==", + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.3.8.tgz", + "integrity": "sha512-6A4vdGj7qKNRF16UIcO8HhHjKW27thsxYci+5r/uVRkdcBEkOEiY8OMPuydLX4QHSrJqGHPJzPRwwVTqbLZJhg==", "license": "Apache-2.0", "optional": true, "dependencies": { "@smithy/is-array-buffer": "^4.2.0", - "@smithy/protocol-http": "^5.3.7", - "@smithy/types": "^4.11.0", + "@smithy/protocol-http": "^5.3.8", + "@smithy/types": "^4.12.0", "@smithy/util-hex-encoding": "^4.2.0", - "@smithy/util-middleware": "^4.2.7", + "@smithy/util-middleware": "^4.2.8", "@smithy/util-uri-escape": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" @@ -5369,18 +5358,18 @@ } }, "node_modules/@smithy/smithy-client": { - "version": "4.10.5", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.10.5.tgz", - "integrity": "sha512-uotYm3WDne01R0DxBqF9J8WZc8gSgdj+uC7Lv/R+GinH4rxcgRLxLDayYkyGAboZlYszly6maQA+NGQ5N4gLhQ==", + "version": "4.10.9", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.10.9.tgz", + "integrity": "sha512-Je0EvGXVJ0Vrrr2lsubq43JGRIluJ/hX17aN/W/A0WfE+JpoMdI8kwk2t9F0zTX9232sJDGcoH4zZre6m6f/sg==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@smithy/core": "^3.20.3", - "@smithy/middleware-endpoint": "^4.4.4", - "@smithy/middleware-stack": "^4.2.7", - "@smithy/protocol-http": "^5.3.7", - "@smithy/types": "^4.11.0", - "@smithy/util-stream": "^4.5.8", + "@smithy/core": "^3.20.7", + "@smithy/middleware-endpoint": "^4.4.8", + "@smithy/middleware-stack": "^4.2.8", + "@smithy/protocol-http": "^5.3.8", + "@smithy/types": "^4.12.0", + "@smithy/util-stream": "^4.5.10", "tslib": "^2.6.2" }, "engines": { @@ -5388,9 +5377,9 @@ } }, "node_modules/@smithy/types": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.11.0.tgz", - "integrity": "sha512-mlrmL0DRDVe3mNrjTcVcZEgkFmufITfUAPBEA+AHYiIeYyJebso/He1qLbP3PssRe22KUzLRpQSdBPbXdgZ2VA==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.12.0.tgz", + "integrity": "sha512-9YcuJVTOBDjg9LWo23Qp0lTQ3D7fQsQtwle0jVfpbUHy9qBwCEgKuVH4FqFB3VYu0nwdHKiEMA+oXz7oV8X1kw==", "license": "Apache-2.0", "optional": true, "dependencies": { @@ -5401,14 +5390,14 @@ } }, "node_modules/@smithy/url-parser": { - "version": "4.2.7", - "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.2.7.tgz", - "integrity": "sha512-/RLtVsRV4uY3qPWhBDsjwahAtt3x2IsMGnP5W1b2VZIe+qgCqkLxI1UOHDZp1Q1QSOrdOR32MF3Ph2JfWT1VHg==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.2.8.tgz", + "integrity": "sha512-NQho9U68TGMEU639YkXnVMV3GEFFULmmaWdlu1E9qzyIePOHsoSnagTGSDv1Zi8DCNN6btxOSdgmy5E/hsZwhA==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@smithy/querystring-parser": "^4.2.7", - "@smithy/types": "^4.11.0", + "@smithy/querystring-parser": "^4.2.8", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -5484,15 +5473,15 @@ } }, "node_modules/@smithy/util-defaults-mode-browser": { - "version": "4.3.19", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.3.19.tgz", - "integrity": "sha512-5fkC/yE5aepnzcF9dywKefGlJUMM7JEYUOv97TRDLTtGiiAqf7YG80HJWIBR0qWQPQW3dlQ5eFlUsySvt0rGEA==", + "version": "4.3.23", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.3.23.tgz", + "integrity": "sha512-mMg+r/qDfjfF/0psMbV4zd7F/i+rpyp7Hjh0Wry7eY15UnzTEId+xmQTGDU8IdZtDfbGQxuWNfgBZKBj+WuYbA==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@smithy/property-provider": "^4.2.7", - "@smithy/smithy-client": "^4.10.5", - "@smithy/types": "^4.11.0", + "@smithy/property-provider": "^4.2.8", + "@smithy/smithy-client": "^4.10.9", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -5500,18 +5489,18 @@ } }, "node_modules/@smithy/util-defaults-mode-node": { - "version": "4.2.22", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.2.22.tgz", - "integrity": "sha512-f0KNaSK192+kv6GFkUDA0Tvr5B8eU2bFh1EO+cUdlzZ2jap5Zv7KZXa0B/7r/M1+xiYPSIuroxlxQVP1ua9kxg==", + "version": "4.2.26", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.2.26.tgz", + "integrity": "sha512-EQqe/WkbCinah0h1lMWh9ICl0Ob4lyl20/10WTB35SC9vDQfD8zWsOT+x2FIOXKAoZQ8z/y0EFMoodbcqWJY/w==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@smithy/config-resolver": "^4.4.5", - "@smithy/credential-provider-imds": "^4.2.7", - "@smithy/node-config-provider": "^4.3.7", - "@smithy/property-provider": "^4.2.7", - "@smithy/smithy-client": "^4.10.5", - "@smithy/types": "^4.11.0", + "@smithy/config-resolver": "^4.4.6", + "@smithy/credential-provider-imds": "^4.2.8", + "@smithy/node-config-provider": "^4.3.8", + "@smithy/property-provider": "^4.2.8", + "@smithy/smithy-client": "^4.10.9", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -5519,14 +5508,14 @@ } }, "node_modules/@smithy/util-endpoints": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-3.2.7.tgz", - "integrity": "sha512-s4ILhyAvVqhMDYREeTS68R43B1V5aenV5q/V1QpRQJkCXib5BPRo4s7uNdzGtIKxaPHCfU/8YkvPAEvTpxgspg==", + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-3.2.8.tgz", + "integrity": "sha512-8JaVTn3pBDkhZgHQ8R0epwWt+BqPSLCjdjXXusK1onwJlRuN69fbvSK66aIKKO7SwVFM6x2J2ox5X8pOaWcUEw==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@smithy/node-config-provider": "^4.3.7", - "@smithy/types": "^4.11.0", + "@smithy/node-config-provider": "^4.3.8", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -5547,13 +5536,13 @@ } }, "node_modules/@smithy/util-middleware": { - "version": "4.2.7", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.2.7.tgz", - "integrity": "sha512-i1IkpbOae6NvIKsEeLLM9/2q4X+M90KV3oCFgWQI4q0Qz+yUZvsr+gZPdAEAtFhWQhAHpTsJO8DRJPuwVyln+w==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.2.8.tgz", + "integrity": "sha512-PMqfeJxLcNPMDgvPbbLl/2Vpin+luxqTGPpW3NAQVLbRrFRzTa4rNAASYeIGjRV9Ytuhzny39SpyU04EQreF+A==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@smithy/types": "^4.11.0", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -5561,14 +5550,14 @@ } }, "node_modules/@smithy/util-retry": { - "version": "4.2.7", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.2.7.tgz", - "integrity": "sha512-SvDdsQyF5CIASa4EYVT02LukPHVzAgUA4kMAuZ97QJc2BpAqZfA4PINB8/KOoCXEw9tsuv/jQjMeaHFvxdLNGg==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.2.8.tgz", + "integrity": "sha512-CfJqwvoRY0kTGe5AkQokpURNCT1u/MkRzMTASWMPPo2hNSnKtF1D45dQl3DE2LKLr4m+PW9mCeBMJr5mCAVThg==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@smithy/service-error-classification": "^4.2.7", - "@smithy/types": "^4.11.0", + "@smithy/service-error-classification": "^4.2.8", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -5576,15 +5565,15 @@ } }, "node_modules/@smithy/util-stream": { - "version": "4.5.8", - "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.5.8.tgz", - "integrity": "sha512-ZnnBhTapjM0YPGUSmOs0Mcg/Gg87k503qG4zU2v/+Js2Gu+daKOJMeqcQns8ajepY8tgzzfYxl6kQyZKml6O2w==", + "version": "4.5.10", + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.5.10.tgz", + "integrity": "sha512-jbqemy51UFSZSp2y0ZmRfckmrzuKww95zT9BYMmuJ8v3altGcqjwoV1tzpOwuHaKrwQrCjIzOib499ymr2f98g==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@smithy/fetch-http-handler": "^5.3.8", - "@smithy/node-http-handler": "^4.4.7", - "@smithy/types": "^4.11.0", + "@smithy/fetch-http-handler": "^5.3.9", + "@smithy/node-http-handler": "^4.4.8", + "@smithy/types": "^4.12.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", @@ -5692,6 +5681,43 @@ "testcontainers": "^10.28.0" } }, + "node_modules/@testcontainers/hivemq/node_modules/docker-compose": { + "version": "0.24.8", + "resolved": "https://registry.npmjs.org/docker-compose/-/docker-compose-0.24.8.tgz", + "integrity": "sha512-plizRs/Vf15H+GCVxq2EUvyPK7ei9b/cVesHvjnX4xaXjM9spHe2Ytq0BitndFgvTJ3E3NljPNUEl7BAN43iZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "yaml": "^2.2.2" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/@testcontainers/hivemq/node_modules/testcontainers": { + "version": "10.28.0", + "resolved": "https://registry.npmjs.org/testcontainers/-/testcontainers-10.28.0.tgz", + "integrity": "sha512-1fKrRRCsgAQNkarjHCMKzBKXSJFmzNTiTbhb5E/j5hflRXChEtHvkefjaHlgkNUjfw92/Dq8LTgwQn6RDBFbMg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@balena/dockerignore": "^1.0.2", + "@types/dockerode": "^3.3.35", + "archiver": "^7.0.1", + "async-lock": "^1.4.1", + "byline": "^5.0.0", + "debug": "^4.3.5", + "docker-compose": "^0.24.8", + "dockerode": "^4.0.5", + "get-port": "^7.1.0", + "proper-lockfile": "^4.1.2", + "properties-reader": "^2.3.0", + "ssh-remote-port-forward": "^1.0.4", + "tar-fs": "^3.0.7", + "tmp": "^0.2.3", + "undici": "^5.29.0" + } + }, "node_modules/@testcontainers/mariadb": { "version": "10.28.0", "resolved": "https://registry.npmjs.org/@testcontainers/mariadb/-/mariadb-10.28.0.tgz", @@ -5702,6 +5728,43 @@ "testcontainers": "^10.28.0" } }, + "node_modules/@testcontainers/mariadb/node_modules/docker-compose": { + "version": "0.24.8", + "resolved": "https://registry.npmjs.org/docker-compose/-/docker-compose-0.24.8.tgz", + "integrity": "sha512-plizRs/Vf15H+GCVxq2EUvyPK7ei9b/cVesHvjnX4xaXjM9spHe2Ytq0BitndFgvTJ3E3NljPNUEl7BAN43iZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "yaml": "^2.2.2" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/@testcontainers/mariadb/node_modules/testcontainers": { + "version": "10.28.0", + "resolved": "https://registry.npmjs.org/testcontainers/-/testcontainers-10.28.0.tgz", + "integrity": "sha512-1fKrRRCsgAQNkarjHCMKzBKXSJFmzNTiTbhb5E/j5hflRXChEtHvkefjaHlgkNUjfw92/Dq8LTgwQn6RDBFbMg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@balena/dockerignore": "^1.0.2", + "@types/dockerode": "^3.3.35", + "archiver": "^7.0.1", + "async-lock": "^1.4.1", + "byline": "^5.0.0", + "debug": "^4.3.5", + "docker-compose": "^0.24.8", + "dockerode": "^4.0.5", + "get-port": "^7.1.0", + "proper-lockfile": "^4.1.2", + "properties-reader": "^2.3.0", + "ssh-remote-port-forward": "^1.0.4", + "tar-fs": "^3.0.7", + "tmp": "^0.2.3", + "undici": "^5.29.0" + } + }, "node_modules/@testcontainers/mssqlserver": { "version": "10.28.0", "resolved": "https://registry.npmjs.org/@testcontainers/mssqlserver/-/mssqlserver-10.28.0.tgz", @@ -5712,6 +5775,43 @@ "testcontainers": "^10.28.0" } }, + "node_modules/@testcontainers/mssqlserver/node_modules/docker-compose": { + "version": "0.24.8", + "resolved": "https://registry.npmjs.org/docker-compose/-/docker-compose-0.24.8.tgz", + "integrity": "sha512-plizRs/Vf15H+GCVxq2EUvyPK7ei9b/cVesHvjnX4xaXjM9spHe2Ytq0BitndFgvTJ3E3NljPNUEl7BAN43iZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "yaml": "^2.2.2" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/@testcontainers/mssqlserver/node_modules/testcontainers": { + "version": "10.28.0", + "resolved": "https://registry.npmjs.org/testcontainers/-/testcontainers-10.28.0.tgz", + "integrity": "sha512-1fKrRRCsgAQNkarjHCMKzBKXSJFmzNTiTbhb5E/j5hflRXChEtHvkefjaHlgkNUjfw92/Dq8LTgwQn6RDBFbMg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@balena/dockerignore": "^1.0.2", + "@types/dockerode": "^3.3.35", + "archiver": "^7.0.1", + "async-lock": "^1.4.1", + "byline": "^5.0.0", + "debug": "^4.3.5", + "docker-compose": "^0.24.8", + "dockerode": "^4.0.5", + "get-port": "^7.1.0", + "proper-lockfile": "^4.1.2", + "properties-reader": "^2.3.0", + "ssh-remote-port-forward": "^1.0.4", + "tar-fs": "^3.0.7", + "tmp": "^0.2.3", + "undici": "^5.29.0" + } + }, "node_modules/@testcontainers/mysql": { "version": "11.11.0", "resolved": "https://registry.npmjs.org/@testcontainers/mysql/-/mysql-11.11.0.tgz", @@ -5722,19 +5822,6 @@ "testcontainers": "^11.11.0" } }, - "node_modules/@testcontainers/mysql/node_modules/docker-compose": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/docker-compose/-/docker-compose-1.3.0.tgz", - "integrity": "sha512-7Gevk/5eGD50+eMD+XDnFnOrruFkL0kSd7jEG4cjmqweDSUhB7i0g8is/nBdVpl+Bx338SqIB2GLKm32M+Vs6g==", - "dev": true, - "license": "MIT", - "dependencies": { - "yaml": "^2.2.2" - }, - "engines": { - "node": ">= 6.0.0" - } - }, "node_modules/@testcontainers/mysql/node_modules/testcontainers": { "version": "11.11.0", "resolved": "https://registry.npmjs.org/testcontainers/-/testcontainers-11.11.0.tgz", @@ -5779,19 +5866,6 @@ "testcontainers": "^11.11.0" } }, - "node_modules/@testcontainers/postgresql/node_modules/docker-compose": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/docker-compose/-/docker-compose-1.3.0.tgz", - "integrity": "sha512-7Gevk/5eGD50+eMD+XDnFnOrruFkL0kSd7jEG4cjmqweDSUhB7i0g8is/nBdVpl+Bx338SqIB2GLKm32M+Vs6g==", - "dev": true, - "license": "MIT", - "dependencies": { - "yaml": "^2.2.2" - }, - "engines": { - "node": ">= 6.0.0" - } - }, "node_modules/@testcontainers/postgresql/node_modules/testcontainers": { "version": "11.11.0", "resolved": "https://registry.npmjs.org/testcontainers/-/testcontainers-11.11.0.tgz", @@ -5836,6 +5910,43 @@ "testcontainers": "^10.28.0" } }, + "node_modules/@testcontainers/rabbitmq/node_modules/docker-compose": { + "version": "0.24.8", + "resolved": "https://registry.npmjs.org/docker-compose/-/docker-compose-0.24.8.tgz", + "integrity": "sha512-plizRs/Vf15H+GCVxq2EUvyPK7ei9b/cVesHvjnX4xaXjM9spHe2Ytq0BitndFgvTJ3E3NljPNUEl7BAN43iZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "yaml": "^2.2.2" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/@testcontainers/rabbitmq/node_modules/testcontainers": { + "version": "10.28.0", + "resolved": "https://registry.npmjs.org/testcontainers/-/testcontainers-10.28.0.tgz", + "integrity": "sha512-1fKrRRCsgAQNkarjHCMKzBKXSJFmzNTiTbhb5E/j5hflRXChEtHvkefjaHlgkNUjfw92/Dq8LTgwQn6RDBFbMg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@balena/dockerignore": "^1.0.2", + "@types/dockerode": "^3.3.35", + "archiver": "^7.0.1", + "async-lock": "^1.4.1", + "byline": "^5.0.0", + "debug": "^4.3.5", + "docker-compose": "^0.24.8", + "dockerode": "^4.0.5", + "get-port": "^7.1.0", + "proper-lockfile": "^4.1.2", + "properties-reader": "^2.3.0", + "ssh-remote-port-forward": "^1.0.4", + "tar-fs": "^3.0.7", + "tmp": "^0.2.3", + "undici": "^5.29.0" + } + }, "node_modules/@tootallnate/once": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", @@ -6035,9 +6146,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "20.19.28", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.28.tgz", - "integrity": "sha512-VyKBr25BuFDzBFCK5sUM6ZXiWfqgCTwTAOK8qzGV/m9FCirXYDlmczJ+d5dXBAQALGCdRRdbteKYfJ84NGEusw==", + "version": "20.19.30", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.30.tgz", + "integrity": "sha512-WJtwWJu7UdlvzEAUm484QNg5eAoq5QR08KDNx7g45Usrs2NtOPiX8ugDqmKdXkyL03rBqU5dYNYVQetEpBHq2g==", "license": "MIT", "dependencies": { "undici-types": "~6.21.0" @@ -7535,9 +7646,9 @@ } }, "node_modules/baseline-browser-mapping": { - "version": "2.9.14", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.14.tgz", - "integrity": "sha512-B0xUquLkiGLgHhpPBqvl7GWegWBUNuujQ6kXd/r1U38ElPT6Ok8KZ8e+FpUGEc2ZoRQUzq/aUnaKFc/svWUGSg==", + "version": "2.9.15", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.15.tgz", + "integrity": "sha512-kX8h7K2srmDyYnXRIppo4AH/wYgzWVCs+eKr3RusRSQ5PvRYoEFmR/I0PbdTjKFAoKqp5+kbxnNTFO9jOfSVJg==", "dev": true, "license": "Apache-2.0", "bin": { @@ -7902,85 +8013,6 @@ "node": ">= 0.8" } }, - "node_modules/cacache": { - "version": "20.0.3", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-20.0.3.tgz", - "integrity": "sha512-3pUp4e8hv07k1QlijZu6Kn7c9+ZpWWk4j3F8N3xPuCExULobqJydKYOTj1FTq58srkJsXvO7LbGAH4C0ZU3WGw==", - "license": "ISC", - "dependencies": { - "@npmcli/fs": "^5.0.0", - "fs-minipass": "^3.0.0", - "glob": "^13.0.0", - "lru-cache": "^11.1.0", - "minipass": "^7.0.3", - "minipass-collect": "^2.0.1", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "p-map": "^7.0.2", - "ssri": "^13.0.0", - "unique-filename": "^5.0.0" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/cacache/node_modules/glob": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.0.tgz", - "integrity": "sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==", - "license": "BlueOak-1.0.0", - "dependencies": { - "minimatch": "^10.1.1", - "minipass": "^7.1.2", - "path-scurry": "^2.0.0" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/cacache/node_modules/lru-cache": { - "version": "11.2.4", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.4.tgz", - "integrity": "sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==", - "license": "BlueOak-1.0.0", - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/cacache/node_modules/minimatch": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", - "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/brace-expansion": "^5.0.0" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/cacache/node_modules/path-scurry": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", - "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^11.0.0", - "minipass": "^7.1.2" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/cacheable-lookup": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", @@ -8970,15 +9002,6 @@ "dev": true, "license": "MIT" }, - "node_modules/data-uri-to-buffer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", - "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", - "license": "MIT", - "engines": { - "node": ">= 12" - } - }, "node_modules/data-view-buffer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", @@ -9356,9 +9379,9 @@ "license": "MIT" }, "node_modules/docker-compose": { - "version": "0.24.8", - "resolved": "https://registry.npmjs.org/docker-compose/-/docker-compose-0.24.8.tgz", - "integrity": "sha512-plizRs/Vf15H+GCVxq2EUvyPK7ei9b/cVesHvjnX4xaXjM9spHe2Ytq0BitndFgvTJ3E3NljPNUEl7BAN43iZw==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/docker-compose/-/docker-compose-1.3.0.tgz", + "integrity": "sha512-7Gevk/5eGD50+eMD+XDnFnOrruFkL0kSd7jEG4cjmqweDSUhB7i0g8is/nBdVpl+Bx338SqIB2GLKm32M+Vs6g==", "dev": true, "license": "MIT", "dependencies": { @@ -10652,29 +10675,6 @@ "node": ">=0.4.0" } }, - "node_modules/fetch-blob": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", - "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - }, - { - "type": "paypal", - "url": "https://paypal.me/jimmywarting" - } - ], - "license": "MIT", - "dependencies": { - "node-domexception": "^1.0.0", - "web-streams-polyfill": "^3.0.3" - }, - "engines": { - "node": "^12.20 || >= 14.13" - } - }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -10885,27 +10885,6 @@ "node": ">= 14.17" } }, - "node_modules/formdata-node": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-6.0.3.tgz", - "integrity": "sha512-8e1++BCiTzUno9v5IZ2J6bv4RU+3UKDmqWUQD0MIMVCd9AdhWkO1gw57oo1mNEX1dMq2EGI+FbWz4B92pscSQg==", - "license": "MIT", - "engines": { - "node": ">= 18" - } - }, - "node_modules/formdata-polyfill": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", - "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", - "license": "MIT", - "dependencies": { - "fetch-blob": "^3.1.2" - }, - "engines": { - "node": ">=12.20.0" - } - }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -11007,18 +10986,6 @@ "node": ">= 10.0.0" } }, - "node_modules/fs-minipass": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", - "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", - "license": "ISC", - "dependencies": { - "minipass": "^7.0.3" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -11898,6 +11865,7 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "devOptional": true, "license": "MIT", "engines": { "node": ">=0.8.19" @@ -13098,12 +13066,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/locko": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/locko/-/locko-1.1.0.tgz", - "integrity": "sha512-pYB2dzRY93fJkg2RIl41AMNgTQftEjyTK9vlPrGOJvuGQsOjb267VJBw15BjiN3RBd1oBoKkOu9E2dRdFKIfAA==", - "license": "MIT" - }, "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", @@ -13751,18 +13713,6 @@ "node": ">=16 || 14 >=14.17" } }, - "node_modules/minipass-collect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz", - "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", - "license": "ISC", - "dependencies": { - "minipass": "^7.0.3" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, "node_modules/minipass-fetch": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz", @@ -13799,6 +13749,7 @@ "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", "license": "ISC", + "optional": true, "dependencies": { "minipass": "^3.0.0" }, @@ -13811,6 +13762,7 @@ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", "license": "ISC", + "optional": true, "dependencies": { "yallist": "^4.0.0" }, @@ -13823,6 +13775,7 @@ "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", "license": "ISC", + "optional": true, "dependencies": { "minipass": "^3.0.0" }, @@ -13835,6 +13788,7 @@ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", "license": "ISC", + "optional": true, "dependencies": { "yallist": "^4.0.0" }, @@ -14207,26 +14161,6 @@ "command-exists": "^1.2.9" } }, - "node_modules/node-domexception": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", - "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", - "deprecated": "Use your platform's native DOMException instead", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - }, - { - "type": "github", - "url": "https://paypal.me/jimmywarting" - } - ], - "license": "MIT", - "engines": { - "node": ">=10.5.0" - } - }, "node_modules/node-fetch": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", @@ -14247,39 +14181,6 @@ } } }, - "node_modules/node-fetch-cache": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/node-fetch-cache/-/node-fetch-cache-5.1.0.tgz", - "integrity": "sha512-4j3rRHNGIKGX7VzXSrBT0bh7+wFuyJv1DxCfCLDHsnDahJWoD9lXe3BzL3BJg/GEIJiM7KIvqVs3byW1GFtRsQ==", - "license": "MIT", - "dependencies": { - "cacache": "^20.0.1", - "formdata-node": "^6.0.3", - "locko": "^1.1.0", - "node-fetch": "3.3.2" - }, - "engines": { - "node": ">=18.19.0" - } - }, - "node_modules/node-fetch-cache/node_modules/node-fetch": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", - "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", - "license": "MIT", - "dependencies": { - "data-uri-to-buffer": "^4.0.0", - "fetch-blob": "^3.1.4", - "formdata-polyfill": "^4.0.10" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/node-fetch" - } - }, "node_modules/node-fetch/node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", @@ -14756,18 +14657,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-map": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.4.tgz", - "integrity": "sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", @@ -14986,9 +14875,9 @@ } }, "node_modules/pg-cloudflare": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.2.7.tgz", - "integrity": "sha512-YgCtzMH0ptvZJslLM1ffsY4EuGaU0cx4XSdXLRFae8bPP4dS5xL1tNB3k2o/N64cHJpwU7dxKli/nZ2lUa5fLg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.3.0.tgz", + "integrity": "sha512-6lswVVSztmHiRtD6I8hw4qP/nDm1EJbKMRhf3HCYaqud7frGysPv7FYJ5noZQdhQtN2xJnimfMtvQq21pdbzyQ==", "license": "MIT", "optional": true }, @@ -15008,18 +14897,18 @@ } }, "node_modules/pg-pool": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.10.1.tgz", - "integrity": "sha512-Tu8jMlcX+9d8+QVzKIvM/uJtp07PKr82IUOYEphaWcoBhIYkoHpLXN3qO59nAI11ripznDsEzEv8nUxBVWajGg==", + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.11.0.tgz", + "integrity": "sha512-MJYfvHwtGp870aeusDh+hg9apvOe2zmpZJpyt+BMtzUWlVqbhFmMK6bOBXLBUPd7iRtIF9fZplDc7KrPN3PN7w==", "license": "MIT", "peerDependencies": { "pg": ">=8.0" } }, "node_modules/pg-protocol": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.10.3.tgz", - "integrity": "sha512-6DIBgBQaTKDJyxnXaLiLR8wBpQQcGWuAESkRBX/t6OwA8YsqP+iVSiond2EDy6Y/dsGk8rh/jtax3js5NeV7JQ==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.11.0.tgz", + "integrity": "sha512-pfsxk2M9M3BuGgDOfuy37VNRRX3jmKgMjcvAcWqNDpZSf4cUmv8HSOl5ViRQFsfARFn0KuUQTgLxVMbNq5NW3g==", "license": "MIT" }, "node_modules/pg-types": { @@ -15339,9 +15228,9 @@ } }, "node_modules/prettier": { - "version": "3.7.4", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.7.4.tgz", - "integrity": "sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==", + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.0.tgz", + "integrity": "sha512-yEPsovQfpxYfgWNhCfECjG5AQaO+K3dp6XERmOepyPDVqcJm+bjyCVO3pmU+nAPe0N5dDvekfGezt/EIiRe1TA==", "dev": true, "license": "MIT", "bin": { @@ -17325,18 +17214,6 @@ "nan": "^2.23.0" } }, - "node_modules/ssri": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-13.0.0.tgz", - "integrity": "sha512-yizwGBpbCn4YomB2lzhZqrHLJoqFGXihNbib3ozhqF/cIp5ue+xSmOQrjNasEE62hFxsCcg/V/z23t4n8jMEng==", - "license": "ISC", - "dependencies": { - "minipass": "^7.0.3" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", @@ -18243,27 +18120,37 @@ } }, "node_modules/testcontainers": { - "version": "10.28.0", - "resolved": "https://registry.npmjs.org/testcontainers/-/testcontainers-10.28.0.tgz", - "integrity": "sha512-1fKrRRCsgAQNkarjHCMKzBKXSJFmzNTiTbhb5E/j5hflRXChEtHvkefjaHlgkNUjfw92/Dq8LTgwQn6RDBFbMg==", + "version": "11.5.0", + "resolved": "https://registry.npmjs.org/testcontainers/-/testcontainers-11.5.0.tgz", + "integrity": "sha512-RPhuRqJ7OZR5e/uw9UEGbxuKjHGXruLlorRRcJvx429xzVapYammBNxmO2PNUW4M5lM/l6NryOY/AVECXaunSw==", "dev": true, "license": "MIT", "dependencies": { "@balena/dockerignore": "^1.0.2", - "@types/dockerode": "^3.3.35", + "@types/dockerode": "^3.3.42", "archiver": "^7.0.1", "async-lock": "^1.4.1", "byline": "^5.0.0", - "debug": "^4.3.5", - "docker-compose": "^0.24.8", - "dockerode": "^4.0.5", + "debug": "^4.4.1", + "docker-compose": "^1.2.0", + "dockerode": "^4.0.7", "get-port": "^7.1.0", "proper-lockfile": "^4.1.2", "properties-reader": "^2.3.0", "ssh-remote-port-forward": "^1.0.4", - "tar-fs": "^3.0.7", + "tar-fs": "^3.1.0", "tmp": "^0.2.3", - "undici": "^5.29.0" + "undici": "^7.12.0" + } + }, + "node_modules/testcontainers/node_modules/undici": { + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.18.2.tgz", + "integrity": "sha512-y+8YjDFzWdQlSE9N5nzKMT3g4a5UBX1HKowfdXh0uvAnTaqqwqB92Jt4UXBAeKekDs5IaDKyJFR4X1gYVCgXcw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.18.1" } }, "node_modules/text-decoder": { @@ -18692,30 +18579,6 @@ "node": ">=4" } }, - "node_modules/unique-filename": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-5.0.0.tgz", - "integrity": "sha512-2RaJTAvAb4owyjllTfXzFClJ7WsGxlykkPvCr9pA//LD9goVq+m4PPAeBgNodGZ7nSrntT/auWpJ6Y5IFXcfjg==", - "license": "ISC", - "dependencies": { - "unique-slug": "^6.0.0" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/unique-slug": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-6.0.0.tgz", - "integrity": "sha512-4Lup7Ezn8W3d52/xBhZBVdx323ckxa7DEvd9kPQHppTkLoJXw6ltrBCyj5pnrxj0qKDxYMJ56CoxNuFCscdTiw==", - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, "node_modules/unique-string": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", @@ -19367,15 +19230,6 @@ "node": ">= 16" } }, - "node_modules/web-streams-polyfill": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", - "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, "node_modules/webidl-conversions": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", @@ -19511,9 +19365,9 @@ "license": "ISC" }, "node_modules/which-typed-array": { - "version": "1.1.19", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", - "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", + "version": "1.1.20", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.20.tgz", + "integrity": "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==", "dev": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 5574a67b0..3bdf7bbb0 100644 --- a/package.json +++ b/package.json @@ -122,7 +122,6 @@ "nanoid": "~3.3.4", "net-snmp": "^3.11.2", "node-cloudflared-tunnel": "~1.0.9", - "node-fetch-cache": "^5.1.0", "node-radius-utils": "~1.2.0", "nodemailer": "~7.0.12", "nostr-tools": "^2.17.0", @@ -207,7 +206,7 @@ "stylelint-config-standard": "~25.0.0", "terser": "~5.15.0", "test": "~3.3.0", - "testcontainers": "^10.13.1", + "testcontainers": "^11.5.0", "typescript": "~4.4.4", "v-pagination-3": "~0.1.7", "vite": "~5.4.15", diff --git a/server/database.js b/server/database.js index 23923679f..a2a0dd20b 100644 --- a/server/database.js +++ b/server/database.js @@ -165,7 +165,7 @@ class Database { * Read the database config * @throws {Error} If the config is invalid * @typedef {string|undefined} envString - * @returns {{type: "sqlite"} | {type:envString, hostname:envString, port:envString, database:envString, username:envString, password:envString}} Database config + * @returns {{type: "sqlite"} | {type:envString, hostname:envString, port:envString, database:envString, username:envString, password:envString, socketPath:envString}} Database config */ static readDBConfig() { let dbConfig; @@ -185,7 +185,7 @@ class Database { /** * @typedef {string|undefined} envString - * @param {{type: "sqlite"} | {type:envString, hostname:envString, port:envString, database:envString, username:envString, password:envString}} dbConfig the database configuration that should be written + * @param {{type: "sqlite"} | {type:envString, hostname:envString, port:envString, database:envString, username:envString, password:envString, socketPath:envString}} dbConfig the database configuration that should be written * @returns {void} */ static writeDBConfig(dbConfig) { @@ -284,6 +284,7 @@ class Database { port: dbConfig.port, user: dbConfig.username, password: dbConfig.password, + socketPath: dbConfig.socketPath, ...(dbConfig.ssl ? { ssl: { @@ -309,6 +310,7 @@ class Database { user: dbConfig.username, password: dbConfig.password, database: dbConfig.dbName, + socketPath: dbConfig.socketPath, timezone: "Z", typeCast: function (field, next) { if (field.type === "DATETIME") { diff --git a/server/model/domain_expiry.js b/server/model/domain_expiry.js index 6d91b5d63..20236f640 100644 --- a/server/model/domain_expiry.js +++ b/server/model/domain_expiry.js @@ -4,33 +4,19 @@ const { log, TYPES_WITH_DOMAIN_EXPIRY_SUPPORT_VIA_FIELD } = require("../../src/u const { parse: parseTld } = require("tldts"); const { setting, setSetting } = require("../util-server"); const { Notification } = require("../notification"); -const { default: NodeFetchCache, MemoryCache } = require("node-fetch-cache"); const TranslatableError = require("../translatable-error"); const dayjs = require("dayjs"); -const cachedFetch = process.env.NODE_ENV - ? NodeFetchCache.create({ - // cache for 8h - cache: new MemoryCache({ ttl: 1000 * 60 * 60 * 8 }), - }) - : fetch; +// Load static RDAP DNS data from local file (auto-updated by CI) +const rdapDnsData = require("./rdap-dns.json"); /** * Find the RDAP server for a given TLD * @param {string} tld TLD - * @returns {Promise} First RDAP server found + * @returns {string|null} First RDAP server found */ -async function getRdapServer(tld) { - let rdapList; - try { - const res = await cachedFetch("https://data.iana.org/rdap/dns.json"); - rdapList = await res.json(); - } catch (error) { - log.debug("rdap", error); - return null; - } - - const services = rdapList["services"] ?? []; +function getRdapServer(tld) { + const services = rdapDnsData["services"] ?? []; const rootTld = tld?.split(".").pop(); if (rootTld) { for (const [tlds, urls] of services) { @@ -50,7 +36,7 @@ async function getRdapServer(tld) { */ async function getRdapDomainExpiryDate(domain) { const tld = DomainExpiry.parseTld(domain).publicSuffix; - const rdapServer = await getRdapServer(tld); + const rdapServer = getRdapServer(tld); if (rdapServer === null) { log.warn("rdap", `No RDAP server found, TLD ${tld} not supported.`); return null; @@ -178,7 +164,7 @@ class DomainExpiry extends BeanModel { const publicSuffix = tld.publicSuffix; const rootTld = publicSuffix.split(".").pop(); - const rdap = await getRdapServer(publicSuffix); + const rdap = getRdapServer(publicSuffix); if (!rdap) { throw new TranslatableError("domain_expiry_unsupported_unsupported_tld_no_rdap_endpoint", { publicSuffix, diff --git a/server/model/incident.js b/server/model/incident.js index a700172bb..ecf400f79 100644 --- a/server/model/incident.js +++ b/server/model/incident.js @@ -1,9 +1,21 @@ const { BeanModel } = require("redbean-node/dist/bean-model"); +const { R } = require("redbean-node"); +const dayjs = require("dayjs"); class Incident extends BeanModel { + /** + * Resolve the incident and mark it as inactive + * @returns {Promise} + */ + async resolve() { + this.active = false; + this.pin = false; + this.last_updated_date = R.isoDateTime(dayjs.utc()); + await R.store(this); + } + /** * Return an object that ready to parse to JSON for public - * Only show necessary data to public * @returns {object} Object ready to parse */ toPublicJSON() { @@ -12,9 +24,11 @@ class Incident extends BeanModel { style: this.style, title: this.title, content: this.content, - pin: this.pin, - createdDate: this.createdDate, - lastUpdatedDate: this.lastUpdatedDate, + pin: !!this.pin, + active: !!this.active, + createdDate: this.created_date, + lastUpdatedDate: this.last_updated_date, + status_page_id: this.status_page_id, }; } } diff --git a/server/model/monitor.js b/server/model/monitor.js index a1cc3251d..75e239bae 100644 --- a/server/model/monitor.js +++ b/server/model/monitor.js @@ -1517,24 +1517,46 @@ class Monitor extends BeanModel { let msg = `[${monitor.name}] [${text}] ${bean.msg}`; + const heartbeatJSON = await bean.toJSONAsync({ decodeResponse: true }); + const monitorData = [{ id: monitor.id, active: monitor.active, name: monitor.name }]; + const preloadData = await Monitor.preparePreloadData(monitorData); + // Prevent if the msg is undefined, notifications such as Discord cannot send out. + if (!heartbeatJSON["msg"]) { + heartbeatJSON["msg"] = "N/A"; + } + + // Also provide the time in server timezone + heartbeatJSON["timezone"] = await UptimeKumaServer.getInstance().getTimezone(); + heartbeatJSON["timezoneOffset"] = UptimeKumaServer.getInstance().getTimezoneOffset(); + heartbeatJSON["localDateTime"] = dayjs + .utc(heartbeatJSON["time"]) + .tz(heartbeatJSON["timezone"]) + .format(SQL_DATETIME_FORMAT); + + // Calculate downtime tracking information when service comes back up + // This makes downtime information available to all notification providers + if (bean.status === UP && monitor.id) { + try { + const lastDownHeartbeat = await R.getRow( + "SELECT time FROM heartbeat WHERE monitor_id = ? AND status = ? ORDER BY time DESC LIMIT 1", + [monitor.id, DOWN] + ); + + if (lastDownHeartbeat && lastDownHeartbeat.time) { + heartbeatJSON["lastDownTime"] = lastDownHeartbeat.time; + } + } catch (error) { + // If we can't calculate downtime, just continue without it + // Silently fail to avoid disrupting notification sending + log.debug( + "monitor", + `[${monitor.name}] Could not calculate downtime information: ${error.message}` + ); + } + } + for (let notification of notificationList) { try { - const heartbeatJSON = await bean.toJSONAsync({ decodeResponse: true }); - const monitorData = [{ id: monitor.id, active: monitor.active, name: monitor.name }]; - const preloadData = await Monitor.preparePreloadData(monitorData); - // Prevent if the msg is undefined, notifications such as Discord cannot send out. - if (!heartbeatJSON["msg"]) { - heartbeatJSON["msg"] = "N/A"; - } - - // Also provide the time in server timezone - heartbeatJSON["timezone"] = await UptimeKumaServer.getInstance().getTimezone(); - heartbeatJSON["timezoneOffset"] = UptimeKumaServer.getInstance().getTimezoneOffset(); - heartbeatJSON["localDateTime"] = dayjs - .utc(heartbeatJSON["time"]) - .tz(heartbeatJSON["timezone"]) - .format(SQL_DATETIME_FORMAT); - await Notification.send( JSON.parse(notification.config), msg, @@ -1736,6 +1758,55 @@ class Monitor extends BeanModel { } } + // Validate JSON fields to prevent invalid JSON from being stored in database + if (this.kafkaProducerBrokers) { + try { + JSON.parse(this.kafkaProducerBrokers); + } catch (e) { + throw new Error(`Kafka Producer Brokers must be valid JSON: ${e.message}`); + } + } + + if (this.kafkaProducerSaslOptions) { + try { + JSON.parse(this.kafkaProducerSaslOptions); + } catch (e) { + throw new Error(`Kafka Producer SASL Options must be valid JSON: ${e.message}`); + } + } + + if (this.rabbitmqNodes) { + try { + JSON.parse(this.rabbitmqNodes); + } catch (e) { + throw new Error(`RabbitMQ Nodes must be valid JSON: ${e.message}`); + } + } + + if (this.conditions) { + try { + JSON.parse(this.conditions); + } catch (e) { + throw new Error(`Conditions must be valid JSON: ${e.message}`); + } + } + + if (this.headers) { + try { + JSON.parse(this.headers); + } catch (e) { + throw new Error(`Headers must be valid JSON: ${e.message}`); + } + } + + if (this.accepted_statuscodes_json) { + try { + JSON.parse(this.accepted_statuscodes_json); + } catch (e) { + throw new Error(`Accepted status codes must be valid JSON: ${e.message}`); + } + } + if (this.type === "ping") { // ping parameters validation if (this.packetSize && (this.packetSize < PING_PACKET_SIZE_MIN || this.packetSize > PING_PACKET_SIZE_MAX)) { diff --git a/server/model/rdap-dns.json b/server/model/rdap-dns.json new file mode 100644 index 000000000..51bbe45d3 --- /dev/null +++ b/server/model/rdap-dns.json @@ -0,0 +1,1194 @@ +{ + "description": "RDAP bootstrap file for Domain Name System registrations", + "publication": "2025-12-11T00:00:01Z", + "services": [ + [["kg"], ["http://rdap.cctld.kg/"]], + [["mg"], ["http://rdap.nic.mg/"]], + [["xn--kpry57d"], ["https://ccrdap.twnic.tw/taiwan/"]], + [["tw"], ["https://ccrdap.twnic.tw/tw/"]], + [["na"], ["https://keetmans.omadhina.co.na/"]], + [["samsung", "xn--cg4bki"], ["https://nic.samsung/rdap/"]], + [ + [ + "ads", + "android", + "app", + "boo", + "cal", + "channel", + "chrome", + "dad", + "day", + "dclk", + "dev", + "docs", + "drive", + "eat", + "esq", + "fly", + "foo", + "gbiz", + "gle", + "gmail", + "goog", + "google", + "guge", + "hangout", + "here", + "how", + "ing", + "map", + "meet", + "meme", + "mov", + "new", + "nexus", + "page", + "phd", + "play", + "prod", + "prof", + "rsvp", + "search", + "soy", + "xn--flw351e", + "xn--q9jyb4c", + "xn--qcka1pmc", + "youtube", + "zip" + ], + ["https://pubapi.registry.google/rdap/"] + ], + [["blog"], ["https://rdap.blog.fury.ca/rdap/"]], + [["ca"], ["https://rdap.ca.fury.ca/rdap/"]], + [["uz"], ["https://rdap.cctld.uz/"]], + [["allfinanz"], ["https://rdap.centralnic.com/allfinanz/"]], + [["art"], ["https://rdap.centralnic.com/art/"]], + [["audio"], ["https://rdap.centralnic.com/audio/"]], + [["auto"], ["https://rdap.centralnic.com/auto/"]], + [["autos"], ["https://rdap.centralnic.com/autos/"]], + [["baby"], ["https://rdap.centralnic.com/baby/"]], + [["beauty"], ["https://rdap.centralnic.com/beauty/"]], + [["best"], ["https://rdap.centralnic.com/best/"]], + [["bmw"], ["https://rdap.centralnic.com/bmw/"]], + [["boats"], ["https://rdap.centralnic.com/boats/"]], + [["bond"], ["https://rdap.centralnic.com/bond/"]], + [["box"], ["https://rdap.centralnic.com/box/"]], + [["build"], ["https://rdap.centralnic.com/build/"]], + [["cam"], ["https://rdap.centralnic.com/cam/"]], + [["car"], ["https://rdap.centralnic.com/car/"]], + [["cars"], ["https://rdap.centralnic.com/cars/"]], + [["case"], ["https://rdap.centralnic.com/case/"]], + [["ceo"], ["https://rdap.centralnic.com/ceo/"]], + [["cfd"], ["https://rdap.centralnic.com/cfd/"]], + [["christmas"], ["https://rdap.centralnic.com/christmas/"]], + [["college"], ["https://rdap.centralnic.com/college/"]], + [["cyou"], ["https://rdap.centralnic.com/cyou/"]], + [["dealer"], ["https://rdap.centralnic.com/dealer/"]], + [["deloitte"], ["https://rdap.centralnic.com/deloitte/"]], + [["dhl"], ["https://rdap.centralnic.com/dhl/"]], + [["diet"], ["https://rdap.centralnic.com/diet/"]], + [["dvag"], ["https://rdap.centralnic.com/dvag/"]], + [["fans"], ["https://rdap.centralnic.com/fans/"]], + [["flowers"], ["https://rdap.centralnic.com/flowers/"]], + [["fm"], ["https://rdap.centralnic.com/fm/"]], + [["fo"], ["https://rdap.centralnic.com/fo/"]], + [["fresenius"], ["https://rdap.centralnic.com/fresenius/"]], + [["frl"], ["https://rdap.centralnic.com/frl/"]], + [["fun"], ["https://rdap.centralnic.com/fun/"]], + [["game"], ["https://rdap.centralnic.com/game/"]], + [["gd"], ["https://rdap.centralnic.com/gd/"]], + [["gent"], ["https://rdap.centralnic.com/gent/"]], + [["guitars"], ["https://rdap.centralnic.com/guitars/"]], + [["hair"], ["https://rdap.centralnic.com/hair/"]], + [["help"], ["https://rdap.centralnic.com/help/"]], + [["homes"], ["https://rdap.centralnic.com/homes/"]], + [["host"], ["https://rdap.centralnic.com/host/"]], + [["hosting"], ["https://rdap.centralnic.com/hosting/"]], + [["icu"], ["https://rdap.centralnic.com/icu/"]], + [["inc"], ["https://rdap.centralnic.com/inc/"]], + [["kfh"], ["https://rdap.centralnic.com/kfh/"]], + [["kpn"], ["https://rdap.centralnic.com/kpn/"]], + [["kred"], ["https://rdap.centralnic.com/kred/"]], + [["lat"], ["https://rdap.centralnic.com/lat/"]], + [["lidl"], ["https://rdap.centralnic.com/lidl/"]], + [["llp"], ["https://rdap.centralnic.com/llp/"]], + [["lol"], ["https://rdap.centralnic.com/lol/"]], + [["london"], ["https://rdap.centralnic.com/london/"]], + [["lpl"], ["https://rdap.centralnic.com/lpl/"]], + [["lplfinancial"], ["https://rdap.centralnic.com/lplfinancial/"]], + [["luxury"], ["https://rdap.centralnic.com/luxury/"]], + [["makeup"], ["https://rdap.centralnic.com/makeup/"]], + [["mini"], ["https://rdap.centralnic.com/mini/"]], + [["mom"], ["https://rdap.centralnic.com/mom/"]], + [["monster"], ["https://rdap.centralnic.com/monster/"]], + [["motorcycles"], ["https://rdap.centralnic.com/motorcycles/"]], + [["nokia"], ["https://rdap.centralnic.com/nokia/"]], + [["online"], ["https://rdap.centralnic.com/online/"]], + [["ooo"], ["https://rdap.centralnic.com/ooo/"]], + [["pics"], ["https://rdap.centralnic.com/pics/"]], + [["pohl"], ["https://rdap.centralnic.com/pohl/"]], + [["press"], ["https://rdap.centralnic.com/press/"]], + [["protection"], ["https://rdap.centralnic.com/protection/"]], + [["pw"], ["https://rdap.centralnic.com/pw/"]], + [["qpon"], ["https://rdap.centralnic.com/qpon/"]], + [["quest"], ["https://rdap.centralnic.com/quest/"]], + [["reit"], ["https://rdap.centralnic.com/reit/"]], + [["rent"], ["https://rdap.centralnic.com/rent/"]], + [["ruhr"], ["https://rdap.centralnic.com/ruhr/"]], + [["saarland"], ["https://rdap.centralnic.com/saarland/"]], + [["sbs"], ["https://rdap.centralnic.com/sbs/"]], + [["schwarz"], ["https://rdap.centralnic.com/schwarz/"]], + [["security"], ["https://rdap.centralnic.com/security/"]], + [["sfr"], ["https://rdap.centralnic.com/sfr/"]], + [["site"], ["https://rdap.centralnic.com/site/"]], + [["skin"], ["https://rdap.centralnic.com/skin/"]], + [["smart"], ["https://rdap.centralnic.com/smart/"]], + [["space"], ["https://rdap.centralnic.com/space/"]], + [["stc"], ["https://rdap.centralnic.com/stc/"]], + [["stcgroup"], ["https://rdap.centralnic.com/stcgroup/"]], + [["storage"], ["https://rdap.centralnic.com/storage/"]], + [["store"], ["https://rdap.centralnic.com/store/"]], + [["tech"], ["https://rdap.centralnic.com/tech/"]], + [["theatre"], ["https://rdap.centralnic.com/theatre/"]], + [["tickets"], ["https://rdap.centralnic.com/tickets/"]], + [["tui"], ["https://rdap.centralnic.com/tui/"]], + [["uno"], ["https://rdap.centralnic.com/uno/"]], + [["vg"], ["https://rdap.centralnic.com/vg/"]], + [["viva"], ["https://rdap.centralnic.com/viva/"]], + [["website"], ["https://rdap.centralnic.com/website/"]], + [["wme"], ["https://rdap.centralnic.com/wme/"]], + [["xn--4gbrim"], ["https://rdap.centralnic.com/xn--4gbrim/"]], + [["xn--ngbe9e0a"], ["https://rdap.centralnic.com/xn--ngbe9e0a/"]], + [["xn--vermgensberater-ctb"], ["https://rdap.centralnic.com/xn--vermgensberater-ctb/"]], + [["xn--vermgensberatung-pwb"], ["https://rdap.centralnic.com/xn--vermgensberatung-pwb/"]], + [["xyz"], ["https://rdap.centralnic.com/xyz/"]], + [["yachts"], ["https://rdap.centralnic.com/yachts/"]], + [["zuerich"], ["https://rdap.centralnic.com/zuerich/"]], + [["jnj"], ["https://rdap.centralnicregistry.com/jnj/"]], + [["xn--55qw42g", "xn--zfr164b"], ["https://rdap.conac.cn/"]], + [["crown"], ["https://rdap.crown.fury.ca/rdap/"]], + [["pl"], ["https://rdap.dns.pl/"]], + [["eco"], ["https://rdap.eco.fury.ca/rdap/"]], + [["fi"], ["https://rdap.fi/rdap/rdap/"]], + [["moscow", "xn--80adxhks"], ["https://rdap.flexireg.net/"]], + [ + [ + "bridgestone", + "brother", + "canon", + "datsun", + "dnp", + "epson", + "firestone", + "fujitsu", + "ggee", + "gmo", + "goldpoint", + "goo", + "hisamitsu", + "hitachi", + "honda", + "hyundai", + "infiniti", + "jcb", + "kddi", + "kia", + "komatsu", + "kyoto", + "lexus", + "lotte", + "mitsubishi", + "nagoya", + "nec", + "nhk", + "nico", + "nissan", + "okinawa", + "otsuka", + "panasonic", + "playstation", + "ricoh", + "ryukyu", + "sharp", + "shop", + "softbank", + "sony", + "suzuki", + "tokyo", + "toray", + "toshiba", + "toyota", + "yodobashi", + "yokohama" + ], + ["https://rdap.gmoregistry.net/rdap/"] + ], + [["bom", "final", "globo", "rio", "uol"], ["https://rdap.gtlds.nic.br/"]], + [["ua"], ["https://rdap.hostmaster.ua/"]], + [["int"], ["https://rdap.iana.org/"]], + [ + [ + "abb", + "abbott", + "abc", + "academy", + "accenture", + "accountants", + "actor", + "aeg", + "aero", + "agakhan", + "agency", + "ai", + "airbus", + "airforce", + "akdn", + "alibaba", + "alipay", + "allstate", + "aol", + "apartments", + "archi", + "army", + "arte", + "asda", + "asia", + "associates", + "attorney", + "auction", + "audi", + "band", + "barclaycard", + "barclays", + "barefoot", + "bargains", + "bbt", + "bcg", + "beats", + "bestbuy", + "bet", + "bike", + "bingo", + "bio", + "black", + "bloomberg", + "blue", + "bm", + "bms", + "bnpparibas", + "boehringer", + "bofa", + "bosch", + "boutique", + "bradesco", + "broker", + "builders", + "business", + "cab", + "cafe", + "camera", + "camp", + "capital", + "cards", + "care", + "careers", + "cash", + "casino", + "catering", + "center", + "cern", + "cfa", + "chanel", + "chat", + "cheap", + "church", + "cipriani", + "citadel", + "city", + "claims", + "cleaning", + "clinic", + "clinique", + "clothing", + "clubmed", + "coach", + "codes", + "coffee", + "community", + "company", + "computer", + "condos", + "construction", + "consulting", + "contact", + "contractors", + "cool", + "coupon", + "coupons", + "credit", + "creditcard", + "crs", + "cruise", + "cruises", + "dance", + "dating", + "deals", + "degree", + "delivery", + "delta", + "democrat", + "dental", + "dentist", + "diamonds", + "digital", + "direct", + "directory", + "discount", + "discover", + "doctor", + "dog", + "domains", + "edeka", + "education", + "email", + "emerck", + "energy", + "engineer", + "engineering", + "enterprises", + "equipment", + "ericsson", + "estate", + "events", + "exchange", + "expert", + "exposed", + "express", + "extraspace", + "fage", + "fail", + "family", + "fan", + "farm", + "fedex", + "ferrari", + "fidelity", + "fido", + "finance", + "financial", + "fish", + "fitness", + "flights", + "florist", + "football", + "forex", + "forsale", + "frogans", + "fund", + "furniture", + "futbol", + "fyi", + "gallery", + "gallo", + "gallup", + "games", + "genting", + "gifts", + "glass", + "global", + "gmbh", + "gold", + "golf", + "goodyear", + "graphics", + "gratis", + "green", + "gripe", + "group", + "guide", + "guru", + "haus", + "hdfc", + "hdfcbank", + "healthcare", + "helsinki", + "hermes", + "hkt", + "hockey", + "holdings", + "holiday", + "homedepot", + "hospital", + "house", + "hughes", + "ice", + "imamat", + "immo", + "immobilien", + "industries", + "info", + "institute", + "insure", + "international", + "investments", + "irish", + "ismaili", + "ist", + "istanbul", + "itv", + "jaguar", + "java", + "jeep", + "jetzt", + "jewelry", + "jio", + "jll", + "juegos", + "juniper", + "kaufen", + "kerryhotels", + "kerryproperties", + "kids", + "kim", + "kitchen", + "kosher", + "kuokgroup", + "lamborghini", + "lamer", + "land", + "landrover", + "lasalle", + "lawyer", + "lds", + "lease", + "lefrak", + "legal", + "lego", + "lgbt", + "life", + "lighting", + "limited", + "limo", + "live", + "llc", + "loans", + "lotto", + "ltd", + "ltda", + "lundbeck", + "maif", + "maison", + "management", + "market", + "marketing", + "markets", + "marriott", + "mba", + "mckinsey", + "media", + "memorial", + "mit", + "mobi", + "moda", + "money", + "mormon", + "mortgage", + "movie", + "mu", + "nab", + "navy", + "network", + "news", + "next", + "nextdirect", + "nikon", + "ninja", + "nissay", + "nowtv", + "nra", + "obi", + "onl", + "oracle", + "orange", + "organic", + "origins", + "partners", + "parts", + "pccw", + "pet", + "photography", + "photos", + "pictet", + "pictures", + "pink", + "pizza", + "place", + "plumbing", + "plus", + "pnc", + "poker", + "post", + "pro", + "productions", + "progressive", + "promo", + "properties", + "pub", + "pwc", + "recipes", + "red", + "redumbrella", + "rehab", + "reise", + "reisen", + "reliance", + "rentals", + "repair", + "report", + "republican", + "restaurant", + "reviews", + "rexroth", + "rich", + "richardli", + "ril", + "rip", + "rocks", + "rogers", + "run", + "rwe", + "sale", + "salon", + "sanofi", + "sarl", + "saxo", + "sbi", + "scholarships", + "school", + "schule", + "sener", + "services", + "sew", + "shangrila", + "shiksha", + "shoes", + "shopping", + "show", + "sina", + "singles", + "ski", + "soccer", + "social", + "software", + "solar", + "solutions", + "song", + "spa", + "srl", + "stada", + "star", + "statebank", + "stockholm", + "studio", + "style", + "supplies", + "supply", + "support", + "surgery", + "systems", + "taobao", + "tatamotors", + "tax", + "taxi", + "team", + "technology", + "temasek", + "tennis", + "thd", + "theater", + "tiaa", + "tienda", + "tips", + "tires", + "tmall", + "today", + "tools", + "tours", + "town", + "toys", + "trading", + "training", + "travel", + "travelers", + "travelersinsurance", + "trv", + "tvs", + "ubank", + "ubs", + "university", + "ups", + "vacations", + "vanguard", + "vegas", + "ventures", + "vet", + "viajes", + "video", + "vig", + "viking", + "villas", + "vin", + "visa", + "vision", + "volvo", + "vote", + "voto", + "voyage", + "watch", + "watches", + "weber", + "weibo", + "weir", + "wine", + "wolterskluwer", + "works", + "world", + "wtf", + "xin", + "xn--1ck2e1b", + "xn--5su34j936bgsg", + "xn--5tzm5g", + "xn--6frz82g", + "xn--9krt00a", + "xn--b4w605ferd", + "xn--bck1b9a5dre4c", + "xn--cck2b3b", + "xn--czrs0t", + "xn--eckvdtc9d", + "xn--fct429k", + "xn--fjq720a", + "xn--fzys8d69uvgm", + "xn--gckr3f0f", + "xn--gk3at1e", + "xn--jvr189m", + "xn--rovu88b", + "xn--unup4y", + "xn--vhquv", + "xn--w4r85el8fhu5dnra", + "xn--w4rs40l", + "yahoo", + "zara", + "zero", + "zone" + ], + ["https://rdap.identitydigital.services/rdap/"] + ], + [["is"], ["https://rdap.isnic.is/rdap/"]], + [["ke"], ["https://rdap.kenic.or.ke/"]], + [["kiwi"], ["https://rdap.kiwi.fury.ca/rdap/"]], + [["lb"], ["https://rdap.lbdr.org.lb/"]], + [["mls"], ["https://rdap.mls.fury.ca/rdap/"]], + [ + ["blockbuster", "data", "dish", "dot", "dtv", "dvr", "latino", "mobile", "ollo", "ott", "phone", "sling"], + ["https://rdap.mobile-registry.com/rdap/"] + ], + [["aaa"], ["https://rdap.nic.aaa/"]], + [["aarp"], ["https://rdap.nic.aarp/"]], + [["able"], ["https://rdap.nic.able/"]], + [["abogado"], ["https://rdap.nic.abogado/"]], + [["abudhabi"], ["https://rdap.nic.abudhabi/"]], + [["accountant"], ["https://rdap.nic.accountant/"]], + [["aco"], ["https://rdap.nic.aco/"]], + [["ad"], ["https://rdap.nic.ad/"]], + [["adult"], ["https://rdap.nic.adult/"]], + [["aetna"], ["https://rdap.nic.aetna/"]], + [["afl"], ["https://rdap.nic.afl/"]], + [["africa"], ["https://rdap.nic.africa/rdap/"]], + [["aig"], ["https://rdap.nic.aig/"]], + [["airtel"], ["https://rdap.nic.airtel/"]], + [["ally"], ["https://rdap.nic.ally/"]], + [["alsace"], ["https://rdap.nic.alsace/"]], + [["alstom"], ["https://rdap.nic.alstom/"]], + [["americanexpress"], ["https://rdap.nic.americanexpress/"]], + [["americanfamily"], ["https://rdap.nic.americanfamily/"]], + [["amex"], ["https://rdap.nic.amex/"]], + [["amfam"], ["https://rdap.nic.amfam/"]], + [["amica"], ["https://rdap.nic.amica/"]], + [["amsterdam"], ["https://rdap.nic.amsterdam/"]], + [["analytics"], ["https://rdap.nic.analytics/"]], + [["anz"], ["https://rdap.nic.anz/"]], + [["apple"], ["https://rdap.nic.apple/"]], + [["aquarelle"], ["https://rdap.nic.aquarelle/"]], + [["ar"], ["https://rdap.nic.ar/"]], + [["arab"], ["https://rdap.nic.arab/"]], + [["aramco"], ["https://rdap.nic.aramco/"]], + [["as"], ["https://rdap.nic.as/"]], + [["athleta"], ["https://rdap.nic.athleta/"]], + [["auspost"], ["https://rdap.nic.auspost/"]], + [["axa"], ["https://rdap.nic.axa/"]], + [["banamex"], ["https://rdap.nic.banamex/"]], + [["bank"], ["https://rdap.nic.bank/"]], + [["barcelona"], ["https://rdap.nic.barcelona/"]], + [["baseball"], ["https://rdap.nic.baseball/"]], + [["basketball"], ["https://rdap.nic.basketball/"]], + [["bauhaus"], ["https://rdap.nic.bauhaus/"]], + [["bayern"], ["https://rdap.nic.bayern/"]], + [["bcn"], ["https://rdap.nic.bcn/"]], + [["beer"], ["https://rdap.nic.beer/"]], + [["berlin"], ["https://rdap.nic.berlin/v1/"]], + [["bharti"], ["https://rdap.nic.bharti/"]], + [["bible"], ["https://rdap.nic.bible/"]], + [["bid"], ["https://rdap.nic.bid/"]], + [["biz"], ["https://rdap.nic.biz/"]], + [["blackfriday"], ["https://rdap.nic.blackfriday/"]], + [["booking"], ["https://rdap.nic.booking/"]], + [["bostik"], ["https://rdap.nic.bostik/"]], + [["boston"], ["https://rdap.nic.boston/"]], + [["brussels"], ["https://rdap.nic.brussels/"]], + [["buzz"], ["https://rdap.nic.buzz/"]], + [["bzh"], ["https://rdap.nic.bzh/"]], + [["calvinklein"], ["https://rdap.nic.calvinklein/"]], + [["capetown"], ["https://rdap.nic.capetown/rdap/"]], + [["capitalone"], ["https://rdap.nic.capitalone/"]], + [["caravan"], ["https://rdap.nic.caravan/"]], + [["casa"], ["https://rdap.nic.casa/"]], + [["cat"], ["https://rdap.nic.cat/"]], + [["catholic"], ["https://rdap.nic.catholic/"]], + [["cba"], ["https://rdap.nic.cba/"]], + [["cbn"], ["https://rdap.nic.cbn/"]], + [["cbre"], ["https://rdap.nic.cbre/"]], + [["chase"], ["https://rdap.nic.chase/"]], + [["chintai"], ["https://rdap.nic.chintai/"]], + [["cisco"], ["https://rdap.nic.cisco/"]], + [["citi"], ["https://rdap.nic.citi/"]], + [["club"], ["https://rdap.nic.club/"]], + [["cm"], ["https://rdap.nic.cm/"]], + [["commbank"], ["https://rdap.nic.commbank/"]], + [["compare"], ["https://rdap.nic.compare/"]], + [["cooking"], ["https://rdap.nic.cooking/"]], + [["corsica"], ["https://rdap.nic.corsica/"]], + [["courses"], ["https://rdap.nic.courses/"]], + [["cpa"], ["https://rdap.nic.cpa/"]], + [["cr"], ["https://rdap.nic.cr/"]], + [["cricket"], ["https://rdap.nic.cricket/"]], + [["cuisinella"], ["https://rdap.nic.cuisinella/"]], + [["cv"], ["https://rdap.nic.cv/"]], + [["cx"], ["https://rdap.nic.cx/"]], + [["cz"], ["https://rdap.nic.cz/"]], + [["date"], ["https://rdap.nic.date/"]], + [["dds"], ["https://rdap.nic.dds/"]], + [["dell"], ["https://rdap.nic.dell/"]], + [["design"], ["https://rdap.nic.design/"]], + [["download"], ["https://rdap.nic.download/"]], + [["dubai"], ["https://rdap.nic.dubai/"]], + [["dupont"], ["https://rdap.nic.dupont/"]], + [["durban"], ["https://rdap.nic.durban/rdap/"]], + [["earth"], ["https://rdap.nic.earth/"]], + [["erni"], ["https://rdap.nic.erni/"]], + [["eurovision"], ["https://rdap.nic.eurovision/"]], + [["eus"], ["https://rdap.nic.eus/"]], + [["faith"], ["https://rdap.nic.faith/"]], + [["farmers"], ["https://rdap.nic.farmers/"]], + [["fashion"], ["https://rdap.nic.fashion/"]], + [["ferrero"], ["https://rdap.nic.ferrero/"]], + [["film"], ["https://rdap.nic.film/"]], + [["firmdale"], ["https://rdap.nic.firmdale/"]], + [["fishing"], ["https://rdap.nic.fishing/"]], + [["fit"], ["https://rdap.nic.fit/"]], + [["flickr"], ["https://rdap.nic.flickr/"]], + [["flir"], ["https://rdap.nic.flir/"]], + [["ford"], ["https://rdap.nic.ford/"]], + [["fox"], ["https://rdap.nic.fox/"]], + [["fr"], ["https://rdap.nic.fr/"]], + [["frontier"], ["https://rdap.nic.frontier/"]], + [["ftr"], ["https://rdap.nic.ftr/"]], + [["gal"], ["https://rdap.nic.gal/"]], + [["gap"], ["https://rdap.nic.gap/"]], + [["garden"], ["https://rdap.nic.garden/"]], + [["gay"], ["https://rdap.nic.gay/"]], + [["gdn"], ["https://rdap.nic.gdn/"]], + [["gea"], ["https://rdap.nic.gea/"]], + [["george"], ["https://rdap.nic.george/"]], + [["gmx"], ["https://rdap.nic.gmx/"]], + [["godaddy"], ["https://rdap.nic.godaddy/"]], + [["gov"], ["https://rdap.nic.gov/rdap/"]], + [["grainger"], ["https://rdap.nic.grainger/"]], + [["grocery"], ["https://rdap.nic.grocery/"]], + [["gs"], ["https://rdap.nic.gs/"]], + [["hamburg"], ["https://rdap.nic.hamburg/v1/"]], + [["hbo"], ["https://rdap.nic.hbo/"]], + [["health"], ["https://rdap.nic.health/"]], + [["hn"], ["https://rdap.nic.hn/"]], + [["homegoods"], ["https://rdap.nic.homegoods/"]], + [["homesense"], ["https://rdap.nic.homesense/"]], + [["horse"], ["https://rdap.nic.horse/"]], + [["hotels"], ["https://rdap.nic.hotels/"]], + [["hsbc"], ["https://rdap.nic.hsbc/"]], + [["ht"], ["https://rdap.nic.ht/"]], + [["hyatt"], ["https://rdap.nic.hyatt/"]], + [["ibm"], ["https://rdap.nic.ibm/"]], + [["ifm"], ["https://rdap.nic.ifm/"]], + [["ikano"], ["https://rdap.nic.ikano/v1/"]], + [["ink"], ["https://rdap.nic.ink/"]], + [["insurance"], ["https://rdap.nic.insurance/"]], + [["intuit"], ["https://rdap.nic.intuit/"]], + [["ipiranga"], ["https://rdap.nic.ipiranga/"]], + [["itau"], ["https://rdap.nic.itau/"]], + [["jmp"], ["https://rdap.nic.jmp/"]], + [["joburg"], ["https://rdap.nic.joburg/rdap/"]], + [["jpmorgan"], ["https://rdap.nic.jpmorgan/"]], + [["jprs"], ["https://rdap.nic.jprs/rdap/"]], + [["kpmg"], ["https://rdap.nic.kpmg/"]], + [["krd"], ["https://rdap.nic.krd/"]], + [["lacaixa"], ["https://rdap.nic.lacaixa/"]], + [["lanxess"], ["https://rdap.nic.lanxess/"]], + [["latrobe"], ["https://rdap.nic.latrobe/"]], + [["law"], ["https://rdap.nic.law/"]], + [["leclerc"], ["https://rdap.nic.leclerc/"]], + [["lifeinsurance"], ["https://rdap.nic.lifeinsurance/"]], + [["lilly"], ["https://rdap.nic.lilly/"]], + [["lincoln"], ["https://rdap.nic.lincoln/"]], + [["loan"], ["https://rdap.nic.loan/"]], + [["locker"], ["https://rdap.nic.locker/rdap/"]], + [["luxe"], ["https://rdap.nic.luxe/"]], + [["ly"], ["https://rdap.nic.ly/"]], + [["madrid"], ["https://rdap.nic.madrid/"]], + [["man"], ["https://rdap.nic.man/"]], + [["mango"], ["https://rdap.nic.mango/"]], + [["marshalls"], ["https://rdap.nic.marshalls/"]], + [["mattel"], ["https://rdap.nic.mattel/"]], + [["melbourne"], ["https://rdap.nic.melbourne/"]], + [["men"], ["https://rdap.nic.men/"]], + [["menu"], ["https://rdap.nic.menu/"]], + [["merckmsd"], ["https://rdap.nic.merckmsd/"]], + [["miami"], ["https://rdap.nic.miami/"]], + [["mint"], ["https://rdap.nic.mint/"]], + [["ml"], ["https://rdap.nic.ml/"]], + [["mlb"], ["https://rdap.nic.mlb/"]], + [["mma"], ["https://rdap.nic.mma/"]], + [["moe"], ["https://rdap.nic.moe/"]], + [["monash"], ["https://rdap.nic.monash/"]], + [["moto"], ["https://rdap.nic.moto/"]], + [["ms"], ["https://rdap.nic.ms/"]], + [["msd"], ["https://rdap.nic.msd/"]], + [["museum"], ["https://rdap.nic.museum/"]], + [["nba"], ["https://rdap.nic.nba/"]], + [["netbank"], ["https://rdap.nic.netbank/"]], + [["netflix"], ["https://rdap.nic.netflix/"]], + [["neustar"], ["https://rdap.nic.neustar/"]], + [["nf"], ["https://rdap.nic.nf/"]], + [["nfl"], ["https://rdap.nic.nfl/"]], + [["nike"], ["https://rdap.nic.nike/"]], + [["norton"], ["https://rdap.nic.norton/"]], + [["nrw"], ["https://rdap.nic.nrw/"]], + [["ntt"], ["https://rdap.nic.ntt/rdap/"]], + [["nyc"], ["https://rdap.nic.nyc/"]], + [["olayan"], ["https://rdap.nic.olayan/"]], + [["olayangroup"], ["https://rdap.nic.olayangroup/"]], + [["one"], ["https://rdap.nic.one/"]], + [["open"], ["https://rdap.nic.open/"]], + [["osaka"], ["https://rdap.nic.osaka/"]], + [["ovh"], ["https://rdap.nic.ovh/"]], + [["paris"], ["https://rdap.nic.paris/"]], + [["party"], ["https://rdap.nic.party/"]], + [["pfizer"], ["https://rdap.nic.pfizer/"]], + [["pg"], ["https://rdap.nic.pg/"]], + [["philips"], ["https://rdap.nic.philips/"]], + [["photo"], ["https://rdap.nic.photo/"]], + [["physio"], ["https://rdap.nic.physio/"]], + [["ping"], ["https://rdap.nic.ping/"]], + [["pm"], ["https://rdap.nic.pm/"]], + [["politie"], ["https://rdap.nic.politie/"]], + [["porn"], ["https://rdap.nic.porn/"]], + [["praxi"], ["https://rdap.nic.praxi/"]], + [["pru"], ["https://rdap.nic.pru/"]], + [["prudential"], ["https://rdap.nic.prudential/"]], + [["quebec"], ["https://rdap.nic.quebec/"]], + [["racing"], ["https://rdap.nic.racing/"]], + [["radio"], ["https://rdap.nic.radio/"]], + [["re"], ["https://rdap.nic.re/"]], + [["review"], ["https://rdap.nic.review/"]], + [["rodeo"], ["https://rdap.nic.rodeo/"]], + [["rugby"], ["https://rdap.nic.rugby/"]], + [["safety"], ["https://rdap.nic.safety/"]], + [["sakura"], ["https://rdap.nic.sakura/rdap/"]], + [["samsclub"], ["https://rdap.nic.samsclub/"]], + [["sandvik"], ["https://rdap.nic.sandvik/"]], + [["sandvikcoromant"], ["https://rdap.nic.sandvikcoromant/"]], + [["sap"], ["https://rdap.nic.sap/"]], + [["sas"], ["https://rdap.nic.sas/"]], + [["scb"], ["https://rdap.nic.scb/"]], + [["schaeffler"], ["https://rdap.nic.schaeffler/"]], + [["schmidt"], ["https://rdap.nic.schmidt/"]], + [["science"], ["https://rdap.nic.science/"]], + [["scot"], ["https://rdap.nic.scot/"]], + [["sd"], ["https://rdap.nic.sd/"]], + [["seat"], ["https://rdap.nic.seat/"]], + [["seek"], ["https://rdap.nic.seek/"]], + [["select"], ["https://rdap.nic.select/"]], + [["seven"], ["https://rdap.nic.seven/"]], + [["sex"], ["https://rdap.nic.sex/"]], + [["sncf"], ["https://rdap.nic.sncf/"]], + [["sport"], ["https://rdap.nic.sport/"]], + [["ss"], ["https://rdap.nic.ss/"]], + [["staples"], ["https://rdap.nic.staples/"]], + [["statefarm"], ["https://rdap.nic.statefarm/"]], + [["stream"], ["https://rdap.nic.stream/"]], + [["study"], ["https://rdap.nic.study/"]], + [["sucks"], ["https://rdap.nic.sucks/"]], + [["surf"], ["https://rdap.nic.surf/"]], + [["swiss"], ["https://rdap.nic.swiss/"]], + [["sydney"], ["https://rdap.nic.sydney/"]], + [["tab"], ["https://rdap.nic.tab/"]], + [["taipei"], ["https://rdap.nic.taipei/"]], + [["target"], ["https://rdap.nic.target/"]], + [["tattoo"], ["https://rdap.nic.tattoo/"]], + [["tdk"], ["https://rdap.nic.tdk/"]], + [["tel"], ["https://rdap.nic.tel/"]], + [["teva"], ["https://rdap.nic.teva/"]], + [["tf"], ["https://rdap.nic.tf/"]], + [["tjmaxx"], ["https://rdap.nic.tjmaxx/"]], + [["tjx"], ["https://rdap.nic.tjx/"]], + [["tkmaxx"], ["https://rdap.nic.tkmaxx/"]], + [["total"], ["https://rdap.nic.total/"]], + [["trade"], ["https://rdap.nic.trade/"]], + [["tube"], ["https://rdap.nic.tube/"]], + [["tv"], ["https://rdap.nic.tv/"]], + [["versicherung"], ["https://rdap.nic.versicherung/v1/"]], + [["vi"], ["https://rdap.nic.vi/"]], + [["vip"], ["https://rdap.nic.vip/"]], + [["vivo"], ["https://rdap.nic.vivo/"]], + [["vlaanderen"], ["https://rdap.nic.vlaanderen/"]], + [["vodka"], ["https://rdap.nic.vodka/"]], + [["voting"], ["https://rdap.nic.voting/"]], + [["walmart"], ["https://rdap.nic.walmart/"]], + [["walter"], ["https://rdap.nic.walter/"]], + [["weather"], ["https://rdap.nic.weather/"]], + [["weatherchannel"], ["https://rdap.nic.weatherchannel/"]], + [["webcam"], ["https://rdap.nic.webcam/"]], + [["wedding"], ["https://rdap.nic.wedding/"]], + [["wf"], ["https://rdap.nic.wf/"]], + [["whoswho"], ["https://rdap.nic.whoswho/"]], + [["wiki"], ["https://rdap.nic.wiki/"]], + [["williamhill"], ["https://rdap.nic.williamhill/"]], + [["win"], ["https://rdap.nic.win/"]], + [["winners"], ["https://rdap.nic.winners/"]], + [["woodside"], ["https://rdap.nic.woodside/"]], + [["work"], ["https://rdap.nic.work/"]], + [["wtc"], ["https://rdap.nic.wtc/"]], + [["xerox"], ["https://rdap.nic.xerox/"]], + [["xn--80aqecdr1a"], ["https://rdap.nic.xn--80aqecdr1a/"]], + [["xn--80asehdb"], ["https://rdap.nic.xn--80asehdb/"]], + [["xn--80aswg"], ["https://rdap.nic.xn--80aswg/"]], + [["xn--g2xx48c"], ["https://rdap.nic.xn--g2xx48c/"]], + [["xn--kcrx77d1x4a"], ["https://rdap.nic.xn--kcrx77d1x4a/"]], + [["xn--mgba3a3ejt"], ["https://rdap.nic.xn--mgba3a3ejt/"]], + [["xn--mgba7c0bbn0a"], ["https://rdap.nic.xn--mgba7c0bbn0a/"]], + [["xn--mgbab2bd"], ["https://rdap.nic.xn--mgbab2bd/"]], + [["xn--mgbca7dzdo"], ["https://rdap.nic.xn--mgbca7dzdo/"]], + [["xn--mgbi4ecexp"], ["https://rdap.nic.xn--mgbi4ecexp/"]], + [["xn--ngbc5azd"], ["https://rdap.nic.xn--ngbc5azd/"]], + [["xn--ngbrx"], ["https://rdap.nic.xn--ngbrx/"]], + [["xn--p1acf"], ["https://rdap.nic.xn--p1acf/"]], + [["xn--tiq49xqyj"], ["https://rdap.nic.xn--tiq49xqyj/"]], + [["xxx"], ["https://rdap.nic.xxx/"]], + [["yandex"], ["https://rdap.nic.yandex/rdap/"]], + [["yoga"], ["https://rdap.nic.yoga/"]], + [["yt"], ["https://rdap.nic.yt/"]], + [["zm"], ["https://rdap.nic.zm/"]], + [["in"], ["https://rdap.nixiregistry.in/rdap/"]], + [["abbvie"], ["https://rdap.nominet.uk/abbvie/"]], + [["amazon"], ["https://rdap.nominet.uk/amazon/"]], + [["audible"], ["https://rdap.nominet.uk/audible/"]], + [["author"], ["https://rdap.nominet.uk/author/"]], + [["aws"], ["https://rdap.nominet.uk/aws/"]], + [["azure"], ["https://rdap.nominet.uk/azure/"]], + [["bbc"], ["https://rdap.nominet.uk/bbc/"]], + [["bbva"], ["https://rdap.nominet.uk/bbva/"]], + [["bing"], ["https://rdap.nominet.uk/bing/"]], + [["book"], ["https://rdap.nominet.uk/book/"]], + [["bot"], ["https://rdap.nominet.uk/bot/"]], + [["broadway"], ["https://rdap.nominet.uk/broadway/"]], + [["buy"], ["https://rdap.nominet.uk/buy/"]], + [["call"], ["https://rdap.nominet.uk/call/"]], + [["career"], ["https://rdap.nominet.uk/career/"]], + [["circle"], ["https://rdap.nominet.uk/circle/"]], + [["cymru"], ["https://rdap.nominet.uk/cymru/"]], + [["deal"], ["https://rdap.nominet.uk/deal/"]], + [["desi"], ["https://rdap.nominet.uk/desi/"]], + [["fairwinds"], ["https://rdap.nominet.uk/fairwinds/"]], + [["fast"], ["https://rdap.nominet.uk/fast/"]], + [["fire"], ["https://rdap.nominet.uk/fire/"]], + [["free"], ["https://rdap.nominet.uk/free/"]], + [["gop"], ["https://rdap.nominet.uk/gop/"]], + [["got"], ["https://rdap.nominet.uk/got/"]], + [["gucci"], ["https://rdap.nominet.uk/gucci/"]], + [["hot"], ["https://rdap.nominet.uk/hot/"]], + [["hotmail"], ["https://rdap.nominet.uk/hotmail/"]], + [["ieee"], ["https://rdap.nominet.uk/ieee/"]], + [["imdb"], ["https://rdap.nominet.uk/imdb/"]], + [["jobs"], ["https://rdap.nominet.uk/jobs/"]], + [["jot"], ["https://rdap.nominet.uk/jot/"]], + [["joy"], ["https://rdap.nominet.uk/joy/"]], + [["kindle"], ["https://rdap.nominet.uk/kindle/"]], + [["like"], ["https://rdap.nominet.uk/like/"]], + [["locus"], ["https://rdap.nominet.uk/locus/"]], + [["med"], ["https://rdap.nominet.uk/med/"]], + [["microsoft"], ["https://rdap.nominet.uk/microsoft/"]], + [["moi"], ["https://rdap.nominet.uk/moi/"]], + [["mtn"], ["https://rdap.nominet.uk/mtn/"]], + [["now"], ["https://rdap.nominet.uk/now/"]], + [["nowruz"], ["https://rdap.nominet.uk/nowruz/"]], + [["office"], ["https://rdap.nominet.uk/office/"]], + [["omega"], ["https://rdap.nominet.uk/omega/"]], + [["pars"], ["https://rdap.nominet.uk/pars/"]], + [["pay"], ["https://rdap.nominet.uk/pay/"]], + [["pharmacy"], ["https://rdap.nominet.uk/pharmacy/"]], + [["pin"], ["https://rdap.nominet.uk/pin/"]], + [["pioneer"], ["https://rdap.nominet.uk/pioneer/"]], + [["pn"], ["https://rdap.nominet.uk/pn/"]], + [["prime"], ["https://rdap.nominet.uk/prime/"]], + [["read"], ["https://rdap.nominet.uk/read/"]], + [["realestate"], ["https://rdap.nominet.uk/realestate/"]], + [["realtor"], ["https://rdap.nominet.uk/realtor/"]], + [["room"], ["https://rdap.nominet.uk/room/"]], + [["safe"], ["https://rdap.nominet.uk/safe/"]], + [["save"], ["https://rdap.nominet.uk/save/"]], + [["secure"], ["https://rdap.nominet.uk/secure/"]], + [["shell"], ["https://rdap.nominet.uk/shell/"]], + [["shia"], ["https://rdap.nominet.uk/shia/"]], + [["silk"], ["https://rdap.nominet.uk/silk/"]], + [["sky"], ["https://rdap.nominet.uk/sky/"]], + [["skype"], ["https://rdap.nominet.uk/skype/"]], + [["smile"], ["https://rdap.nominet.uk/smile/"]], + [["spot"], ["https://rdap.nominet.uk/spot/"]], + [["swatch"], ["https://rdap.nominet.uk/swatch/"]], + [["talk"], ["https://rdap.nominet.uk/talk/"]], + [["tci"], ["https://rdap.nominet.uk/tci/"]], + [["tunes"], ["https://rdap.nominet.uk/tunes/"]], + [["tushu"], ["https://rdap.nominet.uk/tushu/"]], + [["uk"], ["https://rdap.nominet.uk/uk/"]], + [["virgin"], ["https://rdap.nominet.uk/virgin/"]], + [["wales"], ["https://rdap.nominet.uk/wales/"]], + [["wanggou"], ["https://rdap.nominet.uk/wanggou/"]], + [["wed"], ["https://rdap.nominet.uk/wed/"]], + [["windows"], ["https://rdap.nominet.uk/windows/"]], + [["wow"], ["https://rdap.nominet.uk/wow/"]], + [["xbox"], ["https://rdap.nominet.uk/xbox/"]], + [["xn--cckwcxetd"], ["https://rdap.nominet.uk/xn--cckwcxetd/"]], + [["xn--jlq480n2rg"], ["https://rdap.nominet.uk/xn--jlq480n2rg/"]], + [["xn--mgbt3dhd"], ["https://rdap.nominet.uk/xn--mgbt3dhd/"]], + [["yamaxun"], ["https://rdap.nominet.uk/yamaxun/"]], + [["you"], ["https://rdap.nominet.uk/you/"]], + [["zappos"], ["https://rdap.nominet.uk/zappos/"]], + [["no"], ["https://rdap.norid.no/"]], + [["id"], ["https://rdap.pandi.id/rdap/"]], + [ + [ + "charity", + "foundation", + "gives", + "giving", + "ngo", + "ong", + "org", + "xn--c1avg", + "xn--i1b6b1a6a2e", + "xn--nqv7f", + "xn--nqv7fs00ema" + ], + ["https://rdap.publicinterestregistry.org/rdap/"] + ], + [["si"], ["https://rdap.register.si/"]], + [["br"], ["https://rdap.registro.br/"]], + [["bar", "rest"], ["https://rdap.registry.bar/rdap/"]], + [["feedback", "forum", "observer", "pid", "realty"], ["https://rdap.registry.click/rdap/"]], + [["cloud"], ["https://rdap.registry.cloud/rdap/"]], + [["coop", "creditunion"], ["https://rdap.registry.coop/rdap/"]], + [["ec"], ["https://rdap.registry.ec/"]], + [["gy"], ["https://rdap.registry.gy/"]], + [["hiphop"], ["https://rdap.registry.hiphop/rdap/"]], + [["love"], ["https://rdap.registry.love/rdap/"]], + [["music"], ["https://rdap.registryservices.music/rdap/"]], + [["rw"], ["https://rdap.ricta.org.rw/"]], + [["cologne", "koeln", "tirol", "wien"], ["https://rdap.ryce-rsp.com/rdap/"]], + [["nl"], ["https://rdap.sidn.nl/"]], + [["anquan", "shouji", "xihuan", "xn--vuq861b", "yun"], ["https://rdap.teleinfo.cn/"]], + [["xn--3ds443g"], ["https://rdap.teleinfo.cn/xn--3ds443g/"]], + [["xn--fiq228c5hs"], ["https://rdap.teleinfo.cn/xn--fiq228c5hs/"]], + [["xn--kput3i"], ["https://rdap.teleinfo.cn/xn--kput3i/"]], + [["xn--nyqy26a"], ["https://rdap.teleinfo.cn/xn--nyqy26a/"]], + [["xn--rhqv96g"], ["https://rdap.teleinfo.cn/xn--rhqv96g/"]], + [["th", "xn--o3cw4h"], ["https://rdap.thains.co.th/"]], + [["to"], ["https://rdap.tonicregistry.to/rdap/"]], + [ + [ + "click", + "country", + "diy", + "food", + "gift", + "hiv", + "lifestyle", + "link", + "living", + "property", + "sexy", + "trust", + "vana" + ], + ["https://rdap.tucowsregistry.net/rdap/"] + ], + [["xn--mxtq1m"], ["https://rdap.twnic.tw/rdap/"]], + [["com"], ["https://rdap.verisign.com/com/v1/"]], + [["net"], ["https://rdap.verisign.com/net/v1/"]], + [["ye"], ["https://rdap.y.net.ye/"]], + [["xn--45q11c"], ["https://rdap.zdnsgtld.com/XN--45Q11C/"]], + [["xn--efvy88h"], ["https://rdap.zdnsgtld.com/XN--EFVY88H/"]], + [["baidu"], ["https://rdap.zdnsgtld.com/baidu/"]], + [["citic"], ["https://rdap.zdnsgtld.com/citic/"]], + [["icbc"], ["https://rdap.zdnsgtld.com/icbc/"]], + [["ren"], ["https://rdap.zdnsgtld.com/ren/"]], + [["sohu"], ["https://rdap.zdnsgtld.com/sohu/"]], + [["top"], ["https://rdap.zdnsgtld.com/top/"]], + [["unicom"], ["https://rdap.zdnsgtld.com/unicom/"]], + [["wang"], ["https://rdap.zdnsgtld.com/wang/"]], + [["xn--30rr7y"], ["https://rdap.zdnsgtld.com/xn--30rr7y/"]], + [["xn--3bst00m"], ["https://rdap.zdnsgtld.com/xn--3bst00m/"]], + [["xn--6qq986b3xl"], ["https://rdap.zdnsgtld.com/xn--6qq986b3xl/"]], + [["xn--8y0a063a"], ["https://rdap.zdnsgtld.com/xn--8y0a063a/"]], + [["xn--9et52u"], ["https://rdap.zdnsgtld.com/xn--9et52u/"]], + [["xn--czr694b"], ["https://rdap.zdnsgtld.com/xn--czr694b/"]], + [["xn--czru2d"], ["https://rdap.zdnsgtld.com/xn--czru2d/"]], + [["xn--fiq64b"], ["https://rdap.zdnsgtld.com/xn--fiq64b/"]], + [["xn--hxt814e"], ["https://rdap.zdnsgtld.com/xn--hxt814e/"]], + [["xn--imr513n"], ["https://rdap.zdnsgtld.com/xn--imr513n/"]], + [["xn--otu796d"], ["https://rdap.zdnsgtld.com/xn--otu796d/"]], + [["xn--ses554g"], ["https://rdap.zdnsgtld.com/xn--ses554g/"]], + [["xn--1qqw23a", "xn--55qx5d", "xn--io0a7i", "xn--xhq521b"], ["https://restwhois.ngtld.cn/"]], + [["cc"], ["https://tld-rdap.verisign.com/cc/v1/"]], + [["comsec"], ["https://tld-rdap.verisign.com/comsec/v1/"]], + [["name"], ["https://tld-rdap.verisign.com/name/v1/"]], + [["verisign"], ["https://tld-rdap.verisign.com/verisign/v1/"]], + [["xn--11b4c3d"], ["https://tld-rdap.verisign.com/xn--11b4c3d/v1/"]], + [["xn--3pxu8k"], ["https://tld-rdap.verisign.com/xn--3pxu8k/v1/"]], + [["xn--42c2d9a"], ["https://tld-rdap.verisign.com/xn--42c2d9a/v1/"]], + [["xn--9dbq2a"], ["https://tld-rdap.verisign.com/xn--9dbq2a/v1/"]], + [["xn--c2br7g"], ["https://tld-rdap.verisign.com/xn--c2br7g/v1/"]], + [["xn--fhbei"], ["https://tld-rdap.verisign.com/xn--fhbei/v1/"]], + [["xn--j1aef"], ["https://tld-rdap.verisign.com/xn--j1aef/v1/"]], + [["xn--mk1bu44c"], ["https://tld-rdap.verisign.com/xn--mk1bu44c/v1/"]], + [["xn--pssy2u"], ["https://tld-rdap.verisign.com/xn--pssy2u/v1/"]], + [["xn--t60b56a"], ["https://tld-rdap.verisign.com/xn--t60b56a/v1/"]], + [["xn--tckwe"], ["https://tld-rdap.verisign.com/xn--tckwe/v1/"]], + [["ky"], ["https://whois.kyregistry.ky/rdap/"]], + [["mtr"], ["https://whois.nic.mtr/rdap/"]], + [["tatar"], ["https://whois.nic.tatar/rdap/"]], + [["xn--d1acj3b"], ["https://whois.nic.xn--d1acj3b/rdap/"]], + [["sr"], ["https://whois.sr/rdap/"]], + [["tz"], ["https://whois.tznic.or.tz/rdap/"]], + [["fj"], ["https://www.rdap.fj/"]] + ], + "version": "1.0" +} diff --git a/server/model/status_page.js b/server/model/status_page.js index 9952d56a8..24ec16dba 100644 --- a/server/model/status_page.js +++ b/server/model/status_page.js @@ -7,8 +7,8 @@ const analytics = require("../analytics/analytics"); const { marked } = require("marked"); const { Feed } = require("feed"); const config = require("../config"); -const { setting } = require("../util-server"); +const { setting } = require("../util-server"); const { STATUS_PAGE_ALL_DOWN, STATUS_PAGE_ALL_UP, @@ -17,6 +17,7 @@ const { UP, MAINTENANCE, DOWN, + INCIDENT_PAGE_SIZE, } = require("../../src/util"); class StatusPage extends BeanModel { @@ -307,12 +308,13 @@ class StatusPage extends BeanModel { static async getStatusPageData(statusPage) { const config = await statusPage.toPublicJSON(); - // Incident - let incident = await R.findOne("incident", " pin = 1 AND active = 1 AND status_page_id = ? ", [statusPage.id]); - - if (incident) { - incident = incident.toPublicJSON(); - } + // All active incidents + let incidents = await R.find( + "incident", + " pin = 1 AND active = 1 AND status_page_id = ? ORDER BY created_date DESC", + [statusPage.id] + ); + incidents = incidents.map((i) => i.toPublicJSON()); let maintenanceList = await StatusPage.getMaintenanceList(statusPage.id); @@ -330,7 +332,7 @@ class StatusPage extends BeanModel { // Response return { config, - incident, + incidents, publicGroupList, maintenanceList, }; @@ -499,6 +501,54 @@ class StatusPage extends BeanModel { } } + /** + * Get paginated incident history for a status page using cursor-based pagination + * @param {number} statusPageId ID of the status page + * @param {string|null} cursor ISO date string cursor (created_date of last item from previous page) + * @param {boolean} isPublic Whether to return public or admin data + * @returns {Promise} Paginated incident data with cursor + */ + static async getIncidentHistory(statusPageId, cursor = null, isPublic = true) { + let incidents; + + if (cursor) { + incidents = await R.find( + "incident", + " status_page_id = ? AND created_date < ? ORDER BY created_date DESC LIMIT ? ", + [statusPageId, cursor, INCIDENT_PAGE_SIZE] + ); + } else { + incidents = await R.find("incident", " status_page_id = ? ORDER BY created_date DESC LIMIT ? ", [ + statusPageId, + INCIDENT_PAGE_SIZE, + ]); + } + + const total = await R.count("incident", " status_page_id = ? ", [statusPageId]); + + const lastIncident = incidents[incidents.length - 1]; + let nextCursor = null; + let hasMore = false; + + if (lastIncident) { + const moreCount = await R.count("incident", " status_page_id = ? AND created_date < ? ", [ + statusPageId, + lastIncident.created_date, + ]); + hasMore = moreCount > 0; + if (hasMore) { + nextCursor = lastIncident.created_date; + } + } + + return { + incidents: incidents.map((i) => i.toPublicJSON()), + total, + nextCursor, + hasMore, + }; + } + /** * Get list of maintenances * @param {number} statusPageId ID of status page to get maintenance for diff --git a/server/monitor-types/snmp.js b/server/monitor-types/snmp.js index d670450a1..719ec5f8f 100644 --- a/server/monitor-types/snmp.js +++ b/server/monitor-types/snmp.js @@ -17,7 +17,22 @@ class SNMPMonitorType extends MonitorType { timeout: monitor.timeout * 1000, version: snmp.Version[monitor.snmpVersion], }; - session = snmp.createSession(monitor.hostname, monitor.radiusPassword, sessionOptions); + + if (monitor.snmpVersion === "3") { + if (!monitor.snmp_v3_username) { + throw new Error("SNMPv3 username is required"); + } + // SNMPv3 currently defaults to noAuthNoPriv. + // Supporting authNoPriv / authPriv requires additional inputs + // (auth/priv protocols, passwords), validation, secure storage, + // and database migrations, which is intentionally left for + // a follow-up PR to keep this change scoped. + sessionOptions.securityLevel = snmp.SecurityLevel.noAuthNoPriv; + sessionOptions.username = monitor.snmp_v3_username; + session = snmp.createV3Session(monitor.hostname, monitor.snmp_v3_username, sessionOptions); + } else { + session = snmp.createSession(monitor.hostname, monitor.radiusPassword, sessionOptions); + } // Handle errors during session creation session.on("error", (error) => { diff --git a/server/notification-providers/discord.js b/server/notification-providers/discord.js index 3ed509cea..21b9e07e4 100644 --- a/server/notification-providers/discord.js +++ b/server/notification-providers/discord.js @@ -56,6 +56,8 @@ class Discord extends NotificationProvider { // If heartbeatJSON is not null, we go into the normal alerting loop. let addess = this.extractAddress(monitorJSON); if (heartbeatJSON["status"] === DOWN) { + const wentOfflineTimestamp = Math.floor(new Date(heartbeatJSON["time"]).getTime() / 1000); + let discorddowndata = { username: discordDisplayName, embeds: [ @@ -76,6 +78,11 @@ class Discord extends NotificationProvider { }, ] : []), + { + name: "Went Offline", + // F for full date/time + value: ``, + }, { name: `Time (${heartbeatJSON["timezone"]})`, value: heartbeatJSON["localDateTime"], @@ -104,6 +111,14 @@ class Discord extends NotificationProvider { await axios.post(webhookUrl.toString(), discorddowndata, config); return okMsg; } else if (heartbeatJSON["status"] === UP) { + const backOnlineTimestamp = Math.floor(new Date(heartbeatJSON["time"]).getTime() / 1000); + let downtimeDuration = null; + let wentOfflineTimestamp = null; + if (heartbeatJSON["lastDownTime"]) { + wentOfflineTimestamp = Math.floor(new Date(heartbeatJSON["lastDownTime"]).getTime() / 1000); + downtimeDuration = this.formatDuration(backOnlineTimestamp - wentOfflineTimestamp); + } + let discordupdata = { username: discordDisplayName, embeds: [ @@ -124,10 +139,23 @@ class Discord extends NotificationProvider { }, ] : []), - { - name: `Time (${heartbeatJSON["timezone"]})`, - value: heartbeatJSON["localDateTime"], - }, + ...(wentOfflineTimestamp + ? [ + { + name: "Went Offline", + // F for full date/time + value: ``, + }, + ] + : []), + ...(downtimeDuration + ? [ + { + name: "Downtime Duration", + value: downtimeDuration, + }, + ] + : []), ...(heartbeatJSON["ping"] != null ? [ { @@ -162,6 +190,32 @@ class Discord extends NotificationProvider { this.throwGeneralAxiosError(error); } } + + /** + * Format duration as human-readable string (e.g., "1h 23m", "45m 30s") + * TODO: Update below to `Intl.DurationFormat("en", { style: "short" }).format(duration)` once we are on a newer node version + * @param {number} timeInSeconds The time in seconds to format a duration for + * @returns {string} The formatted duration + */ + formatDuration(timeInSeconds) { + const hours = Math.floor(timeInSeconds / 3600); + const minutes = Math.floor((timeInSeconds % 3600) / 60); + const seconds = timeInSeconds % 60; + + const durationParts = []; + if (hours > 0) { + durationParts.push(`${hours}h`); + } + if (minutes > 0) { + durationParts.push(`${minutes}m`); + } + if (seconds > 0 && hours === 0) { + // Only show seconds if less than an hour + durationParts.push(`${seconds}s`); + } + + return durationParts.length > 0 ? durationParts.join(" ") : "0s"; + } } module.exports = Discord; diff --git a/server/notification-providers/ntfy.js b/server/notification-providers/ntfy.js index ac9ae8e75..d88199b3a 100644 --- a/server/notification-providers/ntfy.js +++ b/server/notification-providers/ntfy.js @@ -57,6 +57,19 @@ class Ntfy extends NotificationProvider { status = "Up"; } } + + // Include monitor's assigned tags + if (monitorJSON && monitorJSON.tags && Array.isArray(monitorJSON.tags)) { + const monitorTagNames = monitorJSON.tags.map((tag) => { + // Include value if it exists + if (tag.value) { + return `${tag.name}: ${tag.value}`; + } + return tag.name; + }); + tags = tags.concat(monitorTagNames); + } + let data = { topic: notification.ntfytopic, message: heartbeatJSON.msg, diff --git a/server/notification-providers/smtp.js b/server/notification-providers/smtp.js index ee17e70e1..2fd717b5d 100644 --- a/server/notification-providers/smtp.js +++ b/server/notification-providers/smtp.js @@ -1,5 +1,6 @@ const nodemailer = require("nodemailer"); const NotificationProvider = require("./notification-provider"); +const { log } = require("../../src/util"); class SMTP extends NotificationProvider { name = "smtp"; @@ -14,11 +15,25 @@ class SMTP extends NotificationProvider { host: notification.smtpHost, port: notification.smtpPort, secure: notification.smtpSecure, - tls: { - rejectUnauthorized: !notification.smtpIgnoreTLSError || false, - }, }; + // Handle TLS/STARTTLS options + if (!notification.smtpSecure && notification.smtpIgnoreSTARTTLS) { + // Disable STARTTLS completely for servers that don't support it + // Connection will remain unencrypted + log.warn( + "notification", + `SMTP notification using unencrypted connection (STARTTLS disabled) to ${notification.smtpHost}:${notification.smtpPort}` + ); + config.ignoreTLS = true; + } else { + // SMTPS (implicit TLS on port 465) + // or STARTTLS (default behavior for ports 25, 587) + config.tls = { + rejectUnauthorized: !notification.smtpIgnoreTLSError || false, + }; + } + // Fix #1129 if (notification.smtpDkimDomain) { config.dkim = { diff --git a/server/notification-providers/wecom.js b/server/notification-providers/wecom.js index 6054208be..d0fbc4a0c 100644 --- a/server/notification-providers/wecom.js +++ b/server/notification-providers/wecom.js @@ -18,7 +18,7 @@ class WeCom extends NotificationProvider { }, }; config = this.getAxiosConfigWithProxy(config); - let body = this.composeMessage(heartbeatJSON, msg); + let body = this.composeMessage(notification, heartbeatJSON, msg); await axios.post( `https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=${notification.weComBotKey}`, body, @@ -32,11 +32,12 @@ class WeCom extends NotificationProvider { /** * Generate the message to send + * @param {object} notification Notification configuration * @param {object} heartbeatJSON Heartbeat details (For Up/Down only) * @param {string} msg General message * @returns {object} Message */ - composeMessage(heartbeatJSON, msg) { + composeMessage(notification, heartbeatJSON, msg) { let title = "UptimeKuma Message"; if (msg != null && heartbeatJSON != null && heartbeatJSON["status"] === UP) { title = "UptimeKuma Monitor Up"; @@ -44,11 +45,26 @@ class WeCom extends NotificationProvider { if (msg != null && heartbeatJSON != null && heartbeatJSON["status"] === DOWN) { title = "UptimeKuma Monitor Down"; } + + let textObj = { + content: title + "\n" + msg, + }; + + // Handle mentioned_mobile_list if configured + if (notification.weComMentionedMobileList?.trim()) { + let mentionedMobiles = notification.weComMentionedMobileList + .split(",") + .map((mobile) => mobile.trim()) + .filter((mobile) => mobile.length > 0); + + if (mentionedMobiles.length > 0) { + textObj.mentioned_mobile_list = mentionedMobiles; + } + } + return { msgtype: "text", - text: { - content: title + "\n" + msg, - }, + text: textObj, }; } } diff --git a/server/routers/status-page-router.js b/server/routers/status-page-router.js index 75e8fdea8..fda296268 100644 --- a/server/routers/status-page-router.js +++ b/server/routers/status-page-router.js @@ -142,6 +142,30 @@ router.get("/api/status-page/:slug/manifest.json", cache("1440 minutes"), async } }); +router.get("/api/status-page/:slug/incident-history", cache("5 minutes"), async (request, response) => { + allowDevAllOrigin(response); + + try { + let slug = request.params.slug; + slug = slug.toLowerCase(); + let statusPageID = await StatusPage.slugToID(slug); + + if (!statusPageID) { + sendHttpError(response, "Status Page Not Found"); + return; + } + + const cursor = request.query.cursor || null; + const result = await StatusPage.getIncidentHistory(statusPageID, cursor, true); + response.json({ + ok: true, + ...result, + }); + } catch (error) { + sendHttpError(response, error.message); + } +}); + // overall status-page status badge router.get("/api/status-page/:slug/badge", cache("5 minutes"), async (request, response) => { allowDevAllOrigin(response); diff --git a/server/setup-database.js b/server/setup-database.js index 81554c160..4f1065307 100644 --- a/server/setup-database.js +++ b/server/setup-database.js @@ -102,6 +102,7 @@ class SetupDatabase { dbConfig.dbName = process.env.UPTIME_KUMA_DB_NAME; dbConfig.username = getEnvOrFile("UPTIME_KUMA_DB_USERNAME"); dbConfig.password = getEnvOrFile("UPTIME_KUMA_DB_PASSWORD"); + dbConfig.socketPath = process.env.UPTIME_KUMA_DB_SOCKET?.trim(); dbConfig.ssl = getEnvOrFile("UPTIME_KUMA_DB_SSL")?.toLowerCase() === "true"; dbConfig.ca = getEnvOrFile("UPTIME_KUMA_DB_CA"); Database.writeDBConfig(dbConfig); @@ -160,6 +161,7 @@ class SetupDatabase { runningSetup: this.runningSetup, needSetup: this.needSetup, isEnabledEmbeddedMariaDB: this.isEnabledEmbeddedMariaDB(), + isEnabledMariaDBSocket: process.env.UPTIME_KUMA_DB_SOCKET?.trim().length > 0, }); }); @@ -202,16 +204,22 @@ class SetupDatabase { // External MariaDB if (dbConfig.type === "mariadb") { - if (!dbConfig.hostname) { - response.status(400).json("Hostname is required"); - this.runningSetup = false; - return; - } + // If socketPath is provided and not empty, validate it + if (process.env.UPTIME_KUMA_DB_SOCKET?.trim().length > 0) { + dbConfig.socketPath = process.env.UPTIME_KUMA_DB_SOCKET.trim(); + } else { + // socketPath not provided, hostname and port are required + if (!dbConfig.hostname) { + response.status(400).json("Hostname is required"); + this.runningSetup = false; + return; + } - if (!dbConfig.port) { - response.status(400).json("Port is required"); - this.runningSetup = false; - return; + if (!dbConfig.port) { + response.status(400).json("Port is required"); + this.runningSetup = false; + return; + } } if (!dbConfig.dbName) { @@ -241,6 +249,7 @@ class SetupDatabase { user: dbConfig.username, password: dbConfig.password, database: dbConfig.dbName, + socketPath: dbConfig.socketPath, ...(dbConfig.ssl ? { ssl: { diff --git a/server/socket-handlers/status-page-socket-handler.js b/server/socket-handlers/status-page-socket-handler.js index a863076cc..5d1035d1d 100644 --- a/server/socket-handlers/status-page-socket-handler.js +++ b/server/socket-handlers/status-page-socket-handler.js @@ -8,6 +8,21 @@ const apicache = require("../modules/apicache"); const StatusPage = require("../model/status_page"); const { UptimeKumaServer } = require("../uptime-kuma-server"); +/** + * Validates incident data + * @param {object} incident - The incident object + * @returns {void} + * @throws {Error} If validation fails + */ +function validateIncident(incident) { + if (!incident.title || incident.title.trim() === "") { + throw new Error("Please input title"); + } + if (!incident.content || incident.content.trim() === "") { + throw new Error("Please input content"); + } +} + /** * Socket handlers for status page * @param {Socket} socket Socket.io instance to add listeners on @@ -25,8 +40,6 @@ module.exports.statusPageSocketHandler = (socket) => { throw new Error("slug is not found"); } - await R.exec("UPDATE incident SET pin = 0 WHERE status_page_id = ? ", [statusPageID]); - let incidentBean; if (incident.id) { @@ -44,12 +57,13 @@ module.exports.statusPageSocketHandler = (socket) => { incidentBean.content = incident.content; incidentBean.style = incident.style; incidentBean.pin = true; + incidentBean.active = true; incidentBean.status_page_id = statusPageID; if (incident.id) { - incidentBean.lastUpdatedDate = R.isoDateTime(dayjs.utc()); + incidentBean.last_updated_date = R.isoDateTime(dayjs.utc()); } else { - incidentBean.createdDate = R.isoDateTime(dayjs.utc()); + incidentBean.created_date = R.isoDateTime(dayjs.utc()); } await R.store(incidentBean); @@ -85,6 +99,171 @@ module.exports.statusPageSocketHandler = (socket) => { } }); + socket.on("getIncidentHistory", async (slug, cursor, callback) => { + try { + let statusPageID = await StatusPage.slugToID(slug); + if (!statusPageID) { + throw new Error("slug is not found"); + } + + const isPublic = !socket.userID; + const result = await StatusPage.getIncidentHistory(statusPageID, cursor, isPublic); + callback({ + ok: true, + ...result, + }); + } catch (error) { + callback({ + ok: false, + msg: error.message, + }); + } + }); + + socket.on("editIncident", async (slug, incidentID, incident, callback) => { + try { + checkLogin(socket); + + let statusPageID = await StatusPage.slugToID(slug); + if (!statusPageID) { + callback({ + ok: false, + msg: "slug is not found", + msgi18n: true, + }); + return; + } + + let bean = await R.findOne("incident", " id = ? AND status_page_id = ? ", [incidentID, statusPageID]); + if (!bean) { + callback({ + ok: false, + msg: "Incident not found or access denied", + msgi18n: true, + }); + return; + } + + try { + validateIncident(incident); + } catch (e) { + callback({ + ok: false, + msg: e.message, + msgi18n: true, + }); + return; + } + + const validStyles = ["info", "warning", "danger", "primary", "light", "dark"]; + if (!validStyles.includes(incident.style)) { + incident.style = "warning"; + } + + bean.title = incident.title; + bean.content = incident.content; + bean.style = incident.style; + bean.pin = incident.pin !== false; + bean.lastUpdatedDate = R.isoDateTime(dayjs.utc()); + + await R.store(bean); + + callback({ + ok: true, + msg: "Saved.", + msgi18n: true, + incident: bean.toPublicJSON(), + }); + } catch (error) { + callback({ + ok: false, + msg: error.message, + msgi18n: true, + }); + } + }); + + socket.on("deleteIncident", async (slug, incidentID, callback) => { + try { + checkLogin(socket); + + let statusPageID = await StatusPage.slugToID(slug); + if (!statusPageID) { + callback({ + ok: false, + msg: "slug is not found", + msgi18n: true, + }); + return; + } + + let bean = await R.findOne("incident", " id = ? AND status_page_id = ? ", [incidentID, statusPageID]); + if (!bean) { + callback({ + ok: false, + msg: "Incident not found or access denied", + msgi18n: true, + }); + return; + } + + await R.trash(bean); + + callback({ + ok: true, + msg: "successDeleted", + msgi18n: true, + }); + } catch (error) { + callback({ + ok: false, + msg: error.message, + msgi18n: true, + }); + } + }); + + socket.on("resolveIncident", async (slug, incidentID, callback) => { + try { + checkLogin(socket); + + let statusPageID = await StatusPage.slugToID(slug); + if (!statusPageID) { + callback({ + ok: false, + msg: "slug is not found", + msgi18n: true, + }); + return; + } + + let bean = await R.findOne("incident", " id = ? AND status_page_id = ? ", [incidentID, statusPageID]); + if (!bean) { + callback({ + ok: false, + msg: "Incident not found or access denied", + msgi18n: true, + }); + return; + } + + await bean.resolve(); + + callback({ + ok: true, + msg: "Resolved", + msgi18n: true, + incident: bean.toPublicJSON(), + }); + } catch (error) { + callback({ + ok: false, + msg: error.message, + msgi18n: true, + }); + } + }); + socket.on("getStatusPage", async (slug, callback) => { try { checkLogin(socket); diff --git a/src/components/IncidentEditForm.vue b/src/components/IncidentEditForm.vue new file mode 100644 index 000000000..08597dfb3 --- /dev/null +++ b/src/components/IncidentEditForm.vue @@ -0,0 +1,119 @@ + + + + + diff --git a/src/components/IncidentHistory.vue b/src/components/IncidentHistory.vue new file mode 100644 index 000000000..d756b7f76 --- /dev/null +++ b/src/components/IncidentHistory.vue @@ -0,0 +1,154 @@ + + + + + diff --git a/src/components/IncidentManageModal.vue b/src/components/IncidentManageModal.vue new file mode 100644 index 000000000..ebe5d06c3 --- /dev/null +++ b/src/components/IncidentManageModal.vue @@ -0,0 +1,204 @@ + + + + + diff --git a/src/components/MonitorList.vue b/src/components/MonitorList.vue index ed354e3a0..6561f5a0a 100644 --- a/src/components/MonitorList.vue +++ b/src/components/MonitorList.vue @@ -35,7 +35,13 @@ :aria-label="selectAll ? $t('deselectAllMonitorsAria') : $t('selectAllMonitorsAria')" /> - + @@ -100,8 +106,8 @@ m.type === "group" && m.parent === null && monitors.some((child) => child.parent === m.id) + ); + }, + + /** + * Determines if all groups are collapsed. + * Note: collapseKey is included to force re-computation when toggleCollapseAll() + * updates localStorage, since Vue cannot detect localStorage changes. + * @returns {boolean} True if all groups are collapsed + */ + allGroupsCollapsed() { + // collapseKey forces this computed to re-evaluate after localStorage updates + if (this.collapseKey < 0 || this.groupMonitors.length === 0) { + return true; + } + + const storage = window.localStorage.getItem("monitorCollapsed"); + if (storage === null) { + return true; // Default is collapsed + } + + const storageObject = JSON.parse(storage); + return this.groupMonitors.every((group) => storageObject[`monitor_${group.id}`] !== false); + }, }, watch: { searchText() { @@ -303,6 +342,26 @@ export default { updateFilter(newFilter) { this.filterState = newFilter; }, + /** + * Toggle collapse state for all group monitors + * @returns {void} + */ + toggleCollapseAll() { + const shouldCollapse = !this.allGroupsCollapsed; + + let storageObject = {}; + const storage = window.localStorage.getItem("monitorCollapsed"); + if (storage !== null) { + storageObject = JSON.parse(storage); + } + + this.groupMonitors.forEach((group) => { + storageObject[`monitor_${group.id}`] = shouldCollapse; + }); + + window.localStorage.setItem("monitorCollapsed", JSON.stringify(storageObject)); + this.collapseKey++; + }, /** * Deselect a monitor * @param {number} id ID of monitor @@ -731,6 +790,7 @@ export default { .search-input { width: 100%; padding-right: 30px; + transition: none !important; } .monitor-item { diff --git a/src/components/MonitorListFilter.vue b/src/components/MonitorListFilter.vue index 1635c3353..0a5a7b91c 100644 --- a/src/components/MonitorListFilter.vue +++ b/src/components/MonitorListFilter.vue @@ -137,6 +137,15 @@ + @@ -1431,12 +1604,14 @@ footer { /* Reset button placed at top-left of the logo */ .reset-top-left { - position: absolute; - top: 0; - left: -15px; - z-index: 2; - width: 20px; - height: 20px; + transition: + transform $easing-in 0.18s, + box-shadow $easing-in 0.18s, + background-color $easing-in 0.18s; + font-size: 18px; + width: 18px; + height: 18px; + padding: 0; display: inline-flex; align-items: center; justify-content: center; @@ -1445,11 +1620,6 @@ footer { border: none; box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2); cursor: pointer; - padding: 0; - transition: - transform $easing-in 0.18s, - box-shadow $easing-in 0.18s, - background-color $easing-in 0.18s; transform-origin: center; &:hover { @@ -1586,4 +1756,28 @@ footer { .refresh-info { opacity: 0.7; } + +.past-incidents-title { + font-size: 26px; + font-weight: normal; +} + +.past-incidents-section { + .past-incidents-content { + padding: 0; + } +} + +.incident-date-group { + .incident-date-header { + font-size: 1rem; + font-weight: normal; + color: var(--bs-secondary); + margin-bottom: 0.75rem; + } + + .incident-list-box { + padding: 0; + } +} diff --git a/src/util.js b/src/util.js index df90a740c..169b8a162 100644 --- a/src/util.js +++ b/src/util.js @@ -10,8 +10,8 @@ */ var _a; Object.defineProperty(exports, "__esModule", { value: true }); -exports.CONSOLE_STYLE_FgViolet = exports.CONSOLE_STYLE_FgLightBlue = exports.CONSOLE_STYLE_FgLightGreen = exports.CONSOLE_STYLE_FgOrange = exports.CONSOLE_STYLE_FgGray = exports.CONSOLE_STYLE_FgWhite = exports.CONSOLE_STYLE_FgCyan = exports.CONSOLE_STYLE_FgMagenta = exports.CONSOLE_STYLE_FgBlue = exports.CONSOLE_STYLE_FgYellow = exports.CONSOLE_STYLE_FgGreen = exports.CONSOLE_STYLE_FgRed = exports.CONSOLE_STYLE_FgBlack = exports.CONSOLE_STYLE_Hidden = exports.CONSOLE_STYLE_Reverse = exports.CONSOLE_STYLE_Blink = exports.CONSOLE_STYLE_Underscore = exports.CONSOLE_STYLE_Dim = exports.CONSOLE_STYLE_Bright = exports.CONSOLE_STYLE_Reset = exports.RESPONSE_BODY_LENGTH_MAX = exports.RESPONSE_BODY_LENGTH_DEFAULT = exports.PING_PER_REQUEST_TIMEOUT_DEFAULT = exports.PING_PER_REQUEST_TIMEOUT_MAX = exports.PING_PER_REQUEST_TIMEOUT_MIN = exports.PING_COUNT_DEFAULT = exports.PING_COUNT_MAX = exports.PING_COUNT_MIN = exports.PING_GLOBAL_TIMEOUT_DEFAULT = exports.PING_GLOBAL_TIMEOUT_MAX = exports.PING_GLOBAL_TIMEOUT_MIN = exports.PING_PACKET_SIZE_DEFAULT = exports.PING_PACKET_SIZE_MAX = exports.PING_PACKET_SIZE_MIN = exports.MIN_INTERVAL_SECOND = exports.MAX_INTERVAL_SECOND = exports.SQL_DATETIME_FORMAT_WITHOUT_SECOND = exports.SQL_DATETIME_FORMAT = exports.SQL_DATE_FORMAT = exports.STATUS_PAGE_MAINTENANCE = exports.STATUS_PAGE_PARTIAL_DOWN = exports.STATUS_PAGE_ALL_UP = exports.STATUS_PAGE_ALL_DOWN = exports.MAINTENANCE = exports.PENDING = exports.UP = exports.DOWN = exports.appName = exports.isNode = exports.isDev = void 0; -exports.TYPES_WITH_DOMAIN_EXPIRY_SUPPORT_VIA_FIELD = exports.evaluateJsonQuery = exports.intHash = exports.localToUTC = exports.utcToLocal = exports.utcToISODateTime = exports.isoToUTCDateTime = exports.parseTimeFromTimeObject = exports.parseTimeObject = exports.getMonitorRelativeURL = exports.genSecret = exports.getCryptoRandomInt = exports.getRandomInt = exports.getRandomArbitrary = exports.TimeLogger = exports.polyfill = exports.log = exports.debug = exports.ucfirst = exports.sleep = exports.flipStatus = exports.badgeConstants = exports.CONSOLE_STYLE_BgGray = exports.CONSOLE_STYLE_BgWhite = exports.CONSOLE_STYLE_BgCyan = exports.CONSOLE_STYLE_BgMagenta = exports.CONSOLE_STYLE_BgBlue = exports.CONSOLE_STYLE_BgYellow = exports.CONSOLE_STYLE_BgGreen = exports.CONSOLE_STYLE_BgRed = exports.CONSOLE_STYLE_BgBlack = exports.CONSOLE_STYLE_FgPink = exports.CONSOLE_STYLE_FgBrown = void 0; +exports.CONSOLE_STYLE_FgLightBlue = exports.CONSOLE_STYLE_FgLightGreen = exports.CONSOLE_STYLE_FgOrange = exports.CONSOLE_STYLE_FgGray = exports.CONSOLE_STYLE_FgWhite = exports.CONSOLE_STYLE_FgCyan = exports.CONSOLE_STYLE_FgMagenta = exports.CONSOLE_STYLE_FgBlue = exports.CONSOLE_STYLE_FgYellow = exports.CONSOLE_STYLE_FgGreen = exports.CONSOLE_STYLE_FgRed = exports.CONSOLE_STYLE_FgBlack = exports.CONSOLE_STYLE_Hidden = exports.CONSOLE_STYLE_Reverse = exports.CONSOLE_STYLE_Blink = exports.CONSOLE_STYLE_Underscore = exports.CONSOLE_STYLE_Dim = exports.CONSOLE_STYLE_Bright = exports.CONSOLE_STYLE_Reset = exports.RESPONSE_BODY_LENGTH_MAX = exports.RESPONSE_BODY_LENGTH_DEFAULT = exports.PING_PER_REQUEST_TIMEOUT_DEFAULT = exports.PING_PER_REQUEST_TIMEOUT_MAX = exports.PING_PER_REQUEST_TIMEOUT_MIN = exports.PING_COUNT_DEFAULT = exports.PING_COUNT_MAX = exports.PING_COUNT_MIN = exports.PING_GLOBAL_TIMEOUT_DEFAULT = exports.PING_GLOBAL_TIMEOUT_MAX = exports.PING_GLOBAL_TIMEOUT_MIN = exports.PING_PACKET_SIZE_DEFAULT = exports.PING_PACKET_SIZE_MAX = exports.PING_PACKET_SIZE_MIN = exports.INCIDENT_PAGE_SIZE = exports.MIN_INTERVAL_SECOND = exports.MAX_INTERVAL_SECOND = exports.SQL_DATETIME_FORMAT_WITHOUT_SECOND = exports.SQL_DATETIME_FORMAT = exports.SQL_DATE_FORMAT = exports.STATUS_PAGE_MAINTENANCE = exports.STATUS_PAGE_PARTIAL_DOWN = exports.STATUS_PAGE_ALL_UP = exports.STATUS_PAGE_ALL_DOWN = exports.MAINTENANCE = exports.PENDING = exports.UP = exports.DOWN = exports.appName = exports.isNode = exports.isDev = void 0; +exports.TYPES_WITH_DOMAIN_EXPIRY_SUPPORT_VIA_FIELD = exports.evaluateJsonQuery = exports.intHash = exports.localToUTC = exports.utcToLocal = exports.utcToISODateTime = exports.isoToUTCDateTime = exports.parseTimeFromTimeObject = exports.parseTimeObject = exports.getMonitorRelativeURL = exports.genSecret = exports.getCryptoRandomInt = exports.getRandomInt = exports.getRandomArbitrary = exports.TimeLogger = exports.polyfill = exports.log = exports.debug = exports.ucfirst = exports.sleep = exports.flipStatus = exports.badgeConstants = exports.CONSOLE_STYLE_BgGray = exports.CONSOLE_STYLE_BgWhite = exports.CONSOLE_STYLE_BgCyan = exports.CONSOLE_STYLE_BgMagenta = exports.CONSOLE_STYLE_BgBlue = exports.CONSOLE_STYLE_BgYellow = exports.CONSOLE_STYLE_BgGreen = exports.CONSOLE_STYLE_BgRed = exports.CONSOLE_STYLE_BgBlack = exports.CONSOLE_STYLE_FgPink = exports.CONSOLE_STYLE_FgBrown = exports.CONSOLE_STYLE_FgViolet = void 0; const dayjs_1 = require("dayjs"); const jsonata = require("jsonata"); exports.isDev = process.env.NODE_ENV === "development"; @@ -31,6 +31,7 @@ exports.SQL_DATETIME_FORMAT = "YYYY-MM-DD HH:mm:ss"; exports.SQL_DATETIME_FORMAT_WITHOUT_SECOND = "YYYY-MM-DD HH:mm"; exports.MAX_INTERVAL_SECOND = 2073600; exports.MIN_INTERVAL_SECOND = 1; +exports.INCIDENT_PAGE_SIZE = 10; exports.PING_PACKET_SIZE_MIN = 1; exports.PING_PACKET_SIZE_MAX = 65500; exports.PING_PACKET_SIZE_DEFAULT = 56; diff --git a/src/util.ts b/src/util.ts index c68017341..ca153adac 100644 --- a/src/util.ts +++ b/src/util.ts @@ -46,6 +46,8 @@ export const SQL_DATETIME_FORMAT_WITHOUT_SECOND = "YYYY-MM-DD HH:mm"; export const MAX_INTERVAL_SECOND = 2073600; // 24 days export const MIN_INTERVAL_SECOND = 1; // 1 second +export const INCIDENT_PAGE_SIZE = 10; + // Packet Size limits export const PING_PACKET_SIZE_MIN = 1; export const PING_PACKET_SIZE_MAX = 65500; diff --git a/test/backend-test/test-snmp.js b/test/backend-test/test-snmp.js new file mode 100644 index 000000000..198082eb8 --- /dev/null +++ b/test/backend-test/test-snmp.js @@ -0,0 +1,128 @@ +const { describe, test } = require("node:test"); +const assert = require("node:assert/strict"); +const { GenericContainer } = require("testcontainers"); +const { SNMPMonitorType } = require("../../server/monitor-types/snmp"); +const { UP } = require("../../src/util"); +const snmp = require("net-snmp"); + +describe("SNMPMonitorType", () => { + test( + "check() sets heartbeat to UP when SNMP agent responds", + { + skip: !!process.env.CI && (process.platform !== "linux" || process.arch !== "x64"), + }, + async () => { + const container = await new GenericContainer("polinux/snmpd").withExposedPorts("161/udp").start(); + + try { + // Get the mapped UDP port + const hostPort = container.getMappedPort("161/udp"); + const hostIp = container.getHost(); + + // UDP service small wait to ensure snmpd is ready inside container + await new Promise((r) => setTimeout(r, 2000)); + + const monitor = { + type: "snmp", + hostname: hostIp, + port: hostPort, + snmpVersion: "2c", + radiusPassword: "public", + snmpOid: "1.3.6.1.2.1.1.1.0", + timeout: 5, + maxretries: 1, + jsonPath: "$", + jsonPathOperator: "!=", + expectedValue: "", + }; + + const snmpMonitor = new SNMPMonitorType(); + const heartbeat = {}; + + await snmpMonitor.check(monitor, heartbeat); + + assert.strictEqual(heartbeat.status, UP); + assert.match(heartbeat.msg, /JSON query passes/); + } finally { + await container.stop(); + } + } + ); + + test( + "check() throws when SNMP agent does not respond", + { + skip: !!process.env.CI && (process.platform !== "linux" || process.arch !== "x64"), + }, + async () => { + const monitor = { + type: "snmp", + hostname: "127.0.0.1", + port: 65530, // Assuming no SNMP agent is running here + snmpVersion: "2c", + radiusPassword: "public", + snmpOid: "1.3.6.1.2.1.1.1.0", + timeout: 1, + maxretries: 1, + }; + + const snmpMonitor = new SNMPMonitorType(); + const heartbeat = {}; + + await assert.rejects(() => snmpMonitor.check(monitor, heartbeat), /timeout|RequestTimedOutError/i); + } + ); + + test("check() uses SNMPv3 noAuthNoPriv session when version is 3", async () => { + const originalCreateV3Session = snmp.createV3Session; + const originalCreateSession = snmp.createSession; + + let createV3Called = false; + let createSessionCalled = false; + let receivedOptions = null; + + // Stub createV3Session + snmp.createV3Session = function (_host, _username, options) { + createV3Called = true; + receivedOptions = options; + + return { + on: () => {}, + close: () => {}, + // Stop execution after session creation to avoid real network I/O. + get: (_oids, cb) => cb(new Error("stop test here")), + }; + }; + + // Stub createSession + snmp.createSession = function () { + createSessionCalled = true; + return {}; + }; + + const monitor = { + type: "snmp", + hostname: "127.0.0.1", + port: 161, + timeout: 5, + maxretries: 1, + snmpVersion: "3", + snmp_v3_username: "testuser", + snmpOid: "1.3.6.1.2.1.1.1.0", + }; + + const snmpMonitor = new SNMPMonitorType(); + const heartbeat = {}; + + await assert.rejects(() => snmpMonitor.check(monitor, heartbeat), /stop test here/); + + // Assertions + assert.strictEqual(createV3Called, true); + assert.strictEqual(createSessionCalled, false); + assert.strictEqual(receivedOptions.securityLevel, snmp.SecurityLevel.noAuthNoPriv); + + // Restore originals + snmp.createV3Session = originalCreateV3Session; + snmp.createSession = originalCreateSession; + }); +}); diff --git a/test/e2e/specs/incident-history.spec.js b/test/e2e/specs/incident-history.spec.js new file mode 100644 index 000000000..2e2d9e946 --- /dev/null +++ b/test/e2e/specs/incident-history.spec.js @@ -0,0 +1,150 @@ +import { expect, test } from "@playwright/test"; +import { login, restoreSqliteSnapshot, screenshot } from "../util-test"; + +test.describe("Incident History", () => { + test.beforeEach(async ({ page }) => { + await restoreSqliteSnapshot(page); + }); + + test("past incidents section is hidden when no incidents exist", async ({ page }, testInfo) => { + test.setTimeout(60000); + + await page.goto("./add"); + await login(page); + await expect(page.getByTestId("monitor-type-select")).toBeVisible(); + + await page.goto("./add-status-page"); + await page.getByTestId("name-input").fill("Empty Test"); + await page.getByTestId("slug-input").fill("empty-test"); + await page.getByTestId("submit-button").click(); + await page.waitForURL("/status/empty-test?edit"); + + await page.getByTestId("save-button").click(); + await expect(page.getByTestId("edit-sidebar")).toHaveCount(0); + + const pastIncidentsSection = page.locator(".past-incidents-section"); + await expect(pastIncidentsSection).toHaveCount(0); + + await screenshot(testInfo, page); + }); + + test("active pinned incidents are shown at top and not in past incidents", async ({ page }, testInfo) => { + test.setTimeout(60000); + + await page.goto("./add"); + await login(page); + await expect(page.getByTestId("monitor-type-select")).toBeVisible(); + + await page.goto("./add-status-page"); + await page.getByTestId("name-input").fill("Dedup Test"); + await page.getByTestId("slug-input").fill("dedup-test"); + await page.getByTestId("submit-button").click(); + await page.waitForURL("/status/dedup-test?edit"); + + await page.getByTestId("create-incident-button").click(); + await page.getByTestId("incident-title").fill("Active Incident"); + await page.getByTestId("incident-content-editable").fill("This is an active incident"); + await page.getByTestId("post-incident-button").click(); + + await page.waitForTimeout(500); + + await page.getByTestId("save-button").click(); + await expect(page.getByTestId("edit-sidebar")).toHaveCount(0); + + const activeIncident = page.getByTestId("incident").filter({ hasText: "Active Incident" }); + await expect(activeIncident).toBeVisible(); + + const pastIncidentsSection = page.locator(".past-incidents-section"); + await expect(pastIncidentsSection).toHaveCount(0); + + await screenshot(testInfo, page); + }); + + test("resolved incidents appear in past incidents section", async ({ page }, testInfo) => { + test.setTimeout(120000); + + await page.goto("./add"); + await login(page); + await expect(page.getByTestId("monitor-type-select")).toBeVisible(); + + await page.goto("./add-status-page"); + await page.getByTestId("name-input").fill("Resolve Test"); + await page.getByTestId("slug-input").fill("resolve-test"); + await page.getByTestId("submit-button").click(); + await page.waitForURL("/status/resolve-test?edit"); + + await page.getByTestId("create-incident-button").click(); + await page.getByTestId("incident-title").fill("Resolved Incident"); + await page.getByTestId("incident-content-editable").fill("This incident will be resolved"); + await page.getByTestId("post-incident-button").click(); + + await page.waitForTimeout(500); + + const activeIncidentBanner = page.getByTestId("incident").filter({ hasText: "Resolved Incident" }); + await expect(activeIncidentBanner).toBeVisible({ timeout: 10000 }); + + const resolveButton = activeIncidentBanner.locator("button", { hasText: "Resolve" }); + await expect(resolveButton).toBeVisible(); + await resolveButton.click(); + + await expect(activeIncidentBanner).toHaveCount(0, { timeout: 10000 }); + + await page.getByTestId("save-button").click(); + await expect(page.getByTestId("edit-sidebar")).toHaveCount(0); + + await page.goto("./status/resolve-test"); + await page.waitForLoadState("networkidle"); + + const pastIncidentsSection = page.locator(".past-incidents-section"); + await expect(pastIncidentsSection).toBeVisible({ timeout: 15000 }); + + const resolvedIncidentTitle = pastIncidentsSection.locator(".incident-title"); + await expect(resolvedIncidentTitle).toContainText("Resolved Incident", { timeout: 15000 }); + + await screenshot(testInfo, page); + }); + + test("incident history pagination loads more incidents", async ({ page }, testInfo) => { + test.setTimeout(180000); + + await page.goto("./add"); + await login(page); + await expect(page.getByTestId("monitor-type-select")).toBeVisible(); + + await page.goto("./add-status-page"); + await page.getByTestId("name-input").fill("Pagination Test"); + await page.getByTestId("slug-input").fill("pagination-test"); + await page.getByTestId("submit-button").click(); + await page.waitForURL("/status/pagination-test?edit"); + + for (let i = 1; i <= 12; i++) { + await page.getByTestId("create-incident-button").click(); + await page.getByTestId("incident-title").fill("Incident " + i); + await page.getByTestId("incident-content-editable").fill("Content for incident " + i); + await page.getByTestId("post-incident-button").click(); + await page.waitForTimeout(300); + + const resolveButton = page.locator("button", { hasText: "Resolve" }).first(); + if (await resolveButton.isVisible()) { + await resolveButton.click(); + await page.waitForTimeout(300); + } + } + + await page.getByTestId("save-button").click(); + await expect(page.getByTestId("edit-sidebar")).toHaveCount(0); + + await page.waitForTimeout(1000); + + const pastIncidentsSection = page.locator(".past-incidents-section"); + await expect(pastIncidentsSection).toBeVisible(); + + const loadMoreButton = page.locator("button", { hasText: "Load More" }); + + if (await loadMoreButton.isVisible()) { + await loadMoreButton.click(); + await page.waitForTimeout(1000); + await screenshot(testInfo, page); + } + }); +});