diff --git a/common/config/rush/common-versions.json b/common/config/rush/common-versions.json index 77b7991698a1..98ee83e5af85 100644 --- a/common/config/rush/common-versions.json +++ b/common/config/rush/common-versions.json @@ -69,7 +69,8 @@ // @azure/event-processor-host is on a much lower major version "@azure/ms-rest-nodeauth": ["^0.9.2"], // Idenity is moving from v1 to v2. Moving all packages to v2 is going to take a bit of time, in the mean time we could use v2 on the perf-identity tests. - "@azure/identity": ["2.0.0-beta.3", "^1.1.0"], + "@azure/identity": ["^2.0.0-beta.4", "2.0.0-beta.3", "^1.1.0"], + // App Config uses keyvault-secrets in a sample, switch to latest once the preview becomes GA // Issue #14771 tracks updating to these versions "@microsoft/api-extractor": ["7.13.2"], "prettier": ["2.2.1"], diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index 9335db93b216..6e5303ec974d 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -39,6 +39,8 @@ dependencies: '@rush-temp/eventgrid': file:projects/eventgrid.tgz '@rush-temp/eventhubs-checkpointstore-blob': file:projects/eventhubs-checkpointstore-blob.tgz '@rush-temp/identity': file:projects/identity.tgz + '@rush-temp/identity-cache-persistence': file:projects/identity-cache-persistence.tgz + '@rush-temp/identity-vscode': file:projects/identity-vscode.tgz '@rush-temp/iot-device-update': file:projects/iot-device-update.tgz '@rush-temp/iot-modelsrepository': file:projects/iot-modelsrepository.tgz '@rush-temp/keyvault-admin': file:projects/keyvault-admin.tgz @@ -342,7 +344,7 @@ packages: integrity: sha512-CxaMaEjwtsmIhWtjHyGimKO7RmES0YxPqGQ9+jKqGygNlhG5NYHktDaiQu6w7k3g+I51VaLXtVSt+BVFd6VWfQ== /@azure/identity/1.2.5_debug@4.3.1: dependencies: - '@azure/core-http': 1.2.6 + '@azure/core-http': 1.2.3 '@azure/core-tracing': 1.0.0-preview.9 '@azure/logger': 1.0.2 '@azure/msal-node': 1.0.0-beta.6_debug@4.3.1 @@ -436,30 +438,6 @@ packages: node: '>=8.0.0' resolution: integrity: sha512-eOHstXRBRntoqBLi3bugYBEHpYkm0JiET6y5+P1fz7dqYRFN6hJW8qMJQtYIzIbpXJfRJTJdoiOS5fDQhsez0A== - /@azure/identity/2.0.0-beta.3_debug@4.3.1: - dependencies: - '@azure/abort-controller': 1.0.4 - '@azure/core-http': 1.2.6 - '@azure/core-tracing': 1.0.0-preview.11 - '@azure/logger': 1.0.2 - '@azure/msal-browser': 2.9.0 - '@azure/msal-common': 4.0.3 - '@azure/msal-node': 1.1.0_debug@4.3.1 - '@types/stoppable': 1.1.1 - events: 3.3.0 - jws: 4.0.0 - open: 7.4.2 - qs: 6.10.1 - stoppable: 1.1.0 - tslib: 2.3.0 - uuid: 8.3.2 - dev: false - engines: - node: '>=8.0.0' - peerDependencies: - debug: '*' - resolution: - integrity: sha512-eOHstXRBRntoqBLi3bugYBEHpYkm0JiET6y5+P1fz7dqYRFN6hJW8qMJQtYIzIbpXJfRJTJdoiOS5fDQhsez0A== /@azure/keyvault-certificates/4.2.0: dependencies: '@azure/abort-controller': 1.0.4 @@ -612,6 +590,14 @@ packages: node: '>=0.8.0' resolution: integrity: sha512-Zyus+skNaVWL5fXfSjC17c94XZ95Z3a+bZc7YKkP26KT3Dj26jbfz2oT9KJxAT4XVtH/1WPY/fPFeEFTRvytJQ== + /@azure/msal-common/1.7.2: + dependencies: + debug: 4.3.1 + dev: false + engines: + node: '>=0.8.0' + resolution: + integrity: sha512-3/voCdFKONENX+5tMrNOBSrVJb6NbE7YB8vc4FZ/4ZbjpK7GVtq9Bu1MW+HZhrmsUzSF/joHx0ZIJDYIequ/jg== /@azure/msal-common/2.1.0: dependencies: debug: 4.3.1 @@ -636,6 +622,18 @@ packages: node: '>=0.8.0' resolution: integrity: sha512-jFqUWe83wVb6O8cNGGBFg2QlKvqM1ezUgJTEV7kIsAPX0RXhGFE4B1DLNt6hCnkTXDbw+KGW0zgxOEr4MJQwLw== + /@azure/msal-node-extensions/1.0.0-alpha.6: + dependencies: + '@azure/msal-common': 1.7.2 + bindings: 1.5.0 + keytar: 7.0.0 + nan: 2.14.2 + dev: false + engines: + node: '>=10' + requiresBuild: true + resolution: + integrity: sha512-fVufHc02C+daYOMAHBnE998abB4qUIeJ9gmTxmSelHhGfBGvvzMbCohCu4sTlSVDKUndF3yD/Nxvw/cEtpcZKg== /@azure/msal-node/1.0.0-beta.6: dependencies: '@azure/msal-common': 4.3.0 @@ -667,19 +665,6 @@ packages: node: 10 || 12 || 14 || 16 resolution: integrity: sha512-gMO9aZdWOzufp1PcdD5ID25DdS9eInxgeCqx4Tk8PVU6Z7RxJQhoMzS64cJhGdpYgeIQwKljtF0CLCcPFxew/w== - /@azure/msal-node/1.1.0_debug@4.3.1: - dependencies: - '@azure/msal-common': 4.3.0 - axios: 0.21.1_debug@4.3.1 - jsonwebtoken: 8.5.1 - uuid: 8.3.2 - dev: false - engines: - node: 10 || 12 || 14 || 16 - peerDependencies: - debug: '*' - resolution: - integrity: sha512-gMO9aZdWOzufp1PcdD5ID25DdS9eInxgeCqx4Tk8PVU6Z7RxJQhoMzS64cJhGdpYgeIQwKljtF0CLCcPFxew/w== /@babel/code-frame/7.12.11: dependencies: '@babel/highlight': 7.14.5 @@ -711,7 +696,7 @@ packages: '@babel/template': 7.14.5 '@babel/traverse': 7.14.5 '@babel/types': 7.14.5 - convert-source-map: 1.7.0 + convert-source-map: 1.8.0 debug: 4.3.1 gensync: 1.0.0-beta.2 json5: 2.2.0 @@ -977,7 +962,7 @@ packages: resolve: 1.17.0 semver: 7.3.5 source-map: 0.6.1 - typescript: 4.1.5 + typescript: 4.1.6 dev: false hasBin: true resolution: @@ -1387,33 +1372,33 @@ packages: /@types/body-parser/1.19.0: dependencies: '@types/connect': 3.4.34 - '@types/node': 15.12.2 + '@types/node': 8.10.66 dev: false resolution: integrity: sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ== /@types/chai-as-promised/7.1.4: dependencies: - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 dev: false resolution: integrity: sha512-1y3L1cHePcIm5vXkh1DSGf/zQq5n5xDKG1fpCvf18+uOkpce0Z1ozNFPkyWsVswK7ntN1sZBw3oU6gmN+pDUcA== /@types/chai-string/1.4.2: dependencies: - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 dev: false resolution: integrity: sha512-ld/1hV5qcPRGuwlPdvRfvM3Ka/iofOk2pH4VkasK4b1JJP1LjNmWWn0LsISf6RRzyhVOvs93rb9tM09e+UuF8Q== - /@types/chai/4.2.18: + /@types/chai/4.2.19: dev: false resolution: - integrity: sha512-rS27+EkB/RE1Iz3u0XtVL5q36MGDWbgYe7zWiodyKNUnthxY0rukK5V36eiUCtCisB7NN8zKYH6DO2M37qxFEQ== + integrity: sha512-jRJgpRBuY+7izT7/WNXP/LsMO9YonsstuL+xuvycDyESpoDoIAsMd7suwpB4h9oEWB+ZlPTqJJ8EHomzNhwTPQ== /@types/component-emitter/1.2.10: dev: false resolution: integrity: sha512-bsjleuRKWmGqajMerkzox19aGbscQX5rmmvvXl3wlIp5gMG1HgkiwPxsN5p070fBDKTNSPgojVbuY1+HWMbFhg== /@types/connect/3.4.34: dependencies: - '@types/node': 15.12.2 + '@types/node': 8.10.66 dev: false resolution: integrity: sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ== @@ -1446,7 +1431,7 @@ packages: integrity: sha512-LfZwXoGUDo0C3me81HXgkBg5CTQYb6xzEl+fNmbO4JdRiSKQ8A0GD1OBBvKAIsbCUgoyAty7m99GqqMQe784ew== /@types/express-serve-static-core/4.17.21: dependencies: - '@types/node': 15.12.2 + '@types/node': 8.10.66 '@types/qs': 6.9.6 '@types/range-parser': 1.2.3 dev: false @@ -1470,20 +1455,20 @@ packages: integrity: sha512-IyNhGHu71jH1jCXTHmafuoAAdsbBON3kDh7u/UUhLmjYgN5TYB54e1R8ckTCiIevl2UuZaCsi9XRxineY5yUjw== /@types/fs-extra/8.1.1: dependencies: - '@types/node': 15.12.2 + '@types/node': 8.10.66 dev: false resolution: integrity: sha512-TcUlBem321DFQzBNuz8p0CLLKp0VvF/XH9E4KHNmgwyp4E3AfgI5cjiIVZWlbfThBop2qxFIh4+LeY6hVWWZ2w== /@types/glob/7.1.3: dependencies: '@types/minimatch': 3.0.4 - '@types/node': 15.12.2 + '@types/node': 8.10.66 dev: false resolution: integrity: sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w== /@types/is-buffer/2.0.0: dependencies: - '@types/node': 15.12.2 + '@types/node': 8.10.66 dev: false resolution: integrity: sha512-0f7N/e3BAz32qDYvgB4d2cqv1DqUwvGxHkXsrucICn8la1Vb6Yl6Eg8mPScGwUiqHJeE7diXlzaK+QMA9m4Gxw== @@ -1495,15 +1480,15 @@ packages: dev: false resolution: integrity: sha1-7ihweulOEdK4J7y+UnC86n8+ce4= - /@types/jsonwebtoken/8.5.1: + /@types/jsonwebtoken/8.5.2: dependencies: - '@types/node': 15.12.2 + '@types/node': 8.10.66 dev: false resolution: - integrity: sha512-rNAPdomlIUX0i0cg2+I+Q1wOUr531zHBQ+cV/28PJ39bSPKjahatZZ2LMuhiguETkCgLVzfruw/ZvNMNkKoSzw== + integrity: sha512-X8BOCkp+WJVNYCYIBugREtVZa4Y09Or9HDx6xqRZem5F8jJV8FuJgNessXyMuv9+U8pjnvdezASwU28uw+1scw== /@types/jws/3.2.3: dependencies: - '@types/node': 15.12.2 + '@types/node': 8.10.66 dev: false resolution: integrity: sha512-g54CHxwvaHvyJyeuZqe7VQujV9SfCXwEkboJp355INPL+kjlS3Aq153EHptaeO/Cch/NPJ1i2sHz0sDDizn7LQ== @@ -1517,7 +1502,7 @@ packages: integrity: sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w== /@types/md5/2.3.0: dependencies: - '@types/node': 15.12.2 + '@types/node': 8.10.66 dev: false resolution: integrity: sha512-556YJ7ejzxIqSSxzyGGpctuZOarNZJt/zlEkhmmDc1f/slOEANHuwu2ZX7YaZ40rMiWoxt8GvAhoDpW1cmSy6A== @@ -1543,13 +1528,13 @@ packages: integrity: sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w== /@types/mock-fs/4.10.0: dependencies: - '@types/node': 15.12.2 + '@types/node': 8.10.66 dev: false resolution: integrity: sha512-FQ5alSzmHMmliqcL36JqIA4Yyn9jyJKvRSGV3mvPh108VFatX7naJDzSG4fnFQNZFq9dIx0Dzoe6ddflMB2Xkg== /@types/mock-require/2.0.0: dependencies: - '@types/node': 15.12.2 + '@types/node': 8.10.66 dev: false resolution: integrity: sha512-nOgjoE5bBiDeiA+z41i95makyHUSMWQMOPocP+J67Pqx/68HAXaeWN1NFtrAYYV6LrISIZZ8vKHm/a50k0f6Sg== @@ -1559,7 +1544,7 @@ packages: integrity: sha512-DPxmjiDwubsNmguG5X4fEJ+XCyzWM3GXWsqQlvUcjJKa91IOoJUy51meDr0GkzK64qqNcq85ymLlyjoct9tInw== /@types/node-fetch/2.5.10: dependencies: - '@types/node': 15.12.2 + '@types/node': 8.10.66 form-data: 3.0.1 dev: false resolution: @@ -1572,10 +1557,10 @@ packages: dev: false resolution: integrity: sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw== - /@types/node/15.12.2: + /@types/node/15.12.4: dev: false resolution: - integrity: sha512-zjQ69G564OCIWIOHSXyQEEDpdpGl+G348RAKY0XXy9Z5kU9Vzv1GMNnkar/ZJ8dzXB3COzD9Mo9NtRZ4xfgUww== + integrity: sha512-zrNj1+yqYF4WskCMOHwN+w9iuD12+dGm0rQ35HLl9/Ouuq52cEtd0CH9qMgrdNmi5ejC1/V7vKEXYubB+65DkA== /@types/node/8.10.66: dev: false resolution: @@ -1602,7 +1587,7 @@ packages: integrity: sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA== /@types/resolve/1.17.1: dependencies: - '@types/node': 15.12.2 + '@types/node': 8.10.66 dev: false resolution: integrity: sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw== @@ -1613,7 +1598,7 @@ packages: /@types/serve-static/1.13.9: dependencies: '@types/mime': 1.3.2 - '@types/node': 15.12.2 + '@types/node': 8.10.66 dev: false resolution: integrity: sha512-ZFqF6qa48XsPdjXV5Gsz0Zqmux2PerNd3a/ktL45mHpa19cuMi/cL8tcxdAx497yRh+QtYPuofjT9oWw9P7nkA== @@ -1629,7 +1614,7 @@ packages: integrity: sha512-dIPoZ3g5gcx9zZEszaxLSVTvMReD3xxyyDnQUjA6IYDG9Ba2AV0otMPs+77sG9ojB4Qr2N2Vk5RnKeuA0X/0bg== /@types/stoppable/1.1.1: dependencies: - '@types/node': 15.12.2 + '@types/node': 8.10.66 dev: false resolution: integrity: sha512-b8N+fCADRIYYrGZOcmOR8ZNBOqhktWTB/bMUl5LvGtT201QKJZOOH5UsFyI3qtteM6ZAJbJqZoBcLqqxKIwjhw== @@ -1639,7 +1624,7 @@ packages: integrity: sha512-I99sngh224D0M7XgW1s120zxCt3VYQ3IQsuw3P3jbq5GG4yc79+ZjyKznyOGIQrflfylLgcfekeZW/vk0yng6A== /@types/tunnel/0.0.1: dependencies: - '@types/node': 15.12.2 + '@types/node': 8.10.66 dev: false resolution: integrity: sha512-AOqu6bQu5MSWwYvehMXLukFHnupHrpZ8nvgae5Ggie9UwzDR1CCwoXgSSWNZJuyOlCdfdsWMA5F2LlmvyoTv8A== @@ -1651,32 +1636,32 @@ packages: dev: false resolution: integrity: sha512-eQ9qFW/fhfGJF8WKHGEHZEyVWfZxrT+6CLIJGBcZPfxUh/+BnEj+UCGYMlr9qZuX/2AltsvwrGqp0LhEW8D0zQ== - /@types/ws/7.4.4: + /@types/ws/7.4.5: dependencies: - '@types/node': 15.12.2 + '@types/node': 8.10.66 dev: false resolution: - integrity: sha512-d/7W23JAXPodQNbOZNXvl2K+bqAQrCMwlh/nuQsPSQk6Fq0opHoPrUw43aHsvSbIiQPr8Of2hkFbnz1XBFVyZQ== + integrity: sha512-8mbDgtc8xpxDDem5Gwj76stBDJX35KQ3YBoayxlqUQcL5BZUthiqP/VQ4PQnLHqM4PmlbyO74t98eJpURO+gPA== /@types/xml2js/0.4.8: dependencies: - '@types/node': 15.12.2 + '@types/node': 8.10.66 dev: false resolution: integrity: sha512-EyvT83ezOdec7BhDaEcsklWy7RSIdi6CNe95tmOAK0yx/Lm30C9K75snT3fYayK59ApC2oyW+rcHErdG05FHJA== /@types/yauzl/2.9.1: dependencies: - '@types/node': 15.12.2 + '@types/node': 8.10.66 dev: false optional: true resolution: integrity: sha512-A1b8SU4D10uoPjwb0lnHmmu8wZhR9d+9o2PKBQT2jU5YPTKsxac6M2qGAdY7VcL+dHHhARVUDmeg0rOrcd9EjA== - /@typescript-eslint/eslint-plugin/4.19.0_579c993deb6b0313d5d0f5c428bab62d: + /@typescript-eslint/eslint-plugin/4.19.0_32b60b6a5d7033b9e5296983f03a72ce: dependencies: - '@typescript-eslint/experimental-utils': 4.19.0_eslint@7.28.0+typescript@4.2.4 - '@typescript-eslint/parser': 4.19.0_eslint@7.28.0+typescript@4.2.4 + '@typescript-eslint/experimental-utils': 4.19.0_eslint@7.29.0+typescript@4.2.4 + '@typescript-eslint/parser': 4.19.0_eslint@7.29.0+typescript@4.2.4 '@typescript-eslint/scope-manager': 4.19.0 debug: 4.3.1 - eslint: 7.28.0 + eslint: 7.29.0 functional-red-black-tree: 1.0.1 lodash: 4.17.21 regexpp: 3.2.0 @@ -1695,13 +1680,13 @@ packages: optional: true resolution: integrity: sha512-CRQNQ0mC2Pa7VLwKFbrGVTArfdVDdefS+gTw0oC98vSI98IX5A8EVH4BzJ2FOB0YlCmm8Im36Elad/Jgtvveaw== - /@typescript-eslint/experimental-utils/4.19.0_eslint@7.28.0+typescript@4.2.4: + /@typescript-eslint/experimental-utils/4.19.0_eslint@7.29.0+typescript@4.2.4: dependencies: '@types/json-schema': 7.0.7 '@typescript-eslint/scope-manager': 4.19.0 '@typescript-eslint/types': 4.19.0 '@typescript-eslint/typescript-estree': 4.19.0_typescript@4.2.4 - eslint: 7.28.0 + eslint: 7.29.0 eslint-scope: 5.1.1 eslint-utils: 2.1.0 dev: false @@ -1712,13 +1697,13 @@ packages: typescript: '*' resolution: integrity: sha512-9/23F1nnyzbHKuoTqFN1iXwN3bvOm/PRIXSBR3qFAYotK/0LveEOHr5JT1WZSzcD6BESl8kPOG3OoDRKO84bHA== - /@typescript-eslint/parser/4.19.0_eslint@7.28.0+typescript@4.2.4: + /@typescript-eslint/parser/4.19.0_eslint@7.29.0+typescript@4.2.4: dependencies: '@typescript-eslint/scope-manager': 4.19.0 '@typescript-eslint/types': 4.19.0 '@typescript-eslint/typescript-estree': 4.19.0_typescript@4.2.4 debug: 4.3.1 - eslint: 7.28.0 + eslint: 7.29.0 typescript: 4.2.4 dev: false engines: @@ -1751,7 +1736,7 @@ packages: '@typescript-eslint/types': 4.19.0 '@typescript-eslint/visitor-keys': 4.19.0 debug: 4.3.1 - globby: 11.0.3 + globby: 11.0.4 is-glob: 4.0.1 semver: 7.3.5 tsutils: 3.21.0_typescript@4.2.4 @@ -1948,7 +1933,6 @@ packages: integrity: sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw== /aproba/1.2.0: dev: false - optional: true resolution: integrity: sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== /archy/1.0.0: @@ -1960,7 +1944,6 @@ packages: delegates: 1.0.0 readable-stream: 2.3.7 dev: false - optional: true resolution: integrity: sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== /arg/4.1.3: @@ -2245,6 +2228,12 @@ packages: node: '>=8' resolution: integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + /bindings/1.5.0: + dependencies: + file-uri-to-path: 1.0.0 + dev: false + resolution: + integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== /bl/4.1.0: dependencies: buffer: 5.7.1 @@ -2295,7 +2284,7 @@ packages: integrity: sha1-rrGvKN5sDXpqLOQK22j/GEIq8x8= /browserslist/4.16.6: dependencies: - caniuse-lite: 1.0.30001237 + caniuse-lite: 1.0.30001239 colorette: 1.2.2 electron-to-chromium: 1.3.752 escalade: 3.1.1 @@ -2379,10 +2368,10 @@ packages: node: '>=6' resolution: integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== - /caniuse-lite/1.0.30001237: + /caniuse-lite/1.0.30001239: dev: false resolution: - integrity: sha512-pDHgRndit6p1NR2GhzMbQ6CkRrp4VKuSsqbcLeOQppYPKOYkKT/6ZvZDvKJUqcmtyWIAHuZq3SVS2vc1egCZzw== + integrity: sha512-cyBkXJDMeI4wthy8xJ2FvDU6+0dtcZSJW3voUF8+e9f1bBeuvyZfc3PNbkOETyhbR+dGCPzn9E7MA3iwzusOhQ== /caseless/0.12.0: dev: false resolution: @@ -2538,7 +2527,6 @@ packages: dev: false engines: node: '>=0.10.0' - optional: true resolution: integrity: sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= /color-convert/1.9.3: @@ -2622,7 +2610,6 @@ packages: integrity: sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ== /console-control-strings/1.1.0: dev: false - optional: true resolution: integrity: sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= /content-disposition/0.5.3: @@ -2639,12 +2626,12 @@ packages: node: '>= 0.6' resolution: integrity: sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== - /convert-source-map/1.7.0: + /convert-source-map/1.8.0: dependencies: safe-buffer: 5.1.2 dev: false resolution: - integrity: sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== + integrity: sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== /cookie-signature/1.0.6: dev: false resolution: @@ -2667,11 +2654,11 @@ packages: requiresBuild: true resolution: integrity: sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== - /core-js/3.14.0: + /core-js/3.15.0: dev: false requiresBuild: true resolution: - integrity: sha512-3s+ed8er9ahK+zJpp9ZtuVcDoFzHNiZsPbNAAE4KXgrRHbjSqqNN6xGSXq6bq7TZIbKj4NLrLb6bJ5i+vSVjHA== + integrity: sha512-GUbtPllXMYRzIgHNZ4dTYTcUemls2cni83Q4Q/TrFONHfhcg9oEGOtaGHfb0cpzec60P96UKPvMkjX1jET8rUw== /core-util-is/1.0.2: dev: false resolution: @@ -2797,7 +2784,7 @@ packages: integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== /debug/3.2.6: dependencies: - ms: 2.1.3 + ms: 2.1.1 deprecated: Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797) dev: false resolution: @@ -2846,7 +2833,6 @@ packages: dev: false engines: node: '>=8' - optional: true resolution: integrity: sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw== /deep-eql/3.0.1: @@ -2861,7 +2847,6 @@ packages: dev: false engines: node: '>=4.0.0' - optional: true resolution: integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== /deep-freeze/0.0.1: @@ -2918,7 +2903,6 @@ packages: integrity: sha1-3zrhmayt+31ECqrgsp4icrJOxhk= /delegates/1.0.0: dev: false - optional: true resolution: integrity: sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= /depd/1.1.2: @@ -2936,7 +2920,6 @@ packages: engines: node: '>=0.10' hasBin: true - optional: true resolution: integrity: sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= /di/0.0.1: @@ -3011,7 +2994,7 @@ packages: /downlevel-dts/0.4.0: dependencies: shelljs: 0.8.4 - typescript: 3.9.9 + typescript: 3.9.10 dev: false hasBin: true resolution: @@ -3184,9 +3167,9 @@ packages: source-map: 0.6.1 resolution: integrity: sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw== - /eslint-config-prettier/7.2.0_eslint@7.28.0: + /eslint-config-prettier/7.2.0_eslint@7.29.0: dependencies: - eslint: 7.28.0 + eslint: 7.29.0 dev: false hasBin: true peerDependencies: @@ -3209,9 +3192,9 @@ packages: node: '>=4' resolution: integrity: sha512-ZXI9B8cxAJIH4nfkhTwcRTEAnrVfobYqwjWy/QMCZ8rHkZHFjf9yO4BzpiF9kCSfNlMG54eKigISHpX0+AaT4A== - /eslint-plugin-es/3.0.1_eslint@7.28.0: + /eslint-plugin-es/3.0.1_eslint@7.29.0: dependencies: - eslint: 7.28.0 + eslint: 7.29.0 eslint-utils: 2.1.0 regexpp: 3.2.0 dev: false @@ -3221,13 +3204,13 @@ packages: eslint: '>=4.19.1' resolution: integrity: sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ== - /eslint-plugin-import/2.23.4_eslint@7.28.0: + /eslint-plugin-import/2.23.4_eslint@7.29.0: dependencies: array-includes: 3.1.3 array.prototype.flat: 1.2.4 debug: 2.6.9 doctrine: 2.1.0 - eslint: 7.28.0 + eslint: 7.29.0 eslint-import-resolver-node: 0.3.4 eslint-module-utils: 2.6.1 find-up: 2.1.0 @@ -3252,10 +3235,10 @@ packages: node: '>=4.0.0' resolution: integrity: sha512-T9SmE/g6UV1uZo1oHAqOvL86XWl7Pl2EpRpnLI8g/bkJu+h7XBCB+1LnubRZ2CUQXj805vh4/CYZdnqtVaEo2Q== - /eslint-plugin-node/11.1.0_eslint@7.28.0: + /eslint-plugin-node/11.1.0_eslint@7.29.0: dependencies: - eslint: 7.28.0 - eslint-plugin-es: 3.0.1_eslint@7.28.0 + eslint: 7.29.0 + eslint-plugin-es: 3.0.1_eslint@7.29.0 eslint-utils: 2.1.0 ignore: 5.1.8 minimatch: 3.0.4 @@ -3310,7 +3293,7 @@ packages: node: '>=10' resolution: integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== - /eslint/7.28.0: + /eslint/7.29.0: dependencies: '@babel/code-frame': 7.12.11 '@eslint/eslintrc': 0.4.2 @@ -3356,7 +3339,7 @@ packages: node: ^10.12.0 || >=12.0.0 hasBin: true resolution: - integrity: sha512-UMfH0VSjP0G4p3EWirscJEQ/cHqnT/iuH6oNZOB94nBjWbMnhGEPxsZm1eyIW0C/9jLI0Fow4W5DXLjEI7mn1g== + integrity: sha512-82G/JToB9qIy/ArBzIWG9xvvwL3R86AlCjtGw+A29OMZDqhTybz/MByORSukGxeI+YPCR4coYyITKk8BFH9nDA== /esm/3.2.25: dev: false engines: @@ -3465,7 +3448,6 @@ packages: dev: false engines: node: '>=6' - optional: true resolution: integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== /expand-tilde/2.0.2: @@ -3581,7 +3563,7 @@ packages: dependencies: '@babel/core': 7.14.6 '@babel/runtime': 7.14.6 - core-js: 3.14.0 + core-js: 3.15.0 debug: 4.3.1 glob-to-regexp: 0.4.1 is-subset: 0.1.1 @@ -3608,6 +3590,10 @@ packages: node: ^10.12.0 || >=12.0.0 resolution: integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== + /file-uri-to-path/1.0.0: + dev: false + resolution: + integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== /file-uri-to-path/2.0.0: dev: false engines: @@ -3859,7 +3845,6 @@ packages: strip-ansi: 3.0.1 wide-align: 1.1.3 dev: false - optional: true resolution: integrity: sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= /gensync/1.0.0-beta.2: @@ -3925,7 +3910,6 @@ packages: integrity: sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= /github-from-package/0.0.0: dev: false - optional: true resolution: integrity: sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4= /glob-parent/5.1.2: @@ -4005,7 +3989,7 @@ packages: node: '>=8' resolution: integrity: sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA== - /globby/11.0.3: + /globby/11.0.4: dependencies: array-union: 2.1.0 dir-glob: 3.0.1 @@ -4017,7 +4001,7 @@ packages: engines: node: '>=10' resolution: - integrity: sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg== + integrity: sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg== /graceful-fs/4.2.6: dev: false resolution: @@ -4108,7 +4092,6 @@ packages: integrity: sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== /has-unicode/2.0.1: dev: false - optional: true resolution: integrity: sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= /has/1.0.3: @@ -4431,7 +4414,6 @@ packages: dev: false engines: node: '>=0.10.0' - optional: true resolution: integrity: sha1-754xOG8DGn8NZDr4L95QxFfvAMs= /is-fullwidth-code-point/2.0.0: @@ -4740,10 +4722,10 @@ packages: hasBin: true resolution: integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== - /jsbi/3.1.4: + /jsbi/3.1.5: dev: false resolution: - integrity: sha512-52QRRFSsi9impURE8ZUbzAMCLjPm4THO7H2fcuIvaaeFTbSysvkodbQQXIVsNgq/ypDbq6dJiuGKL0vZ/i9hUg== + integrity: sha512-w2BY0VOYC1ahe+w6Qhl4SFoPvPsZ9NPHY4bwass+LCgU7RK3PBoVQlQ3G1s7vI8W3CYyJiEXcbKF7FIM/L8q3Q== /jsbn/0.1.1: dev: false resolution: @@ -5087,12 +5069,19 @@ packages: debug: '*' resolution: integrity: sha512-hbhRogUYIulfkBTZT7xoPrCYhRBnBoqbbL4fszWD0ReFGUxU+LYBr3dwKdAluaDQ/ynT9/7C+Lf7pPNW4gSx4Q== + /keytar/7.0.0: + dependencies: + node-addon-api: 3.2.1 + prebuild-install: 5.3.5 + dev: false + requiresBuild: true + resolution: + integrity: sha512-uvmdb5ZE2NgegcUDrmhutI9BUh+bTbt8+bwPliOMiLiWmrV76Tfg6DyI7Ud903a/4xlkJpKGnR0TyRpRyFOc3A== /keytar/7.7.0: dependencies: node-addon-api: 3.2.1 prebuild-install: 6.1.3 dev: false - optional: true requiresBuild: true resolution: integrity: sha512-YEY9HWqThQc5q5xbXbRwsZTh2PJ36OSYRjSv3NN2xf5s5dpLTjEZnC2YikR29OaVybf9nQ0dJ/80i40RS97t/A== @@ -5421,7 +5410,6 @@ packages: dev: false engines: node: '>=8' - optional: true resolution: integrity: sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA== /min-document/2.19.0: @@ -5544,6 +5532,10 @@ packages: node: '>=0.8.0' resolution: integrity: sha512-8vW5/+irlcQQk87r8Qp3/kQEc552hr7FQLJ6GF5LLkqnwJDDxrswz6RYPiQhmiampymIs0PbHVZrNf8m+6DmgQ== + /nan/2.14.2: + dev: false + resolution: + integrity: sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ== /nanoid/3.1.23: dev: false engines: @@ -5553,7 +5545,6 @@ packages: integrity: sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw== /napi-build-utils/1.0.2: dev: false - optional: true resolution: integrity: sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== /natural-compare/1.4.0: @@ -5609,7 +5600,6 @@ packages: dependencies: semver: 5.7.1 dev: false - optional: true resolution: integrity: sha512-g6bZh3YCKQRdwuO/tSZZYJAw622SjsRfJ2X0Iy4sSOHZ34/sPPdVBn8fev2tj7njzLwuqPw9uMtGsGkO5kIQvg== /node-abort-controller/1.2.1: @@ -5618,7 +5608,6 @@ packages: integrity: sha512-79PYeJuj6S9+yOHirR0JBLFOgjB6sQCir10uN6xRx25iD+ZD4ULqgRn3MwWBRaQGB0vEgReJzWwJo42T1R6YbQ== /node-addon-api/3.2.1: dev: false - optional: true resolution: integrity: sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A== /node-environment-flags/1.0.6: @@ -5638,6 +5627,10 @@ packages: dev: false resolution: integrity: sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg== + /noop-logger/0.1.1: + dev: false + resolution: + integrity: sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI= /normalize-package-data/2.5.0: dependencies: hosted-git-info: 2.8.9 @@ -5693,21 +5686,19 @@ packages: gauge: 2.7.4 set-blocking: 2.0.0 dev: false - optional: true resolution: integrity: sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== /number-is-nan/1.0.1: dev: false engines: node: '>=0.10.0' - optional: true resolution: integrity: sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= /nyc/14.1.1: dependencies: archy: 1.0.0 caching-transform: 3.0.2 - convert-source-map: 1.7.0 + convert-source-map: 1.8.0 cp-file: 6.2.0 find-cache-dir: 2.1.0 find-up: 3.0.0 @@ -6104,6 +6095,29 @@ packages: node: '>=4' resolution: integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA== + /prebuild-install/5.3.5: + dependencies: + detect-libc: 1.0.3 + expand-template: 2.0.3 + github-from-package: 0.0.0 + minimist: 1.2.5 + mkdirp: 0.5.5 + napi-build-utils: 1.0.2 + node-abi: 2.30.0 + noop-logger: 0.1.1 + npmlog: 4.1.2 + pump: 3.0.0 + rc: 1.2.8 + simple-get: 3.1.0 + tar-fs: 2.1.1 + tunnel-agent: 0.6.0 + which-pm-runs: 1.0.0 + dev: false + engines: + node: '>=6' + hasBin: true + resolution: + integrity: sha512-YmMO7dph9CYKi5IR/BzjOJlRzpxGGVo1EsLSUZ0mt/Mq0HWZIHOKHHcHdT69yG54C9m6i45GpItwRHpk0Py7Uw== /prebuild-install/6.1.3: dependencies: detect-libc: 1.0.3 @@ -6123,7 +6137,6 @@ packages: engines: node: '>=6' hasBin: true - optional: true resolution: integrity: sha512-iqqSR84tNYQUQHRXalSKdIaM8Ov1QxOVuBNWI7+BzZWv6Ih9k75wOnH1rGQ9WWTaaLkTpxWKIciOF0KyfM74+Q== /prelude-ls/1.1.2: @@ -6252,7 +6265,7 @@ packages: rimraf: 3.0.2 tar-fs: 2.1.1 unbzip2-stream: 1.4.3 - ws: 7.4.6 + ws: 7.5.0 dev: false engines: node: '>=10.18.1' @@ -6361,7 +6374,6 @@ packages: strip-json-comments: 2.0.1 dev: false hasBin: true - optional: true resolution: integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== /read-pkg-up/3.0.0: @@ -6705,7 +6717,7 @@ packages: /rollup/1.32.1: dependencies: '@types/estree': 0.0.48 - '@types/node': 15.12.2 + '@types/node': 8.10.66 acorn: 7.4.1 dev: false hasBin: true @@ -6879,7 +6891,6 @@ packages: integrity: sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== /simple-concat/1.0.1: dev: false - optional: true resolution: integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== /simple-get/3.1.0: @@ -6888,7 +6899,6 @@ packages: once: 1.4.0 simple-concat: 1.0.1 dev: false - optional: true resolution: integrity: sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA== /sinon/9.2.4: @@ -6996,7 +7006,7 @@ packages: dependencies: '@types/cookie': 0.4.0 '@types/cors': 2.8.10 - '@types/node': 15.12.2 + '@types/node': 15.12.4 accepts: 1.3.7 base64id: 2.0.0 debug: 4.3.1 @@ -7175,7 +7185,6 @@ packages: dev: false engines: node: '>=0.10.0' - optional: true resolution: integrity: sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= /string-width/2.1.1: @@ -7607,20 +7616,20 @@ packages: hasBin: true resolution: integrity: sha512-MmQdgo/XenfZPvVLtKZOq9jQQvzaUAUpcKW8Z43x9B2fOm4S5g//tPtMweZUIP+SoBqrVPEIm+dJeQ9dfO0QdA== - /typescript/3.9.9: + /typescript/3.9.10: dev: false engines: node: '>=4.2.0' hasBin: true resolution: - integrity: sha512-kdMjTiekY+z/ubJCATUPlRDl39vXYiMV9iyeMuEuXZh2we6zz80uovNN2WlAxmmdE/Z/YQe+EbOEXB5RHEED3w== - /typescript/4.1.5: + integrity: sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q== + /typescript/4.1.6: dev: false engines: node: '>=4.2.0' hasBin: true resolution: - integrity: sha512-6OSu9PTIzmn9TCDiovULTnET6BgXtDYL4Gg4szY+cGsc3JP1dQL8qvE8kShTRx1NIw4Q9IBHlwODjkjWEtMUyA== + integrity: sha512-pxnwLxeb/Z5SP80JDRzVjh58KsM6jZHRAOtTpS7sXLS4ogXNKC9ANxHHZqLLeVHZN35jCtI4JdmLLbLiC1kBow== /typescript/4.2.4: dev: false engines: @@ -7815,6 +7824,10 @@ packages: dev: false resolution: integrity: sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= + /which-pm-runs/1.0.0: + dev: false + resolution: + integrity: sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs= /which-typed-array/1.1.4: dependencies: available-typed-arrays: 1.0.4 @@ -7913,6 +7926,20 @@ packages: optional: true resolution: integrity: sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== + /ws/7.5.0: + dev: false + engines: + node: '>=8.3.0' + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + resolution: + integrity: sha512-6ezXvzOZupqKj4jUqbQ9tXuJNo+BR2gU8fFRk3XCP3e0G6WT414u5ELe6Y0vtp7kmSJ3F7YWObSNr1ESsgi4vw== /xhr-mock/2.5.1: dependencies: global: 4.4.0 @@ -8008,12 +8035,12 @@ packages: dev: false resolution: integrity: sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== - /yargs-parser/20.2.7: + /yargs-parser/20.2.9: dev: false engines: node: '>=10' resolution: - integrity: sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw== + integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== /yargs-unparser/1.6.0: dependencies: flat: 4.1.1 @@ -8047,7 +8074,7 @@ packages: require-directory: 2.1.1 string-width: 4.2.2 y18n: 5.0.8 - yargs-parser: 20.2.7 + yargs-parser: 20.2.9 dev: false engines: node: '>=10' @@ -8090,7 +8117,7 @@ packages: cross-env: 7.0.3 delay: 4.4.1 downlevel-dts: 0.4.0 - eslint: 7.28.0 + eslint: 7.29.0 karma: 6.3.4 karma-chrome-launcher: 3.1.0 karma-coverage: 2.0.3 @@ -8125,13 +8152,13 @@ packages: '@azure/core-rest-pipeline': 1.0.4 '@azure/identity': 1.3.0 '@microsoft/api-extractor': 7.13.2 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/mocha': 7.0.2 '@types/node': 8.10.66 chai: 4.3.4 cross-env: 7.0.3 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 karma: 6.3.4 karma-chrome-launcher: 3.1.0 karma-coverage: 2.0.3 @@ -8165,7 +8192,6 @@ packages: version: 0.0.0 file:projects/ai-anomaly-detector.tgz: dependencies: - '@azure/core-tracing': 1.0.0-preview.11 '@azure/identity': 1.3.0 '@microsoft/api-extractor': 7.7.11 '@rollup/plugin-commonjs': 11.0.2_rollup@1.32.1 @@ -8173,14 +8199,14 @@ packages: '@rollup/plugin-multi-entry': 3.0.1_rollup@1.32.1 '@rollup/plugin-node-resolve': 8.4.0_rollup@1.32.1 '@rollup/plugin-replace': 2.4.2_rollup@1.32.1 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/mocha': 7.0.2 '@types/node': 8.10.66 chai: 4.3.4 cross-env: 7.0.3 csv-parse: 4.16.0 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 inherits: 2.0.4 karma: 6.3.4 karma-chrome-launcher: 3.1.0 @@ -8218,13 +8244,13 @@ packages: '@azure/core-rest-pipeline': 1.0.4 '@azure/identity': 1.3.0 '@microsoft/api-extractor': 7.13.2 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/mocha': 7.0.2 '@types/node': 8.10.66 chai: 4.3.4 cross-env: 7.0.3 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 karma: 6.3.4 karma-chrome-launcher: 3.1.0 karma-coverage: 2.0.3 @@ -8257,10 +8283,8 @@ packages: version: 0.0.0 file:projects/ai-form-recognizer.tgz: dependencies: - '@azure/core-tracing': 1.0.0-preview.11 - '@azure/identity': 2.0.0-beta.3 '@microsoft/api-extractor': 7.7.11 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/mocha': 7.0.2 '@types/node': 8.10.66 '@types/sinon': 9.0.11 @@ -8268,7 +8292,7 @@ packages: chai-as-promised: 7.1.1_chai@4.3.4 cross-env: 7.0.3 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 karma: 6.3.4 karma-chrome-launcher: 3.1.0 karma-coverage: 2.0.3 @@ -8301,10 +8325,9 @@ packages: version: 0.0.0 file:projects/ai-metrics-advisor.tgz: dependencies: - '@azure/core-tracing': 1.0.0-preview.11 '@azure/identity': 1.3.0 '@microsoft/api-extractor': 7.7.11 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/mocha': 7.0.2 '@types/node': 8.10.66 '@types/sinon': 9.0.11 @@ -8312,7 +8335,7 @@ packages: chai-as-promised: 7.1.1_chai@4.3.4 cross-env: 7.0.3 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 karma: 6.3.4 karma-chrome-launcher: 3.1.0 karma-coverage: 2.0.3 @@ -8350,7 +8373,7 @@ packages: '@azure/core-tracing': 1.0.0-preview.11 '@azure/identity': 2.0.0-beta.3 '@microsoft/api-extractor': 7.7.11 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/chai-as-promised': 7.1.4 '@types/mocha': 7.0.2 '@types/node': 8.10.66 @@ -8359,7 +8382,7 @@ packages: chai-as-promised: 7.1.1_chai@4.3.4 cross-env: 7.0.3 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 karma: 6.3.4 karma-chrome-launcher: 3.1.0 karma-coverage: 2.0.3 @@ -8394,8 +8417,6 @@ packages: version: 0.0.0 file:projects/app-configuration.tgz: dependencies: - '@azure/core-tracing': 1.0.0-preview.11 - '@azure/identity': 2.0.0-beta.3 '@azure/keyvault-secrets': 4.2.0 '@microsoft/api-extractor': 7.7.11 '@rollup/plugin-commonjs': 11.0.2_rollup@1.32.1 @@ -8404,7 +8425,7 @@ packages: '@rollup/plugin-multi-entry': 3.0.1_rollup@1.32.1 '@rollup/plugin-node-resolve': 8.4.0_rollup@1.32.1 '@rollup/plugin-replace': 2.4.2_rollup@1.32.1 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/mocha': 7.0.2 '@types/node': 8.10.66 '@types/sinon': 9.0.11 @@ -8412,7 +8433,7 @@ packages: chai: 4.3.4 cross-env: 7.0.3 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 esm: 3.2.25 karma: 6.3.4 karma-chrome-launcher: 3.1.0 @@ -8453,7 +8474,7 @@ packages: '@azure/core-tracing': 1.0.0-preview.11 '@azure/identity': 1.3.0 '@microsoft/api-extractor': 7.7.11 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/chai-as-promised': 7.1.4 '@types/mocha': 7.0.2 '@types/node': 8.10.66 @@ -8463,7 +8484,7 @@ packages: cross-env: 7.0.3 dotenv: 8.6.0 downlevel-dts: 0.4.0 - eslint: 7.28.0 + eslint: 7.29.0 esm: 3.2.25 inherits: 2.0.4 jsrsasign: 10.3.0 @@ -8506,14 +8527,13 @@ packages: dependencies: '@azure/communication-identity': 1.0.0 '@azure/communication-signaling': 1.0.0-beta.5 - '@azure/core-tracing': 1.0.0-preview.11 '@microsoft/api-extractor': 7.7.11 '@rollup/plugin-commonjs': 11.0.2_rollup@1.32.1 '@rollup/plugin-json': 4.1.0_rollup@1.32.1 '@rollup/plugin-multi-entry': 3.0.1_rollup@1.32.1 '@rollup/plugin-node-resolve': 8.4.0_rollup@1.32.1 '@rollup/plugin-replace': 2.4.2_rollup@1.32.1 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/mocha': 7.0.2 '@types/node': 8.10.66 '@types/sinon': 9.0.11 @@ -8521,7 +8541,7 @@ packages: chai: 4.3.4 cross-env: 7.0.3 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 events: 3.3.0 inherits: 2.0.4 karma: 6.3.4 @@ -8560,14 +8580,13 @@ packages: version: 0.0.0 file:projects/communication-common.tgz: dependencies: - '@azure/core-tracing': 1.0.0-preview.11 '@microsoft/api-extractor': 7.7.11 '@rollup/plugin-commonjs': 11.0.2_rollup@1.32.1 '@rollup/plugin-json': 4.1.0_rollup@1.32.1 '@rollup/plugin-multi-entry': 3.0.1_rollup@1.32.1 '@rollup/plugin-node-resolve': 8.4.0_rollup@1.32.1 '@rollup/plugin-replace': 2.4.2_rollup@1.32.1 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/chai-as-promised': 7.1.4 '@types/jwt-decode': 2.2.1 '@types/mocha': 7.0.2 @@ -8577,7 +8596,7 @@ packages: chai: 4.3.4 chai-as-promised: 7.1.1_chai@4.3.4 cross-env: 7.0.3 - eslint: 7.28.0 + eslint: 7.29.0 events: 3.3.0 inherits: 2.0.4 jwt-decode: 2.2.0 @@ -8614,14 +8633,13 @@ packages: version: 0.0.0 file:projects/communication-identity.tgz: dependencies: - '@azure/core-tracing': 1.0.0-preview.11 '@microsoft/api-extractor': 7.7.11 '@rollup/plugin-commonjs': 11.0.2_rollup@1.32.1 '@rollup/plugin-json': 4.1.0_rollup@1.32.1 '@rollup/plugin-multi-entry': 3.0.1_rollup@1.32.1 '@rollup/plugin-node-resolve': 8.4.0_rollup@1.32.1 '@rollup/plugin-replace': 2.4.2_rollup@1.32.1 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/mocha': 7.0.2 '@types/node': 8.10.66 '@types/sinon': 9.0.11 @@ -8629,7 +8647,7 @@ packages: chai: 4.3.4 cross-env: 7.0.3 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 events: 3.3.0 inherits: 2.0.4 karma: 6.3.4 @@ -8668,14 +8686,13 @@ packages: file:projects/communication-network-traversal.tgz: dependencies: '@azure/communication-identity': 1.0.0 - '@azure/core-tracing': 1.0.0-preview.11 '@microsoft/api-extractor': 7.7.11 '@rollup/plugin-commonjs': 11.0.2_rollup@1.32.1 '@rollup/plugin-json': 4.1.0_rollup@1.32.1 '@rollup/plugin-multi-entry': 3.0.1_rollup@1.32.1 '@rollup/plugin-node-resolve': 8.4.0_rollup@1.32.1 '@rollup/plugin-replace': 2.4.2_rollup@1.32.1 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/mocha': 7.0.2 '@types/node': 8.10.66 '@types/sinon': 9.0.11 @@ -8683,7 +8700,7 @@ packages: chai: 4.3.4 cross-env: 7.0.3 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 events: 3.3.0 inherits: 2.0.4 karma: 6.3.4 @@ -8721,14 +8738,13 @@ packages: version: 0.0.0 file:projects/communication-phone-numbers.tgz: dependencies: - '@azure/core-tracing': 1.0.0-preview.11 '@microsoft/api-extractor': 7.7.11 '@rollup/plugin-commonjs': 11.0.2_rollup@1.32.1 '@rollup/plugin-json': 4.1.0_rollup@1.32.1 '@rollup/plugin-multi-entry': 3.0.1_rollup@1.32.1 '@rollup/plugin-node-resolve': 8.4.0_rollup@1.32.1 '@rollup/plugin-replace': 2.4.2_rollup@1.32.1 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/mocha': 7.0.2 '@types/node': 8.10.66 '@types/sinon': 9.0.11 @@ -8736,7 +8752,7 @@ packages: chai: 4.3.4 cross-env: 7.0.3 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 events: 3.3.0 inherits: 2.0.4 karma: 6.3.4 @@ -8774,14 +8790,13 @@ packages: version: 0.0.0 file:projects/communication-sms.tgz: dependencies: - '@azure/core-tracing': 1.0.0-preview.11 '@microsoft/api-extractor': 7.7.11 '@rollup/plugin-commonjs': 11.0.2_rollup@1.32.1 '@rollup/plugin-json': 4.1.0_rollup@1.32.1 '@rollup/plugin-multi-entry': 3.0.1_rollup@1.32.1 '@rollup/plugin-node-resolve': 8.4.0_rollup@1.32.1 '@rollup/plugin-replace': 2.4.2_rollup@1.32.1 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/mocha': 7.0.2 '@types/node': 8.10.66 '@types/sinon': 9.0.11 @@ -8789,7 +8804,7 @@ packages: chai: 4.3.4 cross-env: 7.0.3 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 events: 3.3.0 inherits: 2.0.4 karma: 6.3.4 @@ -8829,13 +8844,13 @@ packages: '@azure/core-rest-pipeline': 1.0.4 '@azure/identity': 1.3.0 '@microsoft/api-extractor': 7.13.2 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/mocha': 7.0.2 '@types/node': 8.10.66 chai: 4.3.4 cross-env: 7.0.3 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 karma: 6.3.4 karma-chrome-launcher: 3.1.0 karma-coverage: 2.0.3 @@ -8871,7 +8886,7 @@ packages: '@azure/core-tracing': 1.0.0-preview.11 '@azure/ms-rest-nodeauth': 3.0.10 '@microsoft/api-extractor': 7.7.11 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/chai-as-promised': 7.1.4 '@types/mocha': 7.0.2 '@types/node': 8.10.66 @@ -8879,7 +8894,7 @@ packages: chai-as-promised: 7.1.1_chai@4.3.4 cross-env: 7.0.3 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 inherits: 2.0.4 karma: 6.3.4 karma-chrome-launcher: 3.1.0 @@ -8919,13 +8934,13 @@ packages: '@rollup/plugin-multi-entry': 3.0.1_rollup@1.32.1 '@rollup/plugin-node-resolve': 8.4.0_rollup@1.32.1 '@rollup/plugin-replace': 2.4.2_rollup@1.32.1 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/chai-as-promised': 7.1.4 '@types/debug': 4.1.5 '@types/mocha': 7.0.2 '@types/node': 8.10.66 '@types/sinon': 9.0.11 - '@types/ws': 7.4.4 + '@types/ws': 7.4.5 assert: 1.5.0 buffer: 5.7.1 chai: 4.3.4 @@ -8934,7 +8949,7 @@ packages: debug: 4.3.1 dotenv: 8.6.0 downlevel-dts: 0.4.0 - eslint: 7.28.0 + eslint: 7.29.0 events: 3.3.0 jssha: 3.2.0 karma: 6.3.4_debug@4.3.1 @@ -8960,7 +8975,7 @@ packages: typescript: 4.2.4 url: 0.11.0 util: 0.12.4 - ws: 7.4.6 + ws: 7.5.0 dev: false name: '@rush-temp/core-amqp' resolution: @@ -8970,7 +8985,7 @@ packages: file:projects/core-asynciterator-polyfill.tgz: dependencies: '@types/node': 8.10.66 - eslint: 7.28.0 + eslint: 7.29.0 prettier: 1.19.1 typedoc: 0.15.2 typescript: 4.2.4 @@ -8993,7 +9008,7 @@ packages: assert: 1.5.0 cross-env: 7.0.3 downlevel-dts: 0.4.0 - eslint: 7.28.0 + eslint: 7.29.0 inherits: 2.0.4 mocha: 7.2.0 mocha-junit-reporter: 1.23.3_mocha@7.2.0 @@ -9024,14 +9039,14 @@ packages: '@rollup/plugin-multi-entry': 3.0.1_rollup@1.32.1 '@rollup/plugin-node-resolve': 8.4.0_rollup@1.32.1 '@rollup/plugin-replace': 2.4.2_rollup@1.32.1 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/mocha': 7.0.2 '@types/node': 8.10.66 '@types/sinon': 9.0.11 chai: 4.3.4 cross-env: 7.0.3 downlevel-dts: 0.4.0 - eslint: 7.28.0 + eslint: 7.29.0 inherits: 2.0.4 karma: 6.3.4 karma-chrome-launcher: 3.1.0 @@ -9067,12 +9082,12 @@ packages: dependencies: '@azure/core-rest-pipeline': 1.0.4 '@microsoft/api-extractor': 7.13.2 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/mocha': 7.0.2 '@types/node': 8.10.66 chai: 4.3.4 cross-env: 7.0.3 - eslint: 7.28.0 + eslint: 7.29.0 inherits: 2.0.4 karma: 6.3.4 karma-chrome-launcher: 3.1.0 @@ -9109,7 +9124,7 @@ packages: '@rollup/plugin-multi-entry': 3.0.1_rollup@1.32.1 '@rollup/plugin-node-resolve': 8.4.0_rollup@1.32.1 '@rollup/plugin-replace': 2.4.2_rollup@1.32.1 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/mocha': 7.0.2 '@types/node': 8.10.66 '@types/sinon': 9.0.11 @@ -9117,7 +9132,7 @@ packages: chai: 4.3.4 cross-env: 7.0.3 downlevel-dts: 0.4.0 - eslint: 7.28.0 + eslint: 7.29.0 karma: 6.3.4 karma-chrome-launcher: 3.1.0 karma-coverage: 2.0.3 @@ -9148,7 +9163,6 @@ packages: version: 0.0.0 file:projects/core-http.tgz: dependencies: - '@azure/core-tracing': 1.0.0-preview.11 '@azure/logger-js': 1.3.2 '@microsoft/api-extractor': 7.7.11 '@rollup/plugin-commonjs': 11.0.2_rollup@1.32.1 @@ -9156,7 +9170,7 @@ packages: '@rollup/plugin-multi-entry': 3.0.1_rollup@1.32.1 '@rollup/plugin-node-resolve': 8.4.0_rollup@1.32.1 '@rollup/plugin-replace': 2.4.2_rollup@1.32.1 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/express': 4.17.12 '@types/glob': 7.1.3 '@types/mocha': 7.0.2 @@ -9171,7 +9185,7 @@ packages: chai: 4.3.4 cross-env: 7.0.3 downlevel-dts: 0.4.0 - eslint: 7.28.0 + eslint: 7.29.0 express: 4.17.1 fetch-mock: 9.11.0_node-fetch@2.6.1 form-data: 3.0.1 @@ -9217,19 +9231,18 @@ packages: version: 0.0.0 file:projects/core-lro.tgz: dependencies: - '@azure/core-tracing': 1.0.0-preview.11 '@microsoft/api-extractor': 7.7.11 '@rollup/plugin-commonjs': 11.0.2_rollup@1.32.1 '@rollup/plugin-multi-entry': 3.0.1_rollup@1.32.1 '@rollup/plugin-node-resolve': 8.4.0_rollup@1.32.1 '@rollup/plugin-replace': 2.4.2_rollup@1.32.1 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/mocha': 7.0.2 '@types/node': 8.10.66 assert: 1.5.0 chai: 4.3.4 cross-env: 7.0.3 - eslint: 7.28.0 + eslint: 7.29.0 events: 3.3.0 karma: 6.3.4 karma-chrome-launcher: 3.1.0 @@ -9267,7 +9280,7 @@ packages: file:projects/core-paging.tgz: dependencies: '@types/node': 8.10.66 - eslint: 7.28.0 + eslint: 7.29.0 prettier: 1.19.1 rimraf: 3.0.2 typedoc: 0.15.2 @@ -9280,14 +9293,13 @@ packages: version: 0.0.0 file:projects/core-rest-pipeline.tgz: dependencies: - '@azure/core-tracing': 1.0.0-preview.11 '@microsoft/api-extractor': 7.7.11 '@rollup/plugin-commonjs': 11.0.2_rollup@1.32.1 '@rollup/plugin-json': 4.1.0_rollup@1.32.1 '@rollup/plugin-multi-entry': 3.0.1_rollup@1.32.1 '@rollup/plugin-node-resolve': 8.4.0_rollup@1.32.1 '@rollup/plugin-replace': 2.4.2_rollup@1.32.1 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/mocha': 7.0.2 '@types/node': 8.10.66 '@types/sinon': 9.0.11 @@ -9295,7 +9307,7 @@ packages: chai: 4.3.4 cross-env: 7.0.3 downlevel-dts: 0.4.0 - eslint: 7.28.0 + eslint: 7.29.0 form-data: 3.0.1 http-proxy-agent: 4.0.1 https-proxy-agent: 5.0.0 @@ -9335,7 +9347,6 @@ packages: file:projects/core-tracing.tgz: dependencies: '@microsoft/api-extractor': 7.7.11 - '@opencensus/web-types': 0.0.7 '@opentelemetry/api': 0.20.0 '@rollup/plugin-commonjs': 11.0.2_rollup@1.32.1 '@rollup/plugin-json': 4.1.0_rollup@1.32.1 @@ -9347,7 +9358,7 @@ packages: '@types/sinon': 9.0.11 assert: 1.5.0 cross-env: 7.0.3 - eslint: 7.28.0 + eslint: 7.29.0 inherits: 2.0.4 karma: 6.3.4 karma-chrome-launcher: 3.1.0 @@ -9387,14 +9398,14 @@ packages: '@rollup/plugin-multi-entry': 3.0.1_rollup@1.32.1 '@rollup/plugin-node-resolve': 8.4.0_rollup@1.32.1 '@rollup/plugin-replace': 2.4.2_rollup@1.32.1 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/mocha': 7.0.2 '@types/node': 8.10.66 '@types/sinon': 9.0.11 chai: 4.3.4 cross-env: 7.0.3 downlevel-dts: 0.4.0 - eslint: 7.28.0 + eslint: 7.29.0 inherits: 2.0.4 karma: 6.3.4 karma-chrome-launcher: 3.1.0 @@ -9434,7 +9445,7 @@ packages: '@rollup/plugin-multi-entry': 3.0.1_rollup@1.32.1 '@rollup/plugin-node-resolve': 8.4.0_rollup@1.32.1 '@rollup/plugin-replace': 2.4.2_rollup@1.32.1 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/mocha': 7.0.2 '@types/node': 8.10.66 '@types/sinon': 9.0.11 @@ -9442,7 +9453,7 @@ packages: chai: 4.3.4 cross-env: 7.0.3 downlevel-dts: 0.4.0 - eslint: 7.28.0 + eslint: 7.29.0 inherits: 2.0.4 karma: 6.3.4 karma-chrome-launcher: 3.1.0 @@ -9496,11 +9507,11 @@ packages: debug: 4.3.1 dotenv: 8.6.0 downlevel-dts: 0.4.0 - eslint: 7.28.0 + eslint: 7.29.0 esm: 3.2.25 execa: 3.4.0 fast-json-stable-stringify: 2.1.0 - jsbi: 3.1.4 + jsbi: 3.1.5 mocha: 7.2.0 mocha-junit-reporter: 1.23.3_mocha@7.2.0 node-abort-controller: 1.2.1 @@ -9539,7 +9550,7 @@ packages: '@rollup/plugin-multi-entry': 3.0.1_rollup@1.32.1 '@rollup/plugin-node-resolve': 8.4.0_rollup@1.32.1 '@rollup/plugin-replace': 2.4.2_rollup@1.32.1 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/mocha': 7.0.2 '@types/node': 8.10.66 '@types/sinon': 9.0.11 @@ -9548,7 +9559,7 @@ packages: cross-env: 7.0.3 dotenv: 8.6.0 downlevel-dts: 0.4.0 - eslint: 7.28.0 + eslint: 7.29.0 inherits: 2.0.4 karma: 6.3.4 karma-chrome-launcher: 3.1.0 @@ -9590,7 +9601,7 @@ packages: '@rollup/plugin-json': 4.1.0_rollup@1.32.1 '@rollup/plugin-multi-entry': 3.0.1_rollup@1.32.1 '@rollup/plugin-node-resolve': 8.4.0_rollup@1.32.1 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/chai-as-promised': 7.1.4 '@types/fs-extra': 8.1.1 '@types/minimist': 1.2.1 @@ -9602,7 +9613,7 @@ packages: chai-as-promised: 7.1.1_chai@4.3.4 chalk: 4.1.1 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 fs-extra: 8.1.0 minimist: 1.2.5 mocha: 7.2.0 @@ -9624,7 +9635,6 @@ packages: version: 0.0.0 file:projects/digital-twins-core.tgz: dependencies: - '@azure/core-tracing': 1.0.0-preview.11 '@azure/identity': 1.3.0 '@microsoft/api-extractor': 7.7.11 '@rollup/plugin-commonjs': 11.0.2_rollup@1.32.1 @@ -9632,7 +9642,7 @@ packages: '@rollup/plugin-multi-entry': 3.0.1_rollup@1.32.1 '@rollup/plugin-node-resolve': 8.4.0_rollup@1.32.1 '@rollup/plugin-replace': 2.4.2_rollup@1.32.1 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/mocha': 7.0.2 '@types/node': 8.10.66 '@types/sinon': 9.0.11 @@ -9640,7 +9650,7 @@ packages: chai: 4.3.4 cross-env: 7.0.3 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 inherits: 2.0.4 karma: 6.3.4 karma-chrome-launcher: 3.1.0 @@ -9679,21 +9689,21 @@ packages: version: 0.0.0 file:projects/eslint-plugin-azure-sdk.tgz: dependencies: - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/eslint': 7.2.13 '@types/estree': 0.0.48 '@types/glob': 7.1.3 '@types/json-schema': 7.0.7 '@types/mocha': 7.0.2 '@types/node': 10.17.60 - '@typescript-eslint/eslint-plugin': 4.19.0_579c993deb6b0313d5d0f5c428bab62d - '@typescript-eslint/experimental-utils': 4.19.0_eslint@7.28.0+typescript@4.2.4 - '@typescript-eslint/parser': 4.19.0_eslint@7.28.0+typescript@4.2.4 + '@typescript-eslint/eslint-plugin': 4.19.0_32b60b6a5d7033b9e5296983f03a72ce + '@typescript-eslint/experimental-utils': 4.19.0_eslint@7.29.0+typescript@4.2.4 + '@typescript-eslint/parser': 4.19.0_eslint@7.29.0+typescript@4.2.4 '@typescript-eslint/typescript-estree': 4.19.0_typescript@4.2.4 chai: 4.3.4 - eslint: 7.28.0 - eslint-config-prettier: 7.2.0_eslint@7.28.0 - eslint-plugin-import: 2.23.4_eslint@7.28.0 + eslint: 7.29.0 + eslint-config-prettier: 7.2.0_eslint@7.29.0 + eslint-plugin-import: 2.23.4_eslint@7.29.0 eslint-plugin-no-only-tests: 2.6.0 eslint-plugin-promise: 4.3.1 eslint-plugin-tsdoc: 0.2.14 @@ -9715,7 +9725,6 @@ packages: version: 0.0.0 file:projects/event-hubs.tgz: dependencies: - '@azure/core-tracing': 1.0.0-preview.11 '@microsoft/api-extractor': 7.7.11 '@rollup/plugin-commonjs': 11.0.2_rollup@1.32.1 '@rollup/plugin-inject': 4.0.2_rollup@1.32.1 @@ -9724,7 +9733,7 @@ packages: '@rollup/plugin-node-resolve': 8.4.0_rollup@1.32.1 '@rollup/plugin-replace': 2.4.2_rollup@1.32.1 '@types/async-lock': 1.1.2 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/chai-as-promised': 7.1.4 '@types/chai-string': 1.4.2 '@types/debug': 4.1.5 @@ -9733,7 +9742,7 @@ packages: '@types/node': 8.10.66 '@types/sinon': 9.0.11 '@types/uuid': 8.3.0 - '@types/ws': 7.4.4 + '@types/ws': 7.4.5 assert: 1.5.0 buffer: 5.7.1 chai: 4.3.4 @@ -9743,7 +9752,7 @@ packages: debug: 4.3.1 dotenv: 8.6.0 downlevel-dts: 0.4.0 - eslint: 7.28.0 + eslint: 7.29.0 esm: 3.2.25 https-proxy-agent: 5.0.0 is-buffer: 2.0.5 @@ -9778,7 +9787,7 @@ packages: typedoc: 0.15.2 typescript: 4.2.4 uuid: 8.3.2 - ws: 7.4.6 + ws: 7.5.0 dev: false name: '@rush-temp/event-hubs' resolution: @@ -9796,14 +9805,14 @@ packages: '@rollup/plugin-node-resolve': 8.4.0_rollup@1.32.1 '@rollup/plugin-replace': 2.4.2_rollup@1.32.1 '@types/async-lock': 1.1.2 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/chai-as-promised': 7.1.4 '@types/chai-string': 1.4.2 '@types/debug': 4.1.5 '@types/mocha': 7.0.2 '@types/node': 8.10.66 '@types/uuid': 8.3.0 - '@types/ws': 7.4.4 + '@types/ws': 7.4.5 async-lock: 1.3.0 azure-storage: 2.10.4 chai: 4.3.4 @@ -9812,7 +9821,7 @@ packages: cross-env: 7.0.3 debug: 4.3.1 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 esm: 3.2.25 https-proxy-agent: 5.0.0 mocha: 7.2.0 @@ -9828,7 +9837,7 @@ packages: typedoc: 0.15.2 typescript: 4.2.4 uuid: 8.3.2 - ws: 7.4.6 + ws: 7.5.0 dev: false name: '@rush-temp/event-processor-host' resolution: @@ -9845,7 +9854,7 @@ packages: '@rollup/plugin-multi-entry': 3.0.1_rollup@1.32.1 '@rollup/plugin-node-resolve': 8.4.0_rollup@1.32.1 '@rollup/plugin-replace': 2.4.2_rollup@1.32.1 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/chai-as-promised': 7.1.4 '@types/mocha': 7.0.2 '@types/node': 8.10.66 @@ -9855,7 +9864,7 @@ packages: chai-as-promised: 7.1.1_chai@4.3.4 cross-env: 7.0.3 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 karma: 6.3.4 karma-chrome-launcher: 3.1.0 karma-coverage: 2.0.3 @@ -9901,7 +9910,7 @@ packages: '@rollup/plugin-multi-entry': 3.0.1_rollup@1.32.1 '@rollup/plugin-node-resolve': 8.4.0_rollup@1.32.1 '@rollup/plugin-replace': 2.4.2_rollup@1.32.1 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/chai-as-promised': 7.1.4 '@types/chai-string': 1.4.2 '@types/debug': 4.1.5 @@ -9914,7 +9923,7 @@ packages: cross-env: 7.0.3 debug: 4.3.1 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 esm: 3.2.25 events: 3.3.0 guid-typescript: 1.0.9 @@ -9951,9 +9960,75 @@ packages: integrity: sha512-kPDNdx4ZkZ5doODbROhFMQDIxyBwbahRK/NtXhvFHdcVBe+LNdSX2XgXVdzY36Ouwwr9/uWbnvlzHhgsG3l9xQ== tarball: file:projects/eventhubs-checkpointstore-blob.tgz version: 0.0.0 + file:projects/identity-cache-persistence.tgz: + dependencies: + '@azure/msal-node': 1.1.0 + '@azure/msal-node-extensions': 1.0.0-alpha.6 + '@microsoft/api-extractor': 7.7.11 + '@types/jws': 3.2.3 + '@types/mocha': 7.0.2 + '@types/node': 8.10.66 + '@types/qs': 6.9.6 + '@types/sinon': 9.0.11 + assert: 1.5.0 + cross-env: 7.0.3 + dotenv: 8.6.0 + eslint: 7.29.0 + inherits: 2.0.4 + keytar: 7.7.0 + mocha: 7.2.0 + mocha-junit-reporter: 1.23.3_mocha@7.2.0 + mock-fs: 4.14.0 + prettier: 1.19.1 + puppeteer: 3.3.0 + rimraf: 3.0.2 + rollup: 1.32.1 + sinon: 9.2.4 + tslib: 2.3.0 + typedoc: 0.15.2 + typescript: 4.2.4 + util: 0.12.4 + dev: false + name: '@rush-temp/identity-cache-persistence' + resolution: + integrity: sha512-4kcOh05iPn1Q/OPFhlcPgE8+2HNI/hTed17+qMabC68jt8SzX7c1Llhiu8uJfmrvyg/ws83dgWnd38dEYDDqEA== + tarball: file:projects/identity-cache-persistence.tgz + version: 0.0.0 + file:projects/identity-vscode.tgz: + dependencies: + '@microsoft/api-extractor': 7.7.11 + '@types/jws': 3.2.3 + '@types/mocha': 7.0.2 + '@types/node': 8.10.66 + '@types/qs': 6.9.6 + '@types/sinon': 9.0.11 + '@types/uuid': 8.3.0 + assert: 1.5.0 + cross-env: 7.0.3 + dotenv: 8.6.0 + eslint: 7.29.0 + inherits: 2.0.4 + keytar: 7.7.0 + mocha: 7.2.0 + mocha-junit-reporter: 1.23.3_mocha@7.2.0 + mock-fs: 4.14.0 + prettier: 1.19.1 + puppeteer: 3.3.0 + rimraf: 3.0.2 + rollup: 1.32.1 + sinon: 9.2.4 + tslib: 2.3.0 + typedoc: 0.15.2 + typescript: 4.2.4 + util: 0.12.4 + dev: false + name: '@rush-temp/identity-vscode' + resolution: + integrity: sha512-Vz1rlmfRj9+CsPGCuj2RxyXlemnz6MrZnch7WSmsMUe/OYljjtVDCiYycAub9HwqqGSIT9xiNgXOBDt+KZIgCA== + tarball: file:projects/identity-vscode.tgz + version: 0.0.0 file:projects/identity.tgz: dependencies: - '@azure/core-tracing': 1.0.0-preview.11 '@azure/msal-browser': 2.14.2 '@azure/msal-common': 4.3.0 '@azure/msal-node': 1.1.0 @@ -9968,7 +10043,7 @@ packages: assert: 1.5.0 cross-env: 7.0.3 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 events: 3.3.0 inherits: 2.0.4 jws: 4.0.0 @@ -9998,18 +10073,17 @@ packages: dev: false name: '@rush-temp/identity' resolution: - integrity: sha512-OFIS+gx/7T0Bs3YObe7wv2MKfdGawdgRQ7UvRN6mQUYDCjkW37NpPdP8QoLCNQi1m3u0BwWf2HhuKEUhG/Y/Bw== + integrity: sha512-WhzQXtuVDAdYFtQtAqj9om+FireeOVVkgmVP/bZwh4vYueDup+Nlp6slAq9lMJz/auX80Y9LXy1VzErjNxWtsA== tarball: file:projects/identity.tgz version: 0.0.0 file:projects/iot-device-update.tgz: dependencies: - '@azure/core-tracing': 1.0.0-preview.11 '@microsoft/api-extractor': 7.7.11 '@types/node': 8.10.66 '@types/uuid': 8.3.0 cross-env: 7.0.3 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 mkdirp: 1.0.4 prettier: 1.19.1 rimraf: 3.0.2 @@ -10038,13 +10112,13 @@ packages: '@rollup/plugin-multi-entry': 3.0.1_rollup@1.32.1 '@rollup/plugin-node-resolve': 8.4.0_rollup@1.32.1 '@rollup/plugin-replace': 2.4.2_rollup@1.32.1 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/mocha': 7.0.2 '@types/node': 8.10.66 '@types/sinon': 9.0.11 chai: 4.3.4 cross-env: 7.0.3 - eslint: 7.28.0 + eslint: 7.29.0 events: 3.3.0 inherits: 2.0.4 karma: 6.3.4 @@ -10082,8 +10156,6 @@ packages: version: 0.0.0 file:projects/keyvault-admin.tgz: dependencies: - '@azure/core-tracing': 1.0.0-preview.11 - '@azure/identity': 2.0.0-beta.3 '@azure/keyvault-keys': 4.2.1 '@microsoft/api-extractor': 7.7.11 '@rollup/plugin-commonjs': 11.0.2_rollup@1.32.1 @@ -10091,7 +10163,7 @@ packages: '@rollup/plugin-multi-entry': 3.0.1_rollup@1.32.1 '@rollup/plugin-node-resolve': 8.4.0_rollup@1.32.1 '@rollup/plugin-replace': 2.4.2_rollup@1.32.1 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/chai-as-promised': 7.1.4 '@types/mocha': 7.0.2 '@types/node': 8.10.66 @@ -10102,7 +10174,7 @@ packages: chai-as-promised: 7.1.1_chai@4.3.4 cross-env: 7.0.3 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 esm: 3.2.25 mocha: 7.2.0 mocha-junit-reporter: 1.23.3_mocha@7.2.0 @@ -10128,8 +10200,6 @@ packages: version: 0.0.0 file:projects/keyvault-certificates.tgz: dependencies: - '@azure/core-tracing': 1.0.0-preview.11 - '@azure/identity': 2.0.0-beta.3 '@azure/keyvault-secrets': 4.2.0 '@microsoft/api-extractor': 7.7.11 '@rollup/plugin-commonjs': 11.0.2_rollup@1.32.1 @@ -10137,7 +10207,7 @@ packages: '@rollup/plugin-multi-entry': 3.0.1_rollup@1.32.1 '@rollup/plugin-node-resolve': 8.4.0_rollup@1.32.1 '@rollup/plugin-replace': 2.4.2_rollup@1.32.1 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/mocha': 7.0.2 '@types/node': 8.10.66 '@types/query-string': 6.2.0 @@ -10146,7 +10216,7 @@ packages: chai: 4.3.4 cross-env: 7.0.3 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 esm: 3.2.25 karma: 6.3.4 karma-chrome-launcher: 3.1.0 @@ -10187,8 +10257,7 @@ packages: version: 0.0.0 file:projects/keyvault-common.tgz: dependencies: - '@azure/core-tracing': 1.0.0-preview.11 - eslint: 7.28.0 + eslint: 7.29.0 prettier: 1.19.1 rimraf: 3.0.2 tslib: 2.3.0 @@ -10201,15 +10270,13 @@ packages: version: 0.0.0 file:projects/keyvault-keys.tgz: dependencies: - '@azure/core-tracing': 1.0.0-preview.11 - '@azure/identity': 2.0.0-beta.3 '@microsoft/api-extractor': 7.7.11 '@rollup/plugin-commonjs': 11.0.2_rollup@1.32.1 '@rollup/plugin-json': 4.1.0_rollup@1.32.1 '@rollup/plugin-multi-entry': 3.0.1_rollup@1.32.1 '@rollup/plugin-node-resolve': 8.4.0_rollup@1.32.1 '@rollup/plugin-replace': 2.4.2_rollup@1.32.1 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/chai-as-promised': 7.1.4 '@types/mocha': 7.0.2 '@types/node': 8.10.66 @@ -10220,7 +10287,7 @@ packages: chai-as-promised: 7.1.1_chai@4.3.4 cross-env: 7.0.3 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 esm: 3.2.25 karma: 6.3.4 karma-chrome-launcher: 3.1.0 @@ -10261,15 +10328,13 @@ packages: version: 0.0.0 file:projects/keyvault-secrets.tgz: dependencies: - '@azure/core-tracing': 1.0.0-preview.11 - '@azure/identity': 2.0.0-beta.3 '@microsoft/api-extractor': 7.7.11 '@rollup/plugin-commonjs': 11.0.2_rollup@1.32.1 '@rollup/plugin-json': 4.1.0_rollup@1.32.1 '@rollup/plugin-multi-entry': 3.0.1_rollup@1.32.1 '@rollup/plugin-node-resolve': 8.4.0_rollup@1.32.1 '@rollup/plugin-replace': 2.4.2_rollup@1.32.1 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/mocha': 7.0.2 '@types/node': 8.10.66 '@types/query-string': 6.2.0 @@ -10278,7 +10343,7 @@ packages: chai: 4.3.4 cross-env: 7.0.3 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 esm: 3.2.25 karma: 6.3.4 karma-chrome-launcher: 3.1.0 @@ -10324,7 +10389,7 @@ packages: '@rollup/plugin-multi-entry': 3.0.1_rollup@1.32.1 '@rollup/plugin-node-resolve': 8.4.0_rollup@1.32.1 '@rollup/plugin-replace': 2.4.2_rollup@1.32.1 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/mocha': 7.0.2 '@types/node': 8.10.66 '@types/sinon': 9.0.11 @@ -10333,7 +10398,7 @@ packages: cross-env: 7.0.3 delay: 4.4.1 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 karma: 6.3.4 karma-chrome-launcher: 3.1.0 karma-coverage: 2.0.3 @@ -10367,9 +10432,8 @@ packages: version: 0.0.0 file:projects/mixedreality-authentication.tgz: dependencies: - '@azure/core-tracing': 1.0.0-preview.11 '@microsoft/api-extractor': 7.7.11 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/chai-as-promised': 7.1.4 '@types/mocha': 7.0.2 '@types/node': 8.10.66 @@ -10377,7 +10441,7 @@ packages: chai-as-promised: 7.1.1_chai@4.3.4 cross-env: 7.0.3 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 inherits: 2.0.4 karma: 6.3.4 karma-chrome-launcher: 3.1.0 @@ -10412,7 +10476,7 @@ packages: dependencies: '@types/node': 8.10.66 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 prettier: 1.19.1 rhea: 2.0.2 rimraf: 3.0.2 @@ -10434,8 +10498,8 @@ packages: '@opentelemetry/tracing': 0.18.2 '@types/mocha': 7.0.2 '@types/node': 10.17.60 - eslint: 7.28.0 - eslint-plugin-node: 11.1.0_eslint@7.28.0 + eslint: 7.29.0 + eslint-plugin-node: 11.1.0_eslint@7.29.0 execa: 3.4.0 mocha: 7.2.0 nock: 12.0.3 @@ -10456,13 +10520,12 @@ packages: version: 0.0.0 file:projects/monitor-query.tgz: dependencies: - '@azure/core-tracing': 1.0.0-preview.11 '@azure/identity': 1.3.0 '@microsoft/api-extractor': 7.7.11 '@opentelemetry/api': 0.20.0 '@opentelemetry/node': 0.20.0_@opentelemetry+api@0.20.0 '@opentelemetry/tracing': 0.18.2 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/chai-as-promised': 7.1.4 '@types/mocha': 7.0.2 '@types/node': 8.10.66 @@ -10471,7 +10534,7 @@ packages: cross-env: 7.0.3 dotenv: 8.6.0 downlevel-dts: 0.4.0 - eslint: 7.28.0 + eslint: 7.29.0 esm: 3.2.25 inherits: 2.0.4 karma: 6.3.4 @@ -10506,10 +10569,9 @@ packages: file:projects/perf-ai-form-recognizer.tgz: dependencies: '@azure/ai-form-recognizer': 3.1.0-beta.3 - '@azure/identity': 2.0.0-beta.3 '@types/node': 8.10.66 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 prettier: 1.19.1 rimraf: 3.0.2 ts-node: 9.1.1_typescript@4.2.4 @@ -10526,7 +10588,7 @@ packages: '@azure/ai-metrics-advisor': 1.0.0-beta.3 '@types/node': 8.10.66 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 prettier: 1.19.1 rimraf: 3.0.2 ts-node: 9.1.1_typescript@4.2.4 @@ -10540,10 +10602,9 @@ packages: version: 0.0.0 file:projects/perf-ai-text-analytics.tgz: dependencies: - '@azure/identity': 2.0.0-beta.3 '@types/node': 8.10.66 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 prettier: 1.19.1 rimraf: 3.0.2 ts-node: 9.1.1_typescript@4.2.4 @@ -10559,7 +10620,7 @@ packages: dependencies: '@types/uuid': 8.3.0 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 prettier: 1.19.1 rimraf: 3.0.2 ts-node: 9.1.1_typescript@4.2.4 @@ -10575,7 +10636,7 @@ packages: dependencies: '@types/node': 8.10.66 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 prettier: 1.19.1 rimraf: 3.0.2 ts-node: 9.1.1_typescript@4.2.4 @@ -10591,7 +10652,7 @@ packages: dependencies: '@types/uuid': 8.3.0 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 prettier: 1.19.1 rimraf: 3.0.2 ts-node: 9.1.1_typescript@4.2.4 @@ -10600,16 +10661,15 @@ packages: dev: false name: '@rush-temp/perf-identity' resolution: - integrity: sha512-0AGKpgyfSwfjXGgEfT+3JFmDLtwWSuYPjMoPgo0Cr6QKwleihOaC2Gkxlb5jgXuo412syQrJyQI2TTs8xhsVGA== + integrity: sha512-Xcm3bc1sQF3yp0wCcTZ3eSDf2o3DDxQvgPzy1Byjird4i3hf4PrhG0l0Z21Oy/OeVDHm50pELO38mJIosuxR7w== tarball: file:projects/perf-identity.tgz version: 0.0.0 file:projects/perf-keyvault-certificates.tgz: dependencies: - '@azure/identity': 2.0.0-beta.3 '@azure/keyvault-certificates': 4.2.0 '@types/uuid': 8.3.0 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 prettier: 1.19.1 rimraf: 3.0.2 ts-node: 9.1.1_typescript@4.2.4 @@ -10624,11 +10684,10 @@ packages: version: 0.0.0 file:projects/perf-keyvault-keys.tgz: dependencies: - '@azure/identity': 2.0.0-beta.3 '@azure/keyvault-keys': 4.2.1 '@types/uuid': 8.3.0 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 prettier: 1.19.1 rimraf: 3.0.2 ts-node: 9.1.1_typescript@4.2.4 @@ -10643,11 +10702,10 @@ packages: version: 0.0.0 file:projects/perf-keyvault-secrets.tgz: dependencies: - '@azure/identity': 2.0.0-beta.3 '@azure/keyvault-secrets': 4.2.0 '@types/uuid': 8.3.0 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 prettier: 1.19.1 rimraf: 3.0.2 ts-node: 9.1.1_typescript@4.2.4 @@ -10662,10 +10720,9 @@ packages: version: 0.0.0 file:projects/perf-search-documents.tgz: dependencies: - '@azure/identity': 2.0.0-beta.3 '@types/node': 8.10.66 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 prettier: 1.19.1 rimraf: 3.0.2 ts-node: 9.1.1_typescript@4.2.4 @@ -10684,7 +10741,7 @@ packages: '@types/node-fetch': 2.5.10 '@types/uuid': 8.3.0 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 node-fetch: 2.6.1 prettier: 1.19.1 rimraf: 3.0.2 @@ -10703,7 +10760,7 @@ packages: '@types/node': 8.10.66 '@types/uuid': 8.3.0 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 prettier: 1.19.1 rimraf: 3.0.2 ts-node: 9.1.1_typescript@4.2.4 @@ -10721,7 +10778,7 @@ packages: '@types/node': 8.10.66 '@types/uuid': 8.3.0 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 prettier: 1.19.1 rimraf: 3.0.2 ts-node: 9.1.1_typescript@4.2.4 @@ -10739,13 +10796,13 @@ packages: '@azure/core-rest-pipeline': 1.0.4 '@azure/identity': 1.3.0 '@microsoft/api-extractor': 7.13.2 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/mocha': 7.0.2 '@types/node': 8.10.66 chai: 4.3.4 cross-env: 7.0.3 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 karma: 6.3.4 karma-chrome-launcher: 3.1.0 karma-coverage: 2.0.3 @@ -10782,13 +10839,13 @@ packages: '@azure/core-rest-pipeline': 1.0.4 '@azure/identity': 1.3.0 '@microsoft/api-extractor': 7.13.2 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/mocha': 7.0.2 '@types/node': 8.10.66 chai: 4.3.4 cross-env: 7.0.3 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 karma: 6.3.4 karma-chrome-launcher: 3.1.0 karma-coverage: 2.0.3 @@ -10822,7 +10879,6 @@ packages: version: 0.0.0 file:projects/quantum-jobs.tgz: dependencies: - '@azure/core-tracing': 1.0.0-preview.11 '@azure/identity': 1.3.0 '@microsoft/api-extractor': 7.7.11 '@rollup/plugin-commonjs': 11.0.2_rollup@1.32.1 @@ -10830,14 +10886,14 @@ packages: '@rollup/plugin-multi-entry': 3.0.1_rollup@1.32.1 '@rollup/plugin-node-resolve': 8.4.0_rollup@1.32.1 '@rollup/plugin-replace': 2.4.2_rollup@1.32.1 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/mocha': 7.0.2 '@types/node': 8.10.66 '@types/sinon': 9.0.11 chai: 4.3.4 cross-env: 7.0.3 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 events: 3.3.0 inherits: 2.0.4 karma: 6.3.4 @@ -10876,8 +10932,6 @@ packages: version: 0.0.0 file:projects/schema-registry-avro.tgz: dependencies: - '@azure/core-tracing': 1.0.0-preview.11 - '@azure/identity': 2.0.0-beta.3 '@microsoft/api-extractor': 7.7.11 '@rollup/plugin-commonjs': 11.0.2_rollup@1.32.1 '@rollup/plugin-inject': 4.0.2_rollup@1.32.1 @@ -10885,7 +10939,7 @@ packages: '@rollup/plugin-multi-entry': 3.0.1_rollup@1.32.1 '@rollup/plugin-node-resolve': 8.4.0_rollup@1.32.1 '@rollup/plugin-replace': 2.4.2_rollup@1.32.1 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/chai-as-promised': 7.1.4 '@types/mocha': 7.0.2 '@types/node': 8.10.66 @@ -10895,7 +10949,7 @@ packages: chai-as-promised: 7.1.1_chai@4.3.4 cross-env: 7.0.3 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 karma: 6.3.4 karma-chrome-launcher: 3.1.0 karma-coverage: 2.0.3 @@ -10932,15 +10986,13 @@ packages: version: 0.0.0 file:projects/schema-registry.tgz: dependencies: - '@azure/core-tracing': 1.0.0-preview.11 - '@azure/identity': 2.0.0-beta.3 '@microsoft/api-extractor': 7.7.11 '@rollup/plugin-commonjs': 11.0.2_rollup@1.32.1 '@rollup/plugin-json': 4.1.0_rollup@1.32.1 '@rollup/plugin-multi-entry': 3.0.1_rollup@1.32.1 '@rollup/plugin-node-resolve': 8.4.0_rollup@1.32.1 '@rollup/plugin-replace': 2.4.2_rollup@1.32.1 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/chai-as-promised': 7.1.4 '@types/mocha': 7.0.2 '@types/node': 8.10.66 @@ -10948,7 +11000,7 @@ packages: chai-as-promised: 7.1.1_chai@4.3.4 cross-env: 7.0.3 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 karma: 6.3.4 karma-chrome-launcher: 3.1.0 karma-coverage: 2.0.3 @@ -10984,21 +11036,20 @@ packages: version: 0.0.0 file:projects/search-documents.tgz: dependencies: - '@azure/core-tracing': 1.0.0-preview.11 '@microsoft/api-extractor': 7.7.11 '@rollup/plugin-commonjs': 11.0.2_rollup@1.32.1 '@rollup/plugin-json': 4.1.0_rollup@1.32.1 '@rollup/plugin-multi-entry': 3.0.1_rollup@1.32.1 '@rollup/plugin-node-resolve': 8.4.0_rollup@1.32.1 '@rollup/plugin-replace': 2.4.2_rollup@1.32.1 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/mocha': 7.0.2 '@types/node': 8.10.66 '@types/sinon': 9.0.11 chai: 4.3.4 cross-env: 7.0.3 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 events: 3.3.0 inherits: 2.0.4 karma: 6.3.4 @@ -11038,8 +11089,6 @@ packages: version: 0.0.0 file:projects/service-bus.tgz: dependencies: - '@azure/core-tracing': 1.0.0-preview.11 - '@azure/identity': 2.0.0-beta.3_debug@4.3.1 '@microsoft/api-extractor': 7.7.11 '@rollup/plugin-commonjs': 11.0.2_rollup@1.32.1 '@rollup/plugin-inject': 4.0.2_rollup@1.32.1 @@ -11047,7 +11096,7 @@ packages: '@rollup/plugin-multi-entry': 3.0.1_rollup@1.32.1 '@rollup/plugin-node-resolve': 8.4.0_rollup@1.32.1 '@rollup/plugin-replace': 2.4.2_rollup@1.32.1 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/chai-as-promised': 7.1.4 '@types/debug': 4.1.5 '@types/glob': 7.1.3 @@ -11056,7 +11105,7 @@ packages: '@types/mocha': 7.0.2 '@types/node': 8.10.66 '@types/sinon': 9.0.11 - '@types/ws': 7.4.4 + '@types/ws': 7.4.5 assert: 1.5.0 buffer: 5.7.1 chai: 4.3.4 @@ -11067,7 +11116,7 @@ packages: delay: 4.4.1 dotenv: 8.6.0 downlevel-dts: 0.4.0 - eslint: 7.28.0 + eslint: 7.29.0 esm: 3.2.25 events: 3.3.0 glob: 7.1.7 @@ -11105,7 +11154,7 @@ packages: tslib: 2.3.0 typedoc: 0.15.2 typescript: 4.2.4 - ws: 7.4.6 + ws: 7.5.0 dev: false name: '@rush-temp/service-bus' resolution: @@ -11114,7 +11163,6 @@ packages: version: 0.0.0 file:projects/storage-blob-changefeed.tgz: dependencies: - '@azure/core-tracing': 1.0.0-preview.11 '@microsoft/api-extractor': 7.7.11 '@rollup/plugin-commonjs': 11.0.2_rollup@1.32.1 '@rollup/plugin-multi-entry': 3.0.1_rollup@1.32.1 @@ -11128,7 +11176,7 @@ packages: dotenv: 8.6.0 downlevel-dts: 0.4.0 es6-promise: 4.2.8 - eslint: 7.28.0 + eslint: 7.29.0 esm: 3.2.25 events: 3.3.0 inherits: 2.0.4 @@ -11172,8 +11220,6 @@ packages: file:projects/storage-blob.tgz: dependencies: '@azure/core-rest-pipeline': 1.0.4 - '@azure/core-tracing': 1.0.0-preview.11 - '@azure/identity': 2.0.0-beta.3 '@microsoft/api-extractor': 7.7.11 '@rollup/plugin-commonjs': 11.0.2_rollup@1.32.1 '@rollup/plugin-json': 4.1.0_rollup@1.32.1 @@ -11188,7 +11234,7 @@ packages: dotenv: 8.6.0 downlevel-dts: 0.4.0 es6-promise: 4.2.8 - eslint: 7.28.0 + eslint: 7.29.0 esm: 3.2.25 events: 3.3.0 inherits: 2.0.4 @@ -11231,8 +11277,6 @@ packages: version: 0.0.0 file:projects/storage-file-datalake.tgz: dependencies: - '@azure/core-tracing': 1.0.0-preview.11 - '@azure/identity': 2.0.0-beta.3 '@microsoft/api-extractor': 7.7.11 '@rollup/plugin-commonjs': 11.0.2_rollup@1.32.1 '@rollup/plugin-json': 4.1.0_rollup@1.32.1 @@ -11247,7 +11291,7 @@ packages: dotenv: 8.6.0 downlevel-dts: 0.4.0 es6-promise: 4.2.8 - eslint: 7.28.0 + eslint: 7.29.0 esm: 3.2.25 events: 3.3.0 execa: 3.4.0 @@ -11291,7 +11335,6 @@ packages: version: 0.0.0 file:projects/storage-file-share.tgz: dependencies: - '@azure/core-tracing': 1.0.0-preview.11 '@microsoft/api-extractor': 7.7.11 '@rollup/plugin-commonjs': 11.0.2_rollup@1.32.1 '@rollup/plugin-multi-entry': 3.0.1_rollup@1.32.1 @@ -11304,7 +11347,7 @@ packages: dotenv: 8.6.0 downlevel-dts: 0.4.0 es6-promise: 4.2.8 - eslint: 7.28.0 + eslint: 7.29.0 esm: 3.2.25 events: 3.3.0 inherits: 2.0.4 @@ -11357,7 +11400,7 @@ packages: dotenv: 8.6.0 downlevel-dts: 0.4.0 es6-promise: 4.2.8 - eslint: 7.28.0 + eslint: 7.29.0 esm: 3.2.25 inherits: 2.0.4 karma: 6.3.4 @@ -11397,8 +11440,6 @@ packages: version: 0.0.0 file:projects/storage-queue.tgz: dependencies: - '@azure/core-tracing': 1.0.0-preview.11 - '@azure/identity': 2.0.0-beta.3 '@microsoft/api-extractor': 7.7.11 '@rollup/plugin-commonjs': 11.0.2_rollup@1.32.1 '@rollup/plugin-multi-entry': 3.0.1_rollup@1.32.1 @@ -11411,7 +11452,7 @@ packages: dotenv: 8.6.0 downlevel-dts: 0.4.0 es6-promise: 4.2.8 - eslint: 7.28.0 + eslint: 7.29.0 esm: 3.2.25 inherits: 2.0.4 karma: 6.3.4 @@ -11452,10 +11493,9 @@ packages: version: 0.0.0 file:projects/synapse-access-control.tgz: dependencies: - '@azure/core-tracing': 1.0.0-preview.11 '@microsoft/api-extractor': 7.7.11 '@rollup/plugin-commonjs': 11.0.2_rollup@1.32.1 - eslint: 7.28.0 + eslint: 7.29.0 rimraf: 3.0.2 rollup: 1.32.1 rollup-plugin-node-resolve: 3.4.0 @@ -11472,10 +11512,9 @@ packages: version: 0.0.0 file:projects/synapse-artifacts.tgz: dependencies: - '@azure/core-tracing': 1.0.0-preview.11 '@microsoft/api-extractor': 7.7.11 '@rollup/plugin-commonjs': 11.0.2_rollup@1.32.1 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/chai-as-promised': 7.1.4 '@types/mocha': 7.0.2 '@types/node': 8.10.66 @@ -11484,7 +11523,7 @@ packages: chai-as-promised: 7.1.1_chai@4.3.4 cross-env: 7.0.3 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 karma: 6.3.4 karma-chrome-launcher: 3.1.0 karma-coverage: 2.0.3 @@ -11522,10 +11561,9 @@ packages: version: 0.0.0 file:projects/synapse-managed-private-endpoints.tgz: dependencies: - '@azure/core-tracing': 1.0.0-preview.11 '@microsoft/api-extractor': 7.7.11 '@rollup/plugin-commonjs': 11.0.2_rollup@1.32.1 - eslint: 7.28.0 + eslint: 7.29.0 rimraf: 3.0.2 rollup: 1.32.1 rollup-plugin-node-resolve: 3.4.0 @@ -11542,10 +11580,9 @@ packages: version: 0.0.0 file:projects/synapse-monitoring.tgz: dependencies: - '@azure/core-tracing': 1.0.0-preview.11 '@microsoft/api-extractor': 7.7.11 '@rollup/plugin-commonjs': 11.0.2_rollup@1.32.1 - eslint: 7.28.0 + eslint: 7.29.0 rimraf: 3.0.2 rollup: 1.32.1 rollup-plugin-node-resolve: 3.4.0 @@ -11562,10 +11599,9 @@ packages: version: 0.0.0 file:projects/synapse-spark.tgz: dependencies: - '@azure/core-tracing': 1.0.0-preview.11 '@microsoft/api-extractor': 7.7.11 '@rollup/plugin-commonjs': 11.0.2_rollup@1.32.1 - eslint: 7.28.0 + eslint: 7.29.0 rimraf: 3.0.2 rollup: 1.32.1 rollup-plugin-node-resolve: 3.4.0 @@ -11582,9 +11618,8 @@ packages: version: 0.0.0 file:projects/template.tgz: dependencies: - '@azure/core-tracing': 1.0.0-preview.11 '@microsoft/api-extractor': 7.7.11 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/chai-as-promised': 7.1.4 '@types/mocha': 7.0.2 '@types/node': 8.10.66 @@ -11593,7 +11628,7 @@ packages: cross-env: 7.0.3 dotenv: 8.6.0 downlevel-dts: 0.4.0 - eslint: 7.28.0 + eslint: 7.29.0 esm: 3.2.25 inherits: 2.0.4 karma: 6.3.4 @@ -11630,7 +11665,7 @@ packages: '@types/minimist': 1.2.1 '@types/node': 8.10.66 '@types/node-fetch': 2.5.10 - eslint: 7.28.0 + eslint: 7.29.0 karma: 6.3.4 karma-chrome-launcher: 3.1.0 karma-coverage: 2.0.3 @@ -11649,12 +11684,11 @@ packages: version: 0.0.0 file:projects/test-utils-recorder.tgz: dependencies: - '@azure/core-tracing': 1.0.0-preview.11 '@rollup/plugin-commonjs': 11.0.2_rollup@1.32.1 '@rollup/plugin-multi-entry': 3.0.1_rollup@1.32.1 '@rollup/plugin-node-resolve': 8.4.0_rollup@1.32.1 '@rollup/plugin-replace': 2.4.2_rollup@1.32.1 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/fs-extra': 8.1.1 '@types/md5': 2.3.0 '@types/mocha': 7.0.2 @@ -11664,7 +11698,7 @@ packages: '@types/node': 8.10.66 chai: 4.3.4 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 fs-extra: 8.1.0 karma: 6.3.4 karma-chrome-launcher: 3.1.0 @@ -11707,13 +11741,13 @@ packages: file:projects/test-utils.tgz: dependencies: '@microsoft/api-extractor': 7.7.11 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/mocha': 7.0.2 '@types/node': 8.10.66 '@types/sinon': 9.0.11 chai: 4.3.4 chai-as-promised: 7.1.1_chai@4.3.4 - eslint: 7.28.0 + eslint: 7.29.0 karma: 6.3.4 karma-chrome-launcher: 3.1.0 karma-coverage: 2.0.3 @@ -11733,10 +11767,8 @@ packages: version: 0.0.0 file:projects/video-analyzer-edge.tgz: dependencies: - '@azure/core-tracing': 1.0.0-preview.11 '@microsoft/api-extractor': 7.7.11 - '@opentelemetry/api': 1.0.0-rc.0 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/chai-as-promised': 7.1.4 '@types/mocha': 7.0.2 '@types/node': 8.10.66 @@ -11745,7 +11777,7 @@ packages: chai-as-promised: 7.1.1_chai@4.3.4 cross-env: 7.0.3 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 events: 3.3.0 inherits: 2.0.4 karma: 6.3.4 @@ -11777,7 +11809,6 @@ packages: version: 0.0.0 file:projects/web-pubsub-express.tgz: dependencies: - '@azure/core-tracing': 1.0.0-preview.11 '@azure/identity': 1.3.0 '@microsoft/api-extractor': 7.7.11 '@rollup/plugin-commonjs': 11.0.2_rollup@1.32.1 @@ -11785,10 +11816,10 @@ packages: '@rollup/plugin-multi-entry': 3.0.1_rollup@1.32.1 '@rollup/plugin-node-resolve': 8.4.0_rollup@1.32.1 '@rollup/plugin-replace': 2.4.2_rollup@1.32.1 - '@types/chai': 4.2.18 + '@types/chai': 4.2.19 '@types/express': 4.17.12 '@types/express-serve-static-core': 4.17.21 - '@types/jsonwebtoken': 8.5.1 + '@types/jsonwebtoken': 8.5.2 '@types/mocha': 7.0.2 '@types/node': 8.10.66 '@types/query-string': 6.2.0 @@ -11798,7 +11829,7 @@ packages: cloudevents: 4.0.2 cross-env: 7.0.3 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 esm: 3.2.25 jsonwebtoken: 8.5.1 karma: 6.3.4 @@ -11839,7 +11870,6 @@ packages: version: 0.0.0 file:projects/web-pubsub.tgz: dependencies: - '@azure/core-tracing': 1.0.0-preview.11 '@azure/identity': 1.3.0 '@microsoft/api-extractor': 7.7.11 '@rollup/plugin-commonjs': 11.0.2_rollup@1.32.1 @@ -11847,7 +11877,7 @@ packages: '@rollup/plugin-multi-entry': 3.0.1_rollup@1.32.1 '@rollup/plugin-node-resolve': 8.4.0_rollup@1.32.1 '@rollup/plugin-replace': 2.4.2_rollup@1.32.1 - '@types/jsonwebtoken': 8.5.1 + '@types/jsonwebtoken': 8.5.2 '@types/mocha': 7.0.2 '@types/node': 8.10.66 '@types/query-string': 6.2.0 @@ -11856,7 +11886,7 @@ packages: chai: 4.3.4 cross-env: 7.0.3 dotenv: 8.6.0 - eslint: 7.28.0 + eslint: 7.29.0 esm: 3.2.25 jsonwebtoken: 8.5.1 karma: 6.3.4 @@ -11895,7 +11925,6 @@ packages: integrity: sha512-vR4Y02jE/bLss6v013XQnI7fHgUp+r4ENYXoaHKRAtNMixhfeobUozzrZuMQJjCTyh0ps8FxxEn3BB3It5SySQ== tarball: file:projects/web-pubsub.tgz version: 0.0.0 -registry: '' specifiers: '@rush-temp/abort-controller': file:./projects/abort-controller.tgz '@rush-temp/agrifood-farming': file:./projects/agrifood-farming.tgz @@ -11937,6 +11966,8 @@ specifiers: '@rush-temp/eventgrid': file:./projects/eventgrid.tgz '@rush-temp/eventhubs-checkpointstore-blob': file:./projects/eventhubs-checkpointstore-blob.tgz '@rush-temp/identity': file:./projects/identity.tgz + '@rush-temp/identity-cache-persistence': file:./projects/identity-cache-persistence.tgz + '@rush-temp/identity-vscode': file:./projects/identity-vscode.tgz '@rush-temp/iot-device-update': file:./projects/iot-device-update.tgz '@rush-temp/iot-modelsrepository': file:./projects/iot-modelsrepository.tgz '@rush-temp/keyvault-admin': file:./projects/keyvault-admin.tgz diff --git a/rush.json b/rush.json index 61ea3b71b0ce..eb5e506f2aeb 100644 --- a/rush.json +++ b/rush.json @@ -541,6 +541,16 @@ "projectFolder": "sdk/identity/identity", "versionPolicyName": "client" }, + { + "packageName": "@azure/identity-vscode", + "projectFolder": "sdk/identity/identity-vscode", + "versionPolicyName": "client" + }, + { + "packageName": "@azure/identity-cache-persistence", + "projectFolder": "sdk/identity/identity-cache-persistence", + "versionPolicyName": "client" + }, { "packageName": "@azure/keyvault-common", "projectFolder": "sdk/keyvault/keyvault-common", diff --git a/sdk/identity/identity-cache-persistence/.eslintrc.json b/sdk/identity/identity-cache-persistence/.eslintrc.json new file mode 100644 index 000000000000..1c1503b9333a --- /dev/null +++ b/sdk/identity/identity-cache-persistence/.eslintrc.json @@ -0,0 +1,8 @@ +{ + "plugins": ["@azure/azure-sdk"], + "extends": ["plugin:@azure/azure-sdk/azure-sdk-base"], + "rules": { + "@azure/azure-sdk/ts-package-json-module": "off", + "@azure/azure-sdk/ts-package-json-engine-is-present": "off" + } +} diff --git a/sdk/identity/identity-cache-persistence/.gitignore b/sdk/identity/identity-cache-persistence/.gitignore new file mode 100644 index 000000000000..3c8af5ad63ff --- /dev/null +++ b/sdk/identity/identity-cache-persistence/.gitignore @@ -0,0 +1 @@ +!test/assets/cert.pem diff --git a/sdk/identity/identity-cache-persistence/CHANGELOG.md b/sdk/identity/identity-cache-persistence/CHANGELOG.md new file mode 100644 index 000000000000..078f0038aef8 --- /dev/null +++ b/sdk/identity/identity-cache-persistence/CHANGELOG.md @@ -0,0 +1,11 @@ +# Release History + +## 1.0.0-beta.1 (Unreleased) + +### New features + +- This release marks the initial beta availability of the `@azure/identity-cache-persistence` package. This package provides an extension to `@azure/identity` that enables persistent token caching in a secure storage defined by the Operating System (caching of token values across sessions), which allows skipping interactive authentication flows if a previously-cached token is still available. This is implemented using the following technologies: + - On Windows, the cache will use a DPAPI-protected file. + - On macOS, the cache will use the macOS Keychain. + - On Linux, the cache will use `libsecret` to store the tokens (this will use a provider backend, e.g. GNOME Keyring). + - On Linux and macOS, the cache may optionally use an unencrypted file as a last resort, but only if the `allowUnencryptedStorage` property is set to true in the `tokenCachePersistenceOptions` passed to the credential constructor. diff --git a/sdk/identity/identity-cache-persistence/LICENSE b/sdk/identity/identity-cache-persistence/LICENSE new file mode 100644 index 000000000000..ea8fb1516028 --- /dev/null +++ b/sdk/identity/identity-cache-persistence/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2020 Microsoft + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/sdk/identity/identity-cache-persistence/README.md b/sdk/identity/identity-cache-persistence/README.md new file mode 100644 index 000000000000..ffd728000ef3 --- /dev/null +++ b/sdk/identity/identity-cache-persistence/README.md @@ -0,0 +1,95 @@ +## Azure Identity Extension for Token Cache Persistence + +This package provides an extension to the Azure Identity library for JavaScript ([`@azure/identity`](https://npmjs.com/package/@azure/identity)) that enables persistent token caching. Token cache persistence allows the built-in token cache to persist across sessions using a secure storage system provided by the local Operating System. + +[Source code](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/identity/identity-cache-persistence) | [Samples](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity-cache-persistence/samples-dev) + +## Getting started + +### Install the package + +This package is designed to be used with Azure Identity for JavaScript. Install both `@azure/identity` and this package using `npm`: + +```sh +$ npm install --save @azure/identity +$ npm install --save @azure/identity-cache-persistence +``` + +### Prerequisites + +- An [Azure subscription](https://azure.microsoft.com/free/). + +#### Supported Environments + +Azure Identity extensions for JavaScript support stable (even numbered) versions of Node.js starting from v12. While it may run in other Node versions, no support is guaranteed. `@azure/identity-cache-persistence` **does not** support browser environments. + +## Key concepts + +If this is your first time using `@azure/identity` or the Microsoft identity platform (Azure Active Directory), we recommend that you read [Using `@azure/identity` with Microsoft Identity Platform](https://github.com/Azure/azure-sdk-for-js/blob/main/documentation/using-azure-identity.md) first. This document will give you a deeper understanding of the platform and how to configure your Azure account correctly. + +### Azure Identity Extensions + +As of `@azure/identity` version 2.0.0, the Identity client library for JavaScript includes an extension API. This package (`@azure/identity-cache-persistence`) exports an extension object that you must pass as an argument to the top-level `useIdentityExtension` function from the `@azure/identity` package. Enable token cache persistence in your program as follows: + +```typescript +import { useIdentityExtension } from "@azure/identity"; +import { cachePersistenceExtension } from "@azure/identity-cache-persistence"; + +useIdentityExtension(cachePersistenceExtension); +``` + +After calling `useIdentityExtension`, the persistent token cache extension is registered to the `@azure/identity` package and will be available on all credentials that support persistent token caching (those that have `tokenCachePersistenceOptions` in their constructor options). + +## Examples + +Once the extension is registered, you can enable token cache persistence by passing `tokenCachePersistenceOptions` with an `enabled` property set to `true` to a credential constructor. In the following example, we use the `DeviceCodeCredential`, since persistent caching of its tokens allows you to skip the interactive device-code authentication flow if a cached token is available. + +```typescript +import { useIdentityExtension, DeviceCodeCredential } from "@azure/identity"; +import { cachePersistenceExtension } from "@azure/identity-cache-persistence"; + +useIdentityExtension(cachePersistenceExtension); + +async function main() { + const credential = new DeviceCodeCredential({ + tokenCachePersistenceOptions: { + enabled: true + } + }); + + // We'll use the Microsoft Graph scope as an example + const scope = "https://graph.microsoft.com/.default"; + + // Print out part of the access token + console.log((await credential.getToken(scope)).token.substr(0, 10), "..."); +} + +main().catch((error) => { + console.error("An error occurred:", error); + process.exit(1); +}); +``` + +## Troubleshooting + +### Logging + +Enabling logging may help uncover useful information about failures. In order to see a log of HTTP requests and responses, set the `AZURE_LOG_LEVEL` environment variable to `info`. Alternatively, logging can be enabled at runtime by calling `setLogLevel` in the `@azure/logger`: + +```javascript +import { setLogLevel } from "@azure/logger"; + +setLogLevel("info"); +``` + +## Next steps + +### Provide Feedback + +If you encounter bugs or have suggestions, please [open an issue](https://github.com/Azure/azure-sdk-for-js/issues). + +## Contributing + +If you'd like to contribute to this library, please read the [contributing guide](https://github.com/Azure/azure-sdk-for-js/blob/main/CONTRIBUTING.md) to learn more about how to build and test the code. + +![Impressions](https://azure-sdk-impressions.azurewebsites.net/api/impressions/azure-sdk-for-js%2Fsdk%2Fidentity%2Fidentity%2FREADME.png) diff --git a/sdk/identity/identity-cache-persistence/api-extractor.json b/sdk/identity/identity-cache-persistence/api-extractor.json new file mode 100644 index 000000000000..f7b471ed2265 --- /dev/null +++ b/sdk/identity/identity-cache-persistence/api-extractor.json @@ -0,0 +1,31 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", + "mainEntryPointFilePath": "./types/identity-cache-persistence/src/index.d.ts", + "docModel": { + "enabled": true + }, + "apiReport": { + "enabled": true, + "reportFolder": "./review" + }, + "dtsRollup": { + "enabled": true, + "untrimmedFilePath": "", + "publicTrimmedFilePath": "./types/identity-cache-persistence.d.ts" + }, + "messages": { + "tsdocMessageReporting": { + "default": { + "logLevel": "none" + } + }, + "extractorMessageReporting": { + "ae-missing-release-tag": { + "logLevel": "none" + }, + "ae-unresolved-link": { + "logLevel": "none" + } + } + } +} diff --git a/sdk/identity/identity-cache-persistence/package.json b/sdk/identity/identity-cache-persistence/package.json new file mode 100644 index 000000000000..abaac4be0321 --- /dev/null +++ b/sdk/identity/identity-cache-persistence/package.json @@ -0,0 +1,100 @@ +{ + "name": "@azure/identity-cache-persistence", + "version": "1.0.0-beta.1", + "description": "A secure, persistent token cache for Azure Identity credentials that uses the OS secret-management API", + "main": "dist/index.js", + "module": "dist-esm/identity-cache-persistence/src/index.js", + "types": "./types/identity-cache-persistence.d.ts", + "scripts": { + "audit": "node ../../../common/scripts/rush-audit.js && rimraf node_modules package-lock.json && npm i --package-lock-only 2>&1 && npm audit", + "build:samples": "echo skipped", + "build:test": "tsc -p . && rollup -c rollup.config.js 2>&1", + "build": "npm run extract-api && tsc -p . && rollup -c 2>&1", + "check-format": "prettier --list-different --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\" \"samples-dev/**/*.ts\"", + "clean": "rimraf dist dist-* typings *.tgz *.log", + "execute:samples": "echo skipped", + "extract-api": "tsc -p . && api-extractor run --local", + "format": "prettier --write --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\" \"samples-dev/**/*.ts\"", + "integration-test:browser": "echo skipped", + "integration-test:node": "echo skipped", + "integration-test": "npm run integration-test:node && npm run integration-test:browser", + "lint:fix": "eslint package.json api-extractor.json src test --ext .ts --fix --fix-type [problem,suggestion]", + "lint": "eslint package.json api-extractor.json src test --ext .ts", + "pack": "npm pack 2>&1", + "prebuild": "npm run clean", + "test:browser": "npm run clean && npm run build:test && npm run unit-test:browser && npm run integration-test:browser", + "test:node": "npm run clean && npm run build:test && npm run unit-test:node && npm run integration-test:node", + "test": "npm run clean && npm run build:test && npm run unit-test && npm run integration-test", + "unit-test:browser": "echo skipped", + "unit-test:node": "mocha -r esm -r ts-node/register --reporter ../../../common/tools/mocha-multi-reporter.js --timeout 180000 --full-trace --exclude \"test/**/browser/**/*.spec.ts\" \"test/**/*.spec.ts\"", + "unit-test": "npm run unit-test:node && npm run unit-test:browser", + "docs": "typedoc --excludePrivate --excludeNotExported --excludeExternals --stripInternal --mode file --out ./dist/docs ./src" + }, + "files": [ + "dist/", + "dist-esm/identity/src", + "dist-esm/identity-cache-persistence/src", + "types/identity-cache-persistence.d.ts", + "README.md", + "LICENSE" + ], + "engines": { + "node": ">=12.0.0" + }, + "repository": "github:Azure/azure-sdk-for-js", + "keywords": [ + "azure", + "cloud", + "active directory", + "authentication", + "credential", + "certificate", + "persistence", + "cache" + ], + "author": "Microsoft Corporation", + "license": "MIT", + "bugs": { + "url": "https://github.com/Azure/azure-sdk-for-js/issues" + }, + "engine": { + "node": ">=12.0.0" + }, + "homepage": "https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/identity/identity-cache-persistence/README.md", + "sideEffects": false, + "dependencies": { + "@azure/core-auth": "^1.3.0", + "@azure/identity": "^2.0.0-beta.4", + "@azure/msal-node": "^1.1.0", + "@azure/msal-node-extensions": "1.0.0-alpha.6", + "keytar": "^7.6.0", + "tslib": "^2.2.0" + }, + "devDependencies": { + "@azure/eslint-plugin-azure-sdk": "^3.0.0", + "@azure/dev-tool": "^1.0.0", + "@azure/test-utils-recorder": "^1.0.0", + "@microsoft/api-extractor": "7.7.11", + "@types/jws": "^3.2.2", + "@types/mocha": "^7.0.2", + "@types/node": "^8.0.0", + "@types/qs": "^6.5.3", + "assert": "^1.4.1", + "cross-env": "^7.0.2", + "dotenv": "^8.2.0", + "eslint": "^7.15.0", + "inherits": "^2.0.3", + "mocha": "^7.1.1", + "mocha-junit-reporter": "^1.18.0", + "puppeteer": "^3.3.0", + "rimraf": "^3.0.0", + "rollup": "^1.16.3", + "typescript": "~4.2.0", + "util": "^0.12.1", + "sinon": "^9.0.2", + "@types/sinon": "^9.0.4", + "mock-fs": "^4.10.4", + "typedoc": "0.15.2", + "prettier": "^1.16.4" + } +} diff --git a/sdk/identity/identity-cache-persistence/recordings/node/clientcertificatecredential_internal/recording_accepts_tokencachepersistenceoptions.js b/sdk/identity/identity-cache-persistence/recordings/node/clientcertificatecredential_internal/recording_accepts_tokencachepersistenceoptions.js new file mode 100644 index 000000000000..0011ebc6bd57 --- /dev/null +++ b/sdk/identity/identity-cache-persistence/recordings/node/clientcertificatecredential_internal/recording_accepts_tokencachepersistenceoptions.js @@ -0,0 +1,111 @@ +let nock = require('nock'); + +module.exports.hash = "f2f314ebfb0b21270e281f8cfaa428eb"; + +module.exports.testInfo = {"uniqueName":{},"newDate":{}} + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .get('/common/discovery/instance') + .query(true) + .reply(200, {"tenant_discovery_endpoint":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/v2.0/.well-known/openid-configuration","api-version":"1.1","metadata":[{"preferred_network":"login.microsoftonline.com","preferred_cache":"login.windows.net","aliases":["login.microsoftonline.com","login.windows.net","login.microsoft.com","sts.windows.net"]},{"preferred_network":"login.partner.microsoftonline.cn","preferred_cache":"login.partner.microsoftonline.cn","aliases":["login.partner.microsoftonline.cn","login.chinacloudapi.cn"]},{"preferred_network":"login.microsoftonline.de","preferred_cache":"login.microsoftonline.de","aliases":["login.microsoftonline.de"]},{"preferred_network":"login.microsoftonline.us","preferred_cache":"login.microsoftonline.us","aliases":["login.microsoftonline.us","login.usgovcloudapi.net"]},{"preferred_network":"login-us.microsoftonline.com","preferred_cache":"login-us.microsoftonline.com","aliases":["login-us.microsoftonline.com"]}]}, [ + 'Cache-Control', + 'max-age=86400, private', + 'Content-Type', + 'application/json; charset=utf-8', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'Access-Control-Allow-Origin', + '*', + 'Access-Control-Allow-Methods', + 'GET, OPTIONS', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + 'afae0f31-2449-4ead-bae3-5872d9ac1000', + 'x-ms-ests-server', + '2.1.11787.14 - NCUS ProdSlices', + 'Set-Cookie', + 'fpc=fpc;; expires=Fri, 09-Jul-2021 22:05:37 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'esctx=esctx; domain=.login.microsoftonline.com; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Wed, 09 Jun 2021 22:05:36 GMT', + 'Content-Length', + '980' +]); + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .get('/12345678-1234-1234-1234-123456789012/v2.0/.well-known/openid-configuration') + .reply(200, {"token_endpoint":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/oauth2/v2.0/token","token_endpoint_auth_methods_supported":["client_secret_post","private_key_jwt","client_secret_basic"],"jwks_uri":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/discovery/v2.0/keys","response_modes_supported":["query","fragment","form_post"],"subject_types_supported":["pairwise"],"id_token_signing_alg_values_supported":["RS256"],"response_types_supported":["code","id_token","code id_token","id_token token"],"scopes_supported":["openid","profile","email","offline_access"],"issuer":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/v2.0","request_uri_parameter_supported":false,"userinfo_endpoint":"https://graph.microsoft.com/oidc/userinfo","authorization_endpoint":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/oauth2/v2.0/authorize","device_authorization_endpoint":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/oauth2/v2.0/devicecode","http_logout_supported":true,"frontchannel_logout_supported":true,"end_session_endpoint":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/oauth2/v2.0/logout","claims_supported":["sub","iss","cloud_instance_name","cloud_instance_host_name","cloud_graph_host_name","msgraph_host","aud","exp","iat","auth_time","acr","nonce","preferred_username","name","tid","ver","at_hash","c_hash","email"],"tenant_region_scope":"NA","cloud_instance_name":"microsoftonline.com","cloud_graph_host_name":"graph.windows.net","msgraph_host":"graph.microsoft.com","rbac_url":"https://pas.windows.net"}, [ + 'Cache-Control', + 'max-age=86400, private', + 'Content-Type', + 'application/json; charset=utf-8', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'Access-Control-Allow-Origin', + '*', + 'Access-Control-Allow-Methods', + 'GET, OPTIONS', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + '9b573481-cec3-4a8f-add9-eabeab1c2300', + 'x-ms-ests-server', + '2.1.11787.14 - SCUS ProdSlices', + 'Set-Cookie', + 'fpc=fpc;; expires=Fri, 09-Jul-2021 22:05:37 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'esctx=esctx; domain=.login.microsoftonline.com; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Wed, 09 Jun 2021 22:05:37 GMT', + 'Content-Length', + '1651' +]); + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .post('/12345678-1234-1234-1234-123456789012/oauth2/v2.0/token', "client_id=azure_client_id&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default%20openid%20profile%20offline_access&grant_type=client_credentials&x-client-SKU=msal.js.node&x-client-VER=1.1.0&x-client-OS=linux&x-client-CPU=x64&x-ms-lib-capability=retry-after, h429&x-client-current-telemetry=2|771,0|,&x-client-last-telemetry=2|0|||0,0&client-request-id=client-request-id&client_assertion=client_assertion&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer") + .reply(200, {"token_type":"Bearer","expires_in":3599,"ext_expires_in":3599,"access_token":"access_token"}, [ + 'Cache-Control', + 'no-store, no-cache', + 'Pragma', + 'no-cache', + 'Content-Type', + 'application/json; charset=utf-8', + 'Expires', + '-1', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + '76255ad6-29e6-4527-a4a3-ff6ce6a97600', + 'x-ms-ests-server', + '2.1.11787.14 - WUS2 ProdSlices', + 'x-ms-clitelem', + '1,0,0,,', + 'Set-Cookie', + 'fpc=fpc;; expires=Fri, 09-Jul-2021 22:05:37 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Wed, 09 Jun 2021 22:05:37 GMT', + 'Content-Length', + '1588' +]); diff --git a/sdk/identity/identity-cache-persistence/recordings/node/clientcertificatecredential_internal/recording_authenticates_silently_with_tokencachepersistenceoptions.js b/sdk/identity/identity-cache-persistence/recordings/node/clientcertificatecredential_internal/recording_authenticates_silently_with_tokencachepersistenceoptions.js new file mode 100644 index 000000000000..34219511f44d --- /dev/null +++ b/sdk/identity/identity-cache-persistence/recordings/node/clientcertificatecredential_internal/recording_authenticates_silently_with_tokencachepersistenceoptions.js @@ -0,0 +1,182 @@ +let nock = require('nock'); + +module.exports.hash = "a35165f908e286361502828da4c76736"; + +module.exports.testInfo = {"uniqueName":{},"newDate":{}} + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .get('/common/discovery/instance') + .query(true) + .reply(200, {"tenant_discovery_endpoint":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/v2.0/.well-known/openid-configuration","api-version":"1.1","metadata":[{"preferred_network":"login.microsoftonline.com","preferred_cache":"login.windows.net","aliases":["login.microsoftonline.com","login.windows.net","login.microsoft.com","sts.windows.net"]},{"preferred_network":"login.partner.microsoftonline.cn","preferred_cache":"login.partner.microsoftonline.cn","aliases":["login.partner.microsoftonline.cn","login.chinacloudapi.cn"]},{"preferred_network":"login.microsoftonline.de","preferred_cache":"login.microsoftonline.de","aliases":["login.microsoftonline.de"]},{"preferred_network":"login.microsoftonline.us","preferred_cache":"login.microsoftonline.us","aliases":["login.microsoftonline.us","login.usgovcloudapi.net"]},{"preferred_network":"login-us.microsoftonline.com","preferred_cache":"login-us.microsoftonline.com","aliases":["login-us.microsoftonline.com"]}]}, [ + 'Cache-Control', + 'max-age=86400, private', + 'Content-Type', + 'application/json; charset=utf-8', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'Access-Control-Allow-Origin', + '*', + 'Access-Control-Allow-Methods', + 'GET, OPTIONS', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + '839e3095-5d46-49ec-a3de-bde9f1a40e00', + 'x-ms-ests-server', + '2.1.11787.14 - NCUS ProdSlices', + 'Set-Cookie', + 'fpc=fpc;; expires=Fri, 09-Jul-2021 22:05:37 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'esctx=esctx; domain=.login.microsoftonline.com; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Wed, 09 Jun 2021 22:05:37 GMT', + 'Content-Length', + '980' +]); + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .get('/12345678-1234-1234-1234-123456789012/v2.0/.well-known/openid-configuration') + .reply(200, {"token_endpoint":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/oauth2/v2.0/token","token_endpoint_auth_methods_supported":["client_secret_post","private_key_jwt","client_secret_basic"],"jwks_uri":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/discovery/v2.0/keys","response_modes_supported":["query","fragment","form_post"],"subject_types_supported":["pairwise"],"id_token_signing_alg_values_supported":["RS256"],"response_types_supported":["code","id_token","code id_token","id_token token"],"scopes_supported":["openid","profile","email","offline_access"],"issuer":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/v2.0","request_uri_parameter_supported":false,"userinfo_endpoint":"https://graph.microsoft.com/oidc/userinfo","authorization_endpoint":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/oauth2/v2.0/authorize","device_authorization_endpoint":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/oauth2/v2.0/devicecode","http_logout_supported":true,"frontchannel_logout_supported":true,"end_session_endpoint":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/oauth2/v2.0/logout","claims_supported":["sub","iss","cloud_instance_name","cloud_instance_host_name","cloud_graph_host_name","msgraph_host","aud","exp","iat","auth_time","acr","nonce","preferred_username","name","tid","ver","at_hash","c_hash","email"],"tenant_region_scope":"NA","cloud_instance_name":"microsoftonline.com","cloud_graph_host_name":"graph.windows.net","msgraph_host":"graph.microsoft.com","rbac_url":"https://pas.windows.net"}, [ + 'Cache-Control', + 'max-age=86400, private', + 'Content-Type', + 'application/json; charset=utf-8', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'Access-Control-Allow-Origin', + '*', + 'Access-Control-Allow-Methods', + 'GET, OPTIONS', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + '9e1bae85-2215-44d4-8edc-49f2ba2c1a00', + 'x-ms-ests-server', + '2.1.11787.14 - EUS ProdSlices', + 'Set-Cookie', + 'fpc=fpc;; expires=Fri, 09-Jul-2021 22:05:37 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'esctx=esctx; domain=.login.microsoftonline.com; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Wed, 09 Jun 2021 22:05:37 GMT', + 'Content-Length', + '1651' +]); + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .post('/12345678-1234-1234-1234-123456789012/oauth2/v2.0/token', "client_id=azure_client_id&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default%20openid%20profile%20offline_access&grant_type=client_credentials&x-client-SKU=msal.js.node&x-client-VER=1.1.0&x-client-OS=linux&x-client-CPU=x64&x-ms-lib-capability=retry-after, h429&x-client-current-telemetry=2|771,0|,&x-client-last-telemetry=2|0|||0,0&client-request-id=client-request-id&client_assertion=client_assertion&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer") + .reply(200, {"token_type":"Bearer","expires_in":3599,"ext_expires_in":3599,"access_token":"access_token"}, [ + 'Cache-Control', + 'no-store, no-cache', + 'Pragma', + 'no-cache', + 'Content-Type', + 'application/json; charset=utf-8', + 'Expires', + '-1', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + '409bd16b-3d19-4ecb-993b-15cb6b951800', + 'x-ms-ests-server', + '2.1.11787.14 - NCUS ProdSlices', + 'x-ms-clitelem', + '1,0,0,,', + 'Set-Cookie', + 'fpc=fpc;; expires=Fri, 09-Jul-2021 22:05:38 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Wed, 09 Jun 2021 22:05:37 GMT', + 'Content-Length', + '1588' +]); + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .get('/common/discovery/instance') + .query(true) + .reply(200, {"tenant_discovery_endpoint":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/v2.0/.well-known/openid-configuration","api-version":"1.1","metadata":[{"preferred_network":"login.microsoftonline.com","preferred_cache":"login.windows.net","aliases":["login.microsoftonline.com","login.windows.net","login.microsoft.com","sts.windows.net"]},{"preferred_network":"login.partner.microsoftonline.cn","preferred_cache":"login.partner.microsoftonline.cn","aliases":["login.partner.microsoftonline.cn","login.chinacloudapi.cn"]},{"preferred_network":"login.microsoftonline.de","preferred_cache":"login.microsoftonline.de","aliases":["login.microsoftonline.de"]},{"preferred_network":"login.microsoftonline.us","preferred_cache":"login.microsoftonline.us","aliases":["login.microsoftonline.us","login.usgovcloudapi.net"]},{"preferred_network":"login-us.microsoftonline.com","preferred_cache":"login-us.microsoftonline.com","aliases":["login-us.microsoftonline.com"]}]}, [ + 'Cache-Control', + 'max-age=86400, private', + 'Content-Type', + 'application/json; charset=utf-8', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'Access-Control-Allow-Origin', + '*', + 'Access-Control-Allow-Methods', + 'GET, OPTIONS', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + 'df68a08d-09ef-4790-8194-b5dbacdd6c00', + 'x-ms-ests-server', + '2.1.11787.14 - NCUS ProdSlices', + 'Set-Cookie', + 'fpc=fpc;; expires=Fri, 09-Jul-2021 22:05:38 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'esctx=esctx; domain=.login.microsoftonline.com; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Wed, 09 Jun 2021 22:05:37 GMT', + 'Content-Length', + '980' +]); + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .get('/12345678-1234-1234-1234-123456789012/v2.0/.well-known/openid-configuration') + .reply(200, {"token_endpoint":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/oauth2/v2.0/token","token_endpoint_auth_methods_supported":["client_secret_post","private_key_jwt","client_secret_basic"],"jwks_uri":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/discovery/v2.0/keys","response_modes_supported":["query","fragment","form_post"],"subject_types_supported":["pairwise"],"id_token_signing_alg_values_supported":["RS256"],"response_types_supported":["code","id_token","code id_token","id_token token"],"scopes_supported":["openid","profile","email","offline_access"],"issuer":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/v2.0","request_uri_parameter_supported":false,"userinfo_endpoint":"https://graph.microsoft.com/oidc/userinfo","authorization_endpoint":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/oauth2/v2.0/authorize","device_authorization_endpoint":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/oauth2/v2.0/devicecode","http_logout_supported":true,"frontchannel_logout_supported":true,"end_session_endpoint":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/oauth2/v2.0/logout","claims_supported":["sub","iss","cloud_instance_name","cloud_instance_host_name","cloud_graph_host_name","msgraph_host","aud","exp","iat","auth_time","acr","nonce","preferred_username","name","tid","ver","at_hash","c_hash","email"],"tenant_region_scope":"NA","cloud_instance_name":"microsoftonline.com","cloud_graph_host_name":"graph.windows.net","msgraph_host":"graph.microsoft.com","rbac_url":"https://pas.windows.net"}, [ + 'Cache-Control', + 'max-age=86400, private', + 'Content-Type', + 'application/json; charset=utf-8', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'Access-Control-Allow-Origin', + '*', + 'Access-Control-Allow-Methods', + 'GET, OPTIONS', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + '18fea51e-7f24-414e-9d58-99875bde2500', + 'x-ms-ests-server', + '2.1.11787.14 - SCUS ProdSlices', + 'Set-Cookie', + 'fpc=fpc;; expires=Fri, 09-Jul-2021 22:05:38 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'esctx=esctx; domain=.login.microsoftonline.com; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Wed, 09 Jun 2021 22:05:37 GMT', + 'Content-Length', + '1651' +]); diff --git a/sdk/identity/identity-cache-persistence/recordings/node/clientsecretcredential_internal/recording_accepts_tokencachepersistenceoptions.js b/sdk/identity/identity-cache-persistence/recordings/node/clientsecretcredential_internal/recording_accepts_tokencachepersistenceoptions.js new file mode 100644 index 000000000000..c2a6d0a6f70b --- /dev/null +++ b/sdk/identity/identity-cache-persistence/recordings/node/clientsecretcredential_internal/recording_accepts_tokencachepersistenceoptions.js @@ -0,0 +1,111 @@ +let nock = require('nock'); + +module.exports.hash = "e5b2fd33648fbcb25002eb5d85a3b1b7"; + +module.exports.testInfo = {"uniqueName":{},"newDate":{}} + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .get('/common/discovery/instance') + .query(true) + .reply(200, {"tenant_discovery_endpoint":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/v2.0/.well-known/openid-configuration","api-version":"1.1","metadata":[{"preferred_network":"login.microsoftonline.com","preferred_cache":"login.windows.net","aliases":["login.microsoftonline.com","login.windows.net","login.microsoft.com","sts.windows.net"]},{"preferred_network":"login.partner.microsoftonline.cn","preferred_cache":"login.partner.microsoftonline.cn","aliases":["login.partner.microsoftonline.cn","login.chinacloudapi.cn"]},{"preferred_network":"login.microsoftonline.de","preferred_cache":"login.microsoftonline.de","aliases":["login.microsoftonline.de"]},{"preferred_network":"login.microsoftonline.us","preferred_cache":"login.microsoftonline.us","aliases":["login.microsoftonline.us","login.usgovcloudapi.net"]},{"preferred_network":"login-us.microsoftonline.com","preferred_cache":"login-us.microsoftonline.com","aliases":["login-us.microsoftonline.com"]}]}, [ + 'Cache-Control', + 'max-age=86400, private', + 'Content-Type', + 'application/json; charset=utf-8', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'Access-Control-Allow-Origin', + '*', + 'Access-Control-Allow-Methods', + 'GET, OPTIONS', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + '6ec3837f-1b8d-4b9c-899e-c708c14b9200', + 'x-ms-ests-server', + '2.1.11787.14 - WUS2 ProdSlices', + 'Set-Cookie', + 'fpc=fpc;; expires=Fri, 09-Jul-2021 22:05:38 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'esctx=esctx; domain=.login.microsoftonline.com; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Wed, 09 Jun 2021 22:05:38 GMT', + 'Content-Length', + '980' +]); + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .get('/12345678-1234-1234-1234-123456789012/v2.0/.well-known/openid-configuration') + .reply(200, {"token_endpoint":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/oauth2/v2.0/token","token_endpoint_auth_methods_supported":["client_secret_post","private_key_jwt","client_secret_basic"],"jwks_uri":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/discovery/v2.0/keys","response_modes_supported":["query","fragment","form_post"],"subject_types_supported":["pairwise"],"id_token_signing_alg_values_supported":["RS256"],"response_types_supported":["code","id_token","code id_token","id_token token"],"scopes_supported":["openid","profile","email","offline_access"],"issuer":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/v2.0","request_uri_parameter_supported":false,"userinfo_endpoint":"https://graph.microsoft.com/oidc/userinfo","authorization_endpoint":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/oauth2/v2.0/authorize","device_authorization_endpoint":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/oauth2/v2.0/devicecode","http_logout_supported":true,"frontchannel_logout_supported":true,"end_session_endpoint":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/oauth2/v2.0/logout","claims_supported":["sub","iss","cloud_instance_name","cloud_instance_host_name","cloud_graph_host_name","msgraph_host","aud","exp","iat","auth_time","acr","nonce","preferred_username","name","tid","ver","at_hash","c_hash","email"],"tenant_region_scope":"NA","cloud_instance_name":"microsoftonline.com","cloud_graph_host_name":"graph.windows.net","msgraph_host":"graph.microsoft.com","rbac_url":"https://pas.windows.net"}, [ + 'Cache-Control', + 'max-age=86400, private', + 'Content-Type', + 'application/json; charset=utf-8', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'Access-Control-Allow-Origin', + '*', + 'Access-Control-Allow-Methods', + 'GET, OPTIONS', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + '409bd16b-3d19-4ecb-993b-15cb9b951800', + 'x-ms-ests-server', + '2.1.11787.14 - NCUS ProdSlices', + 'Set-Cookie', + 'fpc=fpc;; expires=Fri, 09-Jul-2021 22:05:38 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'esctx=esctx; domain=.login.microsoftonline.com; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Wed, 09 Jun 2021 22:05:38 GMT', + 'Content-Length', + '1651' +]); + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .post('/12345678-1234-1234-1234-123456789012/oauth2/v2.0/token', "client_id=azure_client_id&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default%20openid%20profile%20offline_access&grant_type=client_credentials&x-client-SKU=msal.js.node&x-client-VER=1.1.0&x-client-OS=linux&x-client-CPU=x64&x-ms-lib-capability=retry-after, h429&x-client-current-telemetry=2|771,0|,&x-client-last-telemetry=2|0|||0,0&client-request-id=client-request-id&client_secret=azure_client_secret") + .reply(200, {"token_type":"Bearer","expires_in":3599,"ext_expires_in":3599,"access_token":"access_token"}, [ + 'Cache-Control', + 'no-store, no-cache', + 'Pragma', + 'no-cache', + 'Content-Length', + '1588', + 'Content-Type', + 'application/json; charset=utf-8', + 'Expires', + '-1', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + 'bd0f0928-051d-4666-8f19-5267ddc31900', + 'x-ms-ests-server', + '2.1.11787.14 - EUS ProdSlices', + 'x-ms-clitelem', + '1,0,0,,', + 'Set-Cookie', + 'fpc=fpc;; expires=Fri, 09-Jul-2021 22:05:38 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Wed, 09 Jun 2021 22:05:38 GMT' +]); diff --git a/sdk/identity/identity-cache-persistence/recordings/node/clientsecretcredential_internal/recording_authenticates_silently_with_tokencachepersistenceoptions.js b/sdk/identity/identity-cache-persistence/recordings/node/clientsecretcredential_internal/recording_authenticates_silently_with_tokencachepersistenceoptions.js new file mode 100644 index 000000000000..dc5389c124fd --- /dev/null +++ b/sdk/identity/identity-cache-persistence/recordings/node/clientsecretcredential_internal/recording_authenticates_silently_with_tokencachepersistenceoptions.js @@ -0,0 +1,182 @@ +let nock = require('nock'); + +module.exports.hash = "efc3f10af9de458ea8671542d0000e3b"; + +module.exports.testInfo = {"uniqueName":{},"newDate":{}} + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .get('/common/discovery/instance') + .query(true) + .reply(200, {"tenant_discovery_endpoint":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/v2.0/.well-known/openid-configuration","api-version":"1.1","metadata":[{"preferred_network":"login.microsoftonline.com","preferred_cache":"login.windows.net","aliases":["login.microsoftonline.com","login.windows.net","login.microsoft.com","sts.windows.net"]},{"preferred_network":"login.partner.microsoftonline.cn","preferred_cache":"login.partner.microsoftonline.cn","aliases":["login.partner.microsoftonline.cn","login.chinacloudapi.cn"]},{"preferred_network":"login.microsoftonline.de","preferred_cache":"login.microsoftonline.de","aliases":["login.microsoftonline.de"]},{"preferred_network":"login.microsoftonline.us","preferred_cache":"login.microsoftonline.us","aliases":["login.microsoftonline.us","login.usgovcloudapi.net"]},{"preferred_network":"login-us.microsoftonline.com","preferred_cache":"login-us.microsoftonline.com","aliases":["login-us.microsoftonline.com"]}]}, [ + 'Cache-Control', + 'max-age=86400, private', + 'Content-Length', + '980', + 'Content-Type', + 'application/json; charset=utf-8', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'Access-Control-Allow-Origin', + '*', + 'Access-Control-Allow-Methods', + 'GET, OPTIONS', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + '2d859df5-c16e-4a19-8c78-d944bed23c00', + 'x-ms-ests-server', + '2.1.11787.14 - WUS2 ProdSlices', + 'Set-Cookie', + 'fpc=fpc;; expires=Fri, 09-Jul-2021 22:05:38 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'esctx=esctx; domain=.login.microsoftonline.com; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Wed, 09 Jun 2021 22:05:38 GMT' +]); + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .get('/12345678-1234-1234-1234-123456789012/v2.0/.well-known/openid-configuration') + .reply(200, {"token_endpoint":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/oauth2/v2.0/token","token_endpoint_auth_methods_supported":["client_secret_post","private_key_jwt","client_secret_basic"],"jwks_uri":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/discovery/v2.0/keys","response_modes_supported":["query","fragment","form_post"],"subject_types_supported":["pairwise"],"id_token_signing_alg_values_supported":["RS256"],"response_types_supported":["code","id_token","code id_token","id_token token"],"scopes_supported":["openid","profile","email","offline_access"],"issuer":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/v2.0","request_uri_parameter_supported":false,"userinfo_endpoint":"https://graph.microsoft.com/oidc/userinfo","authorization_endpoint":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/oauth2/v2.0/authorize","device_authorization_endpoint":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/oauth2/v2.0/devicecode","http_logout_supported":true,"frontchannel_logout_supported":true,"end_session_endpoint":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/oauth2/v2.0/logout","claims_supported":["sub","iss","cloud_instance_name","cloud_instance_host_name","cloud_graph_host_name","msgraph_host","aud","exp","iat","auth_time","acr","nonce","preferred_username","name","tid","ver","at_hash","c_hash","email"],"tenant_region_scope":"NA","cloud_instance_name":"microsoftonline.com","cloud_graph_host_name":"graph.windows.net","msgraph_host":"graph.microsoft.com","rbac_url":"https://pas.windows.net"}, [ + 'Cache-Control', + 'max-age=86400, private', + 'Content-Type', + 'application/json; charset=utf-8', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'Access-Control-Allow-Origin', + '*', + 'Access-Control-Allow-Methods', + 'GET, OPTIONS', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + '76255ad6-29e6-4527-a4a3-ff6c5aaa7600', + 'x-ms-ests-server', + '2.1.11787.14 - WUS2 ProdSlices', + 'Set-Cookie', + 'fpc=fpc;; expires=Fri, 09-Jul-2021 22:05:38 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'esctx=esctx; domain=.login.microsoftonline.com; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Wed, 09 Jun 2021 22:05:38 GMT', + 'Content-Length', + '1651' +]); + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .post('/12345678-1234-1234-1234-123456789012/oauth2/v2.0/token', "client_id=azure_client_id&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default%20openid%20profile%20offline_access&grant_type=client_credentials&x-client-SKU=msal.js.node&x-client-VER=1.1.0&x-client-OS=linux&x-client-CPU=x64&x-ms-lib-capability=retry-after, h429&x-client-current-telemetry=2|771,0|,&x-client-last-telemetry=2|0|||0,0&client-request-id=client-request-id&client_secret=azure_client_secret") + .reply(200, {"token_type":"Bearer","expires_in":3599,"ext_expires_in":3599,"access_token":"access_token"}, [ + 'Cache-Control', + 'no-store, no-cache', + 'Pragma', + 'no-cache', + 'Content-Length', + '1588', + 'Content-Type', + 'application/json; charset=utf-8', + 'Expires', + '-1', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + '9b573481-cec3-4a8f-add9-eabe3a1d2300', + 'x-ms-ests-server', + '2.1.11787.14 - SCUS ProdSlices', + 'x-ms-clitelem', + '1,0,0,,', + 'Set-Cookie', + 'fpc=fpc;; expires=Fri, 09-Jul-2021 22:05:39 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Wed, 09 Jun 2021 22:05:38 GMT' +]); + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .get('/common/discovery/instance') + .query(true) + .reply(200, {"tenant_discovery_endpoint":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/v2.0/.well-known/openid-configuration","api-version":"1.1","metadata":[{"preferred_network":"login.microsoftonline.com","preferred_cache":"login.windows.net","aliases":["login.microsoftonline.com","login.windows.net","login.microsoft.com","sts.windows.net"]},{"preferred_network":"login.partner.microsoftonline.cn","preferred_cache":"login.partner.microsoftonline.cn","aliases":["login.partner.microsoftonline.cn","login.chinacloudapi.cn"]},{"preferred_network":"login.microsoftonline.de","preferred_cache":"login.microsoftonline.de","aliases":["login.microsoftonline.de"]},{"preferred_network":"login.microsoftonline.us","preferred_cache":"login.microsoftonline.us","aliases":["login.microsoftonline.us","login.usgovcloudapi.net"]},{"preferred_network":"login-us.microsoftonline.com","preferred_cache":"login-us.microsoftonline.com","aliases":["login-us.microsoftonline.com"]}]}, [ + 'Cache-Control', + 'max-age=86400, private', + 'Content-Type', + 'application/json; charset=utf-8', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'Access-Control-Allow-Origin', + '*', + 'Access-Control-Allow-Methods', + 'GET, OPTIONS', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + '884b75b2-1b54-49f2-a391-454a07e21400', + 'x-ms-ests-server', + '2.1.11787.14 - NCUS ProdSlices', + 'Set-Cookie', + 'fpc=fpc;; expires=Fri, 09-Jul-2021 22:05:39 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'esctx=esctx; domain=.login.microsoftonline.com; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Wed, 09 Jun 2021 22:05:38 GMT', + 'Content-Length', + '980' +]); + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .get('/12345678-1234-1234-1234-123456789012/v2.0/.well-known/openid-configuration') + .reply(200, {"token_endpoint":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/oauth2/v2.0/token","token_endpoint_auth_methods_supported":["client_secret_post","private_key_jwt","client_secret_basic"],"jwks_uri":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/discovery/v2.0/keys","response_modes_supported":["query","fragment","form_post"],"subject_types_supported":["pairwise"],"id_token_signing_alg_values_supported":["RS256"],"response_types_supported":["code","id_token","code id_token","id_token token"],"scopes_supported":["openid","profile","email","offline_access"],"issuer":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/v2.0","request_uri_parameter_supported":false,"userinfo_endpoint":"https://graph.microsoft.com/oidc/userinfo","authorization_endpoint":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/oauth2/v2.0/authorize","device_authorization_endpoint":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/oauth2/v2.0/devicecode","http_logout_supported":true,"frontchannel_logout_supported":true,"end_session_endpoint":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/oauth2/v2.0/logout","claims_supported":["sub","iss","cloud_instance_name","cloud_instance_host_name","cloud_graph_host_name","msgraph_host","aud","exp","iat","auth_time","acr","nonce","preferred_username","name","tid","ver","at_hash","c_hash","email"],"tenant_region_scope":"NA","cloud_instance_name":"microsoftonline.com","cloud_graph_host_name":"graph.windows.net","msgraph_host":"graph.microsoft.com","rbac_url":"https://pas.windows.net"}, [ + 'Cache-Control', + 'max-age=86400, private', + 'Content-Type', + 'application/json; charset=utf-8', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'Access-Control-Allow-Origin', + '*', + 'Access-Control-Allow-Methods', + 'GET, OPTIONS', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + '9e1bae85-2215-44d4-8edc-49f21d2d1a00', + 'x-ms-ests-server', + '2.1.11787.14 - EUS ProdSlices', + 'Set-Cookie', + 'fpc=fpc;; expires=Fri, 09-Jul-2021 22:05:39 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'esctx=esctx; domain=.login.microsoftonline.com; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Wed, 09 Jun 2021 22:05:38 GMT', + 'Content-Length', + '1651' +]); diff --git a/sdk/identity/identity-cache-persistence/recordings/node/devicecodecredential_internal/recording_accepts_tokencachepersistenceoptions.js b/sdk/identity/identity-cache-persistence/recordings/node/devicecodecredential_internal/recording_accepts_tokencachepersistenceoptions.js new file mode 100644 index 000000000000..20612e770d36 --- /dev/null +++ b/sdk/identity/identity-cache-persistence/recordings/node/devicecodecredential_internal/recording_accepts_tokencachepersistenceoptions.js @@ -0,0 +1,146 @@ +let nock = require('nock'); + +module.exports.hash = "1835013ecdba7993776a10d98850fb5f"; + +module.exports.testInfo = {"uniqueName":{},"newDate":{}} + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .get('/common/discovery/instance') + .query(true) + .reply(200, {"tenant_discovery_endpoint":"https://login.microsoftonline.com/organizations/v2.0/.well-known/openid-configuration","api-version":"1.1","metadata":[{"preferred_network":"login.microsoftonline.com","preferred_cache":"login.windows.net","aliases":["login.microsoftonline.com","login.windows.net","login.microsoft.com","sts.windows.net"]},{"preferred_network":"login.partner.microsoftonline.cn","preferred_cache":"login.partner.microsoftonline.cn","aliases":["login.partner.microsoftonline.cn","login.chinacloudapi.cn"]},{"preferred_network":"login.microsoftonline.de","preferred_cache":"login.microsoftonline.de","aliases":["login.microsoftonline.de"]},{"preferred_network":"login.microsoftonline.us","preferred_cache":"login.microsoftonline.us","aliases":["login.microsoftonline.us","login.usgovcloudapi.net"]},{"preferred_network":"login-us.microsoftonline.com","preferred_cache":"login-us.microsoftonline.com","aliases":["login-us.microsoftonline.com"]}]}, [ + 'Cache-Control', + 'max-age=86400, private', + 'Content-Type', + 'application/json; charset=utf-8', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'Access-Control-Allow-Origin', + '*', + 'Access-Control-Allow-Methods', + 'GET, OPTIONS', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + 'ae17da35-2635-4b07-a094-b0de800c1200', + 'x-ms-ests-server', + '2.1.11787.14 - NCUS ProdSlices', + 'Set-Cookie', + 'fpc=fpc;; expires=Fri, 09-Jul-2021 22:05:39 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'esctx=esctx; domain=.login.microsoftonline.com; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Wed, 09 Jun 2021 22:05:39 GMT', + 'Content-Length', + '957' +]); + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .get('/organizations/v2.0/.well-known/openid-configuration') + .reply(200, {"token_endpoint":"https://login.microsoftonline.com/organizations/oauth2/v2.0/token","token_endpoint_auth_methods_supported":["client_secret_post","private_key_jwt","client_secret_basic"],"jwks_uri":"https://login.microsoftonline.com/organizations/discovery/v2.0/keys","response_modes_supported":["query","fragment","form_post"],"subject_types_supported":["pairwise"],"id_token_signing_alg_values_supported":["RS256"],"response_types_supported":["code","id_token","code id_token","id_token token"],"scopes_supported":["openid","profile","email","offline_access"],"issuer":"https://login.microsoftonline.com/{tenantid}/v2.0","request_uri_parameter_supported":false,"userinfo_endpoint":"https://graph.microsoft.com/oidc/userinfo","authorization_endpoint":"https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize","device_authorization_endpoint":"https://login.microsoftonline.com/organizations/oauth2/v2.0/devicecode","http_logout_supported":true,"frontchannel_logout_supported":true,"end_session_endpoint":"https://login.microsoftonline.com/organizations/oauth2/v2.0/logout","claims_supported":["sub","iss","cloud_instance_name","cloud_instance_host_name","cloud_graph_host_name","msgraph_host","aud","exp","iat","auth_time","acr","nonce","preferred_username","name","tid","ver","at_hash","c_hash","email"],"tenant_region_scope":null,"cloud_instance_name":"microsoftonline.com","cloud_graph_host_name":"graph.windows.net","msgraph_host":"graph.microsoft.com","rbac_url":"https://pas.windows.net"}, [ + 'Cache-Control', + 'max-age=86400, private', + 'Content-Type', + 'application/json; charset=utf-8', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'Access-Control-Allow-Origin', + '*', + 'Access-Control-Allow-Methods', + 'GET, OPTIONS', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + '13bdc6cc-fd34-4d40-a854-12a2ef7c8000', + 'x-ms-ests-server', + '2.1.11787.14 - SCUS ProdSlices', + 'Set-Cookie', + 'fpc=fpc;; expires=Fri, 09-Jul-2021 22:05:39 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'esctx=esctx; domain=.login.microsoftonline.com; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Wed, 09 Jun 2021 22:05:39 GMT', + 'Content-Length', + '1510' +]); + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .post('/organizations/oauth2/v2.0/devicecode', "scope=https%3A%2F%2Fgraph.microsoft.com%2F.default%20openid%20profile%20offline_access&client_id=04b07795-8ddb-461a-bbee-02f9e1bf7b46") + .reply(200, {"user_code":"USER_CODE","device_code":"DEVICE_CODE","verification_uri":"https://microsoft.com/devicelogin","expires_in":900,"interval": 0,"message":"To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code USER_CODE to authenticate."}, [ + 'Cache-Control', + 'no-store, no-cache', + 'Pragma', + 'no-cache', + 'Content-Length', + '473', + 'Content-Type', + 'application/json; charset=utf-8', + 'Expires', + '-1', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + '700be316-e865-4268-95dd-d742ba380200', + 'x-ms-ests-server', + '2.1.11787.15 - SCUS ProdSlices', + 'Set-Cookie', + 'fpc=fpc;; expires=Fri, 09-Jul-2021 22:05:39 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'esctx=esctx; domain=.login.microsoftonline.com; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Wed, 09 Jun 2021 22:05:39 GMT' +]); + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .post('/organizations/oauth2/v2.0/token', "scope=https%3A%2F%2Fgraph.microsoft.com%2F.default%20openid%20profile%20offline_access&client_id=04b07795-8ddb-461a-bbee-02f9e1bf7b46&grant_type=device_code&device_code=DEVICE_CODE&client-request-id=client-request-id&client_info=1&x-client-SKU=msal.js.node&x-client-VER=1.1.0&x-client-OS=linux&x-client-CPU=x64&x-ms-lib-capability=retry-after, h429&x-client-current-telemetry=2|671,0|,&x-client-last-telemetry=2|0|||0,0") + .reply(200, {"token_type":"Bearer","scope":"email openid profile https://graph.microsoft.com/AuditLog.Read.All https://graph.microsoft.com/Directory.AccessAsUser.All https://graph.microsoft.com/Group.ReadWrite.All https://graph.microsoft.com/User.ReadWrite.All https://graph.microsoft.com/.default","expires_in":3599,"ext_expires_in":3599,"access_token":"access_token","refresh_token":"refresh_token","foci":"1","id_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6ImtpZCJ9.eyJhdWQiOiJhdWQiLCJpc3MiOiJodHRwczovL2xvZ2luLm1pY3Jvc29mdG9ubGluZS5jb20vMTIzNDU2NzgtMTIzNC0xMjM0LTEyMzQtMTIzNDU2Nzg5MDEyL3YyLjAiLCJpYXQiOjE2MTUzMzcxNjMsIm5iZiI6MTYxNTMzNzE2MywiZXhwIjoxNjE1MzQxMDYzLCJhaW8iOiJhaW8iLCJpZHAiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC9pZHAvIiwibmFtZSI6IkRhbmllbCBSb2Ryw61ndWV6Iiwib2lkIjoib2lkIiwicHJlZmVycmVkX3VzZXJuYW1lIjoiZGFucm9kcmlAbWljcm9zb2Z0LmNvbSIsInJoIjoicmguIiwic3ViIjoic3ViIiwidGlkIjoiMTIzNDU2NzgtMTIzNC0xMjM0LTEyMzQtMTIzNDU2Nzg5MDEyIiwidXRpIjoidXRpIiwidmVyIjoiMi4wIn0=.bm9faWRlYV93aGF0c190aGlz","client_info":"eyJ1aWQiOiIxMjM0NTY3OC0xMjM0LTEyMzQtMTIzNC0xMjM0NTY3ODkwMTIiLCJ1dGlkIjoiMTIzNDU2NzgtMTIzNC0xMjM0LTEyMzQtMTIzNDU2Nzg5MDEyIn0K"}, [ + 'Cache-Control', + 'no-store, no-cache', + 'Pragma', + 'no-cache', + 'Content-Type', + 'application/json; charset=utf-8', + 'Expires', + '-1', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + '409bd16b-3d19-4ecb-993b-15cbe49a1800', + 'x-ms-ests-server', + '2.1.11787.14 - NCUS ProdSlices', + 'x-ms-clitelem', + '1,0,0,,', + 'Set-Cookie', + 'fpc=fpc;; expires=Fri, 09-Jul-2021 22:05:54 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Wed, 09 Jun 2021 22:05:54 GMT', + 'Content-Length', + '5043' +]); diff --git a/sdk/identity/identity-cache-persistence/recordings/node/devicecodecredential_internal/recording_allows_passing_an_authenticationrecord_to_avoid_further_manual_authentications.js b/sdk/identity/identity-cache-persistence/recordings/node/devicecodecredential_internal/recording_allows_passing_an_authenticationrecord_to_avoid_further_manual_authentications.js new file mode 100644 index 000000000000..efbb014a72e9 --- /dev/null +++ b/sdk/identity/identity-cache-persistence/recordings/node/devicecodecredential_internal/recording_allows_passing_an_authenticationrecord_to_avoid_further_manual_authentications.js @@ -0,0 +1,287 @@ +let nock = require('nock'); + +module.exports.hash = "9b2722ac6356324e61d860b570724ee6"; + +module.exports.testInfo = {"uniqueName":{},"newDate":{}} + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .get('/common/discovery/instance') + .query(true) + .reply(200, {"tenant_discovery_endpoint":"https://login.microsoftonline.com/organizations/v2.0/.well-known/openid-configuration","api-version":"1.1","metadata":[{"preferred_network":"login.microsoftonline.com","preferred_cache":"login.windows.net","aliases":["login.microsoftonline.com","login.windows.net","login.microsoft.com","sts.windows.net"]},{"preferred_network":"login.partner.microsoftonline.cn","preferred_cache":"login.partner.microsoftonline.cn","aliases":["login.partner.microsoftonline.cn","login.chinacloudapi.cn"]},{"preferred_network":"login.microsoftonline.de","preferred_cache":"login.microsoftonline.de","aliases":["login.microsoftonline.de"]},{"preferred_network":"login.microsoftonline.us","preferred_cache":"login.microsoftonline.us","aliases":["login.microsoftonline.us","login.usgovcloudapi.net"]},{"preferred_network":"login-us.microsoftonline.com","preferred_cache":"login-us.microsoftonline.com","aliases":["login-us.microsoftonline.com"]}]}, [ + 'Cache-Control', + 'max-age=86400, private', + 'Content-Type', + 'application/json; charset=utf-8', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'Access-Control-Allow-Origin', + '*', + 'Access-Control-Allow-Methods', + 'GET, OPTIONS', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + '1862a810-e5a7-40ee-a59a-5a4f1abb2400', + 'x-ms-ests-server', + '2.1.11787.14 - EUS ProdSlices', + 'Set-Cookie', + 'fpc=fpc;; expires=Fri, 09-Jul-2021 22:06:10 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'esctx=esctx; domain=.login.microsoftonline.com; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Wed, 09 Jun 2021 22:06:10 GMT', + 'Content-Length', + '957' +]); + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .get('/organizations/v2.0/.well-known/openid-configuration') + .reply(200, {"token_endpoint":"https://login.microsoftonline.com/organizations/oauth2/v2.0/token","token_endpoint_auth_methods_supported":["client_secret_post","private_key_jwt","client_secret_basic"],"jwks_uri":"https://login.microsoftonline.com/organizations/discovery/v2.0/keys","response_modes_supported":["query","fragment","form_post"],"subject_types_supported":["pairwise"],"id_token_signing_alg_values_supported":["RS256"],"response_types_supported":["code","id_token","code id_token","id_token token"],"scopes_supported":["openid","profile","email","offline_access"],"issuer":"https://login.microsoftonline.com/{tenantid}/v2.0","request_uri_parameter_supported":false,"userinfo_endpoint":"https://graph.microsoft.com/oidc/userinfo","authorization_endpoint":"https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize","device_authorization_endpoint":"https://login.microsoftonline.com/organizations/oauth2/v2.0/devicecode","http_logout_supported":true,"frontchannel_logout_supported":true,"end_session_endpoint":"https://login.microsoftonline.com/organizations/oauth2/v2.0/logout","claims_supported":["sub","iss","cloud_instance_name","cloud_instance_host_name","cloud_graph_host_name","msgraph_host","aud","exp","iat","auth_time","acr","nonce","preferred_username","name","tid","ver","at_hash","c_hash","email"],"tenant_region_scope":null,"cloud_instance_name":"microsoftonline.com","cloud_graph_host_name":"graph.windows.net","msgraph_host":"graph.microsoft.com","rbac_url":"https://pas.windows.net"}, [ + 'Cache-Control', + 'max-age=86400, private', + 'Content-Type', + 'application/json; charset=utf-8', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'Access-Control-Allow-Origin', + '*', + 'Access-Control-Allow-Methods', + 'GET, OPTIONS', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + '73d7c60d-e6d5-4b21-ae5d-7961dd751700', + 'x-ms-ests-server', + '2.1.11787.14 - NCUS ProdSlices', + 'Set-Cookie', + 'fpc=fpc;; expires=Fri, 09-Jul-2021 22:06:10 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'esctx=esctx; domain=.login.microsoftonline.com; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Wed, 09 Jun 2021 22:06:10 GMT', + 'Content-Length', + '1510' +]); + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .post('/organizations/oauth2/v2.0/devicecode', "scope=https%3A%2F%2Fgraph.microsoft.com%2F.default%20openid%20profile%20offline_access&client_id=04b07795-8ddb-461a-bbee-02f9e1bf7b46") + .reply(200, {"user_code":"USER_CODE","device_code":"DEVICE_CODE","verification_uri":"https://microsoft.com/devicelogin","expires_in":900,"interval": 0,"message":"To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code USER_CODE to authenticate."}, [ + 'Cache-Control', + 'no-store, no-cache', + 'Pragma', + 'no-cache', + 'Content-Type', + 'application/json; charset=utf-8', + 'Expires', + '-1', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + '1a3165b3-78ec-42a2-95fe-ff3930e97000', + 'x-ms-ests-server', + '2.1.11787.14 - NCUS ProdSlices', + 'Set-Cookie', + 'fpc=fpc;; expires=Fri, 09-Jul-2021 22:06:11 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'esctx=esctx; domain=.login.microsoftonline.com; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Wed, 09 Jun 2021 22:06:10 GMT', + 'Content-Length', + '473' +]); + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .post('/organizations/oauth2/v2.0/token', "scope=https%3A%2F%2Fgraph.microsoft.com%2F.default%20openid%20profile%20offline_access&client_id=04b07795-8ddb-461a-bbee-02f9e1bf7b46&grant_type=device_code&device_code=DEVICE_CODE&client-request-id=client-request-id&client_info=1&x-client-SKU=msal.js.node&x-client-VER=1.1.0&x-client-OS=linux&x-client-CPU=x64&x-ms-lib-capability=retry-after, h429&x-client-current-telemetry=2|671,0|,&x-client-last-telemetry=2|0|||0,0") + .reply(200, {"token_type":"Bearer","scope":"email openid profile https://graph.microsoft.com/AuditLog.Read.All https://graph.microsoft.com/Directory.AccessAsUser.All https://graph.microsoft.com/Group.ReadWrite.All https://graph.microsoft.com/User.ReadWrite.All https://graph.microsoft.com/.default","expires_in":3599,"ext_expires_in":3599,"access_token":"access_token","refresh_token":"refresh_token","foci":"1","id_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6ImtpZCJ9.eyJhdWQiOiJhdWQiLCJpc3MiOiJodHRwczovL2xvZ2luLm1pY3Jvc29mdG9ubGluZS5jb20vMTIzNDU2NzgtMTIzNC0xMjM0LTEyMzQtMTIzNDU2Nzg5MDEyL3YyLjAiLCJpYXQiOjE2MTUzMzcxNjMsIm5iZiI6MTYxNTMzNzE2MywiZXhwIjoxNjE1MzQxMDYzLCJhaW8iOiJhaW8iLCJpZHAiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC9pZHAvIiwibmFtZSI6IkRhbmllbCBSb2Ryw61ndWV6Iiwib2lkIjoib2lkIiwicHJlZmVycmVkX3VzZXJuYW1lIjoiZGFucm9kcmlAbWljcm9zb2Z0LmNvbSIsInJoIjoicmguIiwic3ViIjoic3ViIiwidGlkIjoiMTIzNDU2NzgtMTIzNC0xMjM0LTEyMzQtMTIzNDU2Nzg5MDEyIiwidXRpIjoidXRpIiwidmVyIjoiMi4wIn0=.bm9faWRlYV93aGF0c190aGlz","client_info":"eyJ1aWQiOiIxMjM0NTY3OC0xMjM0LTEyMzQtMTIzNC0xMjM0NTY3ODkwMTIiLCJ1dGlkIjoiMTIzNDU2NzgtMTIzNC0xMjM0LTEyMzQtMTIzNDU2Nzg5MDEyIn0K"}, [ + 'Cache-Control', + 'no-store, no-cache', + 'Pragma', + 'no-cache', + 'Content-Type', + 'application/json; charset=utf-8', + 'Expires', + '-1', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + 'bd0f0928-051d-4666-8f19-52673ccf1900', + 'x-ms-ests-server', + '2.1.11787.14 - EUS ProdSlices', + 'x-ms-clitelem', + '1,0,0,,', + 'Set-Cookie', + 'fpc=fpc;; expires=Fri, 09-Jul-2021 22:06:21 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Wed, 09 Jun 2021 22:06:21 GMT', + 'Content-Length', + '5038' +]); + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .get('/common/discovery/instance') + .query(true) + .reply(200, {"tenant_discovery_endpoint":"https://login.microsoftonline.com/organizations/v2.0/.well-known/openid-configuration","api-version":"1.1","metadata":[{"preferred_network":"login.microsoftonline.com","preferred_cache":"login.windows.net","aliases":["login.microsoftonline.com","login.windows.net","login.microsoft.com","sts.windows.net"]},{"preferred_network":"login.partner.microsoftonline.cn","preferred_cache":"login.partner.microsoftonline.cn","aliases":["login.partner.microsoftonline.cn","login.chinacloudapi.cn"]},{"preferred_network":"login.microsoftonline.de","preferred_cache":"login.microsoftonline.de","aliases":["login.microsoftonline.de"]},{"preferred_network":"login.microsoftonline.us","preferred_cache":"login.microsoftonline.us","aliases":["login.microsoftonline.us","login.usgovcloudapi.net"]},{"preferred_network":"login-us.microsoftonline.com","preferred_cache":"login-us.microsoftonline.com","aliases":["login-us.microsoftonline.com"]}]}, [ + 'Cache-Control', + 'max-age=86400, private', + 'Content-Type', + 'application/json; charset=utf-8', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'Access-Control-Allow-Origin', + '*', + 'Access-Control-Allow-Methods', + 'GET, OPTIONS', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + 'cb7b6143-2d08-4775-81b7-fd8aa6979800', + 'x-ms-ests-server', + '2.1.11787.14 - SCUS ProdSlices', + 'Set-Cookie', + 'fpc=fpc;; expires=Fri, 09-Jul-2021 22:06:22 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'esctx=esctx; domain=.login.microsoftonline.com; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Wed, 09 Jun 2021 22:06:21 GMT', + 'Content-Length', + '957' +]); + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .get('/organizations/v2.0/.well-known/openid-configuration') + .reply(200, {"token_endpoint":"https://login.microsoftonline.com/organizations/oauth2/v2.0/token","token_endpoint_auth_methods_supported":["client_secret_post","private_key_jwt","client_secret_basic"],"jwks_uri":"https://login.microsoftonline.com/organizations/discovery/v2.0/keys","response_modes_supported":["query","fragment","form_post"],"subject_types_supported":["pairwise"],"id_token_signing_alg_values_supported":["RS256"],"response_types_supported":["code","id_token","code id_token","id_token token"],"scopes_supported":["openid","profile","email","offline_access"],"issuer":"https://login.microsoftonline.com/{tenantid}/v2.0","request_uri_parameter_supported":false,"userinfo_endpoint":"https://graph.microsoft.com/oidc/userinfo","authorization_endpoint":"https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize","device_authorization_endpoint":"https://login.microsoftonline.com/organizations/oauth2/v2.0/devicecode","http_logout_supported":true,"frontchannel_logout_supported":true,"end_session_endpoint":"https://login.microsoftonline.com/organizations/oauth2/v2.0/logout","claims_supported":["sub","iss","cloud_instance_name","cloud_instance_host_name","cloud_graph_host_name","msgraph_host","aud","exp","iat","auth_time","acr","nonce","preferred_username","name","tid","ver","at_hash","c_hash","email"],"tenant_region_scope":null,"cloud_instance_name":"microsoftonline.com","cloud_graph_host_name":"graph.windows.net","msgraph_host":"graph.microsoft.com","rbac_url":"https://pas.windows.net"}, [ + 'Cache-Control', + 'max-age=86400, private', + 'Content-Type', + 'application/json; charset=utf-8', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'Access-Control-Allow-Origin', + '*', + 'Access-Control-Allow-Methods', + 'GET, OPTIONS', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + 'a03f3270-b884-43e5-9ac1-f8e494da1e00', + 'x-ms-ests-server', + '2.1.11787.14 - NCUS ProdSlices', + 'Set-Cookie', + 'fpc=fpc;; expires=Fri, 09-Jul-2021 22:06:22 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'esctx=esctx; domain=.login.microsoftonline.com; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Wed, 09 Jun 2021 22:06:21 GMT', + 'Content-Length', + '1510' +]); + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .post('/organizations/oauth2/v2.0/devicecode', "scope=https%3A%2F%2Fgraph.microsoft.com%2F.default%20openid%20profile%20offline_access&client_id=04b07795-8ddb-461a-bbee-02f9e1bf7b46") + .reply(200, {"user_code":"USER_CODE","device_code":"DEVICE_CODE","verification_uri":"https://microsoft.com/devicelogin","expires_in":900,"interval": 0,"message":"To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code USER_CODE to authenticate."}, [ + 'Cache-Control', + 'no-store, no-cache', + 'Pragma', + 'no-cache', + 'Content-Type', + 'application/json; charset=utf-8', + 'Expires', + '-1', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + 'fa8fbb31-7fa8-4dc8-b47c-a23004171d00', + 'x-ms-ests-server', + '2.1.11787.14 - SCUS ProdSlices', + 'Set-Cookie', + 'fpc=fpc;; expires=Fri, 09-Jul-2021 22:06:22 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'esctx=esctx; domain=.login.microsoftonline.com; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Wed, 09 Jun 2021 22:06:21 GMT', + 'Content-Length', + '473' +]); + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .post('/organizations/oauth2/v2.0/token', "scope=https%3A%2F%2Fgraph.microsoft.com%2F.default%20openid%20profile%20offline_access&client_id=04b07795-8ddb-461a-bbee-02f9e1bf7b46&grant_type=device_code&device_code=DEVICE_CODE&client-request-id=client-request-id&client_info=1&x-client-SKU=msal.js.node&x-client-VER=1.1.0&x-client-OS=linux&x-client-CPU=x64&x-ms-lib-capability=retry-after, h429&x-client-current-telemetry=2|671,0|,&x-client-last-telemetry=2|0|||0,0") + .reply(200, {"token_type":"Bearer","scope":"email openid profile https://graph.microsoft.com/AuditLog.Read.All https://graph.microsoft.com/Directory.AccessAsUser.All https://graph.microsoft.com/Group.ReadWrite.All https://graph.microsoft.com/User.ReadWrite.All https://graph.microsoft.com/.default","expires_in":3599,"ext_expires_in":3599,"access_token":"access_token","refresh_token":"refresh_token","foci":"1","id_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6ImtpZCJ9.eyJhdWQiOiJhdWQiLCJpc3MiOiJodHRwczovL2xvZ2luLm1pY3Jvc29mdG9ubGluZS5jb20vMTIzNDU2NzgtMTIzNC0xMjM0LTEyMzQtMTIzNDU2Nzg5MDEyL3YyLjAiLCJpYXQiOjE2MTUzMzcxNjMsIm5iZiI6MTYxNTMzNzE2MywiZXhwIjoxNjE1MzQxMDYzLCJhaW8iOiJhaW8iLCJpZHAiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC9pZHAvIiwibmFtZSI6IkRhbmllbCBSb2Ryw61ndWV6Iiwib2lkIjoib2lkIiwicHJlZmVycmVkX3VzZXJuYW1lIjoiZGFucm9kcmlAbWljcm9zb2Z0LmNvbSIsInJoIjoicmguIiwic3ViIjoic3ViIiwidGlkIjoiMTIzNDU2NzgtMTIzNC0xMjM0LTEyMzQtMTIzNDU2Nzg5MDEyIiwidXRpIjoidXRpIiwidmVyIjoiMi4wIn0=.bm9faWRlYV93aGF0c190aGlz","client_info":"eyJ1aWQiOiIxMjM0NTY3OC0xMjM0LTEyMzQtMTIzNC0xMjM0NTY3ODkwMTIiLCJ1dGlkIjoiMTIzNDU2NzgtMTIzNC0xMjM0LTEyMzQtMTIzNDU2Nzg5MDEyIn0K"}, [ + 'Cache-Control', + 'no-store, no-cache', + 'Pragma', + 'no-cache', + 'Content-Type', + 'application/json; charset=utf-8', + 'Expires', + '-1', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + '76255ad6-29e6-4527-a4a3-ff6c7dbf7600', + 'x-ms-ests-server', + '2.1.11787.14 - WUS2 ProdSlices', + 'x-ms-clitelem', + '1,0,0,,', + 'Set-Cookie', + 'fpc=fpc;; expires=Fri, 09-Jul-2021 22:06:47 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Wed, 09 Jun 2021 22:06:47 GMT', + 'Content-Length', + '5038' +]); diff --git a/sdk/identity/identity-cache-persistence/recordings/node/devicecodecredential_internal/recording_authenticates_silently_with_tokencachepersistenceoptions.js b/sdk/identity/identity-cache-persistence/recordings/node/devicecodecredential_internal/recording_authenticates_silently_with_tokencachepersistenceoptions.js new file mode 100644 index 000000000000..616d46331ca6 --- /dev/null +++ b/sdk/identity/identity-cache-persistence/recordings/node/devicecodecredential_internal/recording_authenticates_silently_with_tokencachepersistenceoptions.js @@ -0,0 +1,146 @@ +let nock = require('nock'); + +module.exports.hash = "aeb016d49a5430c8099b373e080e5151"; + +module.exports.testInfo = {"uniqueName":{},"newDate":{}} + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .get('/common/discovery/instance') + .query(true) + .reply(200, {"tenant_discovery_endpoint":"https://login.microsoftonline.com/organizations/v2.0/.well-known/openid-configuration","api-version":"1.1","metadata":[{"preferred_network":"login.microsoftonline.com","preferred_cache":"login.windows.net","aliases":["login.microsoftonline.com","login.windows.net","login.microsoft.com","sts.windows.net"]},{"preferred_network":"login.partner.microsoftonline.cn","preferred_cache":"login.partner.microsoftonline.cn","aliases":["login.partner.microsoftonline.cn","login.chinacloudapi.cn"]},{"preferred_network":"login.microsoftonline.de","preferred_cache":"login.microsoftonline.de","aliases":["login.microsoftonline.de"]},{"preferred_network":"login.microsoftonline.us","preferred_cache":"login.microsoftonline.us","aliases":["login.microsoftonline.us","login.usgovcloudapi.net"]},{"preferred_network":"login-us.microsoftonline.com","preferred_cache":"login-us.microsoftonline.com","aliases":["login-us.microsoftonline.com"]}]}, [ + 'Cache-Control', + 'max-age=86400, private', + 'Content-Type', + 'application/json; charset=utf-8', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'Access-Control-Allow-Origin', + '*', + 'Access-Control-Allow-Methods', + 'GET, OPTIONS', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + 'aae5811f-fa30-46fd-ad7c-d5462ccf3700', + 'x-ms-ests-server', + '2.1.11787.14 - WUS2 ProdSlices', + 'Set-Cookie', + 'fpc=fpc;; expires=Fri, 09-Jul-2021 22:05:55 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'esctx=esctx; domain=.login.microsoftonline.com; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Wed, 09 Jun 2021 22:05:54 GMT', + 'Content-Length', + '957' +]); + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .get('/organizations/v2.0/.well-known/openid-configuration') + .reply(200, {"token_endpoint":"https://login.microsoftonline.com/organizations/oauth2/v2.0/token","token_endpoint_auth_methods_supported":["client_secret_post","private_key_jwt","client_secret_basic"],"jwks_uri":"https://login.microsoftonline.com/organizations/discovery/v2.0/keys","response_modes_supported":["query","fragment","form_post"],"subject_types_supported":["pairwise"],"id_token_signing_alg_values_supported":["RS256"],"response_types_supported":["code","id_token","code id_token","id_token token"],"scopes_supported":["openid","profile","email","offline_access"],"issuer":"https://login.microsoftonline.com/{tenantid}/v2.0","request_uri_parameter_supported":false,"userinfo_endpoint":"https://graph.microsoft.com/oidc/userinfo","authorization_endpoint":"https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize","device_authorization_endpoint":"https://login.microsoftonline.com/organizations/oauth2/v2.0/devicecode","http_logout_supported":true,"frontchannel_logout_supported":true,"end_session_endpoint":"https://login.microsoftonline.com/organizations/oauth2/v2.0/logout","claims_supported":["sub","iss","cloud_instance_name","cloud_instance_host_name","cloud_graph_host_name","msgraph_host","aud","exp","iat","auth_time","acr","nonce","preferred_username","name","tid","ver","at_hash","c_hash","email"],"tenant_region_scope":null,"cloud_instance_name":"microsoftonline.com","cloud_graph_host_name":"graph.windows.net","msgraph_host":"graph.microsoft.com","rbac_url":"https://pas.windows.net"}, [ + 'Cache-Control', + 'max-age=86400, private', + 'Content-Type', + 'application/json; charset=utf-8', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'Access-Control-Allow-Origin', + '*', + 'Access-Control-Allow-Methods', + 'GET, OPTIONS', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + 'de6f2ed2-0294-42be-b8e8-334a8f181000', + 'x-ms-ests-server', + '2.1.11787.14 - EUS ProdSlices', + 'Set-Cookie', + 'fpc=fpc;; expires=Fri, 09-Jul-2021 22:05:55 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'esctx=esctx; domain=.login.microsoftonline.com; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Wed, 09 Jun 2021 22:05:54 GMT', + 'Content-Length', + '1510' +]); + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .post('/organizations/oauth2/v2.0/devicecode', "scope=https%3A%2F%2Fgraph.microsoft.com%2F.default%20openid%20profile%20offline_access&client_id=04b07795-8ddb-461a-bbee-02f9e1bf7b46") + .reply(200, {"user_code":"USER_CODE","device_code":"DEVICE_CODE","verification_uri":"https://microsoft.com/devicelogin","expires_in":900,"interval": 0,"message":"To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code USER_CODE to authenticate."}, [ + 'Cache-Control', + 'no-store, no-cache', + 'Pragma', + 'no-cache', + 'Content-Type', + 'application/json; charset=utf-8', + 'Expires', + '-1', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + '3cc42f87-f9a4-4066-a5e2-f4c107629700', + 'x-ms-ests-server', + '2.1.11787.14 - SCUS ProdSlices', + 'Set-Cookie', + 'fpc=fpc;; expires=Fri, 09-Jul-2021 22:05:55 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'esctx=esctx; domain=.login.microsoftonline.com; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Wed, 09 Jun 2021 22:05:54 GMT', + 'Content-Length', + '473' +]); + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .post('/organizations/oauth2/v2.0/token', "scope=https%3A%2F%2Fgraph.microsoft.com%2F.default%20openid%20profile%20offline_access&client_id=04b07795-8ddb-461a-bbee-02f9e1bf7b46&grant_type=device_code&device_code=DEVICE_CODE&client-request-id=client-request-id&client_info=1&x-client-SKU=msal.js.node&x-client-VER=1.1.0&x-client-OS=linux&x-client-CPU=x64&x-ms-lib-capability=retry-after, h429&x-client-current-telemetry=2|671,0|,&x-client-last-telemetry=2|0|||0,0") + .reply(200, {"token_type":"Bearer","scope":"email openid profile https://graph.microsoft.com/AuditLog.Read.All https://graph.microsoft.com/Directory.AccessAsUser.All https://graph.microsoft.com/Group.ReadWrite.All https://graph.microsoft.com/User.ReadWrite.All https://graph.microsoft.com/.default","expires_in":3599,"ext_expires_in":3599,"access_token":"access_token","refresh_token":"refresh_token","foci":"1","id_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6ImtpZCJ9.eyJhdWQiOiJhdWQiLCJpc3MiOiJodHRwczovL2xvZ2luLm1pY3Jvc29mdG9ubGluZS5jb20vMTIzNDU2NzgtMTIzNC0xMjM0LTEyMzQtMTIzNDU2Nzg5MDEyL3YyLjAiLCJpYXQiOjE2MTUzMzcxNjMsIm5iZiI6MTYxNTMzNzE2MywiZXhwIjoxNjE1MzQxMDYzLCJhaW8iOiJhaW8iLCJpZHAiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC9pZHAvIiwibmFtZSI6IkRhbmllbCBSb2Ryw61ndWV6Iiwib2lkIjoib2lkIiwicHJlZmVycmVkX3VzZXJuYW1lIjoiZGFucm9kcmlAbWljcm9zb2Z0LmNvbSIsInJoIjoicmguIiwic3ViIjoic3ViIiwidGlkIjoiMTIzNDU2NzgtMTIzNC0xMjM0LTEyMzQtMTIzNDU2Nzg5MDEyIiwidXRpIjoidXRpIiwidmVyIjoiMi4wIn0=.bm9faWRlYV93aGF0c190aGlz","client_info":"eyJ1aWQiOiIxMjM0NTY3OC0xMjM0LTEyMzQtMTIzNC0xMjM0NTY3ODkwMTIiLCJ1dGlkIjoiMTIzNDU2NzgtMTIzNC0xMjM0LTEyMzQtMTIzNDU2Nzg5MDEyIn0K"}, [ + 'Cache-Control', + 'no-store, no-cache', + 'Pragma', + 'no-cache', + 'Content-Type', + 'application/json; charset=utf-8', + 'Expires', + '-1', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + '9b573481-cec3-4a8f-add9-eabecc262300', + 'x-ms-ests-server', + '2.1.11787.14 - SCUS ProdSlices', + 'x-ms-clitelem', + '1,0,0,,', + 'Set-Cookie', + 'fpc=fpc;; expires=Fri, 09-Jul-2021 22:06:10 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Wed, 09 Jun 2021 22:06:10 GMT', + 'Content-Length', + '5043' +]); diff --git a/sdk/identity/identity-cache-persistence/recordings/node/usernamepasswordcredential_internal/recording_accepts_tokencachepersistenceoptions.js b/sdk/identity/identity-cache-persistence/recordings/node/usernamepasswordcredential_internal/recording_accepts_tokencachepersistenceoptions.js new file mode 100644 index 000000000000..e5ebaf7786de --- /dev/null +++ b/sdk/identity/identity-cache-persistence/recordings/node/usernamepasswordcredential_internal/recording_accepts_tokencachepersistenceoptions.js @@ -0,0 +1,111 @@ +let nock = require('nock'); + +module.exports.hash = "7990c61bae7d74517e9b9878ee29fdfe"; + +module.exports.testInfo = {"uniqueName":{},"newDate":{}} + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .get('/common/discovery/instance') + .query(true) + .reply(200, {"tenant_discovery_endpoint":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/v2.0/.well-known/openid-configuration","api-version":"1.1","metadata":[{"preferred_network":"login.microsoftonline.com","preferred_cache":"login.windows.net","aliases":["login.microsoftonline.com","login.windows.net","login.microsoft.com","sts.windows.net"]},{"preferred_network":"login.partner.microsoftonline.cn","preferred_cache":"login.partner.microsoftonline.cn","aliases":["login.partner.microsoftonline.cn","login.chinacloudapi.cn"]},{"preferred_network":"login.microsoftonline.de","preferred_cache":"login.microsoftonline.de","aliases":["login.microsoftonline.de"]},{"preferred_network":"login.microsoftonline.us","preferred_cache":"login.microsoftonline.us","aliases":["login.microsoftonline.us","login.usgovcloudapi.net"]},{"preferred_network":"login-us.microsoftonline.com","preferred_cache":"login-us.microsoftonline.com","aliases":["login-us.microsoftonline.com"]}]}, [ + 'Cache-Control', + 'max-age=86400, private', + 'Content-Type', + 'application/json; charset=utf-8', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'Access-Control-Allow-Origin', + '*', + 'Access-Control-Allow-Methods', + 'GET, OPTIONS', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + 'cbc58672-7ee0-42bd-a2ff-04c07925a700', + 'x-ms-ests-server', + '2.1.11787.14 - SCUS ProdSlices', + 'Set-Cookie', + 'fpc=fpc;; expires=Fri, 09-Jul-2021 22:06:47 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'esctx=esctx; domain=.login.microsoftonline.com; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Wed, 09 Jun 2021 22:06:47 GMT', + 'Content-Length', + '980' +]); + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .get('/12345678-1234-1234-1234-123456789012/v2.0/.well-known/openid-configuration') + .reply(200, {"token_endpoint":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/oauth2/v2.0/token","token_endpoint_auth_methods_supported":["client_secret_post","private_key_jwt","client_secret_basic"],"jwks_uri":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/discovery/v2.0/keys","response_modes_supported":["query","fragment","form_post"],"subject_types_supported":["pairwise"],"id_token_signing_alg_values_supported":["RS256"],"response_types_supported":["code","id_token","code id_token","id_token token"],"scopes_supported":["openid","profile","email","offline_access"],"issuer":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/v2.0","request_uri_parameter_supported":false,"userinfo_endpoint":"https://graph.microsoft.com/oidc/userinfo","authorization_endpoint":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/oauth2/v2.0/authorize","device_authorization_endpoint":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/oauth2/v2.0/devicecode","http_logout_supported":true,"frontchannel_logout_supported":true,"end_session_endpoint":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/oauth2/v2.0/logout","claims_supported":["sub","iss","cloud_instance_name","cloud_instance_host_name","cloud_graph_host_name","msgraph_host","aud","exp","iat","auth_time","acr","nonce","preferred_username","name","tid","ver","at_hash","c_hash","email"],"tenant_region_scope":"NA","cloud_instance_name":"microsoftonline.com","cloud_graph_host_name":"graph.windows.net","msgraph_host":"graph.microsoft.com","rbac_url":"https://pas.windows.net"}, [ + 'Cache-Control', + 'max-age=86400, private', + 'Content-Type', + 'application/json; charset=utf-8', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'Access-Control-Allow-Origin', + '*', + 'Access-Control-Allow-Methods', + 'GET, OPTIONS', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + 'bd0f0928-051d-4666-8f19-526771d51900', + 'x-ms-ests-server', + '2.1.11787.14 - EUS ProdSlices', + 'Set-Cookie', + 'fpc=fpc;; expires=Fri, 09-Jul-2021 22:06:47 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'esctx=esctx; domain=.login.microsoftonline.com; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Wed, 09 Jun 2021 22:06:47 GMT', + 'Content-Length', + '1651' +]); + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .post('/12345678-1234-1234-1234-123456789012/oauth2/v2.0/token', "client_id=azure_client_id&username=azure_username&password=azure_password&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default%20openid%20profile%20offline_access&grant_type=password&client_info=1&x-client-SKU=msal.js.node&x-client-VER=1.1.0&x-client-OS=linux&x-client-CPU=x64&x-ms-lib-capability=retry-after, h429&x-client-current-telemetry=2|371,0|,&x-client-last-telemetry=2|0|||0,0&client-request-id=client-request-id") + .reply(200, {"token_type":"Bearer","scope":"profile openid email https://graph.microsoft.com/User.Read https://graph.microsoft.com/.default","expires_in":3599,"ext_expires_in":3599,"access_token":"access_token","refresh_token":"refresh_token","id_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6ImtpZCJ9.eyJhdWQiOiJhdWQiLCJpc3MiOiJodHRwczovL2xvZ2luLm1pY3Jvc29mdG9ubGluZS5jb20vMTIzNDU2NzgtMTIzNC0xMjM0LTEyMzQtMTIzNDU2Nzg5MDEyL3YyLjAiLCJpYXQiOjE2MTUzMzcxNjMsIm5iZiI6MTYxNTMzNzE2MywiZXhwIjoxNjE1MzQxMDYzLCJhaW8iOiJhaW8iLCJpZHAiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC9pZHAvIiwibmFtZSI6IkRhbmllbCBSb2Ryw61ndWV6Iiwib2lkIjoib2lkIiwicHJlZmVycmVkX3VzZXJuYW1lIjoiZGFucm9kcmlAbWljcm9zb2Z0LmNvbSIsInJoIjoicmguIiwic3ViIjoic3ViIiwidGlkIjoiMTIzNDU2NzgtMTIzNC0xMjM0LTEyMzQtMTIzNDU2Nzg5MDEyIiwidXRpIjoidXRpIiwidmVyIjoiMi4wIn0=.bm9faWRlYV93aGF0c190aGlz","client_info":"eyJ1aWQiOiIxMjM0NTY3OC0xMjM0LTEyMzQtMTIzNC0xMjM0NTY3ODkwMTIiLCJ1dGlkIjoiMTIzNDU2NzgtMTIzNC0xMjM0LTEyMzQtMTIzNDU2Nzg5MDEyIn0K"}, [ + 'Cache-Control', + 'no-store, no-cache', + 'Pragma', + 'no-cache', + 'Content-Type', + 'application/json; charset=utf-8', + 'Expires', + '-1', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + '9e1bae85-2215-44d4-8edc-49f25c3d1a00', + 'x-ms-ests-server', + '2.1.11787.14 - EUS ProdSlices', + 'x-ms-clitelem', + '1,0,0,,', + 'Set-Cookie', + 'fpc=fpc;; expires=Fri, 09-Jul-2021 22:06:48 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Wed, 09 Jun 2021 22:06:47 GMT', + 'Content-Length', + '4609' +]); diff --git a/sdk/identity/identity-cache-persistence/recordings/node/usernamepasswordcredential_internal/recording_authenticates_silently_with_tokencachepersistenceoptions.js b/sdk/identity/identity-cache-persistence/recordings/node/usernamepasswordcredential_internal/recording_authenticates_silently_with_tokencachepersistenceoptions.js new file mode 100644 index 000000000000..75b1ab05eee8 --- /dev/null +++ b/sdk/identity/identity-cache-persistence/recordings/node/usernamepasswordcredential_internal/recording_authenticates_silently_with_tokencachepersistenceoptions.js @@ -0,0 +1,111 @@ +let nock = require('nock'); + +module.exports.hash = "bdd6d580a139539982f96a31a4f9e3cc"; + +module.exports.testInfo = {"uniqueName":{},"newDate":{}} + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .get('/common/discovery/instance') + .query(true) + .reply(200, {"tenant_discovery_endpoint":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/v2.0/.well-known/openid-configuration","api-version":"1.1","metadata":[{"preferred_network":"login.microsoftonline.com","preferred_cache":"login.windows.net","aliases":["login.microsoftonline.com","login.windows.net","login.microsoft.com","sts.windows.net"]},{"preferred_network":"login.partner.microsoftonline.cn","preferred_cache":"login.partner.microsoftonline.cn","aliases":["login.partner.microsoftonline.cn","login.chinacloudapi.cn"]},{"preferred_network":"login.microsoftonline.de","preferred_cache":"login.microsoftonline.de","aliases":["login.microsoftonline.de"]},{"preferred_network":"login.microsoftonline.us","preferred_cache":"login.microsoftonline.us","aliases":["login.microsoftonline.us","login.usgovcloudapi.net"]},{"preferred_network":"login-us.microsoftonline.com","preferred_cache":"login-us.microsoftonline.com","aliases":["login-us.microsoftonline.com"]}]}, [ + 'Cache-Control', + 'max-age=86400, private', + 'Content-Type', + 'application/json; charset=utf-8', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'Access-Control-Allow-Origin', + '*', + 'Access-Control-Allow-Methods', + 'GET, OPTIONS', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + 'dab65d46-f669-4e01-8263-513c9e450e00', + 'x-ms-ests-server', + '2.1.11787.14 - EUS ProdSlices', + 'Set-Cookie', + 'fpc=fpc;; expires=Fri, 09-Jul-2021 22:06:48 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'esctx=esctx; domain=.login.microsoftonline.com; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Wed, 09 Jun 2021 22:06:47 GMT', + 'Content-Length', + '980' +]); + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .get('/12345678-1234-1234-1234-123456789012/v2.0/.well-known/openid-configuration') + .reply(200, {"token_endpoint":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/oauth2/v2.0/token","token_endpoint_auth_methods_supported":["client_secret_post","private_key_jwt","client_secret_basic"],"jwks_uri":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/discovery/v2.0/keys","response_modes_supported":["query","fragment","form_post"],"subject_types_supported":["pairwise"],"id_token_signing_alg_values_supported":["RS256"],"response_types_supported":["code","id_token","code id_token","id_token token"],"scopes_supported":["openid","profile","email","offline_access"],"issuer":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/v2.0","request_uri_parameter_supported":false,"userinfo_endpoint":"https://graph.microsoft.com/oidc/userinfo","authorization_endpoint":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/oauth2/v2.0/authorize","device_authorization_endpoint":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/oauth2/v2.0/devicecode","http_logout_supported":true,"frontchannel_logout_supported":true,"end_session_endpoint":"https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/oauth2/v2.0/logout","claims_supported":["sub","iss","cloud_instance_name","cloud_instance_host_name","cloud_graph_host_name","msgraph_host","aud","exp","iat","auth_time","acr","nonce","preferred_username","name","tid","ver","at_hash","c_hash","email"],"tenant_region_scope":"NA","cloud_instance_name":"microsoftonline.com","cloud_graph_host_name":"graph.windows.net","msgraph_host":"graph.microsoft.com","rbac_url":"https://pas.windows.net"}, [ + 'Cache-Control', + 'max-age=86400, private', + 'Content-Type', + 'application/json; charset=utf-8', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'Access-Control-Allow-Origin', + '*', + 'Access-Control-Allow-Methods', + 'GET, OPTIONS', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + 'fccd1380-a9b6-4c6b-86b8-f9064aeb1900', + 'x-ms-ests-server', + '2.1.11787.14 - NCUS ProdSlices', + 'Set-Cookie', + 'fpc=fpc;; expires=Fri, 09-Jul-2021 22:06:48 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'esctx=esctx; domain=.login.microsoftonline.com; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Wed, 09 Jun 2021 22:06:47 GMT', + 'Content-Length', + '1651' +]); + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .post('/12345678-1234-1234-1234-123456789012/oauth2/v2.0/token', "client_id=azure_client_id&username=azure_username&password=azure_password&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default%20openid%20profile%20offline_access&grant_type=password&client_info=1&x-client-SKU=msal.js.node&x-client-VER=1.1.0&x-client-OS=linux&x-client-CPU=x64&x-ms-lib-capability=retry-after, h429&x-client-current-telemetry=2|371,0|,&x-client-last-telemetry=2|0|||0,0&client-request-id=client-request-id") + .reply(200, {"token_type":"Bearer","scope":"profile openid email https://graph.microsoft.com/User.Read https://graph.microsoft.com/.default","expires_in":3599,"ext_expires_in":3599,"access_token":"access_token","refresh_token":"refresh_token","id_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6ImtpZCJ9.eyJhdWQiOiJhdWQiLCJpc3MiOiJodHRwczovL2xvZ2luLm1pY3Jvc29mdG9ubGluZS5jb20vMTIzNDU2NzgtMTIzNC0xMjM0LTEyMzQtMTIzNDU2Nzg5MDEyL3YyLjAiLCJpYXQiOjE2MTUzMzcxNjMsIm5iZiI6MTYxNTMzNzE2MywiZXhwIjoxNjE1MzQxMDYzLCJhaW8iOiJhaW8iLCJpZHAiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC9pZHAvIiwibmFtZSI6IkRhbmllbCBSb2Ryw61ndWV6Iiwib2lkIjoib2lkIiwicHJlZmVycmVkX3VzZXJuYW1lIjoiZGFucm9kcmlAbWljcm9zb2Z0LmNvbSIsInJoIjoicmguIiwic3ViIjoic3ViIiwidGlkIjoiMTIzNDU2NzgtMTIzNC0xMjM0LTEyMzQtMTIzNDU2Nzg5MDEyIiwidXRpIjoidXRpIiwidmVyIjoiMi4wIn0=.bm9faWRlYV93aGF0c190aGlz","client_info":"eyJ1aWQiOiIxMjM0NTY3OC0xMjM0LTEyMzQtMTIzNC0xMjM0NTY3ODkwMTIiLCJ1dGlkIjoiMTIzNDU2NzgtMTIzNC0xMjM0LTEyMzQtMTIzNDU2Nzg5MDEyIn0K"}, [ + 'Cache-Control', + 'no-store, no-cache', + 'Pragma', + 'no-cache', + 'Content-Type', + 'application/json; charset=utf-8', + 'Expires', + '-1', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + '588429da-f260-4926-899e-61e0ae787a00', + 'x-ms-ests-server', + '2.1.11787.14 - WUS2 ProdSlices', + 'x-ms-clitelem', + '1,0,0,,', + 'Set-Cookie', + 'fpc=fpc;; expires=Fri, 09-Jul-2021 22:06:48 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Wed, 09 Jun 2021 22:06:48 GMT', + 'Content-Length', + '4615' +]); diff --git a/sdk/identity/identity-cache-persistence/review/identity-cache-persistence.api.md b/sdk/identity/identity-cache-persistence/review/identity-cache-persistence.api.md new file mode 100644 index 000000000000..4d1cf8afbe53 --- /dev/null +++ b/sdk/identity/identity-cache-persistence/review/identity-cache-persistence.api.md @@ -0,0 +1,15 @@ +## API Report File for "@azure/identity-cache-persistence" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +import { IdentityExtension } from '@azure/identity'; + +// @public +export const cachePersistenceExtension: IdentityExtension; + + +// (No @packageDocumentation comment for this package) + +``` diff --git a/sdk/identity/identity-cache-persistence/rollup.config.js b/sdk/identity/identity-cache-persistence/rollup.config.js new file mode 100644 index 000000000000..5d7deee44c14 --- /dev/null +++ b/sdk/identity/identity-cache-persistence/rollup.config.js @@ -0,0 +1,3 @@ +import { makeConfig } from "@azure/dev-tool/shared-config/rollup"; + +export default makeConfig(require("./package.json")); diff --git a/sdk/identity/identity-cache-persistence/samples-dev/extension.ts b/sdk/identity/identity-cache-persistence/samples-dev/extension.ts new file mode 100644 index 000000000000..d826b5ca6ee7 --- /dev/null +++ b/sdk/identity/identity-cache-persistence/samples-dev/extension.ts @@ -0,0 +1,57 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +/** + * This sample shows how to add a persistent token cache to `@azure/identity` + * using the persistence extension. Once the persistence extension is added + * through `useIdentityExtension`, some credentials, such as + * `DeviceCodeCredential`, will be able to retrieve tokens from the cache rather + * than requesting new tokens from the Azure Active Directory token endpoint. + * + * In order to utilize the persistent token cache, the `enabled` property must + * be set to `true` within `tokenCachePersistenceOptions` in the credential's + * options. + * + * @summary import and use the persistence extension + */ + +import { useIdentityExtension, DeviceCodeCredential } from "@azure/identity"; + +import { cachePersistenceExtension } from "@azure/identity-cache-persistence"; +useIdentityExtension(cachePersistenceExtension); + +import dotenv from "dotenv"; +dotenv.config(); + +async function main() { + const credential = new DeviceCodeCredential({ + // This property must be provided, with `enabled` set to true to enable + // persistent token caching. + tokenCachePersistenceOptions: { + enabled: true + } + }); + + // This is the scope we will use to get a token from the AAD token endpoint. + // By default, we'll use the Microsoft Graph scope as an example, but when + // you use the credential with an Azure SDK package, it will configure the + // scope for you automatically. + const scope = process.env.AAD_TEST_SCOPE ?? "https://graph.microsoft.com/.default"; + + // A little helper function to print part of an access_token + const logToken = async () => + console.log((await credential.getToken(scope)).token.substr(0, 10), "..."); + + // You should observe that the same token is printed twice, and that running the sample twice + // only prompts for interactive authentication once. In the second execution, the token should + // be retrieved from the cache. + console.log("Calling getToken()", 1); + await logToken(); + console.log("Calling getToken()", 2); + await logToken(); +} + +main().catch((error) => { + console.error("The sample encountered an error:", error); + process.exit(1); +}); diff --git a/sdk/identity/identity-cache-persistence/src/index.ts b/sdk/identity/identity-cache-persistence/src/index.ts new file mode 100644 index 000000000000..9dc439e31e78 --- /dev/null +++ b/sdk/identity/identity-cache-persistence/src/index.ts @@ -0,0 +1,40 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { IdentityExtension } from "@azure/identity"; + +import { AzureExtensionContext } from "../../identity/src/extensions/provider"; +import { createPersistenceCachePlugin } from "./provider"; + +/** + * An extension that provides persistent token caching for `@azure/identity` + * credentials. The extension API is compatible with `@azure/identity` versions + * 2.0.0 and later. Load this extension using the `useIdentityExtension` + * function, imported from `@azure/identity`. + * + * In order to enable this functionality, you must also pass + * `tokenCachePersistenceOptions` to your credential constructors with an + * `enabled` property set to true. + * + * Example: + * + * ```typescript + * import { useIdentityExtension, DeviceCodeCredential } from "@azure/identity"; + * import { cachePersistenceExtension } from "@azure/identity-cache-persistence"; + * + * // Load the extension + * useIdentityExtension(cachePersistenceExtension); + * + * const credential = new DeviceCodeCredential({ + * tokenCachePersistenceOptions: { + * enabled: true + * } + * }); + * ``` + */ + +export const cachePersistenceExtension: IdentityExtension = (context) => { + const { cachePluginControl } = context as AzureExtensionContext; + + cachePluginControl.setPersistence(createPersistenceCachePlugin); +}; diff --git a/sdk/identity/identity-cache-persistence/src/platforms.ts b/sdk/identity/identity-cache-persistence/src/platforms.ts new file mode 100644 index 000000000000..0a1d591fd696 --- /dev/null +++ b/sdk/identity/identity-cache-persistence/src/platforms.ts @@ -0,0 +1,143 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +/* eslint-disable tsdoc/syntax */ + +import * as path from "path"; + +import { + KeychainPersistence, + FilePersistence, + DataProtectionScope, + FilePersistenceWithDataProtection, + LibSecretPersistence, + IPersistence as Persistence +} from "@azure/msal-node-extensions"; + +import { TokenCachePersistenceOptions } from "@azure/identity"; + +/** + * Local application data folder + * Expected values: + * - Darwin: '/Users/user/' + * - Windows 8: 'C:\Users\user\AppData\Local' + * - Windows XP: 'C:\Documents and Settings\user\Application Data\Local' + * - Linux: '/home/user/.local/share' + * @internal + */ +const localApplicationDataFolder = + process.env.APPDATA?.replace?.(/(.Roaming)*$/, "\\Local") ?? process.env.HOME!; + +/** + * Dictionary of values that we use as default as we discover, pick and enable the persistence layer. + * @internal + */ +export const defaultMsalValues = { + tokenCache: { + name: "msal.cache", + // Expected values: + // - Darwin: '/Users/user/.IdentityService' + // - Windows 8: 'C:\Users\user\AppData\Local\.IdentityService' + // - Windows XP: 'C:\Documents and Settings\user\Application Data\Local\.IdentityService' + // - Linux: '/home/user/.IdentityService' + directory: path.join(localApplicationDataFolder, ".IdentityService") + }, + keyRing: { + label: "MSALCache", + schema: "msal.cache", + collection: "default", + attributes: { + MsalClientID: "Microsoft.Developer.IdentityService", + "Microsoft.Developer.IdentityService": "1.0.0.0" + }, + service: "Microsoft.Developer.IdentityService", + account: "MSALCache" + }, + keyChain: { + service: "Microsoft.Developer.IdentityService", + account: "MSALCache" + } +}; + +/** + * Options that are used by the underlying MSAL cache provider. + * @internal + */ +export type MsalPersistenceOptions = Omit; + +/** + * A function that returns a persistent token cache instance. + * @internal + */ +type MsalPersistenceFactory = (options?: MsalPersistenceOptions) => Promise; + +/** + * Expected responses: + * - Darwin: '/Users/user/.IdentityService/' + * - Windows 8: 'C:\Users\user\AppData\Local\.IdentityService\' + * - Windows XP: 'C:\Documents and Settings\user\Application Data\Local\.IdentityService\' + * - Linux: '/home/user/.IdentityService/' + * @internal + */ +function getPersistencePath(name: string): string { + return path.join(defaultMsalValues.tokenCache.directory, name); +} + +/** + * Set of the platforms we attempt to deliver persistence on. + * + * - On Windows we use DPAPI. + * - On OSX (Darwin), we try to use the system's Keychain, otherwise if the property `allowUnencryptedStorage` is set to true, we use an unencrypted file. + * - On Linux, we try to use the system's Keyring, otherwise if the property `allowUnencryptedStorage` is set to true, we use an unencrypted file. + * + * Other platforms _are not supported_ at this time. + * + * @internal + */ +export const msalPersistencePlatforms: Partial> = { + win32: ({ name = defaultMsalValues.tokenCache.name } = {}): Promise => + FilePersistenceWithDataProtection.create( + getPersistencePath(name), + DataProtectionScope.CurrentUser + ), + + darwin: async (options: MsalPersistenceOptions = {}): Promise => { + const { name, allowUnencryptedStorage } = options; + const { service, account } = defaultMsalValues.keyChain; + const persistencePath = getPersistencePath(name || defaultMsalValues.tokenCache.name); + + try { + const persistence = await KeychainPersistence.create(persistencePath, service, account); + // If we don't encounter an error when trying to read from the keychain, then we should be good to go. + await persistence.load(); + return persistence; + } catch (e) { + // If we got an error while trying to read from the keyring, + // we will proceed only if the user has specified that unencrypted storage is allowed. + if (!allowUnencryptedStorage) { + throw new Error("Unable to read from the macOS Keychain."); + } + return FilePersistence.create(persistencePath); + } + }, + + linux: async (options: MsalPersistenceOptions = {}): Promise => { + const { name, allowUnencryptedStorage } = options; + const { service, account } = defaultMsalValues.keyRing; + const persistencePath = getPersistencePath(name || defaultMsalValues.tokenCache.name); + + try { + const persistence = await LibSecretPersistence.create(persistencePath, service, account); + // If we don't encounter an error when trying to read from the keyring, then we should be good to go. + await persistence.load(); + return persistence; + } catch (e) { + // If we got an error while trying to read from the keyring, + // we will proceed only if the user has specified that unencrypted storage is allowed. + if (!allowUnencryptedStorage) { + throw new Error("Unable to read from the system keyring (libsecret)."); + } + return FilePersistence.create(persistencePath); + } + } +}; diff --git a/sdk/identity/identity-cache-persistence/src/provider.ts b/sdk/identity/identity-cache-persistence/src/provider.ts new file mode 100644 index 000000000000..bbad7ddf910b --- /dev/null +++ b/sdk/identity/identity-cache-persistence/src/provider.ts @@ -0,0 +1,34 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { ICachePlugin as CachePlugin } from "@azure/msal-node"; +import { PersistenceCachePlugin, IPersistence as Persistence } from "@azure/msal-node-extensions"; + +import { MsalPersistenceOptions, msalPersistencePlatforms } from "./platforms"; + +/** + * This is used to gain access to the underlying Persistence instance, which we use for testing + * + * @returns a raw persistence instance + * @internal + */ +export async function createPersistence(options: MsalPersistenceOptions): Promise { + const persistence = await msalPersistencePlatforms[process.platform]?.(options); + + if (persistence === undefined) { + throw new Error("no persistence providers are available on this platform"); + } + + return persistence; +} + +export async function createPersistenceCachePlugin( + options?: MsalPersistenceOptions +): Promise { + const persistence = await createPersistence(options ?? {}); + + return new PersistenceCachePlugin(persistence, { + retryNumber: 100, + retryDelay: 50 + }); +} diff --git a/sdk/identity/identity-cache-persistence/test/internal/node/clientCertificateCredential.spec.ts b/sdk/identity/identity-cache-persistence/test/internal/node/clientCertificateCredential.spec.ts new file mode 100644 index 000000000000..9f87a562cc18 --- /dev/null +++ b/sdk/identity/identity-cache-persistence/test/internal/node/clientCertificateCredential.spec.ts @@ -0,0 +1,126 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +/* eslint-disable @typescript-eslint/no-non-null-asserted-optional-chain */ + +import Sinon from "sinon"; +import assert from "assert"; +import * as path from "path"; + +import { env, isPlaybackMode } from "@azure/test-utils-recorder"; +import { ConfidentialClientApplication } from "@azure/msal-node"; + +import { + ClientCertificateCredential, + TokenCachePersistenceOptions +} from "../../../../identity/src"; +import { MsalTestCleanup, msalNodeTestSetup } from "../../../../identity/test/msalTestUtils"; +import { MsalNode } from "../../../../identity/src/msal/nodeFlows/nodeCommon"; + +import { createPersistence } from "./setup.spec"; + +const ASSET_PATH = "assets"; + +describe("ClientCertificateCredential (internal)", function(this: Mocha.Suite) { + let cleanup: MsalTestCleanup; + let getTokenSilentSpy: Sinon.SinonSpy; + let doGetTokenSpy: Sinon.SinonSpy; + + beforeEach(function(this: Mocha.Context) { + const setup = msalNodeTestSetup(this); + cleanup = setup.cleanup; + + getTokenSilentSpy = setup.sandbox.spy(MsalNode.prototype, "getTokenSilent"); + + // MsalClientSecret calls to this method underneath. + doGetTokenSpy = setup.sandbox.spy( + ConfidentialClientApplication.prototype, + "acquireTokenByClientCredential" + ); + }); + afterEach(async function() { + await cleanup(); + }); + + // We use AZURE_CLIENT_CERTIFICATE_PATH if it is defined, and otherwise we will use the dummy cert + const certificatePath = + process.env.AZURE_CLIENT_CERTIFICATE_PATH ?? path.join(ASSET_PATH, "cert.pem"); + const scope = "https://graph.microsoft.com/.default"; + + it("Accepts tokenCachePersistenceOptions", async function(this: Mocha.Context) { + if (isPlaybackMode()) { + // MSAL creates a client assertion based on the certificate that I haven't been able to mock. + // This assertion could be provided as parameters, but we don't have that in the public API yet, + // and I'm trying to avoid having to generate one ourselves. + this.skip(); + } + // OSX asks for passwords on CI, so we need to skip these tests from our automation + if (process.platform === "darwin") { + this.skip(); + } + + const tokenCachePersistenceOptions: TokenCachePersistenceOptions = { + enabled: true, + name: this.test?.title.replace(/[^a-zA-Z]/g, "_"), + allowUnencryptedStorage: true + }; + + // Emptying the token cache before we start. + const persistence = await createPersistence(tokenCachePersistenceOptions); + persistence?.save("{}"); + + const credential = new ClientCertificateCredential( + env.AZURE_TENANT_ID, + env.AZURE_CLIENT_ID, + certificatePath, + { tokenCachePersistenceOptions } + ); + + await credential.getToken(scope); + const result = await persistence?.load(); + const parsedResult = JSON.parse(result!); + assert.ok(parsedResult.AccessToken); + }); + + it("Authenticates silently with tokenCachePersistenceOptions", async function(this: Mocha.Context) { + if (isPlaybackMode()) { + // MSAL creates a client assertion based on the certificate that I haven't been able to mock. + // This assertion could be provided as parameters, but we don't have that in the public API yet, + // and I'm trying to avoid having to generate one ourselves. + this.skip(); + } + // OSX asks for passwords on CI, so we need to skip these tests from our automation + if (process.platform === "darwin") { + this.skip(); + } + + const tokenCachePersistenceOptions: TokenCachePersistenceOptions = { + enabled: true, + name: this.test?.title.replace(/[^a-zA-Z]/g, "_"), + allowUnencryptedStorage: true + }; + + // Emptying the token cache before we start. + const persistence = await createPersistence(tokenCachePersistenceOptions); + await persistence?.save("{}"); + + const credential = new ClientCertificateCredential( + env.AZURE_TENANT_ID, + env.AZURE_CLIENT_ID, + certificatePath, + { tokenCachePersistenceOptions } + ); + + await credential.getToken(scope); + assert.equal(getTokenSilentSpy.callCount, 1); + assert.equal(doGetTokenSpy.callCount, 1); + + await credential.getToken(scope); + assert.equal(getTokenSilentSpy.callCount, 2); + // Even though we're providing a file persistence cache, + // The Client Credential flow does not return the account information from the authentication service, + // so each time getToken gets called, we will have to acquire a new token through the service. + // MSAL also doesn't store the account in the cache (getAllAccounts returns an empty array). + assert.equal(doGetTokenSpy.callCount, 2); + }); +}); diff --git a/sdk/identity/identity-cache-persistence/test/internal/node/clientSecretCredential.spec.ts b/sdk/identity/identity-cache-persistence/test/internal/node/clientSecretCredential.spec.ts new file mode 100644 index 000000000000..cfb960f966f0 --- /dev/null +++ b/sdk/identity/identity-cache-persistence/test/internal/node/clientSecretCredential.spec.ts @@ -0,0 +1,105 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +/* eslint-disable @typescript-eslint/no-non-null-asserted-optional-chain */ + +import Sinon from "sinon"; +import assert from "assert"; + +import { env } from "@azure/test-utils-recorder"; +import { ConfidentialClientApplication } from "@azure/msal-node"; + +import { ClientSecretCredential, TokenCachePersistenceOptions } from "../../../../identity/src"; +import { MsalTestCleanup, msalNodeTestSetup } from "../../../../identity/test/msalTestUtils"; +import { MsalNode } from "../../../../identity/src/msal/nodeFlows/nodeCommon"; + +import { createPersistence } from "./setup.spec"; + +const scope = "https://graph.microsoft.com/.default"; + +describe("ClientSecretCredential (internal)", function(this: Mocha.Suite) { + let cleanup: MsalTestCleanup; + let getTokenSilentSpy: Sinon.SinonSpy; + let doGetTokenSpy: Sinon.SinonSpy; + + beforeEach(function(this: Mocha.Context) { + const setup = msalNodeTestSetup(this); + cleanup = setup.cleanup; + + getTokenSilentSpy = setup.sandbox.spy(MsalNode.prototype, "getTokenSilent"); + + // MsalClientSecret calls to this method underneath. + doGetTokenSpy = setup.sandbox.spy( + ConfidentialClientApplication.prototype, + "acquireTokenByClientCredential" + ); + }); + afterEach(async function() { + await cleanup(); + }); + + it("Accepts tokenCachePersistenceOptions", async function(this: Mocha.Context) { + // OSX asks for passwords on CI, so we need to skip these tests from our automation + if (process.platform === "darwin") { + this.skip(); + } + + const tokenCachePersistenceOptions: TokenCachePersistenceOptions = { + enabled: true, + name: this.test?.title.replace(/[^a-zA-Z]/g, "_"), + allowUnencryptedStorage: true + }; + + // Emptying the token cache before we start. + const persistence = await createPersistence(tokenCachePersistenceOptions); + persistence?.save("{}"); + + const credential = new ClientSecretCredential( + env.AZURE_TENANT_ID, + env.AZURE_CLIENT_ID, + env.AZURE_CLIENT_SECRET, + { tokenCachePersistenceOptions } + ); + + await credential.getToken(scope); + const result = await persistence?.load(); + const parsedResult = JSON.parse(result!); + assert.ok(parsedResult.AccessToken); + }); + + it("Authenticates silently with tokenCachePersistenceOptions", async function(this: Mocha.Context) { + // OSX asks for passwords on CI, so we need to skip these tests from our automation + if (process.platform === "darwin") { + this.skip(); + } + + const tokenCachePersistenceOptions: TokenCachePersistenceOptions = { + enabled: true, + name: this.test?.title.replace(/[^a-zA-Z]/g, "_"), + allowUnencryptedStorage: true + }; + + // Emptying the token cache before we start. + const persistence = await createPersistence(tokenCachePersistenceOptions); + persistence?.save("{}"); + + const credential = new ClientSecretCredential( + env.AZURE_TENANT_ID, + env.AZURE_CLIENT_ID, + env.AZURE_CLIENT_SECRET, + { tokenCachePersistenceOptions } + ); + + await credential.getToken(scope); + assert.equal(getTokenSilentSpy.callCount, 1); + assert.equal(doGetTokenSpy.callCount, 1); + + await credential.getToken(scope); + assert.equal(getTokenSilentSpy.callCount, 2); + + // Even though we're providing the same default in memory persistence cache that we use for DeviceCodeCredential, + // The Client Secret flow does not return the account information from the authentication service, + // so each time getToken gets called, we will have to acquire a new token through the service. + assert.equal(doGetTokenSpy.callCount, 2); + }); +}); diff --git a/sdk/identity/identity-cache-persistence/test/internal/node/deviceCodeCredential.spec.ts b/sdk/identity/identity-cache-persistence/test/internal/node/deviceCodeCredential.spec.ts new file mode 100644 index 000000000000..dbede0e5438d --- /dev/null +++ b/sdk/identity/identity-cache-persistence/test/internal/node/deviceCodeCredential.spec.ts @@ -0,0 +1,160 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +/* eslint-disable @typescript-eslint/no-non-null-asserted-optional-chain */ + +import Sinon from "sinon"; +import assert from "assert"; + +import { PublicClientApplication } from "@azure/msal-node"; +import { isLiveMode } from "@azure/test-utils-recorder"; + +import { DeviceCodeCredential, TokenCachePersistenceOptions } from "../../../../identity/src"; +import { MsalTestCleanup, msalNodeTestSetup } from "../../../../identity/test/msalTestUtils"; +import { MsalNode } from "../../../../identity/src/msal/nodeFlows/nodeCommon"; + +import { createPersistence } from "./setup.spec"; + +describe("DeviceCodeCredential (internal)", function(this: Mocha.Suite) { + let cleanup: MsalTestCleanup; + let getTokenSilentSpy: Sinon.SinonSpy; + let doGetTokenSpy: Sinon.SinonSpy; + + beforeEach(function(this: Mocha.Context) { + const setup = msalNodeTestSetup(this); + cleanup = setup.cleanup; + + getTokenSilentSpy = setup.sandbox.spy(MsalNode.prototype, "getTokenSilent"); + + // MsalClientSecret calls to this method underneath. + doGetTokenSpy = setup.sandbox.spy( + PublicClientApplication.prototype, + "acquireTokenByDeviceCode" + ); + }); + afterEach(async function() { + await cleanup(); + }); + + const scope = "https://graph.microsoft.com/.default"; + + it("Accepts tokenCachePersistenceOptions", async function(this: Mocha.Context) { + // OSX asks for passwords on CI, so we need to skip these tests from our automation + if (process.platform === "darwin") { + this.skip(); + } + // These tests should not run live because this credential requires user interaction. + if (isLiveMode()) { + this.skip(); + } + + const tokenCachePersistenceOptions: TokenCachePersistenceOptions = { + enabled: true, + name: this.test?.title.replace(/[^a-zA-Z]/g, "_"), + allowUnencryptedStorage: true + }; + + // Emptying the token cache before we start. + const persistence = await createPersistence(tokenCachePersistenceOptions); + persistence?.save("{}"); + + const credential = new DeviceCodeCredential({ + tokenCachePersistenceOptions + }); + + await credential.getToken(scope); + const result = await persistence?.load(); + const parsedResult = JSON.parse(result!); + assert.ok(parsedResult.AccessToken); + }); + + it("Authenticates silently with tokenCachePersistenceOptions", async function(this: Mocha.Context) { + // OSX asks for passwords on CI, so we need to skip these tests from our automation + if (process.platform === "darwin") { + this.skip(); + } + // These tests should not run live because this credential requires user interaction. + if (isLiveMode()) { + this.skip(); + } + + const tokenCachePersistenceOptions: TokenCachePersistenceOptions = { + enabled: true, + name: this.test?.title.replace(/[^a-zA-Z]/g, "_"), + allowUnencryptedStorage: true + }; + + // Emptying the token cache before we start. + const persistence = await createPersistence(tokenCachePersistenceOptions); + persistence?.save("{}"); + + const credential = new DeviceCodeCredential({ + tokenCachePersistenceOptions + }); + + await credential.getToken(scope); + assert.equal(getTokenSilentSpy.callCount, 1); + assert.equal(doGetTokenSpy.callCount, 1); + + // The cache should have a token a this point + const result = await persistence?.load(); + const parsedResult = JSON.parse(result!); + assert.ok(parsedResult.AccessToken); + + await credential.getToken(scope); + assert.equal(getTokenSilentSpy.callCount, 2); + assert.equal(doGetTokenSpy.callCount, 1); + }); + + it("allows passing an authenticationRecord to avoid further manual authentications", async function(this: Mocha.Context) { + // OSX asks for passwords on CI, so we need to skip these tests from our automation + if (process.platform === "darwin") { + this.skip(); + } + // These tests should not run live because this credential requires user interaction. + if (isLiveMode()) { + this.skip(); + } + const tokenCachePersistenceOptions: TokenCachePersistenceOptions = { + enabled: true, + name: this.test?.title.replace(/[^a-zA-Z]/g, "_"), + allowUnencryptedStorage: true + }; + + // Emptying the token cache before we start. + const persistence = await createPersistence(tokenCachePersistenceOptions); + persistence?.save("{}"); + + const credential = new DeviceCodeCredential({ + // To be able to re-use the account, the Token Cache must also have been provided. + // TODO: Perhaps make the account parameter part of the tokenCachePersistenceOptions? + tokenCachePersistenceOptions + }); + + const account = await credential.authenticate(scope); + assert.ok(account); + assert.equal(getTokenSilentSpy.callCount, 1); + assert.equal(doGetTokenSpy.callCount, 1); + + const credential2 = new DeviceCodeCredential({ + authenticationRecord: account, + // To be able to re-use the account, the Token Cache must also have been provided. + // TODO: Perhaps make the account parameter part of the tokenCachePersistenceOptions? + tokenCachePersistenceOptions + }); + + // The cache should have a token a this point + const result = await persistence?.load(); + const parsedResult = JSON.parse(result!); + assert.ok(parsedResult.AccessToken); + + const token = await credential2.getToken(scope); + assert.ok(token?.token); + assert.ok(token?.expiresOnTimestamp! > Date.now()); + assert.equal(getTokenSilentSpy.callCount, 2); + + // TODO: Why is this the case? + // I created an issue to track this: https://github.com/Azure/azure-sdk-for-js/issues/14701 + assert.equal(doGetTokenSpy.callCount, 2); + }); +}); diff --git a/sdk/identity/identity-cache-persistence/test/internal/node/setup.spec.ts b/sdk/identity/identity-cache-persistence/test/internal/node/setup.spec.ts new file mode 100644 index 000000000000..175e5f813cb7 --- /dev/null +++ b/sdk/identity/identity-cache-persistence/test/internal/node/setup.spec.ts @@ -0,0 +1,33 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +/* eslint-disable @typescript-eslint/no-require-imports */ + +// We need to set up the extension for the tests! + +import { useIdentityExtension } from "../../../../identity/src"; + +// The persistence tests have to run on the same version of Node that's used to +// install dependencies, currently 14. +// TODO: We need a better solution for this, but this will do for now. +if (!process.versions.node.startsWith("14")) { + console.warn( + "WARNING: skipping persistence tests on incompatible node version:", + process.version + ); + console.warn("Persistence tests are only compatible with Node 14."); + process.exit(0); +} + +// This shim is required to defer loading of msal-node-extensions in environments where +// it will crash CI with an invalid Node API version. +export const createPersistence: typeof import("../../../src/provider").createPersistence = ( + ...args +) => { + const { createPersistence: create } = require("../../../src/provider"); + return create(...args); +}; + +before(function() { + useIdentityExtension(require("../../../src").cachePersistenceExtension); +}); diff --git a/sdk/identity/identity-cache-persistence/test/internal/node/usernamePasswordCredential.spec.ts b/sdk/identity/identity-cache-persistence/test/internal/node/usernamePasswordCredential.spec.ts new file mode 100644 index 000000000000..bf13301d4f89 --- /dev/null +++ b/sdk/identity/identity-cache-persistence/test/internal/node/usernamePasswordCredential.spec.ts @@ -0,0 +1,109 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +/* eslint-disable @typescript-eslint/no-non-null-asserted-optional-chain */ + +import Sinon from "sinon"; +import assert from "assert"; + +import { env } from "@azure/test-utils-recorder"; +import { PublicClientApplication } from "@azure/msal-node"; + +import { UsernamePasswordCredential, TokenCachePersistenceOptions } from "../../../../identity/src"; +import { MsalTestCleanup, msalNodeTestSetup } from "../../../../identity/test/msalTestUtils"; +import { MsalNode } from "../../../../identity/src/msal/nodeFlows/nodeCommon"; + +import { createPersistence } from "./setup.spec"; + +describe("UsernamePasswordCredential (internal)", function(this: Mocha.Suite) { + let cleanup: MsalTestCleanup; + let getTokenSilentSpy: Sinon.SinonSpy; + let doGetTokenSpy: Sinon.SinonSpy; + + beforeEach(function(this: Mocha.Context) { + const setup = msalNodeTestSetup(this); + cleanup = setup.cleanup; + + getTokenSilentSpy = setup.sandbox.spy(MsalNode.prototype, "getTokenSilent"); + + // MsalClientSecret calls to this method underneath. + doGetTokenSpy = setup.sandbox.spy( + PublicClientApplication.prototype, + "acquireTokenByUsernamePassword" + ); + }); + + afterEach(async function() { + await cleanup(); + }); + + const scope = "https://graph.microsoft.com/.default"; + + it("Accepts tokenCachePersistenceOptions", async function(this: Mocha.Context) { + // OSX asks for passwords on CI, so we need to skip these tests from our automation + if (process.platform === "darwin") { + this.skip(); + } + + const tokenCachePersistenceOptions: TokenCachePersistenceOptions = { + enabled: true, + name: this.test?.title.replace(/[^a-zA-Z]/g, "_"), + allowUnencryptedStorage: true + }; + + // Emptying the token cache before we start. + const persistence = await createPersistence(tokenCachePersistenceOptions); + persistence?.save("{}"); + + const credential = new UsernamePasswordCredential( + env.AZURE_TENANT_ID, + env.AZURE_CLIENT_ID, + env.AZURE_USERNAME, + env.AZURE_PASSWORD, + { tokenCachePersistenceOptions } + ); + + await credential.getToken(scope); + const result = await persistence?.load(); + const parsedResult = JSON.parse(result!); + assert.ok(parsedResult.AccessToken); + }); + + it("Authenticates silently with tokenCachePersistenceOptions", async function(this: Mocha.Context) { + // OSX asks for passwords on CI, so we need to skip these tests from our automation + if (process.platform === "darwin") { + this.skip(); + } + + const tokenCachePersistenceOptions: TokenCachePersistenceOptions = { + enabled: true, + name: this.test?.title.replace(/[^a-zA-Z]/g, "_"), + allowUnencryptedStorage: true + }; + + // Emptying the token cache before we start. + const persistence = await createPersistence(tokenCachePersistenceOptions); + persistence?.save("{}"); + + const credential = new UsernamePasswordCredential( + env.AZURE_TENANT_ID, + env.AZURE_CLIENT_ID, + env.AZURE_USERNAME, + env.AZURE_PASSWORD, + { tokenCachePersistenceOptions } + ); + + await credential.getToken(scope); + assert.equal(getTokenSilentSpy.callCount, 1); + assert.equal(doGetTokenSpy.callCount, 1); + + // The cache should have a token a this point + const result = await persistence?.load(); + const parsedResult = JSON.parse(result!); + assert.ok(parsedResult.AccessToken); + + await credential.getToken(scope); + assert.equal(getTokenSilentSpy.callCount, 2); + assert.equal(doGetTokenSpy.callCount, 1); + }); +}); diff --git a/sdk/identity/identity-cache-persistence/tsconfig.json b/sdk/identity/identity-cache-persistence/tsconfig.json new file mode 100644 index 000000000000..fa5828a32c3a --- /dev/null +++ b/sdk/identity/identity-cache-persistence/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "../../../tsconfig.package", + "compilerOptions": { + "target": "es6", + "lib": ["DOM"], + "declarationDir": "./types", + "outDir": "./dist-esm", + "resolveJsonModule": true, + "paths": { + "@azure/identity-cache-persistence": ["./src/index"] + } + }, + "include": ["src/**/*", "test/**/*", "samples-dev/**/*"] +} diff --git a/sdk/identity/identity-cache-persistence/tsdoc.json b/sdk/identity/identity-cache-persistence/tsdoc.json new file mode 100644 index 000000000000..81c5a8a2aa2f --- /dev/null +++ b/sdk/identity/identity-cache-persistence/tsdoc.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", + "extends": ["../../../tsdoc.json"] +} diff --git a/sdk/identity/identity-vscode/.eslintrc.json b/sdk/identity/identity-vscode/.eslintrc.json new file mode 100644 index 000000000000..1c1503b9333a --- /dev/null +++ b/sdk/identity/identity-vscode/.eslintrc.json @@ -0,0 +1,8 @@ +{ + "plugins": ["@azure/azure-sdk"], + "extends": ["plugin:@azure/azure-sdk/azure-sdk-base"], + "rules": { + "@azure/azure-sdk/ts-package-json-module": "off", + "@azure/azure-sdk/ts-package-json-engine-is-present": "off" + } +} diff --git a/sdk/identity/identity-vscode/CHANGELOG.md b/sdk/identity/identity-vscode/CHANGELOG.md new file mode 100644 index 000000000000..b4a00d2e3023 --- /dev/null +++ b/sdk/identity/identity-vscode/CHANGELOG.md @@ -0,0 +1,7 @@ +# Release History + +## 1.0.0-beta.1 (Unreleased) + +### New features + +- This release marks the initial beta availability of the `@azure/identity-vscode` package. This package extends `@azure/identity` by providing the dependencies of `VisualStudioCodeCredential` and enabling it within the `@azure/identity` package. `VisualStudioCodeCredential` uses the authenticated session from the "Azure Account" extension in Visual Studio Code. If this extension package is not loaded using `useIdentityExtension`, then `VisualStudioCodeCredential` from `@azure/identity` will throw a `CredentialUnavailableError`. By enabling `VisualStudioCodeCredential`, the `DefaultAzureCredential` class in `@azure/identity` also gains functionality allowing it to use the "Azure Account" session if it is available. diff --git a/sdk/identity/identity-vscode/LICENSE b/sdk/identity/identity-vscode/LICENSE new file mode 100644 index 000000000000..ea8fb1516028 --- /dev/null +++ b/sdk/identity/identity-vscode/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2020 Microsoft + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/sdk/identity/identity-vscode/README.md b/sdk/identity/identity-vscode/README.md new file mode 100644 index 000000000000..b4da40df904f --- /dev/null +++ b/sdk/identity/identity-vscode/README.md @@ -0,0 +1,125 @@ +## Azure Identity Extension for Visual Studio Code Authentication + +This package provides an extension to the Azure Identity library for JavaScript ([`@azure/identity`](https://npmjs.com/package/@azure/identity)) that enables authentication through the "Azure Account" extension for Visual Studio Code. This extension provides the dependencies of the `VisualStudioCodeCredential` in `@azure/identity` and enables it for use on its own or as part of `DefaultAzureCredential`. + +[Source code](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/identity/identity-vscode) | [Samples](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity-vscode/samples-dev) + +## Getting started + +### Install the package + +This package is designed to be used with Azure Identity for JavaScript. Install both `@azure/identity` and this package using `npm`: + +```sh +$ npm install --save @azure/identity +$ npm install --save @azure/identity-vscode +``` + +### Prerequisites + +- An [Azure subscription](https://azure.microsoft.com/free/). +- Install [Visual Studio Code](https://aka.ms/vscode) and the ["Azure Account" extension][azaccountext] + +#### Supported Environments + +Azure Identity extensions for JavaScript support stable (even numbered) versions of Node.js starting from v12. While it may run in other Node versions, no support is guaranteed. `@azure/identity-vscode` **does not** support browser environments. + +## Key concepts + +If this is your first time using `@azure/identity` or the Microsoft identity platform (Azure Active Directory), we recommend that you read [Using `@azure/identity` with Microsoft Identity Platform](https://github.com/Azure/azure-sdk-for-js/blob/main/documentation/using-azure-identity.md) first. This document will give you a deeper understanding of the platform and how to configure your Azure account correctly. + +### Azure Identity Extensions + +As of `@azure/identity` version 2.0.0, the Identity client library for JavaScript includes an extension API. This package (`@azure/identity-vscode`) exports an extension object that you must pass as an argument to the top-level `useIdentityExtension` function from the `@azure/identity` package. Enable authentication through the "Azure Account" extension for Visual Studio Code as follows: + +```typescript +import { useIdentityExtension } from "@azure/identity"; +import { vsCodeExtension } from "@azure/identity-vscode"; + +useIdentityExtension(vsCodeExtension); +``` + +After calling `useIdentityExtension`, the `VisualStudioCodeCredential` from the `@azure/identity` package will be enabled. If this extension is not used, then `VisualStudioCodeCredential` will throw a `CredentialUnavailableError`, and it will not be available as part of `DefaultAzureCredential`. + +### Visual Studio Code Authentication + +`VisualStudioCodeCredential` uses the authentication session from the ["Azure Accounts" extension][azaccountext]. To use this credential, you must sign in to your Azure account using the extension. To do so, open Visual Studio Code, ensure that the extension is installed, and sign in using the menu (Ctrl+Shift+P), and select the "Azure: Sign In" option to open a browser window and sign in to Azure. Alternatively, you can select "Azure: Sign In with Device Code" to use the device code flow. + +After signing in, you may need to select a subscription (for example, if you have multiple Azure subscriptions), and you can change the active subscription by using the menu to select the "Azure: Select Subscriptions" entry. + +## Examples + +Once the extension is registered, you can use `VisualStudioCodeCredential` in a similar fashion to the other credential classes in `@azure/identity`: + +```typescript +import { useIdentityExtension, VisualStudioCodeCredential } from "@azure/identity"; +import { vsCodeExtension } from "@azure/identity-vscode"; + +useIdentityExtension(vsCodeExtension); + +async function main() { + const credential = new VisualStudioCodeCredential(); + + // The graph.microsoft.com scope is used as an example + const scope = "https://graph.microsoft.com/.default"; + + // Print out part of the access token + console.log((await credential.getToken(scope)).token.substr(0, 10), "..."); +} + +main().catch((error) => { + console.error("An error occurred:", error); + process.exit(1); +}); +``` + +You can also use `DefaultAzureCredential`, which will attempt to authenticate using the "Azure Account" extension for Visual Studio Code if it is available: + +```typescript +import { useIdentityExtension, DefaultAzureCredential } from "@azure/identity"; +import { vsCodeExtension } from "@azure/identity-vscode"; + +useIdentityExtension(vsCodeExtension); + +async function main() { + // With the extension enabled above, `DefaultAzureCredential` will use + // Visual Studio Code's "Azure Account" extension to authenticate if + // it is available. + const credential = new DefaultAzureCredential(); + + // This will print a JWT access_token and its expiration timestamp + // The graph.microsoft.com scope is used as an example + console.log("Token:", await credential.getToken("https://graph.microsoft.com/.default")); +} + +main().catch((error) => { + console.error("An error occurred:", error); + process.exit(1); +}); +``` + +## Troubleshooting + +### Logging + +Enabling logging may help uncover useful information about failures. In order to see a log of HTTP requests and responses, set the `AZURE_LOG_LEVEL` environment variable to `info`. Alternatively, logging can be enabled at runtime by calling `setLogLevel` in the `@azure/logger`: + +```javascript +import { setLogLevel } from "@azure/logger"; + +setLogLevel("info"); +``` + +## Next steps + +### Provide Feedback + +If you encounter bugs or have suggestions, please [open an issue](https://github.com/Azure/azure-sdk-for-js/issues). + +## Contributing + +If you'd like to contribute to this library, please read the [contributing guide](https://github.com/Azure/azure-sdk-for-js/blob/main/CONTRIBUTING.md) to learn more about how to build and test the code. + +[azaccountext]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.azure-account + +![Impressions](https://azure-sdk-impressions.azurewebsites.net/api/impressions/azure-sdk-for-js%2Fsdk%2Fidentity%2Fidentity%2FREADME.png) diff --git a/sdk/identity/identity-vscode/api-extractor.json b/sdk/identity/identity-vscode/api-extractor.json new file mode 100644 index 000000000000..52d0268dd182 --- /dev/null +++ b/sdk/identity/identity-vscode/api-extractor.json @@ -0,0 +1,31 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", + "mainEntryPointFilePath": "./types/identity-vscode/src/index.d.ts", + "docModel": { + "enabled": true + }, + "apiReport": { + "enabled": true, + "reportFolder": "./review" + }, + "dtsRollup": { + "enabled": true, + "untrimmedFilePath": "", + "publicTrimmedFilePath": "./types/identity-vscode.d.ts" + }, + "messages": { + "tsdocMessageReporting": { + "default": { + "logLevel": "none" + } + }, + "extractorMessageReporting": { + "ae-missing-release-tag": { + "logLevel": "none" + }, + "ae-unresolved-link": { + "logLevel": "none" + } + } + } +} diff --git a/sdk/identity/identity-vscode/package.json b/sdk/identity/identity-vscode/package.json new file mode 100644 index 000000000000..1fbe791f863a --- /dev/null +++ b/sdk/identity/identity-vscode/package.json @@ -0,0 +1,98 @@ +{ + "name": "@azure/identity-vscode", + "version": "1.0.0-beta.1", + "description": "Use the Azure Account extension for Visual Studio Code to authenticate with Azure Identity", + "main": "dist/index.js", + "module": "dist-esm/identity-vscode/src/index.js", + "types": "./types/identity-vscode.d.ts", + "scripts": { + "audit": "node ../../../common/scripts/rush-audit.js && rimraf node_modules package-lock.json && npm i --package-lock-only 2>&1 && npm audit", + "build:samples": "echo skipped", + "build:test": "tsc -p . && rollup -c rollup.config.js 2>&1", + "build": "npm run extract-api && tsc -p . && rollup -c 2>&1", + "check-format": "prettier --list-different --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\" \"samples-dev/**/*.ts\"", + "clean": "rimraf dist dist-* typings *.tgz *.log", + "execute:samples": "echo skipped", + "extract-api": "tsc -p . && api-extractor run --local", + "format": "prettier --write --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\" \"samples-dev/**/*.ts\"", + "integration-test:browser": "echo skipped", + "integration-test:node": "echo skipped", + "integration-test": "npm run integration-test:node && npm run integration-test:browser", + "lint:fix": "eslint package.json api-extractor.json src test --ext .ts --fix --fix-type [problem,suggestion]", + "lint": "eslint package.json api-extractor.json src test --ext .ts", + "pack": "npm pack 2>&1", + "prebuild": "npm run clean", + "test:browser": "npm run clean && npm run build:test && npm run unit-test:browser && npm run integration-test:browser", + "test:node": "npm run clean && npm run build:test && npm run unit-test:node && npm run integration-test:node", + "test": "npm run clean && npm run build:test && npm run unit-test && npm run integration-test", + "unit-test:browser": "echo skipped", + "unit-test:node": "mocha -r esm -r ts-node/register --reporter ../../../common/tools/mocha-multi-reporter.js --timeout 180000 --full-trace --exclude \"test/**/browser/**/*.spec.ts\" \"test/**/*.spec.ts\"", + "unit-test": "npm run unit-test:node && npm run unit-test:browser", + "docs": "typedoc --excludePrivate --excludeNotExported --excludeExternals --stripInternal --mode file --out ./dist/docs ./src" + }, + "files": [ + "dist/", + "dist-esm/identity/src", + "dist-esm/identity-vscode/src", + "types/identity-vscode.d.ts", + "README.md", + "LICENSE" + ], + "engines": { + "node": ">=12.0.0" + }, + "repository": "github:Azure/azure-sdk-for-js", + "keywords": [ + "azure", + "cloud", + "active directory", + "authentication", + "credential", + "certificate", + "vscode", + "account" + ], + "author": "Microsoft Corporation", + "license": "MIT", + "bugs": { + "url": "https://github.com/Azure/azure-sdk-for-js/issues" + }, + "engine": { + "node": ">=12.0.0" + }, + "homepage": "https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/identity/identity-vscode/README.md", + "sideEffects": false, + "dependencies": { + "@azure/identity": "^2.0.0-beta.4", + "keytar": "^7.6.0", + "tslib": "^2.2.0" + }, + "devDependencies": { + "@azure/eslint-plugin-azure-sdk": "^3.0.0", + "@azure/dev-tool": "^1.0.0", + "@azure/test-utils-recorder": "^1.0.0", + "@microsoft/api-extractor": "7.7.11", + "@types/jws": "^3.2.2", + "@types/mocha": "^7.0.2", + "@types/node": "^8.0.0", + "@types/qs": "^6.5.3", + "@types/sinon": "^9.0.4", + "@types/uuid": "^8.0.0", + "assert": "^1.4.1", + "cross-env": "^7.0.2", + "dotenv": "^8.2.0", + "eslint": "^7.15.0", + "inherits": "^2.0.3", + "mocha": "^7.1.1", + "mocha-junit-reporter": "^1.18.0", + "mock-fs": "^4.10.4", + "prettier": "^1.16.4", + "puppeteer": "^3.3.0", + "rimraf": "^3.0.0", + "rollup": "^1.16.3", + "sinon": "^9.0.2", + "typedoc": "0.15.2", + "typescript": "~4.2.0", + "util": "^0.12.1" + } +} diff --git a/sdk/identity/identity-vscode/recordings/node/visualstudiocodecredential/recording_successfully_gets_a_token.js b/sdk/identity/identity-vscode/recordings/node/visualstudiocodecredential/recording_successfully_gets_a_token.js new file mode 100644 index 000000000000..b750f17a15ab --- /dev/null +++ b/sdk/identity/identity-vscode/recordings/node/visualstudiocodecredential/recording_successfully_gets_a_token.js @@ -0,0 +1,38 @@ +let nock = require('nock'); + +module.exports.hash = "1c4d58b38fd9e805bcc6c90e143ce993"; + +module.exports.testInfo = {"uniqueName":{},"newDate":{}} + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .post('/common/oauth2/v2.0/token', "grant_type=refresh_token&client_id=aebc6443-996d-45c2-90f0-388ff96faa56&refresh_token=refresh_token&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default%20offline_access") + .reply(200, {"token_type":"Bearer","scope":"email openid profile https://graph.microsoft.com/Mail.ReadWrite https://graph.microsoft.com/Mail.Send https://graph.microsoft.com/Tasks.ReadWrite https://graph.microsoft.com/User.Read https://graph.microsoft.com/.default","expires_in":3599,"ext_expires_in":3599,"access_token":"access_token","refresh_token":"refresh_token"}, [ + 'Cache-Control', + 'no-store, no-cache', + 'Pragma', + 'no-cache', + 'Content-Type', + 'application/json; charset=utf-8', + 'Expires', + '-1', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + 'd8a6162d-b070-4f8b-bcf6-34a6faee0600', + 'x-ms-ests-server', + '2.1.11787.15 - WUS2 ProdSlices', + 'Set-Cookie', + 'fpc=fpc;; expires=Thu, 15-Jul-2021 01:45:15 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Tue, 15 Jun 2021 01:45:15 GMT', + 'Content-Length', + '3657' +]); diff --git a/sdk/identity/identity-vscode/review/identity-vscode.api.md b/sdk/identity/identity-vscode/review/identity-vscode.api.md new file mode 100644 index 000000000000..938540060eaa --- /dev/null +++ b/sdk/identity/identity-vscode/review/identity-vscode.api.md @@ -0,0 +1,15 @@ +## API Report File for "@azure/identity-vscode" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +import { IdentityExtension } from '@azure/identity'; + +// @public +export const vsCodeExtension: IdentityExtension; + + +// (No @packageDocumentation comment for this package) + +``` diff --git a/sdk/identity/identity-vscode/rollup.config.js b/sdk/identity/identity-vscode/rollup.config.js new file mode 100644 index 000000000000..5d7deee44c14 --- /dev/null +++ b/sdk/identity/identity-vscode/rollup.config.js @@ -0,0 +1,3 @@ +import { makeConfig } from "@azure/dev-tool/shared-config/rollup"; + +export default makeConfig(require("./package.json")); diff --git a/sdk/identity/identity-vscode/samples-dev/extension.ts b/sdk/identity/identity-vscode/samples-dev/extension.ts new file mode 100644 index 000000000000..ef72c4698a13 --- /dev/null +++ b/sdk/identity/identity-vscode/samples-dev/extension.ts @@ -0,0 +1,39 @@ +// Copyright (c) Microsoft Corporation +// Licensed under the MIT license. + +/** + * In this sample, we use the extension API to provide an implementation of + * `VisualStudioCodeCredential` to the `@azure/identity` package, and we use it + * through the `DefaultAzureCredential` class. Without the extension, the + * credential will simply throw a `CredentialNotFoundError`, and the + * `DefaultAzureCredential` will use a different credential, if one is + * available. + * + * @summary loads the `VisualStudioCodeCredential` extension and uses it through + * `DefaultAzureCredential` + */ + +import { useIdentityExtension, DefaultAzureCredential } from "@azure/identity"; + +// The extension is the package's default export, so you may import and use it +// as any name you like, and simply pass it to `useIdentityExtension`. +import { vsCodeExtension } from "@azure/identity-vscode"; +useIdentityExtension(vsCodeExtension); + +export async function main() { + const credential = new DefaultAzureCredential(); + + // This is the scope we will use to get a token from the AAD token endpoint. + // By default, we'll use the Microsoft Graph scope as an example, but when + // you use the credential with an Azure SDK package, it will configure the + // scope for you automatically. + const scope = process.env.AAD_TEST_SCOPE ?? "https://graph.microsoft.com/.default"; + + // Print out part of the access token + console.log((await credential.getToken(scope)).token.substr(0, 10), "..."); +} + +main().catch((error) => { + console.error("The sample encountered an error:", error); + process.exit(1); +}); diff --git a/sdk/identity/identity-vscode/samples-dev/nodeEnv.ts b/sdk/identity/identity-vscode/samples-dev/nodeEnv.ts new file mode 100644 index 000000000000..1ee058503bb0 --- /dev/null +++ b/sdk/identity/identity-vscode/samples-dev/nodeEnv.ts @@ -0,0 +1,55 @@ +// Copyright (c) Microsoft Corporation +// Licensed under the MIT license. + +/** + * This sample shows an example of how to load the `@azure/identity-vscode` + * extension only in certain environments. As an example, we use the NODE_ENV + * environment variable to determine whether or not to load the extension. + * + * NOTE: The NODE_ENV environment variable is merely a convention, and you are + * responsible for setting it as appropriate, for example, by setting the + * variable at runtime: + * + * ```bash + * $ NODE_ENV="production" node dist/nodeEnv.js + * ``` + * + * @summary uses NODE_ENV to load the extension only in development environments + * @azsdk-weight -10 + */ + +import { useIdentityExtension, DefaultAzureCredential } from "@azure/identity"; + +// Get the environment according to NODE_ENV. If it is not defined, we will +// assume the environment is _not_ a production environment. This may not be +// what you want for your use case. +const isProduction = process.env.NODE_ENV === "production"; + +// We'll load the VisualStudioCodeCredential extension only in non-production +// environments. For your use case, this could be "development" only, but you +// may also have other development environments. You can customize this logic to +// suit your needs. +if (!isProduction) { + const { + vsCodeExtension + } = require("@azure/identity-vscode") as typeof import("@azure/identity-vscode"); + useIdentityExtension(vsCodeExtension); +} + +export async function main() { + const credential = new DefaultAzureCredential(); + + // This is the scope we will use to get a token from the AAD token endpoint. + // By default, we'll use the Microsoft Graph scope as an example, but when + // you use the credential with an Azure SDK package, it will configure the + // scope for you automatically. + const scope = process.env.AAD_TEST_SCOPE ?? "https://graph.microsoft.com/.default"; + + // Print out part of the access token + console.log((await credential.getToken(scope)).token.substr(0, 10), "..."); +} + +main().catch((error) => { + console.error("The sample encountered an error:", error); + process.exit(1); +}); diff --git a/sdk/identity/identity-vscode/src/index.ts b/sdk/identity/identity-vscode/src/index.ts new file mode 100644 index 000000000000..6131f33b0524 --- /dev/null +++ b/sdk/identity/identity-vscode/src/index.ts @@ -0,0 +1,46 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { IdentityExtension } from "@azure/identity"; + +import { AzureExtensionContext } from "../../identity/src/extensions/provider"; + +import keytar from "keytar"; + +const VSCodeServiceName = "VS Code Azure"; + +/** + * An extension that provides the dependencies of `VisualStudioCodeCredential` + * and enables it within `@azure/identity`. The extension API is compatible with + * `@azure/identity` versions 2.0.0 and later. Load this extension using the + * `useIdentityExtension` function, imported from `@azure/identity`. + * + * `VisualStudioCodeCredential` uses the authentication session from the "Azure + * Account" extension in VS Code. + * + * To use this functionality, import `VisualStudioCodeCredential` or + * `DefaultAzureCredential` from `@azure/identity`. If this extension is not + * enabled, then `VisualStudioCodeCredential` will throw a + * `CredentialUnavailableError`, and `DefaultAzureCredential` will not be able + * to use authentication through Visual Studio Code. + * + * Example: + * + * ```typescript + * import { useIdentityExtension, VisualStudioCodeCredential } from "@azure/identity"; + * import { vsCodeExtension } from "@azure/identity-vscode"; + * + * // Load the extension + * useIdentityExtension(vsCodeExtension); + * + * // Now that the extension is loaded, this credential may be used + * const credential = new VisualStudioCodeCredential(); + * ``` + */ +export const vsCodeExtension: IdentityExtension = (context) => { + const { vsCodeCredentialControl } = context as AzureExtensionContext; + + vsCodeCredentialControl.setVsCodeCredentialFinder(() => + keytar.findCredentials(VSCodeServiceName) + ); +}; diff --git a/sdk/identity/identity-vscode/test/public/node/setup.spec.ts b/sdk/identity/identity-vscode/test/public/node/setup.spec.ts new file mode 100644 index 000000000000..b45a9f5b4f07 --- /dev/null +++ b/sdk/identity/identity-vscode/test/public/node/setup.spec.ts @@ -0,0 +1,10 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { vsCodeExtension as extension } from "../../../src"; + +import { useIdentityExtension } from "@azure/identity"; + +before(function() { + useIdentityExtension(extension); +}); diff --git a/sdk/identity/identity-vscode/test/public/node/visualStudioCodeCredential.spec.ts b/sdk/identity/identity-vscode/test/public/node/visualStudioCodeCredential.spec.ts new file mode 100644 index 000000000000..1ec1824e41f5 --- /dev/null +++ b/sdk/identity/identity-vscode/test/public/node/visualStudioCodeCredential.spec.ts @@ -0,0 +1,52 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +/* eslint-disable @typescript-eslint/no-non-null-asserted-optional-chain */ + +import assert from "assert"; +import sinon from "sinon"; + +import { MsalTestCleanup, msalNodeTestSetup } from "../../../../identity/test/msalTestUtils"; +import { VisualStudioCodeCredential } from "@azure/identity"; +import { isRecordMode } from "@azure/test-utils-recorder"; + +const mockedResponse = [ + { + account: "AzureCloud", + password: "refresh_token" + } +]; + +describe("VisualStudioCodeCredential", function(this: Mocha.Suite) { + let cleanup: MsalTestCleanup; + + beforeEach(function(this: Mocha.Context) { + const setup = msalNodeTestSetup(this); + cleanup = setup.cleanup; + }); + + afterEach(async function() { + await cleanup(); + }); + + const scope = "https://graph.microsoft.com/.default"; + + it("successfully gets a token", async () => { + if (!isRecordMode()) { + // In live CI or playback CI, we need to avoid actually using keytar + // to try to read the Azure Account state, since it won't be available + const mock = sinon.mock(require("keytar")); + mock + .expects("findCredentials") + .onFirstCall() + .returns(mockedResponse); + } + + const cred = new VisualStudioCodeCredential(); + + const token = await cred.getToken(scope); + + assert.ok(token.expiresOnTimestamp); + assert.ok(token.token); + }); +}); diff --git a/sdk/identity/identity-vscode/tsconfig.json b/sdk/identity/identity-vscode/tsconfig.json new file mode 100644 index 000000000000..23d8f29b3565 --- /dev/null +++ b/sdk/identity/identity-vscode/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "../../../tsconfig.package", + "compilerOptions": { + "target": "es6", + "lib": ["DOM"], + "declarationDir": "./types", + "outDir": "./dist-esm", + "resolveJsonModule": true, + "paths": { + "@azure/identity-vscode": ["./src/index"] + } + }, + "include": ["src/**/*", "test/**/*", "samples-dev/**/*"] +} diff --git a/sdk/identity/identity-vscode/tsdoc.json b/sdk/identity/identity-vscode/tsdoc.json new file mode 100644 index 000000000000..81c5a8a2aa2f --- /dev/null +++ b/sdk/identity/identity-vscode/tsdoc.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", + "extends": ["../../../tsdoc.json"] +} diff --git a/sdk/identity/identity/CHANGELOG.md b/sdk/identity/identity/CHANGELOG.md index 3fd454807739..7961335e8f85 100644 --- a/sdk/identity/identity/CHANGELOG.md +++ b/sdk/identity/identity/CHANGELOG.md @@ -2,12 +2,20 @@ ## 2.0.0-beta.4 (Unreleased) +### New features + +- Introduced an extension API through a top-level method `useIdentityExtension`. The function accepts an "extension" as an argument, which is a function accepting a `context`. The extension context is an internal part of the Azure Identity API, so it has an `unknown` type. Two new packages are designed to be used with this API: + - `@azure/identity-vscode`, which provides the dependencies of `VisualStudioCodeCredential` and enables it (see more below). + - `@azure/identity-cache-persistence`, which provides persistent token caching (same as was available in version 2.0.0-beta.2, but now provided through a secondary extension package). +- Reintroduced a stub implementation of `VisualStudioCodeCredential`. If the `@azure/identity-vscode` extension is not used, then it will throw a `CredentialUnavailableError` (similar to how it previously behaved if the `keytar` package was not installed). The extension now provides the underlying implementation of `VisualStudioCodeCredential` through dependency injection. +- Reintroduced the `TokenCachePersistenceOptions` property on most credential constructor options. This property must be present with an `enabled` property set to true to enable persistent token caching for a credential instance. Credentials that do not support persistent token caching do not have this property. + ## Bug fixes - Fixed an issue in which `InteractiveBrowserCredential` on Node would sometimes cause the process to hang if there was no browser available. -- Fixed an issue in which the `AZURE_AUTHORITY_HOST` environment variable was not properly picked up in NodeJS. +- Fixed an issue in which the `AZURE_AUTHORITY_HOST` environment variable was not properly picked up in NodeJS. -### Breaking changes +### Breaking changes - Removed the protected method `getAzureCliAccessToken` from the public API of the `AzureCliCredential`. While it will continue to be available as part of v1, we won't be supporting this method as part of v2's public API. diff --git a/sdk/identity/identity/README.md b/sdk/identity/identity/README.md index bf75a7697e02..596d64004edd 100644 --- a/sdk/identity/identity/README.md +++ b/sdk/identity/identity/README.md @@ -4,6 +4,8 @@ The Azure Identity library provides Azure Active Directory token authentication You can find examples for these various credentials in the [Azure Identity Examples Page](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/identity/identity/samples/AzureIdentityExamples.md) +> **Note**: As of `@azure/identity` >=2.0.0, `VisualStudioCodeCredential` now requires a secondary extension package to use. Please see the [`@azure/identity-vscode` package](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/identity/identity-vscode) as well as [the "Extensions" section](#extensions) below for more information. + [Source code](https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/identity/identity) | [Package (npm)](https://www.npmjs.com/package/@azure/identity) | [API Reference Documentation](https://docs.microsoft.com/javascript/api/@azure/identity) | [Product documentation](https://azure.microsoft.com/services/active-directory/) | [Samples](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/identity/identity/samples) ## Getting started @@ -51,7 +53,7 @@ To authenticate with [Azure PowerShell][azure_powershell] users can run the `Con ![Azure PowerShell Account Sign In][azurepowershelllogin_image] -If interactive authnetication cannot be supported in the session, then the `-UseDeviceAuthentication` argument will force the cmdlet to use a device code authentication flow instead, similar to the corresponding option in the Azure CLI credential. +If interactive authentication cannot be supported in the session, then the `-UseDeviceAuthentication` argument will force the cmdlet to use a device code authentication flow instead, similar to the corresponding option in the Azure CLI credential. ### Authenticate the client in browsers @@ -84,6 +86,13 @@ If used from NodeJS, the `DefaultAzureCredential` will attempt to authenticate v - Azure CLI - If the developer has authenticated an account via the Azure CLI `az login` command, the `DefaultAzureCredential` will authenticate with that account. - Azure PowerShell - If the developer has authenticated using the Azure PowerShell module `Connect-AzAccount` command, the `DefaultAzureCredential` will authenticate with that account. +### Extensions + +Azure Identity for JavaScript provides an extension API that allows us to provide certain functionality through separate _extension packages_. The `@azure/identity` package exports a top-level function (`useIdentityExtension`) that can be used to enable an extension, and we provide two extension packages: + +- [`@azure/identity-cache-persistence`](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/identity/identity-cache-persistence), which provides persistent token caching in Node.js using a native secure storage system provided by your operating system. This extension allows cached `access_token` values to persist across sessions, meaning that an interactive login flow does not need to be repeated as long as a cached token is available. +- [`@azure/identity-vscode](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/identity/identity-vscode), which provides the dependencies of `VisualStudioCodeCredential` and enables it. Without this extension, the `VisualStudioCodeCredential` in this package will throw a `CredentialUnavailableError`. The extension provides the underlying implementation of this credential, enabling it for use both on its own and as part of the `DefaultAzureCredential` described above. + ## Environment Variables `DefaultAzureCredential` and `EnvironmentCredential` can be configured with environment variables. Each type of authentication requires values for specific variables: @@ -203,10 +212,10 @@ For examples of how to use managed identity for authentication please refer to [ ### Authenticating via Development Tools -| credential | usage | example | reference | -| ---------------------------- | ------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | -| `AzureCliCredential` | Authenticate in a development environment with the Azure CLI. | [example](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/identity/identity/samples/AzureIdentityExamples.md#authenticating-a-user-account-with-azure-cli) | [Azure CLI authentication](https://docs.microsoft.com/cli/azure/authenticate-azure-cli) | -| `AzurePowerShellCredential` | Authenticate in a development environment using Azure PowerShell. | [example](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/identity/identity/samples/AzureIdentityExamples.md#authenticating-a-user-account-with-azure-powershell) | [Azure PowerShell authentication](https://docs.microsoft.com/powershell/azure/authenticate-azureps) | +| credential | usage | example | reference | +| --------------------------- | ----------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- | +| `AzureCliCredential` | Authenticate in a development environment with the Azure CLI. | [example](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/identity/identity/samples/AzureIdentityExamples.md#authenticating-a-user-account-with-azure-cli) | [Azure CLI authentication](https://docs.microsoft.com/cli/azure/authenticate-azure-cli) | +| `AzurePowerShellCredential` | Authenticate in a development environment using Azure PowerShell. | [example](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/identity/identity/samples/AzureIdentityExamples.md#authenticating-a-user-account-with-azure-powershell) | [Azure PowerShell authentication](https://docs.microsoft.com/powershell/azure/authenticate-azureps) | ## Troubleshooting diff --git a/sdk/identity/identity/package.json b/sdk/identity/identity/package.json index e703e3ce1622..5c799d94f7b4 100644 --- a/sdk/identity/identity/package.json +++ b/sdk/identity/identity/package.json @@ -20,7 +20,8 @@ "./dist-esm/src/credentials/usernamePasswordCredential.js": "./dist-esm/src/credentials/usernamePasswordCredential.browser.js", "./dist-esm/src/credentials/azurePowerShellCredential.js": "./dist-esm/src/credentials/azurePowerShellCredential.browser.js", "./dist-esm/src/util/authHostEnv.js": "./dist-esm/src/util/authHostEnv.browser.js", - "./dist-esm/src/tokenCache/TokenCachePersistence.js": "./dist-esm/src/tokenCache/TokenCachePersistence.browser.js" + "./dist-esm/src/tokenCache/TokenCachePersistence.js": "./dist-esm/src/tokenCache/TokenCachePersistence.browser.js", + "./dist-esm/src/extensions/consumer.js": "./dist-esm/src/extensions/consumer.browser.js" }, "scripts": { "audit": "node ../../../common/scripts/rush-audit.js && rimraf node_modules package-lock.json && npm i --package-lock-only 2>&1 && npm audit", @@ -78,6 +79,7 @@ "homepage": "https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/identity/identity/README.md", "sideEffects": false, "dependencies": { + "@azure/core-auth": "^1.3.0", "@azure/core-http": "^1.2.0", "@azure/core-tracing": "1.0.0-preview.12", "@azure/logger": "^1.0.0", diff --git a/sdk/identity/identity/review/identity.api.md b/sdk/identity/identity/review/identity.api.md index 4f2152d01d2a..10e053664152 100644 --- a/sdk/identity/identity/review/identity.api.md +++ b/sdk/identity/identity/review/identity.api.md @@ -4,11 +4,11 @@ ```ts -import { AccessToken } from '@azure/core-http'; +import { AccessToken } from '@azure/core-auth'; import { AzureLogger } from '@azure/logger'; -import { GetTokenOptions } from '@azure/core-http'; +import { GetTokenOptions } from '@azure/core-auth'; import { PipelineOptions } from '@azure/core-http'; -import { TokenCredential } from '@azure/core-http'; +import { TokenCredential } from '@azure/core-auth'; export { AccessToken } @@ -91,7 +91,7 @@ export class ClientCertificateCredential implements TokenCredential { } // @public -export interface ClientCertificateCredentialOptions extends TokenCredentialOptions { +export interface ClientCertificateCredentialOptions extends TokenCredentialOptions, CredentialPersistenceOptions { regionalAuthority?: string; sendCertificateChain?: boolean; } @@ -103,10 +103,15 @@ export class ClientSecretCredential implements TokenCredential { } // @public -export interface ClientSecretCredentialOptions extends TokenCredentialOptions { +export interface ClientSecretCredentialOptions extends TokenCredentialOptions, CredentialPersistenceOptions { regionalAuthority?: string; } +// @public +export interface CredentialPersistenceOptions { + tokenCachePersistenceOptions?: TokenCachePersistenceOptions; +} + // @public export class CredentialUnavailableError extends Error { constructor(message?: string); @@ -121,7 +126,7 @@ export class DefaultAzureCredential extends ChainedTokenCredential { } // @public -export interface DefaultAzureCredentialOptions extends TokenCredentialOptions { +export interface DefaultAzureCredentialOptions extends TokenCredentialOptions, CredentialPersistenceOptions { managedIdentityClientId?: string; tenantId?: string; } @@ -137,7 +142,7 @@ export class DeviceCodeCredential implements TokenCredential { } // @public -export interface DeviceCodeCredentialOptions extends InteractiveCredentialOptions { +export interface DeviceCodeCredentialOptions extends InteractiveCredentialOptions, CredentialPersistenceOptions { clientId?: string; tenantId?: string; userPromptCallback?: DeviceCodePromptCallback; @@ -155,10 +160,14 @@ export type DeviceCodePromptCallback = (deviceCodeInfo: DeviceCodeInfo) => void; // @public export class EnvironmentCredential implements TokenCredential { - constructor(options?: TokenCredentialOptions); + constructor(options?: EnvironmentCredentialOptions); getToken(scopes: string | string[], options?: GetTokenOptions): Promise; } +// @public +export interface EnvironmentCredentialOptions extends TokenCredentialOptions, CredentialPersistenceOptions { +} + // @public export interface ErrorResponse { correlationId?: string; @@ -174,6 +183,9 @@ export function getDefaultAzureCredential(): TokenCredential; export { GetTokenOptions } +// @public +export type IdentityExtension = (context: unknown) => void; + // @public export class InteractiveBrowserCredential implements TokenCredential { constructor(options?: InteractiveBrowserCredentialOptions | InteractiveBrowserCredentialBrowserOptions); @@ -182,19 +194,19 @@ export class InteractiveBrowserCredential implements TokenCredential { } // @public -export type InteractiveBrowserCredentialBrowserOptions = TokenCredentialOptions & InteractiveCredentialOptions & { - redirectUri?: string | (() => string); - tenantId?: string; +export interface InteractiveBrowserCredentialBrowserOptions extends InteractiveCredentialOptions { clientId: string; loginStyle?: BrowserLoginStyle; -}; + redirectUri?: string | (() => string); + tenantId?: string; +} // @public -export type InteractiveBrowserCredentialOptions = TokenCredentialOptions & InteractiveCredentialOptions & { +export interface InteractiveBrowserCredentialOptions extends InteractiveCredentialOptions, CredentialPersistenceOptions { + clientId?: string; redirectUri?: string | (() => string); tenantId?: string; - clientId?: string; -}; +} // @public export interface InteractiveCredentialOptions extends TokenCredentialOptions { @@ -272,6 +284,13 @@ export enum RegionalAuthority { // @public export function serializeAuthenticationRecord(record: AuthenticationRecord): string; +// @public +export interface TokenCachePersistenceOptions { + allowUnencryptedStorage?: boolean; + enabled: boolean; + name?: string; +} + export { TokenCredential } // @public @@ -279,6 +298,9 @@ export interface TokenCredentialOptions extends PipelineOptions { authorityHost?: string; } +// @public +export function useIdentityExtension(extension: IdentityExtension): void; + // @public export class UsernamePasswordCredential implements TokenCredential { constructor(tenantId: string, clientId: string, username: string, password: string, options?: UsernamePasswordCredentialOptions); @@ -286,7 +308,18 @@ export class UsernamePasswordCredential implements TokenCredential { } // @public -export interface UsernamePasswordCredentialOptions extends TokenCredentialOptions { +export interface UsernamePasswordCredentialOptions extends TokenCredentialOptions, CredentialPersistenceOptions { +} + +// @public +export class VisualStudioCodeCredential implements TokenCredential { + constructor(options?: VisualStudioCodeCredentialOptions); + getToken(scopes: string | string[], _options?: GetTokenOptions): Promise; + } + +// @public +export interface VisualStudioCodeCredentialOptions extends TokenCredentialOptions { + tenantId?: string; } diff --git a/sdk/identity/identity/src/client/identityClient.ts b/sdk/identity/identity/src/client/identityClient.ts index 063955a18d62..7b107439a1d0 100644 --- a/sdk/identity/identity/src/client/identityClient.ts +++ b/sdk/identity/identity/src/client/identityClient.ts @@ -26,7 +26,6 @@ const noCorrelationId = "noCorrelationId"; /** * An internal type used to communicate details of a token request's * response that should not be sent back as part of the access token. - * @internal */ export interface TokenResponse { /** @@ -62,7 +61,6 @@ export function getIdentityClientAuthorityHost(options?: TokenCredentialOptions) * It allows for credentials to abort any pending request independently of the MSAL flow, * by calling to the `abortRequests()` method. * - * @internal */ export class IdentityClient extends ServiceClient implements INetworkModule { public authorityHost: string; diff --git a/sdk/identity/identity/src/credentials/authorizationCodeCredential.browser.ts b/sdk/identity/identity/src/credentials/authorizationCodeCredential.browser.ts index 44e9169b30b0..364afd8b852f 100644 --- a/sdk/identity/identity/src/credentials/authorizationCodeCredential.browser.ts +++ b/sdk/identity/identity/src/credentials/authorizationCodeCredential.browser.ts @@ -1,7 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { TokenCredential, AccessToken } from "@azure/core-http"; +import { TokenCredential, AccessToken } from "@azure/core-auth"; + import { TokenCredentialOptions } from "../client/identityClient"; import { credentialLogger, formatError } from "../util/logging"; diff --git a/sdk/identity/identity/src/credentials/authorizationCodeCredential.ts b/sdk/identity/identity/src/credentials/authorizationCodeCredential.ts index e976bfee7b30..8bcd49b4204e 100644 --- a/sdk/identity/identity/src/credentials/authorizationCodeCredential.ts +++ b/sdk/identity/identity/src/credentials/authorizationCodeCredential.ts @@ -2,9 +2,11 @@ // Licensed under the MIT license. import qs from "qs"; + +import { TokenCredential, GetTokenOptions, AccessToken } from "@azure/core-auth"; + import { createSpan } from "../util/tracing"; import { CredentialUnavailableError } from "../client/errors"; -import { TokenCredential, GetTokenOptions, AccessToken } from "@azure/core-http"; import { IdentityClient, TokenResponse, TokenCredentialOptions } from "../client/identityClient"; import { SpanStatusCode } from "@azure/core-tracing"; import { credentialLogger, formatSuccess, formatError } from "../util/logging"; diff --git a/sdk/identity/identity/src/credentials/azureCliCredential.browser.ts b/sdk/identity/identity/src/credentials/azureCliCredential.browser.ts index fb9259da24f3..501ee08e4568 100644 --- a/sdk/identity/identity/src/credentials/azureCliCredential.browser.ts +++ b/sdk/identity/identity/src/credentials/azureCliCredential.browser.ts @@ -1,7 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { AccessToken, TokenCredential } from "@azure/core-http"; +import { AccessToken, TokenCredential } from "@azure/core-auth"; + import { credentialLogger, formatError } from "../util/logging"; const BrowserNotSupportedError = new Error("AzureCliCredential is not supported in the browser."); diff --git a/sdk/identity/identity/src/credentials/azureCliCredential.ts b/sdk/identity/identity/src/credentials/azureCliCredential.ts index 7fa8e9332f85..5750a37a0ad7 100644 --- a/sdk/identity/identity/src/credentials/azureCliCredential.ts +++ b/sdk/identity/identity/src/credentials/azureCliCredential.ts @@ -1,7 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { TokenCredential, GetTokenOptions, AccessToken } from "@azure/core-http"; +import { TokenCredential, GetTokenOptions, AccessToken } from "@azure/core-auth"; + import { createSpan } from "../util/tracing"; import { CredentialUnavailableError } from "../client/errors"; import { SpanStatusCode } from "@azure/core-tracing"; diff --git a/sdk/identity/identity/src/credentials/azurePowerShellCredential.browser.ts b/sdk/identity/identity/src/credentials/azurePowerShellCredential.browser.ts index ebf66ebff972..f1ddbc2b9a9e 100644 --- a/sdk/identity/identity/src/credentials/azurePowerShellCredential.browser.ts +++ b/sdk/identity/identity/src/credentials/azurePowerShellCredential.browser.ts @@ -1,7 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { TokenCredential, AccessToken } from "@azure/core-http"; +import { TokenCredential, AccessToken } from "@azure/core-auth"; + import { credentialLogger, formatError } from "../util/logging"; const BrowserNotSupportedError = new Error( diff --git a/sdk/identity/identity/src/credentials/azurePowerShellCredential.ts b/sdk/identity/identity/src/credentials/azurePowerShellCredential.ts index eb1783bd3746..59a8d3e7e196 100644 --- a/sdk/identity/identity/src/credentials/azurePowerShellCredential.ts +++ b/sdk/identity/identity/src/credentials/azurePowerShellCredential.ts @@ -1,7 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { TokenCredential, GetTokenOptions, AccessToken } from "@azure/core-http"; +import { TokenCredential, GetTokenOptions, AccessToken } from "@azure/core-auth"; + import { CredentialUnavailableError } from "../client/errors"; import { credentialLogger, formatSuccess, formatError } from "../util/logging"; import { trace } from "../util/tracing"; diff --git a/sdk/identity/identity/src/credentials/chainedTokenCredential.ts b/sdk/identity/identity/src/credentials/chainedTokenCredential.ts index 739f55338700..d8ca5388ed23 100644 --- a/sdk/identity/identity/src/credentials/chainedTokenCredential.ts +++ b/sdk/identity/identity/src/credentials/chainedTokenCredential.ts @@ -1,7 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { AccessToken, TokenCredential, GetTokenOptions } from "@azure/core-http"; +import { AccessToken, TokenCredential, GetTokenOptions } from "@azure/core-auth"; + import { AggregateAuthenticationError, CredentialUnavailableError } from "../client/errors"; import { createSpan } from "../util/tracing"; import { SpanStatusCode } from "@azure/core-tracing"; diff --git a/sdk/identity/identity/src/credentials/clientCertificateCredential.browser.ts b/sdk/identity/identity/src/credentials/clientCertificateCredential.browser.ts index 0f772315c5e9..ff14581a9e50 100644 --- a/sdk/identity/identity/src/credentials/clientCertificateCredential.browser.ts +++ b/sdk/identity/identity/src/credentials/clientCertificateCredential.browser.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { TokenCredential, AccessToken } from "@azure/core-http"; +import { TokenCredential, AccessToken } from "@azure/core-auth"; import { credentialLogger, formatError } from "../util/logging"; const BrowserNotSupportedError = new Error( diff --git a/sdk/identity/identity/src/credentials/clientCertificateCredential.ts b/sdk/identity/identity/src/credentials/clientCertificateCredential.ts index 392cf5ecdf64..595739d3d3e1 100644 --- a/sdk/identity/identity/src/credentials/clientCertificateCredential.ts +++ b/sdk/identity/identity/src/credentials/clientCertificateCredential.ts @@ -1,7 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { AccessToken, GetTokenOptions, TokenCredential } from "@azure/core-http"; +import { AccessToken, GetTokenOptions, TokenCredential } from "@azure/core-auth"; + import { MsalClientCertificate } from "../msal/nodeFlows/msalClientCertificate"; import { credentialLogger } from "../util/logging"; import { trace } from "../util/tracing"; diff --git a/sdk/identity/identity/src/credentials/clientCertificateCredentialOptions.ts b/sdk/identity/identity/src/credentials/clientCertificateCredentialOptions.ts index 74c149a2f6dd..42dc5a0d6910 100644 --- a/sdk/identity/identity/src/credentials/clientCertificateCredentialOptions.ts +++ b/sdk/identity/identity/src/credentials/clientCertificateCredentialOptions.ts @@ -2,11 +2,14 @@ // Licensed under the MIT license. import { TokenCredentialOptions } from "../client/identityClient"; +import { CredentialPersistenceOptions } from "./credentialPersistenceOptions"; /** * Optional parameters for the {@link ClientCertificateCredential} class. */ -export interface ClientCertificateCredentialOptions extends TokenCredentialOptions { +export interface ClientCertificateCredentialOptions + extends TokenCredentialOptions, + CredentialPersistenceOptions { /** * Option to include x5c header for SubjectName and Issuer name authorization. * Set this option to send base64 encoded public certificate in the client assertion header as an x5c claim diff --git a/sdk/identity/identity/src/credentials/clientSecretCredential.browser.ts b/sdk/identity/identity/src/credentials/clientSecretCredential.browser.ts index b4b2c308c7a2..ed941edad125 100644 --- a/sdk/identity/identity/src/credentials/clientSecretCredential.browser.ts +++ b/sdk/identity/identity/src/credentials/clientSecretCredential.browser.ts @@ -2,7 +2,9 @@ // Licensed under the MIT license. import qs from "qs"; -import { TokenCredential, GetTokenOptions, AccessToken } from "@azure/core-http"; + +import { TokenCredential, GetTokenOptions, AccessToken } from "@azure/core-auth"; + import { TokenCredentialOptions, IdentityClient } from "../client/identityClient"; import { createSpan } from "../util/tracing"; import { SpanStatusCode } from "@azure/core-tracing"; diff --git a/sdk/identity/identity/src/credentials/clientSecretCredential.ts b/sdk/identity/identity/src/credentials/clientSecretCredential.ts index 9286ac21ab28..4e1a2d942e0a 100644 --- a/sdk/identity/identity/src/credentials/clientSecretCredential.ts +++ b/sdk/identity/identity/src/credentials/clientSecretCredential.ts @@ -1,7 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { AccessToken, GetTokenOptions, TokenCredential } from "@azure/core-http"; +import { AccessToken, GetTokenOptions, TokenCredential } from "@azure/core-auth"; + import { MsalClientSecret } from "../msal/nodeFlows/msalClientSecret"; import { credentialLogger } from "../util/logging"; import { trace } from "../util/tracing"; diff --git a/sdk/identity/identity/src/credentials/clientSecretCredentialOptions.ts b/sdk/identity/identity/src/credentials/clientSecretCredentialOptions.ts index 83a4694abb4b..8cc4e68c1d50 100644 --- a/sdk/identity/identity/src/credentials/clientSecretCredentialOptions.ts +++ b/sdk/identity/identity/src/credentials/clientSecretCredentialOptions.ts @@ -2,11 +2,14 @@ // Licensed under the MIT license. import { TokenCredentialOptions } from "../client/identityClient"; +import { CredentialPersistenceOptions } from "./credentialPersistenceOptions"; /** * Optional parameters for the {@link ClientSecretCredential} class. */ -export interface ClientSecretCredentialOptions extends TokenCredentialOptions { +export interface ClientSecretCredentialOptions + extends TokenCredentialOptions, + CredentialPersistenceOptions { /** * Specifies a regional authority. Please refer to the {@link RegionalAuthority} type for the accepted values. * If {@link RegionalAuthority.AutoDiscoverRegion} is specified, we will try to discover the regional authority endpoint. diff --git a/sdk/identity/identity/src/credentials/credentialPersistenceOptions.ts b/sdk/identity/identity/src/credentials/credentialPersistenceOptions.ts new file mode 100644 index 000000000000..ca5e749c0870 --- /dev/null +++ b/sdk/identity/identity/src/credentials/credentialPersistenceOptions.ts @@ -0,0 +1,42 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { TokenCachePersistenceOptions } from "../msal/nodeFlows/tokenCachePersistenceOptions"; + +/** + * Shared configuration options for credentials that support persistent token + * caching. + */ +export interface CredentialPersistenceOptions { + /** + * Options to provide to the persistence layer (if one is available) when + * storing credentials. + * + * You must first register a persistence provider as an extension. See the + * `@azure/identity-cache-persistence` package on NPM. + * + * Example: + * + * ```typescript + * import persistence from "@azure/identity-cache-persistence"; + * import { useIdentityExtension, DeviceCodeCredential } from "@azure/identity"; + * + * useIdentityExtension(persistence); + * + * async function main() { + * const credential = new DeviceCodeCredential({ + * tokenCachePersistenceOptions: { + * name: "mycustomcachename" + * } + * }); + * } + * + * main().catch((error) => { + * console.error("An error occured:", error); + * process.exit(1); + * }); + * ``` +- */ + + tokenCachePersistenceOptions?: TokenCachePersistenceOptions; +} diff --git a/sdk/identity/identity/src/credentials/defaultAzureCredential.browser.ts b/sdk/identity/identity/src/credentials/defaultAzureCredential.browser.ts index 0632d4399020..7a08a8cf0b9d 100644 --- a/sdk/identity/identity/src/credentials/defaultAzureCredential.browser.ts +++ b/sdk/identity/identity/src/credentials/defaultAzureCredential.browser.ts @@ -1,7 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { AccessToken } from "@azure/core-http"; +import { AccessToken } from "@azure/core-auth"; + import { TokenCredentialOptions } from "../client/identityClient"; import { credentialLogger, formatError } from "../util/logging"; import { ChainedTokenCredential } from "./chainedTokenCredential"; diff --git a/sdk/identity/identity/src/credentials/defaultAzureCredential.ts b/sdk/identity/identity/src/credentials/defaultAzureCredential.ts index d07319be6370..1bbbda2020b5 100644 --- a/sdk/identity/identity/src/credentials/defaultAzureCredential.ts +++ b/sdk/identity/identity/src/credentials/defaultAzureCredential.ts @@ -1,17 +1,25 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. +import { TokenCredential } from "@azure/core-auth"; + import { TokenCredentialOptions } from "../client/identityClient"; + import { ChainedTokenCredential } from "./chainedTokenCredential"; -import { EnvironmentCredential } from "./environmentCredential"; -import { ManagedIdentityCredential } from "./managedIdentityCredential"; + import { AzureCliCredential } from "./azureCliCredential"; import { AzurePowerShellCredential } from "./azurePowerShellCredential"; +import { EnvironmentCredential } from "./environmentCredential"; +import { ManagedIdentityCredential } from "./managedIdentityCredential"; +import { CredentialPersistenceOptions } from "./credentialPersistenceOptions"; +import { VisualStudioCodeCredential } from "./visualStudioCodeCredential"; /** * Provides options to configure the {@link DefaultAzureCredential} class. */ -export interface DefaultAzureCredentialOptions extends TokenCredentialOptions { +export interface DefaultAzureCredentialOptions + extends TokenCredentialOptions, + CredentialPersistenceOptions { /** * Optionally pass in a Tenant ID to be used as part of the credential. * By default it may use a generic tenant ID depending on the underlying credential. @@ -25,16 +33,59 @@ export interface DefaultAzureCredentialOptions extends TokenCredentialOptions { } /** - * Provides a default {@link ChainedTokenCredential} configuration that should work for most applications that use the Azure SDK. - * The following credential types will be tried, in order: + * The type of a class that implements TokenCredential and accepts + * `DefaultAzureCredentialOptions`. + */ +interface DefaultCredentialConstructor { + new (options?: DefaultAzureCredentialOptions): TokenCredential; +} + +/** + * A shim around ManagedIdentityCredential that adapts it to accept + * `DefaultAzureCredentialOptions`. + * + * @internal + */ +class DefaultManagedIdentityCredential extends ManagedIdentityCredential { + constructor(options?: DefaultAzureCredentialOptions) { + const managedIdentityClientId = options?.managedIdentityClientId ?? process.env.AZURE_CLIENT_ID; + if (managedIdentityClientId !== undefined) { + super(managedIdentityClientId, options); + } else { + super(options); + } + } +} + +export const defaultCredentials: DefaultCredentialConstructor[] = [ + EnvironmentCredential, + DefaultManagedIdentityCredential, + VisualStudioCodeCredential, + AzureCliCredential, + AzurePowerShellCredential +]; + +/** + * Provides a default {@link ChainedTokenCredential} configuration that should + * work for most applications that use the Azure SDK. The following credential + * types will be tried, in order: * * - {@link EnvironmentCredential} * - {@link ManagedIdentityCredential} + * - {@link VisualStudioCodeCredential} * - {@link AzureCliCredential} * - {@link AzurePowerShellCredential} * * Consult the documentation of these credential types for more information * on how they attempt authentication. + * + * **Note**: `VisualStudioCodeCredential` is provided by an extension package: + * `@azure/identity-vscode`. If this package is not installed and registered + * using the extension API (`useIdentityExtension`), then authentication using + * `VisualStudioCodeCredential` will not be available. + * + * Azure Identity extensions may add credential types to the default credential + * stack. */ export class DefaultAzureCredential extends ChainedTokenCredential { /** @@ -43,24 +94,7 @@ export class DefaultAzureCredential extends ChainedTokenCredential { * @param options - Optional parameters. See {@link DefaultAzureCredentialOptions}. */ constructor(options?: DefaultAzureCredentialOptions) { - const credentials = []; - credentials.push(new EnvironmentCredential(options)); - - // A client ID for the ManagedIdentityCredential - // can be provided either through the optional parameters or through the environment variables. - const managedIdentityClientId = options?.managedIdentityClientId || process.env.AZURE_CLIENT_ID; - - // If a client ID is not provided, we will try with the system assigned ID. - if (managedIdentityClientId) { - credentials.push(new ManagedIdentityCredential(managedIdentityClientId, options)); - } else { - credentials.push(new ManagedIdentityCredential(options)); - } - - credentials.push(new AzureCliCredential()); - credentials.push(new AzurePowerShellCredential()); - - super(...credentials); + super(...defaultCredentials.map((ctor) => new ctor(options))); this.UnavailableMessage = "DefaultAzureCredential => failed to retrieve a token from the included credentials"; } diff --git a/sdk/identity/identity/src/credentials/deviceCodeCredential.browser.ts b/sdk/identity/identity/src/credentials/deviceCodeCredential.browser.ts index 2a8b2ac5ef25..811fba10264f 100644 --- a/sdk/identity/identity/src/credentials/deviceCodeCredential.browser.ts +++ b/sdk/identity/identity/src/credentials/deviceCodeCredential.browser.ts @@ -1,7 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { TokenCredential, AccessToken } from "@azure/core-http"; +import { TokenCredential, AccessToken } from "@azure/core-auth"; + import { credentialLogger, formatError } from "../util/logging"; const BrowserNotSupportedError = new Error("DeviceCodeCredential is not supported in the browser."); diff --git a/sdk/identity/identity/src/credentials/deviceCodeCredential.ts b/sdk/identity/identity/src/credentials/deviceCodeCredential.ts index 32ecb2956d33..c817b616f550 100644 --- a/sdk/identity/identity/src/credentials/deviceCodeCredential.ts +++ b/sdk/identity/identity/src/credentials/deviceCodeCredential.ts @@ -1,7 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { AccessToken, GetTokenOptions, TokenCredential } from "@azure/core-http"; +import { AccessToken, GetTokenOptions, TokenCredential } from "@azure/core-auth"; + import { credentialLogger } from "../util/logging"; import { MsalDeviceCode } from "../msal/nodeFlows/msalDeviceCode"; import { MsalFlow } from "../msal/flows"; diff --git a/sdk/identity/identity/src/credentials/deviceCodeCredentialOptions.ts b/sdk/identity/identity/src/credentials/deviceCodeCredentialOptions.ts index a6cc1c5fbedc..e16679b1d448 100644 --- a/sdk/identity/identity/src/credentials/deviceCodeCredentialOptions.ts +++ b/sdk/identity/identity/src/credentials/deviceCodeCredentialOptions.ts @@ -2,6 +2,7 @@ // Licensed under the MIT license. import { InteractiveCredentialOptions } from "./interactiveCredentialOptions"; +import { CredentialPersistenceOptions } from "./credentialPersistenceOptions"; /** * Provides the user code and verification URI where the code must be @@ -37,7 +38,9 @@ export type DeviceCodePromptCallback = (deviceCodeInfo: DeviceCodeInfo) => void; /** * Defines options for the InteractiveBrowserCredential class for NodeJS. */ -export interface DeviceCodeCredentialOptions extends InteractiveCredentialOptions { +export interface DeviceCodeCredentialOptions + extends InteractiveCredentialOptions, + CredentialPersistenceOptions { /** * The Azure Active Directory tenant (directory) ID. */ diff --git a/sdk/identity/identity/src/credentials/environmentCredential.browser.ts b/sdk/identity/identity/src/credentials/environmentCredential.browser.ts index c01020cd49ed..737c084eaef6 100644 --- a/sdk/identity/identity/src/credentials/environmentCredential.browser.ts +++ b/sdk/identity/identity/src/credentials/environmentCredential.browser.ts @@ -1,7 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { AccessToken, TokenCredential } from "@azure/core-http"; +import { AccessToken, TokenCredential } from "@azure/core-auth"; + import { credentialLogger, formatError } from "../util/logging"; const BrowserNotSupportedError = new Error( diff --git a/sdk/identity/identity/src/credentials/environmentCredential.ts b/sdk/identity/identity/src/credentials/environmentCredential.ts index 32c81b045514..4952faa62a63 100644 --- a/sdk/identity/identity/src/credentials/environmentCredential.ts +++ b/sdk/identity/identity/src/credentials/environmentCredential.ts @@ -1,7 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { AccessToken, TokenCredential, GetTokenOptions } from "@azure/core-http"; +import { AccessToken, TokenCredential, GetTokenOptions } from "@azure/core-auth"; + import { credentialLogger, processEnvVars, formatSuccess, formatError } from "../util/logging"; import { TokenCredentialOptions } from "../client/identityClient"; import { ClientSecretCredential } from "./clientSecretCredential"; @@ -10,6 +11,7 @@ import { checkTenantId } from "../util/checkTenantId"; import { trace } from "../util/tracing"; import { ClientCertificateCredential } from "./clientCertificateCredential"; import { UsernamePasswordCredential } from "./usernamePasswordCredential"; +import { CredentialPersistenceOptions } from "./credentialPersistenceOptions"; /** * Contains the list of all supported environment variable names so that an @@ -29,6 +31,13 @@ export const AllSupportedEnvironmentVariables = [ const logger = credentialLogger("EnvironmentCredential"); +/** + * Defines options for the EnvironmentCredential class. + */ +export interface EnvironmentCredentialOptions + extends TokenCredentialOptions, + CredentialPersistenceOptions {} + /** * Enables authentication to Azure Active Directory using client secret * details configured in the following environment variables: @@ -54,7 +63,7 @@ export class EnvironmentCredential implements TokenCredential { * * @param options - Options for configuring the client which makes the authentication request. */ - constructor(options?: TokenCredentialOptions) { + constructor(options?: EnvironmentCredentialOptions) { // Keep track of any missing environment variables for error details const assigned = processEnvVars(AllSupportedEnvironmentVariables).assigned.join(", "); diff --git a/sdk/identity/identity/src/credentials/interactiveBrowserCredential.browser.ts b/sdk/identity/identity/src/credentials/interactiveBrowserCredential.browser.ts index 8e9dba33ae4a..e04f3d7c8054 100644 --- a/sdk/identity/identity/src/credentials/interactiveBrowserCredential.browser.ts +++ b/sdk/identity/identity/src/credentials/interactiveBrowserCredential.browser.ts @@ -1,7 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { AccessToken, GetTokenOptions, TokenCredential } from "@azure/core-http"; +import { AccessToken, GetTokenOptions, TokenCredential } from "@azure/core-auth"; + import { credentialLogger, formatError } from "../util/logging"; import { trace } from "../util/tracing"; import { MsalFlow } from "../msal/flows"; diff --git a/sdk/identity/identity/src/credentials/interactiveBrowserCredential.ts b/sdk/identity/identity/src/credentials/interactiveBrowserCredential.ts index f7b6ec4f7008..9d98d1fff531 100644 --- a/sdk/identity/identity/src/credentials/interactiveBrowserCredential.ts +++ b/sdk/identity/identity/src/credentials/interactiveBrowserCredential.ts @@ -3,7 +3,8 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ -import { AccessToken, GetTokenOptions, TokenCredential } from "@azure/core-http"; +import { AccessToken, GetTokenOptions, TokenCredential } from "@azure/core-auth"; + import { credentialLogger } from "../util/logging"; import { trace } from "../util/tracing"; import { AuthenticationRecord } from "../msal/types"; diff --git a/sdk/identity/identity/src/credentials/interactiveBrowserCredentialOptions.ts b/sdk/identity/identity/src/credentials/interactiveBrowserCredentialOptions.ts index 7d5e59c947c2..2057c792f8bb 100644 --- a/sdk/identity/identity/src/credentials/interactiveBrowserCredentialOptions.ts +++ b/sdk/identity/identity/src/credentials/interactiveBrowserCredentialOptions.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { TokenCredentialOptions } from "../client/identityClient"; import { InteractiveCredentialOptions } from "./interactiveCredentialOptions"; +import { CredentialPersistenceOptions } from "./credentialPersistenceOptions"; /** * (Browser-only feature) @@ -18,52 +18,52 @@ export type BrowserLoginStyle = "redirect" | "popup"; /** * Defines the common options for the InteractiveBrowserCredential class. */ -export type InteractiveBrowserCredentialOptions = TokenCredentialOptions & - InteractiveCredentialOptions & { - /** - * Gets the redirect URI of the application. This should be same as the value - * in the application registration portal. Defaults to `window.location.href`. - */ - redirectUri?: string | (() => string); +export interface InteractiveBrowserCredentialOptions + extends InteractiveCredentialOptions, + CredentialPersistenceOptions { + /** + * Gets the redirect URI of the application. This should be same as the value + * in the application registration portal. Defaults to `window.location.href`. + */ + redirectUri?: string | (() => string); - /** - * The Azure Active Directory tenant (directory) ID. - */ - tenantId?: string; + /** + * The Azure Active Directory tenant (directory) ID. + */ + tenantId?: string; - /** - * The client (application) ID of an App Registration in the tenant. - */ - clientId?: string; - }; + /** + * The client (application) ID of an App Registration in the tenant. + */ + clientId?: string; +} /** * Defines the common options for the InteractiveBrowserCredential class. */ -export type InteractiveBrowserCredentialBrowserOptions = TokenCredentialOptions & - InteractiveCredentialOptions & { - /** - * Gets the redirect URI of the application. This should be same as the value - * in the application registration portal. Defaults to `window.location.href`. - */ - redirectUri?: string | (() => string); +export interface InteractiveBrowserCredentialBrowserOptions extends InteractiveCredentialOptions { + /** + * Gets the redirect URI of the application. This should be same as the value + * in the application registration portal. Defaults to `window.location.href`. + */ + redirectUri?: string | (() => string); - /** - * The Azure Active Directory tenant (directory) ID. - */ - tenantId?: string; + /** + * The Azure Active Directory tenant (directory) ID. + */ + tenantId?: string; - /** - * The client (application) ID of an App Registration in the tenant. - * This parameter is required on the browser. - */ - clientId: string; + /** + * The client (application) ID of an App Registration in the tenant. + * This parameter is required on the browser. + */ + clientId: string; - /** - * Specifies whether a redirect or a popup window should be used to - * initiate the user authentication flow. Possible values are "redirect" - * or "popup" (default) for browser and "popup" (default) for node. - * - */ - loginStyle?: BrowserLoginStyle; - }; + /** + * Specifies whether a redirect or a popup window should be used to + * initiate the user authentication flow. Possible values are "redirect" + * or "popup" (default) for browser and "popup" (default) for node. + * + */ + loginStyle?: BrowserLoginStyle; +} diff --git a/sdk/identity/identity/src/credentials/managedIdentityCredential/appServiceMsi2017.ts b/sdk/identity/identity/src/credentials/managedIdentityCredential/appServiceMsi2017.ts index 6a556b1d38d0..f0a050f46b20 100644 --- a/sdk/identity/identity/src/credentials/managedIdentityCredential/appServiceMsi2017.ts +++ b/sdk/identity/identity/src/credentials/managedIdentityCredential/appServiceMsi2017.ts @@ -1,7 +1,10 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { AccessToken, GetTokenOptions, RequestPrepareOptions } from "@azure/core-http"; +import { AccessToken, GetTokenOptions } from "@azure/core-auth"; + +import { RequestPrepareOptions } from "@azure/core-http"; + import { IdentityClient } from "../../client/identityClient"; import { credentialLogger } from "../../util/logging"; import { MSI } from "./models"; diff --git a/sdk/identity/identity/src/credentials/managedIdentityCredential/arcMsi.ts b/sdk/identity/identity/src/credentials/managedIdentityCredential/arcMsi.ts index c379f350f1d4..a30b749a4766 100644 --- a/sdk/identity/identity/src/credentials/managedIdentityCredential/arcMsi.ts +++ b/sdk/identity/identity/src/credentials/managedIdentityCredential/arcMsi.ts @@ -1,7 +1,9 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { AccessToken, GetTokenOptions, RequestPrepareOptions } from "@azure/core-http"; +import { AccessToken, GetTokenOptions } from "@azure/core-auth"; +import { RequestPrepareOptions } from "@azure/core-http"; + import { MSI } from "./models"; import { credentialLogger } from "../../util/logging"; import { IdentityClient } from "../../client/identityClient"; diff --git a/sdk/identity/identity/src/credentials/managedIdentityCredential/cloudShellMsi.ts b/sdk/identity/identity/src/credentials/managedIdentityCredential/cloudShellMsi.ts index 80b741f0690e..547b64d07e7c 100644 --- a/sdk/identity/identity/src/credentials/managedIdentityCredential/cloudShellMsi.ts +++ b/sdk/identity/identity/src/credentials/managedIdentityCredential/cloudShellMsi.ts @@ -2,7 +2,10 @@ // Licensed under the MIT license. import qs from "qs"; -import { AccessToken, GetTokenOptions, RequestPrepareOptions } from "@azure/core-http"; + +import { AccessToken, GetTokenOptions } from "@azure/core-auth"; +import { RequestPrepareOptions } from "@azure/core-http"; + import { MSI } from "./models"; import { credentialLogger } from "../../util/logging"; import { IdentityClient } from "../../client/identityClient"; diff --git a/sdk/identity/identity/src/credentials/managedIdentityCredential/fabricMsi.ts b/sdk/identity/identity/src/credentials/managedIdentityCredential/fabricMsi.ts index 2678a9048306..ff625535a64b 100644 --- a/sdk/identity/identity/src/credentials/managedIdentityCredential/fabricMsi.ts +++ b/sdk/identity/identity/src/credentials/managedIdentityCredential/fabricMsi.ts @@ -1,7 +1,9 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { AccessToken, GetTokenOptions, RequestPrepareOptions } from "@azure/core-http"; +import { AccessToken, GetTokenOptions } from "@azure/core-auth"; +import { RequestPrepareOptions } from "@azure/core-http"; + import { MSI } from "./models"; import { credentialLogger } from "../../util/logging"; import { IdentityClient } from "../../client/identityClient"; diff --git a/sdk/identity/identity/src/credentials/managedIdentityCredential/index.browser.ts b/sdk/identity/identity/src/credentials/managedIdentityCredential/index.browser.ts index dff12380ab78..eb8715548626 100644 --- a/sdk/identity/identity/src/credentials/managedIdentityCredential/index.browser.ts +++ b/sdk/identity/identity/src/credentials/managedIdentityCredential/index.browser.ts @@ -1,7 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { AccessToken, TokenCredential } from "@azure/core-http"; +import { AccessToken, TokenCredential } from "@azure/core-auth"; + import { TokenCredentialOptions } from "../../client/identityClient"; import { credentialLogger, formatError } from "../../util/logging"; diff --git a/sdk/identity/identity/src/credentials/managedIdentityCredential/index.ts b/sdk/identity/identity/src/credentials/managedIdentityCredential/index.ts index a49723c57984..ffdc242ce940 100644 --- a/sdk/identity/identity/src/credentials/managedIdentityCredential/index.ts +++ b/sdk/identity/identity/src/credentials/managedIdentityCredential/index.ts @@ -1,7 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { AccessToken, GetTokenOptions, TokenCredential } from "@azure/core-http"; +import { AccessToken, GetTokenOptions, TokenCredential } from "@azure/core-auth"; + import { IdentityClient, TokenCredentialOptions } from "../../client/identityClient"; import { createSpan } from "../../util/tracing"; import { AuthenticationError, CredentialUnavailableError } from "../../client/errors"; diff --git a/sdk/identity/identity/src/credentials/managedIdentityCredential/models.ts b/sdk/identity/identity/src/credentials/managedIdentityCredential/models.ts index e449ffd64b18..237b758554fa 100644 --- a/sdk/identity/identity/src/credentials/managedIdentityCredential/models.ts +++ b/sdk/identity/identity/src/credentials/managedIdentityCredential/models.ts @@ -1,7 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { AccessToken, GetTokenOptions } from "@azure/core-http"; +import { AccessToken, GetTokenOptions } from "@azure/core-auth"; + import { IdentityClient } from "../../client/identityClient"; export type MSIExpiresInParser = (requestBody: any) => number; diff --git a/sdk/identity/identity/src/credentials/managedIdentityCredential/utils.ts b/sdk/identity/identity/src/credentials/managedIdentityCredential/utils.ts index 6c54ec33a94b..ef2336c6a9c7 100644 --- a/sdk/identity/identity/src/credentials/managedIdentityCredential/utils.ts +++ b/sdk/identity/identity/src/credentials/managedIdentityCredential/utils.ts @@ -1,7 +1,9 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { AccessToken, GetTokenOptions, RequestPrepareOptions } from "@azure/core-http"; +import { AccessToken, GetTokenOptions } from "@azure/core-auth"; +import { RequestPrepareOptions } from "@azure/core-http"; + import { IdentityClient } from "../../client/identityClient"; import { DefaultScopeSuffix } from "./constants"; import { MSIExpiresInParser } from "./models"; diff --git a/sdk/identity/identity/src/credentials/usernamePasswordCredential.browser.ts b/sdk/identity/identity/src/credentials/usernamePasswordCredential.browser.ts index e76b83b68863..91f4cd31a692 100644 --- a/sdk/identity/identity/src/credentials/usernamePasswordCredential.browser.ts +++ b/sdk/identity/identity/src/credentials/usernamePasswordCredential.browser.ts @@ -2,7 +2,9 @@ // Licensed under the MIT license. import qs from "qs"; -import { TokenCredential, GetTokenOptions, AccessToken } from "@azure/core-http"; + +import { TokenCredential, GetTokenOptions, AccessToken } from "@azure/core-auth"; + import { TokenCredentialOptions, IdentityClient } from "../client/identityClient"; import { createSpan } from "../util/tracing"; import { SpanStatusCode } from "@azure/core-tracing"; diff --git a/sdk/identity/identity/src/credentials/usernamePasswordCredential.ts b/sdk/identity/identity/src/credentials/usernamePasswordCredential.ts index f7ffeefc0883..f8752b694eb4 100644 --- a/sdk/identity/identity/src/credentials/usernamePasswordCredential.ts +++ b/sdk/identity/identity/src/credentials/usernamePasswordCredential.ts @@ -1,7 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { AccessToken, GetTokenOptions, TokenCredential } from "@azure/core-http"; +import { AccessToken, GetTokenOptions, TokenCredential } from "@azure/core-auth"; + import { credentialLogger } from "../util/logging"; import { MsalUsernamePassword } from "../msal/nodeFlows/msalUsernamePassword"; import { MsalFlow } from "../msal/flows"; diff --git a/sdk/identity/identity/src/credentials/usernamePasswordCredentialOptions.ts b/sdk/identity/identity/src/credentials/usernamePasswordCredentialOptions.ts index f82a1cdb2922..5abe8010dd14 100644 --- a/sdk/identity/identity/src/credentials/usernamePasswordCredentialOptions.ts +++ b/sdk/identity/identity/src/credentials/usernamePasswordCredentialOptions.ts @@ -2,8 +2,11 @@ // Licensed under the MIT license. import { TokenCredentialOptions } from "../client/identityClient"; +import { CredentialPersistenceOptions } from "./credentialPersistenceOptions"; /** * Defines options for the {@link UsernamePasswordCredential} class. */ -export interface UsernamePasswordCredentialOptions extends TokenCredentialOptions {} +export interface UsernamePasswordCredentialOptions + extends TokenCredentialOptions, + CredentialPersistenceOptions {} diff --git a/sdk/identity/identity/src/credentials/visualStudioCodeCredential.browser.ts b/sdk/identity/identity/src/credentials/visualStudioCodeCredential.browser.ts new file mode 100644 index 000000000000..8255eeac4dce --- /dev/null +++ b/sdk/identity/identity/src/credentials/visualStudioCodeCredential.browser.ts @@ -0,0 +1,31 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { TokenCredential, AccessToken } from "@azure/core-auth"; + +import { credentialLogger, formatError } from "../util/logging"; + +const BrowserNotSupportedError = new Error( + "VisualStudioCodeCredential is not supported in the browser." +); +const logger = credentialLogger("VisualStudioCodeCredential"); + +export const vsCodeCredentialControl = { + set vsCodeCredentialFinder(_finder: never) { + throw new Error( + "Attempted to register a VisualStudioCodeCredential provider extension in the browser. This environment is not supported by VisualStudioCodeCredential." + ); + } +}; + +export class VisualStudioCodeCredential implements TokenCredential { + constructor() { + logger.info(formatError("", BrowserNotSupportedError)); + throw BrowserNotSupportedError; + } + + public getToken(): Promise { + logger.getToken.info(formatError("", BrowserNotSupportedError)); + throw BrowserNotSupportedError; + } +} diff --git a/sdk/identity/identity/src/credentials/visualStudioCodeCredential.ts b/sdk/identity/identity/src/credentials/visualStudioCodeCredential.ts new file mode 100644 index 000000000000..c12d7dde7c9b --- /dev/null +++ b/sdk/identity/identity/src/credentials/visualStudioCodeCredential.ts @@ -0,0 +1,234 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { TokenCredential, AccessToken, GetTokenOptions } from "@azure/core-auth"; + +import fs from "fs"; +import os from "os"; +import path from "path"; + +import { CredentialUnavailableError } from "../client/errors"; +import { IdentityClient, TokenCredentialOptions } from "../client/identityClient"; +import { AzureAuthorityHosts } from "../constants"; +import { checkTenantId } from "../util/checkTenantId"; +import { credentialLogger, formatError, formatSuccess } from "../util/logging"; +import { VSCodeCredentialFinder } from "./visualStudioCodeCredentialExtension"; + +const CommonTenantId = "common"; +const AzureAccountClientId = "aebc6443-996d-45c2-90f0-388ff96faa56"; // VSC: 'aebc6443-996d-45c2-90f0-388ff96faa56' +const logger = credentialLogger("VisualStudioCodeCredential"); + +let findCredentials: VSCodeCredentialFinder | undefined = undefined; + +export const vsCodeCredentialControl = { + setVsCodeCredentialFinder(finder: VSCodeCredentialFinder): void { + findCredentials = finder; + } +}; + +// Map of unsupported Tenant IDs and the errors we will be throwing. +const unsupportedTenantIds: Record = { + adfs: "The VisualStudioCodeCredential does not support authentication with ADFS tenants." +}; + +function checkUnsupportedTenant(tenantId: string): void { + // If the Tenant ID isn't supported, we throw. + const unsupportedTenantError = unsupportedTenantIds[tenantId]; + if (unsupportedTenantError) { + throw new CredentialUnavailableError(unsupportedTenantError); + } +} + +type VSCodeCloudNames = "AzureCloud" | "AzureChina" | "AzureGermanCloud" | "AzureUSGovernment"; + +const mapVSCodeAuthorityHosts: Record = { + AzureCloud: AzureAuthorityHosts.AzurePublicCloud, + AzureChina: AzureAuthorityHosts.AzureChina, + AzureGermanCloud: AzureAuthorityHosts.AzureGermany, + AzureUSGovernment: AzureAuthorityHosts.AzureGovernment +}; + +/** + * Attempts to load a specific property from the VSCode configurations of the current OS. + * If it fails at any point, returns undefined. + */ +export function getPropertyFromVSCode(property: string): string | undefined { + const settingsPath = ["User", "settings.json"]; + // Eventually we can add more folders for more versions of VSCode. + const vsCodeFolder = "Code"; + const homedir = os.homedir(); + + function loadProperty(...pathSegments: string[]): string | undefined { + const fullPath = path.join(...pathSegments, vsCodeFolder, ...settingsPath); + const settings = JSON.parse(fs.readFileSync(fullPath, { encoding: "utf8" })); + return settings[property]; + } + + try { + let appData: string; + switch (process.platform) { + case "win32": + appData = process.env.APPDATA!; + return appData ? loadProperty(appData) : undefined; + case "darwin": + return loadProperty(homedir, "Library", "Application Support"); + case "linux": + return loadProperty(homedir, ".config"); + default: + return; + } + } catch (e) { + logger.info(`Failed to load the Visual Studio Code configuration file. Error: ${e.message}`); + return; + } +} + +/** + * Provides options to configure the Visual Studio Code credential. + */ +export interface VisualStudioCodeCredentialOptions extends TokenCredentialOptions { + /** + * Optionally pass in a Tenant ID to be used as part of the credential + */ + tenantId?: string; +} + +/** + * Connect to Azure using the credential provided by the VSCode extension 'Azure Account'. + * Once the user has logged in via the extension, this credential can share the same refresh token + * that is cached by the extension. + */ +export class VisualStudioCodeCredential implements TokenCredential { + private identityClient: IdentityClient; + private tenantId: string; + private cloudName: VSCodeCloudNames; + + /** + * Creates an instance of VisualStudioCodeCredential to use for automatically authenticating via VSCode. + * + * @param options - Options for configuring the client which makes the authentication request. + */ + constructor(options?: VisualStudioCodeCredentialOptions) { + // We want to make sure we use the one assigned by the user on the VSCode settings. + // Or just `AzureCloud` by default. + this.cloudName = (getPropertyFromVSCode("azure.cloud") || "AzureCloud") as VSCodeCloudNames; + + // Picking an authority host based on the cloud name. + const authorityHost = mapVSCodeAuthorityHosts[this.cloudName]; + + this.identityClient = new IdentityClient({ + authorityHost, + ...options + }); + + if (options && options.tenantId) { + checkTenantId(logger, options.tenantId); + this.tenantId = options.tenantId; + } else { + this.tenantId = CommonTenantId; + } + + checkUnsupportedTenant(this.tenantId); + } + + /** + * Runs preparations for any further getToken request. + */ + private async prepare(): Promise { + // Attempts to load the tenant from the VSCode configuration file. + const settingsTenant = getPropertyFromVSCode("azure.tenant"); + if (settingsTenant) { + this.tenantId = settingsTenant; + } + checkUnsupportedTenant(this.tenantId); + } + + /** + * The promise of the single preparation that will be executed at the first getToken request for an instance of this class. + */ + private preparePromise: Promise | undefined; + + /** + * Runs preparations for any further getToken, but only once. + */ + private prepareOnce(): Promise | undefined { + if (!this.preparePromise) { + this.preparePromise = this.prepare(); + } + return this.preparePromise; + } + + /** + * Returns the token found by searching VSCode's authentication cache or + * returns null if no token could be found. + * + * @param scopes - The list of scopes for which the token will have access. + * @param options - The options used to configure any requests this + * `TokenCredential` implementation might make. + */ + public async getToken( + scopes: string | string[], + _options?: GetTokenOptions + ): Promise { + await this.prepareOnce(); + if (findCredentials === undefined) { + throw new CredentialUnavailableError( + "No implementation of VisualStudioCodeCredential is available (do you need to install and use the `@azure/identity-vscode` extension package?)" + ); + } + + let scopeString = typeof scopes === "string" ? scopes : scopes.join(" "); + + // Check to make sure the scope we get back is a valid scope + if (!scopeString.match(/^[0-9a-zA-Z-.:/]+$/)) { + const error = new Error("Invalid scope was specified by the user or calling client"); + logger.getToken.info(formatError(scopes, error)); + throw error; + } + + if (scopeString.indexOf("offline_access") < 0) { + scopeString += " offline_access"; + } + + // findCredentials returns an array similar to: + // [ + // { + // account: "", + // password: "", + // }, + // /* ... */ + // ] + const credentials = await findCredentials(); + + // If we can't find the credential based on the name, we'll pick the first one available. + const { password: refreshToken } = + credentials.find(({ account }) => account === this.cloudName) ?? credentials[0] ?? {}; + + if (refreshToken) { + const tokenResponse = await this.identityClient.refreshAccessToken( + this.tenantId, + AzureAccountClientId, + scopeString, + refreshToken, + undefined + ); + + if (tokenResponse) { + logger.getToken.info(formatSuccess(scopes)); + return tokenResponse.accessToken; + } else { + const error = new CredentialUnavailableError( + "Could not retrieve the token associated with Visual Studio Code. Have you connected using the 'Azure Account' extension recently?" + ); + logger.getToken.info(formatError(scopes, error)); + throw error; + } + } else { + const error = new CredentialUnavailableError( + "Could not retrieve the token associated with Visual Studio Code. Did you connect using the 'Azure Account' extension?" + ); + logger.getToken.info(formatError(scopes, error)); + throw error; + } + } +} diff --git a/sdk/identity/identity/src/credentials/visualStudioCodeCredentialExtension.ts b/sdk/identity/identity/src/credentials/visualStudioCodeCredentialExtension.ts new file mode 100644 index 000000000000..4dd49ae1dbc2 --- /dev/null +++ b/sdk/identity/identity/src/credentials/visualStudioCodeCredentialExtension.ts @@ -0,0 +1,13 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +// Copyright (c) Microsoft Corporation +// Licensed under the MIT license. + +/** + * A function that searches for credentials in the Visual Studio Code credential store. + * + * @returns an array of credentials (username and password) + * @internal + */ +export type VSCodeCredentialFinder = () => Promise>; diff --git a/sdk/identity/identity/src/extensions/consumer.browser.ts b/sdk/identity/identity/src/extensions/consumer.browser.ts new file mode 100644 index 000000000000..900a924cd408 --- /dev/null +++ b/sdk/identity/identity/src/extensions/consumer.browser.ts @@ -0,0 +1,8 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +// This module is a shim for the extension consumer in the browser + +export function useIdentityExtension(_extension: unknown): void { + throw new Error("Identity extensions are not supported in browser environments."); +} diff --git a/sdk/identity/identity/src/extensions/consumer.ts b/sdk/identity/identity/src/extensions/consumer.ts new file mode 100644 index 000000000000..9b3495a8bba2 --- /dev/null +++ b/sdk/identity/identity/src/extensions/consumer.ts @@ -0,0 +1,47 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { AzureExtensionContext, IdentityExtension } from "./provider"; +import { msalNodeFlowCacheControl } from "../msal/nodeFlows/nodeCommon"; +import { vsCodeCredentialControl } from "../credentials/visualStudioCodeCredential"; + +/** + * The context passed to an Identity Extension. This contains objects that + * extensions can use to set backend implementations. + * @internal + */ +const extensionContext: AzureExtensionContext = { + cachePluginControl: msalNodeFlowCacheControl, + vsCodeCredentialControl: vsCodeCredentialControl +}; + +/** + * Extend Azure Identity with additional functionality. Pass an extension from + * an extension package, such as: + * + * - `@azure/identity-cache-persistence`: provides persistent token caching + * - `@azure/identity-vscode`: provides the dependencies of + * `VisualStudioCodeCredential` and enables it + * + * Example: + * + * ```javascript + * import { cachePersistenceExtension } from "@azure/identity-cache-persistence"; + * + * import { useIdentityExtension, DefaultAzureCredential } from "@azure/identity"; + * useIdentityExtension(persistence); + * + * // The extension has the capability to extend `DefaultAzureCredential` and to + * // add middleware to the underlying credentials, such as persistence. + * const credential = new DefaultAzureCredential({ + * tokenCachePersistenceOptions: { + * enabled: true + * } + * }); + * ``` + * + * @param extension - the extension to register + */ +export function useIdentityExtension(extension: IdentityExtension): void { + extension(extensionContext); +} diff --git a/sdk/identity/identity/src/extensions/provider.ts b/sdk/identity/identity/src/extensions/provider.ts new file mode 100644 index 000000000000..ad661a00cdb8 --- /dev/null +++ b/sdk/identity/identity/src/extensions/provider.ts @@ -0,0 +1,42 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { VSCodeCredentialFinder } from "../credentials/visualStudioCodeCredentialExtension"; +import { TokenCachePersistenceOptions } from "../msal/nodeFlows/tokenCachePersistenceOptions"; + +/** + * The type of an Azure Identity Extension, a function accepting an extension + * context. + */ +export type IdentityExtension = (context: unknown) => void; + +/** + * Extension context entries for controlling cache plugins. + */ +export interface CachePluginControl { + setPersistence( + persistenceFactory: ( + options?: TokenCachePersistenceOptions + ) => Promise + ): void; +} + +/** + * Extension context entries for controlling VisualStudioCodeCredential. + */ +export interface VisualStudioCodeCredentialControl { + setVsCodeCredentialFinder(finder: VSCodeCredentialFinder): void; +} + +/** + * Context options passed to an extension during initialization. + * + * Extension authors are responsible for casting their extension context values + * to this type. + * + * @internal + */ +export interface AzureExtensionContext { + cachePluginControl: CachePluginControl; + vsCodeCredentialControl: VisualStudioCodeCredentialControl; +} diff --git a/sdk/identity/identity/src/index.ts b/sdk/identity/identity/src/index.ts index 7e951d958cb3..564e52a96157 100644 --- a/sdk/identity/identity/src/index.ts +++ b/sdk/identity/identity/src/index.ts @@ -1,7 +1,11 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { TokenCredential } from "@azure/core-http"; +export * from "./extensions/consumer"; + +export { IdentityExtension } from "./extensions/provider"; + +import { TokenCredential } from "@azure/core-auth"; import { DefaultAzureCredential } from "./credentials/defaultAzureCredential"; export { AuthenticationRecord } from "./msal/types"; @@ -16,11 +20,15 @@ export { DefaultAzureCredential, DefaultAzureCredentialOptions } from "./credentials/defaultAzureCredential"; -export { EnvironmentCredential } from "./credentials/environmentCredential"; +export { + EnvironmentCredential, + EnvironmentCredentialOptions +} from "./credentials/environmentCredential"; export { ClientSecretCredential } from "./credentials/clientSecretCredential"; export { ClientSecretCredentialOptions } from "./credentials/clientSecretCredentialOptions"; export { ClientCertificateCredential } from "./credentials/clientCertificateCredential"; export { ClientCertificateCredentialOptions } from "./credentials/clientCertificateCredentialOptions"; +export { CredentialPersistenceOptions } from "./credentials/credentialPersistenceOptions"; export { AzureCliCredential } from "./credentials/azureCliCredential"; export { InteractiveBrowserCredential } from "./credentials/interactiveBrowserCredential"; export { @@ -40,6 +48,13 @@ export { UsernamePasswordCredentialOptions } from "./credentials/usernamePasswor export { AuthorizationCodeCredential } from "./credentials/authorizationCodeCredential"; export { AzurePowerShellCredential } from "./credentials/azurePowerShellCredential"; +export { + VisualStudioCodeCredential, + VisualStudioCodeCredentialOptions +} from "./credentials/visualStudioCodeCredential"; + +export { TokenCachePersistenceOptions } from "./msal/nodeFlows/tokenCachePersistenceOptions"; + export { AuthenticationError, ErrorResponse, @@ -50,7 +65,7 @@ export { CredentialUnavailableErrorName } from "./client/errors"; -export { TokenCredential, GetTokenOptions, AccessToken } from "@azure/core-http"; +export { TokenCredential, GetTokenOptions, AccessToken } from "@azure/core-auth"; export { logger } from "./util/logging"; export { AzureAuthorityHosts } from "./constants"; diff --git a/sdk/identity/identity/src/msal/browserFlows/browserCommon.ts b/sdk/identity/identity/src/msal/browserFlows/browserCommon.ts index 75783b8bad7d..5e06a9ea4dbd 100644 --- a/sdk/identity/identity/src/msal/browserFlows/browserCommon.ts +++ b/sdk/identity/identity/src/msal/browserFlows/browserCommon.ts @@ -2,7 +2,9 @@ // Licensed under the MIT license. import * as msalBrowser from "@azure/msal-browser"; -import { AccessToken } from "@azure/core-http"; + +import { AccessToken } from "@azure/core-auth"; + import { DefaultTenantId } from "../../constants"; import { resolveTenantId } from "../../util/resolveTenantId"; import { BrowserLoginStyle } from "../../credentials/interactiveBrowserCredentialOptions"; diff --git a/sdk/identity/identity/src/msal/browserFlows/msalAuthCode.ts b/sdk/identity/identity/src/msal/browserFlows/msalAuthCode.ts index 0a2ed5e90adc..9c8ee4317b26 100644 --- a/sdk/identity/identity/src/msal/browserFlows/msalAuthCode.ts +++ b/sdk/identity/identity/src/msal/browserFlows/msalAuthCode.ts @@ -2,8 +2,10 @@ // Licensed under the MIT license. import * as msalBrowser from "@azure/msal-browser"; + +import { AccessToken } from "@azure/core-auth"; + import { MsalBrowserFlowOptions, MsalBrowser } from "./browserCommon"; -import { AccessToken } from "@azure/core-http"; import { defaultLoggerCallback, msalToPublic, publicToMsal } from "../utils"; import { AuthenticationRecord } from "../types"; import { AuthenticationRequiredError } from "../errors"; diff --git a/sdk/identity/identity/src/msal/credentials.ts b/sdk/identity/identity/src/msal/credentials.ts index 4d0238c83338..6b80f45b96f1 100644 --- a/sdk/identity/identity/src/msal/credentials.ts +++ b/sdk/identity/identity/src/msal/credentials.ts @@ -1,7 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { AccessToken, GetTokenOptions } from "@azure/core-http"; +import { AccessToken, GetTokenOptions } from "@azure/core-auth"; + import { AuthenticationRecord } from "./types"; /** diff --git a/sdk/identity/identity/src/msal/errors.ts b/sdk/identity/identity/src/msal/errors.ts index 1ee4183092d4..71ee673d5fb1 100644 --- a/sdk/identity/identity/src/msal/errors.ts +++ b/sdk/identity/identity/src/msal/errors.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { GetTokenOptions } from "@azure/core-http"; +import { GetTokenOptions } from "@azure/core-auth"; /** * Error used to enforce authentication after trying to retrieve a token silently. diff --git a/sdk/identity/identity/src/msal/flows.ts b/sdk/identity/identity/src/msal/flows.ts index 80d9a69dd38e..f678af41d690 100644 --- a/sdk/identity/identity/src/msal/flows.ts +++ b/sdk/identity/identity/src/msal/flows.ts @@ -1,7 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { AccessToken } from "@azure/core-http"; +import { AccessToken } from "@azure/core-auth"; + import { CredentialLogger } from "../util/logging"; import { AuthenticationRecord } from "./types"; import { CredentialFlowGetTokenOptions } from "./credentials"; @@ -28,10 +29,6 @@ export interface MsalFlow { * Allows for any setup before any request is processed. */ init(options?: CredentialFlowGetTokenOptions): Promise; - /** - * Clears the MSAL cache. - */ - logout(): Promise; /** * Tries to load the active account, either from memory or from MSAL. */ diff --git a/sdk/identity/identity/src/msal/nodeFlows/msalClientCertificate.ts b/sdk/identity/identity/src/msal/nodeFlows/msalClientCertificate.ts index b70aca7356e7..3b5131f5725e 100644 --- a/sdk/identity/identity/src/msal/nodeFlows/msalClientCertificate.ts +++ b/sdk/identity/identity/src/msal/nodeFlows/msalClientCertificate.ts @@ -3,7 +3,9 @@ import { readFileSync } from "fs"; import { createHash } from "crypto"; -import { AccessToken } from "@azure/core-http"; + +import { AccessToken } from "@azure/core-auth"; + import { MsalNodeOptions, MsalNode } from "./nodeCommon"; import { formatError } from "../../util/logging"; import { CredentialFlowGetTokenOptions } from "../credentials"; diff --git a/sdk/identity/identity/src/msal/nodeFlows/msalClientSecret.ts b/sdk/identity/identity/src/msal/nodeFlows/msalClientSecret.ts index e40ba09db500..eafbc6e70be8 100644 --- a/sdk/identity/identity/src/msal/nodeFlows/msalClientSecret.ts +++ b/sdk/identity/identity/src/msal/nodeFlows/msalClientSecret.ts @@ -1,7 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { AccessToken } from "@azure/core-http"; +import { AccessToken } from "@azure/core-auth"; + import { CredentialFlowGetTokenOptions } from "../credentials"; import { MsalNodeOptions, MsalNode } from "./nodeCommon"; diff --git a/sdk/identity/identity/src/msal/nodeFlows/msalDeviceCode.ts b/sdk/identity/identity/src/msal/nodeFlows/msalDeviceCode.ts index f12d90294f85..391726b786fb 100644 --- a/sdk/identity/identity/src/msal/nodeFlows/msalDeviceCode.ts +++ b/sdk/identity/identity/src/msal/nodeFlows/msalDeviceCode.ts @@ -2,7 +2,9 @@ // Licensed under the MIT license. import * as msalNode from "@azure/msal-node"; -import { AccessToken } from "@azure/core-http"; + +import { AccessToken } from "@azure/core-auth"; + import { DeviceCodePromptCallback } from "../../credentials/deviceCodeCredentialOptions"; import { CredentialFlowGetTokenOptions } from "../credentials"; import { MsalNodeOptions, MsalNode } from "./nodeCommon"; diff --git a/sdk/identity/identity/src/msal/nodeFlows/msalOpenBrowser.ts b/sdk/identity/identity/src/msal/nodeFlows/msalOpenBrowser.ts index 674bcbec57d9..8b584bbc99a4 100644 --- a/sdk/identity/identity/src/msal/nodeFlows/msalOpenBrowser.ts +++ b/sdk/identity/identity/src/msal/nodeFlows/msalOpenBrowser.ts @@ -2,11 +2,14 @@ // Licensed under the MIT license. import * as msalNode from "@azure/msal-node"; + +import { AccessToken, GetTokenOptions } from "@azure/core-auth"; + import { Socket } from "net"; import http from "http"; import open from "open"; import stoppable from "stoppable"; -import { AccessToken, GetTokenOptions } from "@azure/core-http"; + import { credentialLogger, formatError, formatSuccess } from "../../util/logging"; import { MsalNodeOptions, MsalNode } from "./nodeCommon"; import { msalToPublic } from "../utils"; diff --git a/sdk/identity/identity/src/msal/nodeFlows/msalUsernamePassword.ts b/sdk/identity/identity/src/msal/nodeFlows/msalUsernamePassword.ts index 8095fd0741ae..93f71eed2a7c 100644 --- a/sdk/identity/identity/src/msal/nodeFlows/msalUsernamePassword.ts +++ b/sdk/identity/identity/src/msal/nodeFlows/msalUsernamePassword.ts @@ -2,7 +2,9 @@ // Licensed under the MIT license. import * as msalNode from "@azure/msal-node"; -import { AccessToken } from "@azure/core-http"; + +import { AccessToken } from "@azure/core-auth"; + import { MsalNodeOptions, MsalNode } from "./nodeCommon"; import { CredentialFlowGetTokenOptions } from "../credentials"; diff --git a/sdk/identity/identity/src/msal/nodeFlows/nodeCommon.ts b/sdk/identity/identity/src/msal/nodeFlows/nodeCommon.ts index d0f90b587c3b..63625c5228af 100644 --- a/sdk/identity/identity/src/msal/nodeFlows/nodeCommon.ts +++ b/sdk/identity/identity/src/msal/nodeFlows/nodeCommon.ts @@ -3,8 +3,10 @@ import * as msalNode from "@azure/msal-node"; import * as msalCommon from "@azure/msal-common"; -import { AccessToken, GetTokenOptions } from "@azure/core-http"; + +import { AccessToken, GetTokenOptions } from "@azure/core-auth"; import { AbortSignalLike } from "@azure/abort-controller"; + import { DeveloperSignOnClientId } from "../../constants"; import { IdentityClient, TokenCredentialOptions } from "../../client/identityClient"; import { resolveTenantId } from "../../util/resolveTenantId"; @@ -20,6 +22,7 @@ import { msalToPublic, publicToMsal } from "../utils"; +import { TokenCachePersistenceOptions } from "./tokenCachePersistenceOptions"; import { RegionalAuthority } from "../../regionalAuthority"; /** @@ -27,6 +30,7 @@ import { RegionalAuthority } from "../../regionalAuthority"; * @internal */ export interface MsalNodeOptions extends MsalFlowOptions { + tokenCachePersistenceOptions?: TokenCachePersistenceOptions; tokenCredentialOptions: TokenCredentialOptions; /** * Specifies a regional authority. Please refer to the {@link RegionalAuthority} type for the accepted values. @@ -36,6 +40,24 @@ export interface MsalNodeOptions extends MsalFlowOptions { regionalAuthority?: string; } +/** + * The current persistence provider, undefined by default. + * @internal + */ +let persistenceProvider: + | ((options?: TokenCachePersistenceOptions) => Promise) + | undefined = undefined; + +/** + * An object that allows setting the persistence provider. + * @internal + */ +export const msalNodeFlowCacheControl = { + setPersistence(pluginProvider: Exclude): void { + persistenceProvider = pluginProvider; + } +}; + /** * MSAL partial base client for NodeJS. * @@ -54,10 +76,22 @@ export abstract class MsalNode extends MsalBaseUtilities implements MsalFlow { protected requiresConfidential: boolean = false; protected azureRegion?: string; + protected createCachePlugin: (() => Promise) | undefined; + constructor(options: MsalNodeOptions) { super(options); this.msalConfig = this.defaultNodeMsalConfig(options); this.clientId = this.msalConfig.auth.clientId; + + // If persistence has been configured + if (persistenceProvider !== undefined && options.tokenCachePersistenceOptions?.enabled) { + this.createCachePlugin = () => persistenceProvider!(options.tokenCachePersistenceOptions); + } else if (options.tokenCachePersistenceOptions?.enabled) { + throw new Error( + "Persistent token caching was requested, but no persistence provider was configured (do you need to use the `@azure/identity-cache-persistence` package?)" + ); + } + this.azureRegion = options.regionalAuthority ?? process.env.AZURE_REGIONAL_AUTHORITY_NAME; if (this.azureRegion === RegionalAuthority.AutoDiscoverRegion) { this.azureRegion = "AUTO_DISCOVER"; @@ -110,6 +144,12 @@ export abstract class MsalNode extends MsalBaseUtilities implements MsalFlow { return; } + if (this.createCachePlugin !== undefined) { + this.msalConfig.cache = { + cachePlugin: await this.createCachePlugin() + }; + } + this.publicApp = new msalNode.PublicClientApplication(this.msalConfig); // The confidential client requires either a secret, assertion or certificate. if ( @@ -156,7 +196,7 @@ export abstract class MsalNode extends MsalBaseUtilities implements MsalFlow { if (this.account) { return this.account; } - const cache = this.publicApp?.getTokenCache(); + const cache = this.confidentialApp?.getTokenCache() ?? this.publicApp?.getTokenCache(); const accountsByTenant = await cache?.getAllAccounts(); if (!accountsByTenant) { @@ -178,13 +218,6 @@ To work with multiple accounts for the same Client ID and Tenant ID, please prov return this.account; } - /** - * Clears MSAL's cache. - */ - async logout(): Promise { - // Intentionally empty - } - /** * Attempts to retrieve a token from cache. */ @@ -206,7 +239,9 @@ To work with multiple accounts for the same Client ID and Tenant ID, please prov try { this.logger.info("Attempting to acquire token silently"); - const response = await this.publicApp!.acquireTokenSilent(silentRequest); + const response = + (await this.confidentialApp?.acquireTokenSilent(silentRequest)) ?? + (await this.publicApp!.acquireTokenSilent(silentRequest)); return this.handleResult(scopes, this.clientId, response || undefined); } catch (err) { throw this.handleError(scopes, err, options); diff --git a/sdk/identity/identity/src/msal/nodeFlows/tokenCachePersistenceOptions.ts b/sdk/identity/identity/src/msal/nodeFlows/tokenCachePersistenceOptions.ts new file mode 100644 index 000000000000..fb5dbe5cf31d --- /dev/null +++ b/sdk/identity/identity/src/msal/nodeFlows/tokenCachePersistenceOptions.ts @@ -0,0 +1,27 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +/** + * Parameters that enable token cache persistence in the Identity credentials. + */ +export interface TokenCachePersistenceOptions { + /** + * If set to true, persistent token caching will be enabled for this credential instance. + */ + enabled: boolean; + /** + * Unique identifier for the persistent token cache. + * + * Based on this identifier, the persistence file will be located in any of the following places: + * - Darwin: '/Users/user/.IdentityService/' + * - Windows 8: 'C:\\Users\\user\\AppData\\Local\\.IdentityService\\' + * - Windows XP: 'C:\\Documents and Settings\\user\\Application Data\\Local\\.IdentityService\\' + * - Linux: '/home/user/.IdentityService/' + */ + name?: string; + /** + * If set to true, the cache will be stored without encryption if no OS level user encryption is available. + * When set to false, the PersistentTokenCache will throw an error if no OS level user encryption is available. + */ + allowUnencryptedStorage?: boolean; +} diff --git a/sdk/identity/identity/src/msal/utils.ts b/sdk/identity/identity/src/msal/utils.ts index 5e8db10a1582..ccf0a5170257 100644 --- a/sdk/identity/identity/src/msal/utils.ts +++ b/sdk/identity/identity/src/msal/utils.ts @@ -2,7 +2,11 @@ // Licensed under the MIT license. import * as msalCommon from "@azure/msal-common"; -import { AccessToken, GetTokenOptions, isNode } from "@azure/core-http"; + +import { AccessToken, GetTokenOptions } from "@azure/core-auth"; +import { isNode } from "@azure/core-http"; +import { AbortError } from "@azure/abort-controller"; + import { v4 as uuidv4 } from "uuid"; import { CredentialLogger, formatError, formatSuccess } from "../util/logging"; import { CredentialUnavailableError } from "../client/errors"; @@ -10,7 +14,6 @@ import { DefaultAuthorityHost, DefaultTenantId } from "../constants"; import { AuthenticationRecord, MsalAccountInfo, MsalResult, MsalToken } from "./types"; import { AuthenticationRequiredError } from "./errors"; import { MsalFlowOptions } from "./flows"; -import { AbortError } from "@azure/abort-controller"; /** * Latest AuthenticationRecord version diff --git a/sdk/identity/identity/test/internal/node/clientSecretCredential.spec.ts b/sdk/identity/identity/test/internal/node/clientSecretCredential.spec.ts index 18cccb957b03..5a7b89162aa4 100644 --- a/sdk/identity/identity/test/internal/node/clientSecretCredential.spec.ts +++ b/sdk/identity/identity/test/internal/node/clientSecretCredential.spec.ts @@ -43,17 +43,15 @@ describe("ClientSecretCredential (internal)", function() { env.AZURE_CLIENT_SECRET ); - await credential.getToken(scope); + const { token: firstToken } = await credential.getToken(scope); assert.equal(getTokenSilentSpy.callCount, 1); assert.equal(doGetTokenSpy.callCount, 1); - await credential.getToken(scope); + const { token: secondToken } = await credential.getToken(scope); + assert.strictEqual(firstToken, secondToken); assert.equal(getTokenSilentSpy.callCount, 2); - // Even though we're providing the same default in memory persistence cache that we use for DeviceCodeCredential, - // The Client Secret flow does not return the account information from the authentication service, - // so each time getToken gets called, we will have to acquire a new token through the service. - assert.equal(doGetTokenSpy.callCount, 2); + assert.equal(doGetTokenSpy.callCount, 1); }); it("supports specifying the regional authority", async function() { diff --git a/sdk/identity/identity/test/internal/node/environmentCredential.spec.ts b/sdk/identity/identity/test/internal/node/environmentCredential.spec.ts index 80f595f64ea4..eb97542dc2b2 100644 --- a/sdk/identity/identity/test/internal/node/environmentCredential.spec.ts +++ b/sdk/identity/identity/test/internal/node/environmentCredential.spec.ts @@ -37,16 +37,14 @@ describe("EnvironmentCredential (internal)", function() { it("Authenticates silently after the initial request", async function() { const credential = new EnvironmentCredential(); - await credential.getToken(scope); + const { token: firstToken } = await credential.getToken(scope); assert.equal(getTokenSilentSpy.callCount, 1); assert.equal(doGetTokenSpy.callCount, 1); - await credential.getToken(scope); + const { token: secondToken } = await credential.getToken(scope); + assert.strictEqual(firstToken, secondToken); assert.equal(getTokenSilentSpy.callCount, 2); - // Even though we're providing the same default in memory persistence cache that we use for DeviceCodeCredential, - // The Client Credential and Client Secret flows do not return the account information from the authentication service, - // so each time getToken gets called, we will have to acquire a new token through the service. - assert.equal(doGetTokenSpy.callCount, 2); + assert.equal(doGetTokenSpy.callCount, 1); }); }); diff --git a/sdk/identity/identity/test/internal/node/managedIdentityCredential.spec.ts b/sdk/identity/identity/test/internal/node/managedIdentityCredential.spec.ts index a3ee69e3199a..4d9fdf5e5cb6 100644 --- a/sdk/identity/identity/test/internal/node/managedIdentityCredential.spec.ts +++ b/sdk/identity/identity/test/internal/node/managedIdentityCredential.spec.ts @@ -3,7 +3,10 @@ import qs from "qs"; import assert from "assert"; -import { WebResource, AccessToken, HttpHeaders, RestError } from "@azure/core-http"; + +import { AccessToken } from "@azure/core-auth"; + +import { WebResource, HttpHeaders, RestError } from "@azure/core-http"; import { ManagedIdentityCredential, AuthenticationError } from "../../../src"; import { imdsEndpoint, diff --git a/sdk/identity/identity/test/msalTestUtils.ts b/sdk/identity/identity/test/msalTestUtils.ts index 6e9bd0e0c2a3..04d3a891df51 100644 --- a/sdk/identity/identity/test/msalTestUtils.ts +++ b/sdk/identity/identity/test/msalTestUtils.ts @@ -51,6 +51,8 @@ export function msalNodeTestSetup( recording.replace(/"access_token":"[^"]*"/g, `"access_token":"access_token"`), (recording: string): string => recording.replace(/"refresh_token":"[^"]*"/g, `"refresh_token":"refresh_token"`), + (recording: string): string => + recording.replace(/refresh_token=[^&]*/g, `refresh_token=refresh_token`), (recording: string): string => recording.replace( /client-request-id=[a-z0-9-]*/g, @@ -72,7 +74,7 @@ export function msalNodeTestSetup( recording.replace(/device_code":"[^"]*/g, `device_code":"DEVICE_CODE`), (recording: string): string => recording.replace(/device_code=[^&]*/g, `device_code=DEVICE_CODE`), - (recording: string): string => recording.replace(/"interval": *[0-9]*/g, `"interval": 1`), + (recording: string): string => recording.replace(/"interval": *[0-9]*/g, `"interval": 0`), // This last part is a JWT token that comes from the service, that has three parts joined by a dot. // Our fake id_token has the following parts encoded in base64 and joined by a dot: // - {"typ":"JWT","alg":"RS256","kid":"kid"} @@ -82,6 +84,13 @@ export function msalNodeTestSetup( recording.replace( /id_token":"[^"]*/g, `id_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6ImtpZCJ9.eyJhdWQiOiJhdWQiLCJpc3MiOiJodHRwczovL2xvZ2luLm1pY3Jvc29mdG9ubGluZS5jb20vMTIzNDU2NzgtMTIzNC0xMjM0LTEyMzQtMTIzNDU2Nzg5MDEyL3YyLjAiLCJpYXQiOjE2MTUzMzcxNjMsIm5iZiI6MTYxNTMzNzE2MywiZXhwIjoxNjE1MzQxMDYzLCJhaW8iOiJhaW8iLCJpZHAiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC9pZHAvIiwibmFtZSI6IkRhbmllbCBSb2Ryw61ndWV6Iiwib2lkIjoib2lkIiwicHJlZmVycmVkX3VzZXJuYW1lIjoiZGFucm9kcmlAbWljcm9zb2Z0LmNvbSIsInJoIjoicmguIiwic3ViIjoic3ViIiwidGlkIjoiMTIzNDU2NzgtMTIzNC0xMjM0LTEyMzQtMTIzNDU2Nzg5MDEyIiwidXRpIjoidXRpIiwidmVyIjoiMi4wIn0=.bm9faWRlYV93aGF0c190aGlz` + ), + // client_info is base64-encoded JSON that contains information about the user and tenant IDs + // The following replaces it with some dummy JSON that uses a UID/UTID of 12345678-1234-1234-1234-123456789012 + (recording) => + recording.replace( + /client_info":"[^"]*/g, + 'client_info":"eyJ1aWQiOiIxMjM0NTY3OC0xMjM0LTEyMzQtMTIzNC0xMjM0NTY3ODkwMTIiLCJ1dGlkIjoiMTIzNDU2NzgtMTIzNC0xMjM0LTEyMzQtMTIzNDU2Nzg5MDEyIn0K' ) ], queryParametersToSkip: [], diff --git a/sdk/identity/identity/test/public/node/extensions.spec.ts b/sdk/identity/identity/test/public/node/extensions.spec.ts new file mode 100644 index 000000000000..493a2eca1bb5 --- /dev/null +++ b/sdk/identity/identity/test/public/node/extensions.spec.ts @@ -0,0 +1,44 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import assert, { AssertionError } from "assert"; +import { DefaultAzureCredential } from "../../../src"; +import { VisualStudioCodeCredential } from "../../../src"; + +/** + * A helper to assert that a Promise rejects. + */ +async function assertRejects(p: Promise, regexp: RegExp): Promise { + try { + await p; + } catch (e) { + if (!regexp.test(e.message)) { + throw new AssertionError({ + message: `The input did not match the regular expression ${regexp}. Input:\n\n'${e.message}'` + }); + } + return; + } + throw new AssertionError({ + message: "Expected the function body to throw." + }); +} + +describe("Extension API", function(this: Mocha.Suite) { + it("Setting persistence options throws if not initialized", function() { + assert.throws(() => { + new DefaultAzureCredential({ + tokenCachePersistenceOptions: { + enabled: true + } + }); + }, /no persistence provider.*@azure\/identity-cache-persistence/); + }); + + it("Calling getToken on VisualStudioCodeCredential throws if not initialized", async function() { + await assertRejects( + new VisualStudioCodeCredential().getToken("https://graph.microsoft.com/.default"), + /No implementation of VisualStudioCodeCredential.*@azure\/identity-vscode/ + ); + }); +}); diff --git a/sdk/identity/perf-tests/identity/package.json b/sdk/identity/perf-tests/identity/package.json index 543a21ce6093..386004f64238 100644 --- a/sdk/identity/perf-tests/identity/package.json +++ b/sdk/identity/perf-tests/identity/package.json @@ -7,7 +7,8 @@ "author": "", "license": "ISC", "dependencies": { - "@azure/identity": "2.0.0-beta.4", + "@azure/identity": "^2.0.0-beta.4", + "@azure/identity-cache-persistence": "~1.0.0-beta.1", "@azure/test-utils-perfstress": "^1.0.0", "dotenv": "^8.2.0" }, diff --git a/sdk/identity/perf-tests/identity/test/ClientSecretCredential/persistence.spec.ts b/sdk/identity/perf-tests/identity/test/ClientSecretCredential/persistence.spec.ts index dc9e2551258e..14f0112f9a6f 100644 --- a/sdk/identity/perf-tests/identity/test/ClientSecretCredential/persistence.spec.ts +++ b/sdk/identity/perf-tests/identity/test/ClientSecretCredential/persistence.spec.ts @@ -1,15 +1,13 @@ import { PerfStressTest, getEnvVar } from "@azure/test-utils-perfstress"; -import { ClientSecretCredential } from "@azure/identity"; +import { useIdentityExtension, ClientSecretCredential } from "@azure/identity"; + +import { cachePersistenceExtension } from "@azure/identity-cache-persistence"; +useIdentityExtension(cachePersistenceExtension); const scope = `https://servicebus.azure.net/.default`; /** * This test does silent authentication with persistence enabled. - * - * TODO: This test was made unusable by removing the persistence - * feature from the mainline identity package. When we add an - * extension package to reintroduce that behavior, this test - * will be refactored to support that. */ export class ClientSecretCredentialPersistenceTest extends PerfStressTest { options = {}; @@ -23,10 +21,11 @@ export class ClientSecretCredentialPersistenceTest extends PerfStressTest { // We want this credential to be initialized only if this test is executed. // Other tests should not be required to set up this credential. const credential = new ClientSecretCredential(tenantId, clientId, clientSecret, { - /* tokenCachePersistenceOptions: { + tokenCachePersistenceOptions: { + enabled: true, name: "nodeTestSilent", allowUnencryptedStorage: true - }*/ + } }); // This getToken call will cache the token. @@ -36,6 +35,6 @@ export class ClientSecretCredentialPersistenceTest extends PerfStressTest { } async runAsync(): Promise { - // await ClientSecretCredentialPersistenceTest.credential.getToken(scope); + await ClientSecretCredentialPersistenceTest.credential.getToken(scope); } }