diff --git a/package-lock.json b/package-lock.json index 5a48ff3..d47e4aa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,520 +1,22 @@ { "name": "@queue-it/fastly", - "version": "2.0.1", + "version": "2.0.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@queue-it/fastly", - "version": "2.0.1", + "version": "2.0.3", "license": "MIT", "dependencies": { - "@fastly/js-compute": "^3.0.0" + "@fastly/js-compute": "^3.0.0", + "@queue-it/connector-javascript": "^5.0.1" }, "devDependencies": { - "@types/jest": "^29.5.0", "esbuild": "^0.27.3", - "jest": "^29.5.0", - "ts-jest": "^29.1.0", "typescript": "^5.4.0" } }, - "node_modules/@babel/code-frame": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", - "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.28.5", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz", - "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", - "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.29.0", - "@babel/generator": "^7.29.0", - "@babel/helper-compilation-targets": "^7.28.6", - "@babel/helper-module-transforms": "^7.28.6", - "@babel/helpers": "^7.28.6", - "@babel/parser": "^7.29.0", - "@babel/template": "^7.28.6", - "@babel/traverse": "^7.29.0", - "@babel/types": "^7.29.0", - "@jridgewell/remapping": "^2.3.5", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/generator": { - "version": "7.29.1", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", - "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.29.0", - "@babel/types": "^7.29.0", - "@jridgewell/gen-mapping": "^0.3.12", - "@jridgewell/trace-mapping": "^0.3.28", - "jsesc": "^3.0.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", - "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.28.6", - "@babel/helper-validator-option": "^7.27.1", - "browserslist": "^4.24.0", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-globals": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", - "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", - "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.28.6", - "@babel/types": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", - "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.28.6", - "@babel/helper-validator-identifier": "^7.28.5", - "@babel/traverse": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", - "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", - "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", - "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", - "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.6.tgz", - "integrity": "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.28.6", - "@babel/types": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz", - "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.29.0" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.28.6.tgz", - "integrity": "sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.28.6.tgz", - "integrity": "sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.28.6.tgz", - "integrity": "sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/template": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", - "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.28.6", - "@babel/parser": "^7.28.6", - "@babel/types": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", - "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.29.0", - "@babel/generator": "^7.29.0", - "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.29.0", - "@babel/template": "^7.28.6", - "@babel/types": "^7.29.0", - "debug": "^4.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/types": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", - "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.28.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true, - "license": "MIT" - }, "node_modules/@bytecodealliance/componentize-js": { "version": "0.19.3", "resolved": "https://registry.npmjs.org/@bytecodealliance/componentize-js/-/componentize-js-0.19.3.tgz", @@ -1739,325 +1241,6 @@ "@esbuild/win32-x64": "0.25.12" } }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/console": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", - "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/core": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", - "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/console": "^29.7.0", - "@jest/reporters": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-changed-files": "^29.7.0", - "jest-config": "^29.7.0", - "jest-haste-map": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-resolve-dependencies": "^29.7.0", - "jest-runner": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "jest-watcher": "^29.7.0", - "micromatch": "^4.0.4", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/@jest/environment": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", - "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/fake-timers": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-mock": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/expect": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", - "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "expect": "^29.7.0", - "jest-snapshot": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/expect-utils": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", - "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", - "dev": true, - "license": "MIT", - "dependencies": { - "jest-get-type": "^29.6.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/fake-timers": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", - "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "@sinonjs/fake-timers": "^10.0.2", - "@types/node": "*", - "jest-message-util": "^29.7.0", - "jest-mock": "^29.7.0", - "jest-util": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/globals": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", - "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/expect": "^29.7.0", - "@jest/types": "^29.6.3", - "jest-mock": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/reporters": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", - "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@jridgewell/trace-mapping": "^0.3.18", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^6.0.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.1.3", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "jest-worker": "^29.7.0", - "slash": "^3.0.0", - "string-length": "^4.0.1", - "strip-ansi": "^6.0.0", - "v8-to-istanbul": "^9.0.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/@jest/schemas": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", - "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.27.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/source-map": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", - "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.18", - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/test-result": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", - "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/console": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/test-sequencer": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", - "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/test-result": "^29.7.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/transform": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", - "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.11.6", - "@jest/types": "^29.6.3", - "@jridgewell/trace-mapping": "^0.3.18", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^2.0.0", - "fast-json-stable-stringify": "^2.1.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-util": "^29.7.0", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "write-file-atomic": "^4.0.2" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/types": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", - "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.13", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", @@ -2694,32 +1877,20 @@ "url": "https://github.com/sponsors/Boshen" } }, - "node_modules/@sinclair/typebox": { - "version": "0.27.10", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.10.tgz", - "integrity": "sha512-MTBk/3jGLNB2tVxv6uLlFh1iu64iYOQ2PbdOSK3NW8JZsmlaOh2q6sdtKowBhfw8QFLmYNzTW4/oK4uATIi6ZA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@sinonjs/commons": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", - "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", - "dev": true, - "license": "BSD-3-Clause", + "node_modules/@queue-it/connector-javascript": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@queue-it/connector-javascript/-/connector-javascript-5.0.1.tgz", + "integrity": "sha512-XK0crDUXSGM1sXjpKhaDR8EWqcLg/vXtg4LJ2L0aGLbWi7VKy1m+fJUopr2Ezws2yJWlFa3TFZQRZ8WpM+DgvA==", + "license": "MIT", "dependencies": { - "type-detect": "4.0.8" + "@queue-it/queue-token": "^1.0.4" } }, - "node_modules/@sinonjs/fake-timers": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", - "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@sinonjs/commons": "^3.0.0" - } + "node_modules/@queue-it/queue-token": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@queue-it/queue-token/-/queue-token-1.0.5.tgz", + "integrity": "sha512-xq+en7SIr2Di5+Pr/ylWVSV5Rh0jkoSiHRGATP2vqnHUNoh/z72ghCyEPlIS2sXYw4HTGLXxfbushmQBfEW1nQ==", + "license": "MIT" }, "node_modules/@tybys/wasm-util": { "version": "0.10.1", @@ -2731,133 +1902,6 @@ "tslib": "^2.4.0" } }, - "node_modules/@types/babel__core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", - "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "node_modules/@types/babel__generator": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", - "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", - "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__traverse": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", - "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.28.2" - } - }, - "node_modules/@types/graceful-fs": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", - "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", - "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", - "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "*" - } - }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", - "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@types/jest": { - "version": "29.5.14", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.14.tgz", - "integrity": "sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "expect": "^29.0.0", - "pretty-format": "^29.0.0" - } - }, - "node_modules/@types/node": { - "version": "25.3.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.3.3.tgz", - "integrity": "sha512-DpzbrH7wIcBaJibpKo9nnSQL0MTRdnWttGyE5haGwK86xgMOkFLp7vEyfQPGLOJh5wNYiJ3V9PmUMDhV9u8kkQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~7.18.0" - } - }, - "node_modules/@types/stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/yargs": { - "version": "17.0.35", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz", - "integrity": "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/yargs-parser": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", - "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", - "dev": true, - "license": "MIT" - }, "node_modules/acorn": { "version": "8.16.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", @@ -2882,83 +1926,6 @@ "node": ">=0.4.0" } }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/anymatch/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, "node_modules/available-typed-arrays": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", @@ -2974,128 +1941,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/babel-jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", - "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/transform": "^29.7.0", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.6.3", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.8.0" - } - }, - "node_modules/babel-plugin-istanbul": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", - "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-jest-hoist": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", - "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.1.14", - "@types/babel__traverse": "^7.0.6" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/babel-preset-current-node-syntax": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz", - "integrity": "sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-import-attributes": "^7.24.7", - "@babel/plugin-syntax-import-meta": "^7.10.4", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5" - }, - "peerDependencies": { - "@babel/core": "^7.0.0 || ^8.0.0-0" - } - }, - "node_modules/babel-preset-jest": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", - "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-plugin-jest-hoist": "^29.6.3", - "babel-preset-current-node-syntax": "^1.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -3116,19 +1961,6 @@ ], "license": "MIT" }, - "node_modules/baseline-browser-mapping": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.0.tgz", - "integrity": "sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "baseline-browser-mapping": "dist/cli.cjs" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/bl": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz", @@ -3139,87 +1971,6 @@ "safe-buffer": "^5.1.1" } }, - "node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "license": "MIT", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browserslist": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", - "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "baseline-browser-mapping": "^2.9.0", - "caniuse-lite": "^1.0.30001759", - "electron-to-chromium": "^1.5.263", - "node-releases": "^2.0.27", - "update-browserslist-db": "^1.2.0" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/bs-logger": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", - "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-json-stable-stringify": "2.x" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "node-int64": "^0.4.0" - } - }, "node_modules/buffer": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", @@ -3328,96 +2079,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001775", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001775.tgz", - "integrity": "sha512-s3Qv7Lht9zbVKE9XoTyRG6wVDCKdtOFIjBGg3+Yhn6JaytuNKPIjBMTMIY1AnOH3seL5mvF+x33oGAyK3hVt3A==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "CC-BY-4.0" - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/cjs-module-lexer": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", - "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", - "dev": true, - "license": "MIT" - }, "node_modules/cli-cursor": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", @@ -3445,136 +2106,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", - "dev": true, - "license": "MIT", - "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" - } - }, - "node_modules/collect-v8-coverage": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.3.tgz", - "integrity": "sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw==", - "dev": true, - "license": "MIT" - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, "node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true, - "license": "MIT" - }, "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "license": "MIT" }, - "node_modules/create-jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", - "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-config": "^29.7.0", - "jest-util": "^29.7.0", - "prompts": "^2.0.1" - }, - "bin": { - "create-jest": "bin/create-jest.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, "node_modules/decompress": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.1.tgz", @@ -3671,31 +2213,6 @@ "node": ">=0.10.0" } }, - "node_modules/dedent": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.2.tgz", - "integrity": "sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "babel-plugin-macros": "^3.1.0" - }, - "peerDependenciesMeta": { - "babel-plugin-macros": { - "optional": true - } - } - }, - "node_modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/define-data-property": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", @@ -3713,26 +2230,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/diff-sequences": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", - "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -3747,32 +2244,6 @@ "node": ">= 0.4" } }, - "node_modules/electron-to-chromium": { - "version": "1.5.302", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.302.tgz", - "integrity": "sha512-sM6HAN2LyK82IyPBpznDRqlTQAtuSaO+ShzFiWTvoMJLHyZ+Y39r8VMfHzwbU8MVBzQ4Wdn85+wlZl2TLGIlwg==", - "dev": true, - "license": "ISC" - }, - "node_modules/emittery": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", - "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sindresorhus/emittery?sponsor=1" - } - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, "node_modules/end-of-stream": { "version": "1.4.5", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", @@ -3782,16 +2253,6 @@ "once": "^1.4.0" } }, - "node_modules/error-ex": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", - "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, "node_modules/es-define-property": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", @@ -3921,176 +2382,22 @@ "node": ">=18" } }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "dev": true, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", "license": "MIT", - "engines": { - "node": ">=6" + "dependencies": { + "pend": "~1.2.0" } }, - "node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true, + "node_modules/file-type": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", + "integrity": "sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ==", "license": "MIT", "engines": { - "node": ">=8" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "license": "BSD-2-Clause", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "license": "MIT", - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/execa/node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/execa/node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/expect": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", - "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/expect-utils": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true, - "license": "MIT" - }, - "node_modules/fb-watchman": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", - "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "bser": "2.1.1" - } - }, - "node_modules/fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", - "license": "MIT", - "dependencies": { - "pend": "~1.2.0" - } - }, - "node_modules/file-type": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", - "integrity": "sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" + "node": ">=4" } }, "node_modules/for-each": { @@ -4114,27 +2421,6 @@ "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", "license": "MIT" }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -4144,26 +2430,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "license": "ISC", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, "node_modules/get-east-asian-width": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.5.0.tgz", @@ -4200,16 +2466,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.0.0" - } - }, "node_modules/get-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", @@ -4236,27 +2492,6 @@ "node": ">=0.10.0" } }, - "node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", @@ -4275,37 +2510,6 @@ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "license": "ISC" }, - "node_modules/handlebars": { - "version": "4.7.8", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", - "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "minimist": "^1.2.5", - "neo-async": "^2.6.2", - "source-map": "^0.6.1", - "wordwrap": "^1.0.0" - }, - "bin": { - "handlebars": "bin/handlebars" - }, - "engines": { - "node": ">=0.4.7" - }, - "optionalDependencies": { - "uglify-js": "^3.1.4" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/has-property-descriptors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", @@ -4357,23 +2561,6 @@ "node": ">= 0.4" } }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true, - "license": "MIT" - }, - "node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=10.17.0" - } - }, "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -4394,59 +2581,11 @@ ], "license": "BSD-3-Clause" }, - "node_modules/import-local": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", - "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", - "dev": true, - "license": "MIT", - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true, - "license": "MIT" - }, "node_modules/is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", @@ -4459,41 +2598,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-core-module": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", - "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", - "dev": true, - "license": "MIT", - "dependencies": { - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/is-interactive": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", @@ -4512,16 +2616,6 @@ "integrity": "sha512-Y4LTamMe0DDQIIAlaer9eKebAlDSV6huy+TWhJVPlzZh2o4tRP5SQWFlLn5N0To4mDD22/qdOq+veo1cSISLgQ==", "license": "MIT" }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, "node_modules/is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", @@ -4563,846 +2657,29 @@ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true, - "license": "ISC" - }, - "node_modules/istanbul-lib-coverage": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", - "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", - "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@babel/core": "^7.23.9", - "@babel/parser": "^7.23.9", - "@istanbuljs/schema": "^0.1.3", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^7.5.4" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", - "dev": true, - "license": "ISC", + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "license": "MIT", "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-report": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", - "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^4.0.0", - "supports-color": "^7.1.0" + "jsesc": "bin/jsesc" }, "engines": { - "node": ">=10" + "node": ">=6" } }, - "node_modules/istanbul-lib-report/node_modules/make-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", - "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", - "dev": true, + "node_modules/log-symbols": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-6.0.0.tgz", + "integrity": "sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==", "license": "MIT", "dependencies": { - "semver": "^7.5.3" + "chalk": "^5.3.0", + "is-unicode-supported": "^1.3.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/istanbul-lib-report/node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-reports": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", - "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", - "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/core": "^29.7.0", - "@jest/types": "^29.6.3", - "import-local": "^3.0.2", - "jest-cli": "^29.7.0" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/jest-changed-files": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", - "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", - "dev": true, - "license": "MIT", - "dependencies": { - "execa": "^5.0.0", - "jest-util": "^29.7.0", - "p-limit": "^3.1.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-circus": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", - "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/expect": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^1.0.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^29.7.0", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", - "p-limit": "^3.1.0", - "pretty-format": "^29.7.0", - "pure-rand": "^6.0.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-cli": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", - "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/core": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "create-jest": "^29.7.0", - "exit": "^0.1.2", - "import-local": "^3.0.2", - "jest-config": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "yargs": "^17.3.1" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/jest-config": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", - "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^29.7.0", - "@jest/types": "^29.6.3", - "babel-jest": "^29.7.0", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-circus": "^29.7.0", - "jest-environment-node": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-runner": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "micromatch": "^4.0.4", - "parse-json": "^5.2.0", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@types/node": "*", - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "ts-node": { - "optional": true - } - } - }, - "node_modules/jest-diff": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", - "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^29.6.3", - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-docblock": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", - "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "detect-newline": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-each": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", - "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "jest-get-type": "^29.6.3", - "jest-util": "^29.7.0", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-environment-node": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", - "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/fake-timers": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-mock": "^29.7.0", - "jest-util": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-get-type": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", - "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-haste-map": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", - "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "@types/graceful-fs": "^4.1.3", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.6.3", - "jest-util": "^29.7.0", - "jest-worker": "^29.7.0", - "micromatch": "^4.0.4", - "walker": "^1.0.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.2" - } - }, - "node_modules/jest-leak-detector": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", - "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", - "dev": true, - "license": "MIT", - "dependencies": { - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-matcher-utils": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", - "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^29.7.0", - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-message-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", - "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.6.3", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-mock": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", - "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-util": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-pnp-resolver": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", - "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - }, - "peerDependencies": { - "jest-resolve": "*" - }, - "peerDependenciesMeta": { - "jest-resolve": { - "optional": true - } - } - }, - "node_modules/jest-regex-util": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", - "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-resolve": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", - "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "resolve": "^1.20.0", - "resolve.exports": "^2.0.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-resolve-dependencies": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", - "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", - "dev": true, - "license": "MIT", - "dependencies": { - "jest-regex-util": "^29.6.3", - "jest-snapshot": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-runner": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", - "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/console": "^29.7.0", - "@jest/environment": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.13.1", - "graceful-fs": "^4.2.9", - "jest-docblock": "^29.7.0", - "jest-environment-node": "^29.7.0", - "jest-haste-map": "^29.7.0", - "jest-leak-detector": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-resolve": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-util": "^29.7.0", - "jest-watcher": "^29.7.0", - "jest-worker": "^29.7.0", - "p-limit": "^3.1.0", - "source-map-support": "0.5.13" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-runtime": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", - "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/fake-timers": "^29.7.0", - "@jest/globals": "^29.7.0", - "@jest/source-map": "^29.6.3", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-mock": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-snapshot": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", - "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.11.6", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-jsx": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^29.7.0", - "graceful-fs": "^4.2.9", - "jest-diff": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "natural-compare": "^1.4.0", - "pretty-format": "^29.7.0", - "semver": "^7.5.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-snapshot/node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", - "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-util/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/jest-validate": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", - "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^29.6.3", - "leven": "^3.1.0", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-validate/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jest-watcher": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", - "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.13.1", - "jest-util": "^29.7.0", - "string-length": "^4.0.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-worker": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", - "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "jest-util": "^29.7.0", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/js-yaml": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", - "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsesc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", - "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", - "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true, - "license": "MIT" - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, - "license": "MIT", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true, - "license": "MIT" - }, - "node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", - "dev": true, - "license": "MIT" - }, - "node_modules/log-symbols": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-6.0.0.tgz", - "integrity": "sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==", - "license": "MIT", - "dependencies": { - "chalk": "^5.3.0", - "is-unicode-supported": "^1.3.0" - }, - "engines": { - "node": ">=18" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -5432,16 +2709,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^3.0.2" - } - }, "node_modules/magic-string": { "version": "0.30.21", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", @@ -5472,23 +2739,6 @@ "node": ">=4" } }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true, - "license": "ISC" - }, - "node_modules/makeerror": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "tmpl": "1.0.5" - } - }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -5498,83 +2748,16 @@ "node": ">= 0.4" } }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true, - "license": "MIT" - }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "dev": true, - "license": "MIT", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/micromatch/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/mimic-function": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", "license": "MIT", "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/minimatch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "license": "MIT", + "node": ">=18" + }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/mkdirp": { @@ -5592,64 +2775,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true, - "license": "MIT" - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true, - "license": "MIT" - }, - "node_modules/node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "dev": true, - "license": "MIT" - }, - "node_modules/node-releases": { - "version": "2.0.27", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", - "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", - "dev": true, - "license": "MIT" - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -5667,22 +2792,6 @@ "wrappy": "1" } }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/ora": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/ora/-/ora-8.2.0.tgz", @@ -5800,129 +2909,12 @@ "@oxc-parser/binding-win32-x64-msvc": "0.76.0" } }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-locate/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "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", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true, - "license": "MIT" - }, "node_modules/pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", "license": "MIT" }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true, - "license": "ISC" - }, "node_modules/picomatch": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", @@ -5965,29 +2957,6 @@ "node": ">=0.10.0" } }, - "node_modules/pirates": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", - "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/possible-typed-array-names": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", @@ -5997,78 +2966,12 @@ "node": ">= 0.4" } }, - "node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "license": "MIT" }, - "node_modules/prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/pure-rand": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", - "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/dubzzz" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fast-check" - } - ], - "license": "MIT" - }, - "node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "dev": true, - "license": "MIT" - }, "node_modules/readable-stream": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", @@ -6143,70 +3046,6 @@ "regjsparser": "bin/parser" } }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve": { - "version": "1.22.11", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", - "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-core-module": "^2.16.1", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve.exports": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.3.tgz", - "integrity": "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, "node_modules/restore-cursor": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", @@ -6283,16 +3122,6 @@ "seek-table": "bin/seek-bzip-table" } }, - "node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/set-function-length": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", @@ -6310,91 +3139,13 @@ "node": ">= 0.4" } }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true, - "license": "MIT" - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/stack-utils": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", - "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "escape-string-regexp": "^2.0.0" - }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", "engines": { - "node": ">=10" + "node": ">=0.10.0" } }, "node_modules/stdin-discarder": { @@ -6424,56 +3175,6 @@ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "license": "MIT" }, - "node_modules/string-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/strip-dirs": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz", @@ -6483,54 +3184,6 @@ "is-natural-number": "^4.0.1" } }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/tar-stream": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", @@ -6577,34 +3230,12 @@ "source-map": "^0.6.0" } }, - "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dev": true, - "license": "ISC", - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "license": "MIT" }, - "node_modules/tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "dev": true, - "license": "BSD-3-Clause" - }, "node_modules/to-buffer": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.2.tgz", @@ -6625,98 +3256,6 @@ "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", "license": "MIT" }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/ts-jest": { - "version": "29.4.6", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.6.tgz", - "integrity": "sha512-fSpWtOO/1AjSNQguk43hb/JCo16oJDnMJf3CdEGNkqsEX3t0KX96xvyX1D7PfLCpVoKu4MfVrqUkFyblYoY4lA==", - "dev": true, - "license": "MIT", - "dependencies": { - "bs-logger": "^0.2.6", - "fast-json-stable-stringify": "^2.1.0", - "handlebars": "^4.7.8", - "json5": "^2.2.3", - "lodash.memoize": "^4.1.2", - "make-error": "^1.3.6", - "semver": "^7.7.3", - "type-fest": "^4.41.0", - "yargs-parser": "^21.1.1" - }, - "bin": { - "ts-jest": "cli.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0" - }, - "peerDependencies": { - "@babel/core": ">=7.0.0-beta.0 <8", - "@jest/transform": "^29.0.0 || ^30.0.0", - "@jest/types": "^29.0.0 || ^30.0.0", - "babel-jest": "^29.0.0 || ^30.0.0", - "jest": "^29.0.0 || ^30.0.0", - "jest-util": "^29.0.0 || ^30.0.0", - "typescript": ">=4.3 <6" - }, - "peerDependenciesMeta": { - "@babel/core": { - "optional": true - }, - "@jest/transform": { - "optional": true - }, - "@jest/types": { - "optional": true - }, - "babel-jest": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "jest-util": { - "optional": true - } - } - }, - "node_modules/ts-jest/node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/ts-jest/node_modules/type-fest": { - "version": "4.41.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", - "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", @@ -6724,29 +3263,6 @@ "license": "0BSD", "optional": true }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/typed-array-buffer": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", @@ -6775,20 +3291,6 @@ "node": ">=14.17" } }, - "node_modules/uglify-js": { - "version": "3.19.3", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", - "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", - "dev": true, - "license": "BSD-2-Clause", - "optional": true, - "bin": { - "uglifyjs": "bin/uglifyjs" - }, - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/unbzip2-stream": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", @@ -6799,13 +3301,6 @@ "through": "^2.3.8" } }, - "node_modules/undici-types": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", - "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", - "dev": true, - "license": "MIT" - }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", @@ -6846,84 +3341,12 @@ "node": ">=4" } }, - "node_modules/update-browserslist-db": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", - "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "escalade": "^3.2.0", - "picocolors": "^1.1.1" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "license": "MIT" }, - "node_modules/v8-to-istanbul": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", - "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", - "dev": true, - "license": "ISC", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.12", - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^2.0.0" - }, - "engines": { - "node": ">=10.12.0" - } - }, - "node_modules/walker": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "makeerror": "1.0.12" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/which-typed-array": { "version": "1.1.20", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.20.tgz", @@ -6945,50 +3368,11 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, - "node_modules/write-file-atomic": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", - "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", - "dev": true, - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.7" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -6998,52 +3382,6 @@ "node": ">=0.4" } }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true, - "license": "ISC" - }, - "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=12" - } - }, "node_modules/yauzl": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", @@ -7053,19 +3391,6 @@ "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } } } } diff --git a/package.json b/package.json index b9d32d7..449b1e4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@queue-it/fastly", - "version": "2.0.2", + "version": "2.0.3", "description": "Queue-it connector for Fastly", "main": "src/index.ts", "author": "devs@queue-it.com", @@ -9,7 +9,8 @@ "files": [ "package.json", "README.md", - "src/sdk", + "src/helpers", + "src/fastlyCryptoProvider.ts", "src/contextProvider.ts", "src/helper.ts", "src/integrationConfigProvider.ts", @@ -17,19 +18,17 @@ "src/index.ts" ], "scripts": { - "test": "jest", + "typecheck": "tsc --noEmit", "bundle": "esbuild src/index.ts --bundle --outfile=bin/index.js --platform=node --target=es2022 && js-compute-runtime bin/index.js bin/main.wasm", "build": "fastly compute build", "deploy": "fastly compute deploy" }, "dependencies": { - "@fastly/js-compute": "^3.0.0" + "@fastly/js-compute": "^3.0.0", + "@queue-it/connector-javascript": "^5.0.1" }, "devDependencies": { - "@types/jest": "^29.5.0", "esbuild": "^0.27.3", - "jest": "^29.5.0", - "ts-jest": "^29.1.0", "typescript": "^5.4.0" } } diff --git a/src/__tests__/CustomerIntegrationDecodingHandler.spec.ts b/src/__tests__/CustomerIntegrationDecodingHandler.spec.ts deleted file mode 100644 index 18bbfd5..0000000 --- a/src/__tests__/CustomerIntegrationDecodingHandler.spec.ts +++ /dev/null @@ -1,1129 +0,0 @@ -import {CustomerIntegrationDecodingHandler} from "../sdk/IntegrationConfig/CustomerIntegrationDecodingHandler"; -import * as IntegrationModels from "../sdk/IntegrationConfig/IntegrationConfigModel"; - -describe('CustomerIntegrationDecodingHandler', () => { - - it('should deserialize', () => { - const integrationConfigString = `{ - "Description":"tst", - "Integrations":[ - { - "Name":"Integration - With InvolvedWaitingRoomIds", - "ActionType":"Cancel", - "EventId":"event2", - "InvolvedWaitingRoomIds":["event2"], - "Triggers":[ - { - "TriggerParts":[ - { - "ValidatorType":"UrlValidator", - "Operator":"Contains", - "ValueToCompare":"test2", - "IsNegative":false, - "IsIgnoreCase":true - } - ], - "LogicalOperator":"And" - } - ] - }, - { - "Name":"mojitest", - "ActionType":"Queue", - "EventId":"event1", - "CookieDomain":"", - "LayoutName":null, - "Culture":"", - "ExtendCookieValidity":true, - "CookieValidityMinute":20, - "Triggers":[ - { - "TriggerParts":[ - { - "Operator":"Contains", - "ValueToCompare":"mojitest", - "ValuesToCompare":null, - "UrlPart":"PageUrl", - "CookieName":null, - "HttpHeaderName":null, - "ValidatorType":"UrlValidator", - "IsNegative":false, - "IsIgnoreCase":true - } - ], - "LogicalOperator":"And" - } - ], - "QueueDomain":"queueitknownusertst.test.queue-it.net", - "RedirectLogic":"AllowTParameter", - "ForcedTargetUrl":"" - }, - { - "Name":"all pages", - "ActionType":"Queue", - "EventId":"disabled", - "CookieDomain":"", - "LayoutName":null, - "Culture":"", - "ExtendCookieValidity":true, - "CookieValidityMinute":20, - "Triggers":[ - { - "TriggerParts":[ - { - "Operator":"Contains", - "ValueToCompare":"test02082018", - "ValuesToCompare":null, - "UrlPart":"PageUrl", - "CookieName":null, - "HttpHeaderName":null, - "ValidatorType":"UrlValidator", - "IsNegative":false, - "IsIgnoreCase":true - } - ], - "LogicalOperator":"And" - } - ], - "QueueDomain":"queueitknownusertst.test.queue-it.net", - "RedirectLogic":"AllowTParameter", - "ForcedTargetUrl":"" - }, - { - "Name":"event1 ignore action (default)", - "ActionType":"Ignore", - "EventId":null, - "CookieDomain":null, - "LayoutName":null, - "Culture":null, - "ExtendCookieValidity":null, - "CookieValidityMinute":0, - "Triggers":[ - { - "TriggerParts":[ - { - "Operator":"Contains", - "ValueToCompare":"ignore-queue-event1-nodomain", - "ValuesToCompare":null, - "UrlPart":"PageUrl", - "CookieName":null, - "HttpHeaderName":null, - "ValidatorType":"UrlValidator", - "IsNegative":false, - "IsIgnoreCase":true - }, - { - "Operator":"ContainsAny", - "ValueToCompare":"", - "ValuesToCompare":[ - "ignore-this-queue-event1-nodomain", - "ignore-that-queue-event1-nodomain" - ], - "UrlPart":"PageUrl", - "CookieName":null, - "HttpHeaderName":null, - "ValidatorType":"UrlValidator", - "IsNegative":false, - "IsIgnoreCase":true - }, - { - "Operator":"Contains", - "ValueToCompare":"*", - "ValuesToCompare":null, - "UrlPart":null, - "CookieName":"ignore-queue-event1", - "HttpHeaderName":null, - "ValidatorType":"CookieValidator", - "IsNegative":false, - "IsIgnoreCase":true - }, - { - "Operator":"Contains", - "ValueToCompare":"ignore-queue-event1", - "ValuesToCompare":null, - "UrlPart":null, - "CookieName":null, - "HttpHeaderName":null, - "ValidatorType":"RequestBodyValidator", - "IsNegative":false, - "IsIgnoreCase":true - } - ], - "LogicalOperator":"Or" - } - ], - "QueueDomain":null, - "RedirectLogic":null, - "ForcedTargetUrl":null - }, - { - "Name":"event1 queue action (default)", - "ActionType":"Queue", - "EventId":"event1", - "CookieDomain":"", - "LayoutName":"White Space", - "Culture":"", - "ExtendCookieValidity":true, - "CookieValidityMinute":20, - "Triggers":[ - { - "TriggerParts":[ - { - "Operator":"Contains", - "ValueToCompare":"queue-event1-nodomain", - "ValuesToCompare":null, - "UrlPart":"PageUrl", - "CookieName":null, - "HttpHeaderName":null, - "ValidatorType":"UrlValidator", - "IsNegative":false, - "IsIgnoreCase":true - }, - { - "Operator":"Contains", - "ValueToCompare":"bot", - "ValuesToCompare":null, - "UrlPart":null, - "CookieName":"Akamai-bot", - "HttpHeaderName":null, - "ValidatorType":"CookieValidator", - "IsNegative":true, - "IsIgnoreCase":true - }, - { - "Operator":"Contains", - "ValueToCompare":"bot", - "ValuesToCompare":null, - "UrlPart":null, - "CookieName":null, - "HttpHeaderName":null, - "ValidatorType":"UserAgentValidator", - "IsNegative":true, - "IsIgnoreCase":true - }, - { - "Operator":"Contains", - "ValueToCompare":"bot", - "ValuesToCompare":null, - "UrlPart":null, - "CookieName":null, - "HttpHeaderName":"Akamai-bot", - "ValidatorType":"HttpHeaderValidator", - "IsNegative":true, - "IsIgnoreCase":true - } - ], - "LogicalOperator":"And" - } - ], - "QueueDomain":"queueitknownusertst.test.queue-it.net", - "RedirectLogic":"AllowTParameter", - "ForcedTargetUrl":"" - }, - { - "Name":"event1 cancel action (default)", - "ActionType":"Cancel", - "EventId":"event1", - "CookieDomain":"", - "LayoutName":null, - "Culture":null, - "ExtendCookieValidity":null, - "CookieValidityMinute":0, - "Triggers":[ - { - "TriggerParts":[ - { - "Operator":"Contains", - "ValueToCompare":"cancel-event1-nodomain", - "ValuesToCompare":null, - "UrlPart":"PageUrl", - "CookieName":null, - "HttpHeaderName":null, - "ValidatorType":"UrlValidator", - "IsNegative":false, - "IsIgnoreCase":true - } - ], - "LogicalOperator":"And" - } - ], - "QueueDomain":"queueitknownusertst.test.queue-it.net", - "RedirectLogic":null, - "ForcedTargetUrl":null - }, - { - "Name":"event1 ignore action (ticketania)", - "ActionType":"Ignore", - "EventId":null, - "CookieDomain":null, - "LayoutName":null, - "Culture":null, - "ExtendCookieValidity":null, - "CookieValidityMinute":0, - "Triggers":[ - { - "TriggerParts":[ - { - "Operator":"Contains", - "ValueToCompare":"ignore-queue-event1", - "ValuesToCompare":null, - "UrlPart":"PageUrl", - "CookieName":null, - "HttpHeaderName":null, - "ValidatorType":"UrlValidator", - "IsNegative":false, - "IsIgnoreCase":true - }, - { - "Operator":"ContainsAny", - "ValueToCompare":"", - "ValuesToCompare":[ - "ignore-that-queue-event1", - "ignore-this-queue-event1" - ], - "UrlPart":"PageUrl", - "CookieName":null, - "HttpHeaderName":null, - "ValidatorType":"UrlValidator", - "IsNegative":false, - "IsIgnoreCase":true - } - ], - "LogicalOperator":"Or" - } - ], - "QueueDomain":null, - "RedirectLogic":null, - "ForcedTargetUrl":null - }, - { - "Name":"event1 queue action (ticketania)", - "ActionType":"Queue", - "EventId":"event1", - "CookieDomain":".ticketania.com", - "LayoutName":"White Space", - "Culture":"", - "ExtendCookieValidity":true, - "CookieValidityMinute":20, - "Triggers":[ - { - "TriggerParts":[ - { - "Operator":"Contains", - "ValueToCompare":"queue-event1", - "ValuesToCompare":null, - "UrlPart":"PageUrl", - "CookieName":null, - "HttpHeaderName":null, - "ValidatorType":"UrlValidator", - "IsNegative":false, - "IsIgnoreCase":true - }, - { - "Operator":"Contains", - "ValueToCompare":"bot", - "ValuesToCompare":null, - "UrlPart":null, - "CookieName":"Akamai-bot", - "HttpHeaderName":null, - "ValidatorType":"CookieValidator", - "IsNegative":true, - "IsIgnoreCase":true - }, - { - "Operator":"Contains", - "ValueToCompare":"bot", - "ValuesToCompare":null, - "UrlPart":null, - "CookieName":null, - "HttpHeaderName":null, - "ValidatorType":"UserAgentValidator", - "IsNegative":true, - "IsIgnoreCase":true - }, - { - "Operator":"Contains", - "ValueToCompare":"bot", - "ValuesToCompare":null, - "UrlPart":null, - "CookieName":null, - "HttpHeaderName":"Akamai-bot", - "ValidatorType":"HttpHeaderValidator", - "IsNegative":true, - "IsIgnoreCase":true - }, - { - "Operator":"Contains", - "ValueToCompare":"ticketania", - "ValuesToCompare":null, - "UrlPart":"HostName", - "CookieName":null, - "HttpHeaderName":null, - "ValidatorType":"UrlValidator", - "IsNegative":false, - "IsIgnoreCase":true - } - ], - "LogicalOperator":"And" - } - ], - "QueueDomain":"queueitknownusertst.test.queue-it.net", - "RedirectLogic":"AllowTParameter", - "ForcedTargetUrl":"" - }, - { - "Name":"event1 queue action (cloudflare)", - "ActionType":"Queue", - "EventId":"event1", - "CookieDomain":".cloudflare-queue-it.com", - "LayoutName":"White Space", - "Culture":"", - "ExtendCookieValidity":true, - "CookieValidityMinute":20, - "Triggers":[ - { - "TriggerParts":[ - { - "Operator":"Contains", - "ValueToCompare":"queue-event1", - "ValuesToCompare":null, - "UrlPart":"PageUrl", - "CookieName":null, - "HttpHeaderName":null, - "ValidatorType":"UrlValidator", - "IsNegative":false, - "IsIgnoreCase":true - }, - { - "Operator":"Contains", - "ValueToCompare":"bot", - "ValuesToCompare":null, - "UrlPart":null, - "CookieName":"Akamai-bot", - "HttpHeaderName":null, - "ValidatorType":"CookieValidator", - "IsNegative":true, - "IsIgnoreCase":true - }, - { - "Operator":"Contains", - "ValueToCompare":"bot", - "ValuesToCompare":null, - "UrlPart":null, - "CookieName":null, - "HttpHeaderName":null, - "ValidatorType":"UserAgentValidator", - "IsNegative":true, - "IsIgnoreCase":true - }, - { - "Operator":"Contains", - "ValueToCompare":"bot", - "ValuesToCompare":null, - "UrlPart":null, - "CookieName":null, - "HttpHeaderName":"Akamai-bot", - "ValidatorType":"HttpHeaderValidator", - "IsNegative":true, - "IsIgnoreCase":true - }, - { - "Operator":"Contains", - "ValueToCompare":"cloudflare-queue-it.com", - "ValuesToCompare":null, - "UrlPart":"HostName", - "CookieName":null, - "HttpHeaderName":null, - "ValidatorType":"UrlValidator", - "IsNegative":false, - "IsIgnoreCase":true - } - ], - "LogicalOperator":"And" - } - ], - "QueueDomain":"queueitknownusertst.test.queue-it.net", - "RedirectLogic":"AllowTParameter", - "ForcedTargetUrl":"" - }, - { - "Name":"event1 queue action (akamai)", - "ActionType":"Queue", - "EventId":"event1", - "CookieDomain":".hypequeue.com", - "LayoutName":"White Space", - "Culture":"", - "ExtendCookieValidity":true, - "CookieValidityMinute":20, - "Triggers":[ - { - "TriggerParts":[ - { - "Operator":"Contains", - "ValueToCompare":"queue-event1-nodomain", - "ValuesToCompare":null, - "UrlPart":"PageUrl", - "CookieName":null, - "HttpHeaderName":null, - "ValidatorType":"UrlValidator", - "IsNegative":false, - "IsIgnoreCase":true - } - ], - "LogicalOperator":"And" - }, - { - "TriggerParts":[ - { - "Operator":"Contains", - "ValueToCompare":"queue-event1", - "ValuesToCompare":null, - "UrlPart":"PageUrl", - "CookieName":null, - "HttpHeaderName":null, - "ValidatorType":"UrlValidator", - "IsNegative":false, - "IsIgnoreCase":true - }, - { - "Operator":"Equals", - "ValueToCompare":"bot", - "ValuesToCompare":null, - "UrlPart":null, - "CookieName":"Akamai-bot", - "HttpHeaderName":null, - "ValidatorType":"CookieValidator", - "IsNegative":true, - "IsIgnoreCase":true - }, - { - "Operator":"Contains", - "ValueToCompare":"bot", - "ValuesToCompare":null, - "UrlPart":null, - "CookieName":null, - "HttpHeaderName":null, - "ValidatorType":"UserAgentValidator", - "IsNegative":true, - "IsIgnoreCase":true - }, - { - "Operator":"Contains", - "ValueToCompare":"bot", - "ValuesToCompare":null, - "UrlPart":null, - "CookieName":null, - "HttpHeaderName":"Akamai-bot", - "ValidatorType":"HttpHeaderValidator", - "IsNegative":true, - "IsIgnoreCase":true - }, - { - "Operator":"Contains", - "ValueToCompare":"hypequeue.com", - "ValuesToCompare":null, - "UrlPart":"HostName", - "CookieName":null, - "HttpHeaderName":null, - "ValidatorType":"UrlValidator", - "IsNegative":false, - "IsIgnoreCase":true - } - ], - "LogicalOperator":"And" - } - ], - "QueueDomain":"queueitknownusertst.test.queue-it.net", - "RedirectLogic":"AllowTParameter", - "ForcedTargetUrl":"" - }, - { - "Name":"event1 cancel action (ticketania)", - "ActionType":"Cancel", - "EventId":"event1", - "CookieDomain":".ticketania.com", - "LayoutName":null, - "Culture":null, - "ExtendCookieValidity":null, - "CookieValidityMinute":0, - "Triggers":[ - { - "TriggerParts":[ - { - "Operator":"Contains", - "ValueToCompare":"cancel-event1", - "ValuesToCompare":null, - "UrlPart":"PageUrl", - "CookieName":null, - "HttpHeaderName":null, - "ValidatorType":"UrlValidator", - "IsNegative":false, - "IsIgnoreCase":true - }, - { - "Operator":"Contains", - "ValueToCompare":"ticketania", - "ValuesToCompare":null, - "UrlPart":"HostName", - "CookieName":null, - "HttpHeaderName":null, - "ValidatorType":"UrlValidator", - "IsNegative":false, - "IsIgnoreCase":true - } - ], - "LogicalOperator":"And" - } - ], - "QueueDomain":"queueitknownusertst.test.queue-it.net", - "RedirectLogic":null, - "ForcedTargetUrl":null - }, - { - "Name":"event1 cancel action (cloudflare)", - "ActionType":"Cancel", - "EventId":"event1", - "CookieDomain":".cloudflare-queue-it.com", - "LayoutName":null, - "Culture":null, - "ExtendCookieValidity":null, - "CookieValidityMinute":0, - "Triggers":[ - { - "TriggerParts":[ - { - "Operator":"Contains", - "ValueToCompare":"cancel-event1", - "ValuesToCompare":null, - "UrlPart":"PageUrl", - "CookieName":null, - "HttpHeaderName":null, - "ValidatorType":"UrlValidator", - "IsNegative":false, - "IsIgnoreCase":true - }, - { - "Operator":"Contains", - "ValueToCompare":"cloudflare-queue-it.com", - "ValuesToCompare":null, - "UrlPart":"HostName", - "CookieName":null, - "HttpHeaderName":null, - "ValidatorType":"UrlValidator", - "IsNegative":false, - "IsIgnoreCase":true - } - ], - "LogicalOperator":"And" - } - ], - "QueueDomain":"queueitknownusertst.test.queue-it.net", - "RedirectLogic":null, - "ForcedTargetUrl":null - }, - { - "Name":"event1 cancel action (akamai)", - "ActionType":"Cancel", - "EventId":"event1", - "CookieDomain":".hypequeue.com", - "LayoutName":null, - "Culture":null, - "ExtendCookieValidity":null, - "CookieValidityMinute":0, - "Triggers":[ - { - "TriggerParts":[ - { - "Operator":"Contains", - "ValueToCompare":"cancel-event1", - "ValuesToCompare":null, - "UrlPart":"PageUrl", - "CookieName":null, - "HttpHeaderName":null, - "ValidatorType":"UrlValidator", - "IsNegative":false, - "IsIgnoreCase":true - }, - { - "Operator":"Contains", - "ValueToCompare":"hypequeue.com", - "ValuesToCompare":null, - "UrlPart":"HostName", - "CookieName":null, - "HttpHeaderName":null, - "ValidatorType":"UrlValidator", - "IsNegative":false, - "IsIgnoreCase":true - } - ], - "LogicalOperator":"And" - } - ], - "QueueDomain":"queueitknownusertst.test.queue-it.net", - "RedirectLogic":null, - "ForcedTargetUrl":null - }, - { - "Name":"future queue action (default)", - "ActionType":"Queue", - "EventId":"future", - "CookieDomain":"", - "LayoutName":null, - "Culture":"", - "ExtendCookieValidity":true, - "CookieValidityMinute":20, - "Triggers":[ - { - "TriggerParts":[ - { - "Operator":"Contains", - "ValueToCompare":"idle-future-nodomain", - "ValuesToCompare":null, - "UrlPart":"PageUrl", - "CookieName":null, - "HttpHeaderName":null, - "ValidatorType":"UrlValidator", - "IsNegative":false, - "IsIgnoreCase":true - } - ], - "LogicalOperator":"And" - } - ], - "QueueDomain":"queueitknownusertst.test.queue-it.net", - "RedirectLogic":"AllowTParameter", - "ForcedTargetUrl":"" - }, - { - "Name":"future queue action (ticketania)", - "ActionType":"Queue", - "EventId":"future", - "CookieDomain":".ticketania.com", - "LayoutName":null, - "Culture":"", - "ExtendCookieValidity":true, - "CookieValidityMinute":20, - "Triggers":[ - { - "TriggerParts":[ - { - "Operator":"Contains", - "ValueToCompare":"idle-future", - "ValuesToCompare":null, - "UrlPart":"PageUrl", - "CookieName":null, - "HttpHeaderName":null, - "ValidatorType":"UrlValidator", - "IsNegative":false, - "IsIgnoreCase":true - }, - { - "Operator":"Contains", - "ValueToCompare":"ticketania", - "ValuesToCompare":null, - "UrlPart":"HostName", - "CookieName":null, - "HttpHeaderName":null, - "ValidatorType":"UrlValidator", - "IsNegative":false, - "IsIgnoreCase":true - } - ], - "LogicalOperator":"And" - } - ], - "QueueDomain":"queueitknownusertst.test.queue-it.net", - "RedirectLogic":"AllowTParameter", - "ForcedTargetUrl":"" - }, - { - "Name":"future queue action (cloudflare)", - "ActionType":"Queue", - "EventId":"future", - "CookieDomain":".cloudflare-queue-it.com", - "LayoutName":null, - "Culture":"", - "ExtendCookieValidity":true, - "CookieValidityMinute":20, - "Triggers":[ - { - "TriggerParts":[ - { - "Operator":"Contains", - "ValueToCompare":"idle-future", - "ValuesToCompare":null, - "UrlPart":"PageUrl", - "CookieName":null, - "HttpHeaderName":null, - "ValidatorType":"UrlValidator", - "IsNegative":false, - "IsIgnoreCase":true - }, - { - "Operator":"Contains", - "ValueToCompare":"cloudflare-queue-it.com", - "ValuesToCompare":null, - "UrlPart":"HostName", - "CookieName":null, - "HttpHeaderName":null, - "ValidatorType":"UrlValidator", - "IsNegative":false, - "IsIgnoreCase":true - } - ], - "LogicalOperator":"And" - } - ], - "QueueDomain":"queueitknownusertst.test.queue-it.net", - "RedirectLogic":"AllowTParameter", - "ForcedTargetUrl":"" - }, - { - "Name":"future queue action (akamai)", - "ActionType":"Queue", - "EventId":"future", - "CookieDomain":".hypequeue.com", - "LayoutName":null, - "Culture":"", - "ExtendCookieValidity":true, - "CookieValidityMinute":20, - "Triggers":[ - { - "TriggerParts":[ - { - "Operator":"Contains", - "ValueToCompare":"idle-future", - "ValuesToCompare":null, - "UrlPart":"PageUrl", - "CookieName":null, - "HttpHeaderName":null, - "ValidatorType":"UrlValidator", - "IsNegative":false, - "IsIgnoreCase":true - }, - { - "Operator":"Contains", - "ValueToCompare":"hypequeue.com", - "ValuesToCompare":null, - "UrlPart":"HostName", - "CookieName":null, - "HttpHeaderName":null, - "ValidatorType":"UrlValidator", - "IsNegative":false, - "IsIgnoreCase":true - } - ], - "LogicalOperator":"And" - } - ], - "QueueDomain":"queueitknownusertst.test.queue-it.net", - "RedirectLogic":"AllowTParameter", - "ForcedTargetUrl":"" - }, - { - "Name":"disabled queue action (default)", - "ActionType":"Queue", - "EventId":"disabled", - "CookieDomain":"", - "LayoutName":null, - "Culture":"", - "ExtendCookieValidity":true, - "CookieValidityMinute":20, - "Triggers":[ - { - "TriggerParts":[ - { - "Operator":"Contains", - "ValueToCompare":"queue-disabled-nodomain", - "ValuesToCompare":null, - "UrlPart":"PageUrl", - "CookieName":null, - "HttpHeaderName":null, - "ValidatorType":"UrlValidator", - "IsNegative":false, - "IsIgnoreCase":true - } - ], - "LogicalOperator":"And" - } - ], - "QueueDomain":"queueitknownusertst.test.queue-it.net", - "RedirectLogic":"AllowTParameter", - "ForcedTargetUrl":"" - }, - { - "Name":"disabled [not extend cookie] queue action (default)", - "ActionType":"Queue", - "EventId":"disabled", - "CookieDomain":"", - "LayoutName":null, - "Culture":"", - "ExtendCookieValidity":false, - "CookieValidityMinute":20, - "Triggers":[ - { - "TriggerParts":[ - { - "Operator":"Contains", - "ValueToCompare":"queue-disabled-notextendcookie-nodomain", - "ValuesToCompare":null, - "UrlPart":"PageUrl", - "CookieName":null, - "HttpHeaderName":null, - "ValidatorType":"UrlValidator", - "IsNegative":false, - "IsIgnoreCase":true - } - ], - "LogicalOperator":"And" - } - ], - "QueueDomain":"queueitknownusertst.test.queue-it.net", - "RedirectLogic":"AllowTParameter", - "ForcedTargetUrl":"" - }, - { - "Name":"disabled queue action (ticketania)", - "ActionType":"Queue", - "EventId":"disabled", - "CookieDomain":".ticketania.com", - "LayoutName":null, - "Culture":"", - "ExtendCookieValidity":true, - "CookieValidityMinute":20, - "Triggers":[ - { - "TriggerParts":[ - { - "Operator":"Contains", - "ValueToCompare":"queue-disabled", - "ValuesToCompare":null, - "UrlPart":"PageUrl", - "CookieName":null, - "HttpHeaderName":null, - "ValidatorType":"UrlValidator", - "IsNegative":false, - "IsIgnoreCase":true - }, - { - "Operator":"Contains", - "ValueToCompare":"ticketania", - "ValuesToCompare":null, - "UrlPart":"HostName", - "CookieName":null, - "HttpHeaderName":null, - "ValidatorType":"UrlValidator", - "IsNegative":false, - "IsIgnoreCase":true - } - ], - "LogicalOperator":"And" - } - ], - "QueueDomain":"queueitknownusertst.test.queue-it.net", - "RedirectLogic":"AllowTParameter", - "ForcedTargetUrl":"" - }, - { - "Name":"disabled queue action (cloudflare)", - "ActionType":"Queue", - "EventId":"disabled", - "CookieDomain":".cloudflare-queue-it.com", - "LayoutName":null, - "Culture":"", - "ExtendCookieValidity":true, - "CookieValidityMinute":20, - "Triggers":[ - { - "TriggerParts":[ - { - "Operator":"Contains", - "ValueToCompare":"queue-disabled", - "ValuesToCompare":null, - "UrlPart":"PageUrl", - "CookieName":null, - "HttpHeaderName":null, - "ValidatorType":"UrlValidator", - "IsNegative":false, - "IsIgnoreCase":true - }, - { - "Operator":"Contains", - "ValueToCompare":"cloudflare-queue-it.com", - "ValuesToCompare":null, - "UrlPart":"HostName", - "CookieName":null, - "HttpHeaderName":null, - "ValidatorType":"UrlValidator", - "IsNegative":false, - "IsIgnoreCase":true - } - ], - "LogicalOperator":"And" - } - ], - "QueueDomain":"queueitknownusertst.test.queue-it.net", - "RedirectLogic":"AllowTParameter", - "ForcedTargetUrl":"" - }, - { - "Name":"disabled queue action (akamai)", - "ActionType":"Queue", - "EventId":"disabled", - "CookieDomain":".hypequeue.com", - "LayoutName":null, - "Culture":"", - "ExtendCookieValidity":true, - "CookieValidityMinute":20, - "Triggers":[ - { - "TriggerParts":[ - { - "Operator":"Contains", - "ValueToCompare":"queue-disabled", - "ValuesToCompare":null, - "UrlPart":"PageUrl", - "CookieName":null, - "HttpHeaderName":null, - "ValidatorType":"UrlValidator", - "IsNegative":false, - "IsIgnoreCase":true - }, - { - "Operator":"Contains", - "ValueToCompare":"hypequeue.com", - "ValuesToCompare":null, - "UrlPart":"HostName", - "CookieName":null, - "HttpHeaderName":null, - "ValidatorType":"UrlValidator", - "IsNegative":false, - "IsIgnoreCase":true - } - ], - "LogicalOperator":"And" - } - ], - "QueueDomain":"queueitknownusertst.test.queue-it.net", - "RedirectLogic":"AllowTParameter", - "ForcedTargetUrl":"" - }, - { - "Name":"safetynet queue action (default)", - "ActionType":"Queue", - "EventId":"safetynet", - "CookieDomain":"", - "LayoutName":null, - "Culture":"", - "ExtendCookieValidity":true, - "CookieValidityMinute":20, - "Triggers":[ - { - "TriggerParts":[ - { - "Operator":"Contains", - "ValueToCompare":"queue-safetynet-nodomain", - "ValuesToCompare":null, - "UrlPart":"PageUrl", - "CookieName":null, - "HttpHeaderName":null, - "ValidatorType":"UrlValidator", - "IsNegative":false, - "IsIgnoreCase":true - } - ], - "LogicalOperator":"And" - } - ], - "QueueDomain":"queueitknownusertst.test.queue-it.net", - "RedirectLogic":"AllowTParameter", - "ForcedTargetUrl":"" - }, - { - "Name":"test02082018", - "ActionType":"Queue", - "EventId":"test02082018", - "CookieDomain":"", - "LayoutName":null, - "Culture":"", - "ExtendCookieValidity":false, - "CookieValidityMinute":20, - "Triggers":[ - { - "TriggerParts":[ - { - "Operator":"Contains", - "ValueToCompare":"test02082018", - "ValuesToCompare":null, - "UrlPart":"PageUrl", - "CookieName":null, - "HttpHeaderName":null, - "ValidatorType":"UrlValidator", - "IsNegative":false, - "IsIgnoreCase":true - } - ], - "LogicalOperator":"And" - } - ], - "QueueDomain":"queueitknownusertst.test.queue-it.net", - "RedirectLogic":"AllowTParameter", - "ForcedTargetUrl":"" - }, - { - "Name":"Integration - With InvolvedWaitingRoomIds null", - "ActionType":"Queue", - "EventId":"event1", - "InvolvedWaitingRoomIds":null, - "Triggers":[ - { - "TriggerParts":[ - { - "ValidatorType":"UrlValidator", - "Operator":"Contains", - "ValueToCompare":"test1", - "IsNegative":false, - "IsIgnoreCase":true - } - ], - "LogicalOperator":"And" - } - ] - } - ], - "CustomerId":"queueitknownusertst", - "AccountId":"queueit-mosa", - "Version":55, - "PublishDate":"2021-05-25T08:43:43.3277603Z", - "ConfigDataVersion":"1.0.0.3" -}`; - const customerIntegrationInfo = CustomerIntegrationDecodingHandler.deserialize(integrationConfigString); - - expect(customerIntegrationInfo.Version).toBe(55); - expect(customerIntegrationInfo.Description).toBe("tst"); - expect(customerIntegrationInfo.Integrations.length).toBe(25); - - // Test InvolvedWaitingRoomIds array handling first (verifies no trigger accumulation bug) - expect(customerIntegrationInfo.Integrations[0].Name).toBe('Integration - With InvolvedWaitingRoomIds'); - expect(customerIntegrationInfo.Integrations[0].Triggers.length).toBe(1); - - expect(customerIntegrationInfo.Integrations[1].Name).toBe("mojitest"); - expect(customerIntegrationInfo.Integrations[2].Name).toBe("all pages"); - let triggerModel = customerIntegrationInfo.Integrations[1].Triggers[0]; - expect(triggerModel.LogicalOperator).toBe("And"); - expect(triggerModel.TriggerParts[0].ValueToCompare).toBe("mojitest"); - expect(triggerModel.TriggerParts[0].IsNegative).toBe(false); - expect(triggerModel.TriggerParts[0].IsIgnoreCase).toBe(true); - - triggerModel = customerIntegrationInfo.Integrations[2].Triggers[0]; - expect(triggerModel.TriggerParts[0].ValueToCompare).toBe('test02082018'); - - triggerModel = customerIntegrationInfo.Integrations[3].Triggers[0]; - expect(triggerModel.TriggerParts[1].ValuesToCompare.length).toBe(2); - expect(triggerModel.TriggerParts[1].ValuesToCompare[0]).toBe('ignore-this-queue-event1-nodomain'); - expect(triggerModel.TriggerParts[1].ValuesToCompare[1]).toBe('ignore-that-queue-event1-nodomain'); - - expect(customerIntegrationInfo.Integrations[24].Name).toBe('Integration - With InvolvedWaitingRoomIds null'); - expect(customerIntegrationInfo.Integrations[24].Triggers.length).toBe(1); - }); -}) diff --git a/src/__tests__/IntegrationConfigHelpersTest.spec.ts b/src/__tests__/IntegrationConfigHelpersTest.spec.ts deleted file mode 100644 index a147256..0000000 --- a/src/__tests__/IntegrationConfigHelpersTest.spec.ts +++ /dev/null @@ -1,574 +0,0 @@ -import { - ComparisonOperatorHelper, - CookieValidatorHelper, HttpHeaderValidatorHelper, IntegrationEvaluator, - UrlValidatorHelper, UserAgentValidatorHelper -} from "../sdk/IntegrationConfig/IntegrationConfigHelpers"; -import {ComparisonOperatorType, TriggerPart, UrlPartType} from "../sdk/IntegrationConfig/IntegrationConfigModel"; -import {CustomerIntegrationDecodingHandler} from "../sdk/IntegrationConfig/CustomerIntegrationDecodingHandler"; -import {MockHttpContextProvider, MockHttpRequest, MockHttpResponse} from "./Mocks"; - -const httpContextMock = new MockHttpContextProvider(new MockHttpRequest(), new MockHttpResponse()); - -function resetMocks(): void { - httpContextMock.reset(); -} - -describe('ComparisonOperatorHelper', () => { - it('should evaluate_equals', () => { - expect(ComparisonOperatorHelper.evaluate(ComparisonOperatorType.EqualS, false, false, "test1", "test1", null)).toBeTruthy(); - expect(ComparisonOperatorHelper.evaluate(ComparisonOperatorType.EqualS, false, false, "test1", "Test1", null)).toBeFalsy(); - expect(ComparisonOperatorHelper.evaluate(ComparisonOperatorType.EqualS, false, true, "test1", "Test1", null)).toBeTruthy(); - expect(ComparisonOperatorHelper.evaluate(ComparisonOperatorType.EqualS, true, false, "test1", "Test1", null)).toBeTruthy(); - expect(ComparisonOperatorHelper.evaluate(ComparisonOperatorType.EqualS, true, false, "test1", "test1", null)).toBeFalsy(); - expect(ComparisonOperatorHelper.evaluate(ComparisonOperatorType.EqualS, true, true, "test1", "Test1", null)).toBeFalsy(); - }); - - it('should evaluate_contains', () => { - expect(ComparisonOperatorHelper.evaluate(ComparisonOperatorType.Contains, false, false, "test_test1_test", "test1", null)).toBeTruthy(); - expect(ComparisonOperatorHelper.evaluate(ComparisonOperatorType.Contains, false, false, "test_test1_test", "Test1", null)).toBeFalsy(); - expect(ComparisonOperatorHelper.evaluate(ComparisonOperatorType.Contains, false, true, "test_test1_test", "Test1", null)).toBeTruthy(); - expect(ComparisonOperatorHelper.evaluate(ComparisonOperatorType.Contains, true, false, "test_test1_test", "Test1", null)).toBeTruthy(); - expect(ComparisonOperatorHelper.evaluate(ComparisonOperatorType.Contains, true, true, "test_test1", "Test1", null)).toBeFalsy(); - expect(ComparisonOperatorHelper.evaluate(ComparisonOperatorType.Contains, true, false, "test_test1", "test1", null)).toBeFalsy(); - expect(ComparisonOperatorHelper.evaluate(ComparisonOperatorType.Contains, false, false, "test_dsdsdsdtest1", "*", null)).toBeTruthy(); - expect(ComparisonOperatorHelper.evaluate(ComparisonOperatorType.Contains, false, false, "", "*", null)).toBeFalsy(); - }); - - it('should evaluate_equals_any', () => { - expect(ComparisonOperatorHelper.evaluate(ComparisonOperatorType.EqualsAny, false, false, "test1", '', ["test1"])).toBeTruthy(); - expect(ComparisonOperatorHelper.evaluate(ComparisonOperatorType.EqualsAny, false, false, "test1", '', ["Test1"])).toBeFalsy(); - expect(ComparisonOperatorHelper.evaluate(ComparisonOperatorType.EqualsAny, false, true, "test1", '', ["Test1"])).toBeTruthy(); - expect(ComparisonOperatorHelper.evaluate(ComparisonOperatorType.EqualsAny, true, false, "test1", '', ["Test1"])).toBeTruthy(); - expect(ComparisonOperatorHelper.evaluate(ComparisonOperatorType.EqualsAny, true, false, "test1", '', ["test1"])).toBeFalsy(); - expect(ComparisonOperatorHelper.evaluate(ComparisonOperatorType.EqualsAny, true, true, "test1", '', ["Test1"])).toBeFalsy(); - }); - - it('should evaluate_contains_any', () => { - expect(ComparisonOperatorHelper.evaluate(ComparisonOperatorType.ContainsAny, false, false, "test_test1_test", '', ["test1"])).toBeTruthy(); - expect(ComparisonOperatorHelper.evaluate(ComparisonOperatorType.ContainsAny, false, false, "test_test1_test", '', ["Test1"])).toBeFalsy(); - expect(ComparisonOperatorHelper.evaluate(ComparisonOperatorType.ContainsAny, false, true, "test_test1_test", '', ["Test1"])).toBeTruthy(); - expect(ComparisonOperatorHelper.evaluate(ComparisonOperatorType.ContainsAny, true, false, "test_test1_test", '', ["Test1"])).toBeTruthy(); - expect(ComparisonOperatorHelper.evaluate(ComparisonOperatorType.ContainsAny, true, true, "test_test1", '', ["Test1"])).toBeFalsy(); - expect(ComparisonOperatorHelper.evaluate(ComparisonOperatorType.ContainsAny, true, false, "test_test1", '', ["test1"])).toBeFalsy(); - expect(ComparisonOperatorHelper.evaluate(ComparisonOperatorType.ContainsAny, false, false, "test_dsdsdsdtest1", '', ["*"])).toBeTruthy(); - }); -}); - -describe('ValidatorHelpers', () => { - it('should cookie_evaluate', () => { - resetMocks(); - - const triggerPart = new TriggerPart(); - triggerPart.CookieName = "c1"; - triggerPart.Operator = ComparisonOperatorType.Contains; - triggerPart.ValueToCompare = "1"; - - expect(CookieValidatorHelper.evaluate(triggerPart, httpContextMock.req)).toBeFalsy(); - - httpContextMock.req.setCookieValue("c5", "5") - .setCookieValue("c1", "1") - .setCookieValue("c2", "test"); - expect(CookieValidatorHelper.evaluate(triggerPart, httpContextMock.req)).toBeTruthy(); - - triggerPart.ValueToCompare = "5"; - expect(CookieValidatorHelper.evaluate(triggerPart, httpContextMock.req)).toBeFalsy(); - - triggerPart.ValueToCompare = "Test"; - triggerPart.IsIgnoreCase = true; - triggerPart.CookieName = "c2"; - expect(CookieValidatorHelper.evaluate(triggerPart, httpContextMock.req)).toBeTruthy(); - - triggerPart.ValueToCompare = "Test"; - triggerPart.IsIgnoreCase = true; - triggerPart.IsNegative = true; - triggerPart.CookieName = "c2"; - expect(CookieValidatorHelper.evaluate(triggerPart, httpContextMock.req)).toBeFalsy(); - }); - - it('should url_evaluate', () => { - resetMocks(); - - const triggerPart = new TriggerPart(); - triggerPart.UrlPart = UrlPartType.PageUrl; - triggerPart.Operator = ComparisonOperatorType.Contains; - triggerPart.ValueToCompare = "http://test.tesdomain.com:8080/test?q=1"; - - expect(UrlValidatorHelper.evaluate(triggerPart, "http://test.tesdomain.com:8080/test?q=2")).toBeFalsy(); - - triggerPart.ValueToCompare = "/Test/t1"; - triggerPart.UrlPart = UrlPartType.PagePath; - triggerPart.Operator = ComparisonOperatorType.EqualS; - triggerPart.IsIgnoreCase = true; - expect(UrlValidatorHelper.evaluate(triggerPart, "http://test.tesdomain.com:8080/test/t1?q=2&y02")).toBeTruthy(); - - triggerPart.UrlPart = UrlPartType.HostName; - triggerPart.ValueToCompare = "test.tesdomain.com"; - triggerPart.Operator = ComparisonOperatorType.Contains; - expect(UrlValidatorHelper.evaluate(triggerPart, "http://m.test.tesdomain.com:8080/test?q=2")).toBeTruthy(); - - triggerPart.UrlPart = UrlPartType.HostName; - triggerPart.ValueToCompare = "test.tesdomain.com"; - triggerPart.IsNegative = true; - triggerPart.Operator = ComparisonOperatorType.Contains; - expect(UrlValidatorHelper.evaluate(triggerPart, "http://m.test.tesdomain.com:8080/test?q=2")).toBeFalsy(); - }); - - it('should userAgent_evaluate', () => { - resetMocks(); - - const triggerPart = new TriggerPart(); - triggerPart.Operator = ComparisonOperatorType.Contains; - triggerPart.ValueToCompare = "googlebot"; - - expect(UserAgentValidatorHelper.evaluate(triggerPart, "Googlebot sample useraagent")).toBeFalsy(); - - triggerPart.ValueToCompare = "googlebot"; - triggerPart.Operator = ComparisonOperatorType.EqualS; - triggerPart.IsIgnoreCase = true; - triggerPart.IsNegative = true; - expect(UserAgentValidatorHelper.evaluate(triggerPart, "oglebot sample useraagent")).toBeTruthy(); - - triggerPart.ValueToCompare = "googlebot"; - triggerPart.Operator = ComparisonOperatorType.Contains; - triggerPart.IsIgnoreCase = false; - triggerPart.IsNegative = true; - expect(UserAgentValidatorHelper.evaluate(triggerPart, "googlebot")).toBeFalsy(); - - triggerPart.ValueToCompare = "googlebot"; - triggerPart.IsIgnoreCase = true; - triggerPart.IsNegative = false; - triggerPart.Operator = ComparisonOperatorType.Contains; - expect(UserAgentValidatorHelper.evaluate(triggerPart, "Googlebot")).toBeTruthy(); - - triggerPart.ValueToCompare = ''; - triggerPart.ValuesToCompare = ["googlebot"]; - triggerPart.IsIgnoreCase = true; - triggerPart.IsNegative = false; - triggerPart.Operator = ComparisonOperatorType.ContainsAny; - expect(UserAgentValidatorHelper.evaluate(triggerPart, "Googlebot")).toBeTruthy(); - - triggerPart.ValuesToCompare = ["googlebot"]; - triggerPart.IsIgnoreCase = true; - triggerPart.IsNegative = true; - triggerPart.Operator = ComparisonOperatorType.EqualsAny; - expect(UserAgentValidatorHelper.evaluate(triggerPart, "oglebot sample useraagent")).toBeTruthy(); - }); - - it('should httpHeader_evaluate', () => { - resetMocks(); - - const triggerPart = new TriggerPart(); - triggerPart.Operator = ComparisonOperatorType.Contains; - triggerPart.ValueToCompare = "1"; - - expect(HttpHeaderValidatorHelper.evaluate(triggerPart, "")).toBeFalsy(); - - expect(HttpHeaderValidatorHelper.evaluate(triggerPart, "1")).toBeTruthy(); - - triggerPart.ValueToCompare = "5"; - expect(HttpHeaderValidatorHelper.evaluate(triggerPart, "1")).toBeFalsy(); - - triggerPart.ValueToCompare = "Test"; - triggerPart.IsIgnoreCase = true; - expect(HttpHeaderValidatorHelper.evaluate(triggerPart, "test")).toBeTruthy(); - - triggerPart.ValueToCompare = "Test"; - triggerPart.IsIgnoreCase = true; - triggerPart.IsNegative = true; - expect(HttpHeaderValidatorHelper.evaluate(triggerPart, "test")).toBeFalsy(); - }); -}); - -describe('IntegrationConfigHelpers', () => { - it('should getMatchedIntegrationConfig_OneTrigger_And_NotMatched', () => { - resetMocks(); - - const integrationsConfigString = `{ - "Integrations": [{ - "Triggers": [{ - "LogicalOperator": - "Or", - "TriggerParts": [{ - "CookieName": "c1", - "Operator": "Equals", - "ValueToCompare": "value1", - "ValidatorType": "CookieValidator" - },{ - "ValidatorType": "UserAgentValidator", - "ValueToCompare": "test", - "Operator": "Contains" - }] - }] - }] - }`; - - const integrationConfig = CustomerIntegrationDecodingHandler.deserialize(integrationsConfigString); - const url = "http://test.tesdomain.com:8080/test?q=2"; - - const testObj = new IntegrationEvaluator(); - const result = testObj.getMatchedIntegrationConfig(integrationConfig, url, httpContextMock.req); - expect(result).toBeNull(); - }); - - it('should getMatchedIntegrationConfig_OneTrigger_And_Matched', () => { - resetMocks(); - - httpContextMock.req.setCookieValue("c1", "Value1"); - const integrationsConfigString = `{ - "Integrations": [{ - "Name": "integration1", - "Triggers": [{ - "LogicalOperator": "And", - "TriggerParts": [{ - "CookieName": "c1", - "Operator": "Equals", - "IsIgnoreCase" : true, - "ValueToCompare": "value1", - "ValidatorType": "CookieValidator" - },{ - "UrlPart": "PageUrl", - "ValidatorType": "UrlValidator", - "ValueToCompare": "test", - "Operator": "Contains" - }] - }] - }] - }`; - - const integrationConfig = CustomerIntegrationDecodingHandler.deserialize(integrationsConfigString); - const url = "http://test.tesdomain.com:8080/test?q=2"; - const result = (new IntegrationEvaluator()).getMatchedIntegrationConfig(integrationConfig, url, httpContextMock.req); - - expect(result).not.toBeNull(); - expect(result!.first).not.toBeNull(); - expect(result!.first!.Name).toBe('integration1'); - }); - - it('should getMatchedIntegrationConfig_OneTrigger_And_NotMatched_UserAgent', () => { - resetMocks(); - - httpContextMock.req.setCookieValue("c1", "Value1"); - httpContextMock.req.setUserAgent("bot.html google.com googlebot test") - - const integrationsConfigString = `{ - "Integrations": [{ - "Name": "integration1", - "Triggers": [{ - "LogicalOperator": "And", - "TriggerParts": [{ - "CookieName": "c1", - "Operator": "Equals", - "IsIgnoreCase" : true, - "IsNegative": false, - "ValueToCompare": "value1", - "ValidatorType": "CookieValidator" - },{ - "UrlPart": "PageUrl", - "ValidatorType": "UrlValidator", - "ValueToCompare": "test", - "IsIgnoreCase": false, - "IsNegative": false, - "Operator": "Contains" - },{ - "ValidatorType": "UserAgentValidator", - "ValueToCompare": "Googlebot", - "Operator": "Contains", - "IsIgnoreCase": true, - "IsNegative": true - }] - }] - }] - }`; - - const integrationConfig = CustomerIntegrationDecodingHandler.deserialize(integrationsConfigString); - const url = "http://test.tesdomain.com:8080/test?q=2"; - const result = (new IntegrationEvaluator()).getMatchedIntegrationConfig(integrationConfig, url, httpContextMock.req); - - expect(result).toBeNull(); - }); - - it('should getMatchedIntegrationConfig_OneTrigger_And_NotMatched_HttpHeader', () => { - resetMocks(); - - httpContextMock.req.setCookieValue("c2", "ddd") - .setCookieValue("c1", "Value1") - .setHeader("c1", "t1") - .setHeader("headertest", "abcd efg test gklm"); - const integrationsConfigString = `{ - "Integrations": [{ - "Name": - "integration1", - "Triggers": [{ - "LogicalOperator": - "And", - "TriggerParts": [{ - "CookieName": "c1", - "Operator": "Equals", - "ValueToCompare": "value1", - "ValidatorType": "CookieValidator", - "IsIgnoreCase": true, - "IsNegative": false - },{ - "UrlPart": "PageUrl", - "ValidatorType": "UrlValidator", - "ValueToCompare": "test", - "Operator": "Contains", - "IsIgnoreCase": false, - "IsNegative": false - },{ - "ValidatorType": "HttpHeaderValidator", - "ValueToCompare": "test", - "HttpHeaderName": "HeaderTest", - "Operator": "Contains", - "IsIgnoreCase": true, - "IsNegative": true - }] - }] - }] - }`; - - const integrationConfig = CustomerIntegrationDecodingHandler.deserialize(integrationsConfigString); - const url = "http://www.tesdomain.com:8080/test?q=2"; - - expect((new IntegrationEvaluator()).getMatchedIntegrationConfig(integrationConfig, url, httpContextMock.req) == null).toBeTruthy(); - }); - - it('should getMatchedIntegrationConfig_OneTrigger_And_Matched_RequestBody', () => { - resetMocks(); - - httpContextMock.req.setCookieValue("c2", "ddd") - .setCookieValue("c1", "Value1") - .setHeader("c1", "t1") - .setHeader("headertest", "abcd efg test gklm") - .setBody("test body test request"); - - const integrationsConfigString = `{ - "Integrations": [{ - "Name": - "integration1", - "Triggers": [{ - "LogicalOperator": - "And", - "TriggerParts": [{ - "CookieName": "c1", - "Operator": "Equals", - "ValueToCompare": "value1", - "ValidatorType": "CookieValidator", - "IsIgnoreCase": true, - "IsNegative": false - },{ - "UrlPart": "PageUrl", - "ValidatorType": "UrlValidator", - "ValueToCompare": "test", - "Operator": "Contains", - "IsIgnoreCase": false, - "IsNegative": false - },{ - "ValidatorType": "RequestBodyValidator", - "ValueToCompare": "test body", - "Operator": "Contains", - "IsIgnoreCase": true, - "IsNegative": false - }] - }] - }] - }`; - - const integrationConfig = CustomerIntegrationDecodingHandler.deserialize(integrationsConfigString); - const url = "http://www.tesdomain.com:8080/test?q=2"; - - const result = (new IntegrationEvaluator()).getMatchedIntegrationConfig(integrationConfig, url, httpContextMock.req); - expect(result).not.toBeNull(); - expect(result!.first).not.toBeNull(); - expect(result!.first!.Name).toBe('integration1'); - }); - - it('should getMatchedIntegrationConfig_OneTrigger_Or_NotMatched', () => { - resetMocks(); - - httpContextMock.req.setCookieValue("c2", "Value1"); - const integrationsConfigString = `{ - "Integrations": [{ - "Name": - "integration1", - "Triggers": [{ - "LogicalOperator": - "Or", - "TriggerParts": [{ - "CookieName": "c1", - "Operator": "Equals", - "ValueToCompare": "value1", - "ValidatorType": "CookieValidator" - },{ - "UrlPart": "PageUrl", - "ValidatorType": "UrlValidator", - "IsIgnoreCase": true, - "IsNegative": true, - "ValueToCompare": "test", - "Operator": "Contains" - }] - }] - }] - }`; - - const integrationConfig = CustomerIntegrationDecodingHandler.deserialize(integrationsConfigString); - const url = "http://test.tesdomain.com:8080/test?q=2"; - const result = (new IntegrationEvaluator()).getMatchedIntegrationConfig(integrationConfig, url, httpContextMock.req); - - expect(result).toBeNull(); - }); - - it('should getMatchedIntegrationConfig_OneTrigger_Or_Matched', () => { - resetMocks(); - - httpContextMock.req.setCookieValue("c1", "Value1"); - const integrationsConfigString = `{ - "Integrations": [{ - "Name": - "integration1", - "Triggers": [{ - "LogicalOperator": - "Or", - "TriggerParts": [{ - "CookieName": "c1", - "Operator": "Equals", - "ValueToCompare": "value1", - "ValidatorType": "CookieValidator" - },{ - "UrlPart": "PageUrl", - "ValidatorType": "UrlValidator", - "ValueToCompare": "test", - "Operator": "Contains" - }] - }] - }] - }`; - - const integrationConfig = CustomerIntegrationDecodingHandler.deserialize(integrationsConfigString); - const url = "http://test.tesdomain.com:8080/test?q=2"; - const result = (new IntegrationEvaluator()).getMatchedIntegrationConfig(integrationConfig, url, httpContextMock.req); - - expect(result).not.toBeNull(); - expect(result!.first).not.toBeNull(); - expect(result!.first!.Name == "integration1").toBeTruthy(); - }); - - it('should getMatchedIntegrationConfig_TwoTriggers_Matched', () => { - resetMocks(); - - httpContextMock.req.setCookieValue("c1", "Value1"); - const integrationsConfigString = `{ - "Integrations": [{ - "Name": "integration1", - "Triggers": [{ - "LogicalOperator": "And", - "TriggerParts": [{ - "CookieName": "c1", - "Operator": "Equals", - "ValueToCompare": "value1", - "ValidatorType": "CookieValidator", - "IsIgnoreCase": true, - "IsNegative": false - },{ - "UrlPart": "PageUrl", - "ValidatorType": "UrlValidator", - "ValueToCompare": "*", - "Operator": "Contains" - }] - }] - }] - }`; - - const integrationConfig = CustomerIntegrationDecodingHandler.deserialize(integrationsConfigString); - const url = "http://test.tesdomain.com:8080/test?q=2"; - const result = (new IntegrationEvaluator()).getMatchedIntegrationConfig(integrationConfig, url, httpContextMock.req); - - expect(result).not.toBeNull(); - expect(result!.first).not.toBeNull(); - expect(result!.first!.Name).toBe('integration1'); - }); - - it('should getMatchedIntegrationConfig_TwoTriggers_NotMatched', () => { - resetMocks(); - - const integrationsConfigString = `{ - "Integrations": [{ - "Name": - "integration1", - "Triggers": [{ - "LogicalOperator": - "And", - "TriggerParts": [{ - "CookieName": "c1", - "Operator": "Equals", - "ValueToCompare": "value1", - "ValidatorType": "CookieValidator" - },{ - "UrlPart": "PageUrl", - "ValidatorType": "UrlValidator", - "ValueToCompare": "tesT", - "Operator": "Contains" - }] - }] - }] - }`; - - const integrationConfig = CustomerIntegrationDecodingHandler.deserialize(integrationsConfigString); - const url = "http://test.tesdomain.com:8080/test?q=2"; - const result = (new IntegrationEvaluator()).getMatchedIntegrationConfig(integrationConfig, url, httpContextMock.req); - - expect(result).toBeNull(); - }); - - it('should getMatchedIntegrationConfig_ThreeIntegrationsInOrder_SecondMatched', () => { - resetMocks(); - - httpContextMock.req.setCookieValue("c1", "Value1"); - const integrationsConfigString = `{ - "Integrations": [{ - "Name": "integration0", - "Triggers": [{ - "LogicalOperator": "And", - "TriggerParts": [{ - "CookieName": "c1", - "Operator": "Equals", - "ValueToCompare": "value1", - "ValidatorType": "CookieValidator" - }] - }] - }], - "Integrations": [{ - "Name": "integration1", - "Triggers": [{ - "LogicalOperator": "And", - "TriggerParts": [{ - "CookieName": "c1", - "Operator": "Equals", - "ValueToCompare": "value1", - "ValidatorType": "CookieValidator" - }] - }] - }], - "Integrations": [{ - "Name": "integration2", - "Triggers": [{ - "LogicalOperator": "And", - "TriggerParts": [{ - "UrlPart": "PageUrl", - "Operator": "Contains", - "ValueToCompare": "test", - "ValidatorType": "UrlValidator" - }] - }] - }] - }`; - - const integrationConfig = CustomerIntegrationDecodingHandler.deserialize(integrationsConfigString); - const url = "http://test.tesdomain.com:8080/test?q=2"; - const result = (new IntegrationEvaluator()).getMatchedIntegrationConfig(integrationConfig, url, httpContextMock.req) - - expect(result).not.toBeNull(); - expect(result!.first).not.toBeNull(); - expect(result!.first!.Name == "integration2").toBeTruthy(); - }); -}); diff --git a/src/__tests__/KnownUserTest.spec.ts b/src/__tests__/KnownUserTest.spec.ts deleted file mode 100644 index bf7b4d5..0000000 --- a/src/__tests__/KnownUserTest.spec.ts +++ /dev/null @@ -1,1893 +0,0 @@ -import {QueueParameterHelper, Utils} from "../sdk/QueueITHelpers"; -import {UserInQueueService} from "../sdk/UserInQueueService"; -import {CancelEventConfig, QueueEventConfig, RequestValidationResult} from "../sdk/Models"; -import { - MockDateTimeProvider, - MockHttpContextProvider, - MockHttpRequest, MockHttpResponse, - UserInQueueServiceMock, - UserInQueueStateCookieRepositoryMock, ValidateQueueRequestCall -} from "./Mocks"; -import {hmacString} from '../sdk/helpers/crypto' -import {KnownUser} from '../sdk/KnownUser'; - -Utils.generateSHA256Hash = hmacString; - -const SDK_VERSION = UserInQueueService.SDK_VERSION; -const userInQueueServiceMock = new UserInQueueServiceMock(new UserInQueueStateCookieRepositoryMock()); -const httpContextMock = new MockHttpContextProvider(new MockHttpRequest(), new MockHttpResponse()); - -function resetMocks(): void { - userInQueueServiceMock.reset(); - httpContextMock.reset(); -} - -function generateDebugToken(eventId: string, secretKey: string, expiredToken: boolean = false): string { - let timeStamp = Utils.getCurrentTime() + 3 * 60; - - if (expiredToken) { - timeStamp = timeStamp - 1000; - } - - const tokenWithoutHash: string = - QueueParameterHelper.EventIdKey + - QueueParameterHelper.KeyValueSeparatorChar + - eventId + - QueueParameterHelper.KeyValueSeparatorGroupChar + - QueueParameterHelper.RedirectTypeKey + - QueueParameterHelper.KeyValueSeparatorChar + - "debug" + - QueueParameterHelper.KeyValueSeparatorGroupChar + - QueueParameterHelper.TimeStampKey + - QueueParameterHelper.KeyValueSeparatorChar + - timeStamp.toString(); - - const hashValue = Utils.generateSHA256Hash(secretKey, tokenWithoutHash); - - return tokenWithoutHash + - QueueParameterHelper.KeyValueSeparatorGroupChar + - QueueParameterHelper.HashKey + - QueueParameterHelper.KeyValueSeparatorChar + - hashValue; -} - -function mockGoogleHeaders(): void { - httpContextMock.req.headers.set('user-agent', 'googlebot'); - httpContextMock.req.headers.set('via', 'v'); - httpContextMock.req.headers.set('forwarded', 'f'); - httpContextMock.req.headers.set('x-forwarded-for', 'xff'); - httpContextMock.req.headers.set('x-forwarded-host', 'xfh'); - httpContextMock.req.headers.set('x-forwarded-proto', 'xfp'); -} - -describe('extendQueueCookie', () => { - it('should handle NullEventId', () => { - //Arrange - resetMocks(); - - //Act - const err = KnownUser.extendQueueCookie("", 0, "", "", httpContextMock); - const exceptionWasThrown = err != null && err.message == "eventId can not be null or empty."; - - //Assert - expect(userInQueueServiceMock.extendQueueCookieCall).toBeNull(); - expect(exceptionWasThrown).toBeTruthy(); - }); - - it('should handle InvalidCookieValidityMinutes', () => { - //Arrange - resetMocks(); - - //Act - const err = KnownUser.extendQueueCookie("eventId", -1, "cookiedomain", "secretkey", httpContextMock); - const exceptionWasThrown = err != null && err.message == "cookieValidityMinute should be integer greater than 0."; - - //Assert - expect(userInQueueServiceMock.extendQueueCookieCall).toBeNull(); - expect(exceptionWasThrown).toBeTruthy(); - }); - - it('should handle NullSecretKey', () => { - //Arrange - resetMocks(); - - //Act - const err = KnownUser.extendQueueCookie("eventId", 20, "cookiedomain", '', httpContextMock); - const exceptionWasThrown = err != null && err.message == "secretKey can not be null or empty."; - - //Assert - expect(userInQueueServiceMock.extendQueueCookieCall).toBeNull(); - expect(exceptionWasThrown).toBeTruthy(); - }); - - it('Should extend', () => { - //Arrange - resetMocks(); - - //Act - KnownUser.UserInQueueService = userInQueueServiceMock; - const result = KnownUser.extendQueueCookie("eventId", 20, "cookiedomain", "secretKey", httpContextMock); - - //Assert - expect(result).toBeNull(); - expect(userInQueueServiceMock.extendQueueCookieCall).not.toBeNull(); - expect(userInQueueServiceMock.extendQueueCookieCall!.method).toBe('extendQueueCookie'); - expect(userInQueueServiceMock.extendQueueCookieCall!.eventId).toBe('eventId'); - expect(userInQueueServiceMock.extendQueueCookieCall!.cookieValidityMinute).toBe(20); - expect(userInQueueServiceMock.extendQueueCookieCall!.secretKey).toBe('secretKey'); - }); -}); - -function getGoogleBotExampleIntegrationConfig(): string { - const integrationConfigString = `{ - "Description": "test", - "Integrations": [ - { - "Name": "event1action", - "ActionType": "Queue", - "EventId": "event1", - "CookieDomain": ".test.com", - "LayoutName": "Christmas Layout by Queue-it", - "Culture": "", - "ExtendCookieValidity": true, - "CookieValidityMinute": 20, - "Triggers": [ - { - "TriggerParts": [ - { - "Operator": "Contains", - "ValueToCompare": "event1", - "UrlPart": "PageUrl", - "ValidatorType": "UrlValidator", - "IsNegative": false, - "IsIgnoreCase": true - }, - { - "Operator": "Contains", - "ValueToCompare": "googlebot", - "ValidatorType": "UserAgentValidator", - "IsNegative": false, - "IsIgnoreCase": false - } - ], - "LogicalOperator": "And" - } - ], - "QueueDomain": "knownusertest.queue-it.net", - "RedirectLogic": "AllowTParameter", - "ForcedTargetUrl": "" - } - ], - "CustomerId": "knownusertest", - "AccountId": "knownusertest", - "Version": 3, - "PublishDate": "2017-05-15T21:39:12.0076806Z", - "ConfigDataVersion": "1.0.0.1" - }`; - return integrationConfigString; -} - -describe('validateRequestByIntegrationConfig', () => { - - it('should handle googlebot', () => { - resetMocks(); - userInQueueServiceMock.validateQueueRequestResult = new RequestValidationResult("Queue", "eventidX", "", "http://q.qeuue-it.com", ""); - - httpContextMock.req.headers.set('user-agent', 'googlebot'); - - const result = KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", - "queueIttoken", - getGoogleBotExampleIntegrationConfig(), - "customerid", - "secretkey", - httpContextMock); - - expect(result.first).not.toBeNull(); - expect(result.first!.isAjaxResult).toBeFalsy(); - expect(result.second).toBeNull(); - expect(result.first!.eventId).toBe("eventidX"); - expect(userInQueueServiceMock.validateQueueRequestCall).not.toBeNull() - expect(userInQueueServiceMock.validateQueueRequestCall!.method).toBe("validateQueueRequest"); - expect(userInQueueServiceMock.validateQueueRequestCall!.targetUrl).toBe("http://test.com?event1=true"); - expect(userInQueueServiceMock.validateQueueRequestCall!.queueitToken).toBe("queueIttoken"); - expect(userInQueueServiceMock.validateQueueRequestCall!.queueConfig.queueDomain).toBe("knownusertest.queue-it.net"); - expect(userInQueueServiceMock.validateQueueRequestCall!.queueConfig.eventId).toBe("event1"); - expect(userInQueueServiceMock.validateQueueRequestCall!.queueConfig.culture).toBe(""); - expect(userInQueueServiceMock.validateQueueRequestCall!.queueConfig.layoutName).toBe("Christmas Layout by Queue-it"); - expect(userInQueueServiceMock.validateQueueRequestCall!.queueConfig.extendCookieValidity).toBeTruthy(); - expect(userInQueueServiceMock.validateQueueRequestCall!.queueConfig.cookieValidityMinute).toBe(20); - expect(userInQueueServiceMock.validateQueueRequestCall!.queueConfig.cookieDomain).toBe(".test.com"); - expect(userInQueueServiceMock.validateQueueRequestCall!.queueConfig.version).toBe(3); - expect(userInQueueServiceMock.validateQueueRequestCall!.customerId).toBe('customerid'); - expect(userInQueueServiceMock.validateQueueRequestCall!.secretKey).toBe('secretkey'); - }); - - it('should handle AjaxCall', () => { - resetMocks(); - userInQueueServiceMock.validateQueueRequestResult = new RequestValidationResult("Queue", "eventid", "", "http://q.qeuue-it.com", ""); - - httpContextMock.req.headers.set('x-queueit-ajaxpageurl', 'http%3a%2f%2ftest.com%3fevent1%3dtrue'); - httpContextMock.req.headers.set('user-agent', 'googlebot'); - httpContextMock.req.headers.set('a', 'b'); - httpContextMock.req.headers.set('e', 'f'); - - const integrationConfigString = `{ - "Description": "test", - "Integrations": [ - { - "Name": "event1action", - "ActionType": "Queue", - "EventId": "event1", - "CookieDomain": ".test.com", - "LayoutName": "Christmas Layout by Queue-it", - "Culture": "", - "ExtendCookieValidity": true, - "CookieValidityMinute": 20, - "Triggers": [ - { - "TriggerParts": [ - { - "Operator": "Contains", - "ValueToCompare": "event1", - "UrlPart": "PageUrl", - "ValidatorType": "UrlValidator", - "IsNegative": false, - "IsIgnoreCase": true - }, - { - "Operator": "Contains", - "ValueToCompare": "googlebot", - "ValidatorType": "UserAgentValidator", - "IsNegative": false, - "IsIgnoreCase": false - } - ], - "LogicalOperator": "And" - } - ], - "QueueDomain": "knownusertest.queue-it.net", - "RedirectLogic": "AllowTParameter", - "ForcedTargetUrl": "" - } - ], - "CustomerId": "knownusertest", - "AccountId": "knownusertest", - "Version": 3, - "PublishDate": "2017-05-15T21:39:12.0076806Z", - "ConfigDataVersion": "1.0.0.1" - }`; - - const result = KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", "queueIttoken", integrationConfigString, "customerid", "secretkey", httpContextMock); - - expect(userInQueueServiceMock.validateQueueRequestCall!.method).toBe('validateQueueRequest'); - expect(userInQueueServiceMock.validateQueueRequestCall!.targetUrl).toBe('http://test.com?event1=true'); - expect(userInQueueServiceMock.validateQueueRequestCall!.queueitToken).toBe('queueIttoken'); - expect(userInQueueServiceMock.validateQueueRequestCall!.queueConfig.queueDomain).toBe('knownusertest.queue-it.net'); - expect(userInQueueServiceMock.validateQueueRequestCall!.queueConfig.eventId).toBe('event1'); - expect(userInQueueServiceMock.validateQueueRequestCall!.queueConfig.culture).toBe(''); - expect(userInQueueServiceMock.validateQueueRequestCall!.queueConfig.layoutName).toBe('Christmas Layout by Queue-it'); - expect(userInQueueServiceMock.validateQueueRequestCall!.queueConfig.extendCookieValidity).toBeTruthy(); - expect(userInQueueServiceMock.validateQueueRequestCall!.queueConfig.cookieValidityMinute).toBe(20); - expect(userInQueueServiceMock.validateQueueRequestCall!.queueConfig.cookieDomain).toBe('.test.com'); - expect(userInQueueServiceMock.validateQueueRequestCall!.queueConfig.version).toBe(3); - expect(userInQueueServiceMock.validateQueueRequestCall!.customerId).toBe('customerid'); - expect(userInQueueServiceMock.validateQueueRequestCall!.secretKey).toBe('secretkey'); - expect(result.first!.isAjaxResult).toBeTruthy(); - expect(result.first!.getAjaxRedirectUrl().toLowerCase()).toBe("http%3a%2f%2fq.qeuue-it.com"); - }); - - it('should handle NotMatch', () => { - resetMocks(); - - const integrationConfigString = `{ - "Description": "test", - "Integrations": [ - ], - "CustomerId": "knownusertest", - "AccountId": "knownusertest", - "Version": 3, - "PublishDate": "2017-05-15T21:39:12.0076806Z", - "ConfigDataVersion": "1.0.0.1" - }`; - - const result = KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", "queueIttoken", integrationConfigString, "customerid", "secretkey", httpContextMock); - - expect(userInQueueServiceMock.validateQueueRequestCall).toBeNull(); - expect(result.first!.doRedirect()).toBeFalsy(); - }); - - it('should EmptyCurrentUrl', () => { - //Arrange - resetMocks(); - - const integrationConfigString = `{ - "Description": "test", - "Integrations": [ - { - "Name": "event1action", - "ActionType": "Queue", - "EventId": "event1", - "CookieDomain": ".test.com", - "LayoutName": "Christmas Layout by Queue-it", - "Culture": "", - "ExtendCookieValidity": true, - "CookieValidityMinute": 20, - "Triggers": [ - { - "TriggerParts": [ - { - "Operator": "Contains", - "ValueToCompare": "event1", - "UrlPart": "PageUrl", - "ValidatorType": "UrlValidator", - "IsNegative": false, - "IsIgnoreCase": true - }, - { - "Operator": "Contains", - "ValueToCompare": "googlebot", - "ValidatorType": "UserAgentValidator", - "IsNegative": false, - "IsIgnoreCase": false - } - ], - "LogicalOperator": "And" - } - ], - "QueueDomain": "knownusertest.queue-it.net", - "RedirectLogic": "AllowTParameter", - "ForcedTargetUrl": "" - } - ], - "CustomerId": "knownusertest", - "AccountId": "knownusertest", - "Version": 3, - "PublishDate": "2017-05-15T21:39:12.0076806Z", - "ConfigDataVersion": "1.0.0.1" - }`; - - //Act - const result = KnownUser.validateRequestByIntegrationConfig('', "queueIttoken", integrationConfigString, "customerId", "secretKey", httpContextMock); - const exceptionWasThrown = result.second != null && result.second!.message == "currentUrlWithoutQueueITToken can not be null or empty."; - - //Assert - expect(userInQueueServiceMock.validateQueueRequestCall).toBeNull(); - expect(exceptionWasThrown).toBeTruthy(); - }); - - it('should not be called if integration config is empty', () => { - //Arrange - resetMocks(); - - //Act - let result = KnownUser.validateRequestByIntegrationConfig("currentUrl", "queueitToken", '', "customerId", "secretKey", httpContextMock); - const exceptionWasThrown = result.second != null && result.second!.message == "integrationsConfigString can not be null or empty."; - - //Assert - expect(userInQueueServiceMock.validateQueueRequestCall).toBeNull(); - expect(exceptionWasThrown).toBeTruthy(); - }); - - it('should ForcedTargetUrl', () => { - resetMocks(); - userInQueueServiceMock.validateQueueRequestResult = new RequestValidationResult("Queue", "eventid", "", "http://q.qeuue-it.com", ""); - - const integrationConfigString = `{ - "Description": "test", - "Integrations": [ - { - "Name": "event1action", - "ActionType": "Queue", - "EventId": "event1", - "CookieDomain": ".test.com", - "LayoutName": "Christmas Layout by Queue-it", - "Culture": "", - "ExtendCookieValidity": true, - "CookieValidityMinute": 20, - "Triggers": [ - { - "TriggerParts": [ - { - "Operator": "Contains", - "ValueToCompare": "event1", - "UrlPart": "PageUrl", - "ValidatorType": "UrlValidator", - "IsNegative": false, - "IsIgnoreCase": true - } - ], - "LogicalOperator": "And" - } - ], - "QueueDomain": "knownusertest.queue-it.net", - "RedirectLogic": "ForcedTargetUrl", - "ForcedTargetUrl": "http://test.com" - } - ], - "CustomerId": "knownusertest", - "AccountId": "knownusertest", - "Version": 3, - "PublishDate": "2017-05-15T21:39:12.0076806Z", - "ConfigDataVersion": "1.0.0.1" - }`; - - KnownUser.UserInQueueService = userInQueueServiceMock; - const result = KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", "queueIttoken", integrationConfigString, "customerid", "secretkey", httpContextMock); - - expect(userInQueueServiceMock.validateQueueRequestCall!.method == "validateQueueRequest"); - expect(userInQueueServiceMock.validateQueueRequestCall!.targetUrl == "http://test.com"); - }); - - it('should ForcedTargetUrl_AjaxCall', () => { - resetMocks(); - userInQueueServiceMock.validateQueueRequestResult = new RequestValidationResult("Queue", "eventid", "", "http://q.qeuue-it.com", ""); - - httpContextMock.req.headers.set('x-queueit-ajaxpageurl', 'http%3a%2f%2ftest.com%3fevent1%3dtrue'); - httpContextMock.req.headers.set('a', 'b'); - httpContextMock.req.headers.set('e', 'f'); - - const integrationConfigString = `{ - "Description": "test", - "Integrations": [ - { - "Name": "event1action", - "ActionType": "Queue", - "EventId": "event1", - "CookieDomain": ".test.com", - "LayoutName": "Christmas Layout by Queue-it", - "Culture": "", - "ExtendCookieValidity": true, - "CookieValidityMinute": 20, - "Triggers": [ - { - "TriggerParts": [ - { - "Operator": "Contains", - "ValueToCompare": "event1", - "UrlPart": "PageUrl", - "ValidatorType": "UrlValidator", - "IsNegative": false, - "IsIgnoreCase": true - } - ], - "LogicalOperator": "And" - } - ], - "QueueDomain": "knownusertest.queue-it.net", - "RedirectLogic": "ForcedTargetUrl", - "ForcedTargetUrl": "http://test.com" - } - ], - "CustomerId": "knownusertest", - "AccountId": "knownusertest", - "Version": 3, - "PublishDate": "2017-05-15T21:39:12.0076806Z", - "ConfigDataVersion": "1.0.0.1" - }`; - - KnownUser.UserInQueueService = userInQueueServiceMock; - const result = KnownUser.validateRequestByIntegrationConfig("http://test.com?event1", "queueIttoken", integrationConfigString, "customerid", "secretkey", httpContextMock); - - expect(userInQueueServiceMock.validateQueueRequestCall!.method).toBe('validateQueueRequest'); - expect(userInQueueServiceMock.validateQueueRequestCall!.targetUrl).toBe('http://test.com'); - expect(result.first!.isAjaxResult).toBeTruthy(); - }); - - it('should EventTargetUrl', () => { - resetMocks(); - userInQueueServiceMock.validateQueueRequestResult = new RequestValidationResult("Queue", "eventid", "", "http://q.qeuue-it.com", ""); - - const integrationConfigString = `{ - "Description": "test", - "Integrations": [ - { - "Name": "event1action", - "ActionType": "Queue", - "EventId": "event1", - "CookieDomain": ".test.com", - "LayoutName": "Christmas Layout by Queue-it", - "Culture": "", - "ExtendCookieValidity": true, - "CookieValidityMinute": 20, - "Triggers": [ - { - "TriggerParts": [ - { - "Operator": "Contains", - "ValueToCompare": "event1", - "UrlPart": "PageUrl", - "ValidatorType": "UrlValidator", - "IsNegative": false, - "IsIgnoreCase": true - } - ], - "LogicalOperator": "And" - } - ], - "QueueDomain": "knownusertest.queue-it.net", - "RedirectLogic": "EventTargetUrl" - } - ], - "CustomerId": "knownusertest", - "AccountId": "knownusertest", - "Version": 3, - "PublishDate": "2017-05-15T21:39:12.0076806Z", - "ConfigDataVersion": "1.0.0.1" - }`; - - KnownUser.UserInQueueService = userInQueueServiceMock; - const result = KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", "queueIttoken", integrationConfigString, "customerid", "secretkey", httpContextMock); - - expect(userInQueueServiceMock.validateQueueRequestCall!.method).toBe('validateQueueRequest'); - expect(userInQueueServiceMock.validateQueueRequestCall!.targetUrl).toBe(''); - }); - - it('should EventTargetUrl_AjaxCall', () => { - resetMocks(); - userInQueueServiceMock.validateQueueRequestResult = new RequestValidationResult("Queue", "eventid", "", "http://q.qeuue-it.com", ""); - - httpContextMock.req.headers.set('a', 'b'); - httpContextMock.req.headers.set('x-queueit-ajaxpageurl', 'http%3a%2f%2ftest.com%3fevent1%3dtrue'); - httpContextMock.req.headers.set('e', 'f'); - - const integrationConfigString = `{ - "Description": "test", - "Integrations": [ - { - "Name": "event1action", - "ActionType": "Queue", - "EventId": "event1", - "CookieDomain": ".test.com", - "LayoutName": "Christmas Layout by Queue-it", - "Culture": "", - "ExtendCookieValidity": true, - "CookieValidityMinute": 20, - "Triggers": [ - { - "TriggerParts": [ - { - "Operator": "Contains", - "ValueToCompare": "event1", - "UrlPart": "PageUrl", - "ValidatorType": "UrlValidator", - "IsNegative": false, - "IsIgnoreCase": true - } - ], - "LogicalOperator": "And" - } - ], - "QueueDomain": "knownusertest.queue-it.net", - "RedirectLogic": "EventTargetUrl" - } - ], - "CustomerId": "knownusertest", - "AccountId": "knownusertest", - "Version": 3, - "PublishDate": "2017-05-15T21:39:12.0076806Z", - "ConfigDataVersion": "1.0.0.1" - }`; - - KnownUser.UserInQueueService = userInQueueServiceMock; - const result = KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", "queueIttoken", integrationConfigString, "customerid", "secretkey", httpContextMock); - - expect(userInQueueServiceMock.validateQueueRequestCall!.method).toBe('validateQueueRequest'); - expect(userInQueueServiceMock.validateQueueRequestCall!.targetUrl).toBe(''); - expect(result.first!.isAjaxResult).toBeTruthy(); - }); - - it('should Exception_NoDebugToken', () => { - resetMocks(); - userInQueueServiceMock.validateQueueRequestResultRaiseException = true; - - httpContextMock.req.headers.set('user-agent', 'googlebot'); - - const integrationConfigString = `{ - "Description": "test", - "Integrations": [ - { - "Name": "event1action", - "ActionType": "Queue", - "EventId": "event1", - "CookieDomain": ".test.com", - "LayoutName": "Christmas Layout by Queue-it", - "Culture": "", - "ExtendCookieValidity": true, - "CookieValidityMinute": 20, - "Triggers": [ - { - "TriggerParts": [ - { - "Operator": "Contains", - "ValueToCompare": "event1", - "UrlPart": "PageUrl", - "ValidatorType": "UrlValidator", - "IsNegative": false, - "IsIgnoreCase": true - }, - { - "Operator": "Contains", - "ValueToCompare": "googlebot", - "ValidatorType": "UserAgentValidator", - "IsNegative": false, - "IsIgnoreCase": false - } - ], - "LogicalOperator": "And" - } - ], - "QueueDomain": "knownusertest.queue-it.net", - "RedirectLogic": "AllowTParameter", - "ForcedTargetUrl": "" - } - ], - "CustomerId": "knownusertest", - "AccountId": "knownusertest", - "Version": 3, - "PublishDate": "2017-05-15T21:39:12.0076806Z", - "ConfigDataVersion": "1.0.0.1" - }`; - - const result = KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", "queueIttoken", integrationConfigString, "customerid", "secretkey", httpContextMock); - - expect(result.second).not.toBeNull() - expect(httpContextMock.res.cookies.has(KnownUser.QueueITDebugKey)).toBeFalsy(); - }); - - it('should CancelAction', () => { - resetMocks(); - userInQueueServiceMock.validateQueueRequestResult = new RequestValidationResult("Cancel", "eventid", "queueid", "redirectUrl", ""); - - httpContextMock.req.headers.set('user-agent', 'googlebot'); - - const integrationConfigString = `{ - "Integrations":[ - { - "Name":"event1action", - "EventId":"eventid", - "CookieDomain":"cookiedomain", - "LayoutName":null, - "Culture":null, - "ExtendCookieValidity":null, - "CookieValidityMinute":null, - "QueueDomain":"queuedomain", - "RedirectLogic":null, - "ForcedTargetUrl":null, - "ActionType":"Cancel", - "Triggers":[ - { - "TriggerParts":[ - { - "ValidatorType":"UrlValidator", - "Operator":"Contains", - "ValueToCompare":"event1", - "ValuesToCompare":null, - "IsNegative":false, - "IsIgnoreCase":true, - "UrlPart":"PageUrl", - "CookieName":null, - "HttpHeaderName":null - } - ], - "LogicalOperator":"And" - } - ] - } - ], - "Version":3 - }`; - - KnownUser.UserInQueueService = userInQueueServiceMock; - const result = KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", "queueIttoken", integrationConfigString, "customerid", "secretkey", httpContextMock); - - expect(userInQueueServiceMock.validateCancelRequestCall!.method).toBe('validateCancelRequest'); - expect(userInQueueServiceMock.validateCancelRequestCall!.targetUrl).toBe('http://test.com?event1=true'); - expect(userInQueueServiceMock.validateCancelRequestCall!.customerId).toBe('customerid'); - expect(userInQueueServiceMock.validateCancelRequestCall!.secretKey).toBe('secretkey'); - - expect(userInQueueServiceMock.validateQueueRequestResult.eventId).toBe('eventid'); - expect(userInQueueServiceMock.validateQueueRequestResult.queueId).toBe('queueid'); - expect(userInQueueServiceMock.validateQueueRequestResult.redirectUrl).toBe('redirectUrl'); - - expect(result.first!.isAjaxResult).toBeFalsy(); - }); - - it('should CancelAction_AjaxCall', () => { - resetMocks(); - userInQueueServiceMock.validateQueueRequestResult = new RequestValidationResult("Cancel", "eventid", "", "http://q.qeuue-it.com", ''); - - httpContextMock.req.headers.set('a', 'b'); - httpContextMock.req.headers.set('e', 'f'); - httpContextMock.req.headers.set('x-queueit-ajaxpageurl', 'http%3a%2f%2furl'); - - const integrationConfigString = `{ - "Integrations":[ - { - "Name":"event1action", - "EventId":"eventid", - "CookieDomain":"cookiedomain", - "LayoutName":null, - "Culture":null, - "ExtendCookieValidity":null, - "CookieValidityMinute":null, - "QueueDomain":"queuedomain", - "RedirectLogic":null, - "ForcedTargetUrl":null, - "ActionType":"Cancel", - "Triggers":[ - { - "TriggerParts":[ - { - "ValidatorType":"UrlValidator", - "Operator":"Contains", - "ValueToCompare":"event1", - "ValuesToCompare":null, - "IsNegative":false, - "IsIgnoreCase":true, - "UrlPart":"PageUrl", - "CookieName":null, - "HttpHeaderName":null - } - ], - "LogicalOperator":"And" - } - ] - } - ], - "Version":3 - }`; - - KnownUser.UserInQueueService = userInQueueServiceMock; - const result = KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", "queueIttoken", integrationConfigString, "customerid", "secretkey", httpContextMock); - - expect(userInQueueServiceMock.validateCancelRequestCall!.method).toBe('validateCancelRequest'); - expect(userInQueueServiceMock.validateCancelRequestCall!.targetUrl).toBe('http://url'); - expect(userInQueueServiceMock.validateCancelRequestCall!.customerId).toBe('customerid'); - expect(userInQueueServiceMock.validateCancelRequestCall!.secretKey).toBe('secretkey'); - - expect(userInQueueServiceMock.validateCancelRequestCall!.cancelConfig.eventId).toBe('eventid'); - expect(userInQueueServiceMock.validateCancelRequestCall!.cancelConfig.queueDomain).toBe('queuedomain'); - expect(userInQueueServiceMock.validateCancelRequestCall!.cancelConfig.cookieDomain).toBe('cookiedomain'); - expect(userInQueueServiceMock.validateCancelRequestCall!.cancelConfig.version).toBe(3); - - expect(result.first!.isAjaxResult).toBeTruthy(); - }); - - it('should IgnoreAction', () => { - resetMocks(); - userInQueueServiceMock.validateQueueRequestResult = new RequestValidationResult("Ignore", "eventid", "queueid", "redirectUrl", "", "event1action"); - - httpContextMock.req.headers.set('user-agent', 'googlebot'); - - const integrationConfigString = `{ - "Integrations":[ - { - "Name":"event1action", - "EventId":"eventid", - "CookieDomain":"cookiedomain", - "LayoutName":null, - "Culture":null, - "ExtendCookieValidity":null, - "CookieValidityMinute":null, - "QueueDomain":"queuedomain", - "RedirectLogic":null, - "ForcedTargetUrl":null, - "ActionType":"Ignore", - "Triggers":[ - { - "TriggerParts":[ - { - "ValidatorType":"UrlValidator", - "Operator":"Contains", - "ValueToCompare":"event1", - "ValuesToCompare":null, - "IsNegative":false, - "IsIgnoreCase":true, - "UrlPart":"PageUrl", - "CookieName":null, - "HttpHeaderName":null - } - ], - "LogicalOperator":"And" - } - ] - } - ], - "Version":3 - }`; - - KnownUser.UserInQueueService = userInQueueServiceMock; - - const result = KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", "queueIttoken", integrationConfigString, "customerid", "secretkey", httpContextMock); - const call = userInQueueServiceMock.requestValidationResult; - expect(result.first!.actionType).toBe('Ignore'); - expect(call!.method).toBe('getIgnoreResult'); - expect(result.first!.isAjaxResult).toBe(false); - expect(result.first!.actionName).toBe('event1action'); - }); - - it('should IgnoreAction_AjaxCall', () => { - resetMocks(); - userInQueueServiceMock.validateQueueRequestResult = new RequestValidationResult("Cancel", "eventid", "", "http://q.qeuue-it.com", ''); - - httpContextMock.req.headers.set('a', 'b'); - httpContextMock.req.headers.set('c', 'd'); - httpContextMock.req.headers.set('e', 'f'); - httpContextMock.req.headers.set('x-queueit-ajaxpageurl', 'http%3a%2f%2furl'); - - const integrationConfigString = ` { - "Description": "test", - "Integrations": [ - { - "Name": "event1action", - "EventId": "event1", - "CookieDomain": ".test.com", - "ActionType":"Ignore", - "Triggers": [ - { - "TriggerParts": [ - { - "Operator": "Contains", - "ValueToCompare": "event1", - "UrlPart": "PageUrl", - "ValidatorType": "UrlValidator", - "IsNegative": false, - "IsIgnoreCase": true - } - ], - "LogicalOperator": "And" - } - ], - "QueueDomain": "knownusertest.queue-it.net" - } - ], - "CustomerId": "knownusertest", - "AccountId": "knownusertest", - "Version": 3, - "PublishDate": "2017-05-15T21:39:12.0076806Z", - "ConfigDataVersion": "1.0.0.1" - }`; - - KnownUser.UserInQueueService = userInQueueServiceMock; - const result = KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", "queueIttoken", integrationConfigString, "customerid", "secretkey", httpContextMock); - const call = userInQueueServiceMock.requestValidationResult; - expect(result.first!.actionType).toBe('Ignore'); - expect(call!.method).toBe('getIgnoreResult'); - expect(result.first!.isAjaxResult).toBeTruthy(); - }); - - it('should Debug', () => { - resetMocks(); - - const integrationConfigString = `{ - "Description": - "test", - "Integrations": [{ - "Name": - "event1action", - "ActionType": "Queue", - "EventId": - "event1", - "CookieDomain": - ".test.com", - "LayoutName": - "Christmas Layout by Queue-it", - "Culture": - "da-DK", - "ExtendCookieValidity": - true, - "CookieValidityMinute": - 20, - "Triggers": [{ - "TriggerParts": [{ - "Operator": "Contains", - "ValueToCompare": "event1", - "UrlPart": "PageUrl", - "ValidatorType": "UrlValidator", - "IsNegative": false, - "IsIgnoreCase": true - }, { - "Operator": "Contains", - "ValueToCompare": "googlebot", - "ValidatorType": "UserAgentValidator", - "IsNegative": false, - "IsIgnoreCase": false - }], - "LogicalOperator": - "And" - }], - "QueueDomain": - "knownusertest.queue-it.net", - "RedirectLogic": - "AllowTParameter" - }], - "CustomerId": - "knownusertest", - "AccountId": - "knownusertest", - "Version": - 3, - "PublishDate": - "2017-05-15T21:39:12.0076806Z", - "ConfigDataVersion": - "1.0.0.1" - }`; - - httpContextMock.req.setAbsoluteUri("http://localhost/original_url"); - httpContextMock.req.setUserHostAddress("userIP"); - mockGoogleHeaders(); - - const secretKey = "secretKey"; - const queueitToken = generateDebugToken("eventId", secretKey); - const dateTimeProviderMock = new MockDateTimeProvider(); - const expectedServerTime = dateTimeProviderMock.getCurrentTime().toISOString().split('.')[0] + "Z"; - KnownUser.UserInQueueService = userInQueueServiceMock; - KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", - queueitToken, - integrationConfigString, - "customerId", - secretKey, - httpContextMock, - dateTimeProviderMock); - - const actualCookieValue = httpContextMock.res.cookies.get(KnownUser.QueueITDebugKey)!.value; - expect(actualCookieValue.indexOf("ServerUtcTime=" + expectedServerTime + "|")).not.toBe(-1); - expect(actualCookieValue.indexOf("ConfigVersion=3|")).not.toBe(-1); - expect(actualCookieValue.indexOf("PureUrl=http://test.com?event1=true|")).not.toBe(-1); - expect(actualCookieValue.indexOf("QueueitToken=" + queueitToken + "|")).not.toBe(-1); - expect(actualCookieValue.indexOf("RequestIP=userIP|")).not.toBe(-1); - expect(actualCookieValue.indexOf("RequestHttpHeader_Via=v|")).not.toBe(-1); - expect(actualCookieValue.indexOf("RequestHttpHeader_Forwarded=f|")).not.toBe(-1); - expect(actualCookieValue.indexOf("RequestHttpHeader_XForwardedFor=xff|")).not.toBe(-1); - expect(actualCookieValue.indexOf("RequestHttpHeader_XForwardedHost=xfh|")).not.toBe(-1); - expect(actualCookieValue.indexOf("RequestHttpHeader_XForwardedProto=xfp|")).not.toBe(-1); - expect(actualCookieValue.indexOf("MatchedConfig=event1action|")).not.toBe(-1); - expect(actualCookieValue.indexOf("TargetUrl=http://test.com?event1=true|")).not.toBe(-1); - expect(actualCookieValue.indexOf("|QueueConfig=EventId:event1&Version:3&ActionName:event1action&QueueDomain:knownusertest.queue-it.net&CookieDomain:.test.com&ExtendCookieValidity:true&CookieValidityMinute:20&LayoutName:Christmas Layout by Queue-it&Culture:da-DK")).not.toBe(-1); - expect(actualCookieValue.indexOf("SdkVersion=" + SDK_VERSION + "|")).not.toBe(-1); - }); - - it('should Debug_WithoutMatch', () => { - resetMocks(); - - const requestIP = "80.35.35.34"; - const viaHeader = "1.1 example.com"; - const forwardedHeader = "for=192.0.2.60;proto=http;by=203.0.113.43"; - const xForwardedForHeader = "129.78.138.66, 129.78.64.103"; - const xForwardedHostHeader = "en.wikipedia.org:8080"; - const xForwardedProtoHeader = "https"; - - const integrationConfigString = `{ - "Description": "test", - "Integrations": [ - { - "Name": "event1action", - "EventId": "event1", - "CookieDomain": ".test.com", - "ActionType":"Cancel", - "Triggers": [ - { - "TriggerParts": [ - { - "Operator": "Contains", - "ValueToCompare": "notmatch", - "UrlPart": "PageUrl", - "ValidatorType": "UrlValidator", - "IsNegative": false, - "IsIgnoreCase": true - } - ], - "LogicalOperator": "And" - } - ], - "QueueDomain": "knownusertest.queue-it.net" - } - ], - "CustomerId": "knownusertest", - "AccountId": "knownusertest", - "Version": 10, - "PublishDate": "2017-05-15T21:39:12.0076806Z", - "ConfigDataVersion": "1.0.0.1" - }`; - - httpContextMock.req.setAbsoluteUri("http://test.com/?event1=true&queueittoken=queueittokenvalue"); - httpContextMock.req.setUserHostAddress(requestIP); - httpContextMock.req.headers.set('via', viaHeader); - httpContextMock.req.headers.set('forwarded', forwardedHeader); - httpContextMock.req.headers.set('x-forwarded-for', xForwardedForHeader); - httpContextMock.req.headers.set('x-forwarded-host', xForwardedHostHeader); - httpContextMock.req.headers.set('x-forwarded-proto', xForwardedProtoHeader); - const secretKey = "secretKey"; - const queueitToken = generateDebugToken("eventId", secretKey); - const dateTimeProviderMock = new MockDateTimeProvider(); - const expectedServerTime = dateTimeProviderMock.getCurrentTime().toISOString().split('.')[0] + "Z"; - - const result = KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", - queueitToken, - integrationConfigString, - "customerId", - secretKey, - httpContextMock, - dateTimeProviderMock); - - expect(httpContextMock.res.cookies.has(KnownUser.QueueITDebugKey)).toBeTruthy() - const actualCookieValue = httpContextMock.res.cookies.get(KnownUser.QueueITDebugKey)!.value - expect(actualCookieValue.indexOf("ConfigVersion=10")).not.toBe(-1); - expect(actualCookieValue.indexOf("PureUrl=http://test.com?event1=true")).not.toBe(-1); - expect(actualCookieValue.indexOf(queueitToken)).not.toBe(-1); - expect(actualCookieValue.indexOf("OriginalUrl=http://test.com/?event1=true&queueittoken=queueittokenvalue")).not.toBe(-1); - expect(actualCookieValue.indexOf("ServerUtcTime=" + expectedServerTime)).not.toBe(-1); - expect(actualCookieValue.indexOf("MatchedConfig=NULL")).not.toBe(-1); - expect(actualCookieValue.indexOf("RequestIP=80.35.35.34")).not.toBe(-1); - expect(actualCookieValue.indexOf("RequestHttpHeader_Via=1.1 example.com")).not.toBe(-1); - expect(actualCookieValue.indexOf("RequestHttpHeader_Forwarded=for=192.0.2.60;proto=http;by=203.0.113.43")).not.toBe(-1); - expect(actualCookieValue.indexOf("RequestHttpHeader_XForwardedFor=129.78.138.66, 129.78.64.103")).not.toBe(-1); - expect(actualCookieValue.indexOf("RequestHttpHeader_XForwardedHost=en.wikipedia.org:8080")).not.toBe(-1); - expect(actualCookieValue.indexOf("RequestHttpHeader_XForwardedProto=https")).not.toBe(-1); - expect(actualCookieValue.indexOf("SdkVersion=" + SDK_VERSION + "|")).not.toBe(-1); - }); - - it('should NotValidHash_Debug', () => { - resetMocks(); - userInQueueServiceMock.validateQueueRequestResult = new RequestValidationResult("Debug", "eventid", "queueid", "http://q.qeuue-it.com", ''); - - const requestIP = "80.35.35.34"; - - const integrationConfigString = `{ - "Description": "test", - "Integrations": [ - { - "Name": "event1action", - "EventId": "event1", - "CookieDomain": ".test.com", - "ActionType":"Cancel", - "Triggers": [ - { - "TriggerParts": [ - { - "Operator": "Contains", - "ValueToCompare": "event1", - "UrlPart": "PageUrl", - "ValidatorType": "UrlValidator", - "IsNegative": false, - "IsIgnoreCase": true - } - ], - "LogicalOperator": "And" - } - ], - "QueueDomain": "knownusertest.queue-it.net" - } - ], - "CustomerId": "knownusertest", - "AccountId": "knownusertest", - "Version": 3, - "PublishDate": "2017-05-15T21:39:12.0076806Z", - "ConfigDataVersion": "1.0.0.1" - }`; - - httpContextMock.req.setAbsoluteUri("http://test.com/?event1=true&queueittoken=queueittokenvalue"); - httpContextMock.req.setUserHostAddress(requestIP); - - - const secretKey = "secretKey"; - const queueitToken = generateDebugToken("eventId", secretKey); - const expectedServerTime = new Date(Date.now()).toISOString().split('.')[0] + "Z"; - - KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true=", queueitToken, integrationConfigString, "customerId", secretKey, httpContextMock); - - const actualCookieValue = httpContextMock.res.cookies.get(KnownUser.QueueITDebugKey)!.value - - expect(actualCookieValue.indexOf("PureUrl=http://test.com?event1=true")).not.toBe(-1); - expect(actualCookieValue.indexOf("ConfigVersion=3")).not.toBe(-1); - expect(actualCookieValue.indexOf("MatchedConfig=event1action")).not.toBe(-1); - expect(actualCookieValue.indexOf(queueitToken)).not.toBe(-1); - expect(actualCookieValue.indexOf("OriginalUrl=http://test.com/?event1=true&queueittoken=queueittokenvalue")).not.toBe(-1); - expect(actualCookieValue.indexOf("TargetUrl=http://test.com?event1=true")).not.toBe(-1); - expect(actualCookieValue.indexOf("CancelConfig=EventId:event1&Version:3&QueueDomain:knownusertest.queue-it.net&CookieDomain:.test.com")).not.toBe(-1); - }); - - it('should Debug_NullConfig', () => { - resetMocks(); - - httpContextMock.req.setAbsoluteUri("http://localhost/original_url"); - httpContextMock.req.setUserHostAddress("userIP"); - mockGoogleHeaders(); - - const secretKey = "secretKey"; - const queueitToken = generateDebugToken("eventId", secretKey); - KnownUser.UserInQueueService = userInQueueServiceMock; - - const result = KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", queueitToken, "{}", "customerId", secretKey, httpContextMock); - const errorReturned = result.second != null && result.second!.message == 'integrationsConfigString can not be null or empty.'; - expect(errorReturned).toBeTruthy(); - - //Assert - expect(userInQueueServiceMock.validateQueueRequestCall).toBeNull(); - - const actualCookieValue = httpContextMock.res.cookies.get(KnownUser.QueueITDebugKey)!.value - expect(actualCookieValue.indexOf("ConfigVersion=NULL|")).not.toBe(-1); - expect(actualCookieValue.indexOf("PureUrl=http://test.com?event1=true|")).not.toBe(-1); - expect(actualCookieValue.indexOf("QueueitToken=" + queueitToken + "|")).not.toBe(-1); - expect(actualCookieValue.indexOf("SdkVersion=" + SDK_VERSION + "|")).not.toBe(-1); - expect(actualCookieValue.indexOf("Exception=integrationsConfigString can not be null or empty.")).not.toBe(-1); - }); - - it('should Debug_Missing_CustomerId', () => { - resetMocks(); - const integrationConfigString = `{}`; - httpContextMock.req.setAbsoluteUri("http://localhost/original_url"); - httpContextMock.req.setUserHostAddress("userIP"); - mockGoogleHeaders(); - - const secretKey = "secretKey"; - const queueitToken = generateDebugToken("eventId", secretKey); - KnownUser.UserInQueueService = userInQueueServiceMock; - - const result = KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", queueitToken, integrationConfigString, '', secretKey, httpContextMock); - - //Assert - expect(result.second).toBeNull(); - expect(result.first).not.toBeNull(); - expect("https://api2.queue-it.net/diagnostics/connector/error/?code=setup").toBe(result.first!.redirectUrl); - expect(httpContextMock.res.cookies.has(KnownUser.QueueITDebugKey)).toBeFalsy(); - }); - - it('should Debug_Missing_SecretKey', () => { - resetMocks(); - const integrationConfigString = `{}`; - httpContextMock.req.setAbsoluteUri("http://localhost/original_url"); - httpContextMock.req.setUserHostAddress("userIP"); - mockGoogleHeaders(); - - const secretKey = "secretKey"; - const queueitToken = generateDebugToken("eventId", secretKey); - KnownUser.UserInQueueService = userInQueueServiceMock; - - const result = KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", queueitToken, integrationConfigString, "customerId", '', httpContextMock); - //Assert - expect("https://api2.queue-it.net/diagnostics/connector/error/?code=setup" == result.first!.redirectUrl); - expect(httpContextMock.res.cookies.has(KnownUser.QueueITDebugKey)).toBeFalsy(); - }); - - it('should Debug_ExpiredToken', () => { - resetMocks(); - const integrationConfigString = `{}`; - httpContextMock.req.setAbsoluteUri("http://localhost/original_url"); - httpContextMock.req.setUserHostAddress("userIP"); - mockGoogleHeaders(); - - const secretKey = "secretKey"; - const queueitToken = generateDebugToken("eventId", secretKey, true); - KnownUser.UserInQueueService = userInQueueServiceMock; - - const result = KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", queueitToken, integrationConfigString, "customerId", secretKey, httpContextMock); - //Assert - expect("https://customerId.api2.queue-it.net/customerId/diagnostics/connector/error/?code=timestamp" == result.first!.redirectUrl); - expect(httpContextMock.res.cookies.has(KnownUser.QueueITDebugKey)).toBeFalsy(); - }); - - it('should Debug_ModifiedToken', () => { - resetMocks(); - const integrationConfigString = `{}`; - httpContextMock.req.setAbsoluteUri("http://localhost/original_url"); - httpContextMock.req.setUserHostAddress("userIP"); - mockGoogleHeaders(); - - const secretKey = "secretKey"; - const queueitToken = generateDebugToken("eventId", secretKey) + "invalid-hash"; - KnownUser.UserInQueueService = userInQueueServiceMock; - - const result = KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", queueitToken, integrationConfigString, "customerId", secretKey, httpContextMock); - //Assert - expect("https://customerId.api2.queue-it.net/customerId/diagnostics/connector/error/?code=hash" == result.first!.redirectUrl); - expect(httpContextMock.res.cookies.has(KnownUser.QueueITDebugKey)).toBeFalsy(); - }); - -}); - -describe('resolveQueueRequestByLocalEventConfig', () => { - it('should handle ajax requests', () => { - resetMocks(); - - const eventconfig = new QueueEventConfig('', '', '', '', false, 0, '', 0); - eventconfig.cookieDomain = "cookieDomain"; - eventconfig.layoutName = "layoutName"; - eventconfig.culture = "culture"; - eventconfig.eventId = "eventId"; - eventconfig.queueDomain = "queueDomain"; - eventconfig.extendCookieValidity = true; - eventconfig.cookieValidityMinute = 10; - eventconfig.version = 12; - - KnownUser.UserInQueueService = userInQueueServiceMock; - const result = KnownUser.resolveQueueRequestByLocalConfig("targeturl", "queueIttoken", eventconfig, "customerid", "secretkey", httpContextMock); - - expect(userInQueueServiceMock.validateQueueRequestCall).not.toBeNull(); - expect(userInQueueServiceMock.validateQueueRequestCall!.method).toBe('validateQueueRequest'); - expect(userInQueueServiceMock.validateQueueRequestCall!.targetUrl).toBe('targeturl'); - expect(userInQueueServiceMock.validateQueueRequestCall!.queueitToken).toBe('queueIttoken'); - expect(userInQueueServiceMock.validateQueueRequestCall!.queueConfig).toBe(eventconfig); - expect(userInQueueServiceMock.validateQueueRequestCall!.customerId).toBe('customerid'); - expect(userInQueueServiceMock.validateQueueRequestCall!.secretKey).toBe('secretkey'); - expect(result.first!.isAjaxResult).toBeFalsy(); - }); - - it('should have isAjaxResult set always', () => { - resetMocks(); - - const eventconfig = new QueueEventConfig('', '', '', '', false, 0, '', 0); - eventconfig.cookieDomain = "cookieDomain"; - eventconfig.layoutName = "layoutName"; - eventconfig.culture = "culture"; - eventconfig.eventId = "eventId"; - eventconfig.queueDomain = "queueDomain"; - eventconfig.extendCookieValidity = true; - eventconfig.cookieValidityMinute = 10; - eventconfig.version = 12; - - KnownUser.UserInQueueService = userInQueueServiceMock; - const result = KnownUser.resolveQueueRequestByLocalConfig("targeturl", "queueIttoken", eventconfig, "customerid", "secretkey", httpContextMock); - - expect(userInQueueServiceMock.validateQueueRequestCall).not.toBeNull(); - expect(userInQueueServiceMock.validateQueueRequestCall!.method).toBe('validateQueueRequest'); - expect(userInQueueServiceMock.validateQueueRequestCall!.targetUrl).toBe('targeturl'); - expect(userInQueueServiceMock.validateQueueRequestCall!.queueitToken).toBe('queueIttoken'); - expect(userInQueueServiceMock.validateQueueRequestCall!.queueConfig).toBe(eventconfig); - expect(userInQueueServiceMock.validateQueueRequestCall!.customerId).toBe('customerid'); - expect(userInQueueServiceMock.validateQueueRequestCall!.secretKey).toBe('secretkey'); - - expect(result.second).toBeNull(); - expect(result.first).not.toBeNull(); - expect(result.first!.isAjaxResult).toBeFalsy(); - }); - - it('should handle NullCustomerId', () => { - //Arrange - resetMocks(); - KnownUser.UserInQueueService = userInQueueServiceMock; - - //Act - const result = KnownUser.resolveQueueRequestByLocalConfig("targetUrl", "queueitToken", null, '', "secretKey", httpContextMock); - const exceptionWasThrown = result.second != null && result.second!.message == "customerId can not be null or empty."; - - //Assert - expect(userInQueueServiceMock.validateQueueRequestCall).toBeNull(); - expect(exceptionWasThrown).toBeTruthy(); - }); - - it('NullSecretKey', () => { - //Arrange - resetMocks(); - KnownUser.UserInQueueService = userInQueueServiceMock; - - //Act - const result = KnownUser.resolveQueueRequestByLocalConfig("targetUrl", "queueitToken", null, "customerId", '', httpContextMock); - const exceptionWasThrown = result.second != null && result.second!.message == "secretKey can not be null or empty."; - - //Assert - expect(userInQueueServiceMock.validateQueueRequestCall).toBeNull(); - expect(exceptionWasThrown).toBeTruthy(); - }); - - it('NullEventConfig', () => { - //Arrange - resetMocks(); - KnownUser.UserInQueueService = userInQueueServiceMock; - - //Act - let result = KnownUser.resolveQueueRequestByLocalConfig("targetUrl", "queueitToken", null, "customerId", "secretKey", httpContextMock); - const exceptionWasThrown = result.second != null && result.second!.message == "queueConfig can not be null."; - - //Assert - expect(userInQueueServiceMock.validateQueueRequestCall).toBeNull(); - expect(exceptionWasThrown).toBeTruthy(); - }); - - it('NullEventId', () => { - //Arrange - resetMocks(); - - const eventconfig = new QueueEventConfig('', '', '', '', false, 0, '', 0); - eventconfig.cookieDomain = "cookieDomain"; - eventconfig.layoutName = "layoutName"; - eventconfig.culture = "culture"; - eventconfig.queueDomain = "queueDomain"; - eventconfig.extendCookieValidity = true; - eventconfig.cookieValidityMinute = 10; - eventconfig.version = 12; - KnownUser.UserInQueueService = userInQueueServiceMock; - - //Act - const result = KnownUser.resolveQueueRequestByLocalConfig("targeturl", "queueIttoken", eventconfig, "customerid", "secretkey", httpContextMock); - const exceptionWasThrown = result.second != null && result.second!.message == "queueConfig.eventId can not be null or empty."; - - //Assert - expect(userInQueueServiceMock.validateQueueRequestCall).toBeNull(); - expect(exceptionWasThrown).toBeTruthy(); - }); - - it('NullQueueDomain', () => { - //Arrange - resetMocks(); - - const eventconfig = new QueueEventConfig('', '', '', '', false, 0, '', 0); - eventconfig.cookieDomain = "cookieDomain"; - eventconfig.layoutName = "layoutName"; - eventconfig.culture = "culture"; - eventconfig.eventId = "eventId"; - eventconfig.queueDomain = ''; - eventconfig.extendCookieValidity = true; - eventconfig.cookieValidityMinute = 10; - eventconfig.version = 12; - KnownUser.UserInQueueService = userInQueueServiceMock; - - //Act - const result = KnownUser.resolveQueueRequestByLocalConfig("targeturl", "queueIttoken", eventconfig, "customerid", "secretkey", httpContextMock); - const exceptionWasThrown = result.second != null && result.second!.message == "queueConfig.queueDomain can not be null or empty."; - - //Assert - expect(userInQueueServiceMock.validateQueueRequestCall).toBeNull(); - expect(exceptionWasThrown).toBeTruthy(); - }); - - it('InvalidCookieValidityMinute', () => { - //Arrange - resetMocks(); - - const eventconfig = new QueueEventConfig('', '', '', '', false, 0, '', 0); - eventconfig.cookieDomain = "cookieDomain"; - eventconfig.layoutName = "layoutName"; - eventconfig.culture = "culture"; - eventconfig.eventId = "eventId"; - eventconfig.queueDomain = "queueDomain"; - eventconfig.extendCookieValidity = true; - eventconfig.cookieValidityMinute = 0; - eventconfig.version = 12; - KnownUser.UserInQueueService = userInQueueServiceMock; - - //Act - const result = KnownUser.resolveQueueRequestByLocalConfig("targeturl", "queueIttoken", eventconfig, "customerid", "secretkey", httpContextMock); - const exceptionWasThrown = result.second != null && result.second!.message == "queueConfig.cookieValidityMinute should be integer greater than 0."; - - //Assert - expect(userInQueueServiceMock.validateQueueRequestCall).toBeNull(); - expect(exceptionWasThrown).toBeTruthy(); - }); - - it('should have Debug cookie if token is present', () => { - resetMocks(); - - const requestIP = "80.35.35.34"; - const viaHeader = "v"; - const forwardedHeader = "f"; - const xForwardedForHeader = "xff"; - const xForwardedHostHeader = "xfh"; - const xForwardedProtoHeader = "xfp"; - - httpContextMock.req.headers.set('via', viaHeader); - httpContextMock.req.headers.set('forwarded', forwardedHeader); - httpContextMock.req.headers.set('x-forwarded-for', xForwardedForHeader); - httpContextMock.req.headers.set('x-forwarded-host', xForwardedHostHeader); - httpContextMock.req.headers.set('x-forwarded-proto', xForwardedProtoHeader); - - httpContextMock.req.setAbsoluteUri("http://test.com/?event1=true&queueittoken=queueittokenvalue"); - httpContextMock.req.setUserHostAddress(requestIP); - - const secretKey = "secretKey"; - const queueitToken = generateDebugToken("eventId", secretKey); - const dateTimeProviderMock = new MockDateTimeProvider(); - const expectedServerTime = dateTimeProviderMock.getCurrentTime().toISOString().split('.')[0] + "Z"; - - const eventconfig = new QueueEventConfig('', '', '', '', false, 0, '', 0); - eventconfig.cookieDomain = "cookieDomain"; - eventconfig.layoutName = "layoutName"; - eventconfig.culture = "culture"; - eventconfig.eventId = "eventId"; - eventconfig.queueDomain = "queueDomain"; - eventconfig.extendCookieValidity = true; - eventconfig.cookieValidityMinute = 10; - eventconfig.version = 12; - eventconfig.actionName = "event1action"; - - KnownUser.UserInQueueService = userInQueueServiceMock; - - const result = KnownUser.resolveQueueRequestByLocalConfig("http://test.com?event1=true", - queueitToken, - eventconfig, - "customerId", - secretKey, - httpContextMock, - dateTimeProviderMock); - const actualCookieValue = httpContextMock.res.cookies.get(KnownUser.QueueITDebugKey)!.value; - - expect(actualCookieValue.indexOf("QueueitToken=" + queueitToken)).not.toBe(-1); - expect(actualCookieValue.indexOf("TargetUrl=http://test.com?event1=true")).not.toBe(-1); - expect(actualCookieValue.indexOf("QueueitToken=" + queueitToken)).not.toBe(-1); - expect(actualCookieValue.indexOf("OriginalUrl=http://test.com/?event1=true&queueittoken=queueittokenvalue")).not.toBe(-1); - expect(actualCookieValue.indexOf("ServerUtcTime=" + expectedServerTime)).not.toBe(-1); - expect(actualCookieValue.indexOf("RequestIP=80.35.35.34")).not.toBe(-1); - expect(actualCookieValue.indexOf("RequestHttpHeader_Via=v")).not.toBe(-1); - expect(actualCookieValue.indexOf("RequestHttpHeader_Forwarded=f")).not.toBe(-1); - expect(actualCookieValue.indexOf("RequestHttpHeader_XForwardedFor=xff")).not.toBe(-1); - expect(actualCookieValue.indexOf("RequestHttpHeader_XForwardedHost=xfh")).not.toBe(-1); - expect(actualCookieValue.indexOf("RequestHttpHeader_XForwardedProto=xfp")).not.toBe(-1); - expect(actualCookieValue.indexOf("QueueConfig=EventId:eventId&Version:12&ActionName:event1action&QueueDomain:queueDomain&CookieDomain:cookieDomain&ExtendCookieValidity:true&CookieValidityMinute:10&LayoutName:layoutName&Culture:culture")).not.toBe(-1); - }); - - it('should Debug_NullConfig', () => { - resetMocks(); - - httpContextMock.req.setAbsoluteUri("http://test.com?event1=true"); - httpContextMock.req.setUserHostAddress("userIP"); - mockGoogleHeaders(); - - const secretKey = "secretKey"; - const queueitToken = generateDebugToken("eventId", secretKey); - // const expectedServerTime = (new Date(Date.now())).toISOString().split('.')[0] + "Z"; - KnownUser.UserInQueueService = userInQueueServiceMock; - - const result = KnownUser.resolveQueueRequestByLocalConfig("http://test.com?event1=true", queueitToken, null, "customerId", secretKey, httpContextMock); - const errorReturned = result.second != null && result.second!.message == 'queueConfig can not be null.'; - expect(errorReturned).toBeTruthy(); - - //Assert - expect(userInQueueServiceMock.validateQueueRequestCall).toBeNull(); - - const actualCookieValue = httpContextMock.res.cookies.get(KnownUser.QueueITDebugKey)!.value - expect(actualCookieValue.indexOf("QueueConfig=NULL|")).not.toBe(-1); - expect(actualCookieValue.indexOf("OriginalUrl=http://test.com?event1=true|")).not.toBe(-1); - expect(actualCookieValue.indexOf("QueueitToken=" + queueitToken + "|")).not.toBe(-1); - expect(actualCookieValue.indexOf("SdkVersion=" + SDK_VERSION + "|")).not.toBe(-1); - expect(actualCookieValue.indexOf("Exception=queueConfig can not be null.")).not.toBe(-1); - }); - - it('should Debug_Missing_CustomerId', () => { - resetMocks(); - const eventconfig = new QueueEventConfig('', '', '', '', false, 0, '', 0); - httpContextMock.req.setAbsoluteUri("http://localhost/original_url"); - httpContextMock.req.setUserHostAddress("userIP"); - mockGoogleHeaders(); - - const secretKey = "secretKey"; - const queueitToken = generateDebugToken("eventId", secretKey); - // const expectedServerTime = (new Date(Date.now())).toISOString().split('.')[0] + "Z"; - KnownUser.UserInQueueService = userInQueueServiceMock; - - const result = KnownUser.resolveQueueRequestByLocalConfig("http://test.com?event1=true", queueitToken, eventconfig, '', secretKey, httpContextMock); - //Assert - expect("https://api2.queue-it.net/diagnostics/connector/error/?code=setup" == result.first!.redirectUrl); - expect(httpContextMock.res.cookies.has(KnownUser.QueueITDebugKey)).toBeFalsy(); - }); - - it('should Debug_Missing_SecretKey', () => { - resetMocks(); - const eventconfig = new QueueEventConfig('', '', '', '', false, 0, '', 0); - httpContextMock.req.setAbsoluteUri("http://localhost/original_url"); - httpContextMock.req.setUserHostAddress("userIP"); - mockGoogleHeaders(); - - const secretKey = "secretKey"; - const queueitToken = generateDebugToken("eventId", secretKey); - // const expectedServerTime = (new Date(Date.now())).toISOString().split('.')[0] + "Z"; - KnownUser.UserInQueueService = userInQueueServiceMock; - - const result = KnownUser.resolveQueueRequestByLocalConfig("http://test.com?event1=true", queueitToken, eventconfig, "customerId", '', httpContextMock); - - //Assert - expect(result.first!.redirectUrl).toBe('https://api2.queue-it.net/diagnostics/connector/error/?code=setup'); - expect(httpContextMock.res.cookies.has(KnownUser.QueueITDebugKey)).toBeFalsy(); - }); - - it('should Debug_ExpiredToken', () => { - resetMocks(); - - const eventconfig = new QueueEventConfig('', '', '', '', false, 0, '', 0); - httpContextMock.req.setAbsoluteUri("http://localhost/original_url"); - httpContextMock.req.setUserHostAddress("userIP"); - mockGoogleHeaders(); - - const secretKey = "secretKey"; - const queueitToken = generateDebugToken("eventId", secretKey, true); - // const expectedServerTime = (new Date(Date.now())).toISOString().split('.')[0] + "Z"; - KnownUser.UserInQueueService = userInQueueServiceMock; - - const result = KnownUser.resolveQueueRequestByLocalConfig("http://test.com?event1=true", queueitToken, eventconfig, "customerId", secretKey, httpContextMock); - - //Assert - expect(result.first!.redirectUrl).toBe('https://customerId.api2.queue-it.net/customerId/diagnostics/connector/error/?code=timestamp'); - expect(httpContextMock.res.cookies.has(KnownUser.QueueITDebugKey)).toBeFalsy(); - }); - - it('should Debug_ModifiedToken', () => { - resetMocks(); - const eventconfig = new QueueEventConfig('', '', '', '', false, 0, '', 0); - httpContextMock.req.setAbsoluteUri("http://localhost/original_url"); - httpContextMock.req.setUserHostAddress("userIP"); - mockGoogleHeaders(); - - const secretKey = "secretKey"; - const queueitToken = generateDebugToken("eventId", secretKey) + "invalid-hash"; - // const expectedServerTime = (new Date(Date.now())).toISOString().split('.')[0] + "Z"; - KnownUser.UserInQueueService = userInQueueServiceMock; - - const result = KnownUser.resolveQueueRequestByLocalConfig("http://test.com?event1=true", queueitToken, eventconfig, "customerId", secretKey, httpContextMock); - - //Assert - expect(result.first!.redirectUrl).toBe('https://customerId.api2.queue-it.net/customerId/diagnostics/connector/error/?code=hash'); - expect(httpContextMock.res.cookies.has(KnownUser.QueueITDebugKey)).toBeFalsy(); - }); - - it('should Exception_NoDebugToken', () => { - resetMocks(); - - const requestIP = "80.35.35.34"; - const viaHeader = "v"; - const forwardedHeader = "f"; - const xForwardedForHeader = "xff"; - const xForwardedHostHeader = "xfh"; - const xForwardedProtoHeader = "xfp"; - - httpContextMock.req.headers.set('via', viaHeader); - httpContextMock.req.headers.set('forwarded', forwardedHeader); - httpContextMock.req.headers.set('x-forwarded-for', xForwardedForHeader); - httpContextMock.req.headers.set('x-forwarded-host', xForwardedHostHeader); - httpContextMock.req.headers.set('x-forwarded-proto', xForwardedProtoHeader); - - httpContextMock.req.setAbsoluteUri("http://test.com/?event1=true&queueittoken=queueittokenvalue"); - httpContextMock.req.setUserHostAddress(requestIP); - - const secretKey = "secretKey"; - const queueitToken = generateDebugToken("eventId", secretKey); - const expectedServerTime = new Date(Date.now()).toISOString().split('.')[0] + "Z"; - - const eventconfig = new QueueEventConfig('', '', '', '', false, 0, '', 0); - eventconfig.cookieDomain = "cookieDomain"; - eventconfig.layoutName = "layoutName"; - eventconfig.culture = "culture"; - eventconfig.eventId = "eventId"; - eventconfig.queueDomain = "queueDomain"; - eventconfig.extendCookieValidity = true; - eventconfig.cookieValidityMinute = 10; - eventconfig.version = 12; - eventconfig.actionName = "event1action"; - - userInQueueServiceMock.validateQueueRequestResultRaiseException = true; - KnownUser.UserInQueueService = userInQueueServiceMock; - - //Act - const result = KnownUser.resolveQueueRequestByLocalConfig("http://test.com?event1=true", "queueitToken", eventconfig, "customerId", secretKey, httpContextMock); - - //Assert - expect(result.first).toBeNull(); - expect(result.second).not.toBeNull(); - expect(httpContextMock.res.cookies.has(KnownUser.QueueITDebugKey)).toBeFalsy(); - }); -}) - -describe('cancelRequestByLocalConfig', () => { - it('should work for non-ajax requests', () => { - resetMocks(); - - const cancelEventConfig = new CancelEventConfig("", "", "", 0); - cancelEventConfig.cookieDomain = "cookieDomain"; - cancelEventConfig.eventId = "eventId"; - cancelEventConfig.queueDomain = "queueDomain"; - cancelEventConfig.version = 1; - - KnownUser.UserInQueueService = userInQueueServiceMock; - const result = KnownUser.cancelRequestByLocalConfig("url", "queueitToken", cancelEventConfig, "customerid", "secretkey", httpContextMock); - - expect(userInQueueServiceMock.validateCancelRequestCall!.method).toBe('validateCancelRequest'); - expect(userInQueueServiceMock.validateCancelRequestCall!.targetUrl).toBe('url'); - expect(userInQueueServiceMock.validateCancelRequestCall!.cancelConfig).toBe(cancelEventConfig); - expect(userInQueueServiceMock.validateCancelRequestCall!.customerId).toBe('customerid'); - expect(userInQueueServiceMock.validateCancelRequestCall!.secretKey).toBe('secretkey'); - expect(result.first!.isAjaxResult).toBeFalsy(); - }); - - it('should AjaxCall', () => { - resetMocks(); - - const cancelEventConfig = new CancelEventConfig('', '', '', 0); - cancelEventConfig.cookieDomain = "cookieDomain"; - cancelEventConfig.eventId = "eventId"; - cancelEventConfig.queueDomain = "queueDomain"; - cancelEventConfig.version = 1; - - KnownUser.UserInQueueService = userInQueueServiceMock; - const result = KnownUser.cancelRequestByLocalConfig("url", "queueitToken", cancelEventConfig, "customerid", "secretkey", httpContextMock); - - expect(userInQueueServiceMock.validateCancelRequestCall!.method).toBe('validateCancelRequest'); - expect(userInQueueServiceMock.validateCancelRequestCall!.targetUrl).toBe('url'); - expect(userInQueueServiceMock.validateCancelRequestCall!.cancelConfig).toBe(cancelEventConfig); - expect(userInQueueServiceMock.validateCancelRequestCall!.customerId).toBe('customerid'); - expect(userInQueueServiceMock.validateCancelRequestCall!.secretKey).toBe('secretkey'); - expect(result.first!.isAjaxResult).toBeFalsy(); - }); - - it('should NullQueueDomain', () => { - //Arrange - resetMocks(); - - const cancelEventConfig = new CancelEventConfig('', '', '', 0); - cancelEventConfig.eventId = "eventId"; - cancelEventConfig.cookieDomain = "cookieDomain"; - cancelEventConfig.version = 12; - - //Act - let result = KnownUser.cancelRequestByLocalConfig("targetUrl", "queueitToken", cancelEventConfig, "customerId", "secretKey", httpContextMock); - let exceptionWasThrown = result.second != null && result.second!.message == "cancelConfig.queueDomain can not be null or empty."; - - //Assert - expect(userInQueueServiceMock.validateCancelRequestCall).toBeNull(); - expect(exceptionWasThrown).toBeTruthy(); - }); - - it('should EventIdNull', () => { - //Arrange - resetMocks(); - - const cancelEventConfig = new CancelEventConfig('', '', '', 0); - cancelEventConfig.cookieDomain = "cookieDomain"; - cancelEventConfig.version = 12; - - //Act - const result = KnownUser.cancelRequestByLocalConfig("targetUrl", "queueitToken", cancelEventConfig, "customerId", "secretKey", httpContextMock); - const exceptionWasThrown = result.second != null && result.second!.message == "cancelConfig.eventId can not be null or empty."; - - //Assert - expect(userInQueueServiceMock.validateCancelRequestCall).toBeNull(); - expect(exceptionWasThrown).toBeTruthy(); - }); - - it('should CancelEventConfigNull', () => { - //Arrange - resetMocks(); - - //Act - const result = KnownUser.cancelRequestByLocalConfig("targetUrl", "queueitToken", null, "customerId", "secretKey", httpContextMock); - const exceptionWasThrown = result.second != null && result.second!.message == "cancelConfig can not be null."; - - //Assert - expect(userInQueueServiceMock.validateCancelRequestCall).toBeNull(); - expect(exceptionWasThrown).toBeTruthy(); - }); - - it('should CustomerIdNull', () => { - //Arrange - resetMocks(); - - const eventconfig = new CancelEventConfig('', '', '', 0); - - //Act - const result = KnownUser.cancelRequestByLocalConfig("targetUrl", "queueitToken", eventconfig, '', "secretKey", httpContextMock); - const exceptionWasThrown = result.second != null && result.second!.message == "customerId can not be null or empty."; - - //Assert - expect(userInQueueServiceMock.validateCancelRequestCall).toBeNull(); - expect(exceptionWasThrown).toBeTruthy(); - }); - - it('should SecretKeyNull', () => { - //Arrange - resetMocks(); - const eventconfig = new CancelEventConfig('', '', '', 0); - - //Act - const result = KnownUser.cancelRequestByLocalConfig("targetUrl", "queueitToken", eventconfig, "customerid", '', httpContextMock); - const exceptionWasThrown = result.second != null && result.second!.message == "secretKey can not be null or empty."; - - //Assert - expect(userInQueueServiceMock.validateCancelRequestCall).toBeNull(); - expect(exceptionWasThrown).toBeTruthy(); - }); - - it('should TargetUrl', () => { - //Arrange - resetMocks(); - const eventconfig = new CancelEventConfig('', '', '', 0); - - //Act - const result = KnownUser.cancelRequestByLocalConfig('', "queueitToken", eventconfig, "customerid", "secretkey", httpContextMock); - const exceptionWasThrown = result.second != null && result.second!.message == "targetUrl can not be null or empty."; - - //Assert - expect(userInQueueServiceMock.validateCancelRequestCall).toBeNull(); - expect(exceptionWasThrown).toBeTruthy(); - }) - - it('should Debug', () => { - resetMocks(); - - const requestIP = "80.35.35.34"; - const viaHeader = "1.1 example.com"; - const forwardedHeader = "for=192.0.2.60;proto=http;by=203.0.113.43"; - const xForwardedForHeader = "129.78.138.66, 129.78.64.103"; - const xForwardedHostHeader = "en.wikipedia.org:8080"; - const xForwardedProtoHeader = "https"; - - httpContextMock.req.headers.set('via', viaHeader); - httpContextMock.req.headers.set('forwarded', forwardedHeader); - httpContextMock.req.headers.set('x-forwarded-for', xForwardedForHeader); - httpContextMock.req.headers.set('x-forwarded-host', xForwardedHostHeader); - httpContextMock.req.headers.set('x-forwarded-proto', xForwardedProtoHeader); - httpContextMock.req.setAbsoluteUri("http://test.com/?event1=true&queueittoken=queueittokenvalue"); - httpContextMock.req.setUserHostAddress(requestIP); - - const secretKey = "secretKey"; - const queueitToken = generateDebugToken("eventId", secretKey); - const dateTimeProviderMock = new MockDateTimeProvider(); - const expectedServerTime = dateTimeProviderMock.getCurrentTime().toISOString().split('.')[0] + "Z"; - - const cancelEventconfig = new CancelEventConfig('', '', '', 0); - cancelEventconfig.cookieDomain = "cookieDomain"; - cancelEventconfig.eventId = "eventId"; - cancelEventconfig.queueDomain = "queueDomain"; - cancelEventconfig.version = 1; - - KnownUser.UserInQueueService = userInQueueServiceMock; - const result = KnownUser.cancelRequestByLocalConfig("http://test.com?event1=true", - queueitToken, - cancelEventconfig, - "customerid", - "secretKey", - httpContextMock, - dateTimeProviderMock); - - const actualCookieValue = httpContextMock.res.cookies.get(KnownUser.QueueITDebugKey)!.value; - - expect(userInQueueServiceMock.validateCancelRequestCall!.method).toBe('validateCancelRequest'); - expect(userInQueueServiceMock.validateCancelRequestCall!.targetUrl).toBe('http://test.com?event1=true'); - expect(userInQueueServiceMock.validateCancelRequestCall!.cancelConfig).toBe(cancelEventconfig); - expect(userInQueueServiceMock.validateCancelRequestCall!.customerId).toBe('customerid'); - expect(userInQueueServiceMock.validateCancelRequestCall!.secretKey).toBe('secretKey'); - expect(result.first!.isAjaxResult).toBeFalsy(); - - expect(actualCookieValue.indexOf("QueueitToken=" + queueitToken)).not.toBe(-1) - expect(actualCookieValue.indexOf("OriginalUrl=http://test.com/?event1=true&queueittoken=queueittokenvalue")).not.toBe(-1) - expect(actualCookieValue.indexOf("TargetUrl=http://test.com?event1=true")).not.toBe(-1) - expect(actualCookieValue.indexOf("QueueitToken=" + queueitToken)).not.toBe(-1) - expect(actualCookieValue.indexOf("ServerUtcTime=" + expectedServerTime)).not.toBe(-1) - expect(actualCookieValue.indexOf("RequestIP=80.35.35.34")).not.toBe(-1) - expect(actualCookieValue.indexOf("RequestHttpHeader_Via=1.1 example.com")).not.toBe(-1) - expect(actualCookieValue.indexOf("RequestHttpHeader_Forwarded=for=192.0.2.60;proto=http;by=203.0.113.43")).not.toBe(-1) - expect(actualCookieValue.indexOf("RequestHttpHeader_XForwardedFor=129.78.138.66, 129.78.64.103")).not.toBe(-1) - expect(actualCookieValue.indexOf("RequestHttpHeader_XForwardedHost=en.wikipedia.org:8080")).not.toBe(-1) - expect(actualCookieValue.indexOf("RequestHttpHeader_XForwardedProto=https")).not.toBe(-1) - expect(actualCookieValue.indexOf("EventId:eventId&Version:1&QueueDomain:queueDomain&CookieDomain:cookieDomain")).not.toBe(-1); - }); - - it('should Debug_NullConfig', () => { - resetMocks(); - - httpContextMock.req.setAbsoluteUri("http://test.com?event1=true"); - httpContextMock.req.setUserHostAddress("userIP"); - mockGoogleHeaders(); - - const secretKey = "secretKey"; - const queueitToken = generateDebugToken("eventId", secretKey); - // const expectedServerTime = (new Date(Date.now())).toISOString().split('.')[0] + "Z"; - KnownUser.UserInQueueService = userInQueueServiceMock; - - const result = KnownUser.cancelRequestByLocalConfig("http://test.com?event1=true", queueitToken, null, "customerId", secretKey, httpContextMock); - const errorReturned = result.second != null && result.second!.message == "cancelConfig can not be null."; - - //Assert - expect(userInQueueServiceMock.validateQueueRequestCall).toBeNull(); - expect(errorReturned).toBeTruthy(); - const actualCookieValue = httpContextMock.res.cookies.get(KnownUser.QueueITDebugKey)!.value; - expect(actualCookieValue.indexOf("CancelConfig=NULL|")).not.toBe(-1); - expect(actualCookieValue.indexOf("OriginalUrl=http://test.com?event1=true|")).not.toBe(-1); - expect(actualCookieValue.indexOf("QueueitToken=" + queueitToken + "|")).not.toBe(-1); - expect(actualCookieValue.indexOf("SdkVersion=" + SDK_VERSION + "|")).not.toBe(-1); - expect(actualCookieValue.indexOf("Exception=cancelConfig can not be null.")).not.toBe(-1); - }); - - it('should Debug_Missing_CustomerId', () => { - resetMocks(); - const cancelConfig = new CancelEventConfig('', '', '', 0); - httpContextMock.req.setAbsoluteUri("http://localhost/original_url"); - httpContextMock.req.setUserHostAddress("userIP"); - mockGoogleHeaders(); - - const secretKey = "secretKey"; - const queueitToken = generateDebugToken("eventId", secretKey); - // const expectedServerTime = (new Date(Date.now())).toISOString().split('.')[0] + "Z"; - KnownUser.UserInQueueService = userInQueueServiceMock; - - const result = KnownUser.cancelRequestByLocalConfig("http://test.com?event1=true", queueitToken, cancelConfig, '', secretKey, httpContextMock); - //Assert - expect("https://api2.queue-it.net/diagnostics/connector/error/?code=setup" == result.first!.redirectUrl); - expect(httpContextMock.res.cookies.has(KnownUser.QueueITDebugKey)).toBeFalsy(); - }); - - it('should Debug_Missing_SecretKey', () => { - resetMocks(); - const cancelConfig = new CancelEventConfig('', '', '', 0); - httpContextMock.req.setAbsoluteUri("http://localhost/original_url"); - httpContextMock.req.setUserHostAddress("userIP"); - mockGoogleHeaders(); - - const secretKey = "secretKey"; - const queueitToken = generateDebugToken("eventId", secretKey); - // const expectedServerTime = (new Date(Date.now())).toISOString().split('.')[0] + "Z"; - KnownUser.UserInQueueService = userInQueueServiceMock; - - const result = KnownUser.cancelRequestByLocalConfig("http://test.com?event1=true", queueitToken, cancelConfig, "customerId", '', httpContextMock); - //Assert - expect("https://api2.queue-it.net/diagnostics/connector/error/?code=setup" == result.first!.redirectUrl); - expect(httpContextMock.res.cookies.has(KnownUser.QueueITDebugKey)).toBeFalsy(); - }); - - it('should Debug_ExpiredToken', () => { - resetMocks(); - const cancelConfig = new CancelEventConfig('', '', '', 0); - httpContextMock.req.setAbsoluteUri("http://localhost/original_url"); - httpContextMock.req.setUserHostAddress("userIP"); - mockGoogleHeaders(); - - const secretKey = "secretKey"; - const queueitToken = generateDebugToken("eventId", secretKey, true); - // const expectedServerTime = (new Date(Date.now())).toISOString().split('.')[0] + "Z"; - KnownUser.UserInQueueService = userInQueueServiceMock; - - const result = KnownUser.cancelRequestByLocalConfig("http://test.com?event1=true", queueitToken, cancelConfig, "customerId", secretKey, httpContextMock); - //Assert - expect("https://customerId.api2.queue-it.net/customerId/diagnostics/connector/error/?code=timestamp" == result.first!.redirectUrl); - expect(httpContextMock.res.cookies.has(KnownUser.QueueITDebugKey)).toBeFalsy(); - }); - - it('should Debug_ModifiedToken', () => { - resetMocks(); - const cancelConfig = new CancelEventConfig('', '', '', 0); - httpContextMock.req.setAbsoluteUri("http://localhost/original_url"); - httpContextMock.req.setUserHostAddress("userIP"); - mockGoogleHeaders(); - - const secretKey = "secretKey"; - const queueitToken = generateDebugToken("eventId", secretKey) + "invalid-hash"; - // const expectedServerTime = (new Date(Date.now())).toISOString().split('.')[0] + "Z"; - KnownUser.UserInQueueService = userInQueueServiceMock; - - const result = KnownUser.cancelRequestByLocalConfig("http://test.com?event1=true", queueitToken, cancelConfig, "customerId", secretKey, httpContextMock); - //Assert - expect("https://customerId.api2.queue-it.net/customerId/diagnostics/connector/error/?code=hash" == result.first!.redirectUrl); - expect(httpContextMock.res.cookies.has(KnownUser.QueueITDebugKey)).toBeFalsy(); - }); - - it('should Exception_NoDebugToken', () => { - resetMocks(); - - const requestIP = "80.35.35.34"; - const viaHeader = "1.1 example.com"; - const forwardedHeader = "for=192.0.2.60;proto=http;by=203.0.113.43"; - const xForwardedForHeader = "129.78.138.66, 129.78.64.103"; - const xForwardedHostHeader = "en.wikipedia.org:8080"; - const xForwardedProtoHeader = "https"; - - httpContextMock.req.headers.set('via', viaHeader); - httpContextMock.req.headers.set('forwarded', forwardedHeader); - httpContextMock.req.headers.set('x-forwarded-for', xForwardedForHeader); - httpContextMock.req.headers.set('x-forwarded-host', xForwardedHostHeader); - httpContextMock.req.headers.set('x-forwarded-proto', xForwardedProtoHeader); - - httpContextMock.req.setAbsoluteUri("http://test.com/?event1=true&queueittoken=queueittokenvalue"); - httpContextMock.req.setUserHostAddress(requestIP); - - const secretKey = "secretKey"; - - const cancelEventconfig = new CancelEventConfig('', '', '', 0); - cancelEventconfig.cookieDomain = "cookieDomain"; - cancelEventconfig.eventId = "eventId"; - cancelEventconfig.queueDomain = "queueDomain"; - cancelEventconfig.version = 1; - userInQueueServiceMock.validateCancelRequestrRaiseException = true; - KnownUser.UserInQueueService = userInQueueServiceMock; - - const result = KnownUser.cancelRequestByLocalConfig("http://test.com?event1=true", - "queueitToken", cancelEventconfig, "customerid", "secretKey", httpContextMock); - - expect(httpContextMock.res.cookies.has(KnownUser.QueueITDebugKey)).toBeFalsy(); - }); -}); diff --git a/src/__tests__/Mocks.ts b/src/__tests__/Mocks.ts deleted file mode 100644 index 26aa1f6..0000000 --- a/src/__tests__/Mocks.ts +++ /dev/null @@ -1,319 +0,0 @@ -import {IDateTimeProvider, IHttpContextProvider, IHttpRequest, IHttpResponse} from "../sdk/HttpContextProvider"; -import {StateInfo, UserInQueueStateCookieRepository} from "../sdk/UserInQueueStateCookieRepository"; -import {UserInQueueService} from "../sdk/UserInQueueService"; -import { - CancelEventConfig, - KnownUserException, - QueueEventConfig, - RequestValidationResult, - ValidationResult -} from "../sdk/Models"; -import {encodeURIComponent} from "../sdk/helpers/Uri"; - -export class MockHttpRequest implements IHttpRequest { - headers: Map = new Map(); - cookies: Map = new Map(); - private userHostAddress: string = ""; - private absoluteUri: string = ""; - private body: string = ""; - - getAbsoluteUri(): string { - return this.absoluteUri; - } - - setAbsoluteUri(value: string): void { - this.absoluteUri = value; - } - - getCookieValue(cookieKey: string): string { - if (!this.cookies.has(cookieKey)) { - return '' - } - return this.cookies.get(cookieKey)!.value; - } - - setCookieValue(name: string, value: string): MockHttpRequest { - this.cookies.set(name, new MockCookie(value, '', 0)); - return this; - } - - setCookie(name: string, cookie: MockCookie): MockHttpRequest { - this.cookies.set(name, cookie); - return this; - } - - setHeader(name: string, value: string): MockHttpRequest { - this.headers.set(name, value); - return this; - } - - getHeader(name: string): string { - return this.headers.has(name.toLowerCase()) ? this.headers.get(name.toLowerCase())! : ''; - } - - setBody(body: string): void { - this.body = body; - } - - getRequestBodyAsString(): string { - return this.body; - } - - getUserAgent(): string { - return this.headers.has('user-agent') ? this.headers.get('user-agent')! : 'mocked-user-agent'; - } - - setUserAgent(value: string): MockHttpRequest { - this.headers.set("user-agent", value); - return this; - } - - getUserHostAddress(): string { - return this.userHostAddress; - } - - setUserHostAddress(value: string): void { - this.userHostAddress = value; - } - - reset(): void { - this.userHostAddress = ""; - this.absoluteUri = ""; - this.body = ""; - this.headers.clear(); - this.cookies.clear(); - } -} - -export class MockCookie { - constructor(public value: string, public domain: string, public expiration: number) { - - } -} - -export class MockHttpResponse implements IHttpResponse { - cookies: Map = new Map(); - private cookieHeader: string = ''; - - setCookie(cookieName: string, cookieValue: string, domain: string, expiration: number): void { - const expirationDate = new Date(expiration * 1000); - let setCookieString = cookieName + "=" + encodeURIComponent(cookieValue) + "; expires=" + expirationDate.toUTCString() + ";"; - if (domain != "") { - setCookieString += " domain=" + domain + ";"; - } - setCookieString += " path=/;"; - this.cookieHeader = setCookieString; - this.cookies.set(cookieName, new MockCookie(cookieValue, domain, expiration)) - } - - reset(): void { - this.cookies.clear(); - this.cookieHeader = ''; - } - - getHeaders(): Headers { - let h = new Headers(); - h.set('set-cookie', this.cookieHeader); - return h; - } -} - -export class MockDateTimeProvider implements IDateTimeProvider { - public constructor(public date: Date = new Date(Date.now())) { - } - - getCurrentTime(): Date { - return this.date; - } -} - -export class MockHttpContextProvider implements IHttpContextProvider { - constructor(public req: MockHttpRequest, public res: MockHttpResponse) { - } - - getHttpRequest(): IHttpRequest { - return this.req != null ? this.req : new MockHttpRequest(); - } - - getHttpResponse(): IHttpResponse { - return this.res != null ? this.res : new MockHttpResponse(); - } - - reset(): void { - this.req.reset(); - this.res.reset(); - } -} - -export class ValidateQueueRequestCall { - public constructor( - public method: string, - public targetUrl: string, - public queueitToken: string, - public queueConfig: QueueEventConfig, - public customerId: string, - public secretKey: string - ) { - } -} - -export class ValidateCancelRequestCall { - public constructor( - public method: string, - public targetUrl: string, - public cancelConfig: CancelEventConfig, - public customerId: string, - public secretKey: string - ) { - } -} - -export class RequestValidationResultRecording { - public constructor( - public method: string, - public eventId: string, - public queueId: string, - public redirectUrl: string, - public redirectType: string, - public actionType: string, - public actionName: string - ) { - } -} - -export class ExtendQueueCookieCall { - public constructor( - public method: string, - public eventId: string, - public cookieValidityMinute: number, - public cookieDomain: string, - public secretKey: string - ) { - } -} - -export class UserInQueueServiceMock extends UserInQueueService { - validateQueueRequestResult: RequestValidationResult; - cancelRequestCalls: Map; - extendQueueCookieCalls: Map; - validateQueueRequestCall: ValidateQueueRequestCall | null = null; - validateCancelRequestCall: ValidateCancelRequestCall | null = null; - extendQueueCookieCall: ExtendQueueCookieCall | null = null; - getIgnoreResultIsCalled: boolean; - validateCancelRequestrRaiseException: boolean; - validateQueueRequestResultRaiseException: boolean; - requestValidationResult: RequestValidationResultRecording | null = null; - - constructor(private repo: UserInQueueStateCookieRepository) { - super(repo); - this.validateQueueRequestResult = new RequestValidationResult("", "", "", "", ""); - this.cancelRequestCalls = new Map(); - this.extendQueueCookieCalls = new Map(); - this.getIgnoreResultIsCalled = false; - this.validateCancelRequestrRaiseException = false; - this.validateQueueRequestResultRaiseException = false; - } - - getIgnoreResult(actionName: string): RequestValidationResult { - this.getIgnoreResultIsCalled = true; - - const r = new RequestValidationResultRecording("getIgnoreResult", '', '', '', '', 'Ignore', actionName); - this.requestValidationResult = r; - const result = new RequestValidationResult(r.actionType, r.eventId, r.queueId, r.redirectUrl, r.redirectType, r.actionName); - return result; - } - - validateQueueRequest(targetUrl: string, queueitToken: string, queueConfig: QueueEventConfig, - customerId: string, secretKey: string): ValidationResult { - this.validateQueueRequestCall = new ValidateQueueRequestCall( - "validateQueueRequest", - targetUrl, - queueitToken, - queueConfig, - customerId, - secretKey); - - if (this.validateQueueRequestResultRaiseException) { - return new ValidationResult(null, new KnownUserException("mocked exception")) - } else { - return new ValidationResult(this.validateQueueRequestResult, null); - } - } - - validateCancelRequest(targetUrl: string, - cancelConfig: CancelEventConfig, - customerId: string, - secretKey: string): ValidationResult { - this.validateCancelRequestCall = new ValidateCancelRequestCall('validateCancelRequest', targetUrl, cancelConfig, customerId, secretKey); - - if (this.validateCancelRequestrRaiseException) { - return new ValidationResult(null, new KnownUserException("mocked exception")); - } else { - return new ValidationResult(new RequestValidationResult('Cancel', '', '', '', ''), null); - } - }; - - extendQueueCookie( - eventId: string, - cookieValidityMinutes: number, - cookieDomain: string, - secretKey: string): void { - this.extendQueueCookieCall = new ExtendQueueCookieCall('extendQueueCookie', eventId, cookieValidityMinutes, cookieDomain, secretKey); - //return this.extendQueueCookieCalls; - }; - - reset(): void { - //this.validateQueueRequestResult = null; - this.validateQueueRequestResult = new RequestValidationResult("", "", "", "", ""); - this.cancelRequestCalls.clear(); - this.extendQueueCookieCalls.clear(); - this.validateQueueRequestCall = null; - this.validateCancelRequestCall = null; - this.extendQueueCookieCall = null; - this.validateCancelRequestrRaiseException = false; - this.validateQueueRequestResultRaiseException = false; - } -} - -export class UserInQueueStateCookieRepositoryMock extends UserInQueueStateCookieRepository { - returnThisState: StateInfo - storeCall: Map - getStateCall: Map - cancelQueueCookieCall: Map - - constructor() { - super(new MockHttpContextProvider(new MockHttpRequest(), new MockHttpResponse())); - this.returnThisState = new StateInfo(false, false, "", 0, "") - this.storeCall = new Map(); - this.getStateCall = new Map(); - this.cancelQueueCookieCall = new Map(); - } - - getState(eventId: string, cookieValidityMinutes: number, secretKey: string, validateTime: boolean): StateInfo { - this.getStateCall.set("eventId", eventId); - this.getStateCall.set("cookieValidityMinutes", cookieValidityMinutes.toString()); - this.getStateCall.set("secretKey", secretKey); - this.getStateCall.set("validateTime", validateTime.toString()); - return this.returnThisState; - }; - - store(eventId: string, queueId: string, fixedCookieValidityMinutes: number, cookieDomain: string, redirectType: string, secretKey: string): void { - this.storeCall.set("eventId", eventId); - this.storeCall.set("queueId", queueId); - this.storeCall.set("fixedCookieValidityMinutes", fixedCookieValidityMinutes.toString()); - this.storeCall.set("cookieDomain", cookieDomain); - this.storeCall.set("redirectType", redirectType); - this.storeCall.set("secretKey", secretKey); - } - - cancelQueueCookie(eventId: string, cookieDomain: string): void { - this.cancelQueueCookieCall.set("eventId", eventId); - this.cancelQueueCookieCall.set("cookieDomain", cookieDomain); - }; - - reset(): void { - this.getStateCall.clear(); - this.storeCall.clear(); - this.cancelQueueCookieCall.clear(); - } -} diff --git a/src/__tests__/QueueParameterHelper.spec.ts b/src/__tests__/QueueParameterHelper.spec.ts deleted file mode 100644 index 8d80f29..0000000 --- a/src/__tests__/QueueParameterHelper.spec.ts +++ /dev/null @@ -1,59 +0,0 @@ -import {QueueParameterHelper, Utils} from "../sdk/QueueITHelpers"; - -describe('utils', ()=>{ - it('should be able to encode WR IDs', ()=>{ - const encodedURL = Utils.encodeUrl('e1'); - - expect(encodedURL).toBe('e1'); - }) -}) - -describe("parameter helper", () => { - it('can extract queue params', () => { - const queueitToken = 'ts_1480593661~cv_10~ce_false~q_944c1f44-60dd-4e37-aabc-f3e4bb1c8895~c_customerid~e_eventid~rt_disabled~h_218b734e-d5be-4b60-ad66-9b1b326266e2'; - let result = QueueParameterHelper.extractQueueParams(queueitToken); - - expect(result).not.toBeNull(); - expect(result!.timeStamp).toBe(1480593661) - expect(result!.eventId).toBe("eventid"); - expect(result!.cookieValidityMinutes).toBe(10); - expect(result!.extendableCookie).toBeFalsy(); - expect(result!.hashCode).toBe('218b734e-d5be-4b60-ad66-9b1b326266e2'); - expect(result!.queueITToken).toBe(queueitToken); - expect(result!.queueITTokenWithoutHash).toBe('ts_1480593661~cv_10~ce_false~q_944c1f44-60dd-4e37-aabc-f3e4bb1c8895~c_customerid~e_eventid~rt_disabled'); - }); - - it('can handle non-valid formats', () => { - const queueITToken = 'ts_sasa~cv_adsasa~ce_falwwwse~q_944c1f44-60dd-4e37-aabc-f3e4bb1c8895~h_218b734e-d5be-4b60-ad66-9b1b326266e2'; - const queueitTokenWithoutHash = 'ts_sasa~cv_adsasa~ce_falwwwse~q_944c1f44-60dd-4e37-aabc-f3e4bb1c8895'; - const result = QueueParameterHelper.extractQueueParams(queueITToken); - - expect(result!.timeStamp).toBe(0); - expect(result!.eventId).toBeFalsy(); - expect(result!.cookieValidityMinutes).toBe(0); - expect(result!.extendableCookie).toBeFalsy(); - expect(result!.hashCode).toBe('218b734e-d5be-4b60-ad66-9b1b326266e2'); - expect(result!.queueITToken).toBe(queueITToken); - expect(result!.queueITTokenWithoutHash).toBe(queueitTokenWithoutHash); - }); - - it('can use queueittoken with no values', ()=>{ - const queueITToken = "e~q~ts~ce~rt~h"; - const result = QueueParameterHelper.extractQueueParams(queueITToken); - - expect(result!.timeStamp).toBe(0); - expect(result!.eventId).toBeFalsy(); - expect(result!.cookieValidityMinutes).toBe(0); - expect(result!.extendableCookie).toBeFalsy(); - expect(result!.hashCode).toBeFalsy(); - expect(result!.queueITToken).toBe(queueITToken); - expect(result!.queueITTokenWithoutHash).toBe(queueITToken); - }); - - it('returns null when no queueittoken is given', ()=>{ - const queueITToken = ""; - const result = QueueParameterHelper.extractQueueParams(queueITToken); - - expect(result).toBeNull(); - }); -}); diff --git a/src/__tests__/UserInQueueService.spec.ts b/src/__tests__/UserInQueueService.spec.ts deleted file mode 100644 index 0a2077d..0000000 --- a/src/__tests__/UserInQueueService.spec.ts +++ /dev/null @@ -1,415 +0,0 @@ -import {Utils} from "../sdk/QueueITHelpers"; -import {UserInQueueService} from "../sdk/UserInQueueService"; -import {StateInfo} from "../sdk/UserInQueueStateCookieRepository"; -import {CancelEventConfig, QueueEventConfig} from "../sdk/Models"; -import {UserInQueueStateCookieRepositoryMock} from "./Mocks"; -import {hashString, hmacString} from '../sdk/helpers/crypto' - -const SDK_VERSION = UserInQueueService.SDK_VERSION; - - -function generateHash(eventId: string, - queueId: string, - timestamp: number, - extendableCookie: string, - cookieValidityMinutes: number, - redirectType: string, - secretKey: string): string { - let token = 'e_' + eventId + '~ts_' + timestamp.toString() + '~ce_' + extendableCookie + '~q_' + queueId; - if (cookieValidityMinutes != 0) - token = token + '~cv_' + cookieValidityMinutes.toString(); - if (redirectType != null) - token = token + '~rt_' + redirectType; - return token + '~h_' + Utils.generateSHA256Hash(secretKey, token); -} - -const userInQueueStateCookieRepositoryMock = new UserInQueueStateCookieRepositoryMock(); -const userInQueueService = new UserInQueueService(userInQueueStateCookieRepositoryMock); -Utils.generateSHA256Hash = hmacString; - -function newConfig(): QueueEventConfig { - return new QueueEventConfig("", "", "", "", false, 0, "", 13); -} - -describe('Crypto', () => { - it('should use hmac-sha256', () => { - let hash = hmacString('4e1db821-a825-49da-acd0-5d376f2068db', 'e_e1~ts_1620389879~ce_True~q_queueId~rt_idle'); - let hash2 = hmacString('4e1db821-a825-49da-acd0-5d376f2068db', 'e_e1~ts_1620389879~ce_True~q_queueId~rt_idle'); - expect(hash).toBe("c76001c94ec53a3d46c0c9b5939914d1f0f834cdf14acdc224450a0fe9810fe6"); - expect(hash2).toBe("c76001c94ec53a3d46c0c9b5939914d1f0f834cdf14acdc224450a0fe9810fe6"); - }) - - it('should use sha256', () => { - let r = hashString('asdasdasd'); - expect(r).toBe('d8a928b2043db77e340b523547bf16cb4aa483f0645fe0a290ed1f20aab76257'); - }) -}); - -describe("UserInQueueService.validateQueueRequest", () => { - - it('ValidState_ExtendableCookie_NoCookieExtensionFromConfig_DoNotRedirectDoNotStoreCookieWithExtension', () => { - userInQueueStateCookieRepositoryMock.reset(); - userInQueueStateCookieRepositoryMock.returnThisState = new StateInfo(true, true, "queueId", 0, "idle"); - - const eventConfig = new QueueEventConfig("", "", "", "", false, 0, "", 13, ""); - eventConfig.eventId = "e1"; - eventConfig.queueDomain = "testDomain"; - eventConfig.cookieDomain = "testDomain"; - eventConfig.cookieValidityMinute = 10; - eventConfig.extendCookieValidity = false; - - const result = userInQueueService.validateQueueRequest("url", "token", eventConfig, "customerid", "key"); - expect(result.first!.doRedirect()).toBeFalsy(); - expect(result.first!.queueId).toBe('queueId'); - - expect(userInQueueStateCookieRepositoryMock.storeCall.size).toBe(0); - expect(userInQueueStateCookieRepositoryMock.getStateCall.get("eventId")).toBe("e1"); - expect(userInQueueStateCookieRepositoryMock.getStateCall.get("cookieValidityMinutes")).toBe("10"); - expect(userInQueueStateCookieRepositoryMock.getStateCall.get("secretKey")).toBe("key"); - expect(userInQueueStateCookieRepositoryMock.getStateCall.get("validateTime")).toBe("true"); - }); - - it('ValidState_ExtendableCookie_CookieExtensionFromConfig_DoNotRedirectDoStoreCookieWithExtension', () => { - userInQueueStateCookieRepositoryMock.reset(); - userInQueueStateCookieRepositoryMock.returnThisState = new StateInfo(true, true, "queueId", 0, "disabled"); - - const eventConfig = newConfig(); - eventConfig.eventId = "e1"; - eventConfig.queueDomain = "testDomain.com"; - eventConfig.cookieDomain = "testDomain"; - eventConfig.cookieValidityMinute = 10; - eventConfig.extendCookieValidity = true; - - const result = userInQueueService.validateQueueRequest("url", "token", eventConfig, "customerid", "key"); - - expect(result.first!.doRedirect()).toBeFalsy(); - expect(result.first!.eventId).toBe('e1'); - expect(result.first!.queueId).toBe("queueId"); - - expect(userInQueueStateCookieRepositoryMock.storeCall.get("eventId")).toBe("e1"); - expect(userInQueueStateCookieRepositoryMock.storeCall.get("queueId")).toBe("queueId"); - expect(userInQueueStateCookieRepositoryMock.storeCall.get("fixedCookieValidityMinutes")).toBe("0"); - expect(userInQueueStateCookieRepositoryMock.storeCall.get("cookieDomain")).toBe("testDomain"); - expect(userInQueueStateCookieRepositoryMock.storeCall.get("redirectType")).toBe("disabled"); - expect(userInQueueStateCookieRepositoryMock.storeCall.get("secretKey")).toBe("key"); - }); - - it('ValidState_NoExtendableCookie_DoNotRedirectDoNotStoreCookieWithExtension', () => { - userInQueueStateCookieRepositoryMock.reset(); - userInQueueStateCookieRepositoryMock.returnThisState = new StateInfo(true, true, "queueId", 3, "idle"); - - const eventConfig = newConfig(); - eventConfig.eventId = "e1"; - eventConfig.queueDomain = "testDomain"; - eventConfig.cookieValidityMinute = 10; - eventConfig.extendCookieValidity = true; - - const result = userInQueueService.validateQueueRequest("url", "token", eventConfig, "customerid", "key"); - - expect(result.first!.doRedirect()).toBeFalsy(); - expect(result.first!.eventId).toBe('e1'); - expect(result.first!.queueId).toBe("queueId"); - expect(userInQueueStateCookieRepositoryMock.storeCall.size).toBe(0); - }); - - it('NoCookie_TampredToken_RedirectToErrorPageWithHashError_DoNotStoreCookie', () => { - userInQueueStateCookieRepositoryMock.reset(); - userInQueueStateCookieRepositoryMock.returnThisState = new StateInfo(false, false, "", 0, ""); - - const key = "4e1db821-a825-49da-acd0-5d376f2068db"; - const eventConfig = newConfig(); - eventConfig.eventId = "e1"; - eventConfig.queueDomain = "testDomain.com"; - eventConfig.cookieValidityMinute = 10; - eventConfig.extendCookieValidity = true; - eventConfig.version = 11; - eventConfig.actionName = "Queue Action (._~-) &!*|'\""; - const url = "http://test.test.com?b=h"; - - let token = generateHash('e1', 'queueId', Utils.getCurrentTime() + 3 * 60, 'False', 0, 'idle', key); - token = token.replace("False", "True"); - - const expectedErrorUrl = "https://testDomain.com/error/hash/?c=testCustomer&e=e1" + - "&ver=" + SDK_VERSION - + "&cver=11" - + "&man=Queue%20Action%20%28._~-%29%20%26%21%2a%7C%27%22" - + "&queueittoken=" + token - + "&t=" + Utils.encodeUrl(url); - - const result = userInQueueService.validateQueueRequest(url, token, eventConfig, "testCustomer", key); - const tsPartRx = new RegExp('&ts=[^&]*', 'g') - expect(userInQueueStateCookieRepositoryMock.storeCall.size).toBe(0); - expect(result.first!.doRedirect()).toBeTruthy(); - expect(result.first!.eventId).toBe('e1'); - - const tsMatch = tsPartRx.exec(result.first!.redirectUrl); - expect(tsMatch).not.toBeNull() - - const tsPart = tsMatch![0]; - const timestamp = parseInt(tsPart.replace("&ts=", ""), 10); - const urlWithoutTimeStamp = result.first!.redirectUrl.replace(tsPart, ""); - expect((Utils.getCurrentTime() - timestamp) < 100).toBe(true); - expect(urlWithoutTimeStamp).toBe(expectedErrorUrl); - }); - - it('NoCookie_ValidToken_ExtendableCookie_DoNotRedirect_StoreExtendableCookie', () => { - userInQueueStateCookieRepositoryMock.reset(); - userInQueueStateCookieRepositoryMock.returnThisState = new StateInfo(false, false, '', 0, ''); - - const key = "4e1db821-a825-49da-acd0-5d376f2068db"; - const eventConfig = newConfig(); - eventConfig.eventId = "e1"; - eventConfig.queueDomain = "testDomain.com"; - eventConfig.cookieValidityMinute = 10; - eventConfig.cookieDomain = "testDomain"; - eventConfig.extendCookieValidity = true; - eventConfig.version = 11; - const url = "http://test.test.com?b=h"; - - const token = generateHash('e1', 'queueId', Utils.getCurrentTime() + 3 * 60, 'true', 0, 'queue', key); - - const result = userInQueueService.validateQueueRequest(url, token, eventConfig, "testCustomer", key); - - expect(result.first!.doRedirect()).toBeFalsy(); - expect(result.first!.eventId).toBe('e1'); - expect(result.first!.queueId).toBe('queueId'); - expect(result.first!.redirectType).toBe('queue'); - - expect(userInQueueStateCookieRepositoryMock.storeCall.get('eventId')).toBe('e1'); - expect(userInQueueStateCookieRepositoryMock.storeCall.get('queueId')).toBe('queueId'); - expect(userInQueueStateCookieRepositoryMock.storeCall.get('fixedCookieValidityMinutes')).toBe('0'); - expect(userInQueueStateCookieRepositoryMock.storeCall.get('cookieDomain')).toBe('testDomain'); - expect(userInQueueStateCookieRepositoryMock.storeCall.get('redirectType')).toBe('queue'); - expect(userInQueueStateCookieRepositoryMock.storeCall.get('secretKey')).toBe(key); - expect(userInQueueStateCookieRepositoryMock.cancelQueueCookieCall.size).toBe(0); - }); - - it('NoCookie_ValidToken_CookieValidityMinuteFromToken_DoNotRedirect_StoreNonExtendableCookie', () => { - userInQueueStateCookieRepositoryMock.reset(); - userInQueueStateCookieRepositoryMock.returnThisState = new StateInfo(false, false, '', 0, ''); - - const key = "4e1db821-a825-49da-acd0-5d376f2068db"; - const eventConfig = newConfig(); - eventConfig.eventId = "e1"; - eventConfig.queueDomain = "testDomain.com"; - eventConfig.cookieValidityMinute = 30; - eventConfig.cookieDomain = "testDomain"; - eventConfig.extendCookieValidity = true; - const url = "http://test.test.com?b=h"; - - const token = generateHash('e1', 'queueId', Utils.getCurrentTime() + 3 * 60, 'false', 3, 'DirectLink', key); - const result = userInQueueService.validateQueueRequest(url, token, eventConfig, "testCustomer", key); - - expect(result.first!.doRedirect()).toBeFalsy(); - expect(result.first!.eventId).toBe('e1'); - expect(result.first!.queueId).toBe('queueId'); - expect(result.first!.redirectType).toBe('DirectLink'); - - expect(userInQueueStateCookieRepositoryMock.storeCall.get('eventId')).toBe('e1'); - expect(userInQueueStateCookieRepositoryMock.storeCall.get('queueId')).toBe('queueId'); - expect(userInQueueStateCookieRepositoryMock.storeCall.get('fixedCookieValidityMinutes')).toBe('3'); - expect(userInQueueStateCookieRepositoryMock.storeCall.get('cookieDomain')).toBe('testDomain'); - expect(userInQueueStateCookieRepositoryMock.storeCall.get('redirectType')).toBe('DirectLink'); - expect(userInQueueStateCookieRepositoryMock.storeCall.get('secretKey')).toBe(key); - expect(userInQueueStateCookieRepositoryMock.cancelQueueCookieCall.size).toBe(0); - }); - - it('NoCookie_NoValidToken_WithoutToken_RedirectToQueue', () => { - userInQueueStateCookieRepositoryMock.reset(); - userInQueueStateCookieRepositoryMock.returnThisState = new StateInfo(false, false, '', 0, ''); - - const key = "4e1db821-a825-49da-acd0-5d376f2068db"; - const eventConfig = newConfig(); - eventConfig.eventId = "e1"; - eventConfig.queueDomain = "testDomain.com"; - eventConfig.cookieValidityMinute = 10; - eventConfig.extendCookieValidity = true; - eventConfig.version = 11; - eventConfig.culture = 'en-US'; - eventConfig.layoutName = 'testlayout'; - - const url = "http://test.test.com?b=h"; - const token = ''; - - const expectedRedirectUrl = 'https://testDomain.com/?c=testCustomer&e=e1' + - "&ver=" + SDK_VERSION - + "&cver=11" - + "&man=unspecified" - + "&cid=en-US" - + "&l=testlayout" - + "&t=" + Utils.encodeUrl(url); - - const result = userInQueueService.validateQueueRequest(url, token, eventConfig, "testCustomer", key); - - expect(userInQueueStateCookieRepositoryMock.storeCall.size).toBe(0); - expect(result.first!.doRedirect()).toBeTruthy(); - expect(result.first!.eventId).toBe('e1'); - expect(result.first!.queueId).toBe(''); - expect(result.first!.redirectUrl).toBe(expectedRedirectUrl); - }); - - it('InValidCookie_WithoutToken_RedirectToQueue_CancelCookie', () => { - userInQueueStateCookieRepositoryMock.reset(); - userInQueueStateCookieRepositoryMock.returnThisState = new StateInfo(true, false, '', 0, ''); - - const key = "4e1db821-a825-49da-acd0-5d376f2068db"; - const eventConfig = newConfig(); - eventConfig.eventId = "e1"; - eventConfig.queueDomain = "testDomain.com"; - eventConfig.cookieValidityMinute = 10; - eventConfig.extendCookieValidity = true; - eventConfig.version = 11; - eventConfig.culture = 'en-US'; - eventConfig.layoutName = 'testlayout'; - - const url = "http://test.test.com?b=h"; - const token = ""; - - const expectedRedirectUrl = "https://testDomain.com/?c=testCustomer&e=e1" + - "&ver=" + SDK_VERSION - + "&cver=11" - + "&man=unspecified" - + "&cid=en-US" - + "&l=testlayout" - + "&t=" + Utils.encodeUrl(url); - - const result = userInQueueService.validateQueueRequest(url, token, eventConfig, "testCustomer", key); - - expect(userInQueueStateCookieRepositoryMock.storeCall.size).toBe(0); - expect(result.first!.doRedirect()).toBeTruthy(); - expect(result.first!.eventId).toBe('e1'); - expect(result.first!.queueId).toBe(''); - expect(result.first!.redirectUrl).toBe(expectedRedirectUrl); - expect(userInQueueStateCookieRepositoryMock.cancelQueueCookieCall).toBeTruthy(); - }); - - it('NoCookie_WithoutToken_RedirectToQueue_NotargetUrl', () => { - userInQueueStateCookieRepositoryMock.reset(); - userInQueueStateCookieRepositoryMock.returnThisState = new StateInfo(false, false, '', 0, ''); - - const key = "4e1db821-a825-49da-acd0-5d376f2068db"; - const eventConfig = newConfig(); - eventConfig.eventId = "e1"; - eventConfig.queueDomain = "testDomain.com"; - eventConfig.cookieValidityMinute = 10; - eventConfig.extendCookieValidity = false; - eventConfig.version = 11; - eventConfig.culture = ''; - eventConfig.layoutName = 'testlayout'; - const url = "http://test.test.com?b=h"; - const token = ""; - - const expectedRedirectUrl = "https://testDomain.com/?c=testCustomer&e=e1" + - "&ver=" + SDK_VERSION - + "&cver=" + eventConfig.version.toString() - + "&man=" + 'unspecified' - + "&l=" + eventConfig.layoutName; - - const result = userInQueueService.validateQueueRequest('', token, eventConfig, "testCustomer", key); - - expect(userInQueueStateCookieRepositoryMock.storeCall.size).toBe(0); - expect(result.first!.doRedirect()).toBeTruthy(); - expect(result.first!.eventId).toBe('e1'); - expect(result.first!.queueId).toBe(''); - expect(result.first!.redirectUrl).toBe(expectedRedirectUrl); - }); - - it('NoCookie_InValidToken', () => { - userInQueueStateCookieRepositoryMock.reset(); - userInQueueStateCookieRepositoryMock.returnThisState = new StateInfo(false, false, '', 0, ''); - - const key = "4e1db821-a825-49da-acd0-5d376f2068db"; - const eventConfig = newConfig(); - eventConfig.eventId = "e1"; - eventConfig.queueDomain = "testDomain.com"; - eventConfig.cookieValidityMinute = 10; - eventConfig.extendCookieValidity = true; - eventConfig.version = 11; - eventConfig.culture = 'en-US'; - eventConfig.layoutName = 'testlayout'; - const url = "http://test.test.com?b=h"; - - const result = userInQueueService.validateQueueRequest(url, "ts_sasa~cv_adsasa~ce_falwwwse~q_944c1f44-60dd-4e37-aabc-f3e4bb1c8895", eventConfig, "testCustomer", key); - - expect(userInQueueStateCookieRepositoryMock.storeCall.size).toBe(0); - expect(result.first!.doRedirect()).toBeTruthy(); - expect(result.first!.eventId).toBe('e1'); - expect(result.first!.queueId).toBe(''); - expect(result.first!.redirectUrl.indexOf("https://testDomain.com/error/hash/?c=testCustomer&e=e1")).toBe(0); - - expect(userInQueueStateCookieRepositoryMock.cancelQueueCookieCall.size).toBe(0); - }); - - it('InvalidCookie_InValidToken_CancelCookie', () => { - userInQueueStateCookieRepositoryMock.reset(); - userInQueueStateCookieRepositoryMock.returnThisState = new StateInfo(true, false, '', 0, ''); - - const key = "4e1db821-a825-49da-acd0-5d376f2068db"; - const eventConfig = newConfig(); - eventConfig.eventId = 'e1'; - eventConfig.queueDomain = "testDomain.com"; - eventConfig.cookieValidityMinute = 10; - eventConfig.extendCookieValidity = true; - eventConfig.version = 11; - eventConfig.culture = 'en-US'; - eventConfig.layoutName = 'testlayout'; - - const url = "http://test.test.com?b=h"; - - const resultPair = userInQueueService.validateQueueRequest(url, "ts_sasa~cv_adsasa~ce_falwwwse~q_944c1f44-60dd-4e37-aabc-f3e4bb1c8895", eventConfig, "testCustomer", key); - const result = resultPair.first; - - expect(userInQueueStateCookieRepositoryMock.storeCall.size).toBe(0); - expect(result!.doRedirect()).toBeTruthy(); - expect(result!.eventId).toBe('e1'); - expect(result!.queueId).toBe(''); - expect(result!.redirectUrl.indexOf("https://testDomain.com/error/hash/?c=testCustomer&e=e1")).toBe(0); - - expect(userInQueueStateCookieRepositoryMock.cancelQueueCookieCall.size > 0).toBeTruthy(); - }); - - it('validateCancelRequest', () => { - userInQueueStateCookieRepositoryMock.reset(); - userInQueueStateCookieRepositoryMock.returnThisState = new StateInfo(true, true, "queueid", 3, "idle"); - - const key = "4e1db821-a825-49da-acd0-5d376f2068db"; - const eventConfig = new CancelEventConfig('', '', '', 0); - eventConfig.eventId = "e1"; - eventConfig.queueDomain = "testDomain.com"; - eventConfig.cookieDomain = "testdomain"; - eventConfig.version = 10; - eventConfig.actionName = "Cancel"; - - const url = "http://test.test.com?b=h"; - let expectedUrl = "https://testDomain.com/cancel/testCustomer/e1/?c=testCustomer&e=e1" - + "&ver=" + SDK_VERSION - + "&cver=" + eventConfig.version.toString() - + "&man=" + eventConfig.actionName - + "&r=" + "http%3A%2F%2Ftest.test.com%3Fb%3Dh"; - - const result = userInQueueService.validateCancelRequest(url, eventConfig, "testCustomer", key); - - expect(userInQueueStateCookieRepositoryMock.cancelQueueCookieCall.size).not.toBe(0); - expect(userInQueueStateCookieRepositoryMock.storeCall.size).toBe(0); - expect(result.first!.redirectUrl).toBe(expectedUrl); - expect(result.first!.doRedirect()).toBeTruthy(); - expect(result.first!.eventId).toBe('e1'); - expect(result.first!.queueId).toBe('queueid'); - expect(result.first!.actionName).toBe('Cancel'); - }); - -}); - -describe('getIgnoreResult', () => { - it('should not redirect with empty request', () => { - userInQueueStateCookieRepositoryMock.reset(); - - const result = userInQueueService.getIgnoreResult(""); - - expect(result.doRedirect()).toBeFalsy(); - expect(result.eventId).toBe(""); - expect(result.queueId).toBe(""); - expect(result.redirectUrl).toBe(""); - expect(result.actionType).toBe("Ignore"); - }); -}); diff --git a/src/__tests__/UserInQueueStateCookieRepository.spec.ts b/src/__tests__/UserInQueueStateCookieRepository.spec.ts deleted file mode 100644 index 0ea770a..0000000 --- a/src/__tests__/UserInQueueStateCookieRepository.spec.ts +++ /dev/null @@ -1,337 +0,0 @@ -import {Utils} from "../sdk/QueueITHelpers"; -import {hmacString} from "../sdk/helpers/crypto"; -import { - MockHttpContextProvider, - MockHttpRequest, - MockHttpResponse -} from "./Mocks"; -import {UserInQueueStateCookieRepository} from "../sdk/UserInQueueStateCookieRepository"; - -Utils.generateSHA256Hash = hmacString; - - -function generateHash(eventId: string, queueId: string, fixedCookieValidityMinutes: string, redirectType: string, issueTime: string, secretKey: string): string { - return Utils.generateSHA256Hash(secretKey, eventId + queueId + fixedCookieValidityMinutes + redirectType + issueTime); -} - -const httpContextProvider = new MockHttpContextProvider(new MockHttpRequest(), new MockHttpResponse()); -const userInQueueStateCookieRepository = new UserInQueueStateCookieRepository(httpContextProvider); - -function resetMocks(): void { - httpContextProvider.reset(); -} - -describe('userInQueueStateCookieRepository', () => { - it('should store_hasValidState_ExtendableCookie_CookieIsSaved', () => { - resetMocks(); - const eventId = "event1"; - const secretKey = "4e1deweb821-a82ew5-49da-acdqq0-5d3476f2068db"; - const cookieDomain = ".test.com"; - const queueId = "queueId"; - const cookieValidity = 10; - - userInQueueStateCookieRepository.store(eventId, queueId, 0, cookieDomain, "queue", secretKey); - httpContextProvider.req.setCookie('QueueITAccepted-SDFrts345E-V3_event1', httpContextProvider.res.cookies.get('QueueITAccepted-SDFrts345E-V3_event1')!); - const state = userInQueueStateCookieRepository.getState(eventId, cookieValidity, secretKey, true); - - expect(state.isValid).toBeTruthy(); - expect(state.queueId).toBe(queueId); - expect(state.isStateExtendable()).toBeTruthy(); - expect(state.redirectType).toBe('queue'); - - const cookieKey = UserInQueueStateCookieRepository.getCookieKey(eventId); - - let cookie = httpContextProvider.res.cookies.get(cookieKey)!; - let timeDiff = cookie.expiration - Utils.getCurrentTime() - (24 * 60 * 60); - expect(cookie).not.toBeNull(); - expect(timeDiff < 1000).toBeTruthy(); - expect(cookie.domain).toBe(cookieDomain); - }); - - it('should store_hasValidState_nonExtendableCookie_CookieIsSaved', () => { - resetMocks(); - const eventId = "event1"; - const secretKey = "4e1deweb821-a82ew5-49da-acdqq0-5d3476f2068db"; - const cookieDomain = ".test.com"; - const queueId = "queueId"; - const cookieValidity = 3; - - userInQueueStateCookieRepository.store(eventId, queueId, cookieValidity, cookieDomain, "idle", secretKey); - httpContextProvider.req.setCookie('QueueITAccepted-SDFrts345E-V3_event1', httpContextProvider.res.cookies.get('QueueITAccepted-SDFrts345E-V3_event1')!); - const state = userInQueueStateCookieRepository.getState(eventId, cookieValidity, secretKey, true); - - expect(state.isValid).toBeTruthy(); - expect(state.queueId).toBe(queueId); - expect(state.isStateExtendable()).toBeFalsy(); - expect(state.redirectType).toBe('idle'); - expect(state.fixedCookieValidityMinutes).toBe(3); - - const cookieKey = UserInQueueStateCookieRepository.getCookieKey(eventId); - expect(httpContextProvider.res.cookies.get(cookieKey)).not.toBeNull(); - const timeDiff = httpContextProvider.res.cookies.get(cookieKey)!.expiration - Utils.getCurrentTime() - (24 * 60 * 60); - expect(timeDiff < 100).toBeTruthy(); - expect(httpContextProvider.res.cookies.get(cookieKey)!.domain).toBe(cookieDomain); - }); - - it('should store_hasValidState_tamperedCookie_stateIsNotValid_isCookieExtendable', () => { - resetMocks(); - const eventId = "event1"; - const secretKey = "4e1deweb821-a82ew5-49da-acdqq0-5d3476f2068db"; - const cookieDomain = ".test.com"; - const queueId = "queueId"; - const cookieValidity = 10; - - userInQueueStateCookieRepository.store(eventId, queueId, 3, cookieDomain, "Idle", secretKey); - httpContextProvider.req.setCookie('QueueITAccepted-SDFrts345E-V3_event1', httpContextProvider.res.cookies.get('QueueITAccepted-SDFrts345E-V3_event1')!); - const state = userInQueueStateCookieRepository.getState(eventId, cookieValidity, secretKey, true); - expect(state.isValid).toBeTruthy(); - - const cookieKey = UserInQueueStateCookieRepository.getCookieKey(eventId); - const oldCookieValue = httpContextProvider.res.cookies.get(cookieKey)!.value; - - httpContextProvider.res.cookies.get(cookieKey)!.value = oldCookieValue.replace("FixedValidityMins=3", "FixedValidityMins=10"); - const state2 = userInQueueStateCookieRepository.getState(eventId, cookieValidity, secretKey, true); - expect(state2.isValid).toBeFalsy(); - expect(state.isStateExtendable()).toBeFalsy(); - }); - - it('should store_hasValidState_tamperedCookie_stateIsNotValid_eventId', () => { - resetMocks(); - const eventId = "event1"; - const secretKey = "4e1deweb821-a82ew5-49da-acdqq0-5d3476f2068db"; - const cookieDomain = ".test.com"; - const queueId = "queueId"; - const cookieValidity = 10; - - userInQueueStateCookieRepository.store(eventId, queueId, 3, cookieDomain, "Idle", secretKey); - httpContextProvider.req.setCookie('QueueITAccepted-SDFrts345E-V3_event1', httpContextProvider.res.cookies.get('QueueITAccepted-SDFrts345E-V3_event1')!); - const state = userInQueueStateCookieRepository.getState(eventId, cookieValidity, secretKey, true); - expect(state.isValid).toBeTruthy(); - - const cookieKey = UserInQueueStateCookieRepository.getCookieKey(eventId); - const oldCookieValue = httpContextProvider.res.cookies.get(cookieKey)!.value; - httpContextProvider.res.cookies.get(cookieKey)!.value = oldCookieValue.replace("EventId=event1", "EventId=event2"); - - const state2 = userInQueueStateCookieRepository.getState(eventId, cookieValidity, secretKey, true); - expect(state2.isValid).toBeFalsy(); - expect(state.isStateExtendable()).toBeFalsy(); - }); - - it('should store_hasValidState_expiredCookie_stateIsNotValid', () => { - resetMocks(); - const eventId = "event1"; - const secretKey = "4e1deweb821-a82ew5-49da-acdqq0-5d3476f2068db"; - const cookieDomain = ".test.com"; - const queueId = "queueId"; - const cookieValidity = -1; - - userInQueueStateCookieRepository.store(eventId, queueId, 0, cookieDomain, "idle", secretKey); - httpContextProvider.req.setCookie('QueueITAccepted-SDFrts345E-V3_event1', httpContextProvider.res.cookies.get('QueueITAccepted-SDFrts345E-V3_event1')!); - const state = userInQueueStateCookieRepository.getState(eventId, cookieValidity, secretKey, true); - - expect(state.isValid).toBeFalsy(); - }); - - it('should store_hasValidState_differentEventId_stateIsNotValid', () => { - resetMocks(); - const eventId = "event1"; - const secretKey = "4e1deweb821-a82ew5-49da-acdqq0-5d3476f2068db"; - const cookieDomain = ".test.com"; - const queueId = "queueId"; - const cookieValidity = 10; - - userInQueueStateCookieRepository.store(eventId, queueId, 0, cookieDomain, "Queue", secretKey); - httpContextProvider.req.setCookie('QueueITAccepted-SDFrts345E-V3_event1', httpContextProvider.res.cookies.get('QueueITAccepted-SDFrts345E-V3_event1')!); - const state = userInQueueStateCookieRepository.getState(eventId, cookieValidity, secretKey, true); - expect(state.isValid).toBeTruthy(); - - const state2 = userInQueueStateCookieRepository.getState("event2", cookieValidity, secretKey, true); - expect(state2.isValid).toBeFalsy(); - }); - - it('should hasValidState_noCookie_stateIsNotValid', () => { - resetMocks(); - const eventId = "event1"; - const secretKey = "4e1deweb821-a82ew5-49da-acdqq0-5d3476f2068db"; - const cookieValidity = 10; - - const state = userInQueueStateCookieRepository.getState(eventId, cookieValidity, secretKey, true); - expect(state.isValid).toBeFalsy(); - }); - - it('should hasValidState_invalidCookie_stateIsNotValid', () => { - resetMocks(); - const eventId = "event1"; - const secretKey = "4e1deweb821-a82ew5-49da-acdqq0-5d3476f2068db"; - const cookieDomain = ".test.com"; - const queueId = "queueId"; - const cookieValidity = 10; - - userInQueueStateCookieRepository.store(eventId, queueId, 20, cookieDomain, "Queue", secretKey); - httpContextProvider.req.setCookie('QueueITAccepted-SDFrts345E-V3_event1', httpContextProvider.res.cookies.get('QueueITAccepted-SDFrts345E-V3_event1')!); - const state = userInQueueStateCookieRepository.getState(eventId, cookieValidity, secretKey, true); - expect(state.isValid).toBeTruthy(); - - const cookieKey = UserInQueueStateCookieRepository.getCookieKey(eventId); - httpContextProvider.res.cookies.get(cookieKey)!.value = "IsCookieExtendable=ooOOO&Expires=|||&QueueId=000&Hash=23232"; - const state2 = userInQueueStateCookieRepository.getState(eventId, cookieValidity, secretKey, true); - expect(state2.isValid).toBeFalsy(); - }); - - it('should cancelQueueCookie', () => { - resetMocks(); - const eventId = "event1"; - const secretKey = "4e1deweb821-a82ew5-49da-acdqq0-5d3476f2068db"; - const cookieDomain = ".test.com"; - const queueId = "queueId"; - const cookieValidity = 20; - - userInQueueStateCookieRepository.store(eventId, queueId, 20, cookieDomain, "Queue", secretKey); - httpContextProvider.req.setCookie('QueueITAccepted-SDFrts345E-V3_event1', httpContextProvider.res.cookies.get('QueueITAccepted-SDFrts345E-V3_event1')!); - const state = userInQueueStateCookieRepository.getState(eventId, cookieValidity, secretKey, true); - expect(state.isValid).toBeTruthy(); - - userInQueueStateCookieRepository.cancelQueueCookie(eventId, cookieDomain); - httpContextProvider.req.setCookie('QueueITAccepted-SDFrts345E-V3_event1', httpContextProvider.res.cookies.get('QueueITAccepted-SDFrts345E-V3_event1')!); - const state2 = userInQueueStateCookieRepository.getState(eventId, cookieValidity, secretKey, true); - expect(state2.isValid).toBeFalsy(); - - const cookieKey = UserInQueueStateCookieRepository.getCookieKey(eventId); - expect(httpContextProvider.res.cookies.get(cookieKey)).not.toBeNull(); - expect(httpContextProvider.res.cookies.get(cookieKey)!.expiration).toBe(0); - expect(httpContextProvider.res.cookies.get(cookieKey)!.domain).toBe(cookieDomain); - expect(httpContextProvider.res.cookies.get(cookieKey)!.value).toBe(''); - }); - - it('should extendQueueCookie_cookieExist', () => { - resetMocks(); - const eventId = "event1"; - const secretKey = "4e1deweb821-a82ew5-49da-acdqq0-5d3476f2068db"; - const cookieDomain = ".test.com"; - const queueId = "queueId"; - const cookieKey = UserInQueueStateCookieRepository.getCookieKey(eventId); - - userInQueueStateCookieRepository.store(eventId, queueId, 0, cookieDomain, "Queue", secretKey); - httpContextProvider.req.setCookie('QueueITAccepted-SDFrts345E-V3_event1', httpContextProvider.res.cookies.get('QueueITAccepted-SDFrts345E-V3_event1')!); - userInQueueStateCookieRepository.reissueQueueCookie(eventId, 12, cookieDomain, secretKey); - - const state = userInQueueStateCookieRepository.getState(eventId, 5, secretKey, true); - expect(state.isValid).toBeTruthy(); - expect(state.queueId).toBe(queueId); - expect(state.isStateExtendable()).toBeTruthy(); - expect(httpContextProvider.res.cookies.get(cookieKey)!.expiration - Utils.getCurrentTime() - 24 * 60 * 60 < 100).toBeTruthy(); - expect(httpContextProvider.res.cookies.get(cookieKey)!.domain).toBe(cookieDomain); - }); - - it('should extendQueueCookie_cookieDoesNotExist', () => { - resetMocks(); - const eventId = "event1"; - const secretKey = "4e1deweb821-a82ew5-49da-acdqq0-5d3476f2068db"; - const cookieDomain = ".test.com"; - const queueId = "queueId"; - - userInQueueStateCookieRepository.store("event2", queueId, 20, cookieDomain, "Queue", secretKey); - userInQueueStateCookieRepository.reissueQueueCookie(eventId, 12, cookieDomain, secretKey); - - const cookieKey = UserInQueueStateCookieRepository.getCookieKey("event2"); - expect(httpContextProvider.res.cookies.has(cookieKey)).toBeTruthy() - expect(httpContextProvider.res.cookies.get(cookieKey)).not.toBeNull(); - }); - - it('should getState_validCookieFormat_extendable', () => { - resetMocks(); - const eventId = "event1"; - const secretKey = "4e1deweb821-a82ew5-49da-acdqq0-5d3476f2068db"; - const cookieDomain = ".test.com"; - const queueId = "queueId"; - const issueTime = Utils.getCurrentTime(); - const hash = generateHash(eventId, queueId, '', "queue", issueTime.toString(), secretKey); - - const cookieKey = UserInQueueStateCookieRepository.getCookieKey(eventId); - httpContextProvider.getHttpResponse().setCookie(cookieKey, - "EventId=" + eventId + "&QueueId=" + queueId + "&RedirectType=queue&IssueTime=" + issueTime.toString() + "&Hash=" + hash, - cookieDomain, Utils.getCurrentTime() + (24 * 60 * 60)); - httpContextProvider.req.setCookie(cookieKey, httpContextProvider.res.cookies.get(cookieKey)!); - const state = userInQueueStateCookieRepository.getState(eventId, 10, secretKey, true); - - expect(state.isStateExtendable()).toBeTruthy(); - expect(state.isValid).toBeTruthy(); - expect(state.isFound).toBeTruthy(); - expect(state.queueId).toBe(queueId); - expect(state.redirectType).toBe('queue'); - }); - - it('should getState_oldCookie_invalid_expiredCookie_extendable', () => { - resetMocks(); - const eventId = "event1"; - const secretKey = "4e1deweb821-a82ew5-49da-acdqq0-5d3476f2068db"; - const cookieDomain = ".test.com"; - const queueId = "queueId"; - const cookieKey = UserInQueueStateCookieRepository.getCookieKey(eventId); - const issueTime = Utils.getCurrentTime() - 11 * 60; - const hash = generateHash(eventId, queueId, '', "queue", issueTime.toString(), secretKey); - - httpContextProvider.getHttpResponse().setCookie(cookieKey, - "EventId=" + eventId + "&QueueId=" + queueId + "&RedirectType=queue&IssueTime=" + issueTime.toString() + "&Hash=" + hash, - cookieDomain, Utils.getCurrentTime() + 24 * 60 * 60); - httpContextProvider.req.setCookie(cookieKey, httpContextProvider.res.cookies.get(cookieKey)!); - const state = userInQueueStateCookieRepository.getState(eventId, 10, secretKey, true); - - expect(state.isValid).toBeFalsy(); - expect(state.isFound).toBeTruthy(); - }); - - it('should getState_oldCookie_invalid_expiredCookie_nonExtendable', () => { - resetMocks(); - const eventId = "event1"; - const secretKey = "4e1deweb821-a82ew5-49da-acdqq0-5d3476f2068db"; - const cookieDomain = ".test.com"; - const queueId = "queueId"; - const issueTime = Utils.getCurrentTime() - 4 * 60; - const hash = generateHash(eventId, queueId, '3', "idle", issueTime.toString(), secretKey); - - const cookieKey = UserInQueueStateCookieRepository.getCookieKey(eventId); - httpContextProvider.getHttpResponse().setCookie(cookieKey, - "EventId=" + eventId + "&QueueId=" + queueId + "&FixedValidityMins=3&RedirectType=idle&IssueTime=" + issueTime.toString() + "&Hash=" + hash, - cookieDomain, Utils.getCurrentTime() + (24 * 60 * 60)); - httpContextProvider.req.setCookie(cookieKey, httpContextProvider.res.cookies.get(cookieKey)!); - const state = userInQueueStateCookieRepository.getState(eventId, 10, secretKey, true); - - expect(state.isValid).toBeFalsy(); - expect(state.isFound).toBeTruthy(); - }); - - it('should getState_validCookieFormat_nonExtendable', () => { - resetMocks(); - const eventId = "event1"; - const secretKey = "4e1deweb821-a82ew5-49da-acdqq0-5d3476f2068db"; - const cookieDomain = ".test.com"; - const queueId = "queueId"; - const issueTime = Utils.getCurrentTime(); - const hash = generateHash(eventId, queueId, '3', "idle", issueTime.toString(), secretKey); - - const cookieKey = UserInQueueStateCookieRepository.getCookieKey(eventId); - httpContextProvider.getHttpResponse() - .setCookie(cookieKey, "EventId=" + eventId + "&QueueId=" + queueId + "&FixedValidityMins=3&RedirectType=idle&IssueTime=" + issueTime.toString() + "&Hash=" + hash, - cookieDomain, Utils.getCurrentTime() + (24 * 60 * 60)); - httpContextProvider.req.setCookie(cookieKey, httpContextProvider.res.cookies.get(cookieKey)!); - const state = userInQueueStateCookieRepository.getState(eventId, 10, secretKey, true); - - expect(state.isStateExtendable()).toBeFalsy(); - expect(state.isValid).toBeTruthy(); - expect(state.isFound).toBeTruthy(); - expect(state.queueId).toBe(queueId); - expect(state.redirectType).toBe('idle'); - }); - - it('should getState_NoCookie', () => { - resetMocks(); - const eventId = "event1"; - const secretKey = "4e1deweb821-a82ew5-49da-acdqq0-5d3476f2068db"; - - const state = userInQueueStateCookieRepository.getState(eventId, 10, secretKey, true); - - expect(state.isFound).toBeFalsy(); - expect(state.isValid).toBeFalsy(); - }); -}); diff --git a/src/contextProvider.ts b/src/contextProvider.ts index fcb289a..cf3ba33 100644 --- a/src/contextProvider.ts +++ b/src/contextProvider.ts @@ -1,11 +1,11 @@ -import {IHttpContextProvider, IHttpRequest, IHttpResponse} from "./sdk/HttpContextProvider"; -import {decodeURIComponent, encodeURIComponent} from "./sdk/helpers/Uri"; +import { IConnectorContextProvider, IHttpRequest, IHttpResponse } from '@queue-it/connector-javascript'; +import { FastlyCryptoProvider } from './fastlyCryptoProvider'; export function getHttpHandler(req: Request): FastlyHttpContextProvider { return new FastlyHttpContextProvider(req); } -export class FastlyHttpContextProvider implements IHttpContextProvider { +export class FastlyHttpContextProvider implements IConnectorContextProvider { isError: boolean = false; private readonly req: FastlyHttpRequest; private readonly res: FastlyHttpResponse; @@ -22,6 +22,18 @@ export class FastlyHttpContextProvider implements IHttpContextProvider { getHttpResponse(): IHttpResponse { return this.res; } + + getCryptoProvider(): FastlyCryptoProvider { + return new FastlyCryptoProvider(); + } + + getEnqueueTokenProvider(): null { + return null; + } + + getResponseHeaders(): Headers { + return (this.res as FastlyHttpResponse).getHeaders(); + } } export class FastlyHttpRequest implements IHttpRequest { @@ -49,14 +61,6 @@ export class FastlyHttpRequest implements IHttpRequest { return; } this.bodyFetched = true; - const rawBody: ArrayBuffer | null = null; // this.context.req.arrayBuffer(); - if (rawBody == null) { - return; - } - if (rawBody!.byteLength == 0) { - return; - } - this.body = ''; // this.context.req.text() } @@ -64,11 +68,11 @@ export class FastlyHttpRequest implements IHttpRequest { return this.baseReq.url; } - getCookieValue(cookieKey: string): string { + getCookieValue(cookieKey: string): string | undefined { if (this.parsedCookieDic.size == 0) { this.parseCookies(this.getHeader('cookie')) } - if (!this.parsedCookieDic.has(cookieKey)) return ''; + if (!this.parsedCookieDic.has(cookieKey)) return undefined; const cookieVal = this.parsedCookieDic.get(cookieKey)!; try { return decodeURIComponent(cookieVal); @@ -110,7 +114,7 @@ export class FastlyHttpResponse implements IHttpResponse { this.headers = new Headers(); } - setCookie(cookieName: string, cookieValue: string, domain: string, expiration: number): void { + setCookie(cookieName: string, cookieValue: string, domain: string, expiration: number, _isHttpOnly: boolean, _isSecure: boolean): void { const expirationDate = new Date(expiration * 1000); let setCookieString = cookieName + "=" + encodeURIComponent(cookieValue) + "; expires=" + expirationDate.toUTCString() + ";"; if (domain != "") { diff --git a/src/fastlyCryptoProvider.ts b/src/fastlyCryptoProvider.ts new file mode 100644 index 0000000..1effdcf --- /dev/null +++ b/src/fastlyCryptoProvider.ts @@ -0,0 +1,8 @@ +import { ICryptoProvider } from '@queue-it/connector-javascript'; +import { hmacString } from './helpers/crypto'; + +export class FastlyCryptoProvider implements ICryptoProvider { + getSha256Hash(secretKey: string, plaintext: string): string { + return hmacString(secretKey, plaintext); + } +} diff --git a/src/helper.ts b/src/helper.ts index 48dd1b7..3d3635a 100644 --- a/src/helper.ts +++ b/src/helper.ts @@ -1,18 +1,11 @@ -import { Utils } from "./sdk/QueueITHelpers"; -import { hmacString } from "./sdk/helpers/crypto"; - -export class QueueITHelper { - static readonly KUP_VERSION: string = "fastly-2.0.2"; - - static configureKnownUserHashing(): void { - Utils.generateSHA256Hash = hmacString; - } - - static addKUPlatformVersion(redirectQueueUrl: string): string { - return redirectQueueUrl + "&kupver=" + QueueITHelper.KUP_VERSION; - } -} - -export interface RequestLogger { - log(message: string): void; -} +export class QueueITHelper { + static readonly KUP_VERSION: string = "fastly-2.0.3"; + + static addKUPlatformVersion(redirectQueueUrl: string): string { + return redirectQueueUrl + "&kupver=" + QueueITHelper.KUP_VERSION; + } +} + +export interface RequestLogger { + log(message: string): void; +} diff --git a/src/sdk/helpers/crypto.ts b/src/helpers/crypto.ts similarity index 100% rename from src/sdk/helpers/crypto.ts rename to src/helpers/crypto.ts diff --git a/src/integrationConfigProvider.ts b/src/integrationConfigProvider.ts index b2329d1..052b8ae 100644 --- a/src/integrationConfigProvider.ts +++ b/src/integrationConfigProvider.ts @@ -1,3 +1,4 @@ +import { ConfigStore } from "fastly:config-store"; import { RequestLogger } from "./helper"; export async function getIntegrationConfig( diff --git a/src/requestResponseHandler.ts b/src/requestResponseHandler.ts index 9f9c602..639c220 100644 --- a/src/requestResponseHandler.ts +++ b/src/requestResponseHandler.ts @@ -1,4 +1,4 @@ -import { KnownUser } from "./sdk/KnownUser"; +import { KnownUser } from "@queue-it/connector-javascript"; import { QueueITHelper } from "./helper"; import { FastlyHttpContextProvider, getHttpHandler } from "./contextProvider"; import { @@ -7,7 +7,29 @@ import { IntegrationDetails, QueueItIntegrationEndpointProvider, } from "./integrationConfigProvider"; -import { Utils } from "./sdk/QueueITHelpers"; + +function getParameterByName(url: string, name: string): string { + name = name.replace(/[\[\]]/g, '\\$&'); + const regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'); + const results = regex.exec(url); + if (!results) return ''; + if (!results[2]) return ''; + return results[2].replace(/\+/g, ' '); +} + +function removeQueueItToken(url: string): string { + const pattern = new RegExp("([?&])(" + KnownUser.QueueITTokenKey + "=[^&]*)", 'gi'); + const match = pattern.exec(url); + if (match === null) return url; + url = url.replaceAll(match[0], ''); + return url; +} + +function addNoCacheHeaders(res: Response): void { + res.headers.set('Cache-Control', 'no-cache, no-store, must-revalidate, max-age=0'); + res.headers.set('Pragma', 'no-cache'); + res.headers.set('Expires', 'Fri, 01 Jan 1990 00:00:00 GMT'); +} const QUEUEIT_FAILED_HEADERNAME = "x-queueit-failed"; let httpProvider: FastlyHttpContextProvider | null = null; @@ -30,85 +52,77 @@ export async function onQueueITRequest( conf.provider == null ? new QueueItIntegrationEndpointProvider() : conf.provider; - QueueITHelper.configureKnownUserHashing(); httpProvider = getHttpHandler(req); let integrationConfigJson = await getIntegrationConfig(conf, integrationProvider); const requestUrl: string = conf.resolveWorkerRequestUrl(req.url); - const queueItToken = Utils.getParameterByName( - requestUrl, - KnownUser.QueueITTokenKey - ); - const requestUrlWithoutToken: string = Utils.removeQueueItToken(requestUrl); + const queueItToken = getParameterByName(requestUrl, KnownUser.QueueITTokenKey); + const requestUrlWithoutToken: string = removeQueueItToken(requestUrl); // The requestUrlWithoutToken is used to match Triggers and as the Target url (where to return the users to). // It is therefor important that this is exactly the url of the users browsers. So, if your webserver is // behind e.g. a load balancer that modifies the host name or port, reformat requestUrlWithoutToken before proceeding. - const validationResultPair = KnownUser.validateRequestByIntegrationConfig( - requestUrlWithoutToken, - queueItToken, - integrationConfigJson, - conf.customerId, - conf.secretKey, - httpProvider! - ); - - if ( - validationResultPair.first != null && - validationResultPair.first!.doRedirect() - ) { - const validationResult = validationResultPair.first!; + try { + const validationResult = await KnownUser.validateRequestByIntegrationConfig( + requestUrlWithoutToken, + queueItToken, + integrationConfigJson, + conf.customerId, + conf.secretKey, + httpProvider! + ); - if (validationResult.isAjaxResult) { - let response = new Response(null, { - status: 200, - headers: httpProvider!.getHttpResponse().getHeaders(), - }); - // In case of ajax call send the user to the queue by sending a custom queue-it header and redirecting user to queue from javascript - response.headers.set("Access-Control-Expose-Headers", validationResult.getAjaxQueueRedirectHeaderKey()); - response.headers.set( - validationResult.getAjaxQueueRedirectHeaderKey(), - QueueITHelper.addKUPlatformVersion( - validationResult.getAjaxRedirectUrl() - ) - ); - Utils.addNoCacheHeaders(response); - return response; - } else { - let response = new Response(null, { - status: 302, - headers: httpProvider!.getHttpResponse().getHeaders(), - }); - // Send the user to the queue - either because hash was missing or because is was invalid - response.headers.set( - "Location", - QueueITHelper.addKUPlatformVersion(validationResult.redirectUrl) - ); - Utils.addNoCacheHeaders(response); - return response; - } - } else if (validationResultPair.first != null) { - const validationResult = validationResultPair.first!; - // Request can continue - we remove queueittoken form querystring parameter to avoid sharing of user specific token - // Support mobile scenario adding the condition !validationResult.isAjaxResult - if ( - queueItToken != "" && - !validationResult.isAjaxResult && - validationResult.actionType == "Queue" - ) { - let response = new Response(null, { - status: 302, - headers: httpProvider!.getHttpResponse().getHeaders(), - }); - response.headers.set("Location", requestUrlWithoutToken); - Utils.addNoCacheHeaders(response); - return response; + if (validationResult.doRedirect()) { + if (validationResult.isAjaxResult) { + let response = new Response(null, { + status: 200, + headers: httpProvider!.getResponseHeaders(), + }); + // In case of ajax call send the user to the queue by sending a custom queue-it header and redirecting user to queue from javascript + response.headers.set("Access-Control-Expose-Headers", validationResult.getAjaxQueueRedirectHeaderKey()); + response.headers.set( + validationResult.getAjaxQueueRedirectHeaderKey(), + QueueITHelper.addKUPlatformVersion( + validationResult.getAjaxRedirectUrl() + ) + ); + addNoCacheHeaders(response); + return response; + } else { + let response = new Response(null, { + status: 302, + headers: httpProvider!.getResponseHeaders(), + }); + // Send the user to the queue - either because hash was missing or because is was invalid + response.headers.set( + "Location", + QueueITHelper.addKUPlatformVersion(validationResult.redirectUrl) + ); + addNoCacheHeaders(response); + return response; + } } else { - // lets caller decide the next step, or just serve the request normally - return null; + // Request can continue - we remove queueittoken from querystring parameter to avoid sharing of user specific token + // Support mobile scenario adding the condition !validationResult.isAjaxResult + if ( + queueItToken != "" && + !validationResult.isAjaxResult && + validationResult.actionType == "Queue" + ) { + let response = new Response(null, { + status: 302, + headers: httpProvider!.getResponseHeaders(), + }); + response.headers.set("Location", requestUrlWithoutToken); + addNoCacheHeaders(response); + return response; + } else { + // lets caller decide the next step, or just serve the request normally + return null; + } } - } else if (validationResultPair.second != null) { + } catch { httpProvider!.isError = true; } @@ -117,7 +131,7 @@ export async function onQueueITRequest( //Fill in the Queue-it headers export function onQueueITResponse(res: Response): void { - const contextHeaders = httpProvider!.getHttpResponse().getHeaders(); + const contextHeaders = httpProvider!.getResponseHeaders(); if (httpProvider!.isError) { res.headers.append(QUEUEIT_FAILED_HEADERNAME, "true"); diff --git a/src/sdk/HttpContextProvider.ts b/src/sdk/HttpContextProvider.ts deleted file mode 100644 index 4d31c68..0000000 --- a/src/sdk/HttpContextProvider.ts +++ /dev/null @@ -1,23 +0,0 @@ - -export interface IHttpRequest { - getUserAgent(): string; - getHeader(name: string): string; - getAbsoluteUri(): string; - getUserHostAddress(): string; - getCookieValue(cookieKey: string): string; - getRequestBodyAsString(): string; -} - -export interface IHttpResponse { - setCookie(cookieName: string, cookieValue: string, domain: string, expiration: number): void; - getHeaders(): Headers; -} - -export interface IHttpContextProvider { - getHttpRequest(): IHttpRequest; - getHttpResponse(): IHttpResponse; -} - -export interface IDateTimeProvider { - getCurrentTime(): Date -} diff --git a/src/sdk/IntegrationConfig/CustomerIntegrationDecodingHandler.ts b/src/sdk/IntegrationConfig/CustomerIntegrationDecodingHandler.ts deleted file mode 100644 index dd160f0..0000000 --- a/src/sdk/IntegrationConfig/CustomerIntegrationDecodingHandler.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { - CustomerIntegration, - IntegrationConfigModel, - TriggerModel, - TriggerPart -} from "./IntegrationConfigModel"; - -export class CustomerIntegrationDecodingHandler { - static deserialize(integrationsConfigString: string): CustomerIntegration { - const result = new CustomerIntegration(); - if (!integrationsConfigString) return result; - - const parsed = JSON.parse(integrationsConfigString); - result.Version = parsed.Version ?? 0; - result.Description = parsed.Description ?? ''; - - if (Array.isArray(parsed.Integrations)) { - result.Integrations = parsed.Integrations.map((item: any) => { - const model = new IntegrationConfigModel(); - model.Name = item.Name ?? ''; - model.EventId = item.EventId ?? ''; - model.CookieDomain = item.CookieDomain ?? ''; - model.LayoutName = item.LayoutName ?? ''; - model.Culture = item.Culture ?? ''; - model.ExtendCookieValidity = item.ExtendCookieValidity ?? false; - model.CookieValidityMinute = item.CookieValidityMinute ?? 0; - model.QueueDomain = item.QueueDomain ?? ''; - model.RedirectLogic = item.RedirectLogic ?? ''; - model.ForcedTargetUrl = item.ForcedTargetUrl ?? ''; - model.ActionType = item.ActionType ?? ''; - - model.Triggers = (item.Triggers ?? []).map((trigger: any) => { - const t = new TriggerModel(); - t.LogicalOperator = trigger.LogicalOperator ?? ''; - t.TriggerParts = (trigger.TriggerParts ?? []).map((part: any) => { - const tp = new TriggerPart(); - tp.ValidatorType = part.ValidatorType ?? ''; - tp.Operator = part.Operator ?? ''; - tp.ValueToCompare = part.ValueToCompare ?? ''; - tp.ValuesToCompare = part.ValuesToCompare ?? []; - tp.IsNegative = part.IsNegative ?? false; - tp.IsIgnoreCase = part.IsIgnoreCase ?? false; - tp.UrlPart = part.UrlPart ?? ''; - tp.CookieName = part.CookieName ?? ''; - tp.HttpHeaderName = part.HttpHeaderName ?? ''; - return tp; - }); - return t; - }); - - return model; - }); - } - - return result; - } -} diff --git a/src/sdk/IntegrationConfig/IntegrationConfigHelpers.ts b/src/sdk/IntegrationConfig/IntegrationConfigHelpers.ts deleted file mode 100644 index e91c2fe..0000000 --- a/src/sdk/IntegrationConfig/IntegrationConfigHelpers.ts +++ /dev/null @@ -1,230 +0,0 @@ -import * as IntegrationModels from './IntegrationConfigModel' -import {KnownUserException} from '../Models' -import {IHttpRequest} from '../HttpContextProvider' - -export interface IIntegrationEvaluator { - getMatchedIntegrationConfig( - customerIntegration: IntegrationModels.CustomerIntegration, - currentPageUrl: string, - request: IHttpRequest): IntegrationModels.IntegrationConfigModelResult | null; -} - -export class IntegrationEvaluator implements IIntegrationEvaluator { - public getMatchedIntegrationConfig( - customerIntegration: IntegrationModels.CustomerIntegration, - currentPageUrl: string, - request: IHttpRequest | null): IntegrationModels.IntegrationConfigModelResult | null { - - if (request == null) - return new IntegrationModels.IntegrationConfigModelResult(null, new KnownUserException("request is null")); - - if (customerIntegration == null) - return new IntegrationModels.IntegrationConfigModelResult(null, new KnownUserException("customerIntegration is null")); - - for (let i = 0; i < customerIntegration.Integrations.length; i++) { - let integration = customerIntegration.Integrations[i]; - for (let t = 0; t < integration.Triggers.length; t++) { - let trigger = integration.Triggers[t]; - if (this.evaluateTrigger(trigger, currentPageUrl, request)) { - return new IntegrationModels.IntegrationConfigModelResult(integration, null); - } - } - } - return null; - } - - private evaluateTrigger(trigger: IntegrationModels.TriggerModel, currentPageUrl: string, request: IHttpRequest): boolean { - if (trigger.LogicalOperator == IntegrationModels.LogicalOperatorType.Or) { - for (let i = 0; i < trigger.TriggerParts.length; i++) { - let part = trigger.TriggerParts[i]; - if (this.evaluateTriggerPart(part, currentPageUrl, request)) - return true; - } - return false; - } else { - for (let i = 0; i < trigger.TriggerParts.length; i++) { - let part = trigger.TriggerParts[i]; - let matched = this.evaluateTriggerPart(part, currentPageUrl, request); - if (!matched) - return false; - } - return true; - } - } - - private evaluateTriggerPart(triggerPart: IntegrationModels.TriggerPart, currentPageUrl: string, request: IHttpRequest): boolean { - if (triggerPart.ValidatorType == IntegrationModels.ValidatorType.UrlValidator) { - return UrlValidatorHelper.evaluate(triggerPart, currentPageUrl); - } else if (triggerPart.ValidatorType == IntegrationModels.ValidatorType.CookieValidator) { - return CookieValidatorHelper.evaluate(triggerPart, request); - } else if (triggerPart.ValidatorType == IntegrationModels.ValidatorType.UserAgentValidator) { - return UserAgentValidatorHelper.evaluate(triggerPart, request.getUserAgent()); - } else if (triggerPart.ValidatorType == IntegrationModels.ValidatorType.HttpHeaderValidator) { - return HttpHeaderValidatorHelper.evaluate(triggerPart, request.getHeader(triggerPart.HttpHeaderName)); - } else if (triggerPart.ValidatorType == IntegrationModels.ValidatorType.RequestBodyValidator) { - return RequestBodyValidatorHelper.evaluate(triggerPart, request.getRequestBodyAsString()); - } else { - return false; - } - } -} - -export class UrlValidatorHelper { - public static evaluate(triggerPart: IntegrationModels.TriggerPart, url: string): boolean { - let urlpart = this.getUrlPart(triggerPart, url); - return ComparisonOperatorHelper.evaluate( - triggerPart.Operator, - triggerPart.IsNegative, - triggerPart.IsIgnoreCase, - urlpart, - triggerPart.ValueToCompare, - triggerPart.ValuesToCompare); - } - - private static getUrlPart(triggerPart: IntegrationModels.TriggerPart, url: string): string { - if (triggerPart.UrlPart == IntegrationModels.UrlPartType.PagePath) { - return this.getPathFromUrl(url); - } else if (triggerPart.UrlPart == IntegrationModels.UrlPartType.PageUrl) { - return url; - } else if (triggerPart.UrlPart == IntegrationModels.UrlPartType.HostName) { - return this.getHostNameFromUrl(url); - } else { - return ""; - } - } - - public static getHostNameFromUrl(url: string): string { - let urlx = new URL(url); - return urlx.host; - } - - public static getPathFromUrl(url: string): string { - let urlx = new URL(url); - return urlx.pathname; - } -} - -export class CookieValidatorHelper { - public static evaluate(triggerPart: IntegrationModels.TriggerPart, request: IHttpRequest): boolean { - return ComparisonOperatorHelper.evaluate(triggerPart.Operator, - triggerPart.IsNegative, - triggerPart.IsIgnoreCase, - this.getCookie(triggerPart.CookieName, request), - triggerPart.ValueToCompare, - triggerPart.ValuesToCompare); - } - - private static getCookie(cookieName: string, request: IHttpRequest): string { - return request.getCookieValue(cookieName); - } -} - -export class UserAgentValidatorHelper { - public static evaluate(triggerPart: IntegrationModels.TriggerPart, userAgent: string): boolean { - - return ComparisonOperatorHelper.evaluate(triggerPart.Operator, - triggerPart.IsNegative, - triggerPart.IsIgnoreCase, - userAgent, - triggerPart.ValueToCompare, - triggerPart.ValuesToCompare); - } -} - -export class RequestBodyValidatorHelper { - public static evaluate(triggerPart: IntegrationModels.TriggerPart, bodyString: string): boolean { - - return ComparisonOperatorHelper.evaluate(triggerPart.Operator, - triggerPart.IsNegative, - triggerPart.IsIgnoreCase, - bodyString, - triggerPart.ValueToCompare, - triggerPart.ValuesToCompare); - } -} - -export class HttpHeaderValidatorHelper { - public static evaluate(triggerPart: IntegrationModels.TriggerPart, headerValue: string): boolean { - return ComparisonOperatorHelper.evaluate(triggerPart.Operator, - triggerPart.IsNegative, - triggerPart.IsIgnoreCase, - headerValue, - triggerPart.ValueToCompare, - triggerPart.ValuesToCompare); - } -} - -export class ComparisonOperatorHelper { - public static evaluate(opt: string, - isNegative: boolean, - isIgnoreCase: boolean, - value: string, - valueToCompare: string, - valuesToCompare: Array | null): boolean { - if (valuesToCompare == null) { - valuesToCompare = new Array(); - } - if (opt == IntegrationModels.ComparisonOperatorType.EqualS) { - return ComparisonOperatorHelper.equalS(value, valueToCompare, isNegative, isIgnoreCase); - } else if (opt == IntegrationModels.ComparisonOperatorType.Contains) { - return ComparisonOperatorHelper.contains(value, valueToCompare, isNegative, isIgnoreCase); - } else if (opt == IntegrationModels.ComparisonOperatorType.EqualsAny) { - return ComparisonOperatorHelper.equalsAny(value, valuesToCompare, isNegative, isIgnoreCase); - } else if (opt == IntegrationModels.ComparisonOperatorType.ContainsAny) { - return ComparisonOperatorHelper.containsAny(value, valuesToCompare, isNegative, isIgnoreCase); - } else { - return false; - } - } - - private static contains(value: string, valueToCompare: string, isNegative: boolean, ignoreCase: boolean): boolean { - if (valueToCompare == "*" && value != "") - return true; - - let evaluation = false; - - if (ignoreCase) - evaluation = value.toUpperCase().indexOf(valueToCompare.toUpperCase()) != -1; - else - evaluation = value.indexOf(valueToCompare) != -1; - - if (isNegative) - return !evaluation; - else - return evaluation; - } - - private static equalS(value: string, valueToCompare: string, isNegative: boolean, ignoreCase: boolean): boolean { - let evaluation = false; - - if (ignoreCase) - evaluation = value.toUpperCase() == valueToCompare.toUpperCase(); - else - evaluation = value == valueToCompare; - - if (isNegative) - return !evaluation; - else - return evaluation; - } - - private static equalsAny(value: string, valuesToCompare: Array, isNegative: boolean, isIgnoreCase: boolean): boolean { - for (let i = 0; i < valuesToCompare.length; i++) { - let valueToCompare = valuesToCompare[i]; - if (ComparisonOperatorHelper.equalS(value, valueToCompare, false, isIgnoreCase)) - return !isNegative; - } - - return isNegative; - } - - private static containsAny(value: string, valuesToCompare: Array, isNegative: boolean, isIgnoreCase: boolean): boolean { - for (let i = 0; i < valuesToCompare.length; i++) { - let valueToCompare = valuesToCompare[i]; - if (ComparisonOperatorHelper.contains(value, valueToCompare, false, isIgnoreCase)) - return !isNegative; - } - - return isNegative; - } -} diff --git a/src/sdk/IntegrationConfig/IntegrationConfigModel.ts b/src/sdk/IntegrationConfig/IntegrationConfigModel.ts deleted file mode 100644 index 078ab3a..0000000 --- a/src/sdk/IntegrationConfig/IntegrationConfigModel.ts +++ /dev/null @@ -1,93 +0,0 @@ -import {KnownUserException, Tuple} from "../Models"; - -export class IntegrationConfigModelResult extends Tuple { -} - -export class IntegrationConfigModel { - Name: string = ""; - EventId: string = ""; - CookieDomain: string = ""; - LayoutName: string = ""; - Culture: string = ""; - ExtendCookieValidity: boolean = false; - CookieValidityMinute: number = 0; - QueueDomain: string = ""; - RedirectLogic: string = ""; - ForcedTargetUrl: string = ""; - ActionType: string = ""; - Triggers: Array; - - constructor() { - this.Triggers = new Array(); - } -} - -export class CustomerIntegration { - Integrations: Array; - Version: number; - Description: string; - - constructor() { - this.Integrations = new Array(); - this.Version = 0; - this.Description = ""; - } -} - -export class TriggerPart { - ValidatorType: string = ""; - Operator: string = ""; - ValueToCompare: string = ""; - ValuesToCompare: Array; - IsNegative: boolean = false; - IsIgnoreCase: boolean = false; - UrlPart: string = ""; // UrlValidator - CookieName: string = ""; // CookieValidator - HttpHeaderName: string = ""; // HttpHeaderValidator - - constructor() { - this.ValuesToCompare = new Array(); - } -} - -export class TriggerModel { - constructor() { - this.TriggerParts = new Array(); - this.LogicalOperator = ""; - } - - TriggerParts: Array; - LogicalOperator: string; -} - -export class ValidatorType { - public static readonly UrlValidator: string = "UrlValidator"; - public static readonly CookieValidator: string = "CookieValidator"; - public static readonly UserAgentValidator: string = "UserAgentValidator"; - public static readonly HttpHeaderValidator: string = "HttpHeaderValidator"; - public static readonly RequestBodyValidator: string = "RequestBodyValidator"; -} - -export class UrlPartType { - static readonly HostName: string = "HostName"; - static readonly PagePath: string = "PagePath"; - static readonly PageUrl: string = "PageUrl"; -} - -export class ComparisonOperatorType { - static readonly EqualS: string = "Equals"; - static readonly Contains: string = "Contains"; - static readonly EqualsAny: string = "EqualsAny"; - static readonly ContainsAny: string = "ContainsAny"; -} - -export class LogicalOperatorType { - public static readonly Or: string = "Or"; - public static readonly And: string = "And"; -} - -export class ActionType { - public static readonly IgnoreAction: string = "Ignore"; - public static readonly CancelAction: string = "Cancel"; - public static readonly QueueAction: string = "Queue"; -} diff --git a/src/sdk/KnownUser.ts b/src/sdk/KnownUser.ts deleted file mode 100644 index dcfcb1b..0000000 --- a/src/sdk/KnownUser.ts +++ /dev/null @@ -1,393 +0,0 @@ -import {UserInQueueService} from './UserInQueueService' -import {UserInQueueStateCookieRepository} from './UserInQueueStateCookieRepository' -import {IDateTimeProvider, IHttpContextProvider} from './HttpContextProvider' -import { - CancelEventConfig, - QueueEventConfig, - KnownUserException, - RequestValidationResult, - ActionTypes, - ValidationResult -} from './Models' -import {Utils, ConnectorDiagnostics, DateTimeProvider} from './QueueITHelpers' -import * as IntegrationConfig from './IntegrationConfig/IntegrationConfigModel' -import * as IntegrationConfigHelpers from './IntegrationConfig/IntegrationConfigHelpers' -import {CustomerIntegrationDecodingHandler} from "./IntegrationConfig/CustomerIntegrationDecodingHandler"; - -export class KnownUser { - public static readonly QueueITTokenKey: string = "queueittoken"; - public static readonly QueueITDebugKey: string = "queueitdebug"; - public static readonly QueueITAjaxHeaderKey: string = "x-queueit-ajaxpageurl"; - - static UserInQueueService: UserInQueueService | null = null; - - private static getUserInQueueService( - httpContextProvider: IHttpContextProvider): UserInQueueService { - if (this.UserInQueueService == null) { - return new UserInQueueService(new UserInQueueStateCookieRepository(httpContextProvider)); - } - return this.UserInQueueService!; - } - - private static isQueueAjaxCall( - httpContextProvider: IHttpContextProvider): boolean { - const ajaxHeader = httpContextProvider.getHttpRequest().getHeader(this.QueueITAjaxHeaderKey); - return ajaxHeader != ''; - } - - private static generateTargetUrl( - originalTargetUrl: string, - httpContextProvider: IHttpContextProvider): string { - return !this.isQueueAjaxCall(httpContextProvider) ? - originalTargetUrl : - Utils.decodeUrl(httpContextProvider.getHttpRequest().getHeader(this.QueueITAjaxHeaderKey)); - } - - private static logExtraRequestDetails( - debugEntries: Map, - httpContextProvider: IHttpContextProvider, - dateTimeProvider: IDateTimeProvider): void { - const date = dateTimeProvider.getCurrentTime(); - debugEntries.set("ServerUtcTime", date.toISOString().split('.')[0] + "Z"); - debugEntries.set("RequestIP", httpContextProvider.getHttpRequest().getUserHostAddress()); - debugEntries.set("RequestHttpHeader_Via", httpContextProvider.getHttpRequest().getHeader("Via")); - debugEntries.set("RequestHttpHeader_Forwarded", httpContextProvider.getHttpRequest().getHeader("Forwarded")); - debugEntries.set("RequestHttpHeader_XForwardedFor", httpContextProvider.getHttpRequest().getHeader("X-Forwarded-For")); - debugEntries.set("RequestHttpHeader_XForwardedHost", httpContextProvider.getHttpRequest().getHeader("X-Forwarded-Host")); - debugEntries.set("RequestHttpHeader_XForwardedProto", httpContextProvider.getHttpRequest().getHeader("X-Forwarded-Proto")); - } - - private static setDebugCookie( - debugEntries: Map, - httpContextProvider: IHttpContextProvider): void { - let cookieValue = ""; - for (const key of debugEntries.keys()) { - cookieValue += key + "=" + debugEntries.get(key) + "|"; - } - - if (cookieValue.lastIndexOf("|") == cookieValue.length - 1) { - cookieValue = cookieValue.substring(0, cookieValue.length - 1); - } - - if (cookieValue == "") - return; - - httpContextProvider.getHttpResponse().setCookie( - this.QueueITDebugKey, - cookieValue, - "", - Utils.getCurrentTime() + 20 * 60); // now + 20 mins - } - - private static _resolveQueueRequestByLocalConfig( - targetUrl: string, - queueitToken: string, - queueConfig: QueueEventConfig | null, - customerId: string, - secretKey: string, - httpContextProvider: IHttpContextProvider, - dateTimeProvider: IDateTimeProvider, - debugEntries: Map, - isDebug: boolean): ValidationResult { - - if (isDebug) { - debugEntries.set("SdkVersion", UserInQueueService.SDK_VERSION); - debugEntries.set("TargetUrl", targetUrl); - debugEntries.set("QueueitToken", queueitToken); - debugEntries.set("OriginalUrl", httpContextProvider.getHttpRequest().getAbsoluteUri()); - debugEntries.set("QueueConfig", queueConfig != null ? queueConfig.getString() : "NULL"); - - this.logExtraRequestDetails(debugEntries, httpContextProvider, dateTimeProvider); - } - - if (customerId == "") - return new ValidationResult(null, new KnownUserException("customerId can not be null or empty.")); - if (secretKey == "") - return new ValidationResult(null, new KnownUserException("secretKey can not be null or empty.")); - if (queueConfig == null) - return new ValidationResult(null, new KnownUserException("queueConfig can not be null.")); - if (queueConfig.eventId == "") - return new ValidationResult(null, new KnownUserException("queueConfig.eventId can not be null or empty.")); - if (queueConfig.queueDomain == "") - return new ValidationResult(null, new KnownUserException("queueConfig.queueDomain can not be null or empty.")); - if (queueConfig.cookieValidityMinute <= 0) - return new ValidationResult(null, new KnownUserException("queueConfig.cookieValidityMinute should be integer greater than 0.")); - - const userInQueueService = this.getUserInQueueService(httpContextProvider); - const result = userInQueueService.validateQueueRequest(targetUrl, queueitToken, queueConfig, customerId, secretKey); - if (result != null && result.first != null) { - result.first!.isAjaxResult = this.isQueueAjaxCall(httpContextProvider); - } - - return result; - } - - private static _cancelRequestByLocalConfig( - targetUrl: string, - queueitToken: string, - cancelConfig: CancelEventConfig | null, - customerId: string, - secretKey: string, - httpContextProvider: IHttpContextProvider, - dateTimeProvider: IDateTimeProvider, - debugEntries: Map, - isDebug: boolean): ValidationResult { - - targetUrl = this.generateTargetUrl(targetUrl, httpContextProvider); - - if (isDebug) { - debugEntries.set("SdkVersion", UserInQueueService.SDK_VERSION); - debugEntries.set("TargetUrl", targetUrl); - debugEntries.set("QueueitToken", queueitToken); - debugEntries.set("CancelConfig", cancelConfig != null ? cancelConfig.getString() : "NULL"); - debugEntries.set("OriginalUrl", httpContextProvider.getHttpRequest().getAbsoluteUri()); - - this.logExtraRequestDetails(debugEntries, httpContextProvider, dateTimeProvider); - } - - if (targetUrl == '') - return new ValidationResult(null, new KnownUserException("targetUrl can not be null or empty.")); - if (customerId == '') - return new ValidationResult(null, new KnownUserException("customerId can not be null or empty.")); - if (secretKey == '') - return new ValidationResult(null, new KnownUserException("secretKey can not be null or empty.")); - if (cancelConfig == null) - return new ValidationResult(null, new KnownUserException("cancelConfig can not be null.")); - if (cancelConfig.eventId == '') - return new ValidationResult(null, new KnownUserException("cancelConfig.eventId can not be null or empty.")); - if (cancelConfig.queueDomain == '') - return new ValidationResult(null, new KnownUserException("cancelConfig.queueDomain can not be null or empty.")); - - const userInQueueService = this.getUserInQueueService(httpContextProvider); - const result = userInQueueService.validateCancelRequest(targetUrl, cancelConfig, customerId, secretKey); - if (result.first != null) { - result.first!.isAjaxResult = this.isQueueAjaxCall(httpContextProvider); - } - - return result; - } - - private static handleQueueAction( - currentUrlWithoutQueueITToken: string, queueitToken: string, - customerIntegrationInfo: IntegrationConfig.CustomerIntegration, customerId: string, - secretKey: string, - matchedConfig: IntegrationConfig.IntegrationConfigModel, - httpContextProvider: IHttpContextProvider, - dateTimeProvider: IDateTimeProvider, - debugEntries: Map, - isDebug: boolean): ValidationResult { - let targetUrl: string; - - if (matchedConfig.RedirectLogic == "ForcedTargetUrl") { - targetUrl = matchedConfig.ForcedTargetUrl; - } else if (matchedConfig.RedirectLogic == "EventTargetUrl") { - targetUrl = ""; - } else { - targetUrl = this.generateTargetUrl(currentUrlWithoutQueueITToken, httpContextProvider); - } - - const queueEventConfig = new QueueEventConfig( - matchedConfig.EventId, - matchedConfig.LayoutName, - matchedConfig.Culture, - matchedConfig.QueueDomain, - matchedConfig.ExtendCookieValidity, - matchedConfig.CookieValidityMinute, - matchedConfig.CookieDomain, - customerIntegrationInfo.Version, - matchedConfig.Name - ); - - return this._resolveQueueRequestByLocalConfig(targetUrl, queueitToken, queueEventConfig, customerId, secretKey, httpContextProvider, dateTimeProvider, debugEntries, isDebug); - } - - private static handleCancelAction( - currentUrlWithoutQueueITToken: string, queueitToken: string, - customerIntegrationInfo: IntegrationConfig.CustomerIntegration, customerId: string, - secretKey: string, - matchedConfig: IntegrationConfig.IntegrationConfigModel, - httpContextProvider: IHttpContextProvider, - dateTimeProvider: IDateTimeProvider, - debugEntries: Map, - isDebug: boolean): ValidationResult { - const cancelEventConfig = new CancelEventConfig( - matchedConfig.EventId, - matchedConfig.QueueDomain, - matchedConfig.CookieDomain, - customerIntegrationInfo.Version, - matchedConfig.Name - ); - - const targetUrl = this.generateTargetUrl(currentUrlWithoutQueueITToken, httpContextProvider); - return this._cancelRequestByLocalConfig(targetUrl, queueitToken, cancelEventConfig, customerId, secretKey, httpContextProvider, dateTimeProvider, debugEntries, isDebug); - } - - private static handleIgnoreAction( - httpContextProvider: IHttpContextProvider, - actionName: string): ValidationResult { - const userInQueueService = this.getUserInQueueService(httpContextProvider); - const result = userInQueueService.getIgnoreResult(actionName); - result.isAjaxResult = this.isQueueAjaxCall(httpContextProvider); - return new ValidationResult(result, null); - } - - public static extendQueueCookie( - eventId: string, - cookieValidityMinute: number, - cookieDomain: string, - secretKey: string, - httpContextProvider: IHttpContextProvider): KnownUserException | null { - if (eventId == "") { - return new KnownUserException("eventId can not be null or empty."); - } - if (secretKey == "") { - return new KnownUserException("secretKey can not be null or empty."); - } - if (cookieValidityMinute <= 0) { - return new KnownUserException("cookieValidityMinute should be integer greater than 0."); - } - - const userInQueueService = this.getUserInQueueService(httpContextProvider); - userInQueueService.extendQueueCookie(eventId, cookieValidityMinute, cookieDomain, secretKey); - return null; - } - - public static resolveQueueRequestByLocalConfig( - targetUrl: string, - queueitToken: string, - queueConfig: QueueEventConfig | null, - customerId: string, - secretKey: string, - httpContextProvider: IHttpContextProvider, - dateTimeProvider: IDateTimeProvider | null = null): ValidationResult { - if (dateTimeProvider == null) dateTimeProvider = new DateTimeProvider(); - const debugEntries = new Map(); - const connectorDiagnostics = ConnectorDiagnostics.verify(customerId, secretKey, queueitToken); - - if (connectorDiagnostics.hasError) { - return new ValidationResult(connectorDiagnostics.validationResult, null); - } - - targetUrl = this.generateTargetUrl(targetUrl, httpContextProvider); - const result = this._resolveQueueRequestByLocalConfig(targetUrl, queueitToken, queueConfig, customerId, secretKey, httpContextProvider, dateTimeProvider, debugEntries, connectorDiagnostics.isEnabled); - if (result != null && result.second != null) { - if (connectorDiagnostics.isEnabled) { - debugEntries.set("Exception", result.second!.message); - } - } - this.setDebugCookie(debugEntries, httpContextProvider); - return result; - } - - private static handleException(diagnostics: ConnectorDiagnostics, - debugEntries: Map, - ex: KnownUserException, - httpContext: IHttpContextProvider): void { - if (diagnostics.isEnabled) debugEntries.set('Exception', ex.message); - this.setDebugCookie(debugEntries, httpContext); - } - - public static validateRequestByIntegrationConfig( - currentUrlWithoutQueueITToken: string, - queueitToken: string, - integrationsConfigString: string, - customerId: string, - secretKey: string, - httpContextProvider: IHttpContextProvider, - dateTimeProvider: IDateTimeProvider | null = null): ValidationResult { - if (dateTimeProvider == null) dateTimeProvider = new DateTimeProvider(); - - const debugEntries = new Map(); - - const connectorDiagnostics = ConnectorDiagnostics.verify(customerId, secretKey, queueitToken); - if (connectorDiagnostics.hasError) { - return new ValidationResult(connectorDiagnostics.validationResult, null); - } - if (connectorDiagnostics.isEnabled) { - debugEntries.set("SdkVersion", UserInQueueService.SDK_VERSION); - debugEntries.set("PureUrl", currentUrlWithoutQueueITToken); - debugEntries.set("QueueitToken", queueitToken); - debugEntries.set("OriginalUrl", httpContextProvider.getHttpRequest().getAbsoluteUri()); - - this.logExtraRequestDetails(debugEntries, httpContextProvider, dateTimeProvider); - } - - const customerIntegrationInfo = CustomerIntegrationDecodingHandler.deserialize(integrationsConfigString); - - if (connectorDiagnostics.isEnabled) { - debugEntries.set('ConfigVersion', customerIntegrationInfo && customerIntegrationInfo.Version != 0 ? customerIntegrationInfo.Version.toString() : "NULL"); - } - - if (currentUrlWithoutQueueITToken == '') { - const ex = new KnownUserException("currentUrlWithoutQueueITToken can not be null or empty."); - this.handleException(connectorDiagnostics, debugEntries, ex, httpContextProvider); - return new ValidationResult(null, ex); - } - if (customerIntegrationInfo == null || customerIntegrationInfo.Version == 0) { - const ex = new KnownUserException("integrationsConfigString can not be null or empty."); - this.handleException(connectorDiagnostics, debugEntries, ex, httpContextProvider); - return new ValidationResult(null, ex); - } - - const configEvaluator = new IntegrationConfigHelpers.IntegrationEvaluator(); - - const configMatchResult = configEvaluator.getMatchedIntegrationConfig( - customerIntegrationInfo, - currentUrlWithoutQueueITToken, - httpContextProvider.getHttpRequest()); - - if (connectorDiagnostics.isEnabled) { - debugEntries.set('MatchedConfig', configMatchResult != null && configMatchResult.first != null ? - configMatchResult.first!.Name - : "NULL"); - } - if (configMatchResult == null || configMatchResult.second != null) { - this.setDebugCookie(debugEntries, httpContextProvider); - return new ValidationResult(new RequestValidationResult("", "", "", "", "", ""), null); - } - const matchedConfig = configMatchResult.first!; - let result: ValidationResult - - if (matchedConfig.ActionType == ActionTypes.QueueAction) { - result = this.handleQueueAction(currentUrlWithoutQueueITToken, queueitToken, customerIntegrationInfo, - customerId, secretKey, matchedConfig, httpContextProvider, dateTimeProvider, debugEntries, connectorDiagnostics.isEnabled); - } else if (matchedConfig.ActionType == ActionTypes.CancelAction) { - result = this.handleCancelAction(currentUrlWithoutQueueITToken, queueitToken, customerIntegrationInfo, - customerId, secretKey, matchedConfig, httpContextProvider, dateTimeProvider, debugEntries, connectorDiagnostics.isEnabled); - } else { - result = this.handleIgnoreAction(httpContextProvider, matchedConfig.Name); - } - if (result.second != null && connectorDiagnostics.isEnabled) { - debugEntries.set('Exception', result.second!.message); - } - - this.setDebugCookie(debugEntries, httpContextProvider); - return result; - } - - public static cancelRequestByLocalConfig( - targetUrl: string, - queueitToken: string, - cancelConfig: CancelEventConfig | null, - customerId: string, - secretKey: string, - httpContextProvider: IHttpContextProvider, - dateTimeProvider: IDateTimeProvider | null = null): ValidationResult { - if (dateTimeProvider == null) dateTimeProvider = new DateTimeProvider(); - const debugEntries = new Map(); - const connectorDiagnostics = ConnectorDiagnostics.verify(customerId, secretKey, queueitToken); - - if (connectorDiagnostics.hasError) - return new ValidationResult(connectorDiagnostics.validationResult, null); - - const result = this._cancelRequestByLocalConfig( - targetUrl, queueitToken, cancelConfig, customerId, secretKey, httpContextProvider, dateTimeProvider, debugEntries, connectorDiagnostics.isEnabled); - if (result.second != null && connectorDiagnostics.isEnabled) { - debugEntries.set('Exception', result.second!.message); - } - this.setDebugCookie(debugEntries, httpContextProvider); - - return result; - } -} - diff --git a/src/sdk/Models.ts b/src/sdk/Models.ts deleted file mode 100644 index 3d02c54..0000000 --- a/src/sdk/Models.ts +++ /dev/null @@ -1,105 +0,0 @@ -import {Utils} from './QueueITHelpers'; - -export class Tuple { - first: T1 - second: T2 - - constructor(first: T1, second: T2) { - this.first = first; - this.second = second; - } -} - -export class ValidationResult extends Tuple { - -} - -export class QueueEventConfig { - constructor( - public eventId: string, - public layoutName: string, - public culture: string, - public queueDomain: string, - public extendCookieValidity: boolean, - public cookieValidityMinute: number, - public cookieDomain: string, - public version: number, - public actionName: string = 'unspecified') { - } - - getString(): string { - return "EventId:" + this.eventId + - "&Version:" + this.version.toString() + - "&ActionName:" + this.actionName + - "&QueueDomain:" + this.queueDomain + - "&CookieDomain:" + this.cookieDomain + - "&ExtendCookieValidity:" + this.extendCookieValidity.toString() + - "&CookieValidityMinute:" + this.cookieValidityMinute.toString() + - "&LayoutName:" + this.layoutName + - "&Culture:" + this.culture; - } -} - -export class CancelEventConfig { - constructor(public eventId: string, - public queueDomain: string, - public cookieDomain: string, - public version: number, - public actionName: string = 'unspecified') { - } - - getString(): string { - return "EventId:" + this.eventId + - "&Version:" + this.version.toString() + - "&QueueDomain:" + this.queueDomain + - "&CookieDomain:" + this.cookieDomain + - "&ActionName:" + this.actionName; - } -} - -export class RequestValidationResult { - constructor( - public actionType: string, - public eventId: string, - public queueId: string, - public redirectUrl: string, - public redirectType: string, - public actionName: string = 'unspecified' - ) { - } - - public isAjaxResult: boolean = false; - - public doRedirect(): boolean { - return this.redirectUrl.length > 0; - } - - public getAjaxQueueRedirectHeaderKey(): string { - return "x-queueit-redirect"; - } - - public getAjaxRedirectUrl(): string { - if (this.redirectUrl.length > 0) { - return Utils.encodeUrl(this.redirectUrl); - } - return ""; - } -} - -export class KnownUserException { - constructor(public message: string) { - } -} - -export class ActionTypes { - public static readonly QueueAction: string = "Queue"; - public static readonly CancelAction: string = "Cancel"; - public static readonly IgnoreAction: string = "Ignore"; -} - - -export class KeyValuePair { - constructor(public key: string, public value: string) { - } - -} diff --git a/src/sdk/QueueITHelpers.ts b/src/sdk/QueueITHelpers.ts deleted file mode 100644 index 4dd2da0..0000000 --- a/src/sdk/QueueITHelpers.ts +++ /dev/null @@ -1,267 +0,0 @@ -import {KeyValuePair, RequestValidationResult} from "./Models"; -import {IDateTimeProvider} from "./HttpContextProvider"; -import {encodeURIComponent, decodeURIComponent} from "./helpers/Uri"; -import {KnownUser} from "./KnownUser"; -import {UserInQueueService} from "./UserInQueueService"; - -export class QueueUrlParams { - public timeStamp: number = 0; - public eventId: string = ""; - public hashCode: string = ""; - public extendableCookie: boolean = false; - public cookieValidityMinutes: number = 0; - public queueITToken: string = ""; - public queueITTokenWithoutHash: string = ""; - public queueId: string = ""; - public redirectType: string = ""; -} - - -export class Utils { - - static encodeUrl(url: string): string { - if (url.length == 0) - return ""; - let decoded = encodeURIComponent(url); - decoded = decoded.replaceAll('!', '%' + '!'.charCodeAt(0).toString(16)); - decoded = decoded.replaceAll('\'', '%' + '\''.charCodeAt(0).toString(16)); - decoded = decoded.replaceAll('(', '%' + '('.charCodeAt(0).toString(16)); - decoded = decoded.replaceAll(')', '%' + ')'.charCodeAt(0).toString(16)); - decoded = decoded.replaceAll('*', '%' + '*'.charCodeAt(0).toString(16)); - - return decoded; - } - - static decodeUrl(url: string): string { - try { - return decodeURIComponent(url); - } catch { - return url; - } - } - - static generateSHA256Hash: (a: string, b: string) => string = (secretKey: string, stringToHash: string): string => ""; - - static endsWith(str: string, search: string): boolean { - if (str == search) - return true; - if (str.length == 0 || search.length == 0) - return false; - return str.substring(str.length - search.length, str.length) == search; - } - - static getCurrentTime(): number { - return Math.floor(Date.now() / 1000); - } - - private static _hex2bin: number[] = [ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, // 0-9 - 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, // A-F - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, // a-f - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - ]; - - static hex2bin(str: string): string { - let len = str.length; - let rv = ''; - let i = 0; - - let c1: number; - let c2: number; - - while (len > 1) { - let h1 = str.charAt(i++); - c1 = h1.charCodeAt(0); - let h2 = str.charAt(i++); - c2 = h2.charCodeAt(0); - - rv += String.fromCharCode((Utils._hex2bin[c1] << 4) + Utils._hex2bin[c2]); - len -= 2; - } - - return rv; - } - - static addNoCacheHeaders(res: Response): void { - res.headers.set('Cache-Control', 'no-cache, no-store, must-revalidate, max-age=0'); - res.headers.set('Pragma', 'no-cache'); - res.headers.set('Expires', 'Fri, 01 Jan 1990 00:00:00 GMT'); - } - - static getParameterByName(url: string, name: string): string { - const namePart = /[\[\]]/g; - let match = namePart.exec(name); - while (match !== null) { - let rxmatch = match[0]; - name = name.replaceAll(rxmatch, '\\$&') - match = namePart.exec(name); - } - const regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'); - const results = regex.exec(url); - if (results === null) return ''; - if (results.length < 3 || results[2] === null || results[2] === undefined) { - return ''; - } - - try { - return decodeURIComponent(results[2].replaceAll('+', ' ')); - } catch { - return results[2]; - } - } - - static removeQueueItToken(url: string): string { - const pattern = new RegExp("([?&])(" + KnownUser.QueueITTokenKey + "=[^&]*)", 'gi'); - const match = pattern.exec(url); - if (match === null) return url; - - url = url.replaceAll(match[0], '') - return url; - } -} - -export class QueueParameterHelper { - public static readonly TimeStampKey: string = "ts"; - public static readonly ExtendableCookieKey: string = "ce"; - public static readonly CookieValidityMinutesKey: string = "cv"; - public static readonly HashKey: string = "h"; - public static readonly EventIdKey: string = "e"; - public static readonly QueueIdKey: string = "q"; - public static readonly RedirectTypeKey: string = "rt"; - public static readonly KeyValueSeparatorChar: string = '_'; - public static readonly KeyValueSeparatorGroupChar: string = '~'; - - public static extractQueueParams(queueitToken: string): QueueUrlParams | null { - if (queueitToken.length == 0) { - return null; - } - - const result = new QueueUrlParams(); - result.queueITToken = queueitToken; - - const paramList = result.queueITToken.split(QueueParameterHelper.KeyValueSeparatorGroupChar); - for (let i = 0; i < paramList.length; i++) { - let paramKeyValue = paramList[i]; - - let keyValueArr = paramKeyValue.split(QueueParameterHelper.KeyValueSeparatorChar); - if (keyValueArr.length != 2) { - continue; - } - - if (keyValueArr[0] == QueueParameterHelper.HashKey) { - result.hashCode = keyValueArr[1]; - } else if (keyValueArr[0] == QueueParameterHelper.TimeStampKey) { - result.timeStamp = parseInt(keyValueArr[1], 10) || 0; - } else if (keyValueArr[0] == QueueParameterHelper.CookieValidityMinutesKey) { - result.cookieValidityMinutes = parseInt(keyValueArr[1], 10) || 0; - } else if (keyValueArr[0] == QueueParameterHelper.EventIdKey) { - result.eventId = keyValueArr[1]; - } else if (keyValueArr[0] == QueueParameterHelper.ExtendableCookieKey) { - let extendCookie = (keyValueArr[1].length > 0 ? keyValueArr[1] : "false").toLowerCase(); - result.extendableCookie = extendCookie == "true"; - } else if (keyValueArr[0] == QueueParameterHelper.QueueIdKey) { - result.queueId = keyValueArr[1]; - - } else if (keyValueArr[0] == QueueParameterHelper.RedirectTypeKey) { - result.redirectType = keyValueArr[1]; - } - } - - const hashWithPrefix = QueueParameterHelper.KeyValueSeparatorGroupChar + - QueueParameterHelper.HashKey + - QueueParameterHelper.KeyValueSeparatorChar + - result.hashCode; - result.queueITTokenWithoutHash = result.queueITToken.replaceAll(hashWithPrefix, ""); - return result; - } -} - -export class CookieHelper { - public static toMapFromValue(cookieValue: string): Map { - const items: string[] = cookieValue.split('&'); - let result = new Map(); - for (let i = 0; i < items.length; i++) { - let item: string = items[i]; - let keyValue = item.split('='); - if (keyValue.length == 2) { - result.set(keyValue[0], keyValue[1]); - } - } - return result; - } - - public static toValueFromKeyValueCollection(cookieValues: Array): string { - let values = new Array(); - - for (let i = 0; i < cookieValues.length; i++) { - let kvp: KeyValuePair = cookieValues[i]; - values.push(kvp.key + "=" + kvp.value); - } - - return values.join("&"); - } -} - -export class ConnectorDiagnostics { - public isEnabled: boolean = false; - public hasError: boolean = false; - public validationResult: RequestValidationResult | null = null - - private setStateWithTokenError(customerId: string, errorCode: string): void { - this.hasError = true; - const redirectUrl = "https://" + customerId + ".api2.queue-it.net/" + customerId + "/diagnostics/connector/error/?code=" + errorCode; - this.validationResult = new RequestValidationResult("ConnectorDiagnosticsRedirect", "", - "", redirectUrl, "", "") - } - - private setStateWithSetupError(): void { - this.hasError = true; - this.validationResult = new RequestValidationResult("ConnectorDiagnosticsRedirect", "", "", - "https://api2.queue-it.net/diagnostics/connector/error/?code=setup", "", "") - } - - public static verify(customerId: string, secretKey: string, queueitToken: string): ConnectorDiagnostics { - const diagnostics = new ConnectorDiagnostics(); - const qParams = QueueParameterHelper.extractQueueParams(queueitToken); - - if (qParams == null) - return diagnostics; - if (qParams.redirectType == null) - return diagnostics; - if (qParams.redirectType != "debug") - return diagnostics; - if (!(customerId != "" && secretKey != "")) { - diagnostics.setStateWithSetupError(); - return diagnostics; - } - if (Utils.generateSHA256Hash(secretKey, qParams.queueITTokenWithoutHash) != qParams.hashCode) { - diagnostics.setStateWithTokenError(customerId, "hash"); - return diagnostics; - } - if (qParams.timeStamp < Utils.getCurrentTime()) { - diagnostics.setStateWithTokenError(customerId, "timestamp"); - return diagnostics; - } - diagnostics.isEnabled = true; - - return diagnostics; - } -} - -export class DateTimeProvider implements IDateTimeProvider { - getCurrentTime(): Date { - return new Date(Date.now()); - } -} diff --git a/src/sdk/UserInQueueService.ts b/src/sdk/UserInQueueService.ts deleted file mode 100644 index dc1cd91..0000000 --- a/src/sdk/UserInQueueService.ts +++ /dev/null @@ -1,245 +0,0 @@ -import {Utils, QueueUrlParams, QueueParameterHelper} from './QueueITHelpers' -import {ActionTypes, RequestValidationResult, QueueEventConfig, CancelEventConfig, ValidationResult} from './Models' -import {StateInfo, UserInQueueStateCookieRepository} from './UserInQueueStateCookieRepository' - -export class UserInQueueService { - static readonly SDK_VERSION: string = "v3-javascript-3.6.2"; - - constructor(private userInQueueStateRepository: UserInQueueStateCookieRepository) { - } - - private getValidTokenResult( - config: QueueEventConfig, - queueParams: QueueUrlParams, - secretKey: string) - : RequestValidationResult { - - this.userInQueueStateRepository.store( - config.eventId, - queueParams.queueId, - queueParams.cookieValidityMinutes, - config.cookieDomain, - queueParams.redirectType, - secretKey); - - return new RequestValidationResult( - ActionTypes.QueueAction, - config.eventId, - queueParams.queueId, - "", - queueParams.redirectType, - config.actionName, - ); - } - - private getErrorResult( - customerId: string, - targetUrl: string, - config: QueueEventConfig, - qParams: QueueUrlParams, - errorCode: string) - : RequestValidationResult { - - let query = this.getQueryString(customerId, config.eventId, config.version, config.culture, config.layoutName, config.actionName) + - "&queueittoken=" + qParams.queueITToken + - "&ts=" + Utils.getCurrentTime().toString() + - (targetUrl.length > 0 ? "&t=" + Utils.encodeUrl(targetUrl) : ""); - const uriPath = "error/" + errorCode + "/"; - const redirectUrl = this.generateRedirectUrl(config.queueDomain, uriPath, query); - - return new RequestValidationResult( - ActionTypes.QueueAction, - config.eventId, - "", - redirectUrl, - "", - config.actionName - ); - } - - private getQueueResult( - targetUrl: string, - config: QueueEventConfig, - customerId: string) - : RequestValidationResult { - - let query = this.getQueryString(customerId, config.eventId, config.version, config.culture, config.layoutName, config.actionName) + - (targetUrl.length > 0 ? "&t=" + Utils.encodeUrl(targetUrl) : ""); - - const redirectUrl = this.generateRedirectUrl(config.queueDomain, "", query); - - return new RequestValidationResult( - ActionTypes.QueueAction, - config.eventId, - "", - redirectUrl, - "", - config.actionName - ); - } - - private getQueryString( - customerId: string, - eventId: string, - configVersion: number, - culture: string, - layoutName: string, - actionName: string) - : string { - const queryStringList = new Array(); - queryStringList.push("c=" + Utils.encodeUrl(customerId)); - queryStringList.push("e=" + Utils.encodeUrl(eventId)); - queryStringList.push("ver=" + UserInQueueService.SDK_VERSION); - queryStringList.push("cver=" + configVersion.toString()); - queryStringList.push("man=" + Utils.encodeUrl(actionName)); - - if (culture.length > 0) { - queryStringList.push("cid=" + Utils.encodeUrl(culture)); - } - - - if (layoutName.length > 0) { - queryStringList.push("l=" + Utils.encodeUrl(layoutName)); - } - - return queryStringList.join("&"); - } - - - private generateRedirectUrl(queueDomain: string, uriPath: string, query: string): string { - if (!Utils.endsWith(queueDomain, "/")) - queueDomain = queueDomain + "/"; - - return "https://".concat(queueDomain).concat(uriPath).concat("?").concat(query); - } - - public validateQueueRequest( - targetUrl: string, - queueitToken: string, - config: QueueEventConfig, - customerId: string, - secretKey: string): ValidationResult { - const state: StateInfo = this.userInQueueStateRepository.getState(config.eventId, - config.cookieValidityMinute, secretKey, true); - if (state.isValid) { - if (state.isStateExtendable() && config.extendCookieValidity) { - this.userInQueueStateRepository.store(config.eventId, - state.queueId, - 0, - config.cookieDomain, - state.redirectType, - secretKey); - } - return new ValidationResult(new RequestValidationResult( - ActionTypes.QueueAction, - config.eventId, - state.queueId, - "", - state.redirectType, - config.actionName - ), null); - } - - const queueParams = QueueParameterHelper.extractQueueParams(queueitToken); - - let requestValidationResult: RequestValidationResult | null; - let isTokenValid: boolean = false; - - if (queueParams != null) { - const tokenValidationResult = this.validateToken(config, queueParams, secretKey); - isTokenValid = tokenValidationResult.isValid; - - if (isTokenValid) { - requestValidationResult = this.getValidTokenResult(config, queueParams, secretKey); - } else { - requestValidationResult = this.getErrorResult(customerId, targetUrl, config, queueParams, tokenValidationResult.errorCode); - } - } else { - requestValidationResult = this.getQueueResult(targetUrl, config, customerId); - } - - if (state.isFound && !isTokenValid) { - this.userInQueueStateRepository.cancelQueueCookie(config.eventId, config.cookieDomain); - } - - return new ValidationResult(requestValidationResult, null); - } - - public validateCancelRequest( - targetUrl: string, - config: CancelEventConfig, - customerId: string, - secretKey: string): ValidationResult { - //we do not care how long cookie is valid while canceling cookie - const state = this.userInQueueStateRepository.getState(config.eventId, -1, secretKey, false); - - if (state.isValid) { - - this.userInQueueStateRepository.cancelQueueCookie(config.eventId, config.cookieDomain); - const query = this.getQueryString(customerId, config.eventId, config.version, '', '', config.actionName) + - (targetUrl.length > 0 ? "&r=" + Utils.encodeUrl(targetUrl) : ""); - - const uriPath = "cancel/" + customerId + "/" + config.eventId + "/"; - const redirectUrl = this.generateRedirectUrl(config.queueDomain, uriPath, query); - return new ValidationResult(new RequestValidationResult( - ActionTypes.CancelAction, - config.eventId, - state.queueId, - redirectUrl, - state.redirectType, - config.actionName), null); - } else { - return new ValidationResult(new RequestValidationResult( - ActionTypes.CancelAction, - config.eventId, - "", - "", - "", - config.actionName), null); - } - } - - public extendQueueCookie( - eventId: string, - cookieValidityMinutes: number, - cookieDomain: string, - secretKey: string): void { - this.userInQueueStateRepository.reissueQueueCookie(eventId, cookieValidityMinutes, cookieDomain, secretKey) - } - - public getIgnoreResult( - actionName: string): RequestValidationResult { - return new RequestValidationResult(ActionTypes.IgnoreAction, "", "", "", "", actionName); - } - - private validateToken( - config: QueueEventConfig, - queueParams: QueueUrlParams, - secretKey: string): TokenValidationResult { - - const calculatedHash = Utils.generateSHA256Hash(secretKey, queueParams.queueITTokenWithoutHash); - - if (calculatedHash != queueParams.hashCode) { - return new TokenValidationResult(false, "hash"); - } - - - if (queueParams.eventId != config.eventId) - return new TokenValidationResult(false, "eventid"); - - if (queueParams.timeStamp < Utils.getCurrentTime()) - return new TokenValidationResult(false, "timestamp"); - - return new TokenValidationResult(true, ""); - } - -} - -class TokenValidationResult { - constructor( - public isValid: boolean, - public errorCode: string) { - - } - -} diff --git a/src/sdk/UserInQueueStateCookieRepository.ts b/src/sdk/UserInQueueStateCookieRepository.ts deleted file mode 100644 index 20c95fc..0000000 --- a/src/sdk/UserInQueueStateCookieRepository.ts +++ /dev/null @@ -1,188 +0,0 @@ -import {IHttpContextProvider} from './HttpContextProvider' -import {Utils, CookieHelper} from './QueueITHelpers' -import {KeyValuePair} from "./Models"; - -export class UserInQueueStateCookieRepository { - private static readonly _QueueITDataKey: string = "QueueITAccepted-SDFrts345E-V3"; - private static readonly _HashKey: string = "Hash"; - private static readonly _IssueTimeKey: string = "IssueTime"; - private static readonly _QueueIdKey: string = "QueueId"; - private static readonly _EventIdKey: string = "EventId"; - private static readonly _RedirectTypeKey: string = "RedirectType"; - private static readonly _FixedCookieValidityMinutesKey: string = "FixedValidityMins"; - - constructor(private httpContextProvider: IHttpContextProvider) { - } - - public static getCookieKey(eventId: string): string { - return UserInQueueStateCookieRepository._QueueITDataKey + "_" + eventId; - } - - public store(eventId: string, queueId: string, fixedCookieValidityMinutes: number, - cookieDomain: string, redirectType: string, secretKey: string): void { - this.createCookie( - eventId, queueId, - fixedCookieValidityMinutes > 0 ? fixedCookieValidityMinutes.toString() : "", - redirectType, cookieDomain, secretKey); - } - - private createCookie( - eventId: string, - queueId: string, - fixedCookieValidityMinutes: string, - redirectType: string, - cookieDomain: string, - secretKey: string): void { - let cookieKey = UserInQueueStateCookieRepository.getCookieKey(eventId); - - let issueTime = Utils.getCurrentTime().toString(); - - let cookieValues = new Array(); - cookieValues.push(new KeyValuePair(UserInQueueStateCookieRepository._EventIdKey, eventId)); - cookieValues.push(new KeyValuePair(UserInQueueStateCookieRepository._QueueIdKey, queueId)); - if (fixedCookieValidityMinutes != '') { - cookieValues.push(new KeyValuePair( - UserInQueueStateCookieRepository._FixedCookieValidityMinutesKey, fixedCookieValidityMinutes - )); - } - cookieValues.push(new KeyValuePair(UserInQueueStateCookieRepository._RedirectTypeKey, redirectType.toLowerCase())); - cookieValues.push(new KeyValuePair(UserInQueueStateCookieRepository._IssueTimeKey, issueTime)); - cookieValues.push(new KeyValuePair( - UserInQueueStateCookieRepository._HashKey, - this.generateHash(eventId.toLowerCase(), queueId, fixedCookieValidityMinutes, redirectType.toLowerCase(), issueTime, secretKey) - )); - const tomorrow: Date = new Date(Date.now() + 1000 * 60 * 60 * 24); - const expire: number = Math.floor(tomorrow.getTime() / 1000); - let cookieValue = CookieHelper.toValueFromKeyValueCollection(cookieValues); - - this.httpContextProvider.getHttpResponse().setCookie(cookieKey, - cookieValue, - cookieDomain, expire); - } - - public getState(eventId: string, cookieValidityMinutes: number, secretKey: string, validateTime: boolean): StateInfo { - const cookieKey = UserInQueueStateCookieRepository.getCookieKey(eventId); - const cookie = this.httpContextProvider.getHttpRequest().getCookieValue(cookieKey); - - if (cookie == "") { - return new StateInfo(false, false, "", 0, ""); - } - const cookieValues = CookieHelper.toMapFromValue(cookie); - - if (!this.isCookieValid(secretKey, cookieValues, eventId, cookieValidityMinutes, validateTime)) { - return new StateInfo(true, false, "", 0, ""); - } - - const fixedCookieValidity: number = cookieValues.has(UserInQueueStateCookieRepository._FixedCookieValidityMinutesKey) - ? parseInt(cookieValues.get(UserInQueueStateCookieRepository._FixedCookieValidityMinutesKey)!, 10) - : 0; - - return new StateInfo( - true, - true, - cookieValues.get(UserInQueueStateCookieRepository._QueueIdKey)!, - fixedCookieValidity, - cookieValues.get(UserInQueueStateCookieRepository._RedirectTypeKey)!); - } - - private isCookieValid( - secretKey: string, - cookieValueMap: Map, - eventId: string, - cookieValidityMinutes: number, - validateTime: boolean): boolean { - - const storedHash = cookieValueMap.has(UserInQueueStateCookieRepository._HashKey) ? - cookieValueMap.get(UserInQueueStateCookieRepository._HashKey)! : ""; - const issueTimeString = cookieValueMap.has(UserInQueueStateCookieRepository._IssueTimeKey) ? - cookieValueMap.get(UserInQueueStateCookieRepository._IssueTimeKey)! : ""; - const queueId = cookieValueMap.has(UserInQueueStateCookieRepository._QueueIdKey) ? - cookieValueMap.get(UserInQueueStateCookieRepository._QueueIdKey)! : ""; - const eventIdFromCookie = cookieValueMap.has(UserInQueueStateCookieRepository._EventIdKey) ? - cookieValueMap.get(UserInQueueStateCookieRepository._EventIdKey)! : ""; - const redirectType = cookieValueMap.has(UserInQueueStateCookieRepository._RedirectTypeKey) ? - cookieValueMap.get(UserInQueueStateCookieRepository._RedirectTypeKey)! : ""; - let fixedCookieValidityMinutes = cookieValueMap.has(UserInQueueStateCookieRepository._FixedCookieValidityMinutesKey) ? - cookieValueMap.get(UserInQueueStateCookieRepository._FixedCookieValidityMinutesKey)! : ""; - - const expectedHash = this.generateHash( - eventIdFromCookie, - queueId, - fixedCookieValidityMinutes, - redirectType, - issueTimeString, - secretKey); - if (expectedHash.length == 0) { - return false - } - - if (expectedHash != storedHash) - return false; - - if (eventId.toLowerCase() != eventIdFromCookie.toLowerCase()) - return false; - - if (validateTime) { - let validity: number = fixedCookieValidityMinutes.length > 0 ? parseInt(fixedCookieValidityMinutes, 10) : cookieValidityMinutes; - let expirationTime: number = parseInt(issueTimeString, 10) + validity * 60; - - if (expirationTime < Utils.getCurrentTime()) - return false; - } - return true; - } - - public cancelQueueCookie(eventId: string, cookieDomain: string): void { - const cookieKey = UserInQueueStateCookieRepository.getCookieKey(eventId); - this.httpContextProvider.getHttpResponse().setCookie(cookieKey, "", cookieDomain, 0); - } - - public reissueQueueCookie(eventId: string, cookieValidityMinutes: number, cookieDomain: string, secretKey: string): void { - const cookieKey = UserInQueueStateCookieRepository.getCookieKey(eventId); - const cookie = this.httpContextProvider.getHttpRequest().getCookieValue(cookieKey); - - if (cookie == '') - return; - - const cookieValues = CookieHelper.toMapFromValue(cookie); - - if (!this.isCookieValid(secretKey, cookieValues, eventId, cookieValidityMinutes, true)) - return; - - let fixedCookieValidityMinutes = ""; - if (cookieValues.has(UserInQueueStateCookieRepository._FixedCookieValidityMinutesKey)) { - fixedCookieValidityMinutes = cookieValues.get(UserInQueueStateCookieRepository._FixedCookieValidityMinutesKey)!.toString(); - } - - this.createCookie( - eventId, - cookieValues.get(UserInQueueStateCookieRepository._QueueIdKey)!, - fixedCookieValidityMinutes, - cookieValues.get(UserInQueueStateCookieRepository._RedirectTypeKey)!, - cookieDomain, secretKey); - } - - private generateHash( - eventId: string, - queueId: string, - fixedCookieValidityMinutes: string, - redirectType: string, - issueTime: string, - secretKey: string): string { - let valueToHash = eventId + queueId + fixedCookieValidityMinutes + redirectType + issueTime; - return Utils.generateSHA256Hash(secretKey, valueToHash); - } -} - -export class StateInfo { - constructor(public isFound: boolean, - public isValid: boolean, - public queueId: string, - public fixedCookieValidityMinutes: number, - public redirectType: string) { - } - - isStateExtendable(): boolean { - return this.isValid && !this.fixedCookieValidityMinutes; - } -} diff --git a/src/sdk/helpers/Uri.ts b/src/sdk/helpers/Uri.ts deleted file mode 100644 index 4ae890a..0000000 --- a/src/sdk/helpers/Uri.ts +++ /dev/null @@ -1,4 +0,0 @@ -export const encodeURI = globalThis.encodeURI; -export const decodeURI = globalThis.decodeURI; -export const encodeURIComponent = globalThis.encodeURIComponent; -export const decodeURIComponent = globalThis.decodeURIComponent;