diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index ed9ffc7af9a0..6d56f3b47258 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -812,6 +812,9 @@ dependencies: '@rush-temp/data-tables': specifier: file:./projects/data-tables.tgz version: file:projects/data-tables.tgz + '@rush-temp/defender-easm-rest': + specifier: file:./projects/defender-easm-rest.tgz + version: file:projects/defender-easm-rest.tgz '@rush-temp/dev-tool': specifier: file:./projects/dev-tool.tgz version: file:projects/dev-tool.tgz @@ -1828,6 +1831,16 @@ packages: lodash: 4.17.21 dev: false + /@microsoft/api-extractor-model@7.28.2(@types/node@14.18.63): + resolution: {integrity: sha512-vkojrM2fo3q4n4oPh4uUZdjJ2DxQ2+RnDQL/xhTWSRUNPF6P4QyrvY357HBxbnltKcYu+nNNolVqc6TIGQ73Ig==} + dependencies: + '@microsoft/tsdoc': 0.14.2 + '@microsoft/tsdoc-config': 0.16.2 + '@rushstack/node-core-library': 3.61.0(@types/node@14.18.63) + transitivePeerDependencies: + - '@types/node' + dev: false + /@microsoft/api-extractor-model@7.28.2(@types/node@16.18.58): resolution: {integrity: sha512-vkojrM2fo3q4n4oPh4uUZdjJ2DxQ2+RnDQL/xhTWSRUNPF6P4QyrvY357HBxbnltKcYu+nNNolVqc6TIGQ73Ig==} dependencies: @@ -1838,6 +1851,26 @@ packages: - '@types/node' dev: false + /@microsoft/api-extractor@7.38.0(@types/node@14.18.63): + resolution: {integrity: sha512-e1LhZYnfw+JEebuY2bzhw0imDCl1nwjSThTrQqBXl40hrVo6xm3j/1EpUr89QyzgjqmAwek2ZkIVZbrhaR+cqg==} + hasBin: true + dependencies: + '@microsoft/api-extractor-model': 7.28.2(@types/node@14.18.63) + '@microsoft/tsdoc': 0.14.2 + '@microsoft/tsdoc-config': 0.16.2 + '@rushstack/node-core-library': 3.61.0(@types/node@14.18.63) + '@rushstack/rig-package': 0.5.1 + '@rushstack/ts-command-line': 4.16.1 + colors: 1.2.5 + lodash: 4.17.21 + resolve: 1.22.8 + semver: 7.5.4 + source-map: 0.6.1 + typescript: 5.0.4 + transitivePeerDependencies: + - '@types/node' + dev: false + /@microsoft/api-extractor@7.38.0(@types/node@16.18.58): resolution: {integrity: sha512-e1LhZYnfw+JEebuY2bzhw0imDCl1nwjSThTrQqBXl40hrVo6xm3j/1EpUr89QyzgjqmAwek2ZkIVZbrhaR+cqg==} hasBin: true @@ -2449,6 +2482,24 @@ packages: rollup: 3.29.4 dev: false + /@rushstack/node-core-library@3.61.0(@types/node@14.18.63): + resolution: {integrity: sha512-tdOjdErme+/YOu4gPed3sFS72GhtWCgNV9oDsHDnoLY5oDfwjKUc9Z+JOZZ37uAxcm/OCahDHfuu2ugqrfWAVQ==} + peerDependencies: + '@types/node': '*' + peerDependenciesMeta: + '@types/node': + optional: true + dependencies: + '@types/node': 14.18.63 + colors: 1.2.5 + fs-extra: 7.0.1 + import-lazy: 4.0.0 + jju: 1.4.0 + resolve: 1.22.8 + semver: 7.5.4 + z-schema: 5.0.5 + dev: false + /@rushstack/node-core-library@3.61.0(@types/node@16.18.58): resolution: {integrity: sha512-tdOjdErme+/YOu4gPed3sFS72GhtWCgNV9oDsHDnoLY5oDfwjKUc9Z+JOZZ37uAxcm/OCahDHfuu2ugqrfWAVQ==} peerDependencies: @@ -2731,6 +2782,10 @@ packages: resolution: {integrity: sha512-NaHL0+0lLNhX6d9rs+NSt97WH/gIlRHmszXbQ/8/MV/eVcFNdeJ/GYhrFuUc8K7WuPhRhTSdMkCp8VMzhUq85w==} dev: false + /@types/mocha@7.0.2: + resolution: {integrity: sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==} + dev: false + /@types/ms@0.7.32: resolution: {integrity: sha512-xPSg0jm4mqgEkNhowKgZFBNtwoEwF6gJ4Dhww+GFpm3IgtNseHQZ5IqdNwnquZEoANxyDAKDRAdVo4Z72VvD/g==} dev: false @@ -2752,6 +2807,10 @@ packages: form-data: 4.0.0 dev: false + /@types/node@14.18.63: + resolution: {integrity: sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==} + dev: false + /@types/node@16.18.58: resolution: {integrity: sha512-YGncyA25/MaVtQkjWW9r0EFBukZ+JulsLcVZBlGUfIb96OBMjkoRWwQo5IEWJ8Fj06Go3GHw+bjYDitv6BaGsA==} dev: false @@ -3132,6 +3191,11 @@ packages: uri-js: 4.4.1 dev: false + /ansi-colors@3.2.3: + resolution: {integrity: sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==} + engines: {node: '>=6'} + dev: false + /ansi-colors@4.1.1: resolution: {integrity: sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==} engines: {node: '>=6'} @@ -3149,6 +3213,11 @@ packages: engines: {node: '>=4'} dev: false + /ansi-regex@4.1.1: + resolution: {integrity: sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==} + engines: {node: '>=6'} + dev: false + /ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} @@ -3269,6 +3338,17 @@ packages: es-shim-unscopables: 1.0.0 dev: false + /array.prototype.reduce@1.0.6: + resolution: {integrity: sha512-UW+Mz8LG/sPSU8jRDCjVr6J/ZKAGpHfwrZ6kWTG5qCxIEiXdVshqGnu5vEZA8S1y6X4aCSbQZ0/EEsfvEvBiSg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.1 + es-abstract: 1.22.2 + es-array-method-boxes-properly: 1.0.0 + is-string: 1.0.7 + dev: false + /arraybuffer.prototype.slice@1.0.2: resolution: {integrity: sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==} engines: {node: '>= 0.4'} @@ -3611,6 +3691,21 @@ packages: get-func-name: 2.0.2 dev: false + /chokidar@3.3.0: + resolution: {integrity: sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==} + engines: {node: '>= 8.10.0'} + dependencies: + anymatch: 3.1.3 + braces: 3.0.2 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.2.0 + optionalDependencies: + fsevents: 2.1.3 + dev: false + /chokidar@3.5.3: resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} engines: {node: '>= 8.10.0'} @@ -3665,6 +3760,14 @@ packages: engines: {node: '>= 10'} dev: false + /cliui@5.0.0: + resolution: {integrity: sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==} + dependencies: + string-width: 3.1.0 + strip-ansi: 5.2.0 + wrap-ansi: 5.1.0 + dev: false + /cliui@6.0.0: resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} dependencies: @@ -3925,6 +4028,13 @@ packages: ms: 2.0.0 dev: false + /debug@3.2.6: + resolution: {integrity: sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==} + 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) + dependencies: + ms: 2.1.3 + dev: false + /debug@3.2.7: resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} dependencies: @@ -4104,6 +4214,11 @@ packages: resolution: {integrity: sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA==} dev: false + /diff@3.5.0: + resolution: {integrity: sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==} + engines: {node: '>=0.3.1'} + dev: false + /diff@4.0.2: resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} engines: {node: '>=0.3.1'} @@ -4198,6 +4313,10 @@ packages: resolution: {integrity: sha512-G+mpdiAySMuB7kesVRLuyvYRqDmshB7ReKEVuyBPkzQlmiDiLrt7hHHIy4Aff552bgknVN7B2/d3lzhGO5dvpQ==} dev: false + /emoji-regex@7.0.3: + resolution: {integrity: sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==} + dev: false + /emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} dev: false @@ -4306,6 +4425,10 @@ packages: which-typed-array: 1.1.11 dev: false + /es-array-method-boxes-properly@1.0.0: + resolution: {integrity: sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==} + dev: false + /es-set-tostringtag@2.0.1: resolution: {integrity: sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==} engines: {node: '>= 0.4'} @@ -4880,6 +5003,13 @@ packages: pkg-dir: 4.2.0 dev: false + /find-up@3.0.0: + resolution: {integrity: sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==} + engines: {node: '>=6'} + dependencies: + locate-path: 3.0.0 + dev: false + /find-up@4.1.0: resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} engines: {node: '>=8'} @@ -4905,6 +5035,13 @@ packages: rimraf: 3.0.2 dev: false + /flat@4.1.1: + resolution: {integrity: sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==} + hasBin: true + dependencies: + is-buffer: 2.0.5 + dev: false + /flat@5.0.2: resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} hasBin: true @@ -5028,6 +5165,15 @@ packages: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} dev: false + /fsevents@2.1.3: + resolution: {integrity: sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + deprecated: '"Please update to latest v2.3 or v2.2"' + requiresBuild: true + dev: false + optional: true + /fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -5144,6 +5290,17 @@ packages: path-scurry: 1.10.1 dev: false + /glob@7.1.3: + resolution: {integrity: sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==} + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + dev: false + /glob@7.2.0: resolution: {integrity: sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==} dependencies: @@ -5243,6 +5400,11 @@ packages: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} dev: false + /growl@1.10.5: + resolution: {integrity: sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==} + engines: {node: '>=4.x'} + dev: false + /guid-typescript@1.0.9: resolution: {integrity: sha512-Y8T4vYhEfwJOTbouREvG+3XDsjr8E3kIr7uf+JZ0BYloFsttiHU0WfvANVsR7TxNUJa/WpCnw/Ino/p+DeBhBQ==} dev: false @@ -5574,6 +5736,11 @@ packages: engines: {node: '>=0.10.0'} dev: false + /is-fullwidth-code-point@2.0.0: + resolution: {integrity: sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==} + engines: {node: '>=4'} + dev: false + /is-fullwidth-code-point@3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} @@ -5839,6 +6006,14 @@ packages: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} dev: false + /js-yaml@3.13.1: + resolution: {integrity: sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==} + hasBin: true + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + dev: false + /js-yaml@3.14.1: resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} hasBin: true @@ -6231,6 +6406,14 @@ packages: strip-bom: 3.0.0 dev: false + /locate-path@3.0.0: + resolution: {integrity: sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==} + engines: {node: '>=6'} + dependencies: + p-locate: 3.0.0 + path-exists: 3.0.0 + dev: false + /locate-path@5.0.0: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} engines: {node: '>=8'} @@ -6304,6 +6487,13 @@ packages: chalk: 2.4.2 dev: false + /log-symbols@3.0.0: + resolution: {integrity: sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==} + engines: {node: '>=8'} + dependencies: + chalk: 2.4.2 + dev: false + /log-symbols@4.1.0: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} engines: {node: '>=10'} @@ -6560,6 +6750,12 @@ packages: dom-walk: 0.1.2 dev: false + /minimatch@3.0.4: + resolution: {integrity: sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==} + dependencies: + brace-expansion: 1.1.11 + dev: false + /minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} dependencies: @@ -6623,6 +6819,13 @@ packages: resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} dev: false + /mkdirp@0.5.5: + resolution: {integrity: sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==} + hasBin: true + dependencies: + minimist: 1.2.8 + dev: false + /mkdirp@0.5.6: resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} hasBin: true @@ -6661,6 +6864,19 @@ packages: xml: 1.0.1 dev: false + /mocha-junit-reporter@1.23.3(mocha@7.2.0): + resolution: {integrity: sha512-ed8LqbRj1RxZfjt/oC9t12sfrWsjZ3gNnbhV1nuj9R/Jb5/P3Xb4duv2eCfCDMYH+fEu0mqca7m4wsiVjsxsvA==} + peerDependencies: + mocha: '>=2.2.5' + dependencies: + debug: 2.6.9 + md5: 2.3.0 + mkdirp: 0.5.6 + mocha: 7.2.0 + strip-ansi: 4.0.0 + xml: 1.0.1 + dev: false + /mocha-junit-reporter@2.2.1(mocha@10.2.0): resolution: {integrity: sha512-iDn2tlKHn8Vh8o4nCzcUVW4q7iXp7cC4EB78N0cDHIobLymyHNwe0XG8HEHHjc3hJlXm0Vy6zcrxaIhnI2fWmw==} peerDependencies: @@ -6704,6 +6920,37 @@ packages: yargs-unparser: 2.0.0 dev: false + /mocha@7.2.0: + resolution: {integrity: sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==} + engines: {node: '>= 8.10.0'} + hasBin: true + dependencies: + ansi-colors: 3.2.3 + browser-stdout: 1.3.1 + chokidar: 3.3.0 + debug: 3.2.6 + diff: 3.5.0 + escape-string-regexp: 1.0.5 + find-up: 3.0.0 + glob: 7.1.3 + growl: 1.10.5 + he: 1.2.0 + js-yaml: 3.13.1 + log-symbols: 3.0.0 + minimatch: 3.0.4 + mkdirp: 0.5.5 + ms: 2.1.1 + node-environment-flags: 1.0.6 + object.assign: 4.1.0 + strip-json-comments: 2.0.1 + supports-color: 6.0.0 + which: 1.3.1 + wide-align: 1.1.3 + yargs: 13.3.2 + yargs-parser: 13.1.2 + yargs-unparser: 1.6.0 + dev: false + /mock-socket@9.3.1: resolution: {integrity: sha512-qxBgB7Qa2sEQgHFjj0dSigq7fX4k6Saisd5Nelwp2q8mlbAFh5dHV9JTTlF8viYJLSSWgMCZFUom8PJcMNBoJw==} engines: {node: '>= 8'} @@ -6725,6 +6972,10 @@ packages: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} dev: false + /ms@2.1.1: + resolution: {integrity: sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==} + dev: false + /ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} dev: false @@ -6815,6 +7066,13 @@ packages: engines: {node: '>=10.5.0'} dev: false + /node-environment-flags@1.0.6: + resolution: {integrity: sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==} + dependencies: + object.getownpropertydescriptors: 2.1.7 + semver: 5.7.2 + dev: false + /node-fetch@2.6.7: resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} engines: {node: 4.x || >=6.0.0} @@ -6951,6 +7209,16 @@ packages: engines: {node: '>= 0.4'} dev: false + /object.assign@4.1.0: + resolution: {integrity: sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==} + engines: {node: '>= 0.4'} + dependencies: + define-properties: 1.2.1 + function-bind: 1.1.2 + has-symbols: 1.0.3 + object-keys: 1.1.1 + dev: false + /object.assign@4.1.4: resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==} engines: {node: '>= 0.4'} @@ -6970,6 +7238,17 @@ packages: es-abstract: 1.22.2 dev: false + /object.getownpropertydescriptors@2.1.7: + resolution: {integrity: sha512-PrJz0C2xJ58FNn11XV2lr4Jt5Gzl94qpy9Lu0JlfEj14z88sqbSBJCBEzdlNUCzY2gburhbrwOZ5BHCmuNUy0g==} + engines: {node: '>= 0.8'} + dependencies: + array.prototype.reduce: 1.0.6 + call-bind: 1.0.2 + define-properties: 1.2.1 + es-abstract: 1.22.2 + safe-array-concat: 1.0.1 + dev: false + /object.groupby@1.0.1: resolution: {integrity: sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==} dependencies: @@ -7089,6 +7368,13 @@ packages: yocto-queue: 0.1.0 dev: false + /p-locate@3.0.0: + resolution: {integrity: sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==} + engines: {node: '>=6'} + dependencies: + p-limit: 2.3.0 + dev: false + /p-locate@4.1.0: resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} engines: {node: '>=8'} @@ -7174,6 +7460,11 @@ packages: resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} dev: false + /path-exists@3.0.0: + resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==} + engines: {node: '>=4'} + dev: false + /path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} @@ -7640,6 +7931,13 @@ packages: util-deprecate: 1.0.2 dev: false + /readdirp@3.2.0: + resolution: {integrity: sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==} + engines: {node: '>= 8'} + dependencies: + picomatch: 2.3.1 + dev: false + /readdirp@3.6.0: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} @@ -8227,6 +8525,23 @@ packages: engines: {node: '>=0.6.19'} dev: false + /string-width@2.1.1: + resolution: {integrity: sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==} + engines: {node: '>=4'} + dependencies: + is-fullwidth-code-point: 2.0.0 + strip-ansi: 4.0.0 + dev: false + + /string-width@3.1.0: + resolution: {integrity: sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==} + engines: {node: '>=6'} + dependencies: + emoji-regex: 7.0.3 + is-fullwidth-code-point: 2.0.0 + strip-ansi: 5.2.0 + dev: false + /string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} @@ -8302,6 +8617,13 @@ packages: ansi-regex: 3.0.1 dev: false + /strip-ansi@5.2.0: + resolution: {integrity: sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==} + engines: {node: '>=6'} + dependencies: + ansi-regex: 4.1.1 + dev: false + /strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} @@ -8368,6 +8690,13 @@ packages: has-flag: 3.0.0 dev: false + /supports-color@6.0.0: + resolution: {integrity: sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==} + engines: {node: '>=6'} + dependencies: + has-flag: 3.0.0 + dev: false + /supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} @@ -8511,6 +8840,37 @@ packages: code-block-writer: 12.0.0 dev: false + /ts-node@10.9.1(@types/node@14.18.63)(typescript@5.0.4): + resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.9 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 14.18.63 + acorn: 8.10.0 + acorn-walk: 8.2.0 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.0.4 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + dev: false + /ts-node@10.9.1(@types/node@16.18.58)(typescript@5.0.4): resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} hasBin: true @@ -8926,6 +9286,12 @@ packages: isexe: 2.0.0 dev: false + /wide-align@1.1.3: + resolution: {integrity: sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==} + dependencies: + string-width: 2.1.1 + dev: false + /word-wrap@1.2.5: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} @@ -8935,6 +9301,15 @@ packages: resolution: {integrity: sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==} dev: false + /wrap-ansi@5.1.0: + resolution: {integrity: sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==} + engines: {node: '>=6'} + dependencies: + ansi-styles: 3.2.1 + string-width: 3.1.0 + strip-ansi: 5.2.0 + dev: false + /wrap-ansi@6.2.0: resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} engines: {node: '>=8'} @@ -9087,6 +9462,13 @@ packages: engines: {node: '>= 14'} dev: false + /yargs-parser@13.1.2: + resolution: {integrity: sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==} + dependencies: + camelcase: 5.3.1 + decamelize: 1.2.0 + dev: false + /yargs-parser@18.1.3: resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} engines: {node: '>=6'} @@ -9110,6 +9492,15 @@ packages: engines: {node: '>=12'} dev: false + /yargs-unparser@1.6.0: + resolution: {integrity: sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==} + engines: {node: '>=6'} + dependencies: + flat: 4.1.1 + lodash: 4.17.21 + yargs: 13.3.2 + dev: false + /yargs-unparser@2.0.0: resolution: {integrity: sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==} engines: {node: '>=10'} @@ -9120,6 +9511,21 @@ packages: is-plain-obj: 2.1.0 dev: false + /yargs@13.3.2: + resolution: {integrity: sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==} + dependencies: + cliui: 5.0.0 + find-up: 3.0.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + require-main-filename: 2.0.0 + set-blocking: 2.0.0 + string-width: 3.1.0 + which-module: 2.0.1 + y18n: 4.0.3 + yargs-parser: 13.1.2 + dev: false + /yargs@15.4.1: resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} engines: {node: '>=8'} @@ -17746,6 +18152,50 @@ packages: - utf-8-validate dev: false + file:projects/defender-easm-rest.tgz: + resolution: {integrity: sha512-s0JukqZiKVVk8jG0XA/lVrTOfya6qonuMcpZMP86u92EY7VVyq72ySoqV/dsorrlMdZGsXeEVWf6oH8b8ylCMg==, tarball: file:projects/defender-easm-rest.tgz} + name: '@rush-temp/defender-easm-rest' + version: 0.0.0 + dependencies: + '@azure/identity': 2.1.0 + '@microsoft/api-extractor': 7.38.0(@types/node@14.18.63) + '@types/chai': 4.3.8 + '@types/mocha': 7.0.2 + '@types/node': 14.18.63 + autorest: 3.6.3 + chai: 4.3.10 + cross-env: 7.0.3 + dotenv: 16.3.1 + eslint: 8.51.0 + karma: 6.4.2(debug@4.3.4) + karma-chrome-launcher: 3.2.0 + karma-coverage: 2.2.1 + karma-env-preprocessor: 0.1.1 + karma-firefox-launcher: 2.1.2 + karma-junit-reporter: 2.0.1(karma@6.4.2) + karma-mocha: 2.0.1 + karma-mocha-reporter: 2.2.5(karma@6.4.2) + karma-source-map-support: 1.4.0 + karma-sourcemap-loader: 0.4.0 + mkdirp: 2.1.6 + mocha: 7.2.0 + mocha-junit-reporter: 1.23.3(mocha@7.2.0) + nyc: 15.1.0 + prettier: 2.8.8 + rimraf: 5.0.5 + source-map-support: 0.5.21 + ts-node: 10.9.1(@types/node@14.18.63)(typescript@5.0.4) + tslib: 2.6.2 + typescript: 5.0.4 + transitivePeerDependencies: + - '@swc/core' + - '@swc/wasm' + - bufferutil + - debug + - supports-color + - utf-8-validate + dev: false + file:projects/dev-tool.tgz: resolution: {integrity: sha512-grphK+PUgsY0s72iEX60vMMAn9GEJ9mfafBCsySKUsP42rzviK2OhtsFtPY+Qx6Fd9+PbkEzHdchqYwVF43LFQ==, tarball: file:projects/dev-tool.tgz} name: '@rush-temp/dev-tool' diff --git a/rush.json b/rush.json index 856393f90efa..0190c3576eba 100644 --- a/rush.json +++ b/rush.json @@ -523,7 +523,9 @@ { "packageName": "@azure/core-http", "projectFolder": "sdk/core/core-http", - "decoupledLocalDependencies": ["@azure/core-tracing"], + "decoupledLocalDependencies": [ + "@azure/core-tracing" + ], "versionPolicyName": "core" }, { @@ -614,7 +616,9 @@ { "packageName": "@azure/identity", "projectFolder": "sdk/identity/identity", - "decoupledLocalDependencies": ["@azure/keyvault-keys"], + "decoupledLocalDependencies": [ + "@azure/keyvault-keys" + ], "versionPolicyName": "client" }, { @@ -2121,6 +2125,11 @@ "packageName": "@azure/arm-playwrighttesting", "projectFolder": "sdk/playwrighttesting/arm-playwrighttesting", "versionPolicyName": "management" + }, + { + "packageName": "@azure-rest/defender-easm-rest", + "projectFolder": "sdk/easm/defendereasm-rest", + "versionPolicyName": "client" } ] -} +} \ No newline at end of file diff --git a/sdk/easm/ci.yml b/sdk/easm/ci.yml new file mode 100644 index 000000000000..ea41785c9823 --- /dev/null +++ b/sdk/easm/ci.yml @@ -0,0 +1,33 @@ +# NOTE: Please refer to https://aka.ms/azsdk/engsys/ci-yaml before editing this file. + +trigger: + branches: + include: + - main + - feature/* + - release/* + - hotfix/* + exclude: + - feature/v4 + paths: + include: + - sdk/easm/ +pr: + branches: + include: + - main + - feature/* + - release/* + - hotfix/* + exclude: + - feature/v4 + paths: + include: + - sdk/easm/ +extends: + template: /eng/pipelines/templates/stages/archetype-sdk-client.yml + parameters: + ServiceDirectory: easm + Artifacts: + - name: azure-rest-defender-easm-rest + safeName: azurerestdefendereasmrest diff --git a/sdk/easm/defendereasm-rest/.eslintrc.json b/sdk/easm/defendereasm-rest/.eslintrc.json new file mode 100644 index 000000000000..619797ac39b6 --- /dev/null +++ b/sdk/easm/defendereasm-rest/.eslintrc.json @@ -0,0 +1,11 @@ +{ + "plugins": ["@azure/azure-sdk"], + "extends": ["plugin:@azure/azure-sdk/azure-sdk-base"], + "rules": { + "@azure/azure-sdk/ts-modules-only-named": "warn", + "@azure/azure-sdk/ts-apiextractor-json-types": "warn", + "@azure/azure-sdk/ts-package-json-types": "warn", + "@azure/azure-sdk/ts-package-json-engine-is-present": "warn", + "tsdoc/syntax": "warn" + } +} diff --git a/sdk/easm/defendereasm-rest/README.md b/sdk/easm/defendereasm-rest/README.md new file mode 100644 index 000000000000..27760df9d636 --- /dev/null +++ b/sdk/easm/defendereasm-rest/README.md @@ -0,0 +1,59 @@ +# Azure Easm REST client library for JavaScript + +Defender EASM discovers and maps your digital attack surface to provide an "outside-in" perspective using probes to discover assets. The assets are provided with detailed metadata associated, including vulnerabilities, configurations and web components, allowing customers to view and prioritize external risk. The EASM REST API enables you to develop clients that integrate with your application. + +**Please rely heavily on our [REST client docs](https://github.com/Azure/azure-sdk-for-js/blob/main/documentation/rest-clients.md) to use this library** + +Key links: + +- [Source code](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/easm/defendereasm-rest) +- [Package (NPM)](https://www.npmjs.com/package/@azure-rest/defender-easm-rest) +- [API reference documentation](https://docs.microsoft.com/javascript/api/@azure-rest/defender-easm-rest?view=azure-node-preview) +- [Samples](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/easm/defendereasm-rest/samples) + +## Getting started + +### Currently supported environments + +- LTS versions of Node.js + +### Prerequisites + +- You must have an [Azure subscription](https://azure.microsoft.com/free/) to use this package. + +### Install the `@azure-rest/defender-easm-rest` package + +Install the Azure Easm REST client REST client library for JavaScript with `npm`: + +```bash +npm install @azure-rest/defender-easm-rest +``` + +### Create and authenticate a `EasmClient` + +To use an [Azure Active Directory (AAD) token credential](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/samples/AzureIdentityExamples.md#authenticating-with-a-pre-fetched-access-token), +provide an instance of the desired credential type obtained from the +[@azure/identity](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/identity/identity#credentials) library. + +To authenticate with AAD, you must first `npm` install [`@azure/identity`](https://www.npmjs.com/package/@azure/identity) + +After setup, you can choose which type of [credential](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/identity/identity#credentials) from `@azure/identity` to use. +As an example, [DefaultAzureCredential](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/identity/identity#defaultazurecredential) +can be used to authenticate the client. + +Set the values of the client ID, tenant ID, and client secret of the AAD application as environment variables: +AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_CLIENT_SECRET + +## 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 +const { setLogLevel } = require("@azure/logger"); + +setLogLevel("info"); +``` + +For more detailed instructions on how to enable logs, you can look at the [@azure/logger package docs](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/core/logger). diff --git a/sdk/easm/defendereasm-rest/api-extractor.json b/sdk/easm/defendereasm-rest/api-extractor.json new file mode 100644 index 000000000000..20c97b73c488 --- /dev/null +++ b/sdk/easm/defendereasm-rest/api-extractor.json @@ -0,0 +1,31 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", + "mainEntryPointFilePath": "./types/src/index.d.ts", + "docModel": { + "enabled": true + }, + "apiReport": { + "enabled": true, + "reportFolder": "./review" + }, + "dtsRollup": { + "enabled": true, + "untrimmedFilePath": "", + "publicTrimmedFilePath": "./types/defender-easm-rest.d.ts" + }, + "messages": { + "tsdocMessageReporting": { + "default": { + "logLevel": "none" + } + }, + "extractorMessageReporting": { + "ae-missing-release-tag": { + "logLevel": "none" + }, + "ae-unresolved-link": { + "logLevel": "none" + } + } + } +} \ No newline at end of file diff --git a/sdk/easm/defendereasm-rest/karma.conf.js b/sdk/easm/defendereasm-rest/karma.conf.js new file mode 100644 index 000000000000..a9d5f1b5fc59 --- /dev/null +++ b/sdk/easm/defendereasm-rest/karma.conf.js @@ -0,0 +1,133 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +// https://github.com/karma-runner/karma-chrome-launcher +process.env.CHROME_BIN = require("puppeteer").executablePath(); +require("dotenv").config(); +const { relativeRecordingsPath } = require("@azure-tools/test-recorder"); +process.env.RECORDINGS_RELATIVE_PATH = relativeRecordingsPath(); + +module.exports = function (config) { + config.set({ + // base path that will be used to resolve all patterns (eg. files, exclude) + basePath: "./", + + // frameworks to use + // available frameworks: https://npmjs.org/browse/keyword/karma-adapter + frameworks: ["source-map-support", "mocha"], + + plugins: [ + "karma-mocha", + "karma-mocha-reporter", + "karma-chrome-launcher", + "karma-firefox-launcher", + "karma-env-preprocessor", + "karma-coverage", + "karma-sourcemap-loader", + "karma-junit-reporter", + "karma-source-map-support", + ], + + // list of files / patterns to load in the browser + files: [ + "dist-test/index.browser.js", + { + pattern: "dist-test/index.browser.js.map", + type: "html", + included: false, + served: true, + }, + ], + + // list of files / patterns to exclude + exclude: [], + + // preprocess matching files before serving them to the browser + // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor + preprocessors: { + "**/*.js": ["sourcemap", "env"], + // IMPORTANT: COMMENT following line if you want to debug in your browsers!! + // Preprocess source file to calculate code coverage, however this will make source file unreadable + // "dist-test/index.js": ["coverage"] + }, + + envPreprocessor: [ + "TEST_MODE", + "ENDPOINT", + "AZURE_CLIENT_SECRET", + "AZURE_CLIENT_ID", + "AZURE_TENANT_ID", + "SUBSCRIPTION_ID", + "RECORDINGS_RELATIVE_PATH", + ], + + // test results reporter to use + // possible values: 'dots', 'progress' + // available reporters: https://npmjs.org/browse/keyword/karma-reporter + reporters: ["mocha", "coverage", "junit"], + + coverageReporter: { + // specify a common output directory + dir: "coverage-browser/", + reporters: [ + { type: "json", subdir: ".", file: "coverage.json" }, + { type: "lcovonly", subdir: ".", file: "lcov.info" }, + { type: "html", subdir: "html" }, + { type: "cobertura", subdir: ".", file: "cobertura-coverage.xml" }, + ], + }, + + junitReporter: { + outputDir: "", // results will be saved as $outputDir/$browserName.xml + outputFile: "test-results.browser.xml", // if included, results will be saved as $outputDir/$browserName/$outputFile + suite: "", // suite will become the package name attribute in xml testsuite element + useBrowserName: false, // add browser name to report and classes names + nameFormatter: undefined, // function (browser, result) to customize the name attribute in xml testcase element + classNameFormatter: undefined, // function (browser, result) to customize the classname attribute in xml testcase element + properties: {}, // key value pair of properties to add to the section of the report + }, + + // web server port + port: 9876, + + // enable / disable colors in the output (reporters and logs) + colors: true, + + // level of logging + // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG + logLevel: config.LOG_INFO, + + // enable / disable watching file and executing tests whenever any file changes + autoWatch: false, + + // --no-sandbox allows our tests to run in Linux without having to change the system. + // --disable-web-security allows us to authenticate from the browser without having to write tests using interactive auth, which would be far more complex. + browsers: ["ChromeHeadlessNoSandbox"], + customLaunchers: { + ChromeHeadlessNoSandbox: { + base: "ChromeHeadless", + flags: ["--no-sandbox", "--disable-web-security"], + }, + }, + + // Continuous Integration mode + // if true, Karma captures browsers, runs the tests and exits + singleRun: false, + + // Concurrency level + // how many browser should be started simultaneous + concurrency: 1, + + browserNoActivityTimeout: 60000000, + browserDisconnectTimeout: 10000, + browserDisconnectTolerance: 3, + + client: { + mocha: { + // change Karma's debug.html to the mocha web reporter + reporter: "html", + timeout: "600000", + }, + }, + }); +}; diff --git a/sdk/easm/defendereasm-rest/package.json b/sdk/easm/defendereasm-rest/package.json new file mode 100644 index 000000000000..70f1be9e6809 --- /dev/null +++ b/sdk/easm/defendereasm-rest/package.json @@ -0,0 +1,118 @@ +{ + "name": "@azure-rest/defender-easm-rest", + "sdk-type": "client", + "author": "Microsoft Corporation", + "version": "1.0.0-beta.1", + "description": "undefined", + "keywords": [ + "node", + "azure", + "cloud", + "typescript", + "browser", + "isomorphic" + ], + "license": "MIT", + "main": "dist/index.js", + "module": "./dist-esm/src/index.js", + "types": "./types/defender-easm-rest.d.ts", + "repository": "github:Azure/azure-sdk-for-js", + "bugs": { + "url": "https://github.com/Azure/azure-sdk-for-js/issues" + }, + "files": [ + "dist/", + "dist-esm/src/", + "types/defender-easm-rest.d.ts", + "README.md", + "LICENSE", + "review/*" + ], + "engines": { + "node": ">=14.0.0" + }, + "scripts": { + "audit": "node ../../../common/scripts/rush-audit.js && rimraf node_modules package-lock.json && npm i --package-lock-only 2>&1 && npm audit", + "build:browser": "tsc -p . && cross-env ONLY_BROWSER=true rollup -c 2>&1", + "build:node": "tsc -p . && cross-env ONLY_NODE=true rollup -c 2>&1", + "build:samples": "echo skipped.", + "build:test": "tsc -p . && dev-tool run bundle", + "build:debug": "tsc -p . && dev-tool run bundle && api-extractor run --local", + "check-format": "prettier --list-different --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"*.{js,json}\" \"test/**/*.ts\"", + "clean": "rimraf --glob dist dist-browser dist-esm test-dist temp types *.tgz *.log", + "execute:samples": "echo skipped", + "extract-api": "rimraf review && mkdirp ./review && api-extractor run --local", + "format": "prettier --write --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"*.{js,json}\" \"test/**/*.ts\"", + "generate:client": "echo skipped", + "integration-test:browser": "dev-tool run test:browser", + "integration-test:node": "dev-tool run test:node-js-input -- --timeout 5000000 'dist-esm/test/**/*.spec.js'", + "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", + "test:browser": "npm run clean && npm run build:test && npm run unit-test:browser", + "test:node": "npm run clean && npm run build:test && npm run unit-test:node", + "test": "npm run clean && npm run build:test && npm run unit-test", + "unit-test": "npm run unit-test:node && npm run unit-test:browser", + "unit-test:node": "dev-tool run test:node-ts-input -- --timeout 1200000 --exclude 'test/**/browser/*.spec.ts' 'test/**/*.spec.ts'", + "unit-test:browser": "dev-tool run test:browser", + "build": "npm run clean && tsc -p . && dev-tool run bundle && mkdirp ./review && api-extractor run --local" + }, + "sideEffects": false, + "autoPublish": false, + "dependencies": { + "@azure/core-auth": "^1.3.0", + "@azure-rest/core-client": "^1.1.4", + "@azure/core-rest-pipeline": "^1.12.0", + "@azure/logger": "^1.0.0", + "tslib": "^2.2.0", + "@azure/core-paging": "^1.5.0" + }, + "devDependencies": { + "@microsoft/api-extractor": "^7.31.1", + "autorest": "latest", + "@types/node": "^14.0.0", + "dotenv": "^16.0.0", + "eslint": "^8.0.0", + "mkdirp": "^2.1.2", + "prettier": "^2.5.1", + "rimraf": "^5.0.0", + "source-map-support": "^0.5.9", + "typescript": "~5.0.0", + "@azure/dev-tool": "^1.0.0", + "@azure/eslint-plugin-azure-sdk": "^3.0.0", + "@azure-tools/test-credential": "^1.0.0", + "@azure/identity": "^2.0.1", + "@azure-tools/test-recorder": "^3.0.0", + "mocha": "^7.1.1", + "@types/mocha": "^7.0.2", + "mocha-junit-reporter": "^1.18.0", + "cross-env": "^7.0.2", + "@types/chai": "^4.2.8", + "chai": "^4.2.0", + "karma-chrome-launcher": "^3.0.0", + "karma-coverage": "^2.0.0", + "karma-env-preprocessor": "^0.1.1", + "karma-firefox-launcher": "^2.1.2", + "karma-junit-reporter": "^2.0.1", + "karma-mocha-reporter": "^2.2.5", + "karma-mocha": "^2.0.1", + "karma-source-map-support": "~1.4.0", + "karma-sourcemap-loader": "^0.4.0", + "karma": "^6.2.0", + "nyc": "^15.0.0", + "ts-node": "^10.0.0" + }, + "homepage": "https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/easm/defendereasm-rest/README.md", + "//metadata": { + "constantPaths": [ + { + "path": "src/easmClient.ts", + "prefix": "userAgentInfo" + } + ] + }, + "browser": { + "./dist-esm/test/public/utils/env.js": "./dist-esm/test/public/utils/env.browser.js" + } +} \ No newline at end of file diff --git a/sdk/easm/defendereasm-rest/src/clientDefinitions.ts b/sdk/easm/defendereasm-rest/src/clientDefinitions.ts new file mode 100644 index 000000000000..e722ec36b11e --- /dev/null +++ b/sdk/easm/defendereasm-rest/src/clientDefinitions.ts @@ -0,0 +1,335 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { + ListAssetResourceParameters, + UpdateAssetsParameters, + GetAssetResourceParameters, + ListDataConnectionParameters, + ValidateDataConnectionParameters, + GetDataConnectionParameters, + CreateOrReplaceDataConnectionParameters, + DeleteDataConnectionParameters, + ListDiscoGroupParameters, + ValidateDiscoGroupParameters, + GetDiscoGroupParameters, + CreateOrReplaceDiscoGroupParameters, + RunDiscoGroupParameters, + ListRunsParameters, + ListDiscoTemplateParameters, + GetDiscoTemplateParameters, + GetBillableParameters, + GetSnapshotParameters, + GetSummaryParameters, + ListSavedFilterParameters, + GetSavedFilterParameters, + CreateOrReplaceSavedFilterParameters, + DeleteSavedFilterParameters, + ListTaskParameters, + GetTaskParameters, + CancelTaskParameters, +} from "./parameters"; +import { + ListAssetResource200Response, + ListAssetResourceDefaultResponse, + UpdateAssets200Response, + UpdateAssetsDefaultResponse, + GetAssetResource200Response, + GetAssetResourceDefaultResponse, + ListDataConnection200Response, + ListDataConnectionDefaultResponse, + ValidateDataConnection200Response, + ValidateDataConnectionDefaultResponse, + GetDataConnection200Response, + GetDataConnectionDefaultResponse, + CreateOrReplaceDataConnection200Response, + CreateOrReplaceDataConnectionDefaultResponse, + DeleteDataConnection204Response, + DeleteDataConnectionDefaultResponse, + ListDiscoGroup200Response, + ListDiscoGroupDefaultResponse, + ValidateDiscoGroup200Response, + ValidateDiscoGroupDefaultResponse, + GetDiscoGroup200Response, + GetDiscoGroupDefaultResponse, + CreateOrReplaceDiscoGroup200Response, + CreateOrReplaceDiscoGroupDefaultResponse, + RunDiscoGroup204Response, + RunDiscoGroupDefaultResponse, + ListRuns200Response, + ListRunsDefaultResponse, + ListDiscoTemplate200Response, + ListDiscoTemplateDefaultResponse, + GetDiscoTemplate200Response, + GetDiscoTemplateDefaultResponse, + GetBillable200Response, + GetBillableDefaultResponse, + GetSnapshot200Response, + GetSnapshotDefaultResponse, + GetSummary200Response, + GetSummaryDefaultResponse, + ListSavedFilter200Response, + ListSavedFilterDefaultResponse, + GetSavedFilter200Response, + GetSavedFilterDefaultResponse, + CreateOrReplaceSavedFilter200Response, + CreateOrReplaceSavedFilterDefaultResponse, + DeleteSavedFilter204Response, + DeleteSavedFilterDefaultResponse, + ListTask200Response, + ListTaskDefaultResponse, + GetTask200Response, + GetTaskDefaultResponse, + CancelTask200Response, + CancelTaskDefaultResponse, +} from "./responses"; +import { Client, StreamableMethod } from "@azure-rest/core-client"; + +export interface ListAssetResource { + /** Retrieve a list of assets for the provided search parameters. */ + get( + options?: ListAssetResourceParameters + ): StreamableMethod< + ListAssetResource200Response | ListAssetResourceDefaultResponse + >; + /** Update labels on assets matching the provided filter. */ + post( + options: UpdateAssetsParameters + ): StreamableMethod; +} + +export interface GetAssetResource { + /** Retrieve an asset by assetId. */ + get( + options?: GetAssetResourceParameters + ): StreamableMethod< + GetAssetResource200Response | GetAssetResourceDefaultResponse + >; +} + +export interface ListDataConnection { + /** Retrieve a list of data connections. */ + get( + options?: ListDataConnectionParameters + ): StreamableMethod< + ListDataConnection200Response | ListDataConnectionDefaultResponse + >; +} + +export interface ValidateDataConnection { + /** Validate a data connection with a given dataConnectionName. */ + post( + options?: ValidateDataConnectionParameters + ): StreamableMethod< + ValidateDataConnection200Response | ValidateDataConnectionDefaultResponse + >; +} + +export interface GetDataConnection { + /** Retrieve a data connection with a given dataConnectionName. */ + get( + options?: GetDataConnectionParameters + ): StreamableMethod< + GetDataConnection200Response | GetDataConnectionDefaultResponse + >; + /** Create or replace a data connection with a given dataConnectionName. */ + put( + options?: CreateOrReplaceDataConnectionParameters + ): StreamableMethod< + | CreateOrReplaceDataConnection200Response + | CreateOrReplaceDataConnectionDefaultResponse + >; + /** Delete a data connection with a given dataConnectionName. */ + delete( + options?: DeleteDataConnectionParameters + ): StreamableMethod< + DeleteDataConnection204Response | DeleteDataConnectionDefaultResponse + >; +} + +export interface ListDiscoGroup { + /** Retrieve a list of discovery group for the provided search parameters. */ + get( + options?: ListDiscoGroupParameters + ): StreamableMethod< + ListDiscoGroup200Response | ListDiscoGroupDefaultResponse + >; +} + +export interface ValidateDiscoGroup { + /** Validate a discovery group with a given groupName. */ + post( + options?: ValidateDiscoGroupParameters + ): StreamableMethod< + ValidateDiscoGroup200Response | ValidateDiscoGroupDefaultResponse + >; +} + +export interface GetDiscoGroup { + /** Retrieve a discovery group with a given groupName. */ + get( + options?: GetDiscoGroupParameters + ): StreamableMethod; + /** Create a discovery group with a given groupName. */ + put( + options?: CreateOrReplaceDiscoGroupParameters + ): StreamableMethod< + | CreateOrReplaceDiscoGroup200Response + | CreateOrReplaceDiscoGroupDefaultResponse + >; +} + +export interface RunDiscoGroup { + /** Run a discovery group with a given groupName. */ + post( + options?: RunDiscoGroupParameters + ): StreamableMethod; +} + +export interface ListRuns { + /** Retrieve a collection of discovery run results for a discovery group with a given groupName. */ + get( + options?: ListRunsParameters + ): StreamableMethod; +} + +export interface ListDiscoTemplate { + /** Retrieve a list of disco templates for the provided search parameters. */ + get( + options?: ListDiscoTemplateParameters + ): StreamableMethod< + ListDiscoTemplate200Response | ListDiscoTemplateDefaultResponse + >; +} + +export interface GetDiscoTemplate { + /** Retrieve a disco template with a given templateId. */ + get( + options?: GetDiscoTemplateParameters + ): StreamableMethod< + GetDiscoTemplate200Response | GetDiscoTemplateDefaultResponse + >; +} + +export interface GetBillable { + /** Get billable assets summary for the workspace. */ + post( + options?: GetBillableParameters + ): StreamableMethod; +} + +export interface GetSnapshot { + /** Get the most recent snapshot of asset summary values for the snapshot request. */ + post( + options?: GetSnapshotParameters + ): StreamableMethod; +} + +export interface GetSummary { + /** Get asset summary details for the summary request. */ + post( + options?: GetSummaryParameters + ): StreamableMethod; +} + +export interface ListSavedFilter { + /** Retrieve a list of saved filters for the provided search parameters. */ + get( + options?: ListSavedFilterParameters + ): StreamableMethod< + ListSavedFilter200Response | ListSavedFilterDefaultResponse + >; +} + +export interface GetSavedFilter { + /** Retrieve a saved filter by filterName. */ + get( + options?: GetSavedFilterParameters + ): StreamableMethod< + GetSavedFilter200Response | GetSavedFilterDefaultResponse + >; + /** Create or replace a saved filter with a given filterName. */ + put( + options?: CreateOrReplaceSavedFilterParameters + ): StreamableMethod< + | CreateOrReplaceSavedFilter200Response + | CreateOrReplaceSavedFilterDefaultResponse + >; + /** Delete a saved filter with a given filterName. */ + delete( + options?: DeleteSavedFilterParameters + ): StreamableMethod< + DeleteSavedFilter204Response | DeleteSavedFilterDefaultResponse + >; +} + +export interface ListTask { + /** Retrieve a list of tasks for the provided search parameters. */ + get( + options?: ListTaskParameters + ): StreamableMethod; +} + +export interface GetTask { + /** Retrieve a task by taskId. */ + get( + options?: GetTaskParameters + ): StreamableMethod; +} + +export interface CancelTask { + /** Cancel a task by taskId. */ + post( + options?: CancelTaskParameters + ): StreamableMethod; +} + +export interface Routes { + /** Resource for '/assets' has methods for the following verbs: get, post */ + (path: "/assets"): ListAssetResource; + /** Resource for '/assets/\{assetId\}' has methods for the following verbs: get */ + (path: "/assets/{assetId}", assetId: string): GetAssetResource; + /** Resource for '/dataConnections' has methods for the following verbs: get */ + (path: "/dataConnections"): ListDataConnection; + /** Resource for '/dataConnections:validate' has methods for the following verbs: post */ + (path: "/dataConnections:validate"): ValidateDataConnection; + /** Resource for '/dataConnections/\{dataConnectionName\}' has methods for the following verbs: get, put, delete */ + ( + path: "/dataConnections/{dataConnectionName}", + dataConnectionName: string + ): GetDataConnection; + /** Resource for '/discoGroups' has methods for the following verbs: get */ + (path: "/discoGroups"): ListDiscoGroup; + /** Resource for '/discoGroups:validate' has methods for the following verbs: post */ + (path: "/discoGroups:validate"): ValidateDiscoGroup; + /** Resource for '/discoGroups/\{groupName\}' has methods for the following verbs: get, put */ + (path: "/discoGroups/{groupName}", groupName: string): GetDiscoGroup; + /** Resource for '/discoGroups/\{groupName\}:run' has methods for the following verbs: post */ + (path: "/discoGroups/{groupName}:run", groupName: string): RunDiscoGroup; + /** Resource for '/discoGroups/\{groupName\}/runs' has methods for the following verbs: get */ + (path: "/discoGroups/{groupName}/runs", groupName: string): ListRuns; + /** Resource for '/discoTemplates' has methods for the following verbs: get */ + (path: "/discoTemplates"): ListDiscoTemplate; + /** Resource for '/discoTemplates/\{templateId\}' has methods for the following verbs: get */ + (path: "/discoTemplates/{templateId}", templateId: string): GetDiscoTemplate; + /** Resource for '/reports/assets:getBillable' has methods for the following verbs: post */ + (path: "/reports/assets:getBillable"): GetBillable; + /** Resource for '/reports/assets:getSnapshot' has methods for the following verbs: post */ + (path: "/reports/assets:getSnapshot"): GetSnapshot; + /** Resource for '/reports/assets:getSummary' has methods for the following verbs: post */ + (path: "/reports/assets:getSummary"): GetSummary; + /** Resource for '/savedFilters' has methods for the following verbs: get */ + (path: "/savedFilters"): ListSavedFilter; + /** Resource for '/savedFilters/\{filterName\}' has methods for the following verbs: get, put, delete */ + (path: "/savedFilters/{filterName}", filterName: string): GetSavedFilter; + /** Resource for '/tasks' has methods for the following verbs: get */ + (path: "/tasks"): ListTask; + /** Resource for '/tasks/\{taskId\}' has methods for the following verbs: get */ + (path: "/tasks/{taskId}", taskId: string): GetTask; + /** Resource for '/tasks/\{taskId\}:cancel' has methods for the following verbs: post */ + (path: "/tasks/{taskId}:cancel", taskId: string): CancelTask; +} + +export type EasmClient = Client & { + path: Routes; +}; diff --git a/sdk/easm/defendereasm-rest/src/easmClient.ts b/sdk/easm/defendereasm-rest/src/easmClient.ts new file mode 100644 index 000000000000..c3d8d1c2a270 --- /dev/null +++ b/sdk/easm/defendereasm-rest/src/easmClient.ts @@ -0,0 +1,57 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { getClient, ClientOptions } from "@azure-rest/core-client"; +import { logger } from "./logger"; +import { TokenCredential } from "@azure/core-auth"; +import { EasmClient } from "./clientDefinitions"; + +/** + * Initialize a new instance of `EasmClient` + * @param endpoint - The endpoint hosting the requested resource. For example, https://{region}.easm.defender.microsoft.com + * @param subscriptionId - The ID of the target subscription. + * @param resourceGroupName - The name of the Resource Group. + * @param workspaceName - The name of the Workspace. + * @param credentials - uniquely identify client credential + * @param options - the parameter for all optional parameters + */ +export default function createClient( + endpoint: string, + subscriptionId: string, + resourceGroupName: string, + workspaceName: string, + credentials: TokenCredential, + options: ClientOptions = {} +): EasmClient { + const baseUrl = + options.baseUrl ?? + `${endpoint}/subscriptions/${subscriptionId}/resourceGroups/${resourceGroupName}/workspaces/${workspaceName}`; + options.apiVersion = options.apiVersion ?? "2023-03-01-preview"; + options = { + ...options, + credentials: { + scopes: options.credentials?.scopes ?? [ + "https://easm.defender.microsoft.com/.default", + ], + }, + }; + + const userAgentInfo = `azsdk-js-defender-easm-rest/1.0.0-beta.1`; + const userAgentPrefix = + options.userAgentOptions && options.userAgentOptions.userAgentPrefix + ? `${options.userAgentOptions.userAgentPrefix} ${userAgentInfo}` + : `${userAgentInfo}`; + options = { + ...options, + userAgentOptions: { + userAgentPrefix, + }, + loggingOptions: { + logger: options.loggingOptions?.logger ?? logger.info, + }, + }; + + const client = getClient(baseUrl, credentials, options) as EasmClient; + + return client; +} diff --git a/sdk/easm/defendereasm-rest/src/index.ts b/sdk/easm/defendereasm-rest/src/index.ts new file mode 100644 index 000000000000..42cb62c844d7 --- /dev/null +++ b/sdk/easm/defendereasm-rest/src/index.ts @@ -0,0 +1,15 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import EasmClient from "./easmClient"; + +export * from "./easmClient"; +export * from "./parameters"; +export * from "./responses"; +export * from "./clientDefinitions"; +export * from "./isUnexpected"; +export * from "./models"; +export * from "./outputModels"; +export * from "./paginateHelper"; + +export default EasmClient; diff --git a/sdk/easm/defendereasm-rest/src/isUnexpected.ts b/sdk/easm/defendereasm-rest/src/isUnexpected.ts new file mode 100644 index 000000000000..fe22491d527a --- /dev/null +++ b/sdk/easm/defendereasm-rest/src/isUnexpected.ts @@ -0,0 +1,338 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { + ListAssetResource200Response, + ListAssetResourceDefaultResponse, + UpdateAssets200Response, + UpdateAssetsDefaultResponse, + GetAssetResource200Response, + GetAssetResourceDefaultResponse, + ListDataConnection200Response, + ListDataConnectionDefaultResponse, + ValidateDataConnection200Response, + ValidateDataConnectionDefaultResponse, + GetDataConnection200Response, + GetDataConnectionDefaultResponse, + CreateOrReplaceDataConnection200Response, + CreateOrReplaceDataConnectionDefaultResponse, + DeleteDataConnection204Response, + DeleteDataConnectionDefaultResponse, + ListDiscoGroup200Response, + ListDiscoGroupDefaultResponse, + ValidateDiscoGroup200Response, + ValidateDiscoGroupDefaultResponse, + GetDiscoGroup200Response, + GetDiscoGroupDefaultResponse, + CreateOrReplaceDiscoGroup200Response, + CreateOrReplaceDiscoGroupDefaultResponse, + RunDiscoGroup204Response, + RunDiscoGroupDefaultResponse, + ListRuns200Response, + ListRunsDefaultResponse, + ListDiscoTemplate200Response, + ListDiscoTemplateDefaultResponse, + GetDiscoTemplate200Response, + GetDiscoTemplateDefaultResponse, + GetBillable200Response, + GetBillableDefaultResponse, + GetSnapshot200Response, + GetSnapshotDefaultResponse, + GetSummary200Response, + GetSummaryDefaultResponse, + ListSavedFilter200Response, + ListSavedFilterDefaultResponse, + GetSavedFilter200Response, + GetSavedFilterDefaultResponse, + CreateOrReplaceSavedFilter200Response, + CreateOrReplaceSavedFilterDefaultResponse, + DeleteSavedFilter204Response, + DeleteSavedFilterDefaultResponse, + ListTask200Response, + ListTaskDefaultResponse, + GetTask200Response, + GetTaskDefaultResponse, + CancelTask200Response, + CancelTaskDefaultResponse, +} from "./responses"; + +const responseMap: Record = { + "GET /assets": ["200"], + "POST /assets": ["200"], + "GET /assets/{assetId}": ["200"], + "GET /dataConnections": ["200"], + "POST /dataConnections:validate": ["200"], + "GET /dataConnections/{dataConnectionName}": ["200"], + "PUT /dataConnections/{dataConnectionName}": ["200"], + "DELETE /dataConnections/{dataConnectionName}": ["204"], + "GET /discoGroups": ["200"], + "POST /discoGroups:validate": ["200"], + "GET /discoGroups/{groupName}": ["200"], + "PUT /discoGroups/{groupName}": ["200"], + "POST /discoGroups/{groupName}:run": ["204"], + "GET /discoGroups/{groupName}/runs": ["200"], + "GET /discoTemplates": ["200"], + "GET /discoTemplates/{templateId}": ["200"], + "POST /reports/assets:getBillable": ["200"], + "POST /reports/assets:getSnapshot": ["200"], + "POST /reports/assets:getSummary": ["200"], + "GET /savedFilters": ["200"], + "GET /savedFilters/{filterName}": ["200"], + "PUT /savedFilters/{filterName}": ["200"], + "DELETE /savedFilters/{filterName}": ["204"], + "GET /tasks": ["200"], + "GET /tasks/{taskId}": ["200"], + "POST /tasks/{taskId}:cancel": ["200"], +}; + +export function isUnexpected( + response: ListAssetResource200Response | ListAssetResourceDefaultResponse +): response is ListAssetResourceDefaultResponse; +export function isUnexpected( + response: UpdateAssets200Response | UpdateAssetsDefaultResponse +): response is UpdateAssetsDefaultResponse; +export function isUnexpected( + response: GetAssetResource200Response | GetAssetResourceDefaultResponse +): response is GetAssetResourceDefaultResponse; +export function isUnexpected( + response: ListDataConnection200Response | ListDataConnectionDefaultResponse +): response is ListDataConnectionDefaultResponse; +export function isUnexpected( + response: + | ValidateDataConnection200Response + | ValidateDataConnectionDefaultResponse +): response is ValidateDataConnectionDefaultResponse; +export function isUnexpected( + response: GetDataConnection200Response | GetDataConnectionDefaultResponse +): response is GetDataConnectionDefaultResponse; +export function isUnexpected( + response: + | CreateOrReplaceDataConnection200Response + | CreateOrReplaceDataConnectionDefaultResponse +): response is CreateOrReplaceDataConnectionDefaultResponse; +export function isUnexpected( + response: + | DeleteDataConnection204Response + | DeleteDataConnectionDefaultResponse +): response is DeleteDataConnectionDefaultResponse; +export function isUnexpected( + response: ListDiscoGroup200Response | ListDiscoGroupDefaultResponse +): response is ListDiscoGroupDefaultResponse; +export function isUnexpected( + response: ValidateDiscoGroup200Response | ValidateDiscoGroupDefaultResponse +): response is ValidateDiscoGroupDefaultResponse; +export function isUnexpected( + response: GetDiscoGroup200Response | GetDiscoGroupDefaultResponse +): response is GetDiscoGroupDefaultResponse; +export function isUnexpected( + response: + | CreateOrReplaceDiscoGroup200Response + | CreateOrReplaceDiscoGroupDefaultResponse +): response is CreateOrReplaceDiscoGroupDefaultResponse; +export function isUnexpected( + response: RunDiscoGroup204Response | RunDiscoGroupDefaultResponse +): response is RunDiscoGroupDefaultResponse; +export function isUnexpected( + response: ListRuns200Response | ListRunsDefaultResponse +): response is ListRunsDefaultResponse; +export function isUnexpected( + response: ListDiscoTemplate200Response | ListDiscoTemplateDefaultResponse +): response is ListDiscoTemplateDefaultResponse; +export function isUnexpected( + response: GetDiscoTemplate200Response | GetDiscoTemplateDefaultResponse +): response is GetDiscoTemplateDefaultResponse; +export function isUnexpected( + response: GetBillable200Response | GetBillableDefaultResponse +): response is GetBillableDefaultResponse; +export function isUnexpected( + response: GetSnapshot200Response | GetSnapshotDefaultResponse +): response is GetSnapshotDefaultResponse; +export function isUnexpected( + response: GetSummary200Response | GetSummaryDefaultResponse +): response is GetSummaryDefaultResponse; +export function isUnexpected( + response: ListSavedFilter200Response | ListSavedFilterDefaultResponse +): response is ListSavedFilterDefaultResponse; +export function isUnexpected( + response: GetSavedFilter200Response | GetSavedFilterDefaultResponse +): response is GetSavedFilterDefaultResponse; +export function isUnexpected( + response: + | CreateOrReplaceSavedFilter200Response + | CreateOrReplaceSavedFilterDefaultResponse +): response is CreateOrReplaceSavedFilterDefaultResponse; +export function isUnexpected( + response: DeleteSavedFilter204Response | DeleteSavedFilterDefaultResponse +): response is DeleteSavedFilterDefaultResponse; +export function isUnexpected( + response: ListTask200Response | ListTaskDefaultResponse +): response is ListTaskDefaultResponse; +export function isUnexpected( + response: GetTask200Response | GetTaskDefaultResponse +): response is GetTaskDefaultResponse; +export function isUnexpected( + response: CancelTask200Response | CancelTaskDefaultResponse +): response is CancelTaskDefaultResponse; +export function isUnexpected( + response: + | ListAssetResource200Response + | ListAssetResourceDefaultResponse + | UpdateAssets200Response + | UpdateAssetsDefaultResponse + | GetAssetResource200Response + | GetAssetResourceDefaultResponse + | ListDataConnection200Response + | ListDataConnectionDefaultResponse + | ValidateDataConnection200Response + | ValidateDataConnectionDefaultResponse + | GetDataConnection200Response + | GetDataConnectionDefaultResponse + | CreateOrReplaceDataConnection200Response + | CreateOrReplaceDataConnectionDefaultResponse + | DeleteDataConnection204Response + | DeleteDataConnectionDefaultResponse + | ListDiscoGroup200Response + | ListDiscoGroupDefaultResponse + | ValidateDiscoGroup200Response + | ValidateDiscoGroupDefaultResponse + | GetDiscoGroup200Response + | GetDiscoGroupDefaultResponse + | CreateOrReplaceDiscoGroup200Response + | CreateOrReplaceDiscoGroupDefaultResponse + | RunDiscoGroup204Response + | RunDiscoGroupDefaultResponse + | ListRuns200Response + | ListRunsDefaultResponse + | ListDiscoTemplate200Response + | ListDiscoTemplateDefaultResponse + | GetDiscoTemplate200Response + | GetDiscoTemplateDefaultResponse + | GetBillable200Response + | GetBillableDefaultResponse + | GetSnapshot200Response + | GetSnapshotDefaultResponse + | GetSummary200Response + | GetSummaryDefaultResponse + | ListSavedFilter200Response + | ListSavedFilterDefaultResponse + | GetSavedFilter200Response + | GetSavedFilterDefaultResponse + | CreateOrReplaceSavedFilter200Response + | CreateOrReplaceSavedFilterDefaultResponse + | DeleteSavedFilter204Response + | DeleteSavedFilterDefaultResponse + | ListTask200Response + | ListTaskDefaultResponse + | GetTask200Response + | GetTaskDefaultResponse + | CancelTask200Response + | CancelTaskDefaultResponse +): response is + | ListAssetResourceDefaultResponse + | UpdateAssetsDefaultResponse + | GetAssetResourceDefaultResponse + | ListDataConnectionDefaultResponse + | ValidateDataConnectionDefaultResponse + | GetDataConnectionDefaultResponse + | CreateOrReplaceDataConnectionDefaultResponse + | DeleteDataConnectionDefaultResponse + | ListDiscoGroupDefaultResponse + | ValidateDiscoGroupDefaultResponse + | GetDiscoGroupDefaultResponse + | CreateOrReplaceDiscoGroupDefaultResponse + | RunDiscoGroupDefaultResponse + | ListRunsDefaultResponse + | ListDiscoTemplateDefaultResponse + | GetDiscoTemplateDefaultResponse + | GetBillableDefaultResponse + | GetSnapshotDefaultResponse + | GetSummaryDefaultResponse + | ListSavedFilterDefaultResponse + | GetSavedFilterDefaultResponse + | CreateOrReplaceSavedFilterDefaultResponse + | DeleteSavedFilterDefaultResponse + | ListTaskDefaultResponse + | GetTaskDefaultResponse + | CancelTaskDefaultResponse { + const lroOriginal = response.headers["x-ms-original-url"]; + const url = new URL(lroOriginal ?? response.request.url); + const method = response.request.method; + let pathDetails = responseMap[`${method} ${url.pathname}`]; + if (!pathDetails) { + pathDetails = getParametrizedPathSuccess(method, url.pathname); + } + return !pathDetails.includes(response.status); +} + +function getParametrizedPathSuccess(method: string, path: string): string[] { + const pathParts = path.split("/"); + + // Traverse list to match the longest candidate + // matchedLen: the length of candidate path + // matchedValue: the matched status code array + let matchedLen = -1, + matchedValue: string[] = []; + + // Iterate the responseMap to find a match + for (const [key, value] of Object.entries(responseMap)) { + // Extracting the path from the map key which is in format + // GET /path/foo + if (!key.startsWith(method)) { + continue; + } + const candidatePath = getPathFromMapKey(key); + // Get each part of the url path + const candidateParts = candidatePath.split("/"); + + // track if we have found a match to return the values found. + let found = true; + for ( + let i = candidateParts.length - 1, j = pathParts.length - 1; + i >= 1 && j >= 1; + i--, j-- + ) { + if ( + candidateParts[i]?.startsWith("{") && + candidateParts[i]?.indexOf("}") !== -1 + ) { + const start = candidateParts[i]!.indexOf("}") + 1, + end = candidateParts[i]?.length; + // If the current part of the candidate is a "template" part + // Try to use the suffix of pattern to match the path + // {guid} ==> $ + // {guid}:export ==> :export$ + const isMatched = new RegExp( + `${candidateParts[i]?.slice(start, end)}` + ).test(pathParts[j] || ""); + + if (!isMatched) { + found = false; + break; + } + continue; + } + + // If the candidate part is not a template and + // the parts don't match mark the candidate as not found + // to move on with the next candidate path. + if (candidateParts[i] !== pathParts[j]) { + found = false; + break; + } + } + + // We finished evaluating the current candidate parts + // Update the matched value if and only if we found the longer pattern + if (found && candidatePath.length > matchedLen) { + matchedLen = candidatePath.length; + matchedValue = value; + } + } + + return matchedValue; +} + +function getPathFromMapKey(mapKey: string): string { + const pathStart = mapKey.indexOf("/"); + return mapKey.slice(pathStart); +} diff --git a/sdk/easm/defendereasm-rest/src/logger.ts b/sdk/easm/defendereasm-rest/src/logger.ts new file mode 100644 index 000000000000..b5cba53d7d35 --- /dev/null +++ b/sdk/easm/defendereasm-rest/src/logger.ts @@ -0,0 +1,5 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { createClientLogger } from "@azure/logger"; +export const logger = createClientLogger("defender-easm-rest"); diff --git a/sdk/easm/defendereasm-rest/src/models.ts b/sdk/easm/defendereasm-rest/src/models.ts new file mode 100644 index 000000000000..9acef719112c --- /dev/null +++ b/sdk/easm/defendereasm-rest/src/models.ts @@ -0,0 +1,934 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +/** The items in the current page of results. */ +export interface AssetResourceParent { + /** The caller provided unique name for the resource. */ + name?: string; + /** The name that can be used for display purposes. */ + displayName?: string; + /** Global UUID for the asset. */ + uuid?: string; + /** The date this asset was first added to this workspace. */ + createdDate?: Date | string; + /** The date this asset was last updated for this workspace. */ + updatedDate?: Date | string; + /** Possible values: candidate, confirmed, dismissed, candidateInvestigate, associatedPartner, associatedThirdparty, archived */ + state?: string; + /** An optional customer provided identifier for this asset. */ + externalId?: string; + /** Customer labels assigned to this asset. */ + labels?: string[]; + /** An indicator of whether this asset represents a wildcard rollup of assets on this domain. */ + wildcard?: boolean; + /** The name of the DiscoGroup that brought added this asset to the workspace. */ + discoGroupName?: string; + /** The history of how this asset was pulled into the workspace through the discovery process. */ + auditTrail?: Array; + reason?: string; + kind: string; +} + +/** The history of how this asset was pulled into the workspace through the discovery process. */ +export interface AuditTrailItem { + /** The system generated unique id for the resource. */ + id?: string; + /** The caller provided unique name for the resource. */ + name?: string; + /** The name that can be used for display purposes. */ + displayName?: string; + /** + * The kind of asset. + * + * Possible values: as, contact, domain, host, ipAddress, ipBlock, page, sslCert + */ + kind?: string; + /** An explanation of why this audit trail node was discovered from the previous node. */ + reason?: string; +} + +export interface AsAssetResource extends AssetResourceParent { + /** The kind of AssetResource */ + kind: "as"; + /** asset */ + asset: AsAsset; +} + +export interface AsAsset extends InventoryAsset { + asn?: number; + asNames?: Array; + orgNames?: Array; + orgIds?: Array; + countries?: Array; + registries?: Array; + sources?: Array; + firstSeen?: Date | string; + lastSeen?: Date | string; + count?: number; + registrarCreatedAt?: Array; + registrarUpdatedAt?: Array; + registrantContacts?: Array; + adminContacts?: Array; + technicalContacts?: Array; + registrarNames?: Array; + registrantNames?: Array; + adminNames?: Array; + technicalNames?: Array; + adminOrgs?: Array; + technicalOrgs?: Array; + registrantPhones?: Array; + adminPhones?: Array; + technicalPhones?: Array; + detailedFromWhoisAt?: Date | string; +} + +export interface ObservedString extends ObservedValue { + value?: string; + sources?: Array; +} + +export interface Source { + source?: string; + firstSeen?: Date | string; + lastSeen?: Date | string; + count?: number; + reason?: string; +} + +/** Template model for observed values */ +export interface ObservedValue { + firstSeen?: Date | string; + lastSeen?: Date | string; + count?: number; + recent?: boolean; +} + +export interface ObservedLong extends ObservedValue { + value?: number; + sources?: Array; +} + +export interface ObservedInteger extends ObservedValue { + value?: number; + sources?: Array; +} + +export interface ObservedBoolean extends ObservedValue { + value?: boolean; + sources?: Array; +} + +export interface ObservedHeader extends ObservedValue { + headerName?: string; + headerValue?: string; +} + +export interface ObservedPortState extends ObservedValue { + /** Possible values: open, closed, filtered */ + value?: string; + port?: number; +} + +export interface ObservedLocation extends ObservedValue { + value?: Location; + sources?: Array; +} + +export interface Location { + countryCode?: string; + countryName?: string; + region?: string; + regionName?: string; + city?: string; + areaCode?: number; + postalCode?: string; + latitude?: number; + longitude?: number; + dmaCode?: number; + metroCodeId?: number; +} + +export interface ObservedIntegers extends ObservedValue { + values?: number[]; + sources?: Array; +} + +export interface InventoryAsset {} + +export interface ContactAsset extends InventoryAsset { + email?: string; + names?: Array; + organizations?: Array; + sources?: Array; + firstSeen?: Date | string; + lastSeen?: Date | string; + count?: number; +} + +export interface DomainAsset extends InventoryAsset { + domain?: string; + whoisId?: number; + registrarIanaIds?: Array; + registrantContacts?: Array; + registrantOrgs?: Array; + adminContacts?: Array; + technicalContacts?: Array; + alexaInfos?: Array; + nameServers?: Array; + mailServers?: Array; + whoisServers?: Array; + domainStatuses?: Array; + registrarCreatedAt?: Array; + registrarUpdatedAt?: Array; + registrarExpiresAt?: Array; + soaRecords?: Array; + detailedFromWhoisAt?: Date | string; + registrarNames?: Array; + sources?: Array; + firstSeen?: Date | string; + lastSeen?: Date | string; + count?: number; + parkedDomain?: Array; + registrantNames?: Array; + adminNames?: Array; + technicalNames?: Array; + adminOrgs?: Array; + technicalOrgs?: Array; + registrantPhones?: Array; + adminPhones?: Array; + technicalPhones?: Array; +} + +export interface AlexaInfo { + alexaRank?: number; + category?: string; + firstSeen?: Date | string; + lastSeen?: Date | string; + count?: number; + recent?: boolean; +} + +export interface SoaRecord { + nameServer?: string; + email?: string; + firstSeen?: Date | string; + lastSeen?: Date | string; + count?: number; + serialNumber?: number; + recent?: boolean; +} + +export interface HostAsset extends InventoryAsset { + host?: string; + domain?: string; + ipAddresses?: Array; + webComponents?: Array; + headers?: Array; + attributes?: Array; + cookies?: Array; + sslCerts?: Array; + parentHosts?: Array; + childHosts?: Array; + hostCore?: HostCore; + services?: Array; + cnames?: Array; + sources?: Array; + firstSeen?: Date | string; + lastSeen?: Date | string; + count?: number; + resourceUrls?: Array; + scanMetadata?: Array; + asns?: Array; + ipBlocks?: Array; + responseBodies?: Array; + domainAsset?: DomainAsset; + nsRecord?: Array; + mxRecord?: Array; + webserver?: Array; + location?: Array; + nxdomain?: Array; + sslServerConfig?: Array; + isWildcard?: Array; + banners?: Array; + ipv4?: Array; + ipv6?: Array; +} + +export interface WebComponent { + name?: string; + type?: string; + version?: string; + ruleId?: string[]; + firstSeen?: Date | string; + lastSeen?: Date | string; + count?: number; + cve?: Array; + endOfLife?: number; + recent?: boolean; + ports?: Array; + sources?: Array; + service?: string; +} + +export interface Cve { + name?: string; + cweId?: string; + cvssScore?: number; + cvss3Summary?: Cvss3Summary; +} + +export interface Cvss3Summary { + version?: string; + vectorString?: string; + attackVector?: string; + attackComplexity?: string; + privilegesRequired?: string; + userInteraction?: string; + scope?: string; + confidentialityImpact?: string; + integrityImpact?: string; + availabilityImpact?: string; + baseScore?: number; + baseSeverity?: string; + exploitCodeMaturity?: string; + remediationLevel?: string; + reportConfidence?: string; + exploitabilityScore?: number; + impactScore?: number; +} + +export interface Port { + port?: number; + firstSeen?: Date | string; + lastSeen?: Date | string; + count?: number; +} + +export interface Attribute { + attributeType?: string; + attributeValue?: string; + sources?: Array; + firstSeen?: Date | string; + lastSeen?: Date | string; + count?: number; + recent?: boolean; +} + +export interface Cookie { + cookieName?: string; + cookieDomain?: string; + firstSeen?: Date | string; + lastSeen?: Date | string; + count?: number; + recent?: boolean; + cookieExpiryDate?: Date | string; +} + +export interface SslCertAsset extends InventoryAsset { + sha1?: string; + subjectCommonNames?: string[]; + organizations?: string[]; + organizationalUnits?: string[]; + issuerCommonNames?: string[]; + sigAlgName?: string; + invalidAfter?: Date | string; + serialNumber?: string; + subjectAlternativeNames?: string[]; + issuerAlternativeNames?: string[]; + sources?: Array; + firstSeen?: Date | string; + lastSeen?: Date | string; + count?: number; + invalidBefore?: Date | string; + keySize?: number; + keyAlgorithm?: string; + subjectLocality?: string[]; + subjectState?: string[]; + subjectCountry?: string[]; + issuerLocality?: string[]; + issuerState?: string[]; + issuerCountry?: string[]; + subjectOrganizations?: string[]; + subjectOrganizationalUnits?: string[]; + issuerOrganizations?: string[]; + issuerOrganizationalUnits?: string[]; + version?: number; + certificateAuthority?: boolean; + selfSigned?: boolean; + sigAlgOid?: string; + recent?: boolean; + /** Possible values: domainValidation, organizationValidation, extendedValidation */ + validationType?: string; +} + +export interface HostCore { + host?: string; + domain?: string; + firstSeen?: Date | string; + lastSeen?: Date | string; + count?: number; + blacklistCauseFirstSeen?: Date | string; + blacklistCauseLastSeen?: Date | string; + blacklistCauseCount?: number; + blacklistResourceFirstSeen?: Date | string; + blacklistResourceLastSeen?: Date | string; + blacklistResourceCount?: number; + blacklistSequenceFirstSeen?: Date | string; + blacklistSequenceLastSeen?: Date | string; + blacklistSequenceCount?: number; + phishCauseCount?: number; + malwareCauseCount?: number; + spamCauseCount?: number; + scamCauseCount?: number; + phishResourceCount?: number; + malwareResourceCount?: number; + spamResourceCount?: number; + scamResourceCount?: number; + phishSequenceCount?: number; + malwareSequenceCount?: number; + spamSequenceCount?: number; + scamSequenceCount?: number; + alexaRank?: number; + hostReputationScore?: number; + hostPhishReputationScore?: number; + hostMalwareReputationScore?: number; + hostSpamReputationScore?: number; + hostScamReputationScore?: number; + domainReputationScore?: number; + domainPhishReputationScore?: number; + domainMalwareReputationScore?: number; + domainSpamReputationScore?: number; + domainScamReputationScore?: number; + uuid?: string; +} + +export interface Service { + scheme?: string; + port?: number; + webComponents?: Array; + sslCerts?: Array; + exceptions?: Array; + sources?: Array; + firstSeen?: Date | string; + lastSeen?: Date | string; + count?: number; + recent?: boolean; + portStates?: Array; +} + +export interface ResourceUrl { + url?: string; + resources?: Array; + firstSeen?: Date | string; + lastSeen?: Date | string; + count?: number; + recent?: boolean; +} + +export interface DependentResource { + md5?: string; + responseBodySize?: number; + firstSeen?: Date | string; + lastSeen?: Date | string; + count?: number; + firstSeenCrawlGuid?: string; + firstSeenPageGuid?: string; + firstSeenResourceGuid?: string; + lastSeenCrawlGuid?: string; + lastSeenPageGuid?: string; + lastSeenResourceGuid?: string; + responseBodyMinhash?: number[]; + contentType?: string; + sha256?: string; + sha384?: string; + sha512?: string; + url?: string; + cached?: boolean; + sriChecks?: Array; + host?: string; + lastObservedViolation?: Date | string; + lastObservedValidation?: Date | string; + lastObservedActualSriHash?: string; + lastObservedExpectedSriHash?: string; +} + +export interface SubResourceIntegrityCheck { + violation?: boolean; + firstSeen?: Date | string; + lastSeen?: Date | string; + count?: number; + causePageUrl?: string; + crawlGuid?: string; + pageGuid?: string; + resourceGuid?: string; + expectedHash?: string; +} + +export interface ScanMetadata { + port?: number; + bannerMetadata?: string; + startScan?: Date | string; + endScan?: Date | string; +} + +export interface IpBlock { + ipBlock?: string; + sources?: Array; + firstSeen?: Date | string; + lastSeen?: Date | string; + count?: number; + recent?: boolean; +} + +export interface SslServerConfig { + tlsVersions?: string[]; + cipherSuites?: string[]; + firstSeen?: Date | string; + lastSeen?: Date | string; + count?: number; + sources?: Array; +} + +export interface Banner { + port?: number; + banner?: string; + firstSeen?: Date | string; + lastSeen?: Date | string; + count?: number; + scanType?: string; + bannerMetadata?: string; + recent?: boolean; + sha256?: string; + sources?: Array; +} + +export interface IpAddressAsset extends InventoryAsset { + ipAddress?: string; + asns?: Array; + reputations?: Array; + webComponents?: Array; + netRanges?: Array; + headers?: Array; + attributes?: Array; + cookies?: Array; + sslCerts?: Array; + services?: Array; + ipBlocks?: Array; + sources?: Array; + firstSeen?: Date | string; + lastSeen?: Date | string; + count?: number; + banners?: Array; + scanMetadata?: Array; + nsRecord?: Array; + mxRecord?: Array; + location?: Array; + hosts?: Array; + nxdomain?: Array; + sslServerConfig?: Array; + ipv4?: boolean; + ipv6?: boolean; +} + +export interface Reputation { + listName?: string; + threatType?: string; + trusted?: boolean; + cidr?: string; + firstSeen?: Date | string; + lastSeen?: Date | string; + listUpdatedAt?: Date | string; + recent?: boolean; +} + +export interface IpBlockAsset extends InventoryAsset { + ipBlock?: string; + asns?: Array; + bgpPrefixes?: Array; + netNames?: Array; + registrantContacts?: Array; + registrantOrgs?: Array; + adminContacts?: Array; + technicalContacts?: Array; + registrarCreatedAt?: Array; + registrarUpdatedAt?: Array; + netRanges?: Array; + startIp?: string; + endIp?: string; + reputations?: Array; + detailedFromWhoisAt?: Date | string; + sources?: Array; + firstSeen?: Date | string; + lastSeen?: Date | string; + count?: number; + location?: Array; + registrarExpiresAt?: Array; + registrantNames?: Array; + adminNames?: Array; + technicalNames?: Array; + adminOrgs?: Array; + technicalOrgs?: Array; + registrantPhones?: Array; + adminPhones?: Array; + technicalPhones?: Array; + ipv4?: boolean; + ipv6?: boolean; +} + +export interface PageAsset extends InventoryAsset { + url?: string; + httpMethod?: string; + service?: string; + ipAddresses?: Array; + successful?: Array; + httpResponseCodes?: Array; + httpResponseMessages?: Array; + responseTimes?: Array; + frames?: Array; + windows?: Array; + nonHtmlFrames?: Array; + undirectedContent?: Array; + contentTypes?: Array; + contentLengths?: Array; + windowNames?: Array; + charsets?: Array; + titles?: Array; + languages?: Array; + responseHeaders?: Array; + cookies?: Array; + webComponents?: Array; + attributes?: Array; + assetSecurityPolicies?: Array; + responseBodyMinhashSignatures?: Array; + fullDomMinhashSignatures?: Array; + responseBodyHashSignatures?: Array; + errors?: Array; + sslCerts?: Array; + sources?: Array; + firstSeen?: Date | string; + lastSeen?: Date | string; + count?: number; + cause?: PageCause; + referrer?: string; + redirectUrls?: Array; + /** Possible values: httpHeader, metaRefresh, javascript, final */ + redirectType?: string; + finalUrls?: Array; + finalResponseCodes?: Array; + parkedPage?: Array; + resourceUrls?: Array; + guids?: Array; + finalIpAddresses?: Array; + asns?: Array; + ipBlocks?: Array; + finalAsns?: Array; + finalIpBlocks?: Array; + responseBodies?: Array; + domainAsset?: DomainAsset; + rootUrl?: ObservedBoolean; + isRootUrl?: boolean; + location?: Array; + services?: Array; + siteStatus?: string; + cnames?: Array; + cdns?: Array; + host?: string; + domain?: string; + sslServerConfig?: Array; + gdprAssetSecurityPolicies?: Array; + ipv4?: Array; + ipv6?: Array; +} + +export interface AssetSecurityPolicy { + policyName?: string; + isAffected?: boolean; + description?: string; + firstSeen?: Date | string; + lastSeen?: Date | string; + count?: number; + recent?: boolean; + sources?: Array; +} + +export interface PageCause { + cause?: string; + causeElementXPath?: string; + location?: string; + possibleMatches?: number; + loopDetected?: boolean; + version?: number; + domChangeIndex?: number; +} + +export interface GuidPair { + pageGuid?: string; + crawlStateGuid?: string; + loadDate?: Date | string; + recent?: boolean; +} + +export interface ContactAssetResource extends AssetResourceParent { + /** The kind of AssetResource */ + kind: "contact"; + /** asset */ + asset: ContactAsset; +} + +export interface DomainAssetResource extends AssetResourceParent { + /** The kind of AssetResource */ + kind: "domain"; + /** asset */ + asset: DomainAsset; +} + +export interface HostAssetResource extends AssetResourceParent { + /** The kind of AssetResource */ + kind: "host"; + /** asset */ + asset: HostAsset; +} + +export interface IpAddressAssetResource extends AssetResourceParent { + /** The kind of AssetResource */ + kind: "ipAddress"; + /** asset */ + asset: IpAddressAsset; +} + +export interface IpBlockAssetResource extends AssetResourceParent { + /** The kind of AssetResource */ + kind: "ipBlock"; + /** asset */ + asset: IpBlockAsset; +} + +export interface PageAssetResource extends AssetResourceParent { + /** The kind of AssetResource */ + kind: "page"; + /** asset */ + asset: PageAsset; +} + +export interface SslCertAssetResource extends AssetResourceParent { + /** The kind of AssetResource */ + kind: "sslCert"; + /** asset */ + asset: SslCertAsset; +} + +export interface DataConnectionParent { + /** The system generated unique id for the resource. */ + id?: string; + /** The name that can be used for display purposes. */ + displayName?: string; + /** + * The type of data the data connection will transfer + * + * Possible values: assets, attackSurfaceInsights + */ + content?: string; + /** + * The rate at which the data connection will receive updates. + * + * Possible values: daily, weekly, monthly + */ + frequency?: string; + /** The day to update the data connection on. */ + frequencyOffset?: number; + /** An indicator of whether the data connection is active. */ + active?: boolean; + kind: string; +} + +export interface LogAnalyticsDataConnection extends DataConnectionParent { + /** The kind of DataConnection */ + kind: "logAnalytics"; + /** properties */ + properties: LogAnalyticsDataConnectionProperties; +} + +export interface LogAnalyticsDataConnectionProperties + extends DataConnectionProperties { + /** log analytics api key */ + apiKey?: string; + /** log analytics workspace id */ + workspaceId?: string; +} + +/** The properties required to establish connection to a particular service */ +export interface DataConnectionProperties {} + +export interface AzureDataExplorerDataConnectionProperties + extends DataConnectionProperties { + /** The azure data explorer cluster name */ + clusterName?: string; + /** The azure data explorer region */ + region?: string; + /** The azure data explorer database name */ + databaseName?: string; +} + +export interface AzureDataExplorerDataConnection extends DataConnectionParent { + /** The kind of DataConnection */ + kind: "azureDataExplorer"; + /** properties */ + properties: AzureDataExplorerDataConnectionProperties; +} + +export interface DataConnectionDataParent { + /** The name of data connection */ + name?: string; + /** + * The type of data the data connection will transfer. + * + * Possible values: assets, attackSurfaceInsights + */ + content?: string; + /** + * The rate at which the data connection will receive updates. + * + * Possible values: daily, weekly, monthly + */ + frequency?: string; + /** The day to update the data connection on. (1-7 for weekly, 1-31 for monthly) */ + frequencyOffset?: number; + kind: string; +} + +export interface DiscoGroup { + /** The system generated unique id for the resource. */ + id?: string; + /** The name that can be used for display purposes. */ + displayName?: string; + /** The description for a disco group. */ + description?: string; + /** The tier for the disco group which will affect the algorithm used for the disco runs in this group. */ + tier?: string; + /** The frequency at which the disco group is supposed to be rerun in milliseconds. */ + frequencyMilliseconds?: number; + /** The list of seeds used for the disco group runs. */ + seeds?: Array; + /** The list of names used for the disco group runs. */ + names?: string[]; + /** The list of excludes used for the disco group runs, aka assets to exclude from the discovery algorithm. */ + excludes?: Array; + /** The latest run of this disco group with some limited information, null if the group has never been run. */ + latestRun?: DiscoRunResult; + /** The date for the disco group was created. */ + createdDate?: Date | string; + /** The unique identifier for the disco template used for the disco group creation. */ + templateId?: string; +} + +/** Source entity used to drive discovery. */ +export interface DiscoSource { + /** + * The kind of disco source. + * + * Possible values: as, attribute, contact, domain, host, ipBlock + */ + kind?: string; + /** The name for the disco source. */ + name?: string; +} + +/** The latest run of this disco group with some limited information, null if the group has never been run. */ +export interface DiscoRunResult { + /** The date for when the disco run was created in the system. */ + submittedDate?: Date | string; + /** The date for when the disco run was actually started by the system. */ + startedDate?: Date | string; + /** The date for when the disco run was completed by the system. */ + completedDate?: Date | string; + /** The tier which will affect the algorithm used for the disco run. */ + tier?: string; + /** + * The State of the disco run. + * + * Possible values: pending, running, completed, failed + */ + state?: string; + /** The total count of assets that were found this disco run. */ + totalAssetsFoundCount?: number; + /** The list of seeds used for the disco run. */ + seeds?: Array; + /** The list of excludes used for the disco run, aka assets to exclude from the discovery algorithm. */ + excludes?: Array; + /** The list of names used for the disco run. */ + names?: string[]; +} + +/** A request body used to create a discovery group. */ +export interface DiscoGroupData { + /** The name for a disco group. */ + name?: string; + /** The description for a disco group. */ + description?: string; + /** The tier for the disco group which will affect the algorithm used for the disco runs in this group. */ + tier?: string; + /** The frequency at which the disco group is supposed to be rerun in milliseconds. */ + frequencyMilliseconds?: number; + /** The list of seeds used for the disco group runs. */ + seeds?: Array; + /** The list of names used for the disco group runs. */ + names?: string[]; + /** The list of excludes used for the disco group runs, aka assets to exclude from the discovery algorithm. */ + excludes?: Array; + /** The unique identifier for the disco template used for the disco group creation. */ + templateId?: string; +} + +/** A request body used to retrieve an asset report snapshot. */ +export interface ReportAssetSnapshotRequest { + /** The metric to retrieve a snapshot for. */ + metric?: string; + /** The name of the label to retrieve a snapshot for. */ + labelName?: string; + /** The number of assets per page. */ + size?: number; + /** The page to retrieve. */ + page?: number; +} + +/** A request body used to retrieve summary asset information. One and only one collection of summary identifiers must be provided: filters, metrics, or metricCategories. */ +export interface ReportAssetSummaryRequest { + /** Categories to retrieve risk reporting data for. */ + metricCategories?: string[]; + /** Metrics to retrieve risk reporting data for. */ + metrics?: string[]; + /** Query filters to apply to the asset summary. */ + filters?: string[]; + /** A parameter to group the assets by (first level facet field), only used when the chosen summary identifier is filters. */ + groupBy?: string; + /** A parameter to segment the assets by (second level facet field), only used when the chosen summary identifier is filters. */ + segmentBy?: string; + /** Currently unused. */ + labelName?: string; +} + +export interface SavedFilter { + /** The system generated unique id for the resource. */ + id?: string; + /** The name that can be used for display purposes. */ + displayName?: string; + filter?: string; + description?: string; +} + +/** The items in the current page of results. */ +export type AssetResource = + | AsAssetResource + | ContactAssetResource + | DomainAssetResource + | HostAssetResource + | IpAddressAssetResource + | IpBlockAssetResource + | PageAssetResource + | SslCertAssetResource; +export type DataConnection = + | LogAnalyticsDataConnection + | AzureDataExplorerDataConnection; +export type DataConnectionData = + | LogAnalyticsDataConnectionData + | AzureDataExplorerDataConnectionData; diff --git a/sdk/easm/defendereasm-rest/src/outputModels.ts b/sdk/easm/defendereasm-rest/src/outputModels.ts new file mode 100644 index 000000000000..0a01bd4655e7 --- /dev/null +++ b/sdk/easm/defendereasm-rest/src/outputModels.ts @@ -0,0 +1,1065 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { Paged } from "@azure/core-paging"; + +/** The items in the current page of results. */ +export interface AssetResourceOutputParent { + /** The system generated unique id for the resource. */ + readonly id: string; + /** The caller provided unique name for the resource. */ + name?: string; + /** The name that can be used for display purposes. */ + displayName?: string; + /** Global UUID for the asset. */ + uuid?: string; + /** The date this asset was first added to this workspace. */ + createdDate?: string; + /** The date this asset was last updated for this workspace. */ + updatedDate?: string; + /** Possible values: candidate, confirmed, dismissed, candidateInvestigate, associatedPartner, associatedThirdparty, archived */ + state?: string; + /** An optional customer provided identifier for this asset. */ + externalId?: string; + /** Customer labels assigned to this asset. */ + labels?: string[]; + /** An indicator of whether this asset represents a wildcard rollup of assets on this domain. */ + wildcard?: boolean; + /** The name of the DiscoGroup that brought added this asset to the workspace. */ + discoGroupName?: string; + /** The history of how this asset was pulled into the workspace through the discovery process. */ + auditTrail?: Array; + reason?: string; + kind: string; +} + +/** The history of how this asset was pulled into the workspace through the discovery process. */ +export interface AuditTrailItemOutput { + /** The system generated unique id for the resource. */ + id?: string; + /** The caller provided unique name for the resource. */ + name?: string; + /** The name that can be used for display purposes. */ + displayName?: string; + /** + * The kind of asset. + * + * Possible values: as, contact, domain, host, ipAddress, ipBlock, page, sslCert + */ + kind?: string; + /** An explanation of why this audit trail node was discovered from the previous node. */ + reason?: string; +} + +export interface AsAssetResourceOutput extends AssetResourceOutputParent { + /** The kind of AssetResource */ + kind: "as"; + /** asset */ + asset: AsAssetOutput; +} + +export interface AsAssetOutput extends InventoryAssetOutput { + asn?: number; + asNames?: Array; + orgNames?: Array; + orgIds?: Array; + countries?: Array; + registries?: Array; + sources?: Array; + firstSeen?: string; + lastSeen?: string; + count?: number; + registrarCreatedAt?: Array; + registrarUpdatedAt?: Array; + registrantContacts?: Array; + adminContacts?: Array; + technicalContacts?: Array; + registrarNames?: Array; + registrantNames?: Array; + adminNames?: Array; + technicalNames?: Array; + adminOrgs?: Array; + technicalOrgs?: Array; + registrantPhones?: Array; + adminPhones?: Array; + technicalPhones?: Array; + detailedFromWhoisAt?: string; +} + +export interface ObservedStringOutput extends ObservedValueOutput { + value?: string; + sources?: Array; +} + +export interface SourceOutput { + source?: string; + firstSeen?: string; + lastSeen?: string; + count?: number; + reason?: string; +} + +/** Template model for observed values */ +export interface ObservedValueOutput { + firstSeen?: string; + lastSeen?: string; + count?: number; + recent?: boolean; +} + +export interface ObservedLongOutput extends ObservedValueOutput { + value?: number; + sources?: Array; +} + +export interface ObservedIntegerOutput extends ObservedValueOutput { + value?: number; + sources?: Array; +} + +export interface ObservedBooleanOutput extends ObservedValueOutput { + value?: boolean; + sources?: Array; +} + +export interface ObservedHeaderOutput extends ObservedValueOutput { + headerName?: string; + headerValue?: string; +} + +export interface ObservedPortStateOutput extends ObservedValueOutput { + /** Possible values: open, closed, filtered */ + value?: string; + port?: number; +} + +export interface ObservedLocationOutput extends ObservedValueOutput { + value?: LocationOutput; + sources?: Array; +} + +export interface LocationOutput { + countryCode?: string; + countryName?: string; + region?: string; + regionName?: string; + city?: string; + areaCode?: number; + postalCode?: string; + latitude?: number; + longitude?: number; + dmaCode?: number; + metroCodeId?: number; +} + +export interface ObservedIntegersOutput extends ObservedValueOutput { + values?: number[]; + sources?: Array; +} + +export interface InventoryAssetOutput {} + +export interface ContactAssetOutput extends InventoryAssetOutput { + email?: string; + names?: Array; + organizations?: Array; + sources?: Array; + firstSeen?: string; + lastSeen?: string; + count?: number; +} + +export interface DomainAssetOutput extends InventoryAssetOutput { + domain?: string; + whoisId?: number; + registrarIanaIds?: Array; + registrantContacts?: Array; + registrantOrgs?: Array; + adminContacts?: Array; + technicalContacts?: Array; + alexaInfos?: Array; + nameServers?: Array; + mailServers?: Array; + whoisServers?: Array; + domainStatuses?: Array; + registrarCreatedAt?: Array; + registrarUpdatedAt?: Array; + registrarExpiresAt?: Array; + soaRecords?: Array; + detailedFromWhoisAt?: string; + registrarNames?: Array; + sources?: Array; + firstSeen?: string; + lastSeen?: string; + count?: number; + parkedDomain?: Array; + registrantNames?: Array; + adminNames?: Array; + technicalNames?: Array; + adminOrgs?: Array; + technicalOrgs?: Array; + registrantPhones?: Array; + adminPhones?: Array; + technicalPhones?: Array; +} + +export interface AlexaInfoOutput { + alexaRank?: number; + category?: string; + firstSeen?: string; + lastSeen?: string; + count?: number; + recent?: boolean; +} + +export interface SoaRecordOutput { + nameServer?: string; + email?: string; + firstSeen?: string; + lastSeen?: string; + count?: number; + serialNumber?: number; + recent?: boolean; +} + +export interface HostAssetOutput extends InventoryAssetOutput { + host?: string; + domain?: string; + ipAddresses?: Array; + webComponents?: Array; + headers?: Array; + attributes?: Array; + cookies?: Array; + sslCerts?: Array; + parentHosts?: Array; + childHosts?: Array; + hostCore?: HostCoreOutput; + services?: Array; + cnames?: Array; + sources?: Array; + firstSeen?: string; + lastSeen?: string; + count?: number; + resourceUrls?: Array; + scanMetadata?: Array; + asns?: Array; + ipBlocks?: Array; + responseBodies?: Array; + domainAsset?: DomainAssetOutput; + nsRecord?: Array; + mxRecord?: Array; + webserver?: Array; + location?: Array; + nxdomain?: Array; + sslServerConfig?: Array; + isWildcard?: Array; + banners?: Array; + ipv4?: Array; + ipv6?: Array; +} + +export interface WebComponentOutput { + name?: string; + type?: string; + version?: string; + ruleId?: string[]; + firstSeen?: string; + lastSeen?: string; + count?: number; + cve?: Array; + endOfLife?: number; + recent?: boolean; + ports?: Array; + sources?: Array; + service?: string; +} + +export interface CveOutput { + name?: string; + cweId?: string; + cvssScore?: number; + cvss3Summary?: Cvss3SummaryOutput; +} + +export interface Cvss3SummaryOutput { + version?: string; + vectorString?: string; + attackVector?: string; + attackComplexity?: string; + privilegesRequired?: string; + userInteraction?: string; + scope?: string; + confidentialityImpact?: string; + integrityImpact?: string; + availabilityImpact?: string; + baseScore?: number; + baseSeverity?: string; + exploitCodeMaturity?: string; + remediationLevel?: string; + reportConfidence?: string; + exploitabilityScore?: number; + impactScore?: number; +} + +export interface PortOutput { + port?: number; + firstSeen?: string; + lastSeen?: string; + count?: number; +} + +export interface AttributeOutput { + attributeType?: string; + attributeValue?: string; + sources?: Array; + firstSeen?: string; + lastSeen?: string; + count?: number; + recent?: boolean; +} + +export interface CookieOutput { + cookieName?: string; + cookieDomain?: string; + firstSeen?: string; + lastSeen?: string; + count?: number; + recent?: boolean; + cookieExpiryDate?: string; +} + +export interface SslCertAssetOutput extends InventoryAssetOutput { + sha1?: string; + subjectCommonNames?: string[]; + organizations?: string[]; + organizationalUnits?: string[]; + issuerCommonNames?: string[]; + sigAlgName?: string; + invalidAfter?: string; + serialNumber?: string; + subjectAlternativeNames?: string[]; + issuerAlternativeNames?: string[]; + sources?: Array; + firstSeen?: string; + lastSeen?: string; + count?: number; + invalidBefore?: string; + keySize?: number; + keyAlgorithm?: string; + subjectLocality?: string[]; + subjectState?: string[]; + subjectCountry?: string[]; + issuerLocality?: string[]; + issuerState?: string[]; + issuerCountry?: string[]; + subjectOrganizations?: string[]; + subjectOrganizationalUnits?: string[]; + issuerOrganizations?: string[]; + issuerOrganizationalUnits?: string[]; + version?: number; + certificateAuthority?: boolean; + selfSigned?: boolean; + sigAlgOid?: string; + recent?: boolean; + /** Possible values: domainValidation, organizationValidation, extendedValidation */ + validationType?: string; +} + +export interface HostCoreOutput { + host?: string; + domain?: string; + firstSeen?: string; + lastSeen?: string; + count?: number; + blacklistCauseFirstSeen?: string; + blacklistCauseLastSeen?: string; + blacklistCauseCount?: number; + blacklistResourceFirstSeen?: string; + blacklistResourceLastSeen?: string; + blacklistResourceCount?: number; + blacklistSequenceFirstSeen?: string; + blacklistSequenceLastSeen?: string; + blacklistSequenceCount?: number; + phishCauseCount?: number; + malwareCauseCount?: number; + spamCauseCount?: number; + scamCauseCount?: number; + phishResourceCount?: number; + malwareResourceCount?: number; + spamResourceCount?: number; + scamResourceCount?: number; + phishSequenceCount?: number; + malwareSequenceCount?: number; + spamSequenceCount?: number; + scamSequenceCount?: number; + alexaRank?: number; + hostReputationScore?: number; + hostPhishReputationScore?: number; + hostMalwareReputationScore?: number; + hostSpamReputationScore?: number; + hostScamReputationScore?: number; + domainReputationScore?: number; + domainPhishReputationScore?: number; + domainMalwareReputationScore?: number; + domainSpamReputationScore?: number; + domainScamReputationScore?: number; + uuid?: string; +} + +export interface ServiceOutput { + scheme?: string; + port?: number; + webComponents?: Array; + sslCerts?: Array; + exceptions?: Array; + sources?: Array; + firstSeen?: string; + lastSeen?: string; + count?: number; + recent?: boolean; + portStates?: Array; +} + +export interface ResourceUrlOutput { + url?: string; + resources?: Array; + firstSeen?: string; + lastSeen?: string; + count?: number; + recent?: boolean; +} + +export interface DependentResourceOutput { + md5?: string; + responseBodySize?: number; + firstSeen?: string; + lastSeen?: string; + count?: number; + firstSeenCrawlGuid?: string; + firstSeenPageGuid?: string; + firstSeenResourceGuid?: string; + lastSeenCrawlGuid?: string; + lastSeenPageGuid?: string; + lastSeenResourceGuid?: string; + responseBodyMinhash?: number[]; + contentType?: string; + sha256?: string; + sha384?: string; + sha512?: string; + url?: string; + cached?: boolean; + sriChecks?: Array; + host?: string; + lastObservedViolation?: string; + lastObservedValidation?: string; + lastObservedActualSriHash?: string; + lastObservedExpectedSriHash?: string; +} + +export interface SubResourceIntegrityCheckOutput { + violation?: boolean; + firstSeen?: string; + lastSeen?: string; + count?: number; + causePageUrl?: string; + crawlGuid?: string; + pageGuid?: string; + resourceGuid?: string; + expectedHash?: string; +} + +export interface ScanMetadataOutput { + port?: number; + bannerMetadata?: string; + startScan?: string; + endScan?: string; +} + +export interface IpBlockOutput { + ipBlock?: string; + sources?: Array; + firstSeen?: string; + lastSeen?: string; + count?: number; + recent?: boolean; +} + +export interface SslServerConfigOutput { + tlsVersions?: string[]; + cipherSuites?: string[]; + firstSeen?: string; + lastSeen?: string; + count?: number; + sources?: Array; +} + +export interface BannerOutput { + port?: number; + banner?: string; + firstSeen?: string; + lastSeen?: string; + count?: number; + scanType?: string; + bannerMetadata?: string; + recent?: boolean; + sha256?: string; + sources?: Array; +} + +export interface IpAddressAssetOutput extends InventoryAssetOutput { + ipAddress?: string; + asns?: Array; + reputations?: Array; + webComponents?: Array; + netRanges?: Array; + headers?: Array; + attributes?: Array; + cookies?: Array; + sslCerts?: Array; + services?: Array; + ipBlocks?: Array; + sources?: Array; + firstSeen?: string; + lastSeen?: string; + count?: number; + banners?: Array; + scanMetadata?: Array; + nsRecord?: Array; + mxRecord?: Array; + location?: Array; + hosts?: Array; + nxdomain?: Array; + sslServerConfig?: Array; + ipv4?: boolean; + ipv6?: boolean; +} + +export interface ReputationOutput { + listName?: string; + threatType?: string; + trusted?: boolean; + cidr?: string; + firstSeen?: string; + lastSeen?: string; + listUpdatedAt?: string; + recent?: boolean; +} + +export interface IpBlockAssetOutput extends InventoryAssetOutput { + ipBlock?: string; + asns?: Array; + bgpPrefixes?: Array; + netNames?: Array; + registrantContacts?: Array; + registrantOrgs?: Array; + adminContacts?: Array; + technicalContacts?: Array; + registrarCreatedAt?: Array; + registrarUpdatedAt?: Array; + netRanges?: Array; + startIp?: string; + endIp?: string; + reputations?: Array; + detailedFromWhoisAt?: string; + sources?: Array; + firstSeen?: string; + lastSeen?: string; + count?: number; + location?: Array; + registrarExpiresAt?: Array; + registrantNames?: Array; + adminNames?: Array; + technicalNames?: Array; + adminOrgs?: Array; + technicalOrgs?: Array; + registrantPhones?: Array; + adminPhones?: Array; + technicalPhones?: Array; + ipv4?: boolean; + ipv6?: boolean; +} + +export interface PageAssetOutput extends InventoryAssetOutput { + url?: string; + httpMethod?: string; + service?: string; + ipAddresses?: Array; + successful?: Array; + httpResponseCodes?: Array; + httpResponseMessages?: Array; + responseTimes?: Array; + frames?: Array; + windows?: Array; + nonHtmlFrames?: Array; + undirectedContent?: Array; + contentTypes?: Array; + contentLengths?: Array; + windowNames?: Array; + charsets?: Array; + titles?: Array; + languages?: Array; + responseHeaders?: Array; + cookies?: Array; + webComponents?: Array; + attributes?: Array; + assetSecurityPolicies?: Array; + responseBodyMinhashSignatures?: Array; + fullDomMinhashSignatures?: Array; + responseBodyHashSignatures?: Array; + errors?: Array; + sslCerts?: Array; + sources?: Array; + firstSeen?: string; + lastSeen?: string; + count?: number; + cause?: PageCauseOutput; + referrer?: string; + redirectUrls?: Array; + /** Possible values: httpHeader, metaRefresh, javascript, final */ + redirectType?: string; + finalUrls?: Array; + finalResponseCodes?: Array; + parkedPage?: Array; + resourceUrls?: Array; + guids?: Array; + finalIpAddresses?: Array; + asns?: Array; + ipBlocks?: Array; + finalAsns?: Array; + finalIpBlocks?: Array; + responseBodies?: Array; + domainAsset?: DomainAssetOutput; + rootUrl?: ObservedBooleanOutput; + isRootUrl?: boolean; + location?: Array; + services?: Array; + siteStatus?: string; + cnames?: Array; + cdns?: Array; + host?: string; + domain?: string; + sslServerConfig?: Array; + gdprAssetSecurityPolicies?: Array; + ipv4?: Array; + ipv6?: Array; +} + +export interface AssetSecurityPolicyOutput { + policyName?: string; + isAffected?: boolean; + description?: string; + firstSeen?: string; + lastSeen?: string; + count?: number; + recent?: boolean; + sources?: Array; +} + +export interface PageCauseOutput { + cause?: string; + causeElementXPath?: string; + location?: string; + possibleMatches?: number; + loopDetected?: boolean; + version?: number; + domChangeIndex?: number; +} + +export interface GuidPairOutput { + pageGuid?: string; + crawlStateGuid?: string; + loadDate?: string; + recent?: boolean; +} + +export interface ContactAssetResourceOutput extends AssetResourceOutputParent { + /** The kind of AssetResource */ + kind: "contact"; + /** asset */ + asset: ContactAssetOutput; +} + +export interface DomainAssetResourceOutput extends AssetResourceOutputParent { + /** The kind of AssetResource */ + kind: "domain"; + /** asset */ + asset: DomainAssetOutput; +} + +export interface HostAssetResourceOutput extends AssetResourceOutputParent { + /** The kind of AssetResource */ + kind: "host"; + /** asset */ + asset: HostAssetOutput; +} + +export interface IpAddressAssetResourceOutput + extends AssetResourceOutputParent { + /** The kind of AssetResource */ + kind: "ipAddress"; + /** asset */ + asset: IpAddressAssetOutput; +} + +export interface IpBlockAssetResourceOutput extends AssetResourceOutputParent { + /** The kind of AssetResource */ + kind: "ipBlock"; + /** asset */ + asset: IpBlockAssetOutput; +} + +export interface PageAssetResourceOutput extends AssetResourceOutputParent { + /** The kind of AssetResource */ + kind: "page"; + /** asset */ + asset: PageAssetOutput; +} + +export interface SslCertAssetResourceOutput extends AssetResourceOutputParent { + /** The kind of AssetResource */ + kind: "sslCert"; + /** asset */ + asset: SslCertAssetOutput; +} + +export interface TaskOutput { + /** The unique identifier of the task. */ + readonly id: string; + /** The time the task started. */ + startedAt?: string; + /** The time the task completed. */ + completedAt?: string; + /** The last time the status of the task was updated. */ + lastPolledAt?: string; + /** + * The state the task is in. + * + * Possible values: pending, running, paused, complete, incomplete, failed, warning + */ + state?: string; + /** + * The phase the task is in. + * + * Possible values: running, polling, complete + */ + phase?: string; + /** The reason the task was moved into its current state, if the task wasn't completed. */ + reason?: string; + /** Attributes unique to the task. This differs by task type. */ + metadata?: Record; +} + +export interface DataConnectionOutputParent { + /** The system generated unique id for the resource. */ + id?: string; + /** The caller provided unique name for the resource. */ + readonly name: string; + /** The name that can be used for display purposes. */ + displayName?: string; + /** + * The type of data the data connection will transfer + * + * Possible values: assets, attackSurfaceInsights + */ + content?: string; + /** The date the data connection was created. */ + readonly createdDate?: string; + /** + * The rate at which the data connection will receive updates. + * + * Possible values: daily, weekly, monthly + */ + frequency?: string; + /** The day to update the data connection on. */ + frequencyOffset?: number; + /** The date the data connection was last updated. */ + readonly updatedDate?: string; + /** The date the data connection was last updated by user. */ + readonly userUpdatedAt?: string; + /** An indicator of whether the data connection is active. */ + active?: boolean; + /** A message that specifies details about data connection if inactive. */ + readonly inactiveMessage?: string; + kind: string; +} + +export interface LogAnalyticsDataConnectionOutput + extends DataConnectionOutputParent { + /** The kind of DataConnection */ + kind: "logAnalytics"; + /** properties */ + properties: LogAnalyticsDataConnectionPropertiesOutput; +} + +export interface LogAnalyticsDataConnectionPropertiesOutput + extends DataConnectionPropertiesOutput { + /** log analytics api key */ + apiKey?: string; + /** log analytics workspace id */ + workspaceId?: string; +} + +/** The properties required to establish connection to a particular service */ +export interface DataConnectionPropertiesOutput {} + +export interface AzureDataExplorerDataConnectionPropertiesOutput + extends DataConnectionPropertiesOutput { + /** The azure data explorer cluster name */ + clusterName?: string; + /** The azure data explorer region */ + region?: string; + /** The azure data explorer database name */ + databaseName?: string; +} + +export interface AzureDataExplorerDataConnectionOutput + extends DataConnectionOutputParent { + /** The kind of DataConnection */ + kind: "azureDataExplorer"; + /** properties */ + properties: AzureDataExplorerDataConnectionPropertiesOutput; +} + +export interface ValidateResultOutput { + /** This is the top-level error object whose code matches the x-ms-error-code response header. */ + error?: ErrorDetailOutput; +} + +/** This is the top-level error object whose code matches the x-ms-error-code response header. */ +export interface ErrorDetailOutput { + /** This is one of a server-defined set of error codes. */ + code: string; + /** This is a human-readable representation of the error. */ + message: string; + /** This is the error target. */ + target?: string; + /** This is an array of details about specific errors that led to this reported error. */ + details?: Array; + /** This is an object containing more specific information than the current object about the error. */ + innererror?: InnerErrorOutput; +} + +/** This is an object containing more specific information than the current object about the error. */ +export interface InnerErrorOutput { + /** This is a more specific error code than was provided by the containing error. */ + code?: string; + /** This is an additional field representing the value that caused the error to help with debugging. */ + value?: any; +} + +export interface DiscoGroupOutput { + /** The system generated unique id for the resource. */ + id?: string; + /** The caller provided unique name for the resource. */ + readonly name: string; + /** The name that can be used for display purposes. */ + displayName?: string; + /** The description for a disco group. */ + description?: string; + /** The tier for the disco group which will affect the algorithm used for the disco runs in this group. */ + tier?: string; + /** The frequency at which the disco group is supposed to be rerun in milliseconds. */ + frequencyMilliseconds?: number; + /** The list of seeds used for the disco group runs. */ + seeds?: Array; + /** The list of names used for the disco group runs. */ + names?: string[]; + /** The list of excludes used for the disco group runs, aka assets to exclude from the discovery algorithm. */ + excludes?: Array; + /** The latest run of this disco group with some limited information, null if the group has never been run. */ + latestRun?: DiscoRunResultOutput; + /** The date for the disco group was created. */ + createdDate?: string; + /** The unique identifier for the disco template used for the disco group creation. */ + templateId?: string; +} + +/** Source entity used to drive discovery. */ +export interface DiscoSourceOutput { + /** + * The kind of disco source. + * + * Possible values: as, attribute, contact, domain, host, ipBlock + */ + kind?: string; + /** The name for the disco source. */ + name?: string; +} + +/** The latest run of this disco group with some limited information, null if the group has never been run. */ +export interface DiscoRunResultOutput { + /** The date for when the disco run was created in the system. */ + submittedDate?: string; + /** The date for when the disco run was actually started by the system. */ + startedDate?: string; + /** The date for when the disco run was completed by the system. */ + completedDate?: string; + /** The tier which will affect the algorithm used for the disco run. */ + tier?: string; + /** + * The State of the disco run. + * + * Possible values: pending, running, completed, failed + */ + state?: string; + /** The total count of assets that were found this disco run. */ + totalAssetsFoundCount?: number; + /** The list of seeds used for the disco run. */ + seeds?: Array; + /** The list of excludes used for the disco run, aka assets to exclude from the discovery algorithm. */ + excludes?: Array; + /** The list of names used for the disco run. */ + names?: string[]; +} + +export interface DiscoRunPageResultOutput { + /** The total number of items available in the full result set. */ + totalElements?: number; + /** The link to access the next page of results. Not set if at the end of the result set. */ + nextLink?: string; + /** The items in the current page of results. */ + value?: Array; +} + +/** The items in the current page of results. */ +export interface DiscoTemplateOutput { + /** The system generated unique id for the resource. */ + readonly id: string; + /** The caller provided unique name for the resource. */ + name?: string; + /** The name that can be used for display purposes. */ + displayName?: string; + /** The name of the industry. */ + industry?: string; + /** The name of the region. */ + region?: string; + /** The country code. */ + countryCode?: string; + /** The state code. */ + stateCode?: string; + /** The name of the city. */ + city?: string; + /** The list of disco template seeds. */ + seeds?: Array; + /** The list of disco template names. */ + names?: string[]; +} + +export interface ReportBillableAssetSummaryResultOutput { + assetSummaries?: Array; +} + +export interface ReportBillableAssetSnapshotResultOutput { + /** The date these assets were billed on. */ + date?: string; + /** The total number of billable assets for this date. */ + total?: number; + /** The breakdown of billable asset counts for each asset type. */ + assetBreakdown?: Array; +} + +/** The breakdown of billable asset counts for each asset type. */ +export interface ReportBillableAssetBreakdownOutput { + /** + * The kind of billable asset. + * + * Possible values: domain, host, ipAddress + */ + kind?: string; + /** The number of assets of this type. */ + count?: number; +} + +/** A snapshot of assets captured daily for the provided metric. Asset details only contain primary properties. Detailed asset data can be retrieved from the asset endpoints. */ +export interface ReportAssetSnapshotResultOutput { + /** The name of the metric. */ + displayName?: string; + /** The unique metric name. */ + metric?: string; + /** The customer label that was filtered on, if one was provided. */ + labelName?: string; + /** The last time this asset data was updated on this metric. */ + updatedAt?: string; + /** A description of what the metric represents. */ + description?: string; + /** The page of assets that match the provided metric. */ + assets?: AssetPageResultOutput; +} + +/** The page of assets that match the provided metric. */ +export interface AssetPageResultOutput { + /** The total number of items available in the full result set. */ + totalElements?: number; + /** The cursor mark to be used on the next request. Not set if using paging. */ + mark?: string; + /** The link to access the next page of results. Not set if at the end of the result set. */ + nextLink?: string; + /** The items in the current page of results. */ + value?: Array; +} + +export interface ReportAssetSummaryResultOutput { + /** The collection of asset summaries. */ + assetSummaries?: Array; +} + +/** The collection of asset summaries. */ +export interface AssetSummaryResultOutput { + /** The name of the summary response. Depending on the request time this will either be the asset filter, risk category, or risk metric. */ + displayName?: string; + /** The description of the summary response. Filters don't have a description. */ + description?: string; + /** The last time risk categories or risk metrics were captured. Set to the current time for asset filter requests, which always pull the live asset data. */ + updatedAt?: string; + /** If the request is for a metric category, this will contain the requested unique category name. */ + metricCategory?: string; + /** If the request is for a metric, this will contain the requested unique metric name. */ + metric?: string; + /** If the request is for an asset filter, this will contain the corresponding filter. */ + filter?: string; + /** An optional label used to filter requests results. */ + labelName?: string; + /** The count of assets matching the request parameters. */ + count?: number; + /** The link to the corresponding asset details. */ + link?: string; + /** The corresponding child entities. For metric categories this will contain metrics. For filters with groupBy and segmentBy this will contain facets. */ + children?: Array; +} + +export interface SavedFilterOutput { + /** The system generated unique id for the resource. */ + id?: string; + /** The caller provided unique name for the resource. */ + readonly name: string; + /** The name that can be used for display purposes. */ + displayName?: string; + filter?: string; + description?: string; +} + +/** The items in the current page of results. */ +export type AssetResourceOutput = + | AsAssetResourceOutput + | ContactAssetResourceOutput + | DomainAssetResourceOutput + | HostAssetResourceOutput + | IpAddressAssetResourceOutput + | IpBlockAssetResourceOutput + | PageAssetResourceOutput + | SslCertAssetResourceOutput; +export type DataConnectionOutput = + | LogAnalyticsDataConnectionOutput + | AzureDataExplorerDataConnectionOutput; +/** Paged collection of AssetResource items */ +export type PagedAssetResourceOutput = Paged; +/** Paged collection of DataConnection items */ +export type PagedDataConnectionOutput = Paged; +/** Paged collection of DiscoGroup items */ +export type PagedDiscoGroupOutput = Paged; +/** Paged collection of DiscoTemplate items */ +export type PagedDiscoTemplateOutput = Paged; +/** Paged collection of SavedFilter items */ +export type PagedSavedFilterOutput = Paged; +/** Paged collection of Task items */ +export type PagedTaskOutput = Paged; diff --git a/sdk/easm/defendereasm-rest/src/paginateHelper.ts b/sdk/easm/defendereasm-rest/src/paginateHelper.ts new file mode 100644 index 000000000000..1c9af35b1efd --- /dev/null +++ b/sdk/easm/defendereasm-rest/src/paginateHelper.ts @@ -0,0 +1,154 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { + getPagedAsyncIterator, + PagedAsyncIterableIterator, + PagedResult, +} from "@azure/core-paging"; +import { + Client, + createRestError, + PathUncheckedResponse, +} from "@azure-rest/core-client"; + +/** + * Helper type to extract the type of an array + */ +export type GetArrayType = T extends Array ? TData : never; + +/** + * The type of a custom function that defines how to get a page and a link to the next one if any. + */ +export type GetPage = ( + pageLink: string, + maxPageSize?: number +) => Promise<{ + page: TPage; + nextPageLink?: string; +}>; + +/** + * Options for the paging helper + */ +export interface PagingOptions { + /** + * Custom function to extract pagination details for crating the PagedAsyncIterableIterator + */ + customGetPage?: GetPage[]>; +} + +/** + * Helper type to infer the Type of the paged elements from the response type + * This type is generated based on the swagger information for x-ms-pageable + * specifically on the itemName property which indicates the property of the response + * where the page items are found. The default value is `value`. + * This type will allow us to provide strongly typed Iterator based on the response we get as second parameter + */ +export type PaginateReturn = TResult extends { + body: { value?: infer TPage }; +} + ? GetArrayType + : Array; + +/** + * Helper to paginate results from an initial response that follows the specification of Autorest `x-ms-pageable` extension + * @param client - Client to use for sending the next page requests + * @param initialResponse - Initial response containing the nextLink and current page of elements + * @param customGetPage - Optional - Function to define how to extract the page and next link to be used to paginate the results + * @returns - PagedAsyncIterableIterator to iterate the elements + */ +export function paginate( + client: Client, + initialResponse: TResponse, + options: PagingOptions = {} +): PagedAsyncIterableIterator> { + // Extract element type from initial response + type TElement = PaginateReturn; + let firstRun = true; + const itemName = "value"; + const nextLinkName = "nextLink"; + const { customGetPage } = options; + const pagedResult: PagedResult = { + firstPageLink: "", + getPage: + typeof customGetPage === "function" + ? customGetPage + : async (pageLink: string) => { + const result = firstRun + ? initialResponse + : await client.pathUnchecked(pageLink).get(); + firstRun = false; + checkPagingRequest(result); + const nextLink = getNextLink(result.body, nextLinkName); + const values = getElements(result.body, itemName); + return { + page: values, + nextPageLink: nextLink, + }; + }, + }; + + return getPagedAsyncIterator(pagedResult); +} + +/** + * Gets for the value of nextLink in the body + */ +function getNextLink(body: unknown, nextLinkName?: string): string | undefined { + if (!nextLinkName) { + return undefined; + } + + const nextLink = (body as Record)[nextLinkName]; + + if (typeof nextLink !== "string" && typeof nextLink !== "undefined") { + throw new Error( + `Body Property ${nextLinkName} should be a string or undefined` + ); + } + + return nextLink; +} + +/** + * Gets the elements of the current request in the body. + */ +function getElements(body: unknown, itemName: string): T[] { + const value = (body as Record)[itemName] as T[]; + + // value has to be an array according to the x-ms-pageable extension. + // The fact that this must be an array is used above to calculate the + // type of elements in the page in PaginateReturn + if (!Array.isArray(value)) { + throw new Error( + `Couldn't paginate response\n Body doesn't contain an array property with name: ${itemName}` + ); + } + + return value ?? []; +} + +/** + * Checks if a request failed + */ +function checkPagingRequest(response: PathUncheckedResponse): void { + const Http2xxStatusCodes = [ + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "226", + ]; + if (!Http2xxStatusCodes.includes(response.status)) { + throw createRestError( + `Pagination failed with unexpected statusCode ${response.status}`, + response + ); + } +} diff --git a/sdk/easm/defendereasm-rest/src/parameters.ts b/sdk/easm/defendereasm-rest/src/parameters.ts new file mode 100644 index 000000000000..65b7471f8653 --- /dev/null +++ b/sdk/easm/defendereasm-rest/src/parameters.ts @@ -0,0 +1,203 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { RequestParameters } from "@azure-rest/core-client"; +import { + AssetResource, + DataConnectionData, + DataConnection, + DiscoGroupData, + DiscoGroup, + ReportAssetSnapshotRequest, + ReportAssetSummaryRequest, + SavedFilter, +} from "./models"; + +export interface ListAssetResourceQueryParamProperties { + /** Filter the result list using the given expression. */ + filter?: string; + /** A list of expressions that specify the order of the returned resources. */ + orderby?: string; + /** The number of result items to skip. */ + skip?: number; + /** The maximum number of result items per page. */ + maxpagesize?: number; + /** Specify this value instead of 'skip' to use cursor-based searching. Initial value is '*' and subsequent values are returned in the response. */ + mark?: string; +} + +export interface ListAssetResourceQueryParam { + queryParameters?: ListAssetResourceQueryParamProperties; +} + +export type ListAssetResourceParameters = ListAssetResourceQueryParam & + RequestParameters; + +export interface UpdateAssetsBodyParam { + body?: AssetResource; +} + +export interface UpdateAssetsQueryParamProperties { + /** An expression on the resource type that selects the resources to be returned. */ + filter: string; +} + +export interface UpdateAssetsQueryParam { + queryParameters: UpdateAssetsQueryParamProperties; +} + +export type UpdateAssetsParameters = UpdateAssetsQueryParam & + UpdateAssetsBodyParam & + RequestParameters; +export type GetAssetResourceParameters = RequestParameters; + +export interface ListDataConnectionQueryParamProperties { + /** The number of result items to skip. */ + skip?: number; + /** The maximum number of result items per page. */ + maxpagesize?: number; +} + +export interface ListDataConnectionQueryParam { + queryParameters?: ListDataConnectionQueryParamProperties; +} + +export type ListDataConnectionParameters = ListDataConnectionQueryParam & + RequestParameters; + +export interface ValidateDataConnectionBodyParam { + body?: DataConnectionData; +} + +export type ValidateDataConnectionParameters = ValidateDataConnectionBodyParam & + RequestParameters; +export type GetDataConnectionParameters = RequestParameters; + +export interface CreateOrReplaceDataConnectionBodyParam { + body?: DataConnection; +} + +export type CreateOrReplaceDataConnectionParameters = + CreateOrReplaceDataConnectionBodyParam & RequestParameters; +export type DeleteDataConnectionParameters = RequestParameters; + +export interface ListDiscoGroupQueryParamProperties { + /** Filter the result list using the given expression. */ + filter?: string; + /** The number of result items to skip. */ + skip?: number; + /** The maximum number of result items per page. */ + maxpagesize?: number; +} + +export interface ListDiscoGroupQueryParam { + queryParameters?: ListDiscoGroupQueryParamProperties; +} + +export type ListDiscoGroupParameters = ListDiscoGroupQueryParam & + RequestParameters; + +export interface ValidateDiscoGroupBodyParam { + body?: DiscoGroupData; +} + +export type ValidateDiscoGroupParameters = ValidateDiscoGroupBodyParam & + RequestParameters; +export type GetDiscoGroupParameters = RequestParameters; + +export interface CreateOrReplaceDiscoGroupBodyParam { + body?: DiscoGroup; +} + +export type CreateOrReplaceDiscoGroupParameters = + CreateOrReplaceDiscoGroupBodyParam & RequestParameters; +export type RunDiscoGroupParameters = RequestParameters; + +export interface ListRunsQueryParamProperties { + /** Filter the result list using the given expression. */ + filter?: string; + /** The number of result items to skip. */ + skip?: number; + /** The maximum number of result items per page. */ + maxpagesize?: number; +} + +export interface ListRunsQueryParam { + queryParameters?: ListRunsQueryParamProperties; +} + +export type ListRunsParameters = ListRunsQueryParam & RequestParameters; + +export interface ListDiscoTemplateQueryParamProperties { + /** Filter the result list using the given expression. */ + filter?: string; + /** The number of result items to skip. */ + skip?: number; + /** The maximum number of result items per page. */ + maxpagesize?: number; +} + +export interface ListDiscoTemplateQueryParam { + queryParameters?: ListDiscoTemplateQueryParamProperties; +} + +export type ListDiscoTemplateParameters = ListDiscoTemplateQueryParam & + RequestParameters; +export type GetDiscoTemplateParameters = RequestParameters; +export type GetBillableParameters = RequestParameters; + +export interface GetSnapshotBodyParam { + body?: ReportAssetSnapshotRequest; +} + +export type GetSnapshotParameters = GetSnapshotBodyParam & RequestParameters; + +export interface GetSummaryBodyParam { + body?: ReportAssetSummaryRequest; +} + +export type GetSummaryParameters = GetSummaryBodyParam & RequestParameters; + +export interface ListSavedFilterQueryParamProperties { + /** Filter the result list using the given expression. */ + filter?: string; + /** The number of result items to skip. */ + skip?: number; + /** The maximum number of result items per page. */ + maxpagesize?: number; +} + +export interface ListSavedFilterQueryParam { + queryParameters?: ListSavedFilterQueryParamProperties; +} + +export type ListSavedFilterParameters = ListSavedFilterQueryParam & + RequestParameters; +export type GetSavedFilterParameters = RequestParameters; + +export interface CreateOrReplaceSavedFilterBodyParam { + body?: SavedFilter; +} + +export type CreateOrReplaceSavedFilterParameters = + CreateOrReplaceSavedFilterBodyParam & RequestParameters; +export type DeleteSavedFilterParameters = RequestParameters; + +export interface ListTaskQueryParamProperties { + /** Filter the result list using the given expression. */ + filter?: string; + /** A list of expressions that specify the order of the returned resources. */ + orderby?: string; + /** The number of result items to skip. */ + skip?: number; + /** The maximum number of result items per page. */ + maxpagesize?: number; +} + +export interface ListTaskQueryParam { + queryParameters?: ListTaskQueryParamProperties; +} + +export type ListTaskParameters = ListTaskQueryParam & RequestParameters; +export type GetTaskParameters = RequestParameters; +export type CancelTaskParameters = RequestParameters; diff --git a/sdk/easm/defendereasm-rest/src/responses.ts b/sdk/easm/defendereasm-rest/src/responses.ts new file mode 100644 index 000000000000..992cb37d59e8 --- /dev/null +++ b/sdk/easm/defendereasm-rest/src/responses.ts @@ -0,0 +1,465 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { RawHttpHeaders } from "@azure/core-rest-pipeline"; +import { HttpResponse, ErrorResponse } from "@azure-rest/core-client"; +import { + PagedAssetResourceOutput, + TaskOutput, + AssetResourceOutput, + PagedDataConnectionOutput, + ValidateResultOutput, + DataConnectionOutput, + PagedDiscoGroupOutput, + DiscoGroupOutput, + DiscoRunPageResultOutput, + PagedDiscoTemplateOutput, + DiscoTemplateOutput, + ReportBillableAssetSummaryResultOutput, + ReportAssetSnapshotResultOutput, + ReportAssetSummaryResultOutput, + PagedSavedFilterOutput, + SavedFilterOutput, + PagedTaskOutput, +} from "./outputModels"; + +/** The request has succeeded. */ +export interface ListAssetResource200Response extends HttpResponse { + status: "200"; + body: PagedAssetResourceOutput; +} + +export interface ListAssetResourceDefaultHeaders { + /** String error code indicating what went wrong. */ + "x-ms-error-code"?: string; +} + +export interface ListAssetResourceDefaultResponse extends HttpResponse { + status: string; + body: ErrorResponse; + headers: RawHttpHeaders & ListAssetResourceDefaultHeaders; +} + +/** The request has succeeded. */ +export interface UpdateAssets200Response extends HttpResponse { + status: "200"; + body: TaskOutput; +} + +export interface UpdateAssetsDefaultHeaders { + /** String error code indicating what went wrong. */ + "x-ms-error-code"?: string; +} + +export interface UpdateAssetsDefaultResponse extends HttpResponse { + status: string; + body: ErrorResponse; + headers: RawHttpHeaders & UpdateAssetsDefaultHeaders; +} + +/** The request has succeeded. */ +export interface GetAssetResource200Response extends HttpResponse { + status: "200"; + body: AssetResourceOutput; +} + +export interface GetAssetResourceDefaultHeaders { + /** String error code indicating what went wrong. */ + "x-ms-error-code"?: string; +} + +export interface GetAssetResourceDefaultResponse extends HttpResponse { + status: string; + body: ErrorResponse; + headers: RawHttpHeaders & GetAssetResourceDefaultHeaders; +} + +/** The request has succeeded. */ +export interface ListDataConnection200Response extends HttpResponse { + status: "200"; + body: PagedDataConnectionOutput; +} + +export interface ListDataConnectionDefaultHeaders { + /** String error code indicating what went wrong. */ + "x-ms-error-code"?: string; +} + +export interface ListDataConnectionDefaultResponse extends HttpResponse { + status: string; + body: ErrorResponse; + headers: RawHttpHeaders & ListDataConnectionDefaultHeaders; +} + +/** The request has succeeded. */ +export interface ValidateDataConnection200Response extends HttpResponse { + status: "200"; + body: ValidateResultOutput; +} + +export interface ValidateDataConnectionDefaultHeaders { + /** String error code indicating what went wrong. */ + "x-ms-error-code"?: string; +} + +export interface ValidateDataConnectionDefaultResponse extends HttpResponse { + status: string; + body: ErrorResponse; + headers: RawHttpHeaders & ValidateDataConnectionDefaultHeaders; +} + +/** The request has succeeded. */ +export interface GetDataConnection200Response extends HttpResponse { + status: "200"; + body: DataConnectionOutput; +} + +export interface GetDataConnectionDefaultHeaders { + /** String error code indicating what went wrong. */ + "x-ms-error-code"?: string; +} + +export interface GetDataConnectionDefaultResponse extends HttpResponse { + status: string; + body: ErrorResponse; + headers: RawHttpHeaders & GetDataConnectionDefaultHeaders; +} + +/** The request has succeeded. */ +export interface CreateOrReplaceDataConnection200Response extends HttpResponse { + status: "200"; + body: DataConnectionOutput; +} + +export interface CreateOrReplaceDataConnectionDefaultHeaders { + /** String error code indicating what went wrong. */ + "x-ms-error-code"?: string; +} + +export interface CreateOrReplaceDataConnectionDefaultResponse + extends HttpResponse { + status: string; + body: ErrorResponse; + headers: RawHttpHeaders & CreateOrReplaceDataConnectionDefaultHeaders; +} + +/** There is no content to send for this request, but the headers may be useful. */ +export interface DeleteDataConnection204Response extends HttpResponse { + status: "204"; +} + +export interface DeleteDataConnectionDefaultHeaders { + /** String error code indicating what went wrong. */ + "x-ms-error-code"?: string; +} + +export interface DeleteDataConnectionDefaultResponse extends HttpResponse { + status: string; + body: ErrorResponse; + headers: RawHttpHeaders & DeleteDataConnectionDefaultHeaders; +} + +/** The request has succeeded. */ +export interface ListDiscoGroup200Response extends HttpResponse { + status: "200"; + body: PagedDiscoGroupOutput; +} + +export interface ListDiscoGroupDefaultHeaders { + /** String error code indicating what went wrong. */ + "x-ms-error-code"?: string; +} + +export interface ListDiscoGroupDefaultResponse extends HttpResponse { + status: string; + body: ErrorResponse; + headers: RawHttpHeaders & ListDiscoGroupDefaultHeaders; +} + +/** The request has succeeded. */ +export interface ValidateDiscoGroup200Response extends HttpResponse { + status: "200"; + body: ValidateResultOutput; +} + +export interface ValidateDiscoGroupDefaultHeaders { + /** String error code indicating what went wrong. */ + "x-ms-error-code"?: string; +} + +export interface ValidateDiscoGroupDefaultResponse extends HttpResponse { + status: string; + body: ErrorResponse; + headers: RawHttpHeaders & ValidateDiscoGroupDefaultHeaders; +} + +/** The request has succeeded. */ +export interface GetDiscoGroup200Response extends HttpResponse { + status: "200"; + body: DiscoGroupOutput; +} + +export interface GetDiscoGroupDefaultHeaders { + /** String error code indicating what went wrong. */ + "x-ms-error-code"?: string; +} + +export interface GetDiscoGroupDefaultResponse extends HttpResponse { + status: string; + body: ErrorResponse; + headers: RawHttpHeaders & GetDiscoGroupDefaultHeaders; +} + +/** The request has succeeded. */ +export interface CreateOrReplaceDiscoGroup200Response extends HttpResponse { + status: "200"; + body: DiscoGroupOutput; +} + +export interface CreateOrReplaceDiscoGroupDefaultHeaders { + /** String error code indicating what went wrong. */ + "x-ms-error-code"?: string; +} + +export interface CreateOrReplaceDiscoGroupDefaultResponse extends HttpResponse { + status: string; + body: ErrorResponse; + headers: RawHttpHeaders & CreateOrReplaceDiscoGroupDefaultHeaders; +} + +/** There is no content to send for this request, but the headers may be useful. */ +export interface RunDiscoGroup204Response extends HttpResponse { + status: "204"; +} + +export interface RunDiscoGroupDefaultHeaders { + /** String error code indicating what went wrong. */ + "x-ms-error-code"?: string; +} + +export interface RunDiscoGroupDefaultResponse extends HttpResponse { + status: string; + body: ErrorResponse; + headers: RawHttpHeaders & RunDiscoGroupDefaultHeaders; +} + +/** The request has succeeded. */ +export interface ListRuns200Response extends HttpResponse { + status: "200"; + body: DiscoRunPageResultOutput; +} + +export interface ListRunsDefaultHeaders { + /** String error code indicating what went wrong. */ + "x-ms-error-code"?: string; +} + +export interface ListRunsDefaultResponse extends HttpResponse { + status: string; + body: ErrorResponse; + headers: RawHttpHeaders & ListRunsDefaultHeaders; +} + +/** The request has succeeded. */ +export interface ListDiscoTemplate200Response extends HttpResponse { + status: "200"; + body: PagedDiscoTemplateOutput; +} + +export interface ListDiscoTemplateDefaultHeaders { + /** String error code indicating what went wrong. */ + "x-ms-error-code"?: string; +} + +export interface ListDiscoTemplateDefaultResponse extends HttpResponse { + status: string; + body: ErrorResponse; + headers: RawHttpHeaders & ListDiscoTemplateDefaultHeaders; +} + +/** The request has succeeded. */ +export interface GetDiscoTemplate200Response extends HttpResponse { + status: "200"; + body: DiscoTemplateOutput; +} + +export interface GetDiscoTemplateDefaultHeaders { + /** String error code indicating what went wrong. */ + "x-ms-error-code"?: string; +} + +export interface GetDiscoTemplateDefaultResponse extends HttpResponse { + status: string; + body: ErrorResponse; + headers: RawHttpHeaders & GetDiscoTemplateDefaultHeaders; +} + +/** The request has succeeded. */ +export interface GetBillable200Response extends HttpResponse { + status: "200"; + body: ReportBillableAssetSummaryResultOutput; +} + +export interface GetBillableDefaultHeaders { + /** String error code indicating what went wrong. */ + "x-ms-error-code"?: string; +} + +export interface GetBillableDefaultResponse extends HttpResponse { + status: string; + body: ErrorResponse; + headers: RawHttpHeaders & GetBillableDefaultHeaders; +} + +/** The request has succeeded. */ +export interface GetSnapshot200Response extends HttpResponse { + status: "200"; + body: ReportAssetSnapshotResultOutput; +} + +export interface GetSnapshotDefaultHeaders { + /** String error code indicating what went wrong. */ + "x-ms-error-code"?: string; +} + +export interface GetSnapshotDefaultResponse extends HttpResponse { + status: string; + body: ErrorResponse; + headers: RawHttpHeaders & GetSnapshotDefaultHeaders; +} + +/** The request has succeeded. */ +export interface GetSummary200Response extends HttpResponse { + status: "200"; + body: ReportAssetSummaryResultOutput; +} + +export interface GetSummaryDefaultHeaders { + /** String error code indicating what went wrong. */ + "x-ms-error-code"?: string; +} + +export interface GetSummaryDefaultResponse extends HttpResponse { + status: string; + body: ErrorResponse; + headers: RawHttpHeaders & GetSummaryDefaultHeaders; +} + +/** The request has succeeded. */ +export interface ListSavedFilter200Response extends HttpResponse { + status: "200"; + body: PagedSavedFilterOutput; +} + +export interface ListSavedFilterDefaultHeaders { + /** String error code indicating what went wrong. */ + "x-ms-error-code"?: string; +} + +export interface ListSavedFilterDefaultResponse extends HttpResponse { + status: string; + body: ErrorResponse; + headers: RawHttpHeaders & ListSavedFilterDefaultHeaders; +} + +/** The request has succeeded. */ +export interface GetSavedFilter200Response extends HttpResponse { + status: "200"; + body: SavedFilterOutput; +} + +export interface GetSavedFilterDefaultHeaders { + /** String error code indicating what went wrong. */ + "x-ms-error-code"?: string; +} + +export interface GetSavedFilterDefaultResponse extends HttpResponse { + status: string; + body: ErrorResponse; + headers: RawHttpHeaders & GetSavedFilterDefaultHeaders; +} + +/** The request has succeeded. */ +export interface CreateOrReplaceSavedFilter200Response extends HttpResponse { + status: "200"; + body: SavedFilterOutput; +} + +export interface CreateOrReplaceSavedFilterDefaultHeaders { + /** String error code indicating what went wrong. */ + "x-ms-error-code"?: string; +} + +export interface CreateOrReplaceSavedFilterDefaultResponse + extends HttpResponse { + status: string; + body: ErrorResponse; + headers: RawHttpHeaders & CreateOrReplaceSavedFilterDefaultHeaders; +} + +/** There is no content to send for this request, but the headers may be useful. */ +export interface DeleteSavedFilter204Response extends HttpResponse { + status: "204"; +} + +export interface DeleteSavedFilterDefaultHeaders { + /** String error code indicating what went wrong. */ + "x-ms-error-code"?: string; +} + +export interface DeleteSavedFilterDefaultResponse extends HttpResponse { + status: string; + body: ErrorResponse; + headers: RawHttpHeaders & DeleteSavedFilterDefaultHeaders; +} + +/** The request has succeeded. */ +export interface ListTask200Response extends HttpResponse { + status: "200"; + body: PagedTaskOutput; +} + +export interface ListTaskDefaultHeaders { + /** String error code indicating what went wrong. */ + "x-ms-error-code"?: string; +} + +export interface ListTaskDefaultResponse extends HttpResponse { + status: string; + body: ErrorResponse; + headers: RawHttpHeaders & ListTaskDefaultHeaders; +} + +/** The request has succeeded. */ +export interface GetTask200Response extends HttpResponse { + status: "200"; + body: TaskOutput; +} + +export interface GetTaskDefaultHeaders { + /** String error code indicating what went wrong. */ + "x-ms-error-code"?: string; +} + +export interface GetTaskDefaultResponse extends HttpResponse { + status: string; + body: ErrorResponse; + headers: RawHttpHeaders & GetTaskDefaultHeaders; +} + +/** The request has succeeded. */ +export interface CancelTask200Response extends HttpResponse { + status: "200"; + body: TaskOutput; +} + +export interface CancelTaskDefaultHeaders { + /** String error code indicating what went wrong. */ + "x-ms-error-code"?: string; +} + +export interface CancelTaskDefaultResponse extends HttpResponse { + status: string; + body: ErrorResponse; + headers: RawHttpHeaders & CancelTaskDefaultHeaders; +} diff --git a/sdk/easm/defendereasm-rest/test/public/sampleTest.spec.ts b/sdk/easm/defendereasm-rest/test/public/sampleTest.spec.ts new file mode 100644 index 000000000000..bce68e428645 --- /dev/null +++ b/sdk/easm/defendereasm-rest/test/public/sampleTest.spec.ts @@ -0,0 +1,23 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { Recorder } from "@azure-tools/test-recorder"; +import { assert } from "chai"; +import { createRecorder } from "./utils/recordedClient"; +import { Context } from "mocha"; + +describe("My test", () => { + let recorder: Recorder; + + beforeEach(async function (this: Context) { + recorder = await createRecorder(this); + }); + + afterEach(async function () { + await recorder.stop(); + }); + + it("sample test", async function () { + assert.equal(1, 1); + }); +}); diff --git a/sdk/easm/defendereasm-rest/test/public/utils/env.browser.ts b/sdk/easm/defendereasm-rest/test/public/utils/env.browser.ts new file mode 100644 index 000000000000..fd2aca680c7b --- /dev/null +++ b/sdk/easm/defendereasm-rest/test/public/utils/env.browser.ts @@ -0,0 +1,2 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. diff --git a/sdk/easm/defendereasm-rest/test/public/utils/env.ts b/sdk/easm/defendereasm-rest/test/public/utils/env.ts new file mode 100644 index 000000000000..0e06855b73ae --- /dev/null +++ b/sdk/easm/defendereasm-rest/test/public/utils/env.ts @@ -0,0 +1,6 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import * as dotenv from "dotenv"; + +dotenv.config(); diff --git a/sdk/easm/defendereasm-rest/test/public/utils/recordedClient.ts b/sdk/easm/defendereasm-rest/test/public/utils/recordedClient.ts new file mode 100644 index 000000000000..6cc58bc15e11 --- /dev/null +++ b/sdk/easm/defendereasm-rest/test/public/utils/recordedClient.ts @@ -0,0 +1,29 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { Context } from "mocha"; +import { Recorder, RecorderStartOptions } from "@azure-tools/test-recorder"; +import "./env"; + +const envSetupForPlayback: Record = { + ENDPOINT: "https://endpoint", + AZURE_CLIENT_ID: "azure_client_id", + AZURE_CLIENT_SECRET: "azure_client_secret", + AZURE_TENANT_ID: "88888888-8888-8888-8888-888888888888", + SUBSCRIPTION_ID: "azure_subscription_id", +}; + +const recorderEnvSetup: RecorderStartOptions = { + envSetupForPlayback, +}; + +/** + * creates the recorder and reads the environment variables from the `.env` file. + * Should be called first in the test suite to make sure environment variables are + * read before they are being used. + */ +export async function createRecorder(context: Context): Promise { + const recorder = new Recorder(context.currentTest); + await recorder.start(recorderEnvSetup); + return recorder; +} diff --git a/sdk/easm/defendereasm-rest/tsconfig.json b/sdk/easm/defendereasm-rest/tsconfig.json new file mode 100644 index 000000000000..d5bf593423c9 --- /dev/null +++ b/sdk/easm/defendereasm-rest/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../../../tsconfig.package", + "compilerOptions": { + "outDir": "./dist-esm", + "declarationDir": "./types" + }, + "include": [ + "src/**/*.ts", + "./test/**/*.ts" + ] +} \ No newline at end of file diff --git a/sdk/easm/defendereasm-rest/tsp-location.yaml b/sdk/easm/defendereasm-rest/tsp-location.yaml new file mode 100644 index 000000000000..8a46a40c02bc --- /dev/null +++ b/sdk/easm/defendereasm-rest/tsp-location.yaml @@ -0,0 +1,5 @@ +repo: Azure/azure-rest-api-specs +directory: specification/riskiq/Easm +additionalDirectories: [] +commit: 865101fbf0e04604f15cd1bd65680dd1599ab03e +