diff --git a/package-lock.json b/package-lock.json index 3045bdfcf0..c1dc1fe99f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,7 @@ "extensions/samples/*", "shared-test-utils", "samples/e2eTestUtils", + "samples/labUtils", "samples/msal-browser-samples/*", "samples/msal-angular-samples/*", "samples/msal-react-samples/*", @@ -249,6 +250,7 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz", "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==", "dev": true, + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -342,6 +344,7 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", "dev": true, + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -449,6 +452,7 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.16.tgz", "integrity": "sha512-vOTpLduLkZXePLxHiHsBLp98mHGnl8RptV4YAO3HfKO5UHjDvySGbxKtpYfy8Sx5+WKcgc45qNreJJRVM3L6mw==", "dev": true, + "peer": true, "dependencies": { "undici-types": "~6.19.2" } @@ -649,7 +653,6 @@ "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", "dev": true, "license": "Apache-2.0", - "peer": true, "dependencies": { "dequal": "^2.0.3" } @@ -1326,6 +1329,7 @@ "url": "https://github.com/sponsors/ai" } ], + "peer": true, "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", @@ -1380,6 +1384,7 @@ "resolved": "https://registry.npmjs.org/sass/-/sass-1.58.1.tgz", "integrity": "sha512-bnINi6nPXbP1XNRaranMFEBZWUfdW/AF16Ql5+ypRxfTvCRTTKrLsMIakyDcayUt2t/RZotmL4kgJwNH5xO+bg==", "dev": true, + "peer": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", @@ -1474,6 +1479,7 @@ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.76.1.tgz", "integrity": "sha512-4+YIK4Abzv8172/SGqObnUjaIHjLEuUasz9EwQj/9xmPPkYJy2Mh03Q/lJfSD3YLzbxy5FeTq5Uw0323Oh6SJQ==", "dev": true, + "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.3", "@types/estree": "^0.0.51", @@ -1522,6 +1528,7 @@ "integrity": "sha512-lILVz9tAUy1zGFwieuaQtYiadImb5M3d+H+L1zDYalYoDl0cksAB1UNyuE5MMWJrG6zR1tXkCP2fitl7yoUJiw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/bonjour": "^3.5.9", "@types/connect-history-api-fallback": "^1.3.5", @@ -1578,6 +1585,7 @@ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -2147,6 +2155,7 @@ "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-15.2.10.tgz", "integrity": "sha512-yxfN8qQpMaukRU5LjFkJBmy85rqrOp86tYVCsf+hmPEFRiXBMUj6xYLeCMcpk3Mt1JtnWGBR34ivGx+7bNeAow==", "dev": true, + "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -2264,6 +2273,7 @@ "resolved": "https://registry.npmjs.org/@angular/common/-/common-15.2.10.tgz", "integrity": "sha512-jdBn3fctkqoNrJn9VLsUHpcCEhCxWSczdsR+BBbD6T0oLl6vMrAVNjPwfBejnlgfWN1KoRU9kgOYsMxa5apIWQ==", "dev": true, + "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -2300,6 +2310,7 @@ "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-15.2.10.tgz", "integrity": "sha512-mCFIxrs60XicKfA2o42hA7LrQvhybi9BQveWuZn/2iIEOXx7R62Iemz8E21pLWftAZHGxEW3NECfBrY1d3gVmA==", "dev": true, + "peer": true, "dependencies": { "@babel/core": "7.19.3", "@jridgewell/sourcemap-codec": "^1.4.14", @@ -2398,6 +2409,7 @@ "resolved": "https://registry.npmjs.org/@angular/core/-/core-15.2.10.tgz", "integrity": "sha512-meGGidnitQJGDxYd9/LrqYiVlId+vGaLoiLgJdKBz+o2ZO6OmXQGuNw2VBqf17/Cc0/UjzrOY7+kILNFKkk/WQ==", "dev": true, + "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -2432,6 +2444,7 @@ "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-15.2.10.tgz", "integrity": "sha512-9tbgVGSJqwfrOzT8aA/kWBLNhJSQ9gUg0CJxwFBSJm8VkBUJrszoBlDsnSvlxx8/W2ejNULKHFTXeUzq0O/+RQ==", "dev": true, + "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -2490,7 +2503,6 @@ "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.7.2.tgz", "integrity": "sha512-4gY54eEGEstClvEkGnwVkTkrx0sqwemEFG5OSRRn3tD91XH0+Q8XIkYIfo7IwEWPpJZwILb9GUXeShtplRc/eA==", "dev": true, - "peer": true, "dependencies": { "@jsdevtools/ono": "^7.1.3", "@types/json-schema": "^7.0.15", @@ -2508,7 +2520,6 @@ "resolved": "https://registry.npmjs.org/@apidevtools/openapi-schemas/-/openapi-schemas-2.1.0.tgz", "integrity": "sha512-Zc1AlqrJlX3SlpupFGpiLi2EbteyP7fXmUOGup6/DnkRgjP9bgMM/ag+n91rsv0U1Gpz0H3VILA/o3bW7Ua6BQ==", "dev": true, - "peer": true, "engines": { "node": ">=10" } @@ -2517,15 +2528,13 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/@apidevtools/swagger-methods/-/swagger-methods-3.0.2.tgz", "integrity": "sha512-QAkD5kK2b1WfjDS/UQn/qQkbwF31uqRjPTrsCs5ZG9BQGAkjwvqGFjjPqAuzac/IYzpPtRzjCP1WrTuAIjMrXg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@apidevtools/swagger-parser": { "version": "10.1.1", "resolved": "https://registry.npmjs.org/@apidevtools/swagger-parser/-/swagger-parser-10.1.1.tgz", "integrity": "sha512-u/kozRnsPO/x8QtKYJOqoGtC4kH6yg1lfYkB9Au0WhYB0FNLpyFusttQtvhlwjtG3rOwiRz4D8DnnXa8iEpIKA==", "dev": true, - "peer": true, "dependencies": { "@apidevtools/json-schema-ref-parser": "11.7.2", "@apidevtools/openapi-schemas": "^2.1.0", @@ -2561,7 +2570,6 @@ "resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz", "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==", "dev": true, - "peer": true, "peerDependencies": { "ajv": "^8.5.0" }, @@ -2575,8 +2583,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@assemblyscript/loader": { "version": "0.10.1", @@ -2600,7 +2607,6 @@ "resolved": "https://registry.npmjs.org/@azure/arm-appservice/-/arm-appservice-13.0.3.tgz", "integrity": "sha512-Vu011o3/bikQNwtjouwmUJud+Z6Brcjij2D0omPWClRGg8i5gBfOYSpDkFGkHbhGlaky4fgvfkxD0uHGq34uYA==", "dev": true, - "peer": true, "dependencies": { "@azure/abort-controller": "^1.0.0", "@azure/core-auth": "^1.3.0", @@ -2619,7 +2625,6 @@ "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-1.1.0.tgz", "integrity": "sha512-TrRLIoSQVzfAJX9H1JeFjzAoDGcoK1IYX1UImfceTZpsyYfWr09Ss1aHW1y5TrrR3iq6RZLBwJ3E24uwPhwahw==", "dev": true, - "peer": true, "dependencies": { "tslib": "^2.2.0" }, @@ -2632,7 +2637,6 @@ "resolved": "https://registry.npmjs.org/@azure/arm-resources/-/arm-resources-5.0.1.tgz", "integrity": "sha512-JbZtIqfEulsIA0rC3zM7jfF4KkOnye9aKcaO/jJqxJRm/gM6lAjEv7sL4njW8D+35l50P1f+UuH5OqN+UKJqNA==", "dev": true, - "peer": true, "dependencies": { "@azure/abort-controller": "^1.0.0", "@azure/core-auth": "^1.3.0", @@ -2651,7 +2655,6 @@ "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-1.1.0.tgz", "integrity": "sha512-TrRLIoSQVzfAJX9H1JeFjzAoDGcoK1IYX1UImfceTZpsyYfWr09Ss1aHW1y5TrrR3iq6RZLBwJ3E24uwPhwahw==", "dev": true, - "peer": true, "dependencies": { "tslib": "^2.2.0" }, @@ -2664,7 +2667,6 @@ "resolved": "https://registry.npmjs.org/@azure/arm-storage/-/arm-storage-17.2.1.tgz", "integrity": "sha512-J2jmTPv8ZraSHDTz9l2Bx8gNL3ktfDDWo2mxWfzarn64O9Fjhb+l85YWyubGy2xUdeGuZPKzvQLltGv8bSu8eQ==", "dev": true, - "peer": true, "dependencies": { "@azure/abort-controller": "^1.0.0", "@azure/core-auth": "^1.3.0", @@ -2683,7 +2685,6 @@ "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-1.1.0.tgz", "integrity": "sha512-TrRLIoSQVzfAJX9H1JeFjzAoDGcoK1IYX1UImfceTZpsyYfWr09Ss1aHW1y5TrrR3iq6RZLBwJ3E24uwPhwahw==", "dev": true, - "peer": true, "dependencies": { "tslib": "^2.2.0" }, @@ -2696,7 +2697,6 @@ "resolved": "https://registry.npmjs.org/@azure/arm-subscriptions/-/arm-subscriptions-5.1.0.tgz", "integrity": "sha512-6BeOF2eQWNLq22ch7xP9RxYnPjtGev54OUCGggKOWoOvmesK7jUZbIyLk8JeXDT21PEl7iyYnxw78gxJ7zBxQw==", "dev": true, - "peer": true, "dependencies": { "@azure/abort-controller": "^1.0.0", "@azure/core-auth": "^1.3.0", @@ -2715,7 +2715,6 @@ "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-1.1.0.tgz", "integrity": "sha512-TrRLIoSQVzfAJX9H1JeFjzAoDGcoK1IYX1UImfceTZpsyYfWr09Ss1aHW1y5TrrR3iq6RZLBwJ3E24uwPhwahw==", "dev": true, - "peer": true, "dependencies": { "tslib": "^2.2.0" }, @@ -3081,6 +3080,7 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.0.tgz", "integrity": "sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==", "license": "MIT", + "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.27.1", @@ -4205,6 +4205,7 @@ "version": "7.26.0", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.26.0.tgz", "integrity": "sha512-B+O2DnPc0iG+YXFqOxv2WNuNU97ToWjOomUQ78DouOENWUaM5sVrmet9mcomUGQFwpJd//gvUagXBSdzO1fRKg==", + "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, @@ -5863,6 +5864,7 @@ "version": "6.1.2", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -5983,6 +5985,7 @@ "version": "6.1.2", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -7723,6 +7726,7 @@ "version": "2.1.4", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "peer": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", @@ -7769,15 +7773,13 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/@exodus/schemasafe/-/schemasafe-1.3.0.tgz", "integrity": "sha512-5Aap/GaRupgNx/feGBwLLTVv8OQFfv3pq2lPRzPg9R+IOBnDgghTGW7l7EuVXOvg5cc/xSAlRW8rBrjIC3Nvqw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@feathersjs/hooks": { "version": "0.6.5", "resolved": "https://registry.npmjs.org/@feathersjs/hooks/-/hooks-0.6.5.tgz", "integrity": "sha512-WtcEoG/imdHRvC3vofGi/OcgH+cjHHhO0AfEeTlsnrKLjVKKBXV6aoIrB2nHZPpE7iW5sA7AZMR6bPD8ytxN+w==", "dev": true, - "peer": true, "engines": { "node": ">= 10" } @@ -8291,7 +8293,6 @@ "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-1.5.2.tgz", "integrity": "sha512-CifrkgQjDkUkWexmgYYNyB5603HhTHI91vLFeQXh6qrTKiCMVASol01Rs1cv6LP/A2WccZSRlJKZhbaBIs/9ZA==", "dev": true, - "peer": true, "dependencies": { "@inquirer/core": "^6.0.0", "@inquirer/type": "^1.1.6", @@ -8308,7 +8309,6 @@ "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-6.0.0.tgz", "integrity": "sha512-fKi63Khkisgda3ohnskNf5uZJj+zXOaBvOllHsOkdsXRA/ubQLJQrZchFFi57NKbZzkTunXiBMdvWOv71alonw==", "dev": true, - "peer": true, "dependencies": { "@inquirer/type": "^1.1.6", "@types/mute-stream": "^0.0.4", @@ -8334,7 +8334,6 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.16.tgz", "integrity": "sha512-vOTpLduLkZXePLxHiHsBLp98mHGnl8RptV4YAO3HfKO5UHjDvySGbxKtpYfy8Sx5+WKcgc45qNreJJRVM3L6mw==", "dev": true, - "peer": true, "dependencies": { "undici-types": "~6.19.2" } @@ -8344,7 +8343,6 @@ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", "dev": true, - "peer": true, "engines": { "node": ">= 12" } @@ -8354,7 +8352,6 @@ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", "dev": true, - "peer": true, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -8364,7 +8361,6 @@ "resolved": "https://registry.npmjs.org/run-async/-/run-async-3.0.0.tgz", "integrity": "sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==", "dev": true, - "peer": true, "engines": { "node": ">=0.12.0" } @@ -8374,7 +8370,6 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, - "peer": true, "engines": { "node": ">=14" }, @@ -8387,7 +8382,6 @@ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, - "peer": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -8402,7 +8396,6 @@ "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-2.0.17.tgz", "integrity": "sha512-EqzhGryzmGpy2aJf6LxJVhndxYmFs+m8cxXzf8nejb1DE3sabf6mUgBcp4J0jAUEiAcYzqmkqRr7LPFh/WdnXA==", "dev": true, - "peer": true, "dependencies": { "@inquirer/core": "^6.0.0", "@inquirer/type": "^1.1.6", @@ -8417,7 +8410,6 @@ "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-6.0.0.tgz", "integrity": "sha512-fKi63Khkisgda3ohnskNf5uZJj+zXOaBvOllHsOkdsXRA/ubQLJQrZchFFi57NKbZzkTunXiBMdvWOv71alonw==", "dev": true, - "peer": true, "dependencies": { "@inquirer/type": "^1.1.6", "@types/mute-stream": "^0.0.4", @@ -8443,7 +8435,6 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.16.tgz", "integrity": "sha512-vOTpLduLkZXePLxHiHsBLp98mHGnl8RptV4YAO3HfKO5UHjDvySGbxKtpYfy8Sx5+WKcgc45qNreJJRVM3L6mw==", "dev": true, - "peer": true, "dependencies": { "undici-types": "~6.19.2" } @@ -8453,7 +8444,6 @@ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", "dev": true, - "peer": true, "engines": { "node": ">= 12" } @@ -8463,7 +8453,6 @@ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", "dev": true, - "peer": true, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -8473,7 +8462,6 @@ "resolved": "https://registry.npmjs.org/run-async/-/run-async-3.0.0.tgz", "integrity": "sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==", "dev": true, - "peer": true, "engines": { "node": ">=0.12.0" } @@ -8483,7 +8471,6 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, - "peer": true, "engines": { "node": ">=14" }, @@ -8496,7 +8483,6 @@ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, - "peer": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -8511,7 +8497,6 @@ "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-5.1.2.tgz", "integrity": "sha512-w3PMZH5rahrukn8/I7P9Ihil+twgLTUHDZtJlJyBbUKyPaOSSQjLZkb0PpncVhin1gCaMgOFXy6iNPgcZUoo2w==", "dev": true, - "peer": true, "dependencies": { "@inquirer/type": "^1.1.6", "@types/mute-stream": "^0.0.4", @@ -8537,7 +8522,6 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.16.tgz", "integrity": "sha512-vOTpLduLkZXePLxHiHsBLp98mHGnl8RptV4YAO3HfKO5UHjDvySGbxKtpYfy8Sx5+WKcgc45qNreJJRVM3L6mw==", "dev": true, - "peer": true, "dependencies": { "undici-types": "~6.19.2" } @@ -8547,7 +8531,6 @@ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", "dev": true, - "peer": true, "engines": { "node": ">= 12" } @@ -8557,7 +8540,6 @@ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", "dev": true, - "peer": true, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -8567,7 +8549,6 @@ "resolved": "https://registry.npmjs.org/run-async/-/run-async-3.0.0.tgz", "integrity": "sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==", "dev": true, - "peer": true, "engines": { "node": ">=0.12.0" } @@ -8577,7 +8558,6 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, - "peer": true, "engines": { "node": ">=14" }, @@ -8590,7 +8570,6 @@ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, - "peer": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -8605,7 +8584,6 @@ "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-1.2.15.tgz", "integrity": "sha512-gQ77Ls09x5vKLVNMH9q/7xvYPT6sIs5f7URksw+a2iJZ0j48tVS6crLqm2ugG33tgXHIwiEqkytY60Zyh5GkJQ==", "dev": true, - "peer": true, "dependencies": { "@inquirer/core": "^6.0.0", "@inquirer/type": "^1.1.6", @@ -8621,7 +8599,6 @@ "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-6.0.0.tgz", "integrity": "sha512-fKi63Khkisgda3ohnskNf5uZJj+zXOaBvOllHsOkdsXRA/ubQLJQrZchFFi57NKbZzkTunXiBMdvWOv71alonw==", "dev": true, - "peer": true, "dependencies": { "@inquirer/type": "^1.1.6", "@types/mute-stream": "^0.0.4", @@ -8647,7 +8624,6 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.16.tgz", "integrity": "sha512-vOTpLduLkZXePLxHiHsBLp98mHGnl8RptV4YAO3HfKO5UHjDvySGbxKtpYfy8Sx5+WKcgc45qNreJJRVM3L6mw==", "dev": true, - "peer": true, "dependencies": { "undici-types": "~6.19.2" } @@ -8657,7 +8633,6 @@ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", "dev": true, - "peer": true, "engines": { "node": ">= 12" } @@ -8667,7 +8642,6 @@ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", "dev": true, - "peer": true, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -8677,7 +8651,6 @@ "resolved": "https://registry.npmjs.org/run-async/-/run-async-3.0.0.tgz", "integrity": "sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==", "dev": true, - "peer": true, "engines": { "node": ">=0.12.0" } @@ -8687,7 +8660,6 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, - "peer": true, "engines": { "node": ">=14" }, @@ -8700,7 +8672,6 @@ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, - "peer": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -8715,7 +8686,6 @@ "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-1.1.16.tgz", "integrity": "sha512-TGLU9egcuo+s7PxphKUCnJnpCIVY32/EwPCLLuu+gTvYiD8hZgx8Z2niNQD36sa6xcfpdLY6xXDBiL/+g1r2XQ==", "dev": true, - "peer": true, "dependencies": { "@inquirer/core": "^6.0.0", "@inquirer/type": "^1.1.6", @@ -8731,7 +8701,6 @@ "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-6.0.0.tgz", "integrity": "sha512-fKi63Khkisgda3ohnskNf5uZJj+zXOaBvOllHsOkdsXRA/ubQLJQrZchFFi57NKbZzkTunXiBMdvWOv71alonw==", "dev": true, - "peer": true, "dependencies": { "@inquirer/type": "^1.1.6", "@types/mute-stream": "^0.0.4", @@ -8757,7 +8726,6 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.16.tgz", "integrity": "sha512-vOTpLduLkZXePLxHiHsBLp98mHGnl8RptV4YAO3HfKO5UHjDvySGbxKtpYfy8Sx5+WKcgc45qNreJJRVM3L6mw==", "dev": true, - "peer": true, "dependencies": { "undici-types": "~6.19.2" } @@ -8767,7 +8735,6 @@ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", "dev": true, - "peer": true, "engines": { "node": ">= 12" } @@ -8777,7 +8744,6 @@ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", "dev": true, - "peer": true, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -8787,7 +8753,6 @@ "resolved": "https://registry.npmjs.org/run-async/-/run-async-3.0.0.tgz", "integrity": "sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==", "dev": true, - "peer": true, "engines": { "node": ">=0.12.0" } @@ -8797,7 +8762,6 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, - "peer": true, "engines": { "node": ">=14" }, @@ -8810,7 +8774,6 @@ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, - "peer": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -8881,7 +8844,6 @@ "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-1.2.16.tgz", "integrity": "sha512-Ou0LaSWvj1ni+egnyQ+NBtfM1885UwhRCMtsRt2bBO47DoC1dwtCa+ZUNgrxlnCHHF0IXsbQHYtIIjFGAavI4g==", "dev": true, - "peer": true, "dependencies": { "@inquirer/core": "^6.0.0", "@inquirer/type": "^1.1.6", @@ -8896,7 +8858,6 @@ "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-6.0.0.tgz", "integrity": "sha512-fKi63Khkisgda3ohnskNf5uZJj+zXOaBvOllHsOkdsXRA/ubQLJQrZchFFi57NKbZzkTunXiBMdvWOv71alonw==", "dev": true, - "peer": true, "dependencies": { "@inquirer/type": "^1.1.6", "@types/mute-stream": "^0.0.4", @@ -8922,7 +8883,6 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.16.tgz", "integrity": "sha512-vOTpLduLkZXePLxHiHsBLp98mHGnl8RptV4YAO3HfKO5UHjDvySGbxKtpYfy8Sx5+WKcgc45qNreJJRVM3L6mw==", "dev": true, - "peer": true, "dependencies": { "undici-types": "~6.19.2" } @@ -8932,7 +8892,6 @@ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", "dev": true, - "peer": true, "engines": { "node": ">= 12" } @@ -8942,7 +8901,6 @@ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", "dev": true, - "peer": true, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -8952,7 +8910,6 @@ "resolved": "https://registry.npmjs.org/run-async/-/run-async-3.0.0.tgz", "integrity": "sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==", "dev": true, - "peer": true, "engines": { "node": ">=0.12.0" } @@ -8962,7 +8919,6 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, - "peer": true, "engines": { "node": ">=14" }, @@ -8975,7 +8931,6 @@ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, - "peer": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -9106,7 +9061,6 @@ "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-1.1.16.tgz", "integrity": "sha512-aZYZVHLUXZ2gbBot+i+zOJrks1WaiI95lvZCn1sKfcw6MtSSlYC8uDX8sTzQvAsQ8epHoP84UNvAIT0KVGOGqw==", "dev": true, - "peer": true, "dependencies": { "@inquirer/core": "^6.0.0", "@inquirer/type": "^1.1.6", @@ -9122,7 +9076,6 @@ "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-6.0.0.tgz", "integrity": "sha512-fKi63Khkisgda3ohnskNf5uZJj+zXOaBvOllHsOkdsXRA/ubQLJQrZchFFi57NKbZzkTunXiBMdvWOv71alonw==", "dev": true, - "peer": true, "dependencies": { "@inquirer/type": "^1.1.6", "@types/mute-stream": "^0.0.4", @@ -9148,7 +9101,6 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.16.tgz", "integrity": "sha512-vOTpLduLkZXePLxHiHsBLp98mHGnl8RptV4YAO3HfKO5UHjDvySGbxKtpYfy8Sx5+WKcgc45qNreJJRVM3L6mw==", "dev": true, - "peer": true, "dependencies": { "undici-types": "~6.19.2" } @@ -9158,7 +9110,6 @@ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", "dev": true, - "peer": true, "engines": { "node": ">= 12" } @@ -9168,7 +9119,6 @@ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", "dev": true, - "peer": true, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -9178,7 +9128,6 @@ "resolved": "https://registry.npmjs.org/run-async/-/run-async-3.0.0.tgz", "integrity": "sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==", "dev": true, - "peer": true, "engines": { "node": ">=0.12.0" } @@ -9188,7 +9137,6 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, - "peer": true, "engines": { "node": ">=14" }, @@ -9201,7 +9149,6 @@ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, - "peer": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -9216,7 +9163,6 @@ "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-3.3.2.tgz", "integrity": "sha512-k52mOMRvTUejrqyF1h8Z07chC+sbaoaUYzzr1KrJXyj7yaX7Nrh0a9vktv8TuocRwIJOQMaj5oZEmkspEcJFYQ==", "dev": true, - "peer": true, "dependencies": { "@inquirer/checkbox": "^1.5.2", "@inquirer/confirm": "^2.0.17", @@ -9237,7 +9183,6 @@ "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-6.0.0.tgz", "integrity": "sha512-fKi63Khkisgda3ohnskNf5uZJj+zXOaBvOllHsOkdsXRA/ubQLJQrZchFFi57NKbZzkTunXiBMdvWOv71alonw==", "dev": true, - "peer": true, "dependencies": { "@inquirer/type": "^1.1.6", "@types/mute-stream": "^0.0.4", @@ -9263,7 +9208,6 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.16.tgz", "integrity": "sha512-vOTpLduLkZXePLxHiHsBLp98mHGnl8RptV4YAO3HfKO5UHjDvySGbxKtpYfy8Sx5+WKcgc45qNreJJRVM3L6mw==", "dev": true, - "peer": true, "dependencies": { "undici-types": "~6.19.2" } @@ -9273,7 +9217,6 @@ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", "dev": true, - "peer": true, "engines": { "node": ">= 12" } @@ -9283,7 +9226,6 @@ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", "dev": true, - "peer": true, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -9293,7 +9235,6 @@ "resolved": "https://registry.npmjs.org/run-async/-/run-async-3.0.0.tgz", "integrity": "sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==", "dev": true, - "peer": true, "engines": { "node": ">=0.12.0" } @@ -9303,7 +9244,6 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, - "peer": true, "engines": { "node": ">=14" }, @@ -9316,7 +9256,6 @@ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, - "peer": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -9331,7 +9270,6 @@ "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-1.2.16.tgz", "integrity": "sha512-pZ6TRg2qMwZAOZAV6TvghCtkr53dGnK29GMNQ3vMZXSNguvGqtOVc4j/h1T8kqGJFagjyfBZhUPGwNS55O5qPQ==", "dev": true, - "peer": true, "dependencies": { "@inquirer/core": "^6.0.0", "@inquirer/type": "^1.1.6", @@ -9346,7 +9284,6 @@ "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-6.0.0.tgz", "integrity": "sha512-fKi63Khkisgda3ohnskNf5uZJj+zXOaBvOllHsOkdsXRA/ubQLJQrZchFFi57NKbZzkTunXiBMdvWOv71alonw==", "dev": true, - "peer": true, "dependencies": { "@inquirer/type": "^1.1.6", "@types/mute-stream": "^0.0.4", @@ -9372,7 +9309,6 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.16.tgz", "integrity": "sha512-vOTpLduLkZXePLxHiHsBLp98mHGnl8RptV4YAO3HfKO5UHjDvySGbxKtpYfy8Sx5+WKcgc45qNreJJRVM3L6mw==", "dev": true, - "peer": true, "dependencies": { "undici-types": "~6.19.2" } @@ -9382,7 +9318,6 @@ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", "dev": true, - "peer": true, "engines": { "node": ">= 12" } @@ -9392,7 +9327,6 @@ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", "dev": true, - "peer": true, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -9402,7 +9336,6 @@ "resolved": "https://registry.npmjs.org/run-async/-/run-async-3.0.0.tgz", "integrity": "sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==", "dev": true, - "peer": true, "engines": { "node": ">=0.12.0" } @@ -9412,7 +9345,6 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, - "peer": true, "engines": { "node": ">=14" }, @@ -9425,7 +9357,6 @@ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, - "peer": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -9558,7 +9489,6 @@ "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-1.3.3.tgz", "integrity": "sha512-RzlRISXWqIKEf83FDC9ZtJ3JvuK1l7aGpretf41BCWYrvla2wU8W8MTRNMiPrPJ+1SIqrRC1nZdZ60hD9hRXLg==", "dev": true, - "peer": true, "dependencies": { "@inquirer/core": "^6.0.0", "@inquirer/type": "^1.1.6", @@ -9575,7 +9505,6 @@ "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-6.0.0.tgz", "integrity": "sha512-fKi63Khkisgda3ohnskNf5uZJj+zXOaBvOllHsOkdsXRA/ubQLJQrZchFFi57NKbZzkTunXiBMdvWOv71alonw==", "dev": true, - "peer": true, "dependencies": { "@inquirer/type": "^1.1.6", "@types/mute-stream": "^0.0.4", @@ -9601,7 +9530,6 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.16.tgz", "integrity": "sha512-vOTpLduLkZXePLxHiHsBLp98mHGnl8RptV4YAO3HfKO5UHjDvySGbxKtpYfy8Sx5+WKcgc45qNreJJRVM3L6mw==", "dev": true, - "peer": true, "dependencies": { "undici-types": "~6.19.2" } @@ -9611,7 +9539,6 @@ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", "dev": true, - "peer": true, "engines": { "node": ">= 12" } @@ -9621,7 +9548,6 @@ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", "dev": true, - "peer": true, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -9631,7 +9557,6 @@ "resolved": "https://registry.npmjs.org/run-async/-/run-async-3.0.0.tgz", "integrity": "sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==", "dev": true, - "peer": true, "engines": { "node": ">=0.12.0" } @@ -9641,7 +9566,6 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, - "peer": true, "engines": { "node": ">=14" }, @@ -9654,7 +9578,6 @@ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, - "peer": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -10445,8 +10368,7 @@ "version": "7.1.3", "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@jsonjoy.com/base64": { "version": "1.1.2", @@ -11502,7 +11424,6 @@ "resolved": "https://registry.npmjs.org/@microsoft/dev-tunnels-contracts/-/dev-tunnels-contracts-1.1.9.tgz", "integrity": "sha512-OayhehwI+CnO0Wr53e29ZJZWGsNA5yVG7r54qmZSLc5HxA5Cozk4hP7EbYDCXkxh4NbQoT1dhTzC8bkRo+wWXw==", "dev": true, - "peer": true, "dependencies": { "buffer": "^5.2.1", "debug": "^4.1.1", @@ -11514,7 +11435,6 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", "dev": true, - "peer": true, "dependencies": { "ms": "^2.1.3" }, @@ -11532,7 +11452,6 @@ "resolved": "https://registry.npmjs.org/@microsoft/dev-tunnels-management/-/dev-tunnels-management-1.1.9.tgz", "integrity": "sha512-wGuFEzvRiWZmDxQMGKEjOKhEIVnLiG6vRUuM9Hwqxpe/kbiyA2WiUyEVpniNPaaw8gDHTf9zJHnPNNj0JiL5mA==", "dev": true, - "peer": true, "dependencies": { "@microsoft/dev-tunnels-contracts": ">1.1.8", "axios": "^1.6.2", @@ -11546,7 +11465,6 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", "dev": true, - "peer": true, "dependencies": { "ms": "^2.1.3" }, @@ -11564,7 +11482,6 @@ "resolved": "https://registry.npmjs.org/@microsoft/m365-spec-parser/-/m365-spec-parser-0.2.5.tgz", "integrity": "sha512-nAEd69xK1ZmSDBhogQeGzjaHslo0v/zaTkbd7sbJq21xoW07P4KLu8gkp8qLuxjOGGlaBo5YWXF9vYpkqAyyFg==", "dev": true, - "peer": true, "dependencies": { "@apidevtools/swagger-parser": "^10.1.1", "@microsoft/teams-manifest": "0.1.8", @@ -11582,7 +11499,6 @@ "resolved": "https://registry.npmjs.org/@microsoft/teams-manifest/-/teams-manifest-0.1.8.tgz", "integrity": "sha512-uoXed7wyMIUGXVRQflqWLhD2hpCz+cYhQ06e2s5PW8HIw1AlDBPM3s4+Y+ArJInzMZs0SZ58B66sq0Iy46/WKQ==", "dev": true, - "peer": true, "dependencies": { "@types/fs-extra": "^11.0.1", "@types/node-fetch": "^2.6.9", @@ -11598,7 +11514,6 @@ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", "dev": true, - "peer": true, "dependencies": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", @@ -11614,7 +11529,6 @@ "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-11.0.4.tgz", "integrity": "sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==", "dev": true, - "peer": true, "dependencies": { "@types/jsonfile": "*", "@types/node": "*" @@ -11642,7 +11556,6 @@ "resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz", "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==", "dev": true, - "peer": true, "peerDependencies": { "ajv": "^8.5.0" }, @@ -11657,7 +11570,6 @@ "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", "dev": true, - "peer": true, "dependencies": { "ajv": "^8.0.0" }, @@ -11675,7 +11587,6 @@ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz", "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==", "dev": true, - "peer": true, "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -11689,8 +11600,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@microsoft/teams-manifest": { "version": "0.1.5", @@ -11722,6 +11632,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -11791,7 +11702,6 @@ "integrity": "sha512-AowuJwrrUxeF9Bq/frxuy9YZjK/ECk3pi0UBXl3CQLZ4XNWfgWatiFi/UWpyHDLccFs+0Za3nNYATFvgsxEFwQ==", "dev": true, "hasInstallScript": true, - "peer": true, "dependencies": { "@azure/arm-subscriptions": "^5.0.0", "@azure/core-auth": "^1.4.0", @@ -11834,7 +11744,6 @@ "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-14.16.0.tgz", "integrity": "sha512-1KOZj9IpcDSwpNiQNjt0jDYZpQvNZay7QAEi/5DLubay40iGYtLzya/jbjRPLyOTZhEKyL1MzPuw2HqBCjceYA==", "dev": true, - "peer": true, "engines": { "node": ">=0.8.0" } @@ -11844,7 +11753,6 @@ "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-2.16.2.tgz", "integrity": "sha512-An7l1hEr0w1HMMh1LU+rtDtqL7/jw74ORlc9Wnh06v7TU/xpG39/Zdr1ZJu3QpjUfKJ+E0/OXMW8DRSWTlh7qQ==", "dev": true, - "peer": true, "dependencies": { "@azure/msal-common": "14.16.0", "jsonwebtoken": "^9.0.0", @@ -11859,7 +11767,6 @@ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", "dev": true, - "peer": true, "dependencies": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", @@ -11875,7 +11782,6 @@ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz", "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==", "dev": true, - "peer": true, "dependencies": { "ansi-escapes": "^4.2.1", "chalk": "^4.1.0", @@ -11900,7 +11806,6 @@ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", "dev": true, - "peer": true, "dependencies": { "tslib": "^1.9.0" }, @@ -11912,15 +11817,13 @@ "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@microsoft/teamsfx-api": { "version": "0.23.1", "resolved": "https://registry.npmjs.org/@microsoft/teamsfx-api/-/teamsfx-api-0.23.1.tgz", "integrity": "sha512-XmXX2dccOEU3lbYgOlijfwxmkXp6nO88JWx9P1al/1aMgbIeup2Y2H37Vmz2VwfIQC/i75FbbbbwqYjG2skQjQ==", "dev": true, - "peer": true, "dependencies": { "@azure/core-auth": "^1.4.0", "@microsoft/teams-manifest": "0.1.5", @@ -11936,7 +11839,6 @@ "resolved": "https://registry.npmjs.org/@microsoft/teamsfx-core/-/teamsfx-core-2.0.9.tgz", "integrity": "sha512-6zA/vvpHViROP6eDbnjS8PtPyyB4eZGH/cgTiOHeiRHznT9Pkd3rqFvaIHPEDhv2g76llHEk2gTFSqL7QFovAQ==", "dev": true, - "peer": true, "dependencies": { "@apidevtools/swagger-parser": "^10.1.0", "@azure/arm-appservice": "^13.0.0", @@ -11996,7 +11898,6 @@ "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-14.16.0.tgz", "integrity": "sha512-1KOZj9IpcDSwpNiQNjt0jDYZpQvNZay7QAEi/5DLubay40iGYtLzya/jbjRPLyOTZhEKyL1MzPuw2HqBCjceYA==", "dev": true, - "peer": true, "engines": { "node": ">=0.8.0" } @@ -12006,7 +11907,6 @@ "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-2.16.2.tgz", "integrity": "sha512-An7l1hEr0w1HMMh1LU+rtDtqL7/jw74ORlc9Wnh06v7TU/xpG39/Zdr1ZJu3QpjUfKJ+E0/OXMW8DRSWTlh7qQ==", "dev": true, - "peer": true, "dependencies": { "@azure/msal-common": "14.16.0", "jsonwebtoken": "^9.0.0", @@ -12021,7 +11921,6 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -12038,7 +11937,6 @@ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", "dev": true, - "peer": true, "dependencies": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", @@ -12055,7 +11953,6 @@ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, - "peer": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -12076,7 +11973,6 @@ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "dev": true, - "peer": true, "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, @@ -12088,15 +11984,13 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@microsoft/teamsfx-core/node_modules/yaml": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz", "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==", "dev": true, - "peer": true, "bin": { "yaml": "bin.mjs" }, @@ -12294,6 +12188,7 @@ "version": "5.16.14", "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.16.14.tgz", "integrity": "sha512-eSXQVCMKU2xc7EcTxe/X/rC9QsV2jUe8eLM3MUCPYbo6V52eCE436akRIvELq/AqZpxx2bwkq7HC0cRhLB+yaw==", + "peer": true, "dependencies": { "@babel/runtime": "^7.23.9", "@mui/core-downloads-tracker": "^5.16.14", @@ -13569,6 +13464,7 @@ "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.6.0.tgz", "integrity": "sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q==", "dev": true, + "peer": true, "dependencies": { "@octokit/auth-token": "^2.4.4", "@octokit/graphql": "^4.5.8", @@ -14119,6 +14015,7 @@ "version": "2.11.8", "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "peer": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/popperjs" @@ -14129,7 +14026,6 @@ "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.10.13.tgz", "integrity": "sha512-a9Ruw3j3qlnB5a/zHRTkruppynxqaeE4H9WNj5eYGRWqw0ZauZ23f4W2ARf3hghF5doozyD+CRtt7XSYuYRI/Q==", "license": "Apache-2.0", - "peer": true, "dependencies": { "debug": "^4.4.3", "extract-zip": "^2.0.1", @@ -14151,7 +14047,6 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "license": "MIT", - "peer": true, "dependencies": { "ms": "^2.1.3" }, @@ -14169,7 +14064,6 @@ "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.1.tgz", "integrity": "sha512-LZA0oaPOc2fVo82Txf3gw+AkEd38szODlptMYejQUhndHMLQ9M059uXR+AfS7DNo0NpINvSqDsvyaCrBVkptWg==", "license": "MIT", - "peer": true, "dependencies": { "pump": "^3.0.0", "tar-stream": "^3.1.5" @@ -14184,7 +14078,6 @@ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", "license": "MIT", - "peer": true, "dependencies": { "b4a": "^1.6.4", "fast-fifo": "^1.2.0", @@ -14217,6 +14110,7 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.6.0.tgz", "integrity": "sha512-aR0uffYI700OEEH4gYnitAnv3vzVGXCFvYfdpu/CJKvk4pHfLPEy/JSZyrpQ+15WhXe1yJRXLtfQ84s4mEXnPg==", + "peer": true, "dependencies": { "cluster-key-slot": "1.1.2", "generic-pool": "3.9.0", @@ -14754,7 +14648,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "dependencies": { "@types/estree": "1.0.8" }, @@ -14775,8 +14668,7 @@ "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", "dev": true, "license": "MIT", - "optional": true, - "peer": true + "optional": true }, "node_modules/@rtsao/scc": { "version": "1.1.0", @@ -14817,6 +14709,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.13.0.tgz", "integrity": "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==", "dev": true, + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "json-schema-traverse": "^1.0.0", @@ -15585,8 +15478,7 @@ "version": "0.23.0", "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@trysound/sax": { "version": "0.2.0", @@ -15683,8 +15575,7 @@ "version": "5.0.4", "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@types/babel__core": { "version": "7.20.5", @@ -15791,6 +15682,7 @@ "version": "8.56.12", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.12.tgz", "integrity": "sha512-03ruubjWyOHlmljCVoxSuNDdmfZDzsrrz0P2LeJsOXr+ZwFQ+0yQIwNCwt/GYhV7Z31fgtXJTAEs+FYlEL851g==", + "peer": true, "dependencies": { "@types/estree": "*", "@types/json-schema": "*" @@ -16049,6 +15941,7 @@ "version": "4.17.12", "resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.12.tgz", "integrity": "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==", + "peer": true, "dependencies": { "@types/lodash": "*" } @@ -16077,7 +15970,6 @@ "resolved": "https://registry.npmjs.org/@types/mute-stream/-/mute-stream-0.0.4.tgz", "integrity": "sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow==", "dev": true, - "peer": true, "dependencies": { "@types/node": "*" } @@ -16086,6 +15978,7 @@ "version": "22.10.10", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.10.tgz", "integrity": "sha512-X47y/mPNzxviAGY5TcYPtYL8JsY3kAq2n8fMmKoRCxq/c4v4pyGNCzM2R6+M5/umG4ZfHuT+sgqDYqWc9rJ6ww==", + "peer": true, "dependencies": { "undici-types": "~6.20.0" } @@ -16159,6 +16052,7 @@ "version": "19.2.7", "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.7.tgz", "integrity": "sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg==", + "peer": true, "dependencies": { "csstype": "^3.2.2" } @@ -16167,6 +16061,7 @@ "version": "19.2.3", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", + "peer": true, "peerDependencies": { "@types/react": "^19.2.0" } @@ -16303,8 +16198,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/wrap-ansi/-/wrap-ansi-3.0.0.tgz", "integrity": "sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@types/ws": { "version": "8.5.14", @@ -16332,7 +16226,6 @@ "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", "optional": true, - "peer": true, "dependencies": { "@types/node": "*" } @@ -17417,6 +17310,7 @@ "version": "8.15.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -17598,6 +17492,7 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -17872,8 +17767,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/array-timsort/-/array-timsort-1.0.3.tgz", "integrity": "sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/array-union": { "version": "2.1.0", @@ -18029,7 +17923,6 @@ "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", "dev": true, - "peer": true, "engines": { "node": "*" } @@ -18039,7 +17932,6 @@ "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", "license": "MIT", - "peer": true, "dependencies": { "tslib": "^2.0.1" }, @@ -18115,7 +18007,6 @@ "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.3.2.tgz", "integrity": "sha512-HuTK7E7MT7jZEh1P9GtRW9+aTWiDWWi9InbZ5hjxrnRa39KS4BW04+xLBhYNS2aXhHUIKZSw3gj4Pn1pj+qGAA==", "dev": true, - "peer": true, "dependencies": { "tslib": "^2.3.1" } @@ -18253,7 +18144,6 @@ "resolved": "https://registry.npmjs.org/axios-retry/-/axios-retry-3.9.1.tgz", "integrity": "sha512-8PJDLJv7qTTMMwdnbMvrLYuvB47M81wRtxQmEdV5w4rgbTXTt+vtPkXwajOfOdSyv/wZICJOC+/UhXH4aQ/R+w==", "dev": true, - "peer": true, "dependencies": { "@babel/runtime": "^7.15.4", "is-retry-allowed": "^2.2.0" @@ -18276,7 +18166,6 @@ "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.7.3.tgz", "integrity": "sha512-5Q2mfq2WfGuFp3uS//0s6baOJLMoVduPYVeNmDYxu5OUA1/cBfvr2RIS7vi62LdNj/urk1hfmj867I3qt6uZ7Q==", "license": "Apache-2.0", - "peer": true, "peerDependencies": { "react-native-b4a": "*" }, @@ -18613,7 +18502,6 @@ "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.8.2.tgz", "integrity": "sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==", "license": "Apache-2.0", - "peer": true, "peerDependencies": { "bare-abort-controller": "*" }, @@ -18629,7 +18517,6 @@ "integrity": "sha512-GljgCjeupKZJNetTqxKaQArLK10vpmK28or0+RwWjEl5Rk+/xG3wkpmkv+WrcBm3q1BwHKlnhXzR8O37kcvkXQ==", "license": "Apache-2.0", "optional": true, - "peer": true, "dependencies": { "bare-events": "^2.5.4", "bare-path": "^3.0.0", @@ -18655,7 +18542,6 @@ "integrity": "sha512-T+V1+1srU2qYNBmJCXZkUY5vQ0B4FSlL3QDROnKQYOqeiQR8UbjNHlPa+TIbM4cuidiN9GaTaOZgSEgsvPbh5A==", "license": "Apache-2.0", "optional": true, - "peer": true, "engines": { "bare": ">=1.14.0" } @@ -18666,7 +18552,6 @@ "integrity": "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==", "license": "Apache-2.0", "optional": true, - "peer": true, "dependencies": { "bare-os": "^3.0.1" } @@ -18677,7 +18562,6 @@ "integrity": "sha512-oyXQNicV1y8nc2aKffH+BUHFRXmx6VrPzlnaEvMhram0nPBrKcEdcyBg5r08D0i8VxngHFAiVyn1QKXpSG0B8A==", "license": "Apache-2.0", "optional": true, - "peer": true, "dependencies": { "streamx": "^2.21.0" }, @@ -18700,7 +18584,6 @@ "integrity": "sha512-ZMq4gd9ngV5aTMa5p9+UfY0b3skwhHELaDkhEHetMdX0LRkW9kzaym4oo/Eh+Ghm0CCDuMTsRIGM/ytUc1ZYmw==", "license": "Apache-2.0", "optional": true, - "peer": true, "dependencies": { "bare-path": "^3.0.0" } @@ -18772,7 +18655,6 @@ "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==", "license": "MIT", - "peer": true, "engines": { "node": ">=10.0.0" } @@ -19158,6 +19040,7 @@ "url": "https://tidelift.com/funding/github/npm/browserslist" } ], + "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001449", "electron-to-chromium": "^1.4.284", @@ -19421,8 +19304,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz", "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/callsites": { "version": "3.1.0", @@ -19501,7 +19383,6 @@ "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", "dev": true, - "peer": true, "dependencies": { "assertion-error": "^1.1.0", "check-error": "^1.0.3", @@ -19520,7 +19401,6 @@ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", "dev": true, - "peer": true, "engines": { "node": ">=4" } @@ -19570,7 +19450,6 @@ "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", "dev": true, - "peer": true, "engines": { "node": "*" } @@ -19580,7 +19459,6 @@ "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", "dev": true, - "peer": true, "dependencies": { "get-func-name": "^2.0.2" }, @@ -19652,7 +19530,6 @@ "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-10.5.1.tgz", "integrity": "sha512-rlj6OyhKhVTnk4aENcUme3Jl9h+cq4oXu4AzBcvr8RMmT6BR4a3zSNT9dbIfXr9/BS6ibzRyDhowuw4n2GgzsQ==", "license": "Apache-2.0", - "peer": true, "dependencies": { "mitt": "^3.0.1", "zod": "^3.24.1" @@ -19742,7 +19619,6 @@ "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", "dev": true, - "peer": true, "dependencies": { "string-width": "^4.2.0" }, @@ -20071,7 +19947,6 @@ "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-4.2.5.tgz", "integrity": "sha512-bKw/r35jR3HGt5PEPm1ljsQQGyCrR8sFGNiN5L+ykDHdpO8Smxkrkla9Yi6NkQyUrb8V54PGhfMs6NrIwtxtdw==", "dev": true, - "peer": true, "dependencies": { "array-timsort": "^1.0.3", "core-util-is": "^1.0.3", @@ -20707,7 +20582,6 @@ "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", "dev": true, - "peer": true, "engines": { "node": "*" } @@ -20724,8 +20598,7 @@ "version": "6.3.0", "resolved": "https://registry.npmjs.org/cryptr/-/cryptr-6.3.0.tgz", "integrity": "sha512-TA4byAuorT8qooU9H8YJhBwnqD151i1rcauHfJ3Divg6HmukHB2AYMp0hmjv2873J2alr4t15QqC7zAnWFrtfQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/css-blank-pseudo": { "version": "3.0.3", @@ -21147,7 +21020,6 @@ "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", "license": "MIT", - "peer": true, "engines": { "node": ">= 14" } @@ -21311,7 +21183,6 @@ "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", "dev": true, - "peer": true, "dependencies": { "type-detect": "^4.0.0" }, @@ -21443,7 +21314,6 @@ "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", "license": "MIT", - "peer": true, "dependencies": { "ast-types": "^0.13.4", "escodegen": "^2.1.0", @@ -21534,7 +21404,6 @@ "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.6.1.tgz", "integrity": "sha512-CmnVc+Hek2egPx1PeTFVta2W78xy2K/9Rkf6cC4T59S50tVnzKj+tnx5mmx5lwvCkujZ4uRrpRSuV+IVs3f90Q==", "dev": true, - "peer": true, "dependencies": { "address": "^1.0.1", "debug": "4" @@ -21568,7 +21437,6 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", "dev": true, - "peer": true, "dependencies": { "ms": "^2.1.3" }, @@ -22647,6 +22515,7 @@ "version": "2.4.1", "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", + "peer": true, "dependencies": { "ansi-colors": "^4.1.1", "strip-ansi": "^6.0.1" @@ -22939,8 +22808,7 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", "integrity": "sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/esbuild": { "version": "0.17.8", @@ -23050,6 +22918,7 @@ "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", + "peer": true, "dependencies": { "@babel/code-frame": "7.12.11", "@eslint/eslintrc": "^0.4.3", @@ -23864,7 +23733,6 @@ "resolved": "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz", "integrity": "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==", "license": "Apache-2.0", - "peer": true, "dependencies": { "bare-events": "^2.7.0" } @@ -23954,6 +23822,7 @@ "version": "4.21.2", "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", + "peer": true, "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", @@ -24058,6 +23927,7 @@ "version": "1.18.2", "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.18.2.tgz", "integrity": "sha512-SZjssGQC7TzTs9rpPDuUrR23GNZ9+2+IkA/+IJWmvQilTr5OSliEHGF+D9scbIpdC6yGtTI0/VhaHoVes2AN/A==", + "peer": true, "dependencies": { "cookie": "0.7.2", "cookie-signature": "1.0.7", @@ -24216,8 +24086,7 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/fast-glob": { "version": "3.3.3", @@ -24259,8 +24128,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/fast-uri": { "version": "3.0.6", @@ -24552,7 +24420,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "dependencies": { "common-path-prefix": "^3.0.0", "pkg-dir": "^8.0.0" @@ -24571,7 +24438,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "dependencies": { "find-up-simple": "^1.0.0" }, @@ -24630,7 +24496,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "engines": { "node": ">=18" }, @@ -25062,7 +24927,6 @@ "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", "dev": true, - "peer": true, "engines": { "node": "*" } @@ -25231,7 +25095,6 @@ "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.5.tgz", "integrity": "sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==", "license": "MIT", - "peer": true, "dependencies": { "basic-ftp": "^5.0.2", "data-uri-to-buffer": "^6.0.2", @@ -25246,7 +25109,6 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "license": "MIT", - "peer": true, "dependencies": { "ms": "^2.1.3" }, @@ -25797,7 +25659,6 @@ "resolved": "https://registry.npmjs.org/has-own-prop/-/has-own-prop-2.0.0.tgz", "integrity": "sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==", "dev": true, - "peer": true, "engines": { "node": ">=8" } @@ -26448,8 +26309,7 @@ "version": "1.3.5", "resolved": "https://registry.npmjs.org/http2-client/-/http2-client-1.3.5.tgz", "integrity": "sha512-EC2utToWl4RKfs5zd36Mxq7nzHHBuomZboI0yYL6Y0RmBgT7Sgkq4rQ0ezFTYoIsSs7Tm9SJe+o2FcAg6GBhGA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/http2-wrapper": { "version": "1.0.3", @@ -26997,8 +26857,7 @@ "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true, - "peer": true + "dev": true }, "node_modules/is-bun-module": { "version": "1.3.0", @@ -27318,7 +27177,6 @@ "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-2.2.0.tgz", "integrity": "sha512-XVm7LOeLpTW4jV19QSH38vkswxoLud8sQ57YwJVTPWdiaI9I8keEhGFpBlslyVsgdQy4Opg8QOLb8YRgsyZiQg==", "dev": true, - "peer": true, "engines": { "node": ">=10" }, @@ -27712,7 +27570,8 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-4.0.1.tgz", "integrity": "sha512-w+JDABxQCkxbGGxg+a2hUVZyqUS2JKngvIyLGu/xiw2ZwgsoSB0iiecLQsQORSeaKQ6iGrCyWG86RfNDuoA7Lg==", - "dev": true + "dev": true, + "peer": true }, "node_modules/jasmine-spec-reporter": { "version": "5.0.2", @@ -27727,6 +27586,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", + "peer": true, "dependencies": { "@jest/core": "^29.7.0", "@jest/types": "^29.6.3", @@ -28048,6 +27908,7 @@ "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-29.7.0.tgz", "integrity": "sha512-k9iQbsf9OyOfdzWH8HDmrRT0gSIcX+FLNW7IQq94tFX0gynPwqDTW0Ho6iMVNjGz/nb+l/vW3dWM2bbLLpkbXA==", "dev": true, + "peer": true, "dependencies": { "@jest/environment": "^29.7.0", "@jest/fake-timers": "^29.7.0", @@ -29158,8 +29019,7 @@ "version": "3.7.7", "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.7.tgz", "integrity": "sha512-7rCnleh0z2CkXhH67J8K1Ytz0b2Y+yxTPL+/KOJoa20hfnVQ/3/T6W/KflYI4bRHRagNeXeU2bkNGI3v1oS/lw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/js-tokens": { "version": "4.0.0", @@ -29446,7 +29306,6 @@ "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.5.0.tgz", "integrity": "sha512-K+A9hhqbn0f3pJX17Q/7H6yQfD/5OXgdrR5UE12gMXCiN9D5Xq2o5mddV2QEcX/bjla99ASsAAQUyMCCRWAEhw==", "dev": true, - "peer": true, "engines": { "node": "*" } @@ -29551,6 +29410,7 @@ "resolved": "https://registry.npmjs.org/karma/-/karma-6.3.20.tgz", "integrity": "sha512-HRNQhMuKOwKpjYlWiJP0DUrJOh+QjaI/DTaD8b9rEm4Il3tJ8MijutVZH4ts10LuUFst/CedwTS6vieCN8yTSw==", "dev": true, + "peer": true, "dependencies": { "@colors/colors": "1.5.0", "body-parser": "^1.19.0", @@ -29890,7 +29750,6 @@ "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", "dev": true, - "peer": true, "dependencies": { "graceful-fs": "^4.1.9" } @@ -29911,6 +29770,10 @@ "node": ">= 8" } }, + "node_modules/lab-utils": { + "resolved": "samples/labUtils", + "link": true + }, "node_modules/language-subtag-registry": { "version": "0.3.23", "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", @@ -29941,6 +29804,7 @@ "resolved": "https://registry.npmjs.org/less/-/less-4.1.3.tgz", "integrity": "sha512-w16Xk/Ta9Hhyei0Gpz9m7VS8F28nieJaL/VyShID7cYvP6IL5oHeL6p4TXSDJqZE/lNv0oJ2pGVjJsRkfwm5FA==", "dev": true, + "peer": true, "dependencies": { "copy-anything": "^2.0.1", "parse-node-version": "^1.0.1", @@ -30202,12 +30066,14 @@ "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "peer": true }, "node_modules/lodash-es": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", - "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", + "peer": true }, "node_modules/lodash-unified": { "version": "1.0.3", @@ -30427,7 +30293,6 @@ "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", "dev": true, - "peer": true, "dependencies": { "get-func-name": "^2.0.1" } @@ -30493,7 +30358,6 @@ "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", "dev": true, - "peer": true, "bin": { "lz-string": "bin/bin.js" } @@ -30782,7 +30646,6 @@ "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", "dev": true, - "peer": true, "dependencies": { "charenc": "0.0.2", "crypt": "0.0.2", @@ -31232,8 +31095,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/mkcert": { "version": "3.2.0", @@ -31472,7 +31334,6 @@ "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz", "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==", "dev": true, - "peer": true, "bin": { "mustache": "bin/mustache" } @@ -31593,7 +31454,6 @@ "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", "license": "MIT", - "peer": true, "engines": { "node": ">= 0.4.0" } @@ -31602,8 +31462,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/neverthrow/-/neverthrow-3.2.0.tgz", "integrity": "sha512-AINA32QbYO83L+3CBI6I5lH4LpBSlLwWteJ+uI25s4AQy6g/xz3RZuedmuNo91lLw2rY+AbPEPQdxd7mg1rXoQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/next": { "version": "15.5.9", @@ -31693,6 +31552,7 @@ "resolved": "https://registry.npmjs.org/ng-packagr/-/ng-packagr-15.2.2.tgz", "integrity": "sha512-+042GBD35ztxbHywGJloAiDM/s3Ja3TZtQh361TWqd/xza3K5DMUu6VRGLTgMwG7CW1YsqYHWgMZslP1c+ng7A==", "dev": true, + "peer": true, "dependencies": { "@rollup/plugin-json": "^6.0.0", "@rollup/plugin-node-resolve": "^15.0.0", @@ -31992,7 +31852,6 @@ "resolved": "https://registry.npmjs.org/node-fetch-h2/-/node-fetch-h2-2.3.0.tgz", "integrity": "sha512-ofRW94Ab0T4AOh5Fk8t0h8OBWrmjb0SSB20xh1H8YnPV9EJ+f5AMoYSUQ2zgJ4Iq2HAK0I2l5/Nequ8YzFS3Hg==", "dev": true, - "peer": true, "dependencies": { "http2-client": "^1.2.5" }, @@ -32146,15 +32005,13 @@ "version": "1.1.12", "resolved": "https://registry.npmjs.org/node-machine-id/-/node-machine-id-1.1.12.tgz", "integrity": "sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/node-readfiles": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/node-readfiles/-/node-readfiles-0.2.0.tgz", "integrity": "sha512-SU00ZarexNlE4Rjdm83vglt5Y9yiQ+XI1XpflWlb7q7UTN1JUItm69xMeiQCTxtTfnzt+83T8Cx+vI2ED++VDA==", "dev": true, - "peer": true, "dependencies": { "es6-promise": "^3.2.1" } @@ -32751,7 +32608,6 @@ "resolved": "https://registry.npmjs.org/oas-kit-common/-/oas-kit-common-1.0.8.tgz", "integrity": "sha512-pJTS2+T0oGIwgjGpw7sIRU8RQMcUoKCDWFLdBqKB2BNmGpbBMH2sdqAaOXUg8OzonZHU0L7vfJu1mJFEiYDWOQ==", "dev": true, - "peer": true, "dependencies": { "fast-safe-stringify": "^2.0.7" } @@ -32761,7 +32617,6 @@ "resolved": "https://registry.npmjs.org/oas-linter/-/oas-linter-3.2.2.tgz", "integrity": "sha512-KEGjPDVoU5K6swgo9hJVA/qYGlwfbFx+Kg2QB/kd7rzV5N8N5Mg6PlsoCMohVnQmo+pzJap/F610qTodKzecGQ==", "dev": true, - "peer": true, "dependencies": { "@exodus/schemasafe": "^1.0.0-rc.2", "should": "^13.2.1", @@ -32776,7 +32631,6 @@ "resolved": "https://registry.npmjs.org/oas-resolver/-/oas-resolver-2.5.6.tgz", "integrity": "sha512-Yx5PWQNZomfEhPPOphFbZKi9W93CocQj18NlD2Pa4GWZzdZpSJvYwoiuurRI7m3SpcChrnO08hkuQDL3FGsVFQ==", "dev": true, - "peer": true, "dependencies": { "node-fetch-h2": "^2.3.0", "oas-kit-common": "^1.0.8", @@ -32796,7 +32650,6 @@ "resolved": "https://registry.npmjs.org/oas-schema-walker/-/oas-schema-walker-1.1.5.tgz", "integrity": "sha512-2yucenq1a9YPmeNExoUa9Qwrt9RFkjqaMAA1X+U7sbb0AqBeTIdMHky9SQQ6iN94bO5NW0W4TRYXerG+BdAvAQ==", "dev": true, - "peer": true, "funding": { "url": "https://github.com/Mermade/oas-kit?sponsor=1" } @@ -32806,7 +32659,6 @@ "resolved": "https://registry.npmjs.org/oas-validator/-/oas-validator-5.0.8.tgz", "integrity": "sha512-cu20/HE5N5HKqVygs3dt94eYJfBi0TsZvPVXDhbXQHiEityDN+RROTleefoKRKKJ9dFAF2JBkDHgvWj0sjKGmw==", "dev": true, - "peer": true, "dependencies": { "call-me-maybe": "^1.0.1", "oas-kit-common": "^1.0.8", @@ -33259,6 +33111,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.21.0.tgz", "integrity": "sha512-Wy+/sdEH9kI3w9civgACwabHbKl+qIOu0uFZ9IMKzX3Jpv9og0ZBJrZExGrPpFAY7rWsXuxs5e7CPPP17A4eYA==", "dev": true, + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.21.0", "@typescript-eslint/types": "8.21.0", @@ -33465,6 +33318,7 @@ "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -33587,6 +33441,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.18.0.tgz", "integrity": "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==", "dev": true, + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "7.18.0", "@typescript-eslint/types": "7.18.0", @@ -33859,6 +33714,7 @@ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz", "integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==", "dev": true, + "peer": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -33874,6 +33730,7 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", "dev": true, + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -33930,7 +33787,6 @@ "resolved": "https://registry.npmjs.org/office-addin-manifest-converter/-/office-addin-manifest-converter-0.4.1.tgz", "integrity": "sha512-2eOdCCYJ5bhCe2p9KKETdg1UNshsKaT0lDU/jNopAg3t7zC1WxwvofTSO/+4Log5L4Re+wUdV8MqrQikZBa7+Q==", "dev": true, - "peer": true, "dependencies": { "@xmldom/xmldom": "^0.8.5", "commander": "^9.0.0", @@ -33945,7 +33801,6 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", "dev": true, - "peer": true, "engines": { "node": "^12.20.0 || >=14" } @@ -33955,7 +33810,6 @@ "resolved": "https://registry.npmjs.org/terser/-/terser-5.37.0.tgz", "integrity": "sha512-B8wRRkmre4ERucLM/uXx4MOV5cbnOlVAqUst+1+iLKPI0dOgFO28f84ptoQt9HEI537PMzfYa/d+GEPKTRXmYA==", "dev": true, - "peer": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", @@ -33973,8 +33827,7 @@ "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==", - "dev": true, - "peer": true + "dev": true }, "node_modules/office-addin-manifest/node_modules/ansi-styles": { "version": "3.2.1", @@ -34123,7 +33976,6 @@ "resolved": "https://registry.npmjs.org/office-addin-project/-/office-addin-project-0.8.6.tgz", "integrity": "sha512-S93brHVDaMRZIIEibK12m6eTItoKqdy2Ep51qNhU7RaZTjH7n/C66AzdDai06UJb3I3AXfXHnKv/AJL2voGGWA==", "dev": true, - "peer": true, "dependencies": { "adm-zip": "0.5.12", "commander": "^6.2.1", @@ -34143,7 +33995,6 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", "dev": true, - "peer": true, "engines": { "node": ">= 6" } @@ -34153,7 +34004,6 @@ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", "dev": true, - "peer": true, "dependencies": { "graceful-fs": "^4.1.2", "jsonfile": "^4.0.0", @@ -34168,7 +34018,6 @@ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz", "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==", "dev": true, - "peer": true, "dependencies": { "ansi-escapes": "^4.2.1", "chalk": "^4.1.0", @@ -34193,7 +34042,6 @@ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "dev": true, - "peer": true, "optionalDependencies": { "graceful-fs": "^4.1.6" } @@ -34203,7 +34051,6 @@ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", "dev": true, - "peer": true, "dependencies": { "tslib": "^1.9.0" }, @@ -34215,15 +34062,13 @@ "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/office-addin-project/node_modules/universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true, - "peer": true, "engines": { "node": ">= 4.0.0" } @@ -34525,7 +34370,6 @@ "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.2.0.tgz", "integrity": "sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==", "license": "MIT", - "peer": true, "dependencies": { "@tootallnate/quickjs-emscripten": "^0.23.0", "agent-base": "^7.1.2", @@ -34545,7 +34389,6 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "license": "MIT", - "peer": true, "dependencies": { "ms": "^2.1.3" }, @@ -34563,7 +34406,6 @@ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", "license": "MIT", - "peer": true, "dependencies": { "agent-base": "^7.1.2", "debug": "4" @@ -34577,7 +34419,6 @@ "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", "license": "MIT", - "peer": true, "dependencies": { "agent-base": "^7.1.2", "debug": "^4.3.4", @@ -34592,7 +34433,6 @@ "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", "license": "MIT", - "peer": true, "dependencies": { "degenerator": "^5.0.0", "netmask": "^2.0.2" @@ -34977,7 +34817,6 @@ "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", "dev": true, - "peer": true, "engines": { "node": "*" } @@ -35243,6 +35082,7 @@ "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.56.1.tgz", "integrity": "sha512-hutraynyn31F+Bifme+Ps9Vq59hKuUCz7H1kDOcBs+2oGguKkWTU50bBWrtz34OUWmIwpBTWDxaRPXrIXkgvmQ==", "license": "Apache-2.0", + "peer": true, "bin": { "playwright-core": "cli.js" }, @@ -35306,6 +35146,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "nanoid": "^3.3.8", "picocolors": "^1.1.1", @@ -36146,6 +35987,7 @@ "version": "6.1.2", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -36780,6 +36622,7 @@ "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.7.tgz", "integrity": "sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw==", "dev": true, + "peer": true, "bin": { "prettier": "bin-prettier.js" }, @@ -36958,7 +36801,6 @@ "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-4.1.2.tgz", "integrity": "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==", "dev": true, - "peer": true, "dependencies": { "graceful-fs": "^4.2.4", "retry": "^0.12.0", @@ -36988,7 +36830,6 @@ "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.5.0.tgz", "integrity": "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==", "license": "MIT", - "peer": true, "dependencies": { "agent-base": "^7.1.2", "debug": "^4.3.4", @@ -37008,7 +36849,6 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "license": "MIT", - "peer": true, "dependencies": { "ms": "^2.1.3" }, @@ -37026,7 +36866,6 @@ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", "license": "MIT", - "peer": true, "dependencies": { "agent-base": "^7.1.2", "debug": "4" @@ -37040,7 +36879,6 @@ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", "license": "ISC", - "peer": true, "engines": { "node": ">=12" } @@ -37050,7 +36888,6 @@ "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", "license": "MIT", - "peer": true, "dependencies": { "agent-base": "^7.1.2", "debug": "^4.3.4", @@ -37138,7 +36975,6 @@ "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-24.29.1.tgz", "integrity": "sha512-ErJ9qKCK+bdLvBa7QVSQTBSPm8KZbl1yC/WvhrZ0ut27hDf2QBzjDsn1IukzE1i1KtZ7NYGETOV4W1beoo9izA==", "license": "Apache-2.0", - "peer": true, "dependencies": { "@puppeteer/browsers": "2.10.13", "chromium-bidi": "10.5.1", @@ -37157,7 +36993,6 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "license": "MIT", - "peer": true, "dependencies": { "ms": "^2.1.3" }, @@ -37175,7 +37010,6 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", "license": "MIT", - "peer": true, "engines": { "node": ">=10.0.0" }, @@ -37196,7 +37030,6 @@ "version": "9.0.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", - "peer": true, "dependencies": { "env-paths": "^2.2.1", "import-fresh": "^3.3.0", @@ -37406,6 +37239,7 @@ "version": "19.2.1", "resolved": "https://registry.npmjs.org/react/-/react-19.2.1.tgz", "integrity": "sha512-DGrYcCWK7tvYMnWh79yrPHt+vdx9tY+1gPZa7nJQtO/p8bLTDaHp4dzwEhQB7pZ4Xe3ok4XKuEPrVuc+wlpkmw==", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -37614,6 +37448,7 @@ "version": "19.2.1", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.1.tgz", "integrity": "sha512-ibrK8llX2a4eOskq1mXKu/TGZj9qzomO+sNfO98M6d9zIPOEhlBkMkBUBLd1vgS0gQsLDBzA+8jJBVXDnfHmJg==", + "peer": true, "dependencies": { "scheduler": "^0.27.0" }, @@ -37640,6 +37475,7 @@ "version": "0.11.0", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz", "integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -38257,6 +38093,7 @@ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -38453,6 +38290,7 @@ "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", "integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==", + "peer": true, "dependencies": { "@jest/core": "^27.5.1", "import-local": "^3.0.2", @@ -39638,6 +39476,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -39744,6 +39583,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -40428,7 +40268,6 @@ "resolved": "https://registry.npmjs.org/reftools/-/reftools-1.1.9.tgz", "integrity": "sha512-OVede/NQE13xBQ+ob5CKd5KyeJYU2YInb1bmV4nRoOfquZPkAkxuOXicSe1PvqIuZZ4kD13sPKBbR7UFDmli6w==", "dev": true, - "peer": true, "funding": { "url": "https://github.com/Mermade/oas-kit?sponsor=1" } @@ -40584,7 +40423,6 @@ "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", "dev": true, - "peer": true, "engines": { "node": ">=0.10" } @@ -40905,6 +40743,7 @@ "integrity": "sha512-tfUOg6DTP4rhQ3VjOO6B4wyrJnGOX85requAXvqYTHsOgb2TFJdZ3aWpT8W2kPoypSGP7dZUyzxJ9ee4buM5Fg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/estree": "1.0.7" }, @@ -40989,6 +40828,7 @@ "version": "7.8.1", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "peer": true, "dependencies": { "tslib": "^2.1.0" } @@ -41249,6 +41089,7 @@ "version": "8.17.1", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -41658,7 +41499,6 @@ "resolved": "https://registry.npmjs.org/should/-/should-13.2.3.tgz", "integrity": "sha512-ggLesLtu2xp+ZxI+ysJTmNjh2U0TsC+rQ/pfED9bUZZ4DKefP27D+7YJVVTvKsmjLpIi9jAa7itwDGkDDmt1GQ==", "dev": true, - "peer": true, "dependencies": { "should-equal": "^2.0.0", "should-format": "^3.0.3", @@ -41672,7 +41512,6 @@ "resolved": "https://registry.npmjs.org/should-equal/-/should-equal-2.0.0.tgz", "integrity": "sha512-ZP36TMrK9euEuWQYBig9W55WPC7uo37qzAEmbjHz4gfyuXrEUgF8cUvQVO+w+d3OMfPvSRQJ22lSm8MQJ43LTA==", "dev": true, - "peer": true, "dependencies": { "should-type": "^1.4.0" } @@ -41682,7 +41521,6 @@ "resolved": "https://registry.npmjs.org/should-format/-/should-format-3.0.3.tgz", "integrity": "sha512-hZ58adtulAk0gKtua7QxevgUaXTTXxIi8t41L3zo9AHvjXO1/7sdLECuHeIN2SRtYXpNkmhoUP2pdeWgricQ+Q==", "dev": true, - "peer": true, "dependencies": { "should-type": "^1.3.0", "should-type-adaptors": "^1.0.1" @@ -41692,15 +41530,13 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/should-type/-/should-type-1.4.0.tgz", "integrity": "sha512-MdAsTu3n25yDbIe1NeN69G4n6mUnJGtSJHygX3+oN0ZbO3DTiATnf7XnYJdGT42JCXurTb1JI0qOBR65shvhPQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/should-type-adaptors": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/should-type-adaptors/-/should-type-adaptors-1.1.0.tgz", "integrity": "sha512-JA4hdoLnN+kebEp2Vs8eBe9g7uy0zbRo+RMcU0EsNy+R+k049Ki+N5tT5Jagst2g7EAja+euFuoXFCa8vIklfA==", "dev": true, - "peer": true, "dependencies": { "should-type": "^1.3.0", "should-util": "^1.0.0" @@ -41710,8 +41546,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/should-util/-/should-util-1.0.1.tgz", "integrity": "sha512-oXF8tfxx5cDk8r2kYqlkUJzZpDBqVY/II2WhvU0n9Y3XYvAYRmeaf1PvvIvTgPnv4KJ+ES5M0PyDq5Jp+Ygy2g==", - "dev": true, - "peer": true + "dev": true }, "node_modules/shx": { "version": "0.3.4", @@ -42691,7 +42526,6 @@ "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.23.0.tgz", "integrity": "sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==", "license": "MIT", - "peer": true, "dependencies": { "events-universal": "^1.0.0", "fast-fifo": "^1.3.2", @@ -43416,7 +43250,6 @@ "resolved": "https://registry.npmjs.org/swagger2openapi/-/swagger2openapi-7.0.8.tgz", "integrity": "sha512-upi/0ZGkYgEcLeGieoz8gT74oWHA0E7JivX7aN9mAf+Tc7BQoRBvnIGHoPDw+f9TXTW4s6kGYCZJtauP6OYp7g==", "dev": true, - "peer": true, "dependencies": { "call-me-maybe": "^1.0.1", "node-fetch": "^2.6.1", @@ -43524,6 +43357,7 @@ "version": "3.4.17", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz", "integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==", + "peer": true, "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", @@ -43676,7 +43510,6 @@ "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", "optional": true, - "peer": true, "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -43719,8 +43552,7 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "optional": true, - "peer": true + "optional": true }, "node_modules/tailwindcss/node_modules/yaml": { "version": "2.7.0", @@ -44076,7 +43908,6 @@ "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz", "integrity": "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==", "license": "Apache-2.0", - "peer": true, "dependencies": { "b4a": "^1.6.4" } @@ -44392,6 +44223,7 @@ "integrity": "sha512-SaeUtjfpg9Uqu8IbeDKtdaS0g8lS6FT6OzM3ezrDfErPJPHNDo/Ey+VFGP1bQIDfagYDLyRpd7O15XpG1Es2Uw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "bs-logger": "^0.2.6", "fast-json-stable-stringify": "^2.1.0", @@ -44495,6 +44327,7 @@ "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz", "integrity": "sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==", "devOptional": true, + "peer": true, "dependencies": { "arg": "^4.1.0", "diff": "^4.0.1", @@ -44548,7 +44381,8 @@ "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "peer": true }, "node_modules/tsutils": { "version": "3.21.0", @@ -44751,6 +44585,7 @@ "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "peer": true, "engines": { "node": ">=10" }, @@ -44850,8 +44685,7 @@ "version": "2.12.0", "resolved": "https://registry.npmjs.org/typed-query-selector/-/typed-query-selector-2.12.0.tgz", "integrity": "sha512-SbklCd1F0EiZOyPiW192rrHZzZ5sBijB6xM+cpmrwDqObvdtunOHHIk9fCGsoK5JVIYXoyEp4iEdE3upFH3PAg==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/typedarray-to-buffer": { "version": "3.1.5", @@ -44865,8 +44699,7 @@ "version": "0.10.0", "resolved": "https://registry.npmjs.org/typedi/-/typedi-0.10.0.tgz", "integrity": "sha512-v3UJF8xm68BBj6AF4oQML3ikrfK2c9EmZUyLOfShpJuItAqVBHWP/KtpGinkSsIiP6EZyyb6Z3NXyW9dgS9X1w==", - "dev": true, - "peer": true + "dev": true }, "node_modules/typedoc": { "version": "0.24.8", @@ -44917,6 +44750,7 @@ "version": "4.9.5", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -45541,7 +45375,6 @@ "integrity": "sha512-KxPOq3V2LmfQPP4eqf3Mq/zrT0Dqp2Vmx2Bn285LwVahLc+CsxOM0crBHczm8ijlcjZ0Q5Xd6LW3z3odTPnlrw==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.10" } @@ -45564,6 +45397,7 @@ "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.43", @@ -46062,7 +45896,6 @@ "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==", "dev": true, - "peer": true, "engines": { "node": ">=8.0.0 || >=10.0.0" } @@ -46083,6 +45916,7 @@ "version": "3.5.13", "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.13.tgz", "integrity": "sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==", + "peer": true, "dependencies": { "@vue/compiler-dom": "3.5.13", "@vue/compiler-sfc": "3.5.13", @@ -46227,8 +46061,7 @@ "version": "0.3.8", "resolved": "https://registry.npmjs.org/webdriver-bidi-protocol/-/webdriver-bidi-protocol-0.3.8.tgz", "integrity": "sha512-21Yi2GhGntMc671vNBCjiAeEVknXjVRoyu+k+9xOMShu+ZQfpGQwnBqbNz/Sv4GXZ6JmutlPAi2nIJcrymAWuQ==", - "license": "Apache-2.0", - "peer": true + "license": "Apache-2.0" }, "node_modules/webidl-conversions": { "version": "7.0.0", @@ -46244,6 +46077,7 @@ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.102.1.tgz", "integrity": "sha512-7h/weGm9d/ywQ6qzJ+Xy+r9n/3qgp/thalBbpOi5i223dPXKi04IBtqPN9nTd+jBc7QKfvDbaBnFipYp4sJAUQ==", "license": "MIT", + "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.8", @@ -46327,6 +46161,7 @@ "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", "dev": true, + "peer": true, "dependencies": { "@discoveryjs/json-ext": "^0.5.0", "@webpack-cli/configtest": "^2.1.1", @@ -47177,6 +47012,7 @@ "version": "8.17.1", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -47276,6 +47112,7 @@ "version": "2.79.2", "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz", "integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==", + "peer": true, "bin": { "rollup": "dist/bin/rollup" }, @@ -47697,7 +47534,8 @@ "resolved": "https://registry.npmjs.org/xterm/-/xterm-4.19.0.tgz", "integrity": "sha512-c3Cp4eOVsYY5Q839dR5IejghRPpxciGmLWWaP9g+ppfMeBChMeLa1DCA+pmX/jyDZ+zxFOmlJL/82qVdayVoGQ==", "deprecated": "This package is now deprecated. Move to @xterm/xterm instead.", - "dev": true + "dev": true, + "peer": true }, "node_modules/xterm-addon-fit": { "version": "0.5.0", @@ -47968,7 +47806,6 @@ "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", "license": "MIT", - "peer": true, "funding": { "url": "https://github.com/sponsors/colinhacks" } @@ -48010,6 +47847,41 @@ "puppeteer": "^24.29.0" } }, + "samples/labUtils": { + "name": "lab-utils", + "version": "0.0.1", + "license": "MIT", + "dependencies": { + "@azure/identity": "^4.5.0", + "@azure/keyvault-secrets": "^4.8.0", + "dotenv": "^8.2.0" + }, + "devDependencies": { + "@types/node": "^20.0.0", + "typescript": "^4.9.5" + }, + "peerDependencies": { + "jest": "^29.5.0", + "puppeteer": "^24.29.0" + } + }, + "samples/labUtils/node_modules/@types/node": { + "version": "20.19.30", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.30.tgz", + "integrity": "sha512-WJtwWJu7UdlvzEAUm484QNg5eAoq5QR08KDNx7g45Usrs2NtOPiX8ugDqmKdXkyL03rBqU5dYNYVQetEpBHq2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "samples/labUtils/node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, "samples/msal-angular-samples/angular-b2c-sample": { "version": "0.0.0", "dependencies": { @@ -48325,6 +48197,7 @@ "version": "16.2.12", "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-16.2.12.tgz", "integrity": "sha512-MD0ElviEfAJY8qMOd6/jjSSvtqER2RDAi0lxe6EtUacC1DHCYkaPrKW4vLqY+tmZBg1yf+6n+uS77pXcHHcA3w==", + "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -48339,6 +48212,7 @@ "version": "16.2.14", "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-16.2.14.tgz", "integrity": "sha512-n6PrGdiVeSTEmM/HEiwIyg6YQUUymZrb5afaNLGFRM5YL0Y8OBqd+XhCjb0OfD/AfgCUtedVEPwNqrfW8KzgGw==", + "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -48390,6 +48264,7 @@ "version": "16.2.12", "resolved": "https://registry.npmjs.org/@angular/common/-/common-16.2.12.tgz", "integrity": "sha512-B+WY/cT2VgEaz9HfJitBmgdk4I333XG/ybC98CMC4Wz8E49T8yzivmmxXB3OD6qvjcOB6ftuicl6WBqLbZNg2w==", + "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -48405,6 +48280,7 @@ "version": "16.2.12", "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-16.2.12.tgz", "integrity": "sha512-6SMXUgSVekGM7R6l1Z9rCtUGtlg58GFmgbpMCsGf+VXxP468Njw8rjT2YZkf5aEPxEuRpSHhDYjqz7n14cwCXQ==", + "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -48425,6 +48301,7 @@ "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-16.2.12.tgz", "integrity": "sha512-pWSrr152562ujh6lsFZR8NfNc5Ljj+zSTQO44DsuB0tZjwEpnRcjJEgzuhGXr+CoiBf+jTSPZKemtSktDk5aaA==", "dev": true, + "peer": true, "dependencies": { "@babel/core": "7.23.2", "@jridgewell/sourcemap-codec": "^1.4.14", @@ -48539,6 +48416,7 @@ "version": "16.2.12", "resolved": "https://registry.npmjs.org/@angular/core/-/core-16.2.12.tgz", "integrity": "sha512-GLLlDeke/NjroaLYOks0uyzFVo6HyLl7VOm0K1QpLXnYvW63W9Ql/T3yguRZa7tRkOAeFZ3jw+1wnBD4O8MoUA==", + "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -48554,6 +48432,7 @@ "version": "16.2.12", "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-16.2.12.tgz", "integrity": "sha512-1Eao89hlBgLR3v8tU91vccn21BBKL06WWxl7zLpQmG6Hun+2jrThgOE4Pf3os4fkkbH4Apj0tWL2fNIWe/blbw==", + "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -48635,6 +48514,7 @@ "version": "16.2.12", "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-16.2.12.tgz", "integrity": "sha512-NnH7ju1iirmVEsUq432DTm0nZBGQsBrU40M3ZeVHMQ2subnGiyUs3QyzDz8+VWLL/T5xTxWLt9BkDn65vgzlIQ==", + "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -48691,6 +48571,7 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.9.tgz", "integrity": "sha512-G2EgeufBcYw27U4hhoIwFcgc1XU7TlXJ3mv04oOv1WCuo900U/anZSPzEqNjwdjgffkk2Gs0AN0dW1CKVLcG7w==", "dev": true, + "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.22.5", @@ -48995,7 +48876,6 @@ "os": [ "aix" ], - "peer": true, "engines": { "node": ">=12" } @@ -49403,6 +49283,7 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.16.tgz", "integrity": "sha512-vOTpLduLkZXePLxHiHsBLp98mHGnl8RptV4YAO3HfKO5UHjDvySGbxKtpYfy8Sx5+WKcgc45qNreJJRVM3L6mw==", "dev": true, + "peer": true, "dependencies": { "undici-types": "~6.19.2" } @@ -49615,7 +49496,6 @@ "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "optional": true, - "peer": true, "dependencies": { "balanced-match": "^1.0.0" } @@ -49658,7 +49538,6 @@ "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", "dev": true, "optional": true, - "peer": true, "engines": { "node": ">=16" } @@ -49975,7 +49854,6 @@ "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "dev": true, "optional": true, - "peer": true, "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", @@ -50009,7 +49887,6 @@ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", "dev": true, "optional": true, - "peer": true, "engines": { "node": ">=16 || 14 >=14.17" } @@ -50230,7 +50107,6 @@ "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "dev": true, "optional": true, - "peer": true, "dependencies": { "semver": "^6.0.0" }, @@ -50247,7 +50123,6 @@ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "optional": true, - "peer": true, "bin": { "semver": "bin/semver.js" } @@ -50277,7 +50152,6 @@ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "optional": true, - "peer": true, "dependencies": { "brace-expansion": "^2.0.1" }, @@ -50304,7 +50178,6 @@ "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", "dev": true, "optional": true, - "peer": true, "dependencies": { "minipass": "^7.0.3" }, @@ -50318,7 +50191,6 @@ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", "dev": true, "optional": true, - "peer": true, "engines": { "node": ">=16 || 14 >=14.17" } @@ -50338,7 +50210,6 @@ "integrity": "sha512-VTJ7Qtge52+1subkhmF5nOqLNbVutA8/igJ0A5vH6Mgpb8Z/3HeZomtD1SHzZF5Dqp+p+QPHE548FWYu1MdMSQ==", "dev": true, "optional": true, - "peer": true, "dependencies": { "@rollup/plugin-json": "^6.0.0", "@rollup/plugin-node-resolve": "^15.0.0", @@ -50398,7 +50269,6 @@ "os": [ "android" ], - "peer": true, "engines": { "node": ">=12" } @@ -50415,7 +50285,6 @@ "os": [ "android" ], - "peer": true, "engines": { "node": ">=12" } @@ -50432,7 +50301,6 @@ "os": [ "android" ], - "peer": true, "engines": { "node": ">=12" } @@ -50449,7 +50317,6 @@ "os": [ "darwin" ], - "peer": true, "engines": { "node": ">=12" } @@ -50466,7 +50333,6 @@ "os": [ "darwin" ], - "peer": true, "engines": { "node": ">=12" } @@ -50483,7 +50349,6 @@ "os": [ "freebsd" ], - "peer": true, "engines": { "node": ">=12" } @@ -50500,7 +50365,6 @@ "os": [ "freebsd" ], - "peer": true, "engines": { "node": ">=12" } @@ -50517,7 +50381,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=12" } @@ -50534,7 +50397,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=12" } @@ -50551,7 +50413,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=12" } @@ -50568,7 +50429,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=12" } @@ -50585,7 +50445,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=12" } @@ -50602,7 +50461,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=12" } @@ -50619,7 +50477,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=12" } @@ -50636,7 +50493,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=12" } @@ -50653,7 +50509,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=12" } @@ -50670,7 +50525,6 @@ "os": [ "netbsd" ], - "peer": true, "engines": { "node": ">=12" } @@ -50687,7 +50541,6 @@ "os": [ "openbsd" ], - "peer": true, "engines": { "node": ">=12" } @@ -50704,7 +50557,6 @@ "os": [ "sunos" ], - "peer": true, "engines": { "node": ">=12" } @@ -50721,7 +50573,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">=12" } @@ -50738,7 +50589,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">=12" } @@ -50755,7 +50605,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">=12" } @@ -50766,7 +50615,6 @@ "integrity": "sha512-B+L5iIa9mgcjLbliir2th36yEwPftrzteHYujzsx3dFP/31GCHcIeS8f5MGd80odLOjaOvSpU3EEAmRQptkxLQ==", "dev": true, "optional": true, - "peer": true, "dependencies": { "@npmcli/fs": "^3.1.0", "fs-minipass": "^3.0.0", @@ -50790,8 +50638,7 @@ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true, - "optional": true, - "peer": true + "optional": true }, "samples/msal-angular-samples/angular-b2c-sample/node_modules/ng-packagr/node_modules/esbuild": { "version": "0.19.12", @@ -50800,7 +50647,6 @@ "dev": true, "hasInstallScript": true, "optional": true, - "peer": true, "bin": { "esbuild": "bin/esbuild" }, @@ -50839,7 +50685,6 @@ "integrity": "sha512-Zmc4hk6FibJZBcTx5/8K/4jT3/oG1vkGTEeKJUQFCUQKimD6Q7+adp/bdVQyYJFolMKaXkQnVZdV4O5ZaTYmyQ==", "dev": true, "optional": true, - "peer": true, "bin": { "esbuild": "bin/esbuild" }, @@ -50853,7 +50698,6 @@ "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", "dev": true, "optional": true, - "peer": true, "dependencies": { "commondir": "^1.0.1", "make-dir": "^3.0.2", @@ -50872,7 +50716,6 @@ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "optional": true, - "peer": true, "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -50887,7 +50730,6 @@ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "optional": true, - "peer": true, "dependencies": { "p-locate": "^4.1.0" }, @@ -50900,8 +50742,7 @@ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", "dev": true, - "optional": true, - "peer": true + "optional": true }, "samples/msal-angular-samples/angular-b2c-sample/node_modules/ng-packagr/node_modules/minipass": { "version": "7.1.2", @@ -50909,7 +50750,6 @@ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", "dev": true, "optional": true, - "peer": true, "engines": { "node": ">=16 || 14 >=14.17" } @@ -50920,7 +50760,6 @@ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "optional": true, - "peer": true, "dependencies": { "p-try": "^2.0.0" }, @@ -50937,7 +50776,6 @@ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "optional": true, - "peer": true, "dependencies": { "p-limit": "^2.2.0" }, @@ -50951,7 +50789,6 @@ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, "optional": true, - "peer": true, "engines": { "node": ">=8" } @@ -50962,7 +50799,6 @@ "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, "optional": true, - "peer": true, "dependencies": { "find-up": "^4.0.0" }, @@ -51114,6 +50950,7 @@ "url": "https://github.com/sponsors/ai" } ], + "peer": true, "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", @@ -51431,7 +51268,8 @@ "samples/msal-angular-samples/angular-b2c-sample/node_modules/tslib": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz", - "integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==" + "integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==", + "peer": true }, "samples/msal-angular-samples/angular-b2c-sample/node_modules/vite": { "version": "4.5.5", @@ -51439,6 +51277,7 @@ "integrity": "sha512-ifW3Lb2sMdX+WU91s3R0FyQlAyLxOzCSCP37ujw0+r5POeHPwe6udWVIElKQq8gk3t7b8rkmvqC6IHBpCff4GQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.18.10", "postcss": "^8.4.27", @@ -51515,6 +51354,7 @@ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz", "integrity": "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==", "dev": true, + "peer": true, "dependencies": { "@types/estree": "^1.0.5", "@webassemblyjs/ast": "^1.12.1", @@ -51561,6 +51401,7 @@ "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.1.tgz", "integrity": "sha512-5hbAst3h3C3L8w6W4P96L5vaV0PxSmJhxZvWKYIdgxOQm8pNZ5dEOmmSLBVpP85ReeyRt6AS1QJNyo/oFFPeVA==", "dev": true, + "peer": true, "dependencies": { "@types/bonjour": "^3.5.9", "@types/connect-history-api-fallback": "^1.3.5", @@ -51769,6 +51610,7 @@ "version": "0.13.3", "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.13.3.tgz", "integrity": "sha512-MKPbmZie6fASC/ps4dkmIhaT5eonHkEt6eAy80K42tAm0G2W+AahLJjbfi6X9NPdciOE9GRFTTM8u2IiF6O3ww==", + "peer": true, "dependencies": { "tslib": "^2.3.0" } @@ -52082,6 +51924,7 @@ "version": "16.2.12", "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-16.2.12.tgz", "integrity": "sha512-MD0ElviEfAJY8qMOd6/jjSSvtqER2RDAi0lxe6EtUacC1DHCYkaPrKW4vLqY+tmZBg1yf+6n+uS77pXcHHcA3w==", + "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -52148,6 +51991,7 @@ "version": "16.2.12", "resolved": "https://registry.npmjs.org/@angular/common/-/common-16.2.12.tgz", "integrity": "sha512-B+WY/cT2VgEaz9HfJitBmgdk4I333XG/ybC98CMC4Wz8E49T8yzivmmxXB3OD6qvjcOB6ftuicl6WBqLbZNg2w==", + "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -52163,6 +52007,7 @@ "version": "16.2.12", "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-16.2.12.tgz", "integrity": "sha512-6SMXUgSVekGM7R6l1Z9rCtUGtlg58GFmgbpMCsGf+VXxP468Njw8rjT2YZkf5aEPxEuRpSHhDYjqz7n14cwCXQ==", + "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -52183,6 +52028,7 @@ "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-16.2.12.tgz", "integrity": "sha512-pWSrr152562ujh6lsFZR8NfNc5Ljj+zSTQO44DsuB0tZjwEpnRcjJEgzuhGXr+CoiBf+jTSPZKemtSktDk5aaA==", "dev": true, + "peer": true, "dependencies": { "@babel/core": "7.23.2", "@jridgewell/sourcemap-codec": "^1.4.14", @@ -52297,6 +52143,7 @@ "version": "16.2.12", "resolved": "https://registry.npmjs.org/@angular/core/-/core-16.2.12.tgz", "integrity": "sha512-GLLlDeke/NjroaLYOks0uyzFVo6HyLl7VOm0K1QpLXnYvW63W9Ql/T3yguRZa7tRkOAeFZ3jw+1wnBD4O8MoUA==", + "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -52312,6 +52159,7 @@ "version": "16.2.12", "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-16.2.12.tgz", "integrity": "sha512-1Eao89hlBgLR3v8tU91vccn21BBKL06WWxl7zLpQmG6Hun+2jrThgOE4Pf3os4fkkbH4Apj0tWL2fNIWe/blbw==", + "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -52393,6 +52241,7 @@ "version": "16.2.12", "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-16.2.12.tgz", "integrity": "sha512-NnH7ju1iirmVEsUq432DTm0nZBGQsBrU40M3ZeVHMQ2subnGiyUs3QyzDz8+VWLL/T5xTxWLt9BkDn65vgzlIQ==", + "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -52449,6 +52298,7 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.9.tgz", "integrity": "sha512-G2EgeufBcYw27U4hhoIwFcgc1XU7TlXJ3mv04oOv1WCuo900U/anZSPzEqNjwdjgffkk2Gs0AN0dW1CKVLcG7w==", "dev": true, + "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.22.5", @@ -52753,7 +52603,6 @@ "os": [ "aix" ], - "peer": true, "engines": { "node": ">=12" } @@ -53364,7 +53213,6 @@ "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "optional": true, - "peer": true, "dependencies": { "balanced-match": "^1.0.0" } @@ -53418,7 +53266,6 @@ "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", "dev": true, "optional": true, - "peer": true, "engines": { "node": ">=16" } @@ -53817,7 +53664,8 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-4.5.0.tgz", "integrity": "sha512-9PMzyvhtocxb3aXJVOPqBDswdgyAeSB81QnLop4npOpbqnheaTEwPc9ZloQeVswugPManznQBjD8kWDTjlnHuw==", - "dev": true + "dev": true, + "peer": true }, "samples/msal-angular-samples/angular-modules-sample/node_modules/jsdom": { "version": "16.7.0", @@ -53903,6 +53751,7 @@ "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.4.tgz", "integrity": "sha512-LrtUxbdvt1gOpo3gxG+VAJlJAEMhbWlM4YrFQgql98FwF7+K8K12LYO4hnDdUkNjeztYrOXEMqgTajSWgmtI/w==", "dev": true, + "peer": true, "dependencies": { "@colors/colors": "1.5.0", "body-parser": "^1.19.0", @@ -53941,6 +53790,7 @@ "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-5.1.0.tgz", "integrity": "sha512-i/zQLFrfEpRyQoJF9fsCdTMOF5c2dK7C7OmsuKg2D0YSsuZSfQDiLuaiktbuio6F2wiCsZSnSnieIQ0ant/uzQ==", "dev": true, + "peer": true, "dependencies": { "jasmine-core": "^4.1.0" }, @@ -54034,7 +53884,6 @@ "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "dev": true, "optional": true, - "peer": true, "dependencies": { "semver": "^6.0.0" }, @@ -54051,7 +53900,6 @@ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "optional": true, - "peer": true, "bin": { "semver": "bin/semver.js" } @@ -54091,7 +53939,6 @@ "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", "dev": true, "optional": true, - "peer": true, "dependencies": { "minipass": "^7.0.3" }, @@ -54105,7 +53952,6 @@ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", "dev": true, "optional": true, - "peer": true, "engines": { "node": ">=16 || 14 >=14.17" } @@ -54137,7 +53983,6 @@ "integrity": "sha512-VTJ7Qtge52+1subkhmF5nOqLNbVutA8/igJ0A5vH6Mgpb8Z/3HeZomtD1SHzZF5Dqp+p+QPHE548FWYu1MdMSQ==", "dev": true, "optional": true, - "peer": true, "dependencies": { "@rollup/plugin-json": "^6.0.0", "@rollup/plugin-node-resolve": "^15.0.0", @@ -54197,7 +54042,6 @@ "os": [ "android" ], - "peer": true, "engines": { "node": ">=12" } @@ -54214,7 +54058,6 @@ "os": [ "android" ], - "peer": true, "engines": { "node": ">=12" } @@ -54231,7 +54074,6 @@ "os": [ "android" ], - "peer": true, "engines": { "node": ">=12" } @@ -54248,7 +54090,6 @@ "os": [ "darwin" ], - "peer": true, "engines": { "node": ">=12" } @@ -54265,7 +54106,6 @@ "os": [ "darwin" ], - "peer": true, "engines": { "node": ">=12" } @@ -54282,7 +54122,6 @@ "os": [ "freebsd" ], - "peer": true, "engines": { "node": ">=12" } @@ -54299,7 +54138,6 @@ "os": [ "freebsd" ], - "peer": true, "engines": { "node": ">=12" } @@ -54316,7 +54154,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=12" } @@ -54333,7 +54170,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=12" } @@ -54350,7 +54186,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=12" } @@ -54367,7 +54202,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=12" } @@ -54384,7 +54218,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=12" } @@ -54401,7 +54234,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=12" } @@ -54418,7 +54250,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=12" } @@ -54435,7 +54266,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=12" } @@ -54452,7 +54282,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=12" } @@ -54469,7 +54298,6 @@ "os": [ "netbsd" ], - "peer": true, "engines": { "node": ">=12" } @@ -54486,7 +54314,6 @@ "os": [ "openbsd" ], - "peer": true, "engines": { "node": ">=12" } @@ -54503,7 +54330,6 @@ "os": [ "sunos" ], - "peer": true, "engines": { "node": ">=12" } @@ -54520,7 +54346,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">=12" } @@ -54537,7 +54362,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">=12" } @@ -54554,7 +54378,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">=12" } @@ -54565,7 +54388,6 @@ "integrity": "sha512-B+L5iIa9mgcjLbliir2th36yEwPftrzteHYujzsx3dFP/31GCHcIeS8f5MGd80odLOjaOvSpU3EEAmRQptkxLQ==", "dev": true, "optional": true, - "peer": true, "dependencies": { "@npmcli/fs": "^3.1.0", "fs-minipass": "^3.0.0", @@ -54589,8 +54411,7 @@ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true, - "optional": true, - "peer": true + "optional": true }, "samples/msal-angular-samples/angular-modules-sample/node_modules/ng-packagr/node_modules/esbuild": { "version": "0.19.12", @@ -54599,7 +54420,6 @@ "dev": true, "hasInstallScript": true, "optional": true, - "peer": true, "bin": { "esbuild": "bin/esbuild" }, @@ -54638,7 +54458,6 @@ "integrity": "sha512-Zmc4hk6FibJZBcTx5/8K/4jT3/oG1vkGTEeKJUQFCUQKimD6Q7+adp/bdVQyYJFolMKaXkQnVZdV4O5ZaTYmyQ==", "dev": true, "optional": true, - "peer": true, "bin": { "esbuild": "bin/esbuild" }, @@ -54652,7 +54471,6 @@ "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", "dev": true, "optional": true, - "peer": true, "dependencies": { "commondir": "^1.0.1", "make-dir": "^3.0.2", @@ -54671,7 +54489,6 @@ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "optional": true, - "peer": true, "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -54686,7 +54503,6 @@ "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "dev": true, "optional": true, - "peer": true, "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", @@ -54708,7 +54524,6 @@ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "optional": true, - "peer": true, "dependencies": { "p-locate": "^4.1.0" }, @@ -54721,8 +54536,7 @@ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", "dev": true, - "optional": true, - "peer": true + "optional": true }, "samples/msal-angular-samples/angular-modules-sample/node_modules/ng-packagr/node_modules/minimatch": { "version": "9.0.5", @@ -54730,7 +54544,6 @@ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "optional": true, - "peer": true, "dependencies": { "brace-expansion": "^2.0.1" }, @@ -54747,7 +54560,6 @@ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", "dev": true, "optional": true, - "peer": true, "engines": { "node": ">=16 || 14 >=14.17" } @@ -54758,7 +54570,6 @@ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "optional": true, - "peer": true, "dependencies": { "p-try": "^2.0.0" }, @@ -54775,7 +54586,6 @@ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "optional": true, - "peer": true, "dependencies": { "p-limit": "^2.2.0" }, @@ -54789,7 +54599,6 @@ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, "optional": true, - "peer": true, "engines": { "node": ">=8" } @@ -54800,7 +54609,6 @@ "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, "optional": true, - "peer": true, "dependencies": { "find-up": "^4.0.0" }, @@ -54876,7 +54684,6 @@ "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz", "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==", "optional": true, - "peer": true, "dependencies": { "entities": "^4.5.0" }, @@ -54953,6 +54760,7 @@ "url": "https://github.com/sponsors/ai" } ], + "peer": true, "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", @@ -55279,7 +55087,8 @@ "samples/msal-angular-samples/angular-modules-sample/node_modules/tslib": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz", - "integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==" + "integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==", + "peer": true }, "samples/msal-angular-samples/angular-modules-sample/node_modules/vite": { "version": "4.5.5", @@ -55287,6 +55096,7 @@ "integrity": "sha512-ifW3Lb2sMdX+WU91s3R0FyQlAyLxOzCSCP37ujw0+r5POeHPwe6udWVIElKQq8gk3t7b8rkmvqC6IHBpCff4GQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.18.10", "postcss": "^8.4.27", @@ -55363,6 +55173,7 @@ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz", "integrity": "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==", "dev": true, + "peer": true, "dependencies": { "@types/estree": "^1.0.5", "@webassemblyjs/ast": "^1.12.1", @@ -55409,6 +55220,7 @@ "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.1.tgz", "integrity": "sha512-5hbAst3h3C3L8w6W4P96L5vaV0PxSmJhxZvWKYIdgxOQm8pNZ5dEOmmSLBVpP85ReeyRt6AS1QJNyo/oFFPeVA==", "dev": true, + "peer": true, "dependencies": { "@types/bonjour": "^3.5.9", "@types/connect-history-api-fallback": "^1.3.5", @@ -55626,6 +55438,7 @@ "version": "0.13.3", "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.13.3.tgz", "integrity": "sha512-MKPbmZie6fASC/ps4dkmIhaT5eonHkEt6eAy80K42tAm0G2W+AahLJjbfi6X9NPdciOE9GRFTTM8u2IiF6O3ww==", + "peer": true, "dependencies": { "tslib": "^2.3.0" } @@ -55777,6 +55590,7 @@ "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-20.0.4.tgz", "integrity": "sha512-s0kRcEply2A1ThvFmb0+o+hEpAbPn08lpK8xjWZryM4cMrwjgsUE0OZHZPBANP4I1xT7Z82l+fmQbH+vX48EyA==", "license": "MIT", + "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -55982,6 +55796,7 @@ "resolved": "https://registry.npmjs.org/@angular/common/-/common-20.0.4.tgz", "integrity": "sha512-fWgxe2rgSKgI36ummBYnBN4YUrmp4CHbfEG3RMeJho/vhHKguk2/o6BgL9zvnKybvbWmuaqbkHogi+y0LeJ8Ww==", "license": "MIT", + "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -55998,6 +55813,7 @@ "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-20.0.4.tgz", "integrity": "sha512-1bP3P8Ll/KUYMPiE6TDjkMXkqCDVgSUAUsVCgzAxz4mcMuc9PnlbhQazpWHCkCDIjGFZ5XIAsS49V7tfaTbLDw==", "license": "MIT", + "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -56011,6 +55827,7 @@ "integrity": "sha512-2FP1WMRexAMcDPNE3YO3zB++sCgND9O/qJC5rgKbAebpbmOrCDMUBRlftkwiLT+UhTM9PjhTtAGtK7C+2iwx1g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/core": "7.27.4", "@jridgewell/sourcemap-codec": "^1.4.14", @@ -56246,6 +56063,7 @@ "resolved": "https://registry.npmjs.org/@angular/core/-/core-20.0.4.tgz", "integrity": "sha512-JhSl3B6CrJ9kegLffgWVFGF4D4bWLV/9r8R0+h78vU+ppdPFPWDha7WnirF31cPIg3pBzy6wn103Kcy9Ri5M5w==", "license": "MIT", + "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -56271,6 +56089,7 @@ "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-20.0.4.tgz", "integrity": "sha512-bFTMgJSHiLr80ELymRykZW6o5QroDlk+g5AFFiY9yxM8I0DV5YpCNBefv8GiuWubE+Lw6LkQ/HMYeXYJMTue3A==", "license": "MIT", + "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -56306,6 +56125,7 @@ "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-20.0.4.tgz", "integrity": "sha512-hMJYvtZlNPh4Tt6JrnK+vmBmHWok04EkuJwyPcPhlle1u6/LihuCj4suELLqCanX9EzyNgvyKnws0i6JE/qh8Q==", "license": "MIT", + "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -57644,6 +57464,7 @@ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dev": true, + "peer": true, "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -57797,7 +57618,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "engines": { "node": ">=20" } @@ -57827,7 +57647,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "engines": { "node": ">=4" } @@ -58077,6 +57896,7 @@ "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.4.tgz", "integrity": "sha512-LrtUxbdvt1gOpo3gxG+VAJlJAEMhbWlM4YrFQgql98FwF7+K8K12LYO4hnDdUkNjeztYrOXEMqgTajSWgmtI/w==", "dev": true, + "peer": true, "dependencies": { "@colors/colors": "1.5.0", "body-parser": "^1.19.0", @@ -58174,7 +57994,6 @@ "dev": true, "license": "Apache-2.0", "optional": true, - "peer": true, "dependencies": { "copy-anything": "^2.0.1", "parse-node-version": "^1.0.1", @@ -58203,7 +58022,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "bin": { "mime": "cli.js" }, @@ -58218,7 +58036,6 @@ "dev": true, "license": "BSD-3-Clause", "optional": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -58603,7 +58420,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "dependencies": { "@ampproject/remapping": "^2.3.0", "@rollup/plugin-json": "^6.1.0", @@ -58655,7 +58471,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "dependencies": { "readdirp": "^4.0.1" }, @@ -58673,7 +58488,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "engines": { "node": ">= 14.18.0" }, @@ -58689,7 +58503,6 @@ "dev": true, "license": "LGPL-3.0-only", "optional": true, - "peer": true, "dependencies": { "magic-string": "^0.30.17" }, @@ -59139,6 +58952,7 @@ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", "license": "Apache-2.0", + "peer": true, "dependencies": { "tslib": "^2.1.0" } @@ -59237,7 +59051,6 @@ "dev": true, "license": "BSD-2-Clause", "optional": true, - "peer": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", @@ -59257,8 +59070,7 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true, "license": "MIT", - "optional": true, - "peer": true + "optional": true }, "samples/msal-angular-samples/angular-standalone-sample/node_modules/tmp": { "version": "0.2.5", @@ -59291,6 +59103,7 @@ "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -59341,6 +59154,7 @@ "integrity": "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", @@ -59459,7 +59273,8 @@ "samples/msal-angular-samples/angular-standalone-sample/node_modules/zone.js": { "version": "0.15.0", "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.15.0.tgz", - "integrity": "sha512-9oxn0IIjbCZkJ67L+LkhYWRyAy7axphb3VgE2MBDlOqnmHMPWGYMxJxBYFueFq/JGY2GMwS0rU+UCLunEmy5UA==" + "integrity": "sha512-9oxn0IIjbCZkJ67L+LkhYWRyAy7axphb3VgE2MBDlOqnmHMPWGYMxJxBYFueFq/JGY2GMwS0rU+UCLunEmy5UA==", + "peer": true }, "samples/msal-browser-samples/ExpressSample": { "name": "express-sample", @@ -61201,6 +61016,7 @@ "e2e-test-utils": "file:../../e2eTestUtils", "jest": "^29.5.0", "jest-junit": "^16.0.0", + "lab-utils": "file:../../labUtils", "ts-jest": "^29.1.0" } }, @@ -61284,6 +61100,7 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.74.tgz", "integrity": "sha512-HMwEkkifei3L605gFdV+/UwtpxP6JSzM+xFk2Ia6DNFSwSVBRh9qp5Tgf4lNFOMfPVuU0WnkcWpXZpgn5ufO4A==", "dev": true, + "peer": true, "dependencies": { "undici-types": "~5.26.4" } @@ -61549,6 +61366,7 @@ "e2e-test-utils": "file:../../e2eTestUtils", "jest": "^29.5.0", "jest-junit": "^16.0.0", + "lab-utils": "file:../../labUtils", "ts-jest": "^29.1.0" } }, @@ -61577,6 +61395,7 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.74.tgz", "integrity": "sha512-HMwEkkifei3L605gFdV+/UwtpxP6JSzM+xFk2Ia6DNFSwSVBRh9qp5Tgf4lNFOMfPVuU0WnkcWpXZpgn5ufO4A==", "dev": true, + "peer": true, "dependencies": { "undici-types": "~5.26.4" } @@ -61986,6 +61805,7 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz", "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==", "dev": true, + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -62024,6 +61844,7 @@ "@types/jest": "^29.5.0", "e2e-test-utils": "file:../../e2eTestUtils", "jest": "^29.5.0", + "lab-utils": "file:../../labUtils", "ts-jest": "^29.1.0" } }, @@ -62055,6 +61876,7 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.74.tgz", "integrity": "sha512-HMwEkkifei3L605gFdV+/UwtpxP6JSzM+xFk2Ia6DNFSwSVBRh9qp5Tgf4lNFOMfPVuU0WnkcWpXZpgn5ufO4A==", "dev": true, + "peer": true, "dependencies": { "undici-types": "~5.26.4" } @@ -62235,6 +62057,7 @@ "e2e-test-utils": "file:../../e2eTestUtils", "jest": "^29.5.0", "jest-junit": "^16.0.0", + "lab-utils": "file:../../labUtils", "ts-jest": "^29.1.0" } }, diff --git a/package.json b/package.json index 3fc2fadda9..711abd298e 100644 --- a/package.json +++ b/package.json @@ -57,6 +57,7 @@ "extensions/samples/*", "shared-test-utils", "samples/e2eTestUtils", + "samples/labUtils", "samples/msal-browser-samples/*", "samples/msal-angular-samples/*", "samples/msal-react-samples/*", diff --git a/samples/e2eTestUtils/src/AppConfig.ts b/samples/e2eTestUtils/src/AppConfig.ts new file mode 100644 index 0000000000..51d4850b6b --- /dev/null +++ b/samples/e2eTestUtils/src/AppConfig.ts @@ -0,0 +1,31 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. + */ + +/** + * Represents application configuration retrieved from Key Vault. + * This maps to the 'app' property in Key Vault secret JSON. + */ +export type AppConfig = { + /** The application (client) ID registered in Azure AD */ + appId?: string; + + /** The redirect URI configured for the application */ + redirectUri?: string; + + /** The authority URL (e.g., "https://login.microsoftonline.com/{tenantId}") */ + authority?: string; + + /** The default scopes for the application (space-separated) */ + defaultScopes?: string; + + /** The tenant ID where the application is registered */ + tenantId?: string; + + /** The Azure environment (e.g., "azurecloud", "azureusgovernment") */ + environment?: string; + + /** The name of the Key Vault secret containing the app's client secret */ + secretName?: string; +}; diff --git a/samples/e2eTestUtils/src/KeyVaultSecrets.ts b/samples/e2eTestUtils/src/KeyVaultSecrets.ts new file mode 100644 index 0000000000..b93beeaeab --- /dev/null +++ b/samples/e2eTestUtils/src/KeyVaultSecrets.ts @@ -0,0 +1,42 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. + */ + +/** + * Contains names of secrets stored in Azure Key Vault for lab configuration. + * These secrets contain JSON-serialized configuration objects for users, apps, and lab environments. + */ +export const KeyVaultSecrets = { + // Names of key vault secrets for user configuration JSONs + UserPublicCloud: "User-PublicCloud-Config", + UserFederated: "User-Federated-Config", + UserPublicCloud2: "MSAL-User-Default2-JSON", + UserB2C: "MSAL-USER-B2C-JSON", + UserArlington: "MSAL-USER-Arlington-JSON", + UserCiam: "MSAL-USER-CIAM-JSON", + UserPop: "MSAL-User-POP-JSON", + + // Names of key vault secrets for application configuration JSONs + // - Broad test scenarios + AppS2S: "App-S2S-Config", + AppPCAClient: "App-PCAClient-Config", + AppWebApi: "App-WebApi-Config", + AppWebApp: "App-WebApp-Config", + // - More specific test scenarios, edge cases, etc. + B2CAppIdLabsAppB2C: "MSAL-App-B2C-JSON", + ArlAppIdLabsApp: "MSAL-App-Arlington-JSON", + MsalAppCiam: "MSAL-App-CIAM-JSON", + MsalAppAzureAdMultipleOrgsRegional: + "MSAL-APP-AzureADMultipleOrgsRegional-JSON", + MsalAppArlingtonCCA: "MSAL-App-ArlingtonCCA-JSON", + + // Name of key vault secrets for specific test scenarios + MsalOboSecret: "IdentityDivisionDotNetOBOServiceSecret", + + // Name of key vault secrets for app secrets and certificates + DefaultAppSecret: "MSAL-App-Default", +} as const; + +export type KeyVaultSecretName = + (typeof KeyVaultSecrets)[keyof typeof KeyVaultSecrets]; diff --git a/samples/e2eTestUtils/src/KeyVaultSecretsProvider.ts b/samples/e2eTestUtils/src/KeyVaultSecretsProvider.ts new file mode 100644 index 0000000000..8c0e307e91 --- /dev/null +++ b/samples/e2eTestUtils/src/KeyVaultSecretsProvider.ts @@ -0,0 +1,313 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. + */ + +import { SecretClient, KeyVaultSecret } from "@azure/keyvault-secrets"; +import { ClientCertificateCredential } from "@azure/identity"; +import * as fs from "fs"; +import * as crypto from "crypto"; +import * as dotenv from "dotenv"; + +// Load environment variables from .env file +// Try 1p repo config first +dotenv.config({ path: __dirname + `/../../../../.env` }); +// If CLIENT_ID is not set, try the 3p repo for test env config +if (!process.env["AZURE_CLIENT_ID"]) { + dotenv.config({ path: __dirname + `/../../../.env` }); +} + +/** + * Key Vault URLs for lab infrastructure. + */ +export const KeyVaultInstance = { + /** + * This Key Vault is generally used for frequently rotated credentials (e.g., user passwords). + */ + MSIDLab: "https://msidlabs.vault.azure.net", + + /** + * This Key Vault is generally used for static configuration (user/app configs, app secrets). + */ + MsalTeam: "https://id4skeyvault.vault.azure.net", +} as const; + +/** + * Environment variable names for lab authentication. + */ +const EnvVariables = { + TENANT: "AZURE_TENANT_ID", + CLIENT_ID: "AZURE_CLIENT_ID", + CERTIFICATE_PATH: "AZURE_CLIENT_CERTIFICATE_PATH", +} as const; + +/** + * Certificate credential information that can be used for MSAL ConfidentialClientApplication. + */ +export type LabCertificateCredential = { + /** The client ID of the lab authentication app */ + clientId: string; + /** The tenant ID for lab authentication */ + tenantId: string; + /** The SHA-256 thumbprint of the certificate */ + thumbprintSha256: string; + /** The private key in PEM format */ + privateKey: string; + /** The certificate chain (x5c) in PEM format */ + x5c: string; +}; + +/** Cached lab credential (extracted once, reused across all tests) */ +let cachedLabCredential: LabCertificateCredential | null = null; + +/** Cached ClientCertificateCredential for Key Vault access */ +let cachedKeyVaultCredential: ClientCertificateCredential | null = null; + +/** + * Extracts certificate information from a PEM file containing both certificate and private key. + * @param pemContent - The PEM content as a string + * @returns Certificate credential information (thumbprint, privateKey, x5c) + */ +function extractCertificateInfoFromPem(pemContent: string): { + thumbprintSha256: string; + privateKey: string; + x5c: string; +} { + // Extract private key (supports both PKCS#8 and PKCS#1 formats) + const privateKeyMatch = pemContent.match( + /-----BEGIN PRIVATE KEY-----[\s\S]*?-----END PRIVATE KEY-----/ + ); + const rsaPrivateKeyMatch = pemContent.match( + /-----BEGIN RSA PRIVATE KEY-----[\s\S]*?-----END RSA PRIVATE KEY-----/ + ); + const privateKey = privateKeyMatch?.[0] || rsaPrivateKeyMatch?.[0]; + + if (!privateKey) { + throw new Error("No private key found in PEM content"); + } + + // Extract all certificates (there may be a chain) + const certMatches = pemContent.match( + /-----BEGIN CERTIFICATE-----[\s\S]*?-----END CERTIFICATE-----/g + ); + + if (!certMatches || certMatches.length === 0) { + throw new Error("No certificate found in PEM content"); + } + + // The first certificate should be the leaf certificate + const leafCert = certMatches[0]; + const x5c = certMatches.join("\n"); + + // Calculate SHA-256 thumbprint from the leaf certificate + const certDer = Buffer.from( + leafCert + .replace(/-----BEGIN CERTIFICATE-----/g, "") + .replace(/-----END CERTIFICATE-----/g, "") + .replace(/\s/g, ""), + "base64" + ); + const thumbprintSha256 = crypto + .createHash("sha256") + .update(certDer) + .digest("hex") + .toUpperCase(); + + return { + thumbprintSha256, + privateKey, + x5c, + }; +} + +/** + * Gets the ClientCertificateCredential for authenticating with Azure Key Vault. + * Uses the certificate path from environment variables (expects PEM format). + * This follows the same pattern as LabClient. + * + * @returns ClientCertificateCredential for Key Vault access + * @throws Error if required environment variables are not set + */ +function getKeyVaultCredential(): ClientCertificateCredential { + if (cachedKeyVaultCredential) { + return cachedKeyVaultCredential; + } + + const tenant = process.env[EnvVariables.TENANT]; + const clientId = process.env[EnvVariables.CLIENT_ID]; + const certPath = process.env[EnvVariables.CERTIFICATE_PATH]; + + if (!tenant || !clientId || !certPath) { + throw new Error( + `Environment variables not set! Required: ${EnvVariables.TENANT}, ${EnvVariables.CLIENT_ID}, ${EnvVariables.CERTIFICATE_PATH}` + ); + } + + if (!fs.existsSync(certPath)) { + throw new Error(`Certificate file not found at ${certPath}`); + } + + cachedKeyVaultCredential = new ClientCertificateCredential( + tenant, + clientId, + certPath, + { + sendCertificateChain: true, + } + ); + + return cachedKeyVaultCredential; +} + +/** + * Provides access to Azure Key Vault secrets using certificate-based authentication. + * This class manages connections to Key Vault and provides methods to retrieve secrets. + * + * Authentication uses ClientCertificateCredential with a PEM certificate file, + * following the same pattern as LabClient in e2eTestUtils. + */ +export class KeyVaultSecretsProvider { + private secretClient: SecretClient; + private keyVaultAddress: string; + + /** + * Creates a new KeyVaultSecretsProvider instance. + * @param keyVaultAddress - The URL of the Key Vault (defaults to MSIDLab Key Vault) + */ + constructor(keyVaultAddress: string = KeyVaultInstance.MSIDLab) { + this.keyVaultAddress = keyVaultAddress; + const credential = getKeyVaultCredential(); + this.secretClient = new SecretClient(keyVaultAddress, credential); + } + + /** + * Gets the Key Vault address this provider is connected to. + */ + getKeyVaultAddress(): string { + return this.keyVaultAddress; + } + + /** + * Retrieves a secret from Key Vault by name. + * @param secretName - The name of the secret to retrieve + * @returns The Key Vault secret + */ + async getSecretByName(secretName: string): Promise { + return await this.secretClient.getSecret(secretName); + } + + /** + * Retrieves a secret from Key Vault by name and version. + * @param secretName - The name of the secret to retrieve + * @param secretVersion - The specific version of the secret + * @returns The Key Vault secret + */ + async getSecretByNameAndVersion( + secretName: string, + secretVersion: string + ): Promise { + return await this.secretClient.getSecret(secretName, { + version: secretVersion, + }); + } + + /** + * Retrieves the value of a secret from Key Vault. + * @param secretName - The name of the secret to retrieve + * @returns The secret value as a string + * @throws Error if the secret is not found or has no value + */ + async getSecretValue(secretName: string): Promise { + const secret = await this.getSecretByName(secretName); + if (!secret.value) { + throw new Error(`Secret '${secretName}' found but has no value`); + } + return secret.value; + } +} + +/** + * Singleton instances of KeyVaultSecretsProvider for each Key Vault. + * These are lazily initialized on first access. + */ +let msidLabProvider: KeyVaultSecretsProvider | null = null; +let msalTeamProvider: KeyVaultSecretsProvider | null = null; + +/** + * Gets a KeyVaultSecretsProvider instance for the MSID Lab Key Vault. + * This Key Vault is used for frequently rotated credentials and sensitive configuration. + */ +export function getMsidLabKeyVaultProvider(): KeyVaultSecretsProvider { + if (!msidLabProvider) { + msidLabProvider = new KeyVaultSecretsProvider(KeyVaultInstance.MSIDLab); + } + return msidLabProvider; +} + +/** + * Gets a KeyVaultSecretsProvider instance for the MSAL Team Key Vault. + * This Key Vault is used for static user/app configuration. + */ +export function getMsalTeamKeyVaultProvider(): KeyVaultSecretsProvider { + if (!msalTeamProvider) { + msalTeamProvider = new KeyVaultSecretsProvider( + KeyVaultInstance.MsalTeam + ); + } + return msalTeamProvider; +} + +/** + * Gets the lab certificate credential for use in tests. + * This credential can be used to create ConfidentialClientApplication instances. + * + * Reads the PEM certificate from the path specified in the AZURE_CLIENT_CERTIFICATE_PATH + * environment variable and extracts the thumbprint, private key, and certificate chain. + * + * The result is cached for subsequent calls. + * + * @returns Certificate credential with clientId, tenantId, thumbprintSha256, privateKey, and x5c + * @throws Error if required environment variables are not set or certificate file not found + */ +export function getLabCredential(): LabCertificateCredential { + // Return cached credential if available + if (cachedLabCredential) { + return cachedLabCredential; + } + + const tenant = process.env[EnvVariables.TENANT]; + const clientId = process.env[EnvVariables.CLIENT_ID]; + const certPath = process.env[EnvVariables.CERTIFICATE_PATH]; + + if (!tenant || !clientId || !certPath) { + throw new Error( + `Environment variables not set! Required: ${EnvVariables.TENANT}, ${EnvVariables.CLIENT_ID}, ${EnvVariables.CERTIFICATE_PATH}` + ); + } + + if (!fs.existsSync(certPath)) { + throw new Error(`Certificate file not found at ${certPath}`); + } + + const pemContent = fs.readFileSync(certPath, "utf-8"); + const certInfo = extractCertificateInfoFromPem(pemContent); + + cachedLabCredential = { + clientId, + tenantId: tenant, + thumbprintSha256: certInfo.thumbprintSha256, + privateKey: certInfo.privateKey, + x5c: certInfo.x5c, + }; + + return cachedLabCredential; +} + +/** + * Clears the cached credentials. + * Useful for testing or when you need to force a refresh. + */ +export function clearLabCredentialCache(): void { + cachedLabCredential = null; + cachedKeyVaultCredential = null; +} diff --git a/samples/e2eTestUtils/src/LabResponseHelper.ts b/samples/e2eTestUtils/src/LabResponseHelper.ts new file mode 100644 index 0000000000..d7068c9749 --- /dev/null +++ b/samples/e2eTestUtils/src/LabResponseHelper.ts @@ -0,0 +1,261 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. + */ + +import { + getMsidLabKeyVaultProvider, + getMsalTeamKeyVaultProvider, +} from "./KeyVaultSecretsProvider"; +import { UserConfig, LabUser } from "./UserConfig"; +import { AppConfig } from "./AppConfig"; + +/** + * Caches for configuration objects retrieved from Key Vault. + * Using Map for in-memory caching to avoid repeated Key Vault calls. + */ +const userConfigCache = new Map(); +const appConfigCache = new Map(); +const passwordCache = new Map(); + +/** + * Helper class for retrieving lab configuration from Azure Key Vault. + * Provides methods to fetch user configs, app configs, and passwords with caching. + */ +export class LabResponseHelper { + /** + * Retrieves user configuration from Key Vault with caching. + * @param secretName - The name of the Key Vault secret containing user configuration JSON. + * @returns A UserConfig object deserialized from the Key Vault secret. + */ + static async getUserConfig(secretName: string): Promise { + // Check cache first + const cached = userConfigCache.get(secretName); + if (cached) { + console.debug(`UserConfig '${secretName}' retrieved from cache`); + return cached; + } + + try { + const keyVaultProvider = getMsalTeamKeyVaultProvider(); + const secretValue = await keyVaultProvider.getSecretValue( + secretName + ); + + if (!secretValue) { + throw new Error(`KeyVault secret '${secretName}' is empty`); + } + + let userConfig: UserConfig; + try { + // Parse as JSON and extract the 'user' property + const jsonObject = JSON.parse(secretValue); + + // Look for 'user' property (case-insensitive) + const userKey = Object.keys(jsonObject).find( + (key) => key.toLowerCase() === "user" + ); + + if (!userKey) { + throw new Error( + `KeyVault '${secretName}': no 'user' property found in JSON` + ); + } + + userConfig = jsonObject[userKey] as UserConfig; + console.debug( + `KeyVault '${secretName}': ${ + userConfig.upn ?? "Unknown user" + }` + ); + } catch (parseError) { + if (parseError instanceof SyntaxError) { + throw new Error( + `KeyVault '${secretName}': invalid JSON - ${parseError.message}` + ); + } + throw parseError; + } + + // Cache the result + userConfigCache.set(secretName, userConfig); + return userConfig; + } catch (error) { + console.error(`KeyVault '${secretName}' failed:`, error); + throw new Error( + `Failed to retrieve or parse Key Vault secret '${secretName}'. ${ + error instanceof Error ? error.message : String(error) + }` + ); + } + } + + /** + * Retrieves user configuration as a LabUser instance with password retrieval capability. + * @param secretName - The name of the Key Vault secret containing user configuration JSON. + * @returns A LabUser object with password retrieval capability. + */ + static async getLabUser(secretName: string): Promise { + const config = await this.getUserConfig(secretName); + return new LabUser(config); + } + + /** + * Retrieves app configuration from Key Vault with caching. + * @param secretName - The name of the Key Vault secret containing app configuration JSON. + * @returns An AppConfig object deserialized from the Key Vault secret. + */ + static async getAppConfig(secretName: string): Promise { + // Check cache first + const cached = appConfigCache.get(secretName); + if (cached) { + console.debug(`AppConfig '${secretName}' retrieved from cache`); + return cached; + } + + try { + const keyVaultProvider = getMsalTeamKeyVaultProvider(); + const secretValue = await keyVaultProvider.getSecretValue( + secretName + ); + + if (!secretValue) { + throw new Error(`KeyVault secret '${secretName}' is empty`); + } + + let appConfig: AppConfig; + try { + // Parse as JSON and extract the 'app' property + const jsonObject = JSON.parse(secretValue); + + // Look for 'app' property (case-insensitive) + const appKey = Object.keys(jsonObject).find( + (key) => key.toLowerCase() === "app" + ); + + if (!appKey) { + throw new Error( + `KeyVault '${secretName}': no 'app' property found in JSON` + ); + } + + appConfig = jsonObject[appKey] as AppConfig; + console.debug( + `KeyVault '${secretName}': ${ + appConfig.appId ?? "Unknown app" + }` + ); + } catch (parseError) { + if (parseError instanceof SyntaxError) { + throw new Error( + `KeyVault '${secretName}': invalid JSON - ${parseError.message}` + ); + } + throw parseError; + } + + // Cache the result + appConfigCache.set(secretName, appConfig); + return appConfig; + } catch (error) { + console.error(`KeyVault '${secretName}' failed:`, error); + throw new Error( + `Failed to retrieve or parse Key Vault secret '${secretName}'. ${ + error instanceof Error ? error.message : String(error) + }` + ); + } + } + + /** + * Fetches user password from the MSID Lab Key Vault. + * Used internally by LabUser.getPassword(). + * @param userLabName - The lab name that serves as the secret name for the password. + * @returns The user's password. + */ + static async fetchUserPassword(userLabName: string): Promise { + if (!userLabName || userLabName.trim() === "") { + throw new Error( + "Password fetch failed: lab name is not set on user." + ); + } + + // Check cache first + const cached = passwordCache.get(userLabName); + if (cached) { + console.debug(`Password for '${userLabName}' retrieved from cache`); + return cached; + } + + const password = await this.getMsidLabSecret(userLabName); + + // Cache the result + passwordCache.set(userLabName, password); + console.debug( + `Password retrieved for ${userLabName} (${password.length} chars)` + ); + return password; + } + + /** + * Retrieves a secret from the MSAL Team Key Vault by name. + * Use for app secrets and other static configuration. + * @param secretName - The name of the secret to retrieve. + * @returns The secret value as a string. + */ + static async getSecret(secretName: string): Promise { + if (!secretName || secretName.trim() === "") { + throw new Error("Secret name cannot be empty."); + } + + const keyVaultProvider = getMsalTeamKeyVaultProvider(); + const secretValue = await keyVaultProvider.getSecretValue(secretName); + + if (!secretValue) { + throw new Error( + `Secret '${secretName}' found but was empty in Key Vault.` + ); + } + + console.debug( + `Secret retrieved: ${secretName} (${secretValue.length} chars)` + ); + return secretValue; + } + + /** + * Retrieves a secret from the MSID Lab Key Vault by name. + * Use for frequently rotated credentials like user passwords. + * @param secretName - The name of the secret to retrieve. + * @returns The secret value as a string. + */ + static async getMsidLabSecret(secretName: string): Promise { + if (!secretName || secretName.trim() === "") { + throw new Error("Secret name cannot be empty."); + } + + const keyVaultProvider = getMsidLabKeyVaultProvider(); + const secretValue = await keyVaultProvider.getSecretValue(secretName); + + if (!secretValue) { + throw new Error( + `Secret '${secretName}' found but was empty in Key Vault.` + ); + } + + console.debug( + `MSID Lab secret retrieved: ${secretName} (${secretValue.length} chars)` + ); + return secretValue; + } + + /** + * Clears all cached configurations. Useful for testing or forcing fresh data. + */ + static clearCache(): void { + userConfigCache.clear(); + appConfigCache.clear(); + passwordCache.clear(); + console.debug("LabResponseHelper cache cleared"); + } +} diff --git a/samples/e2eTestUtils/src/UserConfig.ts b/samples/e2eTestUtils/src/UserConfig.ts new file mode 100644 index 0000000000..7ff8ab3cc5 --- /dev/null +++ b/samples/e2eTestUtils/src/UserConfig.ts @@ -0,0 +1,82 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. + */ + +import { LabResponseHelper } from "./LabResponseHelper"; + +/** + * Represents user configuration retrieved from Key Vault. + * This maps to the 'user' property in Key Vault secret JSON. + */ +export type UserConfig = { + /** The object ID (GUID) of the user in Azure AD */ + objectId?: string; + + /** The type of user (e.g., "Cloud", "Federated", "B2C", "MSA") */ + userType?: string; + + /** The user principal name (email) for sign-in */ + upn?: string; + + /** The home UPN for guest users */ + homeUPN?: string; + + /** The B2C identity provider (e.g., "Local", "Facebook", "Google") */ + b2cProvider?: string; + + /** The name of the lab environment this user belongs to */ + labName?: string; + + /** The federation provider (e.g., "None", "ADFSv4") */ + federationProvider?: string; + + /** The tenant ID where the user resides */ + tenantId?: string; + + /** The application ID associated with this user config */ + appId?: string; + + /** The Azure environment (e.g., "azurecloud", "azureusgovernment") */ + azureEnvironment?: string; +}; + +/** + * Extended user config with password retrieval capability. + */ +export class LabUser implements UserConfig { + objectId?: string; + userType?: string; + upn?: string; + homeUPN?: string; + b2cProvider?: string; + labName?: string; + federationProvider?: string; + tenantId?: string; + appId?: string; + azureEnvironment?: string; + + private _password: string | null = null; + + constructor(config: UserConfig) { + Object.assign(this, config); + } + + /** + * Gets the user's password, fetching from Key Vault if not already cached. + * @returns The user's password + */ + async getPassword(): Promise { + if (this._password === null) { + if (!this.labName) { + throw new Error( + "Cannot fetch password: labName is not set on user config" + ); + } + this._password = await LabResponseHelper.fetchUserPassword( + this.labName + ); + } + return this._password; + } +} diff --git a/samples/e2eTestUtils/src/index.ts b/samples/e2eTestUtils/src/index.ts index 95120bf5f1..295c2b0e64 100644 --- a/samples/e2eTestUtils/src/index.ts +++ b/samples/e2eTestUtils/src/index.ts @@ -53,3 +53,20 @@ export { enterCredentials as enterCredentialsElectron, retrieveAuthCodeUrlFromBrowserContext, } from "./ElectronPlaywrightTestUtils"; + +// New Key Vault-based configuration types and helpers +export type { AppConfig } from "./AppConfig"; +export type { UserConfig } from "./UserConfig"; +export { LabUser } from "./UserConfig"; +export { KeyVaultSecrets } from "./KeyVaultSecrets"; +export type { KeyVaultSecretName } from "./KeyVaultSecrets"; +export { + KeyVaultSecretsProvider, + KeyVaultInstance, + getMsidLabKeyVaultProvider, + getMsalTeamKeyVaultProvider, + getLabCredential, + clearLabCredentialCache, +} from "./KeyVaultSecretsProvider"; +export type { LabCertificateCredential } from "./KeyVaultSecretsProvider"; +export { LabResponseHelper } from "./LabResponseHelper"; diff --git a/samples/msal-node-samples/ElectronSystemBrowserTestApp/tests/electron-code-aad.spec.ts b/samples/msal-node-samples/ElectronSystemBrowserTestApp/tests/electron-code-aad.spec.ts index 35dc4b58a3..65339bcdbc 100644 --- a/samples/msal-node-samples/ElectronSystemBrowserTestApp/tests/electron-code-aad.spec.ts +++ b/samples/msal-node-samples/ElectronSystemBrowserTestApp/tests/electron-code-aad.spec.ts @@ -12,13 +12,10 @@ import { ScreenShotElectron, enterCredentialsElectron, retrieveAuthCodeUrlFromBrowserContext, + LabResponseHelper, + KeyVaultSecrets, + LabUser, NodeCacheTestUtils, - LabApiQueryParams, - AppTypes, - AzureEnvironments, - LabClient, - setupCredentials, - SCREENSHOT_BASE_FOLDER_NAME, validateCacheLocation, } from "e2e-test-utils"; import * as path from "path"; @@ -27,10 +24,12 @@ let electronApp: ElectronApplication; let page: Page; let browser: Browser; let browserPage: Page; -let username: string; -let accountPwd: string; +let labUser: LabUser; -const screenshotFolder = path.join(__dirname, "screenshots/ElectronSystemBrowserTestApp"); +const screenshotFolder = path.join( + __dirname, + "screenshots/ElectronSystemBrowserTestApp" +); const TEST_CACHE_LOCATION = `${__dirname}/../data/aad.cache.json`; @@ -39,14 +38,9 @@ import config from "../src/config/AAD.json"; test.beforeAll(async () => { await validateCacheLocation(TEST_CACHE_LOCATION); - const labApiParams: LabApiQueryParams = { - azureEnvironment: AzureEnvironments.CLOUD, - appType: AppTypes.CLOUD, - }; - - const labClient = new LabClient(); - const envResponse = await labClient.getVarsByCloudEnvironment(labApiParams); - [username, accountPwd] = await setupCredentials(envResponse[0], labClient); + labUser = await LabResponseHelper.getLabUser( + KeyVaultSecrets.UserPublicCloud + ); electronApp = await electron.launch({ args: [ @@ -98,8 +92,8 @@ test.describe("Acquire token", () => { await enterCredentialsElectron( browserPage, screenshot, - username, - accountPwd + labUser.upn!, + await labUser.getPassword() ); const cachedTokens = await NodeCacheTestUtils.waitForTokens( TEST_CACHE_LOCATION, @@ -109,6 +103,8 @@ test.describe("Acquire token", () => { expect(cachedTokens.idTokens.length).toBe(1); expect(cachedTokens.refreshTokens.length).toBe(1); - await expect(page.locator(`text=${username}`).first()).toBeVisible(); + await expect( + page.locator(`text=${labUser.upn!}`).first() + ).toBeVisible(); }); }); diff --git a/samples/msal-node-samples/auth-code-cli-app/test/auth-code-cli.spec.ts b/samples/msal-node-samples/auth-code-cli-app/test/auth-code-cli.spec.ts index cbe2bce4a7..956f4a84a2 100644 --- a/samples/msal-node-samples/auth-code-cli-app/test/auth-code-cli.spec.ts +++ b/samples/msal-node-samples/auth-code-cli-app/test/auth-code-cli.spec.ts @@ -6,16 +6,14 @@ import * as puppeteer from "puppeteer"; import { Screenshot, - createFolder, - setupCredentials, - RETRY_TIMES, enterCredentials, - validateCacheLocation, + LabResponseHelper, + KeyVaultSecrets, + LabUser, NodeCacheTestUtils, - LabClient, - LabApiQueryParams, - AppTypes, - AzureEnvironments, + validateCacheLocation, + createFolder, + RETRY_TIMES, } from "e2e-test-utils"; import path from "path"; @@ -37,10 +35,12 @@ describe("Auth Code CLI AAD Prod Tests", () => { let context: puppeteer.BrowserContext; let page: puppeteer.Page; - let username: string; - let accountPwd: string; + let labUser: LabUser; - const screenshotFolder = path.join(__dirname, "screenshots/auth-code-cli-app"); + const screenshotFolder = path.join( + __dirname, + "screenshots/auth-code-cli-app" + ); beforeAll(async () => { await validateCacheLocation(TEST_CACHE_LOCATION); @@ -49,18 +49,8 @@ describe("Auth Code CLI AAD Prod Tests", () => { createFolder(screenshotFolder); - const labApiParms: LabApiQueryParams = { - azureEnvironment: AzureEnvironments.CLOUD, - appType: AppTypes.CLOUD, - }; - - const labClient = new LabClient(); - const envResponse = await labClient.getVarsByCloudEnvironment( - labApiParms - ); - [username, accountPwd] = await setupCredentials( - envResponse[0], - labClient + labUser = await LabResponseHelper.getLabUser( + KeyVaultSecrets.UserPublicCloud ); }); @@ -91,7 +81,12 @@ describe("Auth Code CLI AAD Prod Tests", () => { page = await context.newPage(); page.setDefaultTimeout(5000); page.goto(url); - enterCredentials(page, screenshot, username, accountPwd); + enterCredentials( + page, + screenshot, + labUser.upn, + await labUser.getPassword() + ); }; const successMessage = "Success. You can close the browser now"; const result = @@ -102,7 +97,7 @@ describe("Auth Code CLI AAD Prod Tests", () => { }); expect(result.accessToken).toBeTruthy(); expect(result.idToken).toBeTruthy(); - expect(result.account.username).toEqual(username); + expect(result.account.username).toEqual(labUser.upn); try { expect( diff --git a/samples/msal-node-samples/auth-code/test/auth-code-aad-agc-confidential.spec.ts b/samples/msal-node-samples/auth-code/test/auth-code-aad-agc-confidential.spec.ts index 12bd85e9aa..d82130a5f5 100644 --- a/samples/msal-node-samples/auth-code/test/auth-code-aad-agc-confidential.spec.ts +++ b/samples/msal-node-samples/auth-code/test/auth-code-aad-agc-confidential.spec.ts @@ -6,14 +6,16 @@ import * as puppeteer from "puppeteer"; import { Screenshot, - createFolder, - RETRY_TIMES, enterCredentials, - validateCacheLocation, SAMPLE_HOME_URL, + LabResponseHelper, + KeyVaultSecrets, + LabUser, + AppConfig, NodeCacheTestUtils, - getKeyVaultSecretClient, - getCredentials, + validateCacheLocation, + createFolder, + RETRY_TIMES, } from "e2e-test-utils"; import { ConfidentialClientApplication } from "@azure/msal-node"; import path from "path"; @@ -29,17 +31,6 @@ const cachePlugin = require("../../cachePlugin.js")(TEST_CACHE_LOCATION); // Load scenario configuration const config = require("../config/AAD-AGC-Confidential.json"); -config.authOptions = { - clientId: process.env.AZURE_CLIENT_ID, - clientSecret: process.env.AZURE_CLIENT_SECRET, - authority: `${process.env.AUTHORITY}/${process.env.AZURE_TENANT_ID}`, - knownAuthorities: [ - `${process.env.AUTHORITY}/${process.env.AZURE_TENANT_ID}`, - ], -}; -config.resourceApi = { - endpoint: `${process.env.GRAPH_URL}/v1.0/me`, -}; describe("Auth Code AAD AGC Confidential Tests", () => { jest.retryTimes(RETRY_TIMES); @@ -50,10 +41,13 @@ describe("Auth Code AAD AGC Confidential Tests", () => { let port: string; let homeRoute: string; - let username: string; - let password: string; + let labUser: LabUser; + let appConfig: AppConfig; - const screenshotFolder = path.join(__dirname, "screenshots/auth-code/aad-agc-confidential"); + const screenshotFolder = path.join( + __dirname, + "screenshots/auth-code/aad-agc-confidential" + ); beforeAll(async () => { await validateCacheLocation(TEST_CACHE_LOCATION); @@ -65,8 +59,36 @@ describe("Auth Code AAD AGC Confidential Tests", () => { createFolder(screenshotFolder); - const keyVaultSecretClient = await getKeyVaultSecretClient(); - [username, password] = await getCredentials(keyVaultSecretClient); + labUser = await LabResponseHelper.getLabUser( + KeyVaultSecrets.UserArlington + ); + appConfig = await LabResponseHelper.getAppConfig( + KeyVaultSecrets.MsalAppArlingtonCCA + ); + + // Get client secret from Key Vault + let clientSecret: string | undefined; + if (appConfig.secretName) { + clientSecret = await LabResponseHelper.getSecret( + appConfig.secretName + ); + } + + // Configure auth options from Key Vault app config + const authorityUrl = appConfig.authority + ? new URL(appConfig.authority) + : null; + config.authOptions = { + clientId: appConfig.appId, + clientSecret: clientSecret, + authority: appConfig.authority, + knownAuthorities: authorityUrl ? [authorityUrl.origin] : [], + }; + config.resourceApi = { + endpoint: authorityUrl + ? `${authorityUrl.origin}/v1.0/me` + : undefined, + }; }); afterAll(async () => { @@ -114,8 +136,9 @@ describe("Auth Code AAD AGC Confidential Tests", () => { it("Performs acquire token", async () => { const screenshot = new Screenshot(`${screenshotFolder}/BaseCase`); + const password = await labUser.getPassword(); await page.goto(homeRoute); - await enterCredentials(page, screenshot, username, password); + await enterCredentials(page, screenshot, labUser.upn, password); await page.waitForFunction( `window.location.href.startsWith("${SAMPLE_HOME_URL}")` ); @@ -132,8 +155,9 @@ describe("Auth Code AAD AGC Confidential Tests", () => { const screenshot = new Screenshot( `${screenshotFolder}/PromptLogin` ); + const password = await labUser.getPassword(); await page.goto(`${homeRoute}/?prompt=login`); - await enterCredentials(page, screenshot, username, password); + await enterCredentials(page, screenshot, labUser.upn, password); await page.waitForFunction( `window.location.href.startsWith("${SAMPLE_HOME_URL}")` ); @@ -151,8 +175,9 @@ describe("Auth Code AAD AGC Confidential Tests", () => { const screenshot = new Screenshot( `${screenshotFolder}/PromptConsent` ); + const password = await labUser.getPassword(); await page.goto(`${homeRoute}/?prompt=consent`); - await enterCredentials(page, screenshot, username, password); + await enterCredentials(page, screenshot, labUser.upn, password); await page.waitForFunction( `window.location.href.startsWith("${SAMPLE_HOME_URL}")` ); @@ -168,9 +193,10 @@ describe("Auth Code AAD AGC Confidential Tests", () => { it("Performs acquire token with prompt = 'none'", async () => { const screenshot = new Screenshot(`${screenshotFolder}/PromptNone`); + const password = await labUser.getPassword(); // First log the user in first await page.goto(`${homeRoute}/?prompt=login`); - await enterCredentials(page, screenshot, username, password); + await enterCredentials(page, screenshot, labUser.upn, password); await page.waitForFunction( `window.location.href.startsWith("${SAMPLE_HOME_URL}")` ); @@ -194,9 +220,10 @@ describe("Auth Code AAD AGC Confidential Tests", () => { it("Performs acquire token with state", async () => { const screenshot = new Screenshot(`${screenshotFolder}/WithState`); + const password = await labUser.getPassword(); const STATE_VALUE = "value_on_state"; await page.goto(`${homeRoute}/?prompt=login&state=${STATE_VALUE}`); - await enterCredentials(page, screenshot, username, password); + await enterCredentials(page, screenshot, labUser.upn, password); await page.waitForFunction( `window.location.href.startsWith("${SAMPLE_HOME_URL}")` ); diff --git a/samples/msal-node-samples/auth-code/test/auth-code-aad-agc-public.spec.ts b/samples/msal-node-samples/auth-code/test/auth-code-aad-agc-public.spec.ts index f398882a03..a7a50fc754 100644 --- a/samples/msal-node-samples/auth-code/test/auth-code-aad-agc-public.spec.ts +++ b/samples/msal-node-samples/auth-code/test/auth-code-aad-agc-public.spec.ts @@ -6,14 +6,16 @@ import * as puppeteer from "puppeteer"; import { Screenshot, - createFolder, - RETRY_TIMES, enterCredentials, - validateCacheLocation, SAMPLE_HOME_URL, + LabResponseHelper, + KeyVaultSecrets, + LabUser, + AppConfig, NodeCacheTestUtils, - getKeyVaultSecretClient, - getCredentials, + validateCacheLocation, + createFolder, + RETRY_TIMES, } from "e2e-test-utils"; import { PublicClientApplication } from "@azure/msal-node"; import path from "path"; @@ -29,16 +31,6 @@ const cachePlugin = require("../../cachePlugin.js")(TEST_CACHE_LOCATION); // Load scenario configuration const config = require("../config/AAD-AGC-Public.json"); -config.authOptions = { - clientId: process.env.AZURE_CLIENT_ID, - authority: `${process.env.AUTHORITY}/${process.env.AZURE_TENANT_ID}`, - knownAuthorities: [ - `${process.env.AUTHORITY}/${process.env.AZURE_TENANT_ID}`, - ], -}; -config.resourceApi = { - endpoint: `${process.env.GRAPH_URL}/v1.0/me`, -}; describe("Auth Code AAD AGC Public Tests", () => { jest.retryTimes(RETRY_TIMES); @@ -49,10 +41,13 @@ describe("Auth Code AAD AGC Public Tests", () => { let port: string; let homeRoute: string; - let username: string; - let password: string; + let labUser: LabUser; + let appConfig: AppConfig; - const screenshotFolder = path.join(__dirname, "screenshots/auth-code/aad-agc-public"); + const screenshotFolder = path.join( + __dirname, + "screenshots/auth-code/aad-agc-public" + ); beforeAll(async () => { await validateCacheLocation(TEST_CACHE_LOCATION); @@ -64,8 +59,26 @@ describe("Auth Code AAD AGC Public Tests", () => { createFolder(screenshotFolder); - const keyVaultSecretClient = await getKeyVaultSecretClient(); - [username, password] = await getCredentials(keyVaultSecretClient); + labUser = await LabResponseHelper.getLabUser( + KeyVaultSecrets.UserArlington + ); + appConfig = await LabResponseHelper.getAppConfig( + KeyVaultSecrets.ArlAppIdLabsApp + ); + + // Configure auth options from Key Vault app config + config.authOptions = { + clientId: appConfig.appId, + authority: appConfig.authority, + knownAuthorities: appConfig.authority + ? [new URL(appConfig.authority).origin] + : [], + }; + config.resourceApi = { + endpoint: appConfig.authority + ? `${new URL(appConfig.authority).origin}/v1.0/me` + : undefined, + }; }); afterAll(async () => { @@ -109,8 +122,9 @@ describe("Auth Code AAD AGC Public Tests", () => { it("Performs acquire token", async () => { const screenshot = new Screenshot(`${screenshotFolder}/BaseCase`); + const password = await labUser.getPassword(); await page.goto(homeRoute); - await enterCredentials(page, screenshot, username, password); + await enterCredentials(page, screenshot, labUser.upn, password); await page.waitForFunction( `window.location.href.startsWith("${SAMPLE_HOME_URL}")` ); @@ -127,8 +141,9 @@ describe("Auth Code AAD AGC Public Tests", () => { const screenshot = new Screenshot( `${screenshotFolder}/PromptLogin` ); + const password = await labUser.getPassword(); await page.goto(`${homeRoute}/?prompt=login`); - await enterCredentials(page, screenshot, username, password); + await enterCredentials(page, screenshot, labUser.upn, password); await page.waitForFunction( `window.location.href.startsWith("${SAMPLE_HOME_URL}")` ); @@ -146,8 +161,9 @@ describe("Auth Code AAD AGC Public Tests", () => { const screenshot = new Screenshot( `${screenshotFolder}/PromptConsent` ); + const password = await labUser.getPassword(); await page.goto(`${homeRoute}/?prompt=consent`); - await enterCredentials(page, screenshot, username, password); + await enterCredentials(page, screenshot, labUser.upn, password); await page.waitForFunction( `window.location.href.startsWith("${SAMPLE_HOME_URL}")` ); @@ -163,9 +179,10 @@ describe("Auth Code AAD AGC Public Tests", () => { it("Performs acquire token with prompt = 'none'", async () => { const screenshot = new Screenshot(`${screenshotFolder}/PromptNone`); + const password = await labUser.getPassword(); // First log the user in first await page.goto(`${homeRoute}/?prompt=login`); - await enterCredentials(page, screenshot, username, password); + await enterCredentials(page, screenshot, labUser.upn, password); await page.waitForFunction( `window.location.href.startsWith("${SAMPLE_HOME_URL}")` ); @@ -189,9 +206,10 @@ describe("Auth Code AAD AGC Public Tests", () => { it("Performs acquire token with state", async () => { const screenshot = new Screenshot(`${screenshotFolder}/WithState`); + const password = await labUser.getPassword(); const STATE_VALUE = "value_on_state"; await page.goto(`${homeRoute}/?prompt=login&state=${STATE_VALUE}`); - await enterCredentials(page, screenshot, username, password); + await enterCredentials(page, screenshot, labUser.upn, password); await page.waitForFunction( `window.location.href.startsWith("${SAMPLE_HOME_URL}")` ); diff --git a/samples/msal-node-samples/auth-code/test/auth-code-aad.spec.ts b/samples/msal-node-samples/auth-code/test/auth-code-aad.spec.ts index 8506f17704..3f80830840 100644 --- a/samples/msal-node-samples/auth-code/test/auth-code-aad.spec.ts +++ b/samples/msal-node-samples/auth-code/test/auth-code-aad.spec.ts @@ -6,17 +6,15 @@ import * as puppeteer from "puppeteer"; import { Screenshot, - createFolder, - setupCredentials, - RETRY_TIMES, enterCredentials, - validateCacheLocation, SAMPLE_HOME_URL, + LabResponseHelper, + KeyVaultSecrets, + LabUser, NodeCacheTestUtils, - LabClient, - LabApiQueryParams, - AppTypes, - AzureEnvironments, + validateCacheLocation, + createFolder, + RETRY_TIMES, } from "e2e-test-utils"; import path from "path"; @@ -43,8 +41,7 @@ describe("Auth Code AAD Prod Tests", () => { let port: string; let homeRoute: string; - let username: string; - let accountPwd: string; + let labUser: LabUser; const screenshotFolder = path.join(__dirname, "screenshots/auth-code/aad"); @@ -58,18 +55,8 @@ describe("Auth Code AAD Prod Tests", () => { createFolder(screenshotFolder); - const labApiParms: LabApiQueryParams = { - azureEnvironment: AzureEnvironments.CLOUD, - appType: AppTypes.CLOUD, - }; - - const labClient = new LabClient(); - const envResponse = await labClient.getVarsByCloudEnvironment( - labApiParms - ); - [username, accountPwd] = await setupCredentials( - envResponse[0], - labClient + labUser = await LabResponseHelper.getLabUser( + KeyVaultSecrets.UserPublicCloud ); }); @@ -114,8 +101,9 @@ describe("Auth Code AAD Prod Tests", () => { it("Performs acquire token", async () => { const screenshot = new Screenshot(`${screenshotFolder}/BaseCase`); + const accountPwd = await labUser.getPassword(); await page.goto(homeRoute); - await enterCredentials(page, screenshot, username, accountPwd); + await enterCredentials(page, screenshot, labUser.upn, accountPwd); await page.waitForFunction( `window.location.href.startsWith("${SAMPLE_HOME_URL}")` ); @@ -132,8 +120,9 @@ describe("Auth Code AAD Prod Tests", () => { const screenshot = new Screenshot( `${screenshotFolder}/PromptLogin` ); + const accountPwd = await labUser.getPassword(); await page.goto(`${homeRoute}/?prompt=login`); - await enterCredentials(page, screenshot, username, accountPwd); + await enterCredentials(page, screenshot, labUser.upn, accountPwd); await page.waitForFunction( `window.location.href.startsWith("${SAMPLE_HOME_URL}")` ); @@ -151,8 +140,9 @@ describe("Auth Code AAD Prod Tests", () => { const screenshot = new Screenshot( `${screenshotFolder}/PromptConsent` ); + const accountPwd = await labUser.getPassword(); await page.goto(`${homeRoute}/?prompt=consent`); - await enterCredentials(page, screenshot, username, accountPwd); + await enterCredentials(page, screenshot, labUser.upn, accountPwd); await page.waitForFunction( `window.location.href.startsWith("${SAMPLE_HOME_URL}")` ); @@ -168,9 +158,10 @@ describe("Auth Code AAD Prod Tests", () => { it("Performs acquire token with prompt = 'none'", async () => { const screenshot = new Screenshot(`${screenshotFolder}/PromptNone`); + const accountPwd = await labUser.getPassword(); // First log the user in first await page.goto(`${homeRoute}/?prompt=login`); - await enterCredentials(page, screenshot, username, accountPwd); + await enterCredentials(page, screenshot, labUser.upn, accountPwd); await page.waitForFunction( `window.location.href.startsWith("${SAMPLE_HOME_URL}")` ); @@ -194,9 +185,10 @@ describe("Auth Code AAD Prod Tests", () => { it("Performs acquire token with state", async () => { const screenshot = new Screenshot(`${screenshotFolder}/WithState`); + const accountPwd = await labUser.getPassword(); const STATE_VALUE = "value_on_state"; await page.goto(`${homeRoute}/?prompt=login&state=${STATE_VALUE}`); - await enterCredentials(page, screenshot, username, accountPwd); + await enterCredentials(page, screenshot, labUser.upn, accountPwd); await page.waitForFunction( `window.location.href.startsWith("${SAMPLE_HOME_URL}")` ); diff --git a/samples/msal-node-samples/auth-code/test/auth-code-adfs.spec.ts b/samples/msal-node-samples/auth-code/test/auth-code-adfs.spec.ts index ef9c7c1bae..cdb4a840a3 100644 --- a/samples/msal-node-samples/auth-code/test/auth-code-adfs.spec.ts +++ b/samples/msal-node-samples/auth-code/test/auth-code-adfs.spec.ts @@ -1,19 +1,15 @@ import * as puppeteer from "puppeteer"; import { Screenshot, - createFolder, - setupCredentials, - RETRY_TIMES, enterCredentialsADFS, enterCredentialsADFSWithConsent, SAMPLE_HOME_URL, + LabResponseHelper, + KeyVaultSecrets, + LabUser, NodeCacheTestUtils, - LabClient, - LabApiQueryParams, - AppTypes, - AzureEnvironments, - FederationProviders, - UserTypes, + createFolder, + RETRY_TIMES, } from "e2e-test-utils"; import { PublicClientApplication } from "@azure/msal-node"; import path from "path"; @@ -26,8 +22,7 @@ const cachePlugin = require("../../cachePlugin.js")(TEST_CACHE_LOCATION); const config = require("../config/ADFS.json"); -let username: string; -let accountPwd: string; +let labUser: LabUser; describe.skip("Auth Code ADFS 2019 Tests", () => { jest.retryTimes(RETRY_TIMES); @@ -47,20 +42,8 @@ describe.skip("Auth Code ADFS 2019 Tests", () => { homeRoute = `http://localhost:${port}`; createFolder(screenshotFolder); - const labApiParms: LabApiQueryParams = { - azureEnvironment: AzureEnvironments.CLOUD, - appType: AppTypes.CLOUD, - federationProvider: FederationProviders.ADFS2019, - userType: UserTypes.FEDERATED, - }; - - const labClient = new LabClient(); - const envResponse = await labClient.getVarsByCloudEnvironment( - labApiParms - ); - [username, accountPwd] = await setupCredentials( - envResponse[0], - labClient + labUser = await LabResponseHelper.getLabUser( + KeyVaultSecrets.UserFederated ); }); @@ -101,8 +84,14 @@ describe.skip("Auth Code ADFS 2019 Tests", () => { it("Performs acquire token", async () => { const screenshot = new Screenshot(`${screenshotFolder}/BaseCase`); + const accountPwd = await labUser.getPassword(); await page.goto(homeRoute); - await enterCredentialsADFS(page, screenshot, username, accountPwd); + await enterCredentialsADFS( + page, + screenshot, + labUser.upn, + accountPwd + ); await page.waitForFunction( `window.location.href.startsWith("${SAMPLE_HOME_URL}")` ); @@ -119,8 +108,14 @@ describe.skip("Auth Code ADFS 2019 Tests", () => { const screenshot = new Screenshot( `${screenshotFolder}/PromptLogin` ); + const accountPwd = await labUser.getPassword(); await page.goto(`${homeRoute}/?prompt=login`); - await enterCredentialsADFS(page, screenshot, username, accountPwd); + await enterCredentialsADFS( + page, + screenshot, + labUser.upn, + accountPwd + ); await page.waitForFunction( `window.location.href.startsWith("${SAMPLE_HOME_URL}")` ); @@ -137,11 +132,12 @@ describe.skip("Auth Code ADFS 2019 Tests", () => { const screenshot = new Screenshot( `${screenshotFolder}/PromptConsent` ); + const accountPwd = await labUser.getPassword(); await page.goto(`${homeRoute}/?prompt=consent`); await enterCredentialsADFSWithConsent( page, screenshot, - username, + labUser.upn, accountPwd ); await page.waitForFunction( @@ -158,9 +154,15 @@ describe.skip("Auth Code ADFS 2019 Tests", () => { it("Performs acquire token with prompt = 'none'", async () => { const screenshot = new Screenshot(`${screenshotFolder}/PromptNone`); + const accountPwd = await labUser.getPassword(); // First login await page.goto(`${homeRoute}/?prompt=login`); - await enterCredentialsADFS(page, screenshot, username, accountPwd); + await enterCredentialsADFS( + page, + screenshot, + labUser.upn, + accountPwd + ); await page.waitForFunction( `window.location.href.startsWith("${SAMPLE_HOME_URL}")` ); @@ -182,9 +184,15 @@ describe.skip("Auth Code ADFS 2019 Tests", () => { it("Performs acquire token with state", async () => { const screenshot = new Screenshot(`${screenshotFolder}/WithState`); + const accountPwd = await labUser.getPassword(); const STATE_VALUE = "value_on_state"; await page.goto(`${homeRoute}/?prompt=login&state=${STATE_VALUE}`); - await enterCredentialsADFS(page, screenshot, username, accountPwd); + await enterCredentialsADFS( + page, + screenshot, + labUser.upn, + accountPwd + ); await page.waitForFunction( `window.location.href.startsWith("${SAMPLE_HOME_URL}")` ); diff --git a/samples/msal-node-samples/auth-code/test/auth-code-b2c-aad.spec.ts b/samples/msal-node-samples/auth-code/test/auth-code-b2c-aad.spec.ts index 738d90a51e..09129eefc5 100644 --- a/samples/msal-node-samples/auth-code/test/auth-code-b2c-aad.spec.ts +++ b/samples/msal-node-samples/auth-code/test/auth-code-b2c-aad.spec.ts @@ -6,17 +6,15 @@ import * as puppeteer from "puppeteer"; import { Screenshot, - createFolder, - setupCredentials, b2cAadPpeAccountEnterCredentials, - RETRY_TIMES, - validateCacheLocation, SAMPLE_HOME_URL, + LabResponseHelper, + KeyVaultSecrets, + LabUser, NodeCacheTestUtils, - LabClient, - LabApiQueryParams, - AppTypes, - AzureEnvironments, + validateCacheLocation, + createFolder, + RETRY_TIMES, } from "e2e-test-utils"; import path from "path"; @@ -43,10 +41,12 @@ describe.skip("Auth Code B2C Tests (aad account)", () => { let port: number; let homeRoute: string; - let username: string; - let accountPwd: string; + let labUser: LabUser; - const screenshotFolder = path.join(__dirname, "screenshots/auth-code/b2c-aad"); + const screenshotFolder = path.join( + __dirname, + "screenshots/auth-code/b2c-aad" + ); beforeAll(async () => { await validateCacheLocation(TEST_CACHE_LOCATION); @@ -60,18 +60,8 @@ describe.skip("Auth Code B2C Tests (aad account)", () => { createFolder(screenshotFolder); - const labApiParms: LabApiQueryParams = { - azureEnvironment: AzureEnvironments.CLOUD, - appType: AppTypes.CLOUD, - }; - - const labClient = new LabClient(); - const envResponse = await labClient.getVarsByCloudEnvironment( - labApiParms - ); - [username, accountPwd] = await setupCredentials( - envResponse[0], - labClient + labUser = await LabResponseHelper.getLabUser( + KeyVaultSecrets.UserPublicCloud ); }); @@ -117,11 +107,12 @@ describe.skip("Auth Code B2C Tests (aad account)", () => { it("Performs acquire token", async () => { const screenshot = new Screenshot(`${screenshotFolder}/BaseCase`); + const accountPwd = await labUser.getPassword(); await page.goto(homeRoute); await b2cAadPpeAccountEnterCredentials( page, screenshot, - username, + labUser.upn, accountPwd ); await page.waitForFunction( @@ -140,11 +131,12 @@ describe.skip("Auth Code B2C Tests (aad account)", () => { const screenshot = new Screenshot( `${screenshotFolder}/PromptLogin` ); + const accountPwd = await labUser.getPassword(); await page.goto(`${homeRoute}/?prompt=login`); await b2cAadPpeAccountEnterCredentials( page, screenshot, - username, + labUser.upn, accountPwd ); await page.waitForFunction( @@ -164,11 +156,12 @@ describe.skip("Auth Code B2C Tests (aad account)", () => { const screenshot = new Screenshot( `${screenshotFolder}/PromptSelectAccount` ); + const accountPwd = await labUser.getPassword(); await page.goto(`${homeRoute}/?prompt=select_account`); await b2cAadPpeAccountEnterCredentials( page, screenshot, - username, + labUser.upn, accountPwd ); await page.waitForFunction( @@ -186,12 +179,13 @@ describe.skip("Auth Code B2C Tests (aad account)", () => { it("Performs acquire token with prompt = 'none'", async () => { const screenshot = new Screenshot(`${screenshotFolder}/PromptNone`); + const accountPwd = await labUser.getPassword(); // First log the user in first await page.goto(`${homeRoute}/?prompt=login`); await b2cAadPpeAccountEnterCredentials( page, screenshot, - username, + labUser.upn, accountPwd ); await page.waitForFunction( @@ -217,12 +211,13 @@ describe.skip("Auth Code B2C Tests (aad account)", () => { it("Performs acquire token with state", async () => { const screenshot = new Screenshot(`${screenshotFolder}/WithState`); + const accountPwd = await labUser.getPassword(); const STATE_VALUE = "value_on_state"; await page.goto(`${homeRoute}/?prompt=login&state=${STATE_VALUE}`); await b2cAadPpeAccountEnterCredentials( page, screenshot, - username, + labUser.upn, accountPwd ); await page.waitForFunction( diff --git a/samples/msal-node-samples/auth-code/test/auth-code-b2c-local.spec.ts b/samples/msal-node-samples/auth-code/test/auth-code-b2c-local.spec.ts index ef3b8f23e2..cd967dbe1a 100644 --- a/samples/msal-node-samples/auth-code/test/auth-code-b2c-local.spec.ts +++ b/samples/msal-node-samples/auth-code/test/auth-code-b2c-local.spec.ts @@ -6,17 +6,15 @@ import * as puppeteer from "puppeteer"; import { Screenshot, - createFolder, - setupCredentials, b2cLocalAccountEnterCredentials, - RETRY_TIMES, - validateCacheLocation, SAMPLE_HOME_URL, + LabResponseHelper, + KeyVaultSecrets, + LabUser, NodeCacheTestUtils, - LabClient, - LabApiQueryParams, - B2cProviders, - UserTypes, + validateCacheLocation, + createFolder, + RETRY_TIMES, } from "e2e-test-utils"; import path from "path"; @@ -43,10 +41,12 @@ describe("Auth Code B2C Tests (local account)", () => { let port: number; let homeRoute: string; - let username: string; - let accountPwd: string; + let labUser: LabUser; - const screenshotFolder = path.join(__dirname, "screenshots/auth-code/b2c-local"); + const screenshotFolder = path.join( + __dirname, + "screenshots/auth-code/b2c-local" + ); beforeAll(async () => { await validateCacheLocation(TEST_CACHE_LOCATION); @@ -60,19 +60,7 @@ describe("Auth Code B2C Tests (local account)", () => { createFolder(screenshotFolder); - const labApiParms: LabApiQueryParams = { - userType: UserTypes.B2C, - b2cProvider: B2cProviders.LOCAL, - }; - - const labClient = new LabClient(); - const envResponse = await labClient.getVarsByCloudEnvironment( - labApiParms - ); - [username, accountPwd] = await setupCredentials( - envResponse[0], - labClient - ); + labUser = await LabResponseHelper.getLabUser(KeyVaultSecrets.UserB2C); }); afterAll(async () => { @@ -117,11 +105,12 @@ describe("Auth Code B2C Tests (local account)", () => { it("Performs acquire token", async () => { const screenshot = new Screenshot(`${screenshotFolder}/BaseCase`); + const accountPwd = await labUser.getPassword(); await page.goto(homeRoute); await b2cLocalAccountEnterCredentials( page, screenshot, - username, + labUser.upn, accountPwd ); await page.waitForFunction( @@ -140,11 +129,12 @@ describe("Auth Code B2C Tests (local account)", () => { const screenshot = new Screenshot( `${screenshotFolder}/PromptLogin` ); + const accountPwd = await labUser.getPassword(); await page.goto(`${homeRoute}/?prompt=login`); await b2cLocalAccountEnterCredentials( page, screenshot, - username, + labUser.upn, accountPwd ); await page.waitForFunction( @@ -164,11 +154,12 @@ describe("Auth Code B2C Tests (local account)", () => { const screenshot = new Screenshot( `${screenshotFolder}/PromptSelectAccount` ); + const accountPwd = await labUser.getPassword(); await page.goto(`${homeRoute}/?prompt=select_account`); await b2cLocalAccountEnterCredentials( page, screenshot, - username, + labUser.upn, accountPwd ); await page.waitForFunction( @@ -186,12 +177,13 @@ describe("Auth Code B2C Tests (local account)", () => { it("Performs acquire token with prompt = 'none'", async () => { const screenshot = new Screenshot(`${screenshotFolder}/PromptNone`); + const accountPwd = await labUser.getPassword(); // First log the user in first await page.goto(`${homeRoute}/?prompt=login`); await b2cLocalAccountEnterCredentials( page, screenshot, - username, + labUser.upn, accountPwd ); await page.waitForFunction( @@ -217,12 +209,13 @@ describe("Auth Code B2C Tests (local account)", () => { it("Performs acquire token with state", async () => { const screenshot = new Screenshot(`${screenshotFolder}/WithState`); + const accountPwd = await labUser.getPassword(); const STATE_VALUE = "value_on_state"; await page.goto(`${homeRoute}/?prompt=login&state=${STATE_VALUE}`); await b2cLocalAccountEnterCredentials( page, screenshot, - username, + labUser.upn, accountPwd ); await page.waitForFunction( diff --git a/samples/msal-node-samples/b2c-user-flows/test/user-flows-local.spec.ts b/samples/msal-node-samples/b2c-user-flows/test/user-flows-local.spec.ts index d8d0b5533e..f6fb4d58e7 100644 --- a/samples/msal-node-samples/b2c-user-flows/test/user-flows-local.spec.ts +++ b/samples/msal-node-samples/b2c-user-flows/test/user-flows-local.spec.ts @@ -6,17 +6,15 @@ import * as puppeteer from "puppeteer"; import { Screenshot, - createFolder, - setupCredentials, b2cLocalAccountEnterCredentials, - RETRY_TIMES, - validateCacheLocation, SAMPLE_HOME_URL, + LabResponseHelper, + KeyVaultSecrets, + LabUser, NodeCacheTestUtils, - LabClient, - LabApiQueryParams, - B2cProviders, - UserTypes, + validateCacheLocation, + createFolder, + RETRY_TIMES, } from "e2e-test-utils"; import path from "path"; @@ -43,10 +41,9 @@ describe("B2C User Flow Tests", () => { let port: string; let homeRoute: string; - let username: string; + let labUser: LabUser; let accountPwd: string; - - let clientSecret: { secret: string; value: string }; + let clientSecret: string; const screenshotFolder = path.join( __dirname, @@ -63,20 +60,10 @@ describe("B2C User Flow Tests", () => { port = 3000; homeRoute = `http://localhost:${port}`; - const labApiParams: LabApiQueryParams = { - userType: UserTypes.B2C, - b2cProvider: B2cProviders.LOCAL, - }; - - const labClient = new LabClient(); - - clientSecret = await labClient.getSecret("MSIDLABB2C-MSAapp-AppSecret"); - const envResponse = await labClient.getVarsByCloudEnvironment( - labApiParams - ); - [username, accountPwd] = await setupCredentials( - envResponse[0], - labClient + labUser = await LabResponseHelper.getLabUser(KeyVaultSecrets.UserB2C); + accountPwd = await labUser.getPassword(); + clientSecret = await LabResponseHelper.getMsidLabSecret( + "MSIDLABB2C-MSAapp-AppSecret" ); }); @@ -92,7 +79,7 @@ describe("B2C User Flow Tests", () => { cca = new ConfidentialClientApplication({ auth: { clientId: config.authOptions.clientId, - clientSecret: clientSecret.value, + clientSecret: clientSecret, authority: config.policies.authorities.signUpSignIn.authority, knownAuthorities: [config.policies.authorityDomain], @@ -142,7 +129,7 @@ describe("B2C User Flow Tests", () => { await b2cLocalAccountEnterCredentials( page, screenshot, - username, + labUser.upn, accountPwd ); await page.waitForFunction( diff --git a/samples/msal-node-samples/client-credentials/test/client-credentials-aad.spec.ts b/samples/msal-node-samples/client-credentials/test/client-credentials-aad.spec.ts index 4357093aa0..1831eefb3d 100644 --- a/samples/msal-node-samples/client-credentials/test/client-credentials-aad.spec.ts +++ b/samples/msal-node-samples/client-credentials/test/client-credentials-aad.spec.ts @@ -1,13 +1,21 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. + * + * Client Credentials integration tests using Key Vault-based configuration. + * Tests use certificate-based authentication to acquire tokens. + */ + import { RETRY_TIMES, - retrieveAppConfiguration, validateCacheLocation, - LabApiQueryParams, NodeCacheTestUtils, - LabClient, + LabResponseHelper, + KeyVaultSecrets, + getLabCredential, + LabCertificateCredential, } from "e2e-test-utils"; import { ConfidentialClientApplication } from "@azure/msal-node"; -import config from "../config/AAD.json"; const TEST_CACHE_LOCATION = `${__dirname}/data/aad.cache.json`; @@ -15,42 +23,47 @@ const getClientCredentialsToken = require("../index"); const cachePlugin = require("../../cachePlugin.js")(TEST_CACHE_LOCATION); -let clientID; -let clientSecret; -let authority; - -const clientCredentialRequestScopes = ["https://graph.microsoft.com/.default"]; +const clientCredentialRequestScopes = ["https://vault.azure.net/.default"]; -describe("Client Credentials AAD Prod Tests", () => { +describe("Client Credentials AAD Tests", () => { jest.retryTimes(RETRY_TIMES); jest.setTimeout(90000); + // Lab certificate credential (used for both tests) + let labCredential: LabCertificateCredential; + + // App configs from Key Vault + let s2sAppId: string; + let s2sAuthority: string; + let regionalAppId: string; + let regionalAuthority: string; + beforeAll(async () => { await validateCacheLocation(TEST_CACHE_LOCATION); - const labApiParms: LabApiQueryParams = { - appType: "cloud", - publicClient: "no", - signInAudience: "azureadmyorg", - }; + // Get the lab certificate credential (same cert used for Key Vault auth) + labCredential = getLabCredential(); - const labClient = new LabClient(); - const envResponse = await labClient.getVarsByCloudEnvironment( - labApiParms + // Get standard S2S app configuration from Key Vault + const s2sAppConfig = await LabResponseHelper.getAppConfig( + KeyVaultSecrets.AppS2S ); - [clientID, clientSecret, authority] = await retrieveAppConfiguration( - envResponse[0], - labClient, - true + s2sAppId = s2sAppConfig.appId!; + s2sAuthority = s2sAppConfig.authority!; + + // Get regional app configuration from Key Vault + const regionalAppConfig = await LabResponseHelper.getAppConfig( + KeyVaultSecrets.MsalAppAzureAdMultipleOrgsRegional ); + regionalAppId = regionalAppConfig.appId!; + regionalAuthority = regionalAppConfig.authority!; - // Update the complete config - config.authOptions.clientId = clientID; - config.authOptions.clientSecret = clientSecret; - config.authOptions.authority = authority; + console.log( + `Test setup complete - S2S App ID: ${s2sAppId}, Regional App ID: ${regionalAppId}` + ); }); - describe("Acquire Token", () => { + describe("Acquire Token with Certificate", () => { let confidentialClientApplication: ConfidentialClientApplication; beforeAll(async () => { @@ -63,13 +76,23 @@ describe("Client Credentials AAD Prod Tests", () => { it("Performs acquire token", async () => { confidentialClientApplication = new ConfidentialClientApplication({ - auth: config.authOptions, + auth: { + clientId: s2sAppId, + authority: s2sAuthority, + clientCertificate: { + thumbprintSha256: labCredential.thumbprintSha256, + privateKey: labCredential.privateKey, + x5c: labCredential.x5c, + }, + }, cache: { cachePlugin }, }); + await getClientCredentialsToken( confidentialClientApplication, clientCredentialRequestScopes ); + const cachedTokens = await NodeCacheTestUtils.getTokens( TEST_CACHE_LOCATION ); @@ -78,14 +101,24 @@ describe("Client Credentials AAD Prod Tests", () => { it("Performs acquire token through regional authorities", async () => { confidentialClientApplication = new ConfidentialClientApplication({ - auth: config.authOptions, + auth: { + clientId: regionalAppId, + authority: regionalAuthority, + clientCertificate: { + thumbprintSha256: labCredential.thumbprintSha256, + privateKey: labCredential.privateKey, + x5c: labCredential.x5c, + }, + }, cache: { cachePlugin }, }); + await getClientCredentialsToken( confidentialClientApplication, clientCredentialRequestScopes, { region: "westus2" } ); + const cachedTokens = await NodeCacheTestUtils.getTokens( TEST_CACHE_LOCATION ); diff --git a/samples/msal-node-samples/device-code/test/device-code-aad-agc.spec.ts b/samples/msal-node-samples/device-code/test/device-code-aad-agc.spec.ts index b207061703..4cb2b28768 100644 --- a/samples/msal-node-samples/device-code/test/device-code-aad-agc.spec.ts +++ b/samples/msal-node-samples/device-code/test/device-code-aad-agc.spec.ts @@ -6,15 +6,17 @@ import * as puppeteer from "puppeteer"; import { Screenshot, - createFolder, - RETRY_TIMES, approveRemoteConnect, enterCredentials, enterDeviceCode, - validateCacheLocation, + LabResponseHelper, + KeyVaultSecrets, + LabUser, + AppConfig, NodeCacheTestUtils, - getKeyVaultSecretClient, - getCredentials, + validateCacheLocation, + createFolder, + RETRY_TIMES, } from "e2e-test-utils"; import { Configuration, PublicClientApplication } from "@azure/msal-node"; import path from "path"; @@ -30,16 +32,6 @@ const cachePlugin = require("../../cachePlugin.js")(TEST_CACHE_LOCATION); // Load scenario configuration const config = require("../config/AAD-AGC.json"); -config.authOptions = { - clientId: process.env.AZURE_CLIENT_ID, - authority: `${process.env.AUTHORITY}/${process.env.AZURE_TENANT_ID}`, - knownAuthorities: [ - `${process.env.AUTHORITY}/${process.env.AZURE_TENANT_ID}`, - ], -}; -config.resourceApi = { - endpoint: `${process.env.GRAPH_URL}/v1.0/me`, -}; describe("Device Code AAD AGC Tests", () => { jest.setTimeout(45000); @@ -50,10 +42,13 @@ describe("Device Code AAD AGC Tests", () => { let publicClientApplication: PublicClientApplication; let clientConfig: Configuration; - let username: string; - let password: string; + let labUser: LabUser; + let appConfig: AppConfig; - const screenshotFolder = path.join(__dirname, "screenshots/device-code/aad-agc"); + const screenshotFolder = path.join( + __dirname, + "screenshots/device-code/aad-agc" + ); beforeAll(async () => { await validateCacheLocation(TEST_CACHE_LOCATION); @@ -61,8 +56,26 @@ describe("Device Code AAD AGC Tests", () => { browser = await global.__BROWSER__; createFolder(screenshotFolder); - const keyVaultSecretClient = await getKeyVaultSecretClient(); - [username, password] = await getCredentials(keyVaultSecretClient); + labUser = await LabResponseHelper.getLabUser( + KeyVaultSecrets.UserArlington + ); + appConfig = await LabResponseHelper.getAppConfig( + KeyVaultSecrets.ArlAppIdLabsApp + ); + + // Configure auth options from Key Vault app config + config.authOptions = { + clientId: appConfig.appId, + authority: appConfig.authority, + knownAuthorities: appConfig.authority + ? [new URL(appConfig.authority).origin] + : [], + }; + config.resourceApi = { + endpoint: appConfig.authority + ? `${new URL(appConfig.authority).origin}/v1.0/me` + : undefined, + }; }); afterAll(async () => { @@ -89,6 +102,7 @@ describe("Device Code AAD AGC Tests", () => { it("Performs acquire token with Device Code flow", async () => { const screenshot = new Screenshot(`${screenshotFolder}/BaseCase`); + const password = await labUser.getPassword(); const deviceCodeCallback = async (deviceCodeResponse: any) => { const { userCode, verificationUri } = deviceCodeResponse; @@ -99,7 +113,7 @@ describe("Device Code AAD AGC Tests", () => { verificationUri ); await approveRemoteConnect(page, screenshot); - await enterCredentials(page, screenshot, username, password); + await enterCredentials(page, screenshot, labUser.upn, password); await page.waitForSelector("#message"); await screenshot.takeScreenshot( page, diff --git a/samples/msal-node-samples/device-code/test/device-code-aad.spec.ts b/samples/msal-node-samples/device-code/test/device-code-aad.spec.ts index 5be072f9b6..8660753193 100644 --- a/samples/msal-node-samples/device-code/test/device-code-aad.spec.ts +++ b/samples/msal-node-samples/device-code/test/device-code-aad.spec.ts @@ -6,18 +6,16 @@ import * as puppeteer from "puppeteer"; import { Screenshot, - createFolder, - setupCredentials, - RETRY_TIMES, approveRemoteConnect, enterCredentials, enterDeviceCode, - validateCacheLocation, + LabResponseHelper, + KeyVaultSecrets, + LabUser, NodeCacheTestUtils, - LabClient, - LabApiQueryParams, - AppTypes, - AzureEnvironments, + validateCacheLocation, + createFolder, + RETRY_TIMES, } from "e2e-test-utils"; import { Configuration, PublicClientApplication } from "@azure/msal-node"; import path from "path"; @@ -43,10 +41,12 @@ describe("Device Code AAD Prod Tests", () => { let publicClientApplication: PublicClientApplication; let clientConfig: Configuration; - let username: string; - let accountPwd: string; + let labUser: LabUser; - const screenshotFolder = path.join(__dirname, "screenshots/device-code/aad"); + const screenshotFolder = path.join( + __dirname, + "screenshots/device-code/aad" + ); beforeAll(async () => { await validateCacheLocation(TEST_CACHE_LOCATION); @@ -54,19 +54,8 @@ describe("Device Code AAD Prod Tests", () => { browser = await global.__BROWSER__; createFolder(screenshotFolder); - // Configure Lab API Query Parameters - const labApiParms: LabApiQueryParams = { - azureEnvironment: AzureEnvironments.CLOUD, - appType: AppTypes.CLOUD, - }; - - const labClient = new LabClient(); - const envResponse = await labClient.getVarsByCloudEnvironment( - labApiParms - ); - [username, accountPwd] = await setupCredentials( - envResponse[0], - labClient + labUser = await LabResponseHelper.getLabUser( + KeyVaultSecrets.UserPublicCloud ); }); @@ -94,6 +83,7 @@ describe("Device Code AAD Prod Tests", () => { it("Performs acquire token with Device Code flow", async () => { const screenshot = new Screenshot(`${screenshotFolder}/BaseCase`); + const accountPwd = await labUser.getPassword(); const deviceCodeCallback = async (deviceCodeResponse: any) => { const { userCode, verificationUri } = deviceCodeResponse; @@ -104,7 +94,12 @@ describe("Device Code AAD Prod Tests", () => { verificationUri ); await approveRemoteConnect(page, screenshot); - await enterCredentials(page, screenshot, username, accountPwd); + await enterCredentials( + page, + screenshot, + labUser.upn, + accountPwd + ); await page.waitForSelector("#message"); await screenshot.takeScreenshot( page, diff --git a/samples/msal-node-samples/device-code/test/device-code-adfs.spec.ts b/samples/msal-node-samples/device-code/test/device-code-adfs.spec.ts index c93a958657..c2ee6e2f4e 100644 --- a/samples/msal-node-samples/device-code/test/device-code-adfs.spec.ts +++ b/samples/msal-node-samples/device-code/test/device-code-adfs.spec.ts @@ -6,19 +6,15 @@ import * as puppeteer from "puppeteer"; import { Screenshot, - createFolder, - setupCredentials, - RETRY_TIMES, enterCredentialsADFSWithConsent, enterDeviceCode, - validateCacheLocation, + LabResponseHelper, + KeyVaultSecrets, + LabUser, NodeCacheTestUtils, - LabClient, - LabApiQueryParams, - AppTypes, - AzureEnvironments, - FederationProviders, - UserTypes, + validateCacheLocation, + createFolder, + RETRY_TIMES, } from "e2e-test-utils"; import path from "path"; import { Configuration, PublicClientApplication } from "@azure/msal-node"; @@ -44,10 +40,12 @@ describe.skip("Device Code ADFS 2019 Tests", () => { let publicClientApplication: PublicClientApplication; let clientConfig: Configuration; - let username: string; - let accountPwd: string; + let labUser: LabUser; - const screenshotFolder = path.join(__dirname, "screenshots/device-code/adfs"); + const screenshotFolder = path.join( + __dirname, + "screenshots/device-code/adfs" + ); beforeAll(async () => { await validateCacheLocation(TEST_CACHE_LOCATION); @@ -55,21 +53,8 @@ describe.skip("Device Code ADFS 2019 Tests", () => { browser = await global.__BROWSER__; createFolder(screenshotFolder); - // Configure Lab API Query Parameters - const labApiParms: LabApiQueryParams = { - azureEnvironment: AzureEnvironments.CLOUD, - appType: AppTypes.CLOUD, - federationProvider: FederationProviders.ADFS2019, - userType: UserTypes.FEDERATED, - }; - - const labClient = new LabClient(); - const envResponse = await labClient.getVarsByCloudEnvironment( - labApiParms - ); - [username, accountPwd] = await setupCredentials( - envResponse[0], - labClient + labUser = await LabResponseHelper.getLabUser( + KeyVaultSecrets.UserFederated ); }); @@ -97,6 +82,7 @@ describe.skip("Device Code ADFS 2019 Tests", () => { it("Performs acquire token with Device Code flow", async () => { const screenshot = new Screenshot(`${screenshotFolder}/BaseCase`); + const accountPwd = await labUser.getPassword(); const deviceCodeCallback = async (deviceCodeResponse: any) => { const { userCode, verificationUri } = deviceCodeResponse; @@ -109,7 +95,7 @@ describe.skip("Device Code ADFS 2019 Tests", () => { await enterCredentialsADFSWithConsent( page, screenshot, - username, + labUser.upn, accountPwd ); await page.waitForSelector("#message"); diff --git a/samples/msal-node-samples/on-behalf-of/test/obo-aad.spec.ts b/samples/msal-node-samples/on-behalf-of/test/obo-aad.spec.ts index d2d3610629..9a2c0e1873 100644 --- a/samples/msal-node-samples/on-behalf-of/test/obo-aad.spec.ts +++ b/samples/msal-node-samples/on-behalf-of/test/obo-aad.spec.ts @@ -6,16 +6,14 @@ import * as puppeteer from "puppeteer"; import { Screenshot, - createFolder, - setupCredentials, - enterCredentials - validateCacheLocation, + enterCredentials, SAMPLE_HOME_URL, + LabResponseHelper, + KeyVaultSecrets, + LabUser, NodeCacheTestUtils, - LabClient, - LabApiQueryParams, - AppTypes, - AzureEnvironments, + validateCacheLocation, + createFolder, } from "e2e-test-utils"; import { ConfidentialClientApplication, LogLevel } from "@azure/msal-node"; import path from "path"; @@ -56,10 +54,9 @@ describe("OBO AAD Tests", () => { let context: puppeteer.BrowserContext; let page: puppeteer.Page; - let username: string; - let accountPwd: string; + let labUser: LabUser; - const screenshotFolder = path.join(__dirname, "screenshots/on-behalf-of") + const screenshotFolder = path.join(__dirname, "screenshots/on-behalf-of"); beforeAll(async () => { await validateCacheLocation(WEB_APP_TEST_CACHE_LOCATION); @@ -69,18 +66,8 @@ describe("OBO AAD Tests", () => { createFolder(screenshotFolder); - const labApiParms: LabApiQueryParams = { - azureEnvironment: AzureEnvironments.CLOUD, - appType: AppTypes.CLOUD, - }; - - const labClient = new LabClient(); - const envResponse = await labClient.getVarsByCloudEnvironment( - labApiParms - ); - [username, accountPwd] = await setupCredentials( - envResponse[0], - labClient + labUser = await LabResponseHelper.getLabUser( + KeyVaultSecrets.UserPublicCloud ); }); @@ -164,8 +151,9 @@ describe("OBO AAD Tests", () => { it("Performs acquire token via OBO flow", async () => { const screenshot = new Screenshot(`${screenshotFolder}/BaseCase`); + const accountPwd = await labUser.getPassword(); await page.goto(HOME_ROUTE); - await enterCredentials(page, screenshot, username, accountPwd); + await enterCredentials(page, screenshot, labUser.upn, accountPwd); await page.waitForFunction( `window.location.href.startsWith("${SAMPLE_HOME_URL}")` ); @@ -184,7 +172,7 @@ describe("OBO AAD Tests", () => { expect(Object.keys(accounts).length).toBe(1); const account = Object.values(accounts)[0]; - expect(account.username).toEqual(username); + expect(account.username).toEqual(labUser.upn); }); }); }); diff --git a/samples/msal-node-samples/silent-flow/test/silent-flow-aad-agc-confidential.spec.ts b/samples/msal-node-samples/silent-flow/test/silent-flow-aad-agc-confidential.spec.ts index 1e1db4dfb9..ac7bf1f6df 100644 --- a/samples/msal-node-samples/silent-flow/test/silent-flow-aad-agc-confidential.spec.ts +++ b/samples/msal-node-samples/silent-flow/test/silent-flow-aad-agc-confidential.spec.ts @@ -6,19 +6,21 @@ import * as puppeteer from "puppeteer"; import { Screenshot, - createFolder, - ONE_SECOND_IN_MS, - RETRY_TIMES, clickSignIn, enterCredentials, SAMPLE_HOME_URL, SUCCESSFUL_GRAPH_CALL_ID, SUCCESSFUL_GET_ALL_ACCOUNTS_ID, - validateCacheLocation, SUCCESSFUL_SILENT_TOKEN_ACQUISITION_ID, + LabResponseHelper, + KeyVaultSecrets, + LabUser, + AppConfig, NodeCacheTestUtils, - getKeyVaultSecretClient, - getCredentials, + validateCacheLocation, + createFolder, + RETRY_TIMES, + ONE_SECOND_IN_MS, } from "e2e-test-utils"; import { ConfidentialClientApplication, TokenCache } from "@azure/msal-node"; import path from "path"; @@ -34,18 +36,6 @@ const cachePlugin = require("../../cachePlugin.js")(TEST_CACHE_LOCATION); // Load scenario configuration const config = require("../config/AAD-AGC-Confidential.json"); -config.authOptions = { - ...config.authOptions, - clientId: process.env.AZURE_CLIENT_ID, - clientSecret: process.env.AZURE_CLIENT_SECRET, - authority: `${process.env.AUTHORITY}/${process.env.AZURE_TENANT_ID}`, - knownAuthorities: [ - `${process.env.AUTHORITY}/${process.env.AZURE_TENANT_ID}`, - ], -}; -config.resourceApi = { - endpoint: `${process.env.GRAPH_URL}/v1.0/me`, -}; describe("Silent Flow AAD AGC Confidential Tests", () => { jest.retryTimes(RETRY_TIMES); @@ -60,10 +50,13 @@ describe("Silent Flow AAD AGC Confidential Tests", () => { let msalTokenCache: TokenCache; let server: any; - let username: string; - let password: string; + let labUser: LabUser; + let appConfig: AppConfig; - const screenshotFolder = path.join(__dirname, "screenshots/silent-flow/aad-agc-confidential"); + const screenshotFolder = path.join( + __dirname, + "screenshots/silent-flow/aad-agc-confidential" + ); beforeAll(async () => { await validateCacheLocation(TEST_CACHE_LOCATION); @@ -74,8 +67,37 @@ describe("Silent Flow AAD AGC Confidential Tests", () => { createFolder(screenshotFolder); - const keyVaultSecretClient = await getKeyVaultSecretClient(); - [username, password] = await getCredentials(keyVaultSecretClient); + labUser = await LabResponseHelper.getLabUser( + KeyVaultSecrets.UserArlington + ); + appConfig = await LabResponseHelper.getAppConfig( + KeyVaultSecrets.MsalAppArlingtonCCA + ); + + // Get client secret from Key Vault + let clientSecret: string | undefined; + if (appConfig.secretName) { + clientSecret = await LabResponseHelper.getSecret( + appConfig.secretName + ); + } + + // Configure auth options from Key Vault app config + const authorityUrl = appConfig.authority + ? new URL(appConfig.authority) + : null; + config.authOptions = { + ...config.authOptions, + clientId: appConfig.appId, + clientSecret: clientSecret, + authority: appConfig.authority, + knownAuthorities: authorityUrl ? [authorityUrl.origin] : [], + }; + config.resourceApi = { + endpoint: authorityUrl + ? `${authorityUrl.origin}/v1.0/me` + : undefined, + }; confidentialClientApplication = new ConfidentialClientApplication({ auth: config.authOptions, @@ -116,8 +138,9 @@ describe("Silent Flow AAD AGC Confidential Tests", () => { const screenshot = new Screenshot( `${screenshotFolder}/AcquireTokenAuthCode` ); + const password = await labUser.getPassword(); await clickSignIn(page, screenshot); - await enterCredentials(page, screenshot, username, password); + await enterCredentials(page, screenshot, labUser.upn, password); await page.waitForSelector("#acquireTokenSilent"); await page.click("#acquireTokenSilent"); const cachedTokens = await NodeCacheTestUtils.waitForTokens( @@ -133,8 +156,9 @@ describe("Silent Flow AAD AGC Confidential Tests", () => { const screenshot = new Screenshot( `${screenshotFolder}/AcquireTokenSilent` ); + const password = await labUser.getPassword(); await clickSignIn(page, screenshot); - await enterCredentials(page, screenshot, username, password); + await enterCredentials(page, screenshot, labUser.upn, password); await page.waitForSelector("#acquireTokenSilent"); await screenshot.takeScreenshot(page, "ATS"); await page.click("#acquireTokenSilent"); @@ -155,8 +179,9 @@ describe("Silent Flow AAD AGC Confidential Tests", () => { const screenshot = new Screenshot( `${screenshotFolder}/RefreshExpiredToken` ); + const password = await labUser.getPassword(); await clickSignIn(page, screenshot); - await enterCredentials(page, screenshot, username, password); + await enterCredentials(page, screenshot, labUser.upn, password); await page.waitForSelector("#acquireTokenSilent"); let tokens = await NodeCacheTestUtils.waitForTokens( @@ -218,8 +243,9 @@ describe("Silent Flow AAD AGC Confidential Tests", () => { const screenshot = new Screenshot( `${screenshotFolder}/GetAllAccounts` ); + const password = await labUser.getPassword(); await clickSignIn(page, screenshot); - await enterCredentials(page, screenshot, username, password); + await enterCredentials(page, screenshot, labUser.upn, password); await page.waitForSelector("#getAllAccounts"); await page.click("#getAllAccounts"); await page.waitForSelector( diff --git a/samples/msal-node-samples/silent-flow/test/silent-flow-aad-agc-public.spec.ts b/samples/msal-node-samples/silent-flow/test/silent-flow-aad-agc-public.spec.ts index be82e71a53..5d5d8a2246 100644 --- a/samples/msal-node-samples/silent-flow/test/silent-flow-aad-agc-public.spec.ts +++ b/samples/msal-node-samples/silent-flow/test/silent-flow-aad-agc-public.spec.ts @@ -6,19 +6,21 @@ import * as puppeteer from "puppeteer"; import { Screenshot, - createFolder, - ONE_SECOND_IN_MS, - RETRY_TIMES, clickSignIn, enterCredentials, SAMPLE_HOME_URL, SUCCESSFUL_GRAPH_CALL_ID, SUCCESSFUL_GET_ALL_ACCOUNTS_ID, - validateCacheLocation, SUCCESSFUL_SILENT_TOKEN_ACQUISITION_ID, + LabResponseHelper, + KeyVaultSecrets, + LabUser, + AppConfig, NodeCacheTestUtils, - getKeyVaultSecretClient, - getCredentials, + validateCacheLocation, + createFolder, + RETRY_TIMES, + ONE_SECOND_IN_MS, } from "e2e-test-utils"; import { PublicClientApplication, TokenCache } from "@azure/msal-node"; import path from "path"; @@ -34,17 +36,6 @@ const cachePlugin = require("../../cachePlugin.js")(TEST_CACHE_LOCATION); // Load scenario configuration const config = require("../config/AAD-AGC-Public.json"); -config.authOptions = { - ...config.authOptions, - clientId: process.env.AZURE_CLIENT_ID, - authority: `${process.env.AUTHORITY}/${process.env.AZURE_TENANT_ID}`, - knownAuthorities: [ - `${process.env.AUTHORITY}/${process.env.AZURE_TENANT_ID}`, - ], -}; -config.resourceApi = { - endpoint: `${process.env.AUTHORITY}/v1.0/me`, -}; describe("Silent Flow AAD AGC Public Tests", () => { jest.retryTimes(RETRY_TIMES); @@ -59,10 +50,13 @@ describe("Silent Flow AAD AGC Public Tests", () => { let msalTokenCache: TokenCache; let server: any; - let username: string; - let password: string; + let labUser: LabUser; + let appConfig: AppConfig; - const screenshotFolder = path.join(__dirname, "screenshots/silent-flow/aad-agc-public"); + const screenshotFolder = path.join( + __dirname, + "screenshots/silent-flow/aad-agc-public" + ); beforeAll(async () => { await validateCacheLocation(TEST_CACHE_LOCATION); @@ -73,8 +67,25 @@ describe("Silent Flow AAD AGC Public Tests", () => { createFolder(screenshotFolder); - const keyVaultSecretClient = await getKeyVaultSecretClient(); - [username, password] = await getCredentials(keyVaultSecretClient); + labUser = await LabResponseHelper.getLabUser( + KeyVaultSecrets.UserArlington + ); + appConfig = await LabResponseHelper.getAppConfig( + KeyVaultSecrets.ArlAppIdLabsApp + ); + + // Configure auth options from Key Vault app config + config.authOptions = { + ...config.authOptions, + clientId: appConfig.appId, + authority: appConfig.authority, + knownAuthorities: appConfig.authority + ? [new URL(appConfig.authority).origin] + : [], + }; + config.resourceApi = { + endpoint: `${new URL(appConfig.authority!).origin}/v1.0/me`, + }; publicClientApplication = new PublicClientApplication({ auth: config.authOptions, @@ -115,8 +126,9 @@ describe("Silent Flow AAD AGC Public Tests", () => { const screenshot = new Screenshot( `${screenshotFolder}/AcquireTokenAuthCode` ); + const password = await labUser.getPassword(); await clickSignIn(page, screenshot); - await enterCredentials(page, screenshot, username, password); + await enterCredentials(page, screenshot, labUser.upn, password); await page.waitForSelector("#acquireTokenSilent"); await page.click("#acquireTokenSilent"); const cachedTokens = await NodeCacheTestUtils.waitForTokens( @@ -132,8 +144,9 @@ describe("Silent Flow AAD AGC Public Tests", () => { const screenshot = new Screenshot( `${screenshotFolder}/AcquireTokenSilent` ); + const password = await labUser.getPassword(); await clickSignIn(page, screenshot); - await enterCredentials(page, screenshot, username, password); + await enterCredentials(page, screenshot, labUser.upn, password); await page.waitForSelector("#acquireTokenSilent"); await screenshot.takeScreenshot(page, "ATS"); await page.click("#acquireTokenSilent"); @@ -154,8 +167,9 @@ describe("Silent Flow AAD AGC Public Tests", () => { const screenshot = new Screenshot( `${screenshotFolder}/AcquireTokenSilentFromPersistent` ); + const password = await labUser.getPassword(); await clickSignIn(page, screenshot); - await enterCredentials(page, screenshot, username, password); + await enterCredentials(page, screenshot, labUser.upn, password); await page.waitForSelector("#acquireTokenSilent"); publicClientApplication.clearCache(); await screenshot.takeScreenshot(page, "ATS"); @@ -177,8 +191,9 @@ describe("Silent Flow AAD AGC Public Tests", () => { const screenshot = new Screenshot( `${screenshotFolder}/RefreshExpiredToken` ); + const password = await labUser.getPassword(); await clickSignIn(page, screenshot); - await enterCredentials(page, screenshot, username, password); + await enterCredentials(page, screenshot, labUser.upn, password); await page.waitForSelector("#acquireTokenSilent"); let tokens = await NodeCacheTestUtils.waitForTokens( @@ -240,8 +255,9 @@ describe("Silent Flow AAD AGC Public Tests", () => { const screenshot = new Screenshot( `${screenshotFolder}/GetAllAccounts` ); + const password = await labUser.getPassword(); await clickSignIn(page, screenshot); - await enterCredentials(page, screenshot, username, password); + await enterCredentials(page, screenshot, labUser.upn, password); await page.waitForSelector("#getAllAccounts"); await page.click("#getAllAccounts"); await page.waitForSelector( diff --git a/samples/msal-node-samples/silent-flow/test/silent-flow-aad.spec.ts b/samples/msal-node-samples/silent-flow/test/silent-flow-aad.spec.ts index 74b8bddf17..289c8813c2 100644 --- a/samples/msal-node-samples/silent-flow/test/silent-flow-aad.spec.ts +++ b/samples/msal-node-samples/silent-flow/test/silent-flow-aad.spec.ts @@ -6,22 +6,20 @@ import * as puppeteer from "puppeteer"; import { Screenshot, - createFolder, - setupCredentials, - ONE_SECOND_IN_MS, - RETRY_TIMES, clickSignIn, enterCredentials, SAMPLE_HOME_URL, SUCCESSFUL_GRAPH_CALL_ID, SUCCESSFUL_GET_ALL_ACCOUNTS_ID, - validateCacheLocation, SUCCESSFUL_SILENT_TOKEN_ACQUISITION_ID, + LabResponseHelper, + KeyVaultSecrets, + LabUser, NodeCacheTestUtils, - LabClient, - LabApiQueryParams, - AppTypes, - AzureEnvironments, + validateCacheLocation, + createFolder, + RETRY_TIMES, + ONE_SECOND_IN_MS, } from "e2e-test-utils"; import path from "path"; import { PublicClientApplication, TokenCache } from "@azure/msal-node"; @@ -51,10 +49,12 @@ describe("Silent Flow AAD Prod Tests", () => { let msalTokenCache: TokenCache; let server: any; - let username: string; - let accountPwd: string; + let labUser: LabUser; - const screenshotFolder = path.join(__dirname, "screenshots/silent-flow/aad"); + const screenshotFolder = path.join( + __dirname, + "screenshots/silent-flow/aad" + ); beforeAll(async () => { await validateCacheLocation(TEST_CACHE_LOCATION); @@ -65,19 +65,8 @@ describe("Silent Flow AAD Prod Tests", () => { createFolder(screenshotFolder); - const labApiParms: LabApiQueryParams = { - azureEnvironment: AzureEnvironments.CLOUD, - appType: AppTypes.CLOUD, - }; - - const labClient = new LabClient(); - const envResponse = await labClient.getVarsByCloudEnvironment( - labApiParms - ); - - [username, accountPwd] = await setupCredentials( - envResponse[0], - labClient + labUser = await LabResponseHelper.getLabUser( + KeyVaultSecrets.UserPublicCloud ); publicClientApplication = new PublicClientApplication({ @@ -119,8 +108,9 @@ describe("Silent Flow AAD Prod Tests", () => { const screenshot = new Screenshot( `${screenshotFolder}/AcquireTokenAuthCode` ); + const accountPwd = await labUser.getPassword(); await clickSignIn(page, screenshot); - await enterCredentials(page, screenshot, username, accountPwd); + await enterCredentials(page, screenshot, labUser.upn, accountPwd); await page.waitForSelector("#acquireTokenSilent"); await page.click("#acquireTokenSilent"); const cachedTokens = await NodeCacheTestUtils.waitForTokens( @@ -136,8 +126,9 @@ describe("Silent Flow AAD Prod Tests", () => { const screenshot = new Screenshot( `${screenshotFolder}/AcquireTokenSilent` ); + const accountPwd = await labUser.getPassword(); await clickSignIn(page, screenshot); - await enterCredentials(page, screenshot, username, accountPwd); + await enterCredentials(page, screenshot, labUser.upn, accountPwd); await page.waitForSelector("#acquireTokenSilent"); await screenshot.takeScreenshot(page, "ATS"); await page.click("#acquireTokenSilent"); @@ -158,8 +149,9 @@ describe("Silent Flow AAD Prod Tests", () => { const screenshot = new Screenshot( `${screenshotFolder}/AcquireTokenSilentFromPersistent` ); + const accountPwd = await labUser.getPassword(); await clickSignIn(page, screenshot); - await enterCredentials(page, screenshot, username, accountPwd); + await enterCredentials(page, screenshot, labUser.upn, accountPwd); await page.waitForSelector("#acquireTokenSilent"); await publicClientApplication.clearCache(); await screenshot.takeScreenshot(page, "ATS"); @@ -181,8 +173,9 @@ describe("Silent Flow AAD Prod Tests", () => { const screenshot = new Screenshot( `${screenshotFolder}/RefreshExpiredToken` ); + const accountPwd = await labUser.getPassword(); await clickSignIn(page, screenshot); - await enterCredentials(page, screenshot, username, accountPwd); + await enterCredentials(page, screenshot, labUser.upn, accountPwd); await page.waitForSelector("#acquireTokenSilent"); let tokens = await NodeCacheTestUtils.waitForTokens( @@ -244,8 +237,14 @@ describe("Silent Flow AAD Prod Tests", () => { const screenshot = new Screenshot( `${screenshotFolder}/GetAllAccounts` ); + const accountPwd = await labUser.getPassword(); await clickSignIn(page, screenshot); - await enterCredentials(page, screenshot, username, accountPwd); + await enterCredentials( + page, + screenshot, + labUser.upn, + accountPwd + ); await page.waitForSelector("#getAllAccounts"); await page.click("#getAllAccounts"); await page.waitForSelector( diff --git a/samples/msal-node-samples/silent-flow/test/silent-flow-adfs.spec.ts b/samples/msal-node-samples/silent-flow/test/silent-flow-adfs.spec.ts index d92993f3a1..3c49eea951 100644 --- a/samples/msal-node-samples/silent-flow/test/silent-flow-adfs.spec.ts +++ b/samples/msal-node-samples/silent-flow/test/silent-flow-adfs.spec.ts @@ -6,24 +6,20 @@ import * as puppeteer from "puppeteer"; import { Screenshot, - createFolder, - setupCredentials, - ONE_SECOND_IN_MS, - RETRY_TIMES, clickSignIn, enterCredentialsADFS, SAMPLE_HOME_URL, SUCCESSFUL_GRAPH_CALL_ID, SUCCESSFUL_GET_ALL_ACCOUNTS_ID, - validateCacheLocation, SUCCESSFUL_SILENT_TOKEN_ACQUISITION_ID, + LabResponseHelper, + KeyVaultSecrets, + LabUser, NodeCacheTestUtils, - LabClient, - LabApiQueryParams, - AppTypes, - AzureEnvironments, - FederationProviders, - UserTypes, + validateCacheLocation, + createFolder, + RETRY_TIMES, + ONE_SECOND_IN_MS, } from "e2e-test-utils"; import path from "path"; import { PublicClientApplication, TokenCache } from "@azure/msal-node"; @@ -53,10 +49,12 @@ describe.skip("Silent Flow ADFS 2019 Tests", () => { let msalTokenCache: TokenCache; let server: any; - let username: string; - let accountPwd: string; + let labUser: LabUser; - const screenshotFolder = path.join(__dirname, "screenshots/silent-flow/adfs"); + const screenshotFolder = path.join( + __dirname, + "screenshots/silent-flow/adfs" + ); beforeAll(async () => { await validateCacheLocation(TEST_CACHE_LOCATION); @@ -66,21 +64,9 @@ describe.skip("Silent Flow ADFS 2019 Tests", () => { homeRoute = `${SAMPLE_HOME_URL}:${port}`; createFolder(screenshotFolder); - const labApiParms: LabApiQueryParams = { - azureEnvironment: AzureEnvironments.CLOUD, - appType: AppTypes.CLOUD, - federationProvider: FederationProviders.ADFS2019, - userType: UserTypes.FEDERATED, - }; - - const labClient = new LabClient(); - const envResponse = await labClient.getVarsByCloudEnvironment( - labApiParms - ); - [username, accountPwd] = await setupCredentials( - envResponse[0], - labClient + labUser = await LabResponseHelper.getLabUser( + KeyVaultSecrets.UserFederated ); publicClientApplication = new PublicClientApplication({ @@ -122,8 +108,14 @@ describe.skip("Silent Flow ADFS 2019 Tests", () => { const screenshot = new Screenshot( `${screenshotFolder}/AcquireTokenAuthCode` ); + const accountPwd = await labUser.getPassword(); await clickSignIn(page, screenshot); - await enterCredentialsADFS(page, screenshot, username, accountPwd); + await enterCredentialsADFS( + page, + screenshot, + labUser.upn, + accountPwd + ); await page.waitForSelector("#acquireTokenSilent"); await page.click("#acquireTokenSilent"); const cachedTokens = await NodeCacheTestUtils.waitForTokens( @@ -139,8 +131,14 @@ describe.skip("Silent Flow ADFS 2019 Tests", () => { const screenshot = new Screenshot( `${screenshotFolder}/AcquireTokenSilent` ); + const accountPwd = await labUser.getPassword(); await clickSignIn(page, screenshot); - await enterCredentialsADFS(page, screenshot, username, accountPwd); + await enterCredentialsADFS( + page, + screenshot, + labUser.upn, + accountPwd + ); await page.waitForSelector("#acquireTokenSilent"); await page.click("#acquireTokenSilent"); await page.waitForSelector( @@ -158,8 +156,14 @@ describe.skip("Silent Flow ADFS 2019 Tests", () => { const screenshot = new Screenshot( `${screenshotFolder}/AcquireTokenSilentFromPersistent` ); + const accountPwd = await labUser.getPassword(); await clickSignIn(page, screenshot); - await enterCredentialsADFS(page, screenshot, username, accountPwd); + await enterCredentialsADFS( + page, + screenshot, + labUser.upn, + accountPwd + ); await page.waitForSelector("#acquireTokenSilent"); publicClientApplication.clearCache(); await page.click("#acquireTokenSilent"); @@ -178,8 +182,14 @@ describe.skip("Silent Flow ADFS 2019 Tests", () => { const screenshot = new Screenshot( `${screenshotFolder}/RefreshExpiredToken` ); + const accountPwd = await labUser.getPassword(); await clickSignIn(page, screenshot); - await enterCredentialsADFS(page, screenshot, username, accountPwd); + await enterCredentialsADFS( + page, + screenshot, + labUser.upn, + accountPwd + ); await page.waitForSelector("#acquireTokenSilent"); let tokens = await NodeCacheTestUtils.waitForTokens( @@ -241,11 +251,12 @@ describe.skip("Silent Flow ADFS 2019 Tests", () => { const screenshot = new Screenshot( `${screenshotFolder}/GetAllAccounts` ); + const accountPwd = await labUser.getPassword(); await clickSignIn(page, screenshot); await enterCredentialsADFS( page, screenshot, - username, + labUser.upn, accountPwd ); await page.waitForSelector("#getAllAccounts"); diff --git a/samples/msal-node-samples/silent-flow/test/silent-flow-b2c-aad.spec.ts b/samples/msal-node-samples/silent-flow/test/silent-flow-b2c-aad.spec.ts index e574c77f4c..8765b4d043 100644 --- a/samples/msal-node-samples/silent-flow/test/silent-flow-b2c-aad.spec.ts +++ b/samples/msal-node-samples/silent-flow/test/silent-flow-b2c-aad.spec.ts @@ -6,20 +6,18 @@ import * as puppeteer from "puppeteer"; import { Screenshot, - createFolder, - setupCredentials, b2cAadPpeAccountEnterCredentials, - ONE_SECOND_IN_MS, - RETRY_TIMES, clickSignIn, SAMPLE_HOME_URL, SUCCESSFUL_GET_ALL_ACCOUNTS_ID, - validateCacheLocation, + LabResponseHelper, + KeyVaultSecrets, + LabUser, NodeCacheTestUtils, - LabClient, - LabApiQueryParams, - AppTypes, - AzureEnvironments, + validateCacheLocation, + createFolder, + RETRY_TIMES, + ONE_SECOND_IN_MS, } from "e2e-test-utils"; import path from "path"; import { PublicClientApplication, TokenCache } from "@azure/msal-node"; @@ -49,10 +47,12 @@ describe.skip("Silent Flow B2C Tests (aad account)", () => { let msalTokenCache: TokenCache; let server: any; - let username: string; - let accountPwd: string; + let labUser: LabUser; - const screenshotFolder = path.join(__dirname, "screenshots/silent-flow/b2c-aad"); + const screenshotFolder = path.join( + __dirname, + "screenshots/silent-flow/b2c-aad" + ); beforeAll(async () => { await validateCacheLocation(TEST_CACHE_LOCATION); @@ -65,18 +65,8 @@ describe.skip("Silent Flow B2C Tests (aad account)", () => { createFolder(screenshotFolder); - const labApiParms: LabApiQueryParams = { - azureEnvironment: AzureEnvironments.CLOUD, - appType: AppTypes.CLOUD, - }; - - const labClient = new LabClient(); - const envResponse = await labClient.getVarsByCloudEnvironment( - labApiParms - ); - [username, accountPwd] = await setupCredentials( - envResponse[0], - labClient + labUser = await LabResponseHelper.getLabUser( + KeyVaultSecrets.UserPublicCloud ); publicClientApplication = new PublicClientApplication({ @@ -119,11 +109,12 @@ describe.skip("Silent Flow B2C Tests (aad account)", () => { const screenshot = new Screenshot( `${screenshotFolder}/AcquireTokenAuthCode` ); + const accountPwd = await labUser.getPassword(); await clickSignIn(page, screenshot); await b2cAadPpeAccountEnterCredentials( page, screenshot, - username, + labUser.upn, accountPwd ); await page.waitForSelector("#acquireTokenSilent"); @@ -141,11 +132,12 @@ describe.skip("Silent Flow B2C Tests (aad account)", () => { const screenshot = new Screenshot( `${screenshotFolder}/AcquireTokenSilent` ); + const accountPwd = await labUser.getPassword(); await clickSignIn(page, screenshot); await b2cAadPpeAccountEnterCredentials( page, screenshot, - username, + labUser.upn, accountPwd ); await page.waitForSelector("#acquireTokenSilent"); @@ -164,11 +156,12 @@ describe.skip("Silent Flow B2C Tests (aad account)", () => { const screenshot = new Screenshot( `${screenshotFolder}/RefreshExpiredToken` ); + const accountPwd = await labUser.getPassword(); await clickSignIn(page, screenshot); await b2cAadPpeAccountEnterCredentials( page, screenshot, - username, + labUser.upn, accountPwd ); await page.waitForSelector("#acquireTokenSilent"); @@ -228,11 +221,12 @@ describe.skip("Silent Flow B2C Tests (aad account)", () => { const screenshot = new Screenshot( `${screenshotFolder}/GetAllAccounts` ); + const accountPwd = await labUser.getPassword(); await clickSignIn(page, screenshot); await b2cAadPpeAccountEnterCredentials( page, screenshot, - username, + labUser.upn, accountPwd ); await page.waitForSelector("#getAllAccounts"); diff --git a/samples/msal-node-samples/silent-flow/test/silent-flow-b2c-local.spec.ts b/samples/msal-node-samples/silent-flow/test/silent-flow-b2c-local.spec.ts index 8d7038ad47..d3112e92f0 100644 --- a/samples/msal-node-samples/silent-flow/test/silent-flow-b2c-local.spec.ts +++ b/samples/msal-node-samples/silent-flow/test/silent-flow-b2c-local.spec.ts @@ -6,20 +6,18 @@ import * as puppeteer from "puppeteer"; import { Screenshot, - createFolder, - setupCredentials, b2cLocalAccountEnterCredentials, - ONE_SECOND_IN_MS, - RETRY_TIMES, clickSignIn, SAMPLE_HOME_URL, SUCCESSFUL_GET_ALL_ACCOUNTS_ID, - validateCacheLocation, + LabResponseHelper, + KeyVaultSecrets, + LabUser, NodeCacheTestUtils, - LabClient, - LabApiQueryParams, - B2cProviders, - UserTypes, + validateCacheLocation, + createFolder, + RETRY_TIMES, + ONE_SECOND_IN_MS, } from "e2e-test-utils"; import { PublicClientApplication, TokenCache } from "@azure/msal-node"; import path from "path"; @@ -49,10 +47,12 @@ describe("Silent Flow B2C Tests", () => { let msalTokenCache: TokenCache; let server: any; - let username: string; - let accountPwd: string; + let labUser: LabUser; - const screenshotFolder = path.join(__dirname, "screenshots/silent-flow/b2c-local"); + const screenshotFolder = path.join( + __dirname, + "screenshots/silent-flow/b2c-local" + ); beforeAll(async () => { await validateCacheLocation(TEST_CACHE_LOCATION); @@ -65,19 +65,7 @@ describe("Silent Flow B2C Tests", () => { createFolder(screenshotFolder); - const labApiParms: LabApiQueryParams = { - userType: UserTypes.B2C, - b2cProvider: B2cProviders.LOCAL, - }; - - const labClient = new LabClient(); - const envResponse = await labClient.getVarsByCloudEnvironment( - labApiParms - ); - [username, accountPwd] = await setupCredentials( - envResponse[0], - labClient - ); + labUser = await LabResponseHelper.getLabUser(KeyVaultSecrets.UserB2C); publicClientApplication = new PublicClientApplication({ auth: config.authOptions, @@ -119,11 +107,12 @@ describe("Silent Flow B2C Tests", () => { const screenshot = new Screenshot( `${screenshotFolder}/AcquireTokenAuthCode` ); + const accountPwd = await labUser.getPassword(); await clickSignIn(page, screenshot); await b2cLocalAccountEnterCredentials( page, screenshot, - username, + labUser.upn, accountPwd ); await page.waitForSelector("#acquireTokenSilent"); @@ -141,11 +130,12 @@ describe("Silent Flow B2C Tests", () => { const screenshot = new Screenshot( `${screenshotFolder}/AcquireTokenSilent` ); + const accountPwd = await labUser.getPassword(); await clickSignIn(page, screenshot); await b2cLocalAccountEnterCredentials( page, screenshot, - username, + labUser.upn, accountPwd ); await page.waitForSelector("#acquireTokenSilent"); @@ -164,11 +154,12 @@ describe("Silent Flow B2C Tests", () => { const screenshot = new Screenshot( `${screenshotFolder}/RefreshExpiredToken` ); + const accountPwd = await labUser.getPassword(); await clickSignIn(page, screenshot); await b2cLocalAccountEnterCredentials( page, screenshot, - username, + labUser.upn, accountPwd ); await page.waitForSelector("#acquireTokenSilent"); @@ -228,11 +219,12 @@ describe("Silent Flow B2C Tests", () => { const screenshot = new Screenshot( `${screenshotFolder}/GetAllAccounts` ); + const accountPwd = await labUser.getPassword(); await clickSignIn(page, screenshot); await b2cLocalAccountEnterCredentials( page, screenshot, - username, + labUser.upn, accountPwd ); await page.waitForSelector("#getAllAccounts");