From 3495fe325edc3ff2138495511b9472c64ead6d2e Mon Sep 17 00:00:00 2001 From: Deyaaeldeen Almahallawi Date: Mon, 21 Sep 2020 16:29:28 -0400 Subject: [PATCH 001/152] [Abort Controller] Update linting and fix linting errors (#11269) * update linting and fix linting errors * update linting scripts * formatting * fix linting errors * fixes * fix * run api-extractor * include the shim files in shipped files * use the unrolledup type declarations * do not lint package.json * still lint package.json * remove the call to api-extractor from the npm build script * simplify eslint commands * only ship src types --- sdk/core/abort-controller/.eslintrc.json | 7 +++++++ sdk/core/abort-controller/api-extractor.json | 4 ++-- sdk/core/abort-controller/package.json | 21 +++++++++++-------- .../review/abort-controller.api.md | 2 +- .../abort-controller/rollup.base.config.js | 2 +- .../{src => }/shims-public.d.ts | 3 +++ .../abort-controller/src/AbortController.ts | 4 ++++ sdk/core/abort-controller/src/AbortSignal.ts | 6 +++++- .../src/{aborter.ts => index.ts} | 3 +++ .../abort-controller/test/aborter.spec.ts | 17 ++++++++------- 10 files changed, 48 insertions(+), 21 deletions(-) create mode 100644 sdk/core/abort-controller/.eslintrc.json rename sdk/core/abort-controller/{src => }/shims-public.d.ts (52%) rename sdk/core/abort-controller/src/{aborter.ts => index.ts} (87%) diff --git a/sdk/core/abort-controller/.eslintrc.json b/sdk/core/abort-controller/.eslintrc.json new file mode 100644 index 000000000000..e71d23ff6f57 --- /dev/null +++ b/sdk/core/abort-controller/.eslintrc.json @@ -0,0 +1,7 @@ +{ + "plugins": ["@azure/azure-sdk"], + "extends": ["plugin:@azure/azure-sdk/azure-sdk-base"], + "rules": { + "@azure/azure-sdk/ts-package-json-types": "off" + } +} diff --git a/sdk/core/abort-controller/api-extractor.json b/sdk/core/abort-controller/api-extractor.json index 263e349ba659..8265070b9a1f 100644 --- a/sdk/core/abort-controller/api-extractor.json +++ b/sdk/core/abort-controller/api-extractor.json @@ -1,6 +1,6 @@ { "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", - "mainEntryPointFilePath": "types/src/aborter.d.ts", + "mainEntryPointFilePath": "types/src/index.d.ts", "docModel": { "enabled": true }, @@ -11,7 +11,7 @@ "dtsRollup": { "enabled": true, "untrimmedFilePath": "", - "publicTrimmedFilePath": "./types/aborter.d.ts" + "publicTrimmedFilePath": "./types/abort-controller.d.ts" }, "messages": { "tsdocMessageReporting": { diff --git a/sdk/core/abort-controller/package.json b/sdk/core/abort-controller/package.json index dfe3893ef8b4..d5958c96cf0b 100644 --- a/sdk/core/abort-controller/package.json +++ b/sdk/core/abort-controller/package.json @@ -4,7 +4,7 @@ "version": "1.0.1", "description": "Microsoft Azure SDK for JavaScript - Aborter", "main": "./dist/index.js", - "module": "./dist-esm/src/aborter.js", + "module": "dist-esm/src/index.js", "scripts": { "audit": "node ../../../common/scripts/rush-audit.js && rimraf node_modules package-lock.json && npm i --package-lock-only 2>&1 && npm audit", "build:es6": "tsc -p tsconfig.json", @@ -19,8 +19,8 @@ "integration-test:browser": "echo skipped", "integration-test:node": "echo skipped", "integration-test": "npm run integration-test:node && npm run integration-test:browser", - "lint:fix": "eslint \"src/**/*.ts\" \"test/**/*.ts\" -c ../../.eslintrc.old.json --fix --fix-type [problem,suggestion]", - "lint": "eslint -c ../../.eslintrc.old.json src test --ext .ts -f html -o abort-controller-lintReport.html || exit 0", + "lint:fix": "eslint package.json api-extractor.json src test --ext .ts --fix --fix-type [problem,suggestion]", + "lint": "eslint package.json api-extractor.json src test --ext .ts", "pack": "npm pack 2>&1", "prebuild": "npm run clean", "pretest": "npm run build:test", @@ -31,21 +31,22 @@ "unit-test:node": "cross-env TS_NODE_FILES=true TS_NODE_COMPILER_OPTIONS=\"{\\\"module\\\": \\\"commonjs\\\"}\" mocha --require ts-node/register --require source-map-support/register --reporter ../../../common/tools/mocha-multi-reporter.js --full-trace --no-timeouts test/*.spec.ts", "unit-test": "npm run unit-test:node && npm run unit-test:browser" }, - "types": "./types/src/aborter.d.ts", + "types": "./types/src/index.d.ts", "engine": { "node": ">=8.0.0" }, "files": [ "dist/", "dist-esm/src/", + "shims-public.d.ts", "types/src", "README.md", "LICENSE" ], - "repository": { - "type": "git", - "url": "git+https://github.com/Azure/azure-sdk-for-js.git" + "engines": { + "node": ">=8.0.0" }, + "repository": "github:Azure/azure-sdk-for-js", "keywords": [ "azure", "aborter", @@ -54,19 +55,21 @@ "node.js", "typescript", "javascript", - "browser" + "browser", + "cloud" ], "author": "Microsoft Corporation", "license": "MIT", "bugs": { "url": "https://github.com/Azure/azure-sdk-for-js/issues" }, - "homepage": "https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/core/abort-controller", + "homepage": "https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/core/abort-controller/README.md", "sideEffects": false, "dependencies": { "tslib": "^2.0.0" }, "devDependencies": { + "@azure/eslint-plugin-azure-sdk": "^3.0.0", "@microsoft/api-extractor": "7.7.11", "@rollup/plugin-commonjs": "11.0.2", "@rollup/plugin-multi-entry": "^3.0.0", diff --git a/sdk/core/abort-controller/review/abort-controller.api.md b/sdk/core/abort-controller/review/abort-controller.api.md index 2b646496a2dd..4eaac226487a 100644 --- a/sdk/core/abort-controller/review/abort-controller.api.md +++ b/sdk/core/abort-controller/review/abort-controller.api.md @@ -38,4 +38,4 @@ export interface AbortSignalLike { // (No @packageDocumentation comment for this package) -``` +``` \ No newline at end of file diff --git a/sdk/core/abort-controller/rollup.base.config.js b/sdk/core/abort-controller/rollup.base.config.js index b86b97b12ecd..ee3203a27837 100644 --- a/sdk/core/abort-controller/rollup.base.config.js +++ b/sdk/core/abort-controller/rollup.base.config.js @@ -10,7 +10,7 @@ import sourcemaps from "rollup-plugin-sourcemaps"; const pkg = require("./package.json"); const depNames = Object.keys(pkg.dependencies); -const input = "./dist-esm/src/aborter.js"; +const input = "./dist-esm/src/index.js"; const production = process.env.NODE_ENV === "production"; export function nodeConfig(test = false) { diff --git a/sdk/core/abort-controller/src/shims-public.d.ts b/sdk/core/abort-controller/shims-public.d.ts similarity index 52% rename from sdk/core/abort-controller/src/shims-public.d.ts rename to sdk/core/abort-controller/shims-public.d.ts index 7ef8e860aa31..002bec375f33 100644 --- a/sdk/core/abort-controller/src/shims-public.d.ts +++ b/sdk/core/abort-controller/shims-public.d.ts @@ -1,2 +1,5 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + // forward declaration of Event in case DOM libs are not present. interface Event {} diff --git a/sdk/core/abort-controller/src/AbortController.ts b/sdk/core/abort-controller/src/AbortController.ts index d660a28c9d89..edd5f2123ffc 100644 --- a/sdk/core/abort-controller/src/AbortController.ts +++ b/sdk/core/abort-controller/src/AbortController.ts @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + import { AbortSignal, abortSignal, AbortSignalLike } from "./AbortSignal"; /** @@ -76,6 +79,7 @@ export class AbortController { } // coerce parentSignals into an array if (!Array.isArray(parentSignals)) { + // eslint-disable-next-line prefer-rest-params parentSignals = arguments; } for (const parentSignal of parentSignals) { diff --git a/sdk/core/abort-controller/src/AbortSignal.ts b/sdk/core/abort-controller/src/AbortSignal.ts index 04e8e7500869..4c15c3e60bc3 100644 --- a/sdk/core/abort-controller/src/AbortSignal.ts +++ b/sdk/core/abort-controller/src/AbortSignal.ts @@ -1,4 +1,8 @@ -/// +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +// eslint-disable-next-line @typescript-eslint/triple-slash-reference +/// type AbortEventListener = (this: AbortSignalLike, ev?: any) => any; const listenersMap = new WeakMap(); diff --git a/sdk/core/abort-controller/src/aborter.ts b/sdk/core/abort-controller/src/index.ts similarity index 87% rename from sdk/core/abort-controller/src/aborter.ts rename to sdk/core/abort-controller/src/index.ts index 20ebe21376c4..be655bbc6387 100644 --- a/sdk/core/abort-controller/src/aborter.ts +++ b/sdk/core/abort-controller/src/index.ts @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + // Changes to Aborter // * Rename Aborter to AbortSignal // * Remove withValue and getValue - async context should be solved differently/wholistically, not tied to cancellation diff --git a/sdk/core/abort-controller/test/aborter.spec.ts b/sdk/core/abort-controller/test/aborter.spec.ts index b42fcfbf379a..a60f914adb65 100644 --- a/sdk/core/abort-controller/test/aborter.spec.ts +++ b/sdk/core/abort-controller/test/aborter.spec.ts @@ -1,22 +1,25 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + import * as assert from "assert"; -import { AbortController, AbortSignal, AbortError } from "../src/aborter"; +import { AbortController, AbortSignal, AbortError } from "../src"; describe("AbortController", () => { function doAsyncOperation(aborter: AbortSignal, runningTimeinMs: number = 100): Promise { const s = Date.now(); - return new Promise((res, rej) => { + return new Promise((resolve, reject) => { // check status every 10 ms. const handle = setInterval(() => { // check if we're aborted. if (aborter.aborted) { clearInterval(handle); - return rej(new AbortError()); + return reject(new AbortError()); } // if we're completed, resolve. if (Date.now() - s > runningTimeinMs) { clearInterval(handle); - return res(); + return resolve(); } // else, continue trying. @@ -34,7 +37,7 @@ describe("AbortController", () => { const response = doAsyncOperation(aborter); controller.abort(); try { - let rs = await response; + const rs = await response; console.log("got result", rs); assert.fail(); } catch (err) { @@ -48,7 +51,7 @@ describe("AbortController", () => { const response = doAsyncOperation(aborter, 500); setTimeout(() => controller.abort(), 50); try { - let r = await response; + const r = await response; console.log("got, r", r); assert.fail(); } catch (err) { @@ -83,7 +86,7 @@ describe("AbortController", () => { it("should invoke abort listener callbacks when aborting", async () => { const controller = new AbortController(); const aborter = controller.signal; - let s: string[] = []; + const s: string[] = []; try { aborter.addEventListener("abort", () => { s.push("aborted"); From eceb3abf51c7cb3a6572c7d608ceb403acc6d775 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Rodr=C3=ADguez?= Date: Mon, 21 Sep 2020 17:38:21 -0400 Subject: [PATCH 002/152] [Identity] Idea for the Device Code Credential Use Console Feature (#11355) * [Identity] Idea for the Device Code Credential Use Console Feature * Feedback by Schaab and Vinay --- sdk/identity/identity/review/identity.api.md | 4 ++-- .../identity/src/credentials/deviceCodeCredential.ts | 12 ++++++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/sdk/identity/identity/review/identity.api.md b/sdk/identity/identity/review/identity.api.md index 94b13dadaafa..8acaeb7b504c 100644 --- a/sdk/identity/identity/review/identity.api.md +++ b/sdk/identity/identity/review/identity.api.md @@ -96,7 +96,7 @@ export interface DefaultAzureCredentialOptions extends TokenCredentialOptions { // @public export class DeviceCodeCredential implements TokenCredential { - constructor(tenantId: string | "organizations", clientId: string, userPromptCallback: DeviceCodePromptCallback, options?: TokenCredentialOptions); + constructor(tenantId: string | "organizations", clientId: string, userPromptCallback?: DeviceCodePromptCallback, options?: TokenCredentialOptions); getToken(scopes: string | string[], options?: GetTokenOptions): Promise; } @@ -135,7 +135,7 @@ export { GetTokenOptions } export class InteractiveBrowserCredential implements TokenCredential { constructor(options?: InteractiveBrowserCredentialOptions); getToken(scopes: string | string[], options?: GetTokenOptions): Promise; -} + } // @public export interface InteractiveBrowserCredentialOptions extends TokenCredentialOptions { diff --git a/sdk/identity/identity/src/credentials/deviceCodeCredential.ts b/sdk/identity/identity/src/credentials/deviceCodeCredential.ts index 9598ffbb928c..ef6520f4a4a3 100644 --- a/sdk/identity/identity/src/credentials/deviceCodeCredential.ts +++ b/sdk/identity/identity/src/credentials/deviceCodeCredential.ts @@ -42,6 +42,14 @@ export type DeviceCodePromptCallback = (deviceCodeInfo: DeviceCodeInfo) => void; const logger = credentialLogger("DeviceCodeCredential"); +/** + * Method that logs the user code from the DeviceCodeCredential. + * @param deviceCodeInfo The device code. + */ +export function defaultDeviceCodePromptCallback(deviceCodeInfo: DeviceCodeInfo): void { + console.log(deviceCodeInfo.message); +} + /** * Enables authentication to Azure Active Directory using a device code * that the user can enter into https://microsoft.com/devicelogin. @@ -62,13 +70,13 @@ export class DeviceCodeCredential implements TokenCredential { * 'organizations' may be used when dealing with multi-tenant scenarios. * @param clientId The client (application) ID of an App Registration in the tenant. * @param userPromptCallback A callback function that will be invoked to show - {@link DeviceCodeInfo} to the user. + {@link DeviceCodeInfo} to the user. If left unassigned, we will automatically log the device code information and the authentication instructions in the console. * @param options Options for configuring the client which makes the authentication request. */ constructor( tenantId: string | "organizations", clientId: string, - userPromptCallback: DeviceCodePromptCallback, + userPromptCallback: DeviceCodePromptCallback = defaultDeviceCodePromptCallback, options?: TokenCredentialOptions ) { this.identityClient = new IdentityClient(options); From 555cab83cf3e86617777014a7d862111788fe58e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Rodr=C3=ADguez?= Date: Mon, 21 Sep 2020 18:03:04 -0400 Subject: [PATCH 003/152] [Key Vault] Use the swagger generated from the service 7.2-preview (#11370) * swagger reference to 7.2-preview/keys.json * generated update * 7.2 on keys * 7.2 preview on certs and secrets * generated files for secrets and certs * secrets and certs * sticking the swagger change to a specific commit --- .../src/generated/models/index.ts | 6 +- .../keyvault-certificates/swagger/README.md | 2 +- .../keyvault-keys/review/keyvault-keys.api.md | 2 +- .../src/generated/keyVaultClient.ts | 211 +++++++++++++--- .../src/generated/models/index.ts | 238 +++++++++++++++++- .../src/generated/models/mappers.ts | 171 +++++++++++++ sdk/keyvault/keyvault-keys/src/keysModels.ts | 10 +- sdk/keyvault/keyvault-keys/swagger/README.md | 4 +- .../keyvault-secrets/swagger/README.md | 2 +- 9 files changed, 591 insertions(+), 55 deletions(-) diff --git a/sdk/keyvault/keyvault-certificates/src/generated/models/index.ts b/sdk/keyvault/keyvault-certificates/src/generated/models/index.ts index c0697e9572f7..2fe5f543826d 100644 --- a/sdk/keyvault/keyvault-certificates/src/generated/models/index.ts +++ b/sdk/keyvault/keyvault-certificates/src/generated/models/index.ts @@ -105,7 +105,7 @@ export interface KeyProperties { exportable?: boolean; /** * The type of key pair to be used for the certificate. Possible values include: 'EC', 'EC-HSM', - * 'RSA', 'RSA-HSM', 'oct' + * 'RSA', 'RSA-HSM', 'oct', 'oct-HSM' */ keyType?: JsonWebKeyType; /** @@ -956,11 +956,11 @@ export type DeletionRecoveryLevel = 'Purgeable' | 'Recoverable+Purgeable' | 'Rec /** * Defines values for JsonWebKeyType. - * Possible values include: 'EC', 'EC-HSM', 'RSA', 'RSA-HSM', 'oct' + * Possible values include: 'EC', 'EC-HSM', 'RSA', 'RSA-HSM', 'oct', 'oct-HSM' * @readonly * @enum {string} */ -export type JsonWebKeyType = 'EC' | 'EC-HSM' | 'RSA' | 'RSA-HSM' | 'oct'; +export type JsonWebKeyType = 'EC' | 'EC-HSM' | 'RSA' | 'RSA-HSM' | 'oct' | 'oct-HSM'; /** * Defines values for JsonWebKeyCurveName. diff --git a/sdk/keyvault/keyvault-certificates/swagger/README.md b/sdk/keyvault/keyvault-certificates/swagger/README.md index 04246bdfffff..f0facb162377 100644 --- a/sdk/keyvault/keyvault-certificates/swagger/README.md +++ b/sdk/keyvault/keyvault-certificates/swagger/README.md @@ -11,7 +11,7 @@ azure-arm: false generate-metadata: false add-credentials: false license-header: MICROSOFT_MIT_NO_VERSION -input-file: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/keyvault/data-plane/Microsoft.KeyVault/stable/7.1/certificates.json +input-file: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/f9caf92527ccff06c5b66380e6f2b4f50f5e82b3/specification/keyvault/data-plane/Microsoft.KeyVault/preview/7.2-preview/certificates.json output-folder: ../ source-code-folder-path: ./src/generated ``` diff --git a/sdk/keyvault/keyvault-keys/review/keyvault-keys.api.md b/sdk/keyvault/keyvault-keys/review/keyvault-keys.api.md index 4ccb9f431491..5ab40ebece62 100644 --- a/sdk/keyvault/keyvault-keys/review/keyvault-keys.api.md +++ b/sdk/keyvault/keyvault-keys/review/keyvault-keys.api.md @@ -209,7 +209,7 @@ export interface KeyProperties { } // @public -export type KeyType = "EC" | "EC-HSM" | "RSA" | "RSA-HSM" | "oct"; +export type KeyType = "EC" | "EC-HSM" | "RSA" | "RSA-HSM" | "oct" | "oct-HSM"; // @public export interface KeyVaultKey { diff --git a/sdk/keyvault/keyvault-keys/src/generated/keyVaultClient.ts b/sdk/keyvault/keyvault-keys/src/generated/keyVaultClient.ts index 85cc614abb5a..a4ed581c8888 100644 --- a/sdk/keyvault/keyvault-keys/src/generated/keyVaultClient.ts +++ b/sdk/keyvault/keyvault-keys/src/generated/keyVaultClient.ts @@ -33,7 +33,7 @@ class KeyVaultClient extends KeyVaultClientContext { * @param keyName The name for the new key. The system will generate the version name for the new * key. * @param kty The type of key to create. For valid values, see JsonWebKeyType. Possible values - * include: 'EC', 'EC-HSM', 'RSA', 'RSA-HSM', 'oct' + * include: 'EC', 'EC-HSM', 'RSA', 'RSA-HSM', 'oct', 'oct-HSM' * @param [options] The optional parameters * @returns Promise */ @@ -43,7 +43,7 @@ class KeyVaultClient extends KeyVaultClientContext { * @param keyName The name for the new key. The system will generate the version name for the new * key. * @param kty The type of key to create. For valid values, see JsonWebKeyType. Possible values - * include: 'EC', 'EC-HSM', 'RSA', 'RSA-HSM', 'oct' + * include: 'EC', 'EC-HSM', 'RSA', 'RSA-HSM', 'oct', 'oct-HSM' * @param callback The callback */ createKey(vaultBaseUrl: string, keyName: string, kty: Models.JsonWebKeyType, callback: coreHttp.ServiceCallback): void; @@ -52,7 +52,7 @@ class KeyVaultClient extends KeyVaultClientContext { * @param keyName The name for the new key. The system will generate the version name for the new * key. * @param kty The type of key to create. For valid values, see JsonWebKeyType. Possible values - * include: 'EC', 'EC-HSM', 'RSA', 'RSA-HSM', 'oct' + * include: 'EC', 'EC-HSM', 'RSA', 'RSA-HSM', 'oct', 'oct-HSM' * @param options The optional parameters * @param callback The callback */ @@ -392,18 +392,20 @@ class KeyVaultClient extends KeyVaultClientContext { * @param keyName The name of the key. * @param keyVersion The version of the key. * @param algorithm algorithm identifier. Possible values include: 'RSA-OAEP', 'RSA-OAEP-256', - * 'RSA1_5' + * 'RSA1_5', 'A128GCM', 'A192GCM', 'A256GCM', 'A128KW', 'A192KW', 'A256KW', 'A128CBC', 'A192CBC', + * 'A256CBC', 'A128CBCPAD', 'A192CBCPAD', 'A256CBCPAD' * @param value * @param [options] The optional parameters * @returns Promise */ - encrypt(vaultBaseUrl: string, keyName: string, keyVersion: string, algorithm: Models.JsonWebKeyEncryptionAlgorithm, value: Uint8Array, options?: coreHttp.RequestOptionsBase): Promise; + encrypt(vaultBaseUrl: string, keyName: string, keyVersion: string, algorithm: Models.JsonWebKeyEncryptionAlgorithm, value: Uint8Array, options?: Models.KeyVaultClientEncryptOptionalParams): Promise; /** * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net. * @param keyName The name of the key. * @param keyVersion The version of the key. * @param algorithm algorithm identifier. Possible values include: 'RSA-OAEP', 'RSA-OAEP-256', - * 'RSA1_5' + * 'RSA1_5', 'A128GCM', 'A192GCM', 'A256GCM', 'A128KW', 'A192KW', 'A256KW', 'A128CBC', 'A192CBC', + * 'A256CBC', 'A128CBCPAD', 'A192CBCPAD', 'A256CBCPAD' * @param value * @param callback The callback */ @@ -413,13 +415,14 @@ class KeyVaultClient extends KeyVaultClientContext { * @param keyName The name of the key. * @param keyVersion The version of the key. * @param algorithm algorithm identifier. Possible values include: 'RSA-OAEP', 'RSA-OAEP-256', - * 'RSA1_5' + * 'RSA1_5', 'A128GCM', 'A192GCM', 'A256GCM', 'A128KW', 'A192KW', 'A256KW', 'A128CBC', 'A192CBC', + * 'A256CBC', 'A128CBCPAD', 'A192CBCPAD', 'A256CBCPAD' * @param value * @param options The optional parameters * @param callback The callback */ - encrypt(vaultBaseUrl: string, keyName: string, keyVersion: string, algorithm: Models.JsonWebKeyEncryptionAlgorithm, value: Uint8Array, options: coreHttp.RequestOptionsBase, callback: coreHttp.ServiceCallback): void; - encrypt(vaultBaseUrl: string, keyName: string, keyVersion: string, algorithm: Models.JsonWebKeyEncryptionAlgorithm, value: Uint8Array, options?: coreHttp.RequestOptionsBase | coreHttp.ServiceCallback, callback?: coreHttp.ServiceCallback): Promise { + encrypt(vaultBaseUrl: string, keyName: string, keyVersion: string, algorithm: Models.JsonWebKeyEncryptionAlgorithm, value: Uint8Array, options: Models.KeyVaultClientEncryptOptionalParams, callback: coreHttp.ServiceCallback): void; + encrypt(vaultBaseUrl: string, keyName: string, keyVersion: string, algorithm: Models.JsonWebKeyEncryptionAlgorithm, value: Uint8Array, options?: Models.KeyVaultClientEncryptOptionalParams | coreHttp.ServiceCallback, callback?: coreHttp.ServiceCallback): Promise { return this.sendOperationRequest( { vaultBaseUrl, @@ -445,18 +448,20 @@ class KeyVaultClient extends KeyVaultClientContext { * @param keyName The name of the key. * @param keyVersion The version of the key. * @param algorithm algorithm identifier. Possible values include: 'RSA-OAEP', 'RSA-OAEP-256', - * 'RSA1_5' + * 'RSA1_5', 'A128GCM', 'A192GCM', 'A256GCM', 'A128KW', 'A192KW', 'A256KW', 'A128CBC', 'A192CBC', + * 'A256CBC', 'A128CBCPAD', 'A192CBCPAD', 'A256CBCPAD' * @param value * @param [options] The optional parameters * @returns Promise */ - decrypt(vaultBaseUrl: string, keyName: string, keyVersion: string, algorithm: Models.JsonWebKeyEncryptionAlgorithm, value: Uint8Array, options?: coreHttp.RequestOptionsBase): Promise; + decrypt(vaultBaseUrl: string, keyName: string, keyVersion: string, algorithm: Models.JsonWebKeyEncryptionAlgorithm, value: Uint8Array, options?: Models.KeyVaultClientDecryptOptionalParams): Promise; /** * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net. * @param keyName The name of the key. * @param keyVersion The version of the key. * @param algorithm algorithm identifier. Possible values include: 'RSA-OAEP', 'RSA-OAEP-256', - * 'RSA1_5' + * 'RSA1_5', 'A128GCM', 'A192GCM', 'A256GCM', 'A128KW', 'A192KW', 'A256KW', 'A128CBC', 'A192CBC', + * 'A256CBC', 'A128CBCPAD', 'A192CBCPAD', 'A256CBCPAD' * @param value * @param callback The callback */ @@ -466,13 +471,14 @@ class KeyVaultClient extends KeyVaultClientContext { * @param keyName The name of the key. * @param keyVersion The version of the key. * @param algorithm algorithm identifier. Possible values include: 'RSA-OAEP', 'RSA-OAEP-256', - * 'RSA1_5' + * 'RSA1_5', 'A128GCM', 'A192GCM', 'A256GCM', 'A128KW', 'A192KW', 'A256KW', 'A128CBC', 'A192CBC', + * 'A256CBC', 'A128CBCPAD', 'A192CBCPAD', 'A256CBCPAD' * @param value * @param options The optional parameters * @param callback The callback */ - decrypt(vaultBaseUrl: string, keyName: string, keyVersion: string, algorithm: Models.JsonWebKeyEncryptionAlgorithm, value: Uint8Array, options: coreHttp.RequestOptionsBase, callback: coreHttp.ServiceCallback): void; - decrypt(vaultBaseUrl: string, keyName: string, keyVersion: string, algorithm: Models.JsonWebKeyEncryptionAlgorithm, value: Uint8Array, options?: coreHttp.RequestOptionsBase | coreHttp.ServiceCallback, callback?: coreHttp.ServiceCallback): Promise { + decrypt(vaultBaseUrl: string, keyName: string, keyVersion: string, algorithm: Models.JsonWebKeyEncryptionAlgorithm, value: Uint8Array, options: Models.KeyVaultClientDecryptOptionalParams, callback: coreHttp.ServiceCallback): void; + decrypt(vaultBaseUrl: string, keyName: string, keyVersion: string, algorithm: Models.JsonWebKeyEncryptionAlgorithm, value: Uint8Array, options?: Models.KeyVaultClientDecryptOptionalParams | coreHttp.ServiceCallback, callback?: coreHttp.ServiceCallback): Promise { return this.sendOperationRequest( { vaultBaseUrl, @@ -610,18 +616,20 @@ class KeyVaultClient extends KeyVaultClientContext { * @param keyName The name of the key. * @param keyVersion The version of the key. * @param algorithm algorithm identifier. Possible values include: 'RSA-OAEP', 'RSA-OAEP-256', - * 'RSA1_5' + * 'RSA1_5', 'A128GCM', 'A192GCM', 'A256GCM', 'A128KW', 'A192KW', 'A256KW', 'A128CBC', 'A192CBC', + * 'A256CBC', 'A128CBCPAD', 'A192CBCPAD', 'A256CBCPAD' * @param value * @param [options] The optional parameters * @returns Promise */ - wrapKey(vaultBaseUrl: string, keyName: string, keyVersion: string, algorithm: Models.JsonWebKeyEncryptionAlgorithm, value: Uint8Array, options?: coreHttp.RequestOptionsBase): Promise; + wrapKey(vaultBaseUrl: string, keyName: string, keyVersion: string, algorithm: Models.JsonWebKeyEncryptionAlgorithm, value: Uint8Array, options?: Models.KeyVaultClientWrapKeyOptionalParams): Promise; /** * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net. * @param keyName The name of the key. * @param keyVersion The version of the key. * @param algorithm algorithm identifier. Possible values include: 'RSA-OAEP', 'RSA-OAEP-256', - * 'RSA1_5' + * 'RSA1_5', 'A128GCM', 'A192GCM', 'A256GCM', 'A128KW', 'A192KW', 'A256KW', 'A128CBC', 'A192CBC', + * 'A256CBC', 'A128CBCPAD', 'A192CBCPAD', 'A256CBCPAD' * @param value * @param callback The callback */ @@ -631,13 +639,14 @@ class KeyVaultClient extends KeyVaultClientContext { * @param keyName The name of the key. * @param keyVersion The version of the key. * @param algorithm algorithm identifier. Possible values include: 'RSA-OAEP', 'RSA-OAEP-256', - * 'RSA1_5' + * 'RSA1_5', 'A128GCM', 'A192GCM', 'A256GCM', 'A128KW', 'A192KW', 'A256KW', 'A128CBC', 'A192CBC', + * 'A256CBC', 'A128CBCPAD', 'A192CBCPAD', 'A256CBCPAD' * @param value * @param options The optional parameters * @param callback The callback */ - wrapKey(vaultBaseUrl: string, keyName: string, keyVersion: string, algorithm: Models.JsonWebKeyEncryptionAlgorithm, value: Uint8Array, options: coreHttp.RequestOptionsBase, callback: coreHttp.ServiceCallback): void; - wrapKey(vaultBaseUrl: string, keyName: string, keyVersion: string, algorithm: Models.JsonWebKeyEncryptionAlgorithm, value: Uint8Array, options?: coreHttp.RequestOptionsBase | coreHttp.ServiceCallback, callback?: coreHttp.ServiceCallback): Promise { + wrapKey(vaultBaseUrl: string, keyName: string, keyVersion: string, algorithm: Models.JsonWebKeyEncryptionAlgorithm, value: Uint8Array, options: Models.KeyVaultClientWrapKeyOptionalParams, callback: coreHttp.ServiceCallback): void; + wrapKey(vaultBaseUrl: string, keyName: string, keyVersion: string, algorithm: Models.JsonWebKeyEncryptionAlgorithm, value: Uint8Array, options?: Models.KeyVaultClientWrapKeyOptionalParams | coreHttp.ServiceCallback, callback?: coreHttp.ServiceCallback): Promise { return this.sendOperationRequest( { vaultBaseUrl, @@ -662,18 +671,20 @@ class KeyVaultClient extends KeyVaultClientContext { * @param keyName The name of the key. * @param keyVersion The version of the key. * @param algorithm algorithm identifier. Possible values include: 'RSA-OAEP', 'RSA-OAEP-256', - * 'RSA1_5' + * 'RSA1_5', 'A128GCM', 'A192GCM', 'A256GCM', 'A128KW', 'A192KW', 'A256KW', 'A128CBC', 'A192CBC', + * 'A256CBC', 'A128CBCPAD', 'A192CBCPAD', 'A256CBCPAD' * @param value * @param [options] The optional parameters * @returns Promise */ - unwrapKey(vaultBaseUrl: string, keyName: string, keyVersion: string, algorithm: Models.JsonWebKeyEncryptionAlgorithm, value: Uint8Array, options?: coreHttp.RequestOptionsBase): Promise; + unwrapKey(vaultBaseUrl: string, keyName: string, keyVersion: string, algorithm: Models.JsonWebKeyEncryptionAlgorithm, value: Uint8Array, options?: Models.KeyVaultClientUnwrapKeyOptionalParams): Promise; /** * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net. * @param keyName The name of the key. * @param keyVersion The version of the key. * @param algorithm algorithm identifier. Possible values include: 'RSA-OAEP', 'RSA-OAEP-256', - * 'RSA1_5' + * 'RSA1_5', 'A128GCM', 'A192GCM', 'A256GCM', 'A128KW', 'A192KW', 'A256KW', 'A128CBC', 'A192CBC', + * 'A256CBC', 'A128CBCPAD', 'A192CBCPAD', 'A256CBCPAD' * @param value * @param callback The callback */ @@ -683,13 +694,14 @@ class KeyVaultClient extends KeyVaultClientContext { * @param keyName The name of the key. * @param keyVersion The version of the key. * @param algorithm algorithm identifier. Possible values include: 'RSA-OAEP', 'RSA-OAEP-256', - * 'RSA1_5' + * 'RSA1_5', 'A128GCM', 'A192GCM', 'A256GCM', 'A128KW', 'A192KW', 'A256KW', 'A128CBC', 'A192CBC', + * 'A256CBC', 'A128CBCPAD', 'A192CBCPAD', 'A256CBCPAD' * @param value * @param options The optional parameters * @param callback The callback */ - unwrapKey(vaultBaseUrl: string, keyName: string, keyVersion: string, algorithm: Models.JsonWebKeyEncryptionAlgorithm, value: Uint8Array, options: coreHttp.RequestOptionsBase, callback: coreHttp.ServiceCallback): void; - unwrapKey(vaultBaseUrl: string, keyName: string, keyVersion: string, algorithm: Models.JsonWebKeyEncryptionAlgorithm, value: Uint8Array, options?: coreHttp.RequestOptionsBase | coreHttp.ServiceCallback, callback?: coreHttp.ServiceCallback): Promise { + unwrapKey(vaultBaseUrl: string, keyName: string, keyVersion: string, algorithm: Models.JsonWebKeyEncryptionAlgorithm, value: Uint8Array, options: Models.KeyVaultClientUnwrapKeyOptionalParams, callback: coreHttp.ServiceCallback): void; + unwrapKey(vaultBaseUrl: string, keyName: string, keyVersion: string, algorithm: Models.JsonWebKeyEncryptionAlgorithm, value: Uint8Array, options?: Models.KeyVaultClientUnwrapKeyOptionalParams | coreHttp.ServiceCallback, callback?: coreHttp.ServiceCallback): Promise { return this.sendOperationRequest( { vaultBaseUrl, @@ -703,6 +715,48 @@ class KeyVaultClient extends KeyVaultClientContext { callback) as Promise; } + /** + * The export key operation is applicable to all key types. The target key must be marked + * exportable. This operation requires the keys/export permission. + * @summary Exports a key. + * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net. + * @param keyName The name of the key to get. + * @param keyVersion Adding the version parameter retrieves a specific version of a key. + * @param environment The target environment assertion. + * @param [options] The optional parameters + * @returns Promise + */ + exportKey(vaultBaseUrl: string, keyName: string, keyVersion: string, environment: string, options?: coreHttp.RequestOptionsBase): Promise; + /** + * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net. + * @param keyName The name of the key to get. + * @param keyVersion Adding the version parameter retrieves a specific version of a key. + * @param environment The target environment assertion. + * @param callback The callback + */ + exportKey(vaultBaseUrl: string, keyName: string, keyVersion: string, environment: string, callback: coreHttp.ServiceCallback): void; + /** + * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net. + * @param keyName The name of the key to get. + * @param keyVersion Adding the version parameter retrieves a specific version of a key. + * @param environment The target environment assertion. + * @param options The optional parameters + * @param callback The callback + */ + exportKey(vaultBaseUrl: string, keyName: string, keyVersion: string, environment: string, options: coreHttp.RequestOptionsBase, callback: coreHttp.ServiceCallback): void; + exportKey(vaultBaseUrl: string, keyName: string, keyVersion: string, environment: string, options?: coreHttp.RequestOptionsBase | coreHttp.ServiceCallback, callback?: coreHttp.ServiceCallback): Promise { + return this.sendOperationRequest( + { + vaultBaseUrl, + keyName, + keyVersion, + environment, + options + }, + exportKeyOperationSpec, + callback) as Promise; + } + /** * Retrieves a list of the keys in the Key Vault as JSON Web Key structures that contain the public * part of a deleted key. This operation includes deletion-specific information. The Get Deleted @@ -862,6 +916,10 @@ const createKeyOperationSpec: coreHttp.OperationSpec = { "options", "keySize" ], + publicExponent: [ + "options", + "publicExponent" + ], keyOps: [ "options", "keyOps" @@ -877,6 +935,10 @@ const createKeyOperationSpec: coreHttp.OperationSpec = { curve: [ "options", "curve" + ], + releasePolicy: [ + "options", + "releasePolicy" ] }, mapper: { @@ -919,6 +981,10 @@ const importKeyOperationSpec: coreHttp.OperationSpec = { tags: [ "options", "tags" + ], + releasePolicy: [ + "options", + "releasePolicy" ] }, mapper: { @@ -982,6 +1048,10 @@ const updateKeyOperationSpec: coreHttp.OperationSpec = { tags: [ "options", "tags" + ], + releasePolicy: [ + "options", + "releasePolicy" ] }, mapper: { @@ -1129,7 +1199,19 @@ const encryptOperationSpec: coreHttp.OperationSpec = { requestBody: { parameterPath: { algorithm: "algorithm", - value: "value" + value: "value", + iv: [ + "options", + "iv" + ], + aad: [ + "options", + "aad" + ], + tag: [ + "options", + "tag" + ] }, mapper: { ...Mappers.KeyOperationsParameters, @@ -1161,7 +1243,19 @@ const decryptOperationSpec: coreHttp.OperationSpec = { requestBody: { parameterPath: { algorithm: "algorithm", - value: "value" + value: "value", + iv: [ + "options", + "iv" + ], + aad: [ + "options", + "aad" + ], + tag: [ + "options", + "tag" + ] }, mapper: { ...Mappers.KeyOperationsParameters, @@ -1258,7 +1352,19 @@ const wrapKeyOperationSpec: coreHttp.OperationSpec = { requestBody: { parameterPath: { algorithm: "algorithm", - value: "value" + value: "value", + iv: [ + "options", + "iv" + ], + aad: [ + "options", + "aad" + ], + tag: [ + "options", + "tag" + ] }, mapper: { ...Mappers.KeyOperationsParameters, @@ -1290,7 +1396,19 @@ const unwrapKeyOperationSpec: coreHttp.OperationSpec = { requestBody: { parameterPath: { algorithm: "algorithm", - value: "value" + value: "value", + iv: [ + "options", + "iv" + ], + aad: [ + "options", + "aad" + ], + tag: [ + "options", + "tag" + ] }, mapper: { ...Mappers.KeyOperationsParameters, @@ -1308,6 +1426,37 @@ const unwrapKeyOperationSpec: coreHttp.OperationSpec = { serializer }; +const exportKeyOperationSpec: coreHttp.OperationSpec = { + httpMethod: "POST", + path: "keys/{key-name}/{key-version}/export", + urlParameters: [ + Parameters.vaultBaseUrl, + Parameters.keyName1, + Parameters.keyVersion + ], + queryParameters: [ + Parameters.apiVersion + ], + requestBody: { + parameterPath: { + environment: "environment" + }, + mapper: { + ...Mappers.KeyExportParameters, + required: true + } + }, + responses: { + 200: { + bodyMapper: Mappers.KeyBundle + }, + default: { + bodyMapper: Mappers.KeyVaultError + } + }, + serializer +}; + const getDeletedKeysOperationSpec: coreHttp.OperationSpec = { httpMethod: "GET", path: "deletedkeys", diff --git a/sdk/keyvault/keyvault-keys/src/generated/models/index.ts b/sdk/keyvault/keyvault-keys/src/generated/models/index.ts index 73b49f972c6c..9133dd6dae23 100644 --- a/sdk/keyvault/keyvault-keys/src/generated/models/index.ts +++ b/sdk/keyvault/keyvault-keys/src/generated/models/index.ts @@ -9,6 +9,43 @@ import * as coreHttp from "@azure/core-http"; +/** + * An interface representing KeyReleaseCondition. + */ +export interface KeyReleaseCondition { + /** + * claim type name + */ + claimType?: string; + /** + * condition to test. Possible values include: 'equals' + */ + claimCondition?: KeyReleaseConditionCondition; + value?: string; +} + +/** + * An interface representing KeyReleaseAuthority. + */ +export interface KeyReleaseAuthority { + /** + * Base URL of the attestation service. + */ + authorityURL?: string; + allOf?: KeyReleaseCondition[]; +} + +/** + * An interface representing KeyReleasePolicy. + */ +export interface KeyReleasePolicy { + /** + * key release policy version. Possible values include: '0.2' + */ + version?: KeyReleasePolicyVersion; + anyOf?: KeyReleaseAuthority[]; +} + /** * As of http://tools.ietf.org/html/draft-ietf-jose-json-web-key-18 */ @@ -20,7 +57,7 @@ export interface JsonWebKey { /** * JsonWebKey Key Type (kty), as defined in * https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40. Possible values include: - * 'EC', 'EC-HSM', 'RSA', 'RSA-HSM', 'oct' + * 'EC', 'EC-HSM', 'RSA', 'RSA-HSM', 'oct', 'oct-HSM' */ kty?: JsonWebKeyType; keyOps?: string[]; @@ -61,7 +98,7 @@ export interface JsonWebKey { */ k?: Uint8Array; /** - * HSM Token, used with 'Bring Your Own Key'. + * Protected Key, used with 'Bring Your Own Key'. */ t?: Uint8Array; /** @@ -127,6 +164,10 @@ export interface KeyAttributes extends Attributes { * **NOTE: This property will not be serialized. It can only be populated by the server.** */ readonly recoveryLevel?: DeletionRecoveryLevel; + /** + * Indicates if the private key can be exported. + */ + exportable?: boolean; } /** @@ -151,6 +192,10 @@ export interface KeyBundle { * **NOTE: This property will not be serialized. It can only be populated by the server.** */ readonly managed?: boolean; + /** + * The policy rules under which the key can be exported. + */ + releasePolicy?: KeyReleasePolicy; } /** @@ -227,7 +272,7 @@ export interface KeyProperties { exportable?: boolean; /** * The type of key pair to be used for the certificate. Possible values include: 'EC', 'EC-HSM', - * 'RSA', 'RSA-HSM', 'oct' + * 'RSA', 'RSA-HSM', 'oct', 'oct-HSM' */ keyType?: JsonWebKeyType; /** @@ -251,13 +296,17 @@ export interface KeyProperties { export interface KeyCreateParameters { /** * The type of key to create. For valid values, see JsonWebKeyType. Possible values include: - * 'EC', 'EC-HSM', 'RSA', 'RSA-HSM', 'oct' + * 'EC', 'EC-HSM', 'RSA', 'RSA-HSM', 'oct', 'oct-HSM' */ kty: JsonWebKeyType; /** * The key size in bits. For example: 2048, 3072, or 4096 for RSA. */ keySize?: number; + /** + * The public exponent for a RSA key. + */ + publicExponent?: number; keyOps?: JsonWebKeyOperation[]; keyAttributes?: KeyAttributes; /** @@ -269,6 +318,10 @@ export interface KeyCreateParameters { * 'P-256', 'P-384', 'P-521', 'P-256K' */ curve?: JsonWebKeyCurveName; + /** + * The policy rules under which the key can be exported. + */ + releasePolicy?: KeyReleasePolicy; } /** @@ -291,6 +344,20 @@ export interface KeyImportParameters { * Application specific metadata in the form of key-value pairs. */ tags?: { [propertyName: string]: string }; + /** + * The policy rules under which the key can be exported. + */ + releasePolicy?: KeyReleasePolicy; +} + +/** + * The export key parameters. + */ +export interface KeyExportParameters { + /** + * The target environment assertion. + */ + environment: string; } /** @@ -298,10 +365,25 @@ export interface KeyImportParameters { */ export interface KeyOperationsParameters { /** - * algorithm identifier. Possible values include: 'RSA-OAEP', 'RSA-OAEP-256', 'RSA1_5' + * algorithm identifier. Possible values include: 'RSA-OAEP', 'RSA-OAEP-256', 'RSA1_5', + * 'A128GCM', 'A192GCM', 'A256GCM', 'A128KW', 'A192KW', 'A256KW', 'A128CBC', 'A192CBC', + * 'A256CBC', 'A128CBCPAD', 'A192CBCPAD', 'A256CBCPAD' */ algorithm: JsonWebKeyEncryptionAlgorithm; value: Uint8Array; + /** + * Initialization vector for symmetric algorithms. + */ + iv?: Uint8Array; + /** + * Additional data to authenticate but not encrypt/decrypt when using authenticated crypto + * algorithms. + */ + aad?: Uint8Array; + /** + * The tag to authenticate when performing decryption with an authenticated algorithm. + */ + tag?: Uint8Array; } /** @@ -351,6 +433,10 @@ export interface KeyUpdateParameters { * Application specific metadata in the form of key-value pairs. */ tags?: { [propertyName: string]: string }; + /** + * The policy rules under which the key can be exported. + */ + releasePolicy?: KeyReleasePolicy; } /** @@ -472,6 +558,10 @@ export interface KeyVaultClientCreateKeyOptionalParams extends coreHttp.RequestO * The key size in bits. For example: 2048, 3072, or 4096 for RSA. */ keySize?: number; + /** + * The public exponent for a RSA key. + */ + publicExponent?: number; keyOps?: JsonWebKeyOperation[]; keyAttributes?: KeyAttributes; /** @@ -483,6 +573,10 @@ export interface KeyVaultClientCreateKeyOptionalParams extends coreHttp.RequestO * 'P-256', 'P-384', 'P-521', 'P-256K' */ curve?: JsonWebKeyCurveName; + /** + * The policy rules under which the key can be exported. + */ + releasePolicy?: KeyReleasePolicy; } /** @@ -501,6 +595,10 @@ export interface KeyVaultClientImportKeyOptionalParams extends coreHttp.RequestO * Application specific metadata in the form of key-value pairs. */ tags?: { [propertyName: string]: string }; + /** + * The policy rules under which the key can be exported. + */ + releasePolicy?: KeyReleasePolicy; } /** @@ -517,6 +615,10 @@ export interface KeyVaultClientUpdateKeyOptionalParams extends coreHttp.RequestO * Application specific metadata in the form of key-value pairs. */ tags?: { [propertyName: string]: string }; + /** + * The policy rules under which the key can be exported. + */ + releasePolicy?: KeyReleasePolicy; } /** @@ -541,6 +643,82 @@ export interface KeyVaultClientGetKeysOptionalParams extends coreHttp.RequestOpt maxresults?: number; } +/** + * Optional Parameters. + */ +export interface KeyVaultClientEncryptOptionalParams extends coreHttp.RequestOptionsBase { + /** + * Initialization vector for symmetric algorithms. + */ + iv?: Uint8Array; + /** + * Additional data to authenticate but not encrypt/decrypt when using authenticated crypto + * algorithms. + */ + aad?: Uint8Array; + /** + * The tag to authenticate when performing decryption with an authenticated algorithm. + */ + tag?: Uint8Array; +} + +/** + * Optional Parameters. + */ +export interface KeyVaultClientDecryptOptionalParams extends coreHttp.RequestOptionsBase { + /** + * Initialization vector for symmetric algorithms. + */ + iv?: Uint8Array; + /** + * Additional data to authenticate but not encrypt/decrypt when using authenticated crypto + * algorithms. + */ + aad?: Uint8Array; + /** + * The tag to authenticate when performing decryption with an authenticated algorithm. + */ + tag?: Uint8Array; +} + +/** + * Optional Parameters. + */ +export interface KeyVaultClientWrapKeyOptionalParams extends coreHttp.RequestOptionsBase { + /** + * Initialization vector for symmetric algorithms. + */ + iv?: Uint8Array; + /** + * Additional data to authenticate but not encrypt/decrypt when using authenticated crypto + * algorithms. + */ + aad?: Uint8Array; + /** + * The tag to authenticate when performing decryption with an authenticated algorithm. + */ + tag?: Uint8Array; +} + +/** + * Optional Parameters. + */ +export interface KeyVaultClientUnwrapKeyOptionalParams extends coreHttp.RequestOptionsBase { + /** + * Initialization vector for symmetric algorithms. + */ + iv?: Uint8Array; + /** + * Additional data to authenticate but not encrypt/decrypt when using authenticated crypto + * algorithms. + */ + aad?: Uint8Array; + /** + * The tag to authenticate when performing decryption with an authenticated algorithm. + */ + tag?: Uint8Array; +} + /** * Optional Parameters. */ @@ -552,13 +730,29 @@ export interface KeyVaultClientGetDeletedKeysOptionalParams extends coreHttp.Req maxresults?: number; } +/** + * Defines values for KeyReleaseConditionCondition. + * Possible values include: 'equals' + * @readonly + * @enum {string} + */ +export type KeyReleaseConditionCondition = 'equals'; + +/** + * Defines values for KeyReleasePolicyVersion. + * Possible values include: '0.2' + * @readonly + * @enum {string} + */ +export type KeyReleasePolicyVersion = '0.2'; + /** * Defines values for JsonWebKeyType. - * Possible values include: 'EC', 'EC-HSM', 'RSA', 'RSA-HSM', 'oct' + * Possible values include: 'EC', 'EC-HSM', 'RSA', 'RSA-HSM', 'oct', 'oct-HSM' * @readonly * @enum {string} */ -export type JsonWebKeyType = 'EC' | 'EC-HSM' | 'RSA' | 'RSA-HSM' | 'oct'; +export type JsonWebKeyType = 'EC' | 'EC-HSM' | 'RSA' | 'RSA-HSM' | 'oct' | 'oct-HSM'; /** * Defines values for JsonWebKeyCurveName. @@ -581,19 +775,21 @@ export type DeletionRecoveryLevel = 'Purgeable' | 'Recoverable+Purgeable' | 'Rec /** * Defines values for JsonWebKeyOperation. * Possible values include: 'encrypt', 'decrypt', 'sign', 'verify', 'wrapKey', 'unwrapKey', - * 'import' + * 'import', 'export' * @readonly * @enum {string} */ -export type JsonWebKeyOperation = 'encrypt' | 'decrypt' | 'sign' | 'verify' | 'wrapKey' | 'unwrapKey' | 'import'; +export type JsonWebKeyOperation = 'encrypt' | 'decrypt' | 'sign' | 'verify' | 'wrapKey' | 'unwrapKey' | 'import' | 'export'; /** * Defines values for JsonWebKeyEncryptionAlgorithm. - * Possible values include: 'RSA-OAEP', 'RSA-OAEP-256', 'RSA1_5' + * Possible values include: 'RSA-OAEP', 'RSA-OAEP-256', 'RSA1_5', 'A128GCM', 'A192GCM', 'A256GCM', + * 'A128KW', 'A192KW', 'A256KW', 'A128CBC', 'A192CBC', 'A256CBC', 'A128CBCPAD', 'A192CBCPAD', + * 'A256CBCPAD' * @readonly * @enum {string} */ -export type JsonWebKeyEncryptionAlgorithm = 'RSA-OAEP' | 'RSA-OAEP-256' | 'RSA1_5'; +export type JsonWebKeyEncryptionAlgorithm = 'RSA-OAEP' | 'RSA-OAEP-256' | 'RSA1_5' | 'A128GCM' | 'A192GCM' | 'A256GCM' | 'A128KW' | 'A192KW' | 'A256KW' | 'A128CBC' | 'A192CBC' | 'A256CBC' | 'A128CBCPAD' | 'A192CBCPAD' | 'A256CBCPAD'; /** * Defines values for JsonWebKeySignatureAlgorithm. @@ -904,6 +1100,26 @@ export type UnwrapKeyResponse = KeyOperationResult & { }; }; +/** + * Contains response data for the exportKey operation. + */ +export type ExportKeyResponse = KeyBundle & { + /** + * The underlying HTTP response. + */ + _response: coreHttp.HttpResponse & { + /** + * The response body as text (string format) + */ + bodyAsText: string; + + /** + * The response body as parsed JSON or XML + */ + parsedBody: KeyBundle; + }; +}; + /** * Contains response data for the getDeletedKeys operation. */ diff --git a/sdk/keyvault/keyvault-keys/src/generated/models/mappers.ts b/sdk/keyvault/keyvault-keys/src/generated/models/mappers.ts index 944587ed685b..78e7aa15d7f5 100644 --- a/sdk/keyvault/keyvault-keys/src/generated/models/mappers.ts +++ b/sdk/keyvault/keyvault-keys/src/generated/models/mappers.ts @@ -9,6 +9,99 @@ import * as coreHttp from "@azure/core-http"; +export const KeyReleaseCondition: coreHttp.CompositeMapper = { + serializedName: "KeyReleaseCondition", + type: { + name: "Composite", + className: "KeyReleaseCondition", + modelProperties: { + claimType: { + serializedName: "claim", + constraints: { + MinLength: 1 + }, + type: { + name: "String" + } + }, + claimCondition: { + serializedName: "condition", + constraints: { + MinLength: 1 + }, + type: { + name: "String" + } + }, + value: { + serializedName: "value", + type: { + name: "String" + } + } + } + } +}; + +export const KeyReleaseAuthority: coreHttp.CompositeMapper = { + serializedName: "KeyReleaseAuthority", + type: { + name: "Composite", + className: "KeyReleaseAuthority", + modelProperties: { + authorityURL: { + serializedName: "authority", + constraints: { + MinLength: 1 + }, + type: { + name: "String" + } + }, + allOf: { + serializedName: "allOf", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "KeyReleaseCondition" + } + } + } + } + } + } +}; + +export const KeyReleasePolicy: coreHttp.CompositeMapper = { + serializedName: "KeyReleasePolicy", + type: { + name: "Composite", + className: "KeyReleasePolicy", + modelProperties: { + version: { + serializedName: "version", + type: { + name: "String" + } + }, + anyOf: { + serializedName: "anyOf", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "KeyReleaseAuthority" + } + } + } + } + } + } +}; + export const JsonWebKey: coreHttp.CompositeMapper = { serializedName: "JsonWebKey", type: { @@ -183,6 +276,12 @@ export const KeyAttributes: coreHttp.CompositeMapper = { type: { name: "String" } + }, + exportable: { + serializedName: "exportable", + type: { + name: "Boolean" + } } } } @@ -225,6 +324,13 @@ export const KeyBundle: coreHttp.CompositeMapper = { type: { name: "Boolean" } + }, + releasePolicy: { + serializedName: "release_policy", + type: { + name: "Composite", + className: "KeyReleasePolicy" + } } } } @@ -395,6 +501,12 @@ export const KeyCreateParameters: coreHttp.CompositeMapper = { name: "Number" } }, + publicExponent: { + serializedName: "public_exponent", + type: { + name: "Number" + } + }, keyOps: { serializedName: "key_ops", type: { @@ -429,6 +541,13 @@ export const KeyCreateParameters: coreHttp.CompositeMapper = { type: { name: "String" } + }, + releasePolicy: { + serializedName: "release_policy", + type: { + name: "Composite", + className: "KeyReleasePolicy" + } } } } @@ -471,6 +590,33 @@ export const KeyImportParameters: coreHttp.CompositeMapper = { } } } + }, + releasePolicy: { + serializedName: "release_policy", + type: { + name: "Composite", + className: "KeyReleasePolicy" + } + } + } + } +}; + +export const KeyExportParameters: coreHttp.CompositeMapper = { + serializedName: "KeyExportParameters", + type: { + name: "Composite", + className: "KeyExportParameters", + modelProperties: { + environment: { + required: true, + serializedName: "env", + constraints: { + MinLength: 1 + }, + type: { + name: "String" + } } } } @@ -498,6 +644,24 @@ export const KeyOperationsParameters: coreHttp.CompositeMapper = { type: { name: "Base64Url" } + }, + iv: { + serializedName: "iv", + type: { + name: "Base64Url" + } + }, + aad: { + serializedName: "aad", + type: { + name: "Base64Url" + } + }, + tag: { + serializedName: "tag", + type: { + name: "Base64Url" + } } } } @@ -598,6 +762,13 @@ export const KeyUpdateParameters: coreHttp.CompositeMapper = { } } } + }, + releasePolicy: { + serializedName: "release_policy", + type: { + name: "Composite", + className: "KeyReleasePolicy" + } } } } diff --git a/sdk/keyvault/keyvault-keys/src/keysModels.ts b/sdk/keyvault/keyvault-keys/src/keysModels.ts index 98dd04e5616b..546e5815c674 100644 --- a/sdk/keyvault/keyvault-keys/src/keysModels.ts +++ b/sdk/keyvault/keyvault-keys/src/keysModels.ts @@ -22,11 +22,11 @@ export type KeyOperation = /** * Defines values for KeyType. - * Possible values include: 'EC', 'EC-HSM', 'RSA', 'RSA-HSM', 'oct' + * Possible values include: 'EC', 'EC-HSM', 'RSA', 'RSA-HSM', 'oct', "oct-HSM" * @readonly * @enum {string} */ -export type KeyType = "EC" | "EC-HSM" | "RSA" | "RSA-HSM" | "oct"; +export type KeyType = "EC" | "EC-HSM" | "RSA" | "RSA-HSM" | "oct" | "oct-HSM"; /** * @internal @@ -87,7 +87,7 @@ export interface JsonWebKey { /** * JsonWebKey Key Type (kty), as defined in * https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40. Possible values include: - * 'EC', 'EC-HSM', 'RSA', 'RSA-HSM', 'oct' + * 'EC', 'EC-HSM', 'RSA', 'RSA-HSM', 'oct', "oct-HSM" */ kty?: KeyType; /** @@ -169,7 +169,7 @@ export interface KeyVaultKey { /** * JsonWebKey Key Type (kty), as defined in * https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40. Possible values include: - * 'EC', 'EC-HSM', 'RSA', 'RSA-HSM', 'oct' + * 'EC', 'EC-HSM', 'RSA', 'RSA-HSM', 'oct', "oct-HSM" */ keyType?: KeyType; /** @@ -268,7 +268,7 @@ export interface DeletedKey { /** * JsonWebKey Key Type (kty), as defined in * https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40. Possible values include: - * 'EC', 'EC-HSM', 'RSA', 'RSA-HSM', 'oct' + * 'EC', 'EC-HSM', 'RSA', 'RSA-HSM', 'oct', "oct-HSM" */ keyType?: KeyType; /** diff --git a/sdk/keyvault/keyvault-keys/swagger/README.md b/sdk/keyvault/keyvault-keys/swagger/README.md index 89bd7dc04c04..80e8a578f3ec 100644 --- a/sdk/keyvault/keyvault-keys/swagger/README.md +++ b/sdk/keyvault/keyvault-keys/swagger/README.md @@ -10,8 +10,8 @@ use-extension: azure-arm: false generate-metadata: false add-credentials: false -license-header: MICROSOFT_MIT_NO_VERSION -input-file: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/keyvault/data-plane/Microsoft.KeyVault/stable/7.1/keys.json +license-header: MICROSOFT_MIT_NO_VERSION +input-file: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/f9caf92527ccff06c5b66380e6f2b4f50f5e82b3/specification/keyvault/data-plane/Microsoft.KeyVault/preview/7.2-preview/keys.json output-folder: ../ source-code-folder-path: ./src/generated ``` diff --git a/sdk/keyvault/keyvault-secrets/swagger/README.md b/sdk/keyvault/keyvault-secrets/swagger/README.md index 7332223dd35a..a7d9dc4122b8 100644 --- a/sdk/keyvault/keyvault-secrets/swagger/README.md +++ b/sdk/keyvault/keyvault-secrets/swagger/README.md @@ -11,7 +11,7 @@ azure-arm: false generate-metadata: false add-credentials: false license-header: MICROSOFT_MIT_NO_VERSION -input-file: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/keyvault/data-plane/Microsoft.KeyVault/stable/7.1/secrets.json +input-file: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/f9caf92527ccff06c5b66380e6f2b4f50f5e82b3/specification/keyvault/data-plane/Microsoft.KeyVault/preview/7.2-preview/secrets.json output-folder: ../ source-code-folder-path: ./src/generated ``` From 3f29c59a16e90ede382379256ff47950f2d50b1e Mon Sep 17 00:00:00 2001 From: Wes Haggard Date: Mon, 21 Sep 2020 15:23:01 -0700 Subject: [PATCH 004/152] Add placeholder yml file for pipeline generation --- sdk/communication/ci.yml | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 sdk/communication/ci.yml diff --git a/sdk/communication/ci.yml b/sdk/communication/ci.yml new file mode 100644 index 000000000000..ef575364c3b3 --- /dev/null +++ b/sdk/communication/ci.yml @@ -0,0 +1,28 @@ +# NOTE: Please refer to https://aka.ms/azsdk/engsys/ci-yaml before editing this file. + +trigger: + branches: + include: + - master + - release/* + - hotfix/* + paths: + include: + - sdk/communication/ + +pr: + branches: + include: + - master + - feature/* + - release/* + - hotfix/* + paths: + include: + - sdk/communication/ + +extends: + template: ../../eng/pipelines/templates/stages/archetype-sdk-client.yml + parameters: + ServiceDirectory: communication + Artifacts: From 79c359fbe9c70f44da1355a05967bbbb5625fdef Mon Sep 17 00:00:00 2001 From: praveenkuttappan <55455725+praveenkuttappan@users.noreply.github.com> Date: Mon, 21 Sep 2020 16:50:36 -0700 Subject: [PATCH 005/152] Smoke test failure due to rollup peer dependency error (#11372) * Change to move @rollup/plugin-json as dev dependency --- sdk/identity/identity/CHANGELOG.md | 2 +- sdk/identity/identity/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/identity/identity/CHANGELOG.md b/sdk/identity/identity/CHANGELOG.md index 66b0b679eff9..242d098f8485 100644 --- a/sdk/identity/identity/CHANGELOG.md +++ b/sdk/identity/identity/CHANGELOG.md @@ -1,7 +1,7 @@ # Release History ## 1.2.0-beta.2 (Unreleased) - +- Reverted change in 1.2.0-beta.1 which moved @rollup/plugin-json from devDependencies to dependencies ## 1.2.0-beta.1 (2020-09-08) diff --git a/sdk/identity/identity/package.json b/sdk/identity/identity/package.json index c1ab62f5c083..376399073a30 100644 --- a/sdk/identity/identity/package.json +++ b/sdk/identity/identity/package.json @@ -89,7 +89,6 @@ "msal": "^1.0.2", "open": "^7.0.0", "qs": "^6.7.0", - "@rollup/plugin-json": "^4.0.0", "axios": "^0.19.2", "tslib": "^2.0.0", "uuid": "^8.1.0" @@ -102,6 +101,7 @@ "@azure/abort-controller": "^1.0.0", "@microsoft/api-extractor": "7.7.11", "@rollup/plugin-commonjs": "11.0.2", + "@rollup/plugin-json": "^4.0.0", "@rollup/plugin-multi-entry": "^3.0.0", "@rollup/plugin-node-resolve": "^8.0.0", "@rollup/plugin-replace": "^2.2.0", From a56d29bfdb13827d71deb771362a61803c4b2093 Mon Sep 17 00:00:00 2001 From: Dominik Date: Mon, 21 Sep 2020 22:02:49 -0700 Subject: [PATCH 006/152] Add client libraries for Azure Communication Services (#11385) --- common/config/rush/pnpm-lock.yaml | 335 ++++++- eng/.docsettings.yml | 1 + eng/pipelines/templates/steps/analyze.yml | 10 +- eng/pipelines/templates/steps/build.yml | 2 +- eng/pipelines/templates/steps/test.yml | 8 +- rush.json | 20 + sdk/communication/ci.yml | 8 + .../.eslintrc.json | 18 + .../communication-administration/.gitignore | 2 + .../.vscode/launch.json | 42 + .../communication-administration/CHANGELOG.md | 5 + .../communication-administration/LICENSE | 21 + .../communication-administration/README.md | 83 ++ .../api-extractor.json | 35 + .../karma.conf.js | 144 +++ .../communication-administration/package.json | 125 +++ ...recording_successfully_creates_a_user.json | 22 + ...recording_successfully_deletes_a_user.json | 20 + ...es_a_token_for_a_user_multiple_scopes.json | 22 + ...ssues_a_token_for_a_user_single_scope.json | 22 + ...ully_revokes_tokens_issued_for_a_user.json | 20 + .../recording_successfully_creates_a_user.js | 29 + .../recording_successfully_deletes_a_user.js | 25 + ...sues_a_token_for_a_user_multiple_scopes.js | 33 + ..._issues_a_token_for_a_user_single_scope.js | 33 + ...sfully_revokes_tokens_issued_for_a_user.js | 25 + .../communication-administration.api.md | 64 ++ .../rollup.base.config.js | 131 +++ .../rollup.config.js | 13 + .../rollup.test.config.js | 3 + .../communication-administration/sample.env | 7 + .../samples/.gitignore | 1 + .../samples/javascript/README.md | 67 ++ .../samples/javascript/issueToken.js | 44 + .../samples/javascript/package.json | 29 + .../samples/javascript/revokeTokens.js | 57 ++ .../samples/javascript/sample.env | 3 + .../samples/tsconfig.json | 10 + .../samples/typescript/README.md | 73 ++ .../samples/typescript/package.json | 38 + .../samples/typescript/sample.env | 3 + .../samples/typescript/src/issueToken.ts | 44 + .../samples/typescript/src/revokeTokens.ts | 56 ++ .../samples/typescript/tsconfig.json | 13 + .../src/common/logger.ts | 9 + .../src/common/mappers.ts | 18 + .../src/common/tracing.ts | 57 ++ .../communicationIdentityClient.ts | 237 +++++ .../src/communicationIdentity/constants.ts | 6 + .../generatedCommunicationIdentityClient.ts | 39 + ...ratedCommunicationIdentityClientContext.ts | 36 + .../communicationIdentityOperationsMappers.ts | 14 + .../generated/src/models/index.ts | 107 ++ .../generated/src/models/mappers.ts | 95 ++ .../generated/src/models/parameters.ts | 46 + .../communicationIdentityOperations.ts | 296 ++++++ .../generated/src/operations/index.ts | 11 + .../src/communicationIdentity/models.ts | 48 + .../communication-administration/src/index.ts | 5 + .../swagger/CommunicationIdentity.md | 22 + .../test/README.md | 19 + ...communicationIdentityClient.mocked.spec.ts | 109 +++ .../test/communicationIdentityClient.spec.ts | 63 ++ .../test/utils/mockHttpClients.ts | 33 + .../test/utils/recordedClient.ts | 69 ++ .../utils/testCommunicationIdentityClient.ts | 49 + .../communication-administration/tests.yml | 8 + .../tsconfig.json | 17 + .../communication-chat/.eslintrc.json | 18 + .../communication-chat/.gitignore | 1 + .../communication-chat/.vscode/launch.json | 45 + .../communication-chat/.vscode/tasks.json | 16 + .../communication-chat/CHANGELOG.md | 13 + sdk/communication/communication-chat/LICENSE | 21 + .../communication-chat/README.md | 190 ++++ .../communication-chat/api-extractor.json | 31 + .../communication-chat/karma.conf.js | 151 +++ .../communication-chat/package.json | 131 +++ .../recording_successfully_adds_members.json | 48 + ...cording_successfully_creates_a_thread.json | 75 ++ ...ording_successfully_deletes_a_message.json | 20 + ...cording_successfully_deletes_a_thread.json | 20 + .../recording_successfully_lists_members.json | 22 + ...recording_successfully_lists_messages.json | 22 + ...ding_successfully_lists_read_receipts.json | 22 + .../recording_successfully_lists_threads.json | 22 + ...ecording_successfully_remove_a_member.json | 20 + ...ding_successfully_retrieves_a_message.json | 22 + ...rding_successfully_retrieves_a_thread.json | 22 + ...uccessfully_retrieves_a_thread_client.json | 8 + ...ecording_successfully_sends_a_message.json | 23 + ...rding_successfully_sends_read_receipt.json | 22 + ...uccessfully_sends_typing_notification.json | 22 + .../recording_successfully_adds_members.js | 75 ++ ...recording_successfully_creates_a_thread.js | 125 +++ ...ecording_successfully_deletes_a_message.js | 23 + ...recording_successfully_deletes_a_thread.js | 23 + .../recording_successfully_lists_members.js | 27 + .../recording_successfully_lists_messages.js | 27 + ...ording_successfully_lists_read_receipts.js | 27 + .../recording_successfully_lists_threads.js | 27 + .../recording_successfully_remove_a_member.js | 23 + ...ording_successfully_retrieves_a_message.js | 27 + ...cording_successfully_retrieves_a_thread.js | 27 + ..._successfully_retrieves_a_thread_client.js | 5 + .../recording_successfully_sends_a_message.js | 29 + ...cording_successfully_sends_read_receipt.js | 25 + ..._successfully_sends_typing_notification.js | 25 + .../review/communication-chat.api.md | 285 ++++++ .../communication-chat/rollup.base.config.js | 132 +++ .../communication-chat/rollup.config.js | 13 + .../communication-chat/rollup.test.config.js | 3 + .../communication-chat/sample.env | 8 + .../communication-chat/src/chatClient.ts | 437 +++++++++ .../src/chatThreadClient.ts | 604 ++++++++++++ .../communication-chat/src/constants.ts | 6 + .../communicationUserCredentialPolicy.ts | 65 ++ .../src/generated/src/chatApiClient.ts | 921 ++++++++++++++++++ .../src/generated/src/chatApiClientContext.ts | 51 + .../src/generated/src/models/index.ts | 624 ++++++++++++ .../src/generated/src/models/mappers.ts | 552 +++++++++++ .../src/generated/src/models/parameters.ts | 152 +++ .../communication-chat/src/index.ts | 8 + .../communication-chat/src/models/logger.ts | 6 + .../communication-chat/src/models/mappers.ts | 115 +++ .../communication-chat/src/models/models.ts | 105 ++ .../communication-chat/src/models/options.ts | 110 +++ .../communication-chat/src/models/requests.ts | 36 + .../src/signaling/signalingClient.browser.ts | 13 + .../src/signaling/signalingClient.ts | 13 + .../communication-chat/src/tracing.ts | 57 ++ .../communication-chat/swagger/README.md | 21 + .../communication-chat/test/README.md | 20 + .../test/chatClient.mocked.spec.ts | 133 +++ .../test/chatClient.spec.ts | 150 +++ .../test/chatThreadClient.mocked.spec.ts | 316 ++++++ .../test/utils/connectionUtils.ts | 13 + .../test/utils/mockClient.ts | 95 ++ .../test/utils/recordedClient.ts | 78 ++ .../communication-chat/tsconfig.json | 8 + .../communication-common/.eslintrc.json | 18 + .../communication-common/.vscode/launch.json | 43 + .../communication-common/CHANGELOG.md | 5 + .../communication-common/LICENSE | 21 + .../communication-common/README.md | 90 ++ .../communication-common/api-extractor.json | 31 + .../communication-common/karma.conf.js | 126 +++ .../communication-common/package.json | 122 +++ .../review/communication-common.api.md | 112 +++ .../rollup.base.config.js | 123 +++ .../communication-common/rollup.config.js | 13 + .../rollup.test.config.js | 3 + .../communication-common/samples/.gitkeep | 0 .../src/autoRefreshUserCredential.ts | 132 +++ .../src/communicationUserCredential.ts | 76 ++ .../src/credential/clientArguments.ts | 60 ++ .../communicationAccessKeyCredentialPolicy.ts | 99 ++ .../src/credential/connectionString.ts | 29 + .../src/credential/cryptoUtils.browser.ts | 34 + .../src/credential/cryptoUtils.ts | 17 + .../src/credential/encodeUtils.browser.ts | 28 + .../src/credential/index.ts | 5 + .../src/identifierModels.ts | 150 +++ .../communication-common/src/index.ts | 10 + .../communication-common/src/shims.d.ts | 34 + .../src/staticTokenCredential.ts | 20 + .../communication-common/src/tokenParser.ts | 17 + .../test/clientArguments.spec.ts | 38 + .../test/communicationUserCredential.spec.ts | 248 +++++ .../test/connectionString.spec.ts | 23 + .../test/cryptoUtils.spec.ts | 27 + .../test/identifierModels.spec.ts | 29 + .../communication-common/tsconfig.json | 8 + .../communication-sms/.eslintrc.json | 18 + .../communication-sms/.gitignore | 1 + .../communication-sms/.vscode/launch.json | 45 + .../communication-sms/.vscode/tasks.json | 16 + .../communication-sms/CHANGELOG.md | 8 + sdk/communication/communication-sms/LICENSE | 21 + sdk/communication/communication-sms/README.md | 85 ++ .../communication-sms/api-extractor.json | 31 + .../communication-sms/karma.conf.js | 149 +++ .../communication-sms/package.json | 126 +++ .../recording_sends_an_sms_message.json | 22 + .../recording_sends_an_sms_message.js | 23 + .../review/communication-sms.api.md | 38 + .../communication-sms/rollup.base.config.js | 131 +++ .../communication-sms/rollup.config.js | 13 + .../communication-sms/rollup.test.config.js | 3 + .../communication-sms/sample.env | 10 + .../communication-sms/samples/.gitignore | 1 + .../samples/javascript/README.md | 65 ++ .../samples/javascript/package.json | 31 + .../samples/javascript/sample.env | 3 + .../samples/javascript/sendSms.js | 45 + .../samples/typescript/README.md | 71 ++ .../samples/typescript/package.json | 41 + .../samples/typescript/sample.env | 3 + .../samples/typescript/src/sendSms.ts | 43 + .../samples/typescript/tsconfig.json | 13 + .../communication-sms/src/constants.ts | 6 + .../src/extractOperationOptions.ts | 22 + .../src/generated/src/models/index.ts | 70 ++ .../src/generated/src/models/mappers.ts | 84 ++ .../src/generated/src/models/parameters.ts | 36 + .../src/generated/src/models/smsMappers.ts | 9 + .../src/generated/src/operations/index.ts | 11 + .../src/generated/src/operations/sms.ts | 94 ++ .../src/generated/src/smsApiClient.ts | 35 + .../src/generated/src/smsApiClientContext.ts | 44 + .../communication-sms/src/index.ts | 4 + .../communication-sms/src/logger.ts | 9 + .../communication-sms/src/smsClient.ts | 154 +++ .../communication-sms/src/tracing.ts | 57 ++ .../communication-sms/swagger/README.md | 19 + .../communication-sms/test/README.md | 21 + .../test/smsClient.mocked.spec.ts | 115 +++ .../communication-sms/test/smsClient.spec.ts | 54 + .../communication-sms/tsconfig.json | 8 + sdk/communication/test-resources.json | 79 ++ 220 files changed, 13617 insertions(+), 12 deletions(-) create mode 100644 sdk/communication/communication-administration/.eslintrc.json create mode 100644 sdk/communication/communication-administration/.gitignore create mode 100644 sdk/communication/communication-administration/.vscode/launch.json create mode 100644 sdk/communication/communication-administration/CHANGELOG.md create mode 100644 sdk/communication/communication-administration/LICENSE create mode 100644 sdk/communication/communication-administration/README.md create mode 100644 sdk/communication/communication-administration/api-extractor.json create mode 100644 sdk/communication/communication-administration/karma.conf.js create mode 100644 sdk/communication/communication-administration/package.json create mode 100644 sdk/communication/communication-administration/recordings/browsers/communicationidentityclient_playbacklive/recording_successfully_creates_a_user.json create mode 100644 sdk/communication/communication-administration/recordings/browsers/communicationidentityclient_playbacklive/recording_successfully_deletes_a_user.json create mode 100644 sdk/communication/communication-administration/recordings/browsers/communicationidentityclient_playbacklive/recording_successfully_issues_a_token_for_a_user_multiple_scopes.json create mode 100644 sdk/communication/communication-administration/recordings/browsers/communicationidentityclient_playbacklive/recording_successfully_issues_a_token_for_a_user_single_scope.json create mode 100644 sdk/communication/communication-administration/recordings/browsers/communicationidentityclient_playbacklive/recording_successfully_revokes_tokens_issued_for_a_user.json create mode 100644 sdk/communication/communication-administration/recordings/node/communicationidentityclient_playbacklive/recording_successfully_creates_a_user.js create mode 100644 sdk/communication/communication-administration/recordings/node/communicationidentityclient_playbacklive/recording_successfully_deletes_a_user.js create mode 100644 sdk/communication/communication-administration/recordings/node/communicationidentityclient_playbacklive/recording_successfully_issues_a_token_for_a_user_multiple_scopes.js create mode 100644 sdk/communication/communication-administration/recordings/node/communicationidentityclient_playbacklive/recording_successfully_issues_a_token_for_a_user_single_scope.js create mode 100644 sdk/communication/communication-administration/recordings/node/communicationidentityclient_playbacklive/recording_successfully_revokes_tokens_issued_for_a_user.js create mode 100644 sdk/communication/communication-administration/review/communication-administration.api.md create mode 100644 sdk/communication/communication-administration/rollup.base.config.js create mode 100644 sdk/communication/communication-administration/rollup.config.js create mode 100644 sdk/communication/communication-administration/rollup.test.config.js create mode 100644 sdk/communication/communication-administration/sample.env create mode 100644 sdk/communication/communication-administration/samples/.gitignore create mode 100644 sdk/communication/communication-administration/samples/javascript/README.md create mode 100644 sdk/communication/communication-administration/samples/javascript/issueToken.js create mode 100644 sdk/communication/communication-administration/samples/javascript/package.json create mode 100644 sdk/communication/communication-administration/samples/javascript/revokeTokens.js create mode 100644 sdk/communication/communication-administration/samples/javascript/sample.env create mode 100644 sdk/communication/communication-administration/samples/tsconfig.json create mode 100644 sdk/communication/communication-administration/samples/typescript/README.md create mode 100644 sdk/communication/communication-administration/samples/typescript/package.json create mode 100644 sdk/communication/communication-administration/samples/typescript/sample.env create mode 100644 sdk/communication/communication-administration/samples/typescript/src/issueToken.ts create mode 100644 sdk/communication/communication-administration/samples/typescript/src/revokeTokens.ts create mode 100644 sdk/communication/communication-administration/samples/typescript/tsconfig.json create mode 100644 sdk/communication/communication-administration/src/common/logger.ts create mode 100644 sdk/communication/communication-administration/src/common/mappers.ts create mode 100644 sdk/communication/communication-administration/src/common/tracing.ts create mode 100644 sdk/communication/communication-administration/src/communicationIdentity/communicationIdentityClient.ts create mode 100644 sdk/communication/communication-administration/src/communicationIdentity/constants.ts create mode 100644 sdk/communication/communication-administration/src/communicationIdentity/generated/src/generatedCommunicationIdentityClient.ts create mode 100644 sdk/communication/communication-administration/src/communicationIdentity/generated/src/generatedCommunicationIdentityClientContext.ts create mode 100644 sdk/communication/communication-administration/src/communicationIdentity/generated/src/models/communicationIdentityOperationsMappers.ts create mode 100644 sdk/communication/communication-administration/src/communicationIdentity/generated/src/models/index.ts create mode 100644 sdk/communication/communication-administration/src/communicationIdentity/generated/src/models/mappers.ts create mode 100644 sdk/communication/communication-administration/src/communicationIdentity/generated/src/models/parameters.ts create mode 100644 sdk/communication/communication-administration/src/communicationIdentity/generated/src/operations/communicationIdentityOperations.ts create mode 100644 sdk/communication/communication-administration/src/communicationIdentity/generated/src/operations/index.ts create mode 100644 sdk/communication/communication-administration/src/communicationIdentity/models.ts create mode 100644 sdk/communication/communication-administration/src/index.ts create mode 100644 sdk/communication/communication-administration/swagger/CommunicationIdentity.md create mode 100644 sdk/communication/communication-administration/test/README.md create mode 100644 sdk/communication/communication-administration/test/communicationIdentityClient.mocked.spec.ts create mode 100644 sdk/communication/communication-administration/test/communicationIdentityClient.spec.ts create mode 100644 sdk/communication/communication-administration/test/utils/mockHttpClients.ts create mode 100644 sdk/communication/communication-administration/test/utils/recordedClient.ts create mode 100644 sdk/communication/communication-administration/test/utils/testCommunicationIdentityClient.ts create mode 100644 sdk/communication/communication-administration/tests.yml create mode 100644 sdk/communication/communication-administration/tsconfig.json create mode 100644 sdk/communication/communication-chat/.eslintrc.json create mode 100644 sdk/communication/communication-chat/.gitignore create mode 100644 sdk/communication/communication-chat/.vscode/launch.json create mode 100644 sdk/communication/communication-chat/.vscode/tasks.json create mode 100644 sdk/communication/communication-chat/CHANGELOG.md create mode 100644 sdk/communication/communication-chat/LICENSE create mode 100644 sdk/communication/communication-chat/README.md create mode 100644 sdk/communication/communication-chat/api-extractor.json create mode 100644 sdk/communication/communication-chat/karma.conf.js create mode 100644 sdk/communication/communication-chat/package.json create mode 100644 sdk/communication/communication-chat/recordings/browsers/chatclient/recording_successfully_adds_members.json create mode 100644 sdk/communication/communication-chat/recordings/browsers/chatclient/recording_successfully_creates_a_thread.json create mode 100644 sdk/communication/communication-chat/recordings/browsers/chatclient/recording_successfully_deletes_a_message.json create mode 100644 sdk/communication/communication-chat/recordings/browsers/chatclient/recording_successfully_deletes_a_thread.json create mode 100644 sdk/communication/communication-chat/recordings/browsers/chatclient/recording_successfully_lists_members.json create mode 100644 sdk/communication/communication-chat/recordings/browsers/chatclient/recording_successfully_lists_messages.json create mode 100644 sdk/communication/communication-chat/recordings/browsers/chatclient/recording_successfully_lists_read_receipts.json create mode 100644 sdk/communication/communication-chat/recordings/browsers/chatclient/recording_successfully_lists_threads.json create mode 100644 sdk/communication/communication-chat/recordings/browsers/chatclient/recording_successfully_remove_a_member.json create mode 100644 sdk/communication/communication-chat/recordings/browsers/chatclient/recording_successfully_retrieves_a_message.json create mode 100644 sdk/communication/communication-chat/recordings/browsers/chatclient/recording_successfully_retrieves_a_thread.json create mode 100644 sdk/communication/communication-chat/recordings/browsers/chatclient/recording_successfully_retrieves_a_thread_client.json create mode 100644 sdk/communication/communication-chat/recordings/browsers/chatclient/recording_successfully_sends_a_message.json create mode 100644 sdk/communication/communication-chat/recordings/browsers/chatclient/recording_successfully_sends_read_receipt.json create mode 100644 sdk/communication/communication-chat/recordings/browsers/chatclient/recording_successfully_sends_typing_notification.json create mode 100644 sdk/communication/communication-chat/recordings/node/chatclient/recording_successfully_adds_members.js create mode 100644 sdk/communication/communication-chat/recordings/node/chatclient/recording_successfully_creates_a_thread.js create mode 100644 sdk/communication/communication-chat/recordings/node/chatclient/recording_successfully_deletes_a_message.js create mode 100644 sdk/communication/communication-chat/recordings/node/chatclient/recording_successfully_deletes_a_thread.js create mode 100644 sdk/communication/communication-chat/recordings/node/chatclient/recording_successfully_lists_members.js create mode 100644 sdk/communication/communication-chat/recordings/node/chatclient/recording_successfully_lists_messages.js create mode 100644 sdk/communication/communication-chat/recordings/node/chatclient/recording_successfully_lists_read_receipts.js create mode 100644 sdk/communication/communication-chat/recordings/node/chatclient/recording_successfully_lists_threads.js create mode 100644 sdk/communication/communication-chat/recordings/node/chatclient/recording_successfully_remove_a_member.js create mode 100644 sdk/communication/communication-chat/recordings/node/chatclient/recording_successfully_retrieves_a_message.js create mode 100644 sdk/communication/communication-chat/recordings/node/chatclient/recording_successfully_retrieves_a_thread.js create mode 100644 sdk/communication/communication-chat/recordings/node/chatclient/recording_successfully_retrieves_a_thread_client.js create mode 100644 sdk/communication/communication-chat/recordings/node/chatclient/recording_successfully_sends_a_message.js create mode 100644 sdk/communication/communication-chat/recordings/node/chatclient/recording_successfully_sends_read_receipt.js create mode 100644 sdk/communication/communication-chat/recordings/node/chatclient/recording_successfully_sends_typing_notification.js create mode 100644 sdk/communication/communication-chat/review/communication-chat.api.md create mode 100644 sdk/communication/communication-chat/rollup.base.config.js create mode 100644 sdk/communication/communication-chat/rollup.config.js create mode 100644 sdk/communication/communication-chat/rollup.test.config.js create mode 100644 sdk/communication/communication-chat/sample.env create mode 100644 sdk/communication/communication-chat/src/chatClient.ts create mode 100644 sdk/communication/communication-chat/src/chatThreadClient.ts create mode 100644 sdk/communication/communication-chat/src/constants.ts create mode 100644 sdk/communication/communication-chat/src/credential/communicationUserCredentialPolicy.ts create mode 100644 sdk/communication/communication-chat/src/generated/src/chatApiClient.ts create mode 100644 sdk/communication/communication-chat/src/generated/src/chatApiClientContext.ts create mode 100644 sdk/communication/communication-chat/src/generated/src/models/index.ts create mode 100644 sdk/communication/communication-chat/src/generated/src/models/mappers.ts create mode 100644 sdk/communication/communication-chat/src/generated/src/models/parameters.ts create mode 100644 sdk/communication/communication-chat/src/index.ts create mode 100644 sdk/communication/communication-chat/src/models/logger.ts create mode 100644 sdk/communication/communication-chat/src/models/mappers.ts create mode 100644 sdk/communication/communication-chat/src/models/models.ts create mode 100644 sdk/communication/communication-chat/src/models/options.ts create mode 100644 sdk/communication/communication-chat/src/models/requests.ts create mode 100644 sdk/communication/communication-chat/src/signaling/signalingClient.browser.ts create mode 100644 sdk/communication/communication-chat/src/signaling/signalingClient.ts create mode 100644 sdk/communication/communication-chat/src/tracing.ts create mode 100644 sdk/communication/communication-chat/swagger/README.md create mode 100644 sdk/communication/communication-chat/test/README.md create mode 100644 sdk/communication/communication-chat/test/chatClient.mocked.spec.ts create mode 100644 sdk/communication/communication-chat/test/chatClient.spec.ts create mode 100644 sdk/communication/communication-chat/test/chatThreadClient.mocked.spec.ts create mode 100644 sdk/communication/communication-chat/test/utils/connectionUtils.ts create mode 100644 sdk/communication/communication-chat/test/utils/mockClient.ts create mode 100644 sdk/communication/communication-chat/test/utils/recordedClient.ts create mode 100644 sdk/communication/communication-chat/tsconfig.json create mode 100644 sdk/communication/communication-common/.eslintrc.json create mode 100644 sdk/communication/communication-common/.vscode/launch.json create mode 100644 sdk/communication/communication-common/CHANGELOG.md create mode 100644 sdk/communication/communication-common/LICENSE create mode 100644 sdk/communication/communication-common/README.md create mode 100644 sdk/communication/communication-common/api-extractor.json create mode 100644 sdk/communication/communication-common/karma.conf.js create mode 100644 sdk/communication/communication-common/package.json create mode 100644 sdk/communication/communication-common/review/communication-common.api.md create mode 100644 sdk/communication/communication-common/rollup.base.config.js create mode 100644 sdk/communication/communication-common/rollup.config.js create mode 100644 sdk/communication/communication-common/rollup.test.config.js create mode 100644 sdk/communication/communication-common/samples/.gitkeep create mode 100644 sdk/communication/communication-common/src/autoRefreshUserCredential.ts create mode 100644 sdk/communication/communication-common/src/communicationUserCredential.ts create mode 100644 sdk/communication/communication-common/src/credential/clientArguments.ts create mode 100644 sdk/communication/communication-common/src/credential/communicationAccessKeyCredentialPolicy.ts create mode 100644 sdk/communication/communication-common/src/credential/connectionString.ts create mode 100644 sdk/communication/communication-common/src/credential/cryptoUtils.browser.ts create mode 100644 sdk/communication/communication-common/src/credential/cryptoUtils.ts create mode 100644 sdk/communication/communication-common/src/credential/encodeUtils.browser.ts create mode 100644 sdk/communication/communication-common/src/credential/index.ts create mode 100644 sdk/communication/communication-common/src/identifierModels.ts create mode 100644 sdk/communication/communication-common/src/index.ts create mode 100644 sdk/communication/communication-common/src/shims.d.ts create mode 100644 sdk/communication/communication-common/src/staticTokenCredential.ts create mode 100644 sdk/communication/communication-common/src/tokenParser.ts create mode 100644 sdk/communication/communication-common/test/clientArguments.spec.ts create mode 100644 sdk/communication/communication-common/test/communicationUserCredential.spec.ts create mode 100644 sdk/communication/communication-common/test/connectionString.spec.ts create mode 100644 sdk/communication/communication-common/test/cryptoUtils.spec.ts create mode 100644 sdk/communication/communication-common/test/identifierModels.spec.ts create mode 100644 sdk/communication/communication-common/tsconfig.json create mode 100644 sdk/communication/communication-sms/.eslintrc.json create mode 100644 sdk/communication/communication-sms/.gitignore create mode 100644 sdk/communication/communication-sms/.vscode/launch.json create mode 100644 sdk/communication/communication-sms/.vscode/tasks.json create mode 100644 sdk/communication/communication-sms/CHANGELOG.md create mode 100644 sdk/communication/communication-sms/LICENSE create mode 100644 sdk/communication/communication-sms/README.md create mode 100644 sdk/communication/communication-sms/api-extractor.json create mode 100644 sdk/communication/communication-sms/karma.conf.js create mode 100644 sdk/communication/communication-sms/package.json create mode 100644 sdk/communication/communication-sms/recordings/browsers/smsclient/recording_sends_an_sms_message.json create mode 100644 sdk/communication/communication-sms/recordings/node/smsclient/recording_sends_an_sms_message.js create mode 100644 sdk/communication/communication-sms/review/communication-sms.api.md create mode 100644 sdk/communication/communication-sms/rollup.base.config.js create mode 100644 sdk/communication/communication-sms/rollup.config.js create mode 100644 sdk/communication/communication-sms/rollup.test.config.js create mode 100644 sdk/communication/communication-sms/sample.env create mode 100644 sdk/communication/communication-sms/samples/.gitignore create mode 100644 sdk/communication/communication-sms/samples/javascript/README.md create mode 100644 sdk/communication/communication-sms/samples/javascript/package.json create mode 100644 sdk/communication/communication-sms/samples/javascript/sample.env create mode 100644 sdk/communication/communication-sms/samples/javascript/sendSms.js create mode 100644 sdk/communication/communication-sms/samples/typescript/README.md create mode 100644 sdk/communication/communication-sms/samples/typescript/package.json create mode 100644 sdk/communication/communication-sms/samples/typescript/sample.env create mode 100644 sdk/communication/communication-sms/samples/typescript/src/sendSms.ts create mode 100644 sdk/communication/communication-sms/samples/typescript/tsconfig.json create mode 100644 sdk/communication/communication-sms/src/constants.ts create mode 100644 sdk/communication/communication-sms/src/extractOperationOptions.ts create mode 100644 sdk/communication/communication-sms/src/generated/src/models/index.ts create mode 100644 sdk/communication/communication-sms/src/generated/src/models/mappers.ts create mode 100644 sdk/communication/communication-sms/src/generated/src/models/parameters.ts create mode 100644 sdk/communication/communication-sms/src/generated/src/models/smsMappers.ts create mode 100644 sdk/communication/communication-sms/src/generated/src/operations/index.ts create mode 100644 sdk/communication/communication-sms/src/generated/src/operations/sms.ts create mode 100644 sdk/communication/communication-sms/src/generated/src/smsApiClient.ts create mode 100644 sdk/communication/communication-sms/src/generated/src/smsApiClientContext.ts create mode 100644 sdk/communication/communication-sms/src/index.ts create mode 100644 sdk/communication/communication-sms/src/logger.ts create mode 100644 sdk/communication/communication-sms/src/smsClient.ts create mode 100644 sdk/communication/communication-sms/src/tracing.ts create mode 100644 sdk/communication/communication-sms/swagger/README.md create mode 100644 sdk/communication/communication-sms/test/README.md create mode 100644 sdk/communication/communication-sms/test/smsClient.mocked.spec.ts create mode 100644 sdk/communication/communication-sms/test/smsClient.spec.ts create mode 100644 sdk/communication/communication-sms/tsconfig.json create mode 100644 sdk/communication/test-resources.json diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index 0b425bc4d9bb..5885a8121800 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -4,6 +4,10 @@ dependencies: '@rush-temp/ai-form-recognizer': 'file:projects/ai-form-recognizer.tgz' '@rush-temp/ai-text-analytics': 'file:projects/ai-text-analytics.tgz' '@rush-temp/app-configuration': 'file:projects/app-configuration.tgz' + '@rush-temp/communication-administration': 'file:projects/communication-administration.tgz' + '@rush-temp/communication-chat': 'file:projects/communication-chat.tgz' + '@rush-temp/communication-common': 'file:projects/communication-common.tgz' + '@rush-temp/communication-sms': 'file:projects/communication-sms.tgz' '@rush-temp/core-amqp': 'file:projects/core-amqp.tgz' '@rush-temp/core-arm': 'file:projects/core-arm.tgz' '@rush-temp/core-asynciterator-polyfill': 'file:projects/core-asynciterator-polyfill.tgz' @@ -75,6 +79,18 @@ packages: dev: false resolution: integrity: sha512-RVG1Ad3Afv9gwFFmpeCXQAm+Sa0L8KEZRJJAAZEGoYDb6EoO1iQDVmoBz720h8mdrGpi0D60xNU/KhriIwuZfQ== + /@azure/communication-signaling/1.0.0-beta.1: + dependencies: + '@azure/core-http': 1.1.7 + '@azure/logger': 1.0.0 + '@opentelemetry/api': 0.6.1 + events: 3.1.0 + tslib: 1.13.0 + dev: false + engines: + node: '>=8.0.0' + resolution: + integrity: sha512-xxlGwbbTkEZAline8wrP75FLaOsT23nMukzIg5X/Cs6cQSQ/JKj7Uxq5Idxp9GgAYT+g+PAj+BJ929/jaselBQ== /@azure/core-amqp/1.1.4: dependencies: '@azure/abort-controller': 1.0.1 @@ -453,6 +469,19 @@ packages: node: '>=8' resolution: integrity: sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw== + /@microsoft/api-documenter/7.8.55: + dependencies: + '@microsoft/api-extractor-model': 7.9.6 + '@microsoft/tsdoc': 0.12.19 + '@rushstack/node-core-library': 3.33.5 + '@rushstack/ts-command-line': 4.6.9 + colors: 1.2.5 + js-yaml: 3.13.1 + resolve: 1.17.0 + dev: false + hasBin: true + resolution: + integrity: sha512-NhRc45gUhwZiUzdyA9U5x3A3Ql3nKhu2iBsk5CrguOAtEw/rJ0rGJ9Ufj52V4J+dQ3/itI+sFicReZrXs90Tjg== /@microsoft/api-extractor-model/7.7.10: dependencies: '@microsoft/tsdoc': 0.12.19 @@ -460,6 +489,13 @@ packages: dev: false resolution: integrity: sha512-gMFDXwUgoQYz9TgatyNPALDdZN4xBC3Un3fGwlzME+vM13PoJ26pGuqI7kv/OlK9+q2sgrEdxWns8D3UnLf2TA== + /@microsoft/api-extractor-model/7.9.6: + dependencies: + '@microsoft/tsdoc': 0.12.19 + '@rushstack/node-core-library': 3.33.5 + dev: false + resolution: + integrity: sha512-npGZSgOk1iDre5DbmIZpxAeppsYDCwaRmxNZy8afVOKh0PPiOmnZEUzEyvGCNIQBdHC8B7f8L7qLgLlkm2dq8A== /@microsoft/api-extractor/7.7.11: dependencies: '@microsoft/api-extractor-model': 7.7.10 @@ -646,6 +682,20 @@ packages: dev: false resolution: integrity: sha512-1+FoymIdr9W9k0D8fdZBBPwi5YcMwh/RyESuL5bY29rLICFxSLOPK+ImVZ1OcWj9GEMsvDx5pNpJ311mHQk+MA== + /@rushstack/node-core-library/3.33.5: + dependencies: + '@types/node': 10.17.13 + colors: 1.2.5 + fs-extra: 7.0.1 + import-lazy: 4.0.0 + jju: 1.4.0 + resolve: 1.17.0 + semver: 7.3.2 + timsort: 0.3.0 + z-schema: 3.18.4 + dev: false + resolution: + integrity: sha512-eUTjIbXuWctD5hULyHn2tIm/SqXNagjqlMfGg28ZeQkcPx4gpNTvJSv2Cau8b8Nco+yblbWVOi/BNCh3+ai3bA== /@rushstack/ts-command-line/4.3.13: dependencies: '@types/argparse': 1.0.33 @@ -654,6 +704,15 @@ packages: dev: false resolution: integrity: sha512-BUBbjYu67NJGQkpHu8aYm7kDoMFizL1qx78+72XE3mX/vDdXYJzw/FWS7TPcMJmY4kNlYs979v2B0Q0qa2wRiw== + /@rushstack/ts-command-line/4.6.9: + dependencies: + '@types/argparse': 1.0.38 + argparse: 1.0.10 + colors: 1.2.5 + string-argv: 0.3.1 + dev: false + resolution: + integrity: sha512-HrwXkKAHMj14ZTH/70AbrR7vpA5CMiE1oKC1F+hDnnyi94bvOGKLRf3mpiynHKWMPJAJrwREP1Lcf3/UBfGWGg== /@sinonjs/commons/1.8.0: dependencies: type-detect: 4.0.8 @@ -689,6 +748,10 @@ packages: dev: false resolution: integrity: sha512-VQgHxyPMTj3hIlq9SY1mctqx+Jj8kpQfoLvDlVSDNOyuYs8JYfkuY3OW/4+dO657yPmNhHpePRx0/Tje5ImNVQ== + /@types/argparse/1.0.38: + dev: false + resolution: + integrity: sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA== /@types/async-lock/1.1.2: dev: false resolution: @@ -822,6 +885,10 @@ packages: dev: false resolution: integrity: sha512-S0ohSSX8ioT65zu8KbG99xKyFV3InIjbM3c8roYqWy4+5HpYPyUHLYykfhM6MEI5B/3s7KSZPGFyCzCrZ2TOZA== + /@types/jwt-decode/2.2.1: + dev: false + resolution: + integrity: sha512-aWw2YTtAdT7CskFyxEX2K21/zSDStuf/ikI3yBqmwpwJF0pS+/IX5DWv+1UFffZIbruP6cnT9/LAJV1gFwAT1A== /@types/long/4.0.1: dev: false resolution: @@ -2651,6 +2718,14 @@ packages: eslint: '>=5.16.0' resolution: integrity: sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g== + /eslint-plugin-prefer-arrow/1.2.2_eslint@6.8.0: + dependencies: + eslint: 6.8.0 + dev: false + peerDependencies: + eslint: '>=2.0.0' + resolution: + integrity: sha512-C8YMhL+r8RMeMdYAw/rQtE6xNdMulj+zGWud/qIGnlmomiPRaLDGLMeskZ3alN6uMBojmooRimtdrXebLN4svQ== /eslint-plugin-prettier/3.1.4_eslint@6.8.0+prettier@1.19.1: dependencies: eslint: 6.8.0 @@ -3793,6 +3868,12 @@ packages: node: '>=6' resolution: integrity: sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ== + /import-lazy/4.0.0: + dev: false + engines: + node: '>=8' + resolution: + integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw== /imurmurhash/0.1.4: dev: false engines: @@ -4413,6 +4494,10 @@ packages: dev: false resolution: integrity: sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg== + /jwt-decode/2.2.0: + dev: false + resolution: + integrity: sha1-fYa9VmefWM5qhHBKZX3TkruoGnk= /karma-chai/0.1.0_chai@4.2.0+karma@5.1.1: dependencies: chai: 4.2.0 @@ -6918,6 +7003,12 @@ packages: node: '>=0.10.0' resolution: integrity: sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= + /string-argv/0.3.1: + dev: false + engines: + node: '>=0.6.19' + resolution: + integrity: sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg== /string-width/1.0.2: dependencies: code-point-at: 1.1.0 @@ -8029,7 +8120,7 @@ packages: dev: false name: '@rush-temp/abort-controller' resolution: - integrity: sha512-78SPLuZydRyhpdf4wO9uWQf4g8Ebuk5OZWFKmLKTPk42QJtMJpH9l7X1UXW3nh58BUHYairnIHJ0jamYTC6unw== + integrity: sha512-xM5W0taJ/3c/Rxugc3E+Q0HfRb+CE4yhobdPYaNA2OufzCZMO5OZguDr+cvM52AdLUvNP/M7UUwEljKPJznLeQ== tarball: 'file:projects/abort-controller.tgz' version: 0.0.0 'file:projects/ai-anomaly-detector.tgz': @@ -8268,6 +8359,242 @@ packages: integrity: sha512-o3zyWd0p+Th710h7qEQs8+0UstbL9Vf+kgUNP5amLJDfYh2qfzVA0msroRHAhaM0sRO7BDGXfpkFnU/GUa9PPw== tarball: 'file:projects/app-configuration.tgz' version: 0.0.0 + 'file:projects/communication-administration.tgz': + dependencies: + '@azure/core-tracing': 1.0.0-preview.9 + '@microsoft/api-documenter': 7.8.55 + '@microsoft/api-extractor': 7.7.11 + '@opentelemetry/api': 0.10.2 + '@rollup/plugin-commonjs': 11.0.2_rollup@1.32.1 + '@rollup/plugin-json': 4.1.0_rollup@1.32.1 + '@rollup/plugin-multi-entry': 3.0.1_rollup@1.32.1 + '@rollup/plugin-node-resolve': 8.1.0_rollup@1.32.1 + '@rollup/plugin-replace': 2.3.3_rollup@1.32.1 + '@types/chai': 4.2.11 + '@types/mocha': 7.0.2 + '@types/node': 8.10.61 + '@types/sinon': 9.0.4 + '@typescript-eslint/eslint-plugin': 2.34.0_3787943315ebc5ea524d5c102dc9e452 + '@typescript-eslint/parser': 2.34.0_eslint@6.8.0+typescript@3.9.6 + assert: 1.5.0 + chai: 4.2.0 + cross-env: 7.0.2 + dotenv: 8.2.0 + eslint: 6.8.0 + eslint-config-prettier: 6.11.0_eslint@6.8.0 + eslint-plugin-no-null: 1.0.2_eslint@6.8.0 + eslint-plugin-no-only-tests: 2.4.0 + eslint-plugin-prefer-arrow: 1.2.2_eslint@6.8.0 + eslint-plugin-promise: 4.2.1 + events: 3.1.0 + inherits: 2.0.4 + karma: 5.1.1 + karma-chrome-launcher: 3.1.0 + karma-coverage: 2.0.2 + karma-edge-launcher: 0.4.2_karma@5.1.1 + karma-env-preprocessor: 0.1.1 + karma-firefox-launcher: 1.3.0 + karma-ie-launcher: 1.0.0_karma@5.1.1 + karma-json-preprocessor: 0.3.3_karma@5.1.1 + karma-json-to-file-reporter: 1.0.1 + karma-junit-reporter: 2.0.1_karma@5.1.1 + karma-mocha: 2.0.1 + karma-mocha-reporter: 2.2.5_karma@5.1.1 + karma-remap-istanbul: 0.6.0_karma@5.1.1 + mocha: 7.2.0 + mocha-junit-reporter: 1.23.3_mocha@7.2.0 + node-fetch: 2.6.0 + prettier: 1.19.1 + rimraf: 3.0.2 + rollup: 1.32.1 + rollup-plugin-shim: 1.0.0 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.32.1 + rollup-plugin-terser: 5.3.0_rollup@1.32.1 + rollup-plugin-visualizer: 4.0.4_rollup@1.32.1 + sinon: 9.0.2 + tslib: 2.0.0 + typescript: 3.9.6 + dev: false + name: '@rush-temp/communication-administration' + resolution: + integrity: sha512-7R+ATtNKPhFhlmIncfs+zLaZOT8K8gYG4OZQxeU4Q1w6upb6D3hLROYRHj7peUOkJ1uqr3/Kq+JetTCzG1uRnQ== + tarball: 'file:projects/communication-administration.tgz' + version: 0.0.0 + 'file:projects/communication-chat.tgz': + dependencies: + '@azure/communication-signaling': 1.0.0-beta.1 + '@azure/core-tracing': 1.0.0-preview.9 + '@microsoft/api-extractor': 7.7.11 + '@opentelemetry/api': 0.10.2 + '@rollup/plugin-commonjs': 11.0.2_rollup@1.32.1 + '@rollup/plugin-json': 4.1.0_rollup@1.32.1 + '@rollup/plugin-multi-entry': 3.0.1_rollup@1.32.1 + '@rollup/plugin-node-resolve': 8.1.0_rollup@1.32.1 + '@rollup/plugin-replace': 2.3.3_rollup@1.32.1 + '@types/chai': 4.2.11 + '@types/mocha': 7.0.2 + '@types/node': 8.10.61 + '@types/sinon': 9.0.4 + '@typescript-eslint/eslint-plugin': 2.34.0_3787943315ebc5ea524d5c102dc9e452 + '@typescript-eslint/parser': 2.34.0_eslint@6.8.0+typescript@3.9.6 + assert: 1.5.0 + chai: 4.2.0 + cross-env: 7.0.2 + dotenv: 8.2.0 + eslint: 6.8.0 + eslint-config-prettier: 6.11.0_eslint@6.8.0 + eslint-plugin-no-null: 1.0.2_eslint@6.8.0 + eslint-plugin-no-only-tests: 2.4.0 + eslint-plugin-promise: 4.2.1 + events: 3.1.0 + inherits: 2.0.4 + karma: 5.1.1 + karma-chrome-launcher: 3.1.0 + karma-coverage: 2.0.2 + karma-edge-launcher: 0.4.2_karma@5.1.1 + karma-env-preprocessor: 0.1.1 + karma-firefox-launcher: 1.3.0 + karma-ie-launcher: 1.0.0_karma@5.1.1 + karma-json-preprocessor: 0.3.3_karma@5.1.1 + karma-json-to-file-reporter: 1.0.1 + karma-junit-reporter: 2.0.1_karma@5.1.1 + karma-mocha: 2.0.1 + karma-mocha-reporter: 2.2.5_karma@5.1.1 + karma-remap-istanbul: 0.6.0_karma@5.1.1 + mocha: 7.2.0 + mocha-junit-reporter: 1.23.3_mocha@7.2.0 + prettier: 1.19.1 + rimraf: 3.0.2 + rollup: 1.32.1 + rollup-plugin-shim: 1.0.0 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.32.1 + rollup-plugin-terser: 5.3.0_rollup@1.32.1 + rollup-plugin-visualizer: 4.0.4_rollup@1.32.1 + sinon: 9.0.2 + tslib: 2.0.0 + typescript: 3.9.6 + util: 0.12.3 + dev: false + name: '@rush-temp/communication-chat' + resolution: + integrity: sha512-GqsE5L/Y6v/ZUWjHu/1cEqSgdbVOwyH7bq3Bc1MFtaTz5hYyE1MlXTgMkKijZqUzJR8ETbPtv6YhCM8oISqHgw== + tarball: 'file:projects/communication-chat.tgz' + version: 0.0.0 + 'file:projects/communication-common.tgz': + dependencies: + '@microsoft/api-extractor': 7.7.11 + '@opentelemetry/api': 0.10.2 + '@rollup/plugin-commonjs': 11.0.2_rollup@1.32.1 + '@rollup/plugin-json': 4.1.0_rollup@1.32.1 + '@rollup/plugin-multi-entry': 3.0.1_rollup@1.32.1 + '@rollup/plugin-node-resolve': 8.1.0_rollup@1.32.1 + '@rollup/plugin-replace': 2.3.3_rollup@1.32.1 + '@types/chai': 4.2.11 + '@types/chai-as-promised': 7.1.3 + '@types/jwt-decode': 2.2.1 + '@types/mocha': 7.0.2 + '@types/node': 8.10.61 + '@types/sinon': 9.0.4 + '@typescript-eslint/eslint-plugin': 2.34.0_3787943315ebc5ea524d5c102dc9e452 + '@typescript-eslint/parser': 2.34.0_eslint@6.8.0+typescript@3.9.6 + assert: 1.5.0 + chai: 4.2.0 + chai-as-promised: 7.1.1_chai@4.2.0 + cross-env: 7.0.2 + eslint: 6.8.0 + eslint-config-prettier: 6.11.0_eslint@6.8.0 + eslint-plugin-no-null: 1.0.2_eslint@6.8.0 + eslint-plugin-no-only-tests: 2.4.0 + eslint-plugin-promise: 4.2.1 + events: 3.1.0 + inherits: 2.0.4 + jwt-decode: 2.2.0 + karma: 5.1.1 + karma-chrome-launcher: 3.1.0 + karma-coverage: 2.0.2 + karma-edge-launcher: 0.4.2_karma@5.1.1 + karma-env-preprocessor: 0.1.1 + karma-firefox-launcher: 1.3.0 + karma-ie-launcher: 1.0.0_karma@5.1.1 + karma-junit-reporter: 2.0.1_karma@5.1.1 + karma-mocha: 2.0.1 + karma-mocha-reporter: 2.2.5_karma@5.1.1 + karma-remap-istanbul: 0.6.0_karma@5.1.1 + mocha: 7.2.0 + mocha-junit-reporter: 1.23.3_mocha@7.2.0 + prettier: 1.19.1 + rimraf: 3.0.2 + rollup: 1.32.1 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.32.1 + rollup-plugin-terser: 5.3.0_rollup@1.32.1 + rollup-plugin-visualizer: 4.0.4_rollup@1.32.1 + sinon: 9.0.2 + tslib: 2.0.0 + typescript: 3.9.6 + util: 0.12.3 + dev: false + name: '@rush-temp/communication-common' + resolution: + integrity: sha512-zDlM6WQ2IuIfgNEtzboy0XkFyD/iq/sroDDE7ZoSjUeUvd1NC6r4gf9Sie4IhaNZDDD5iwICBuq2AsNOvogtLw== + tarball: 'file:projects/communication-common.tgz' + version: 0.0.0 + 'file:projects/communication-sms.tgz': + dependencies: + '@azure/core-tracing': 1.0.0-preview.9 + '@microsoft/api-extractor': 7.7.11 + '@opentelemetry/api': 0.10.2 + '@rollup/plugin-commonjs': 11.0.2_rollup@1.32.1 + '@rollup/plugin-json': 4.1.0_rollup@1.32.1 + '@rollup/plugin-multi-entry': 3.0.1_rollup@1.32.1 + '@rollup/plugin-node-resolve': 8.1.0_rollup@1.32.1 + '@rollup/plugin-replace': 2.3.3_rollup@1.32.1 + '@types/chai': 4.2.11 + '@types/mocha': 7.0.2 + '@types/node': 8.10.61 + '@types/sinon': 9.0.4 + '@typescript-eslint/eslint-plugin': 2.34.0_3787943315ebc5ea524d5c102dc9e452 + '@typescript-eslint/parser': 2.34.0_eslint@6.8.0+typescript@3.9.6 + assert: 1.5.0 + chai: 4.2.0 + cross-env: 7.0.2 + dotenv: 8.2.0 + eslint: 6.8.0 + eslint-config-prettier: 6.11.0_eslint@6.8.0 + eslint-plugin-no-null: 1.0.2_eslint@6.8.0 + eslint-plugin-no-only-tests: 2.4.0 + eslint-plugin-promise: 4.2.1 + events: 3.1.0 + inherits: 2.0.4 + karma: 5.1.1 + karma-chrome-launcher: 3.1.0 + karma-coverage: 2.0.2 + karma-edge-launcher: 0.4.2_karma@5.1.1 + karma-env-preprocessor: 0.1.1 + karma-firefox-launcher: 1.3.0 + karma-ie-launcher: 1.0.0_karma@5.1.1 + karma-junit-reporter: 2.0.1_karma@5.1.1 + karma-mocha: 2.0.1 + karma-mocha-reporter: 2.2.5_karma@5.1.1 + karma-remap-istanbul: 0.6.0_karma@5.1.1 + mocha: 7.2.0 + mocha-junit-reporter: 1.23.3_mocha@7.2.0 + prettier: 1.19.1 + rimraf: 3.0.2 + rollup: 1.32.1 + rollup-plugin-shim: 1.0.0 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.32.1 + rollup-plugin-terser: 5.3.0_rollup@1.32.1 + rollup-plugin-visualizer: 4.0.4_rollup@1.32.1 + sinon: 9.0.2 + tslib: 2.0.0 + typescript: 3.9.6 + util: 0.12.3 + dev: false + name: '@rush-temp/communication-sms' + resolution: + integrity: sha512-lQoSU2BOticoPyB2JTgjCp7Mxe34Y/0wDBPBcgyxB42A/YM0R0ZoMuELN7AFJ/XEMzCWLIIqVMDMLPCQtgNbxQ== + tarball: 'file:projects/communication-sms.tgz' + version: 0.0.0 'file:projects/core-amqp.tgz': dependencies: '@azure/identity': 1.1.0 @@ -8836,7 +9163,7 @@ packages: dev: false name: '@rush-temp/cosmos' resolution: - integrity: sha512-n2thQR98RdP6LVfeW9NbiW787UK+JJjZEe7JbgMqbrehiMCBynmPkEY38rgYhlklxwpQDPS8nUir1NFNZlx/fQ== + integrity: sha512-tkGeW5NMFi/1REwH/01mOKnzGUXyCBs8Zjq28esn6R0pA1vUhoNjVp4bqojqGogYme0SHdqNnWgDjFh+y0OLqQ== tarball: 'file:projects/cosmos.tgz' version: 0.0.0 'file:projects/data-tables.tgz': @@ -10493,6 +10820,10 @@ specifiers: '@rush-temp/ai-form-recognizer': 'file:./projects/ai-form-recognizer.tgz' '@rush-temp/ai-text-analytics': 'file:./projects/ai-text-analytics.tgz' '@rush-temp/app-configuration': 'file:./projects/app-configuration.tgz' + '@rush-temp/communication-administration': 'file:./projects/communication-administration.tgz' + '@rush-temp/communication-chat': 'file:./projects/communication-chat.tgz' + '@rush-temp/communication-common': 'file:./projects/communication-common.tgz' + '@rush-temp/communication-sms': 'file:./projects/communication-sms.tgz' '@rush-temp/core-amqp': 'file:./projects/core-amqp.tgz' '@rush-temp/core-arm': 'file:./projects/core-arm.tgz' '@rush-temp/core-asynciterator-polyfill': 'file:./projects/core-asynciterator-polyfill.tgz' diff --git a/eng/.docsettings.yml b/eng/.docsettings.yml index 586305ee5d71..2a61957e3f61 100644 --- a/eng/.docsettings.yml +++ b/eng/.docsettings.yml @@ -3,6 +3,7 @@ omitted_paths: - eng/* - sdk/*/arm-* - sdk/cognitiveservices/* + - sdk/communication/*/test/README.md - sdk/identity/identity/test/manual/* - sdk/identity/identity/test/manual-integration/* - sdk/test-utils/perfstress/README.md diff --git a/eng/pipelines/templates/steps/analyze.yml b/eng/pipelines/templates/steps/analyze.yml index 923eb17dd8c4..3a3ff719c5a1 100644 --- a/eng/pipelines/templates/steps/analyze.yml +++ b/eng/pipelines/templates/steps/analyze.yml @@ -50,11 +50,11 @@ steps: displayName: "Audit libraries" - ${{ each artifact in parameters.Artifacts }}: - - template: /eng/common/pipelines/templates/steps/verify-changelog.yml - parameters: - PackageName: ${{artifact.name}} - ServiceName: ${{parameters.ServiceDirectory}} - ForRelease: false + - template: /eng/common/pipelines/templates/steps/verify-changelog.yml + parameters: + PackageName: ${{artifact.name}} + ServiceName: ${{parameters.ServiceDirectory}} + ForRelease: false - task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0 # ComponentGovernance is currently unable to run on pull requests of public projects. Running on non-PR diff --git a/eng/pipelines/templates/steps/build.yml b/eng/pipelines/templates/steps/build.yml index db710484e695..3fc74e6d0f1b 100644 --- a/eng/pipelines/templates/steps/build.yml +++ b/eng/pipelines/templates/steps/build.yml @@ -30,7 +30,7 @@ steps: displayName: "Build libraries" - pwsh: | - eng/tools/check-api-warning.ps1 + eng/tools/check-api-warning.ps1 displayName: "Check api extractor output changes" - script: | diff --git a/eng/pipelines/templates/steps/test.yml b/eng/pipelines/templates/steps/test.yml index 4ba60e080cd2..0e1b1b857d73 100644 --- a/eng/pipelines/templates/steps/test.yml +++ b/eng/pipelines/templates/steps/test.yml @@ -1,7 +1,7 @@ parameters: Artifacts: [] ServiceDirectory: not-specified - + steps: - script: | node common/scripts/install-run-rush.js install @@ -27,7 +27,7 @@ steps: node eng/tools/rush-runner.js unit-test:node "${{parameters.ServiceDirectory}}" --verbose -p max displayName: "Test libraries" condition: and(succeeded(),eq(variables['TestType'], 'node')) - + # Option "-p max" ensures parallelism is set to the number of cores on all platforms, which improves build times. # The default on Windows is "cores - 1" (microsoft/rushstack#436). - script: | @@ -56,7 +56,7 @@ steps: # PublishTestResults.searchFolder only supports absolute paths, not relative. - task: PublishTestResults@2 inputs: - searchFolder: '$(System.DefaultWorkingDirectory)/sdk' + searchFolder: "$(System.DefaultWorkingDirectory)/sdk" testResultsFiles: "**/test-results.xml" testRunTitle: "$(OSName) - NodeJS - Unit Tests - [Node $(NodeTestVersion)]" condition: and(always(),eq(variables['TestType'], 'node')) @@ -66,7 +66,7 @@ steps: # PublishTestResults.searchFolder only supports absolute paths, not relative. - task: PublishTestResults@2 inputs: - searchFolder: '$(System.DefaultWorkingDirectory)/sdk' + searchFolder: "$(System.DefaultWorkingDirectory)/sdk" testResultsFiles: "**/test-results.browser.xml" testRunTitle: "$(OSName) - Browser - Unit Tests - [Node $(NodeTestVersion)]" condition: and(always(),eq(variables['TestType'], 'browser')) diff --git a/rush.json b/rush.json index c816a9e34d11..299959b1616c 100644 --- a/rush.json +++ b/rush.json @@ -352,6 +352,26 @@ "projectFolder": "sdk/search/search-documents", "versionPolicyName": "client" }, + { + "packageName": "@azure/communication-administration", + "projectFolder": "sdk/communication/communication-administration", + "versionPolicyName": "client" + }, + { + "packageName": "@azure/communication-chat", + "projectFolder": "sdk/communication/communication-chat", + "versionPolicyName": "client" + }, + { + "packageName": "@azure/communication-common", + "projectFolder": "sdk/communication/communication-common", + "versionPolicyName": "client" + }, + { + "packageName": "@azure/communication-sms", + "projectFolder": "sdk/communication/communication-sms", + "versionPolicyName": "client" + }, { "packageName": "@azure/core-amqp", "projectFolder": "sdk/core/core-amqp", diff --git a/sdk/communication/ci.yml b/sdk/communication/ci.yml index ef575364c3b3..07fa45913f7a 100644 --- a/sdk/communication/ci.yml +++ b/sdk/communication/ci.yml @@ -26,3 +26,11 @@ extends: parameters: ServiceDirectory: communication Artifacts: + - name: azure-communication-common + safeName: azurecommunicationcommon + - name: azure-communication-administration + safeName: azurecommunicationadministration + - name: azure-communication-sms + safeName: azurecommunicationsms + - name: azure-communication-chat + safeName: azurecommunicationchat diff --git a/sdk/communication/communication-administration/.eslintrc.json b/sdk/communication/communication-administration/.eslintrc.json new file mode 100644 index 000000000000..9bd67fdc87a5 --- /dev/null +++ b/sdk/communication/communication-administration/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "plugins": ["@azure/azure-sdk"], + "extends": ["plugin:@azure/azure-sdk/azure-sdk-base"], + "rules": { + "@azure/azure-sdk/ts-naming-options": "off" + // "@azure/azure-sdk/ts-config-declaration": "off", + // "@azure/azure-sdk/ts-config-allowsyntheticdefaultimports": "off", + // "@azure/azure-sdk/ts-config-esmoduleinterop": "off", + // "@azure/azure-sdk/ts-config-forceconsistentcasinginfilenames": "off", + // "@azure/azure-sdk/ts-config-importhelpers": "off", + // "@azure/azure-sdk/ts-config-module": "off", + // "@azure/azure-sdk/ts-config-moduleresolution": "off", + // "@azure/azure-sdk/ts-config-sourcemap": "off", + // "@azure/azure-sdk/ts-config-strict": "off", + // "@azure/azure-sdk/ts-config-target": "off", + // "@azure/azure-sdk/ts-config-lib": "off" + } +} diff --git a/sdk/communication/communication-administration/.gitignore b/sdk/communication/communication-administration/.gitignore new file mode 100644 index 000000000000..5480375639b4 --- /dev/null +++ b/sdk/communication/communication-administration/.gitignore @@ -0,0 +1,2 @@ +/**/code-model-v* +/docGen \ No newline at end of file diff --git a/sdk/communication/communication-administration/.vscode/launch.json b/sdk/communication/communication-administration/.vscode/launch.json new file mode 100644 index 000000000000..0838e97b6317 --- /dev/null +++ b/sdk/communication/communication-administration/.vscode/launch.json @@ -0,0 +1,42 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "node", + "request": "launch", + "name": "Debug Mocha Test [Without Rollup]", + "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha", + "args": [ + "-r", + "ts-node/register", + "--timeout", + "999999", + "--colors", + "${workspaceFolder}/test/*.spec.ts" + ], + "env": { "TS_NODE_COMPILER_OPTIONS": "{\"module\": \"commonjs\"}" }, + "console": "integratedTerminal", + "internalConsoleOptions": "neverOpen", + "protocol": "inspector" + }, + { + "type": "node", + "request": "launch", + "name": "Debug Unit Tests", + "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha", + "args": [ + "-u", + "tdd", + "--timeout", + "999999", + "--colors", + "${workspaceFolder}/dist-test/index.node.js" + ], + "internalConsoleOptions": "openOnSessionStart", + "preLaunchTask": "npm: build:test" + } + ] +} diff --git a/sdk/communication/communication-administration/CHANGELOG.md b/sdk/communication/communication-administration/CHANGELOG.md new file mode 100644 index 000000000000..88388cb04159 --- /dev/null +++ b/sdk/communication/communication-administration/CHANGELOG.md @@ -0,0 +1,5 @@ +# Release History + +## 1.0.0-beta.1 (2020-09-22) + +The Azure Communication Administration Client library contains code which facilitates user token administration. diff --git a/sdk/communication/communication-administration/LICENSE b/sdk/communication/communication-administration/LICENSE new file mode 100644 index 000000000000..ea8fb1516028 --- /dev/null +++ b/sdk/communication/communication-administration/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2020 Microsoft + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/sdk/communication/communication-administration/README.md b/sdk/communication/communication-administration/README.md new file mode 100644 index 000000000000..4b8b55f1d73a --- /dev/null +++ b/sdk/communication/communication-administration/README.md @@ -0,0 +1,83 @@ +# Azure Communication Administration client library for JavaScript + +The Azure Communication Administration library lets the developer create/delete users and issue tokens for Communication Services. Users and tokens can then be used when adding Chat or Calling to an app. + +## Getting started + +### Prerequisites + +- An [Azure subscription][azure_sub]. +- An existing Communication Services resource. If you need to create the resource, you can use the [Azure Portal][azure_portal] or [Azure CLI][azure_cli]. + +### Installing + +```bash +npm install @azure/communication-administration +``` + +## Key concepts + +### CommunicationIdentityClient + +`CommunicationIdentityClient` provides methods to manage users and their tokens. + +## Examples + +## Authentication + +You can get a key and/or connection string from your Communication Services resource in [Azure Portal][azure_portal]. Once you have a key, you may authenticate with any of the following methods: + +### Create `KeyCredential` with `AzureKeyCredential` before initializing CommunicationIdentityClient + +```typescript +import { AzureKeyCredential } from "@azure/core-auth"; +import { CommunicationIdentityClient } from "@azure/communication-administration"; + +const credential = new AzureKeyCredential(KEY); +const client = new CommunicationIdentityClient(HOST, credential); +``` + +### Using a connection string + +```typescript +import { CommunicationIdentityClient } from "@azure/communication-administration"; + +const connectionString = `endpoint=HOST;accessKey=KEY`; +const client = new CommunicationIdentityClient(connectionString); +``` + +## Usage + +### Create a user and token + +Here we create an instance of the `CommunicationIdentityClient` class, create a user, then issue a chat scoped token for the user. + +```typescript +import { CommunicationIdentityClient } from "@azure/communication-administration"; + +const client = new CommunicationIdentityClient(CONNECTION_STRING); +const user = await client.createUser(); +const { token } = await client.issueToken(user, ["chat"]); +``` + +## Troubleshooting + +## Next steps + +Please take a look at the +[samples] +directory for detailed examples on how to use this library. + +## Contributing + +If you'd like to contribute to this library, please read the [contributing guide](https://github.com/Azure/azure-sdk-for-js/blob/master/CONTRIBUTING.md) to learn more about how to build and test the code. + +## Related projects + +- [Microsoft Azure SDK for Javascript](https://github.com/Azure/azure-sdk-for-js) + +[azure_cli]: https://docs.microsoft.com/cli/azure +[azure_sub]: https://azure.microsoft.com/free/ +[azure_portal]: https://portal.azure.com + +![Impressions](https://azure-sdk-impressions.azurewebsites.net/api/impressions/azure-sdk-for-js%2Fsdk%2Fcommunication%2Fcommunication-administration%2FREADME.png) diff --git a/sdk/communication/communication-administration/api-extractor.json b/sdk/communication/communication-administration/api-extractor.json new file mode 100644 index 000000000000..641582682b45 --- /dev/null +++ b/sdk/communication/communication-administration/api-extractor.json @@ -0,0 +1,35 @@ +{ + "$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/communication-administration.d.ts" + }, + "messages": { + "tsdocMessageReporting": { + "default": { + "logLevel": "none" + } + }, + "extractorMessageReporting": { + "ae-forgotten-export": { + "logLevel": "error", + "addToApiReportFile": false + }, + "ae-missing-release-tag": { + "logLevel": "none" + }, + "ae-unresolved-link": { + "logLevel": "error" + } + } + } +} diff --git a/sdk/communication/communication-administration/karma.conf.js b/sdk/communication/communication-administration/karma.conf.js new file mode 100644 index 000000000000..8e53409cf259 --- /dev/null +++ b/sdk/communication/communication-administration/karma.conf.js @@ -0,0 +1,144 @@ +// https://github.com/karma-runner/karma-chrome-launcher +process.env.CHROME_BIN = require("puppeteer").executablePath(); +require("dotenv").config(); +const { + jsonRecordingFilterFunction, + isPlaybackMode, + isSoftRecordMode, + isRecordMode +} = require("@azure/test-utils-recorder"); + +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: ["mocha"], + + plugins: [ + "karma-mocha", + "karma-mocha-reporter", + "karma-chrome-launcher", + "karma-edge-launcher", + "karma-firefox-launcher", + "karma-ie-launcher", + "karma-env-preprocessor", + "karma-coverage", + "karma-remap-istanbul", + "karma-junit-reporter", + "karma-json-to-file-reporter", + "karma-json-preprocessor" + ], + + // list of files / patterns to load in the browser + files: [ + // Uncomment the cdn link below for the polyfill service to support IE11 missing features + // Promise,String.prototype.startsWith,String.prototype.endsWith,String.prototype.repeat,String.prototype.includes,Array.prototype.includes,Object.keys + // "https://cdn.polyfill.io/v2/polyfill.js?features=Symbol,Promise,String.prototype.startsWith,String.prototype.endsWith,String.prototype.repeat,String.prototype.includes,Array.prototype.includes,Object.keys|always", + "dist-test/index.browser.js" + ].concat(isPlaybackMode() || isSoftRecordMode() ? ["recordings/browsers/**/*.json"] : []), + + // 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": ["env"], + "recordings/browsers/**/*.json": ["json"] + // 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 + //"test-browser/index.js": ["coverage"] + }, + + // inject following environment values into browser testing with window.__env__ + // environment values MUST be exported or set with same console running "karma start" + // https://www.npmjs.com/package/karma-env-preprocessor + envPreprocessor: ["TEST_MODE", "COMMUNICATION_CONNECTION_STRING"], + + // test results reporter to use + // possible values: 'dots', 'progress' + // available reporters: https://npmjs.org/browse/keyword/karma-reporter + reporters: ["mocha", "coverage", "karma-remap-istanbul", "junit", "json-to-file"], + + coverageReporter: { + // specify a common output directory + dir: "coverage-browser/", + reporters: [ + { + type: "json", + subdir: ".", + file: "coverage.json" + } + ] + }, + + remapIstanbulReporter: { + src: "coverage-browser/coverage.json", + reports: { + lcovonly: "coverage-browser/lcov.info", + html: "coverage-browser/html/report", + "text-summary": null, + cobertura: "./coverage-browser/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 + }, + + jsonToFileReporter: { + filter: jsonRecordingFilterFunction, + outputPath: "." + }, + + // 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, + + // start these browsers + // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher + // 'ChromeHeadless', 'Chrome', 'Firefox', 'Edge', 'IE' + browsers: ["ChromeHeadless"], + + // Continuous Integration mode + // if true, Karma captures browsers, runs the tests and exits + singleRun: true, + + // Concurrency level + // how many browser should be started simultaneous + concurrency: 1, + + browserNoActivityTimeout: 600000, + browserDisconnectTimeout: 10000, + browserDisconnectTolerance: 3, + browserConsoleLogOptions: { + terminal: !isRecordMode() + }, + + client: { + mocha: { + // change Karma's debug.html to the mocha web reporter + reporter: "html", + timeout: "600000" + } + } + }); +}; diff --git a/sdk/communication/communication-administration/package.json b/sdk/communication/communication-administration/package.json new file mode 100644 index 000000000000..c90eaac76870 --- /dev/null +++ b/sdk/communication/communication-administration/package.json @@ -0,0 +1,125 @@ +{ + "name": "@azure/communication-administration", + "version": "1.0.0-beta.1", + "description": "SDK for Azure Communication service which facilitates user token administration.", + "sdk-type": "client", + "main": "dist/index.js", + "module": "dist-esm/src/index.js", + "types": "types/communication-administration.d.ts", + "scripts": { + "audit": "node ../../../common/scripts/rush-audit.js && rimraf node_modules package-lock.json && npm i --package-lock-only 2>&1 && npm audit", + "build": "tsc -p . && rollup -c 2>&1 && api-extractor run --local", + "build:autorest": "autorest --typescript --v3 ./swagger/CommunicationIdentity.md && rushx format", + "build:clean": "rush update --recheck && rush rebuild && npm run build", + "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": "dev-tool samples prep && cd dist-samples && tsc -p .", + "build:test": "tsc -p . && rollup -c rollup.test.config.js 2>&1", + "check-format": "prettier --list-different \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", + "clean": "rimraf dist dist-* types *.tgz *.log", + "execute:samples": "npm run build:samples && dev-tool samples run dist-samples/javascript dist-samples/typescript/dist/dist-samples/typescript/src/", + "extract-api": "tsc -p . && api-extractor run --local", + "format": "prettier --write \"recordings/**/*.{js,json}\" \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", + "generate-doc": "api-documenter markdown -i temp -o docGen", + "integration-test:browser": "echo integration-test:browser skipped", + "integration-test:node": "echo integration-test:node skipped", + "integration-test": "npm run integration-test:node && npm run integration-test:browser", + "lint:fix": "eslint package.json tsconfig.json api-extractor.json src test --ext .ts --fix --fix-type [problem,suggestion]", + "lint": "eslint package.json tsconfig.json api-extractor.json src test --ext .ts -f html -o communication-administration-lintReport.html || exit 0", + "pack": "npm pack 2>&1", + "prebuild": "npm run clean", + "test": "npm run build:test && npm run unit-test && npm run integration-test", + "test:browser": "npm run build:test && npm run unit-test:browser && npm run integration-test:browser", + "test:node": "npm run build:test && npm run unit-test:node && npm run integration-test:node", + "test:watch": "npm run test -- --watch --reporter min", + "unit-test:browser": "karma start --single-run", + "unit-test:node": "mocha --reporter ../../../common/tools/mocha-multi-reporter.js dist-test/index.node.js", + "unit-test": "npm run unit-test:node && npm run unit-test:browser" + }, + "files": [ + "dist/", + "dist-browser/", + "dist-esm/src/", + "types/communication-administration.d.ts", + "README.md", + "LICENSE" + ], + "keywords": [ + "Azure", + "cloud", + "communication" + ], + "author": "Microsoft Corporation", + "license": "MIT", + "engines": { + "node": ">=8.0.0" + }, + "homepage": "https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/communication/communication-administration/", + "sideEffects": false, + "prettier": "@azure/eslint-plugin-azure-sdk/prettier.json", + "dependencies": { + "@azure/communication-common": "1.0.0-beta.1", + "@azure/core-auth": "^1.1.3", + "@azure/core-http": "^1.1.6", + "@azure/core-paging": "^1.1.1", + "@azure/logger": "^1.0.0", + "@azure/core-tracing": "1.0.0-preview.9", + "@opentelemetry/api": "^0.10.2", + "events": "^3.0.0", + "tslib": "^2.0.0" + }, + "devDependencies": { + "@azure/dev-tool": "^1.0.0", + "@azure/eslint-plugin-azure-sdk": "^3.0.0", + "@azure/test-utils-recorder": "^1.0.0", + "@microsoft/api-documenter": "~7.8.17", + "@microsoft/api-extractor": "7.7.11", + "@rollup/plugin-commonjs": "11.0.2", + "@rollup/plugin-json": "^4.0.0", + "@rollup/plugin-multi-entry": "^3.0.0", + "@rollup/plugin-node-resolve": "^8.0.0", + "@rollup/plugin-replace": "^2.2.0", + "@types/chai": "^4.1.6", + "@types/mocha": "^7.0.2", + "@types/sinon": "^9.0.4", + "@types/node": "^8.0.0", + "@typescript-eslint/eslint-plugin": "^2.0.0", + "@typescript-eslint/parser": "^2.0.0", + "assert": "^1.4.1", + "chai": "^4.2.0", + "cross-env": "^7.0.2", + "dotenv": "^8.2.0", + "eslint-config-prettier": "^6.0.0", + "eslint-plugin-no-null": "^1.0.2", + "eslint-plugin-no-only-tests": "^2.3.0", + "eslint-plugin-prefer-arrow": "~1.2.0", + "eslint-plugin-promise": "^4.1.1", + "eslint": "^6.1.0", + "inherits": "^2.0.3", + "karma-chrome-launcher": "^3.0.0", + "karma-coverage": "^2.0.0", + "karma-edge-launcher": "^0.4.2", + "karma-env-preprocessor": "^0.1.1", + "karma-firefox-launcher": "^1.1.0", + "karma-ie-launcher": "^1.0.0", + "karma-json-preprocessor": "^0.3.3", + "karma-json-to-file-reporter": "^1.0.1", + "karma-junit-reporter": "^2.0.1", + "karma-mocha-reporter": "^2.2.5", + "karma-mocha": "^2.0.1", + "karma-remap-istanbul": "^0.6.0", + "karma": "^5.1.0", + "mocha-junit-reporter": "^1.18.0", + "mocha": "^7.1.1", + "node-fetch": "^2.6.0", + "prettier": "^1.16.4", + "rimraf": "^3.0.0", + "rollup-plugin-sourcemaps": "^0.4.2", + "rollup-plugin-terser": "^5.1.1", + "rollup-plugin-visualizer": "^4.0.4", + "rollup-plugin-shim": "^1.0.0", + "rollup": "^1.16.3", + "sinon": "^9.0.2", + "typescript": "~3.9.3" + } +} diff --git a/sdk/communication/communication-administration/recordings/browsers/communicationidentityclient_playbacklive/recording_successfully_creates_a_user.json b/sdk/communication/communication-administration/recordings/browsers/communicationidentityclient_playbacklive/recording_successfully_creates_a_user.json new file mode 100644 index 000000000000..f44b55201cf3 --- /dev/null +++ b/sdk/communication/communication-administration/recordings/browsers/communicationidentityclient_playbacklive/recording_successfully_creates_a_user.json @@ -0,0 +1,22 @@ +{ + "recordings": [ + { + "method": "POST", + "url": "https://endpoint/identities", + "query": { + "api-version": "2020-07-20-preview2" + }, + "requestBody": null, + "status": 200, + "response": "{\"id\":\"sanitized\"}", + "responseHeaders": { + "content-type": "application/json; charset=utf-8" + } + } + ], + "uniqueTestInfo": { + "uniqueName": {}, + "newDate": {} + }, + "hash": "27d09bb5f8e19a5b9a886691bbe0c28c" +} diff --git a/sdk/communication/communication-administration/recordings/browsers/communicationidentityclient_playbacklive/recording_successfully_deletes_a_user.json b/sdk/communication/communication-administration/recordings/browsers/communicationidentityclient_playbacklive/recording_successfully_deletes_a_user.json new file mode 100644 index 000000000000..6544834afeac --- /dev/null +++ b/sdk/communication/communication-administration/recordings/browsers/communicationidentityclient_playbacklive/recording_successfully_deletes_a_user.json @@ -0,0 +1,20 @@ +{ + "recordings": [ + { + "method": "DELETE", + "url": "https://endpoint/identities/sanitized", + "query": { + "api-version": "2020-07-20-preview2" + }, + "requestBody": null, + "status": 204, + "response": "", + "responseHeaders": {} + } + ], + "uniqueTestInfo": { + "uniqueName": {}, + "newDate": {} + }, + "hash": "23307718ae010385eb18d4ce84eb95c9" +} diff --git a/sdk/communication/communication-administration/recordings/browsers/communicationidentityclient_playbacklive/recording_successfully_issues_a_token_for_a_user_multiple_scopes.json b/sdk/communication/communication-administration/recordings/browsers/communicationidentityclient_playbacklive/recording_successfully_issues_a_token_for_a_user_multiple_scopes.json new file mode 100644 index 000000000000..c95b86bb589e --- /dev/null +++ b/sdk/communication/communication-administration/recordings/browsers/communicationidentityclient_playbacklive/recording_successfully_issues_a_token_for_a_user_multiple_scopes.json @@ -0,0 +1,22 @@ +{ + "recordings": [ + { + "method": "POST", + "url": "https://endpoint/identities/sanitized/token", + "query": { + "api-version": "2020-07-20-preview2" + }, + "requestBody": "{\"scopes\":[\"chat\",\"pstn\"]}", + "status": 200, + "response": "{\"id\":\"sanitized\",\"token\":\"sanitized\",\"expiresOn\":\"2020-09-18T17:57:51.2773604+00:00\"}", + "responseHeaders": { + "content-type": "application/json; charset=utf-8" + } + } + ], + "uniqueTestInfo": { + "uniqueName": {}, + "newDate": {} + }, + "hash": "4fcce8a4b300bc164dbce1708fc9ef13" +} diff --git a/sdk/communication/communication-administration/recordings/browsers/communicationidentityclient_playbacklive/recording_successfully_issues_a_token_for_a_user_single_scope.json b/sdk/communication/communication-administration/recordings/browsers/communicationidentityclient_playbacklive/recording_successfully_issues_a_token_for_a_user_single_scope.json new file mode 100644 index 000000000000..1a91970393b5 --- /dev/null +++ b/sdk/communication/communication-administration/recordings/browsers/communicationidentityclient_playbacklive/recording_successfully_issues_a_token_for_a_user_single_scope.json @@ -0,0 +1,22 @@ +{ + "recordings": [ + { + "method": "POST", + "url": "https://endpoint/identities/sanitized/token", + "query": { + "api-version": "2020-07-20-preview2" + }, + "requestBody": "{\"scopes\":[\"chat\"]}", + "status": 200, + "response": "{\"id\":\"sanitized\",\"token\":\"sanitized\",\"expiresOn\":\"2020-09-18T17:57:51.218834+00:00\"}", + "responseHeaders": { + "content-type": "application/json; charset=utf-8" + } + } + ], + "uniqueTestInfo": { + "uniqueName": {}, + "newDate": {} + }, + "hash": "778874dd07d653a79561fb2d94cb0b86" +} diff --git a/sdk/communication/communication-administration/recordings/browsers/communicationidentityclient_playbacklive/recording_successfully_revokes_tokens_issued_for_a_user.json b/sdk/communication/communication-administration/recordings/browsers/communicationidentityclient_playbacklive/recording_successfully_revokes_tokens_issued_for_a_user.json new file mode 100644 index 000000000000..7b52bb71a782 --- /dev/null +++ b/sdk/communication/communication-administration/recordings/browsers/communicationidentityclient_playbacklive/recording_successfully_revokes_tokens_issued_for_a_user.json @@ -0,0 +1,20 @@ +{ + "recordings": [ + { + "method": "PATCH", + "url": "https://endpoint/identities/sanitized", + "query": { + "api-version": "2020-07-20-preview2" + }, + "requestBody": "{\"tokensValidFrom\":\"2020-10-10T00:00:00.000Z\"}", + "status": 204, + "response": "", + "responseHeaders": {} + } + ], + "uniqueTestInfo": { + "uniqueName": {}, + "newDate": {} + }, + "hash": "568db7fa8e03c8fc44cc0f90faaa974f" +} diff --git a/sdk/communication/communication-administration/recordings/node/communicationidentityclient_playbacklive/recording_successfully_creates_a_user.js b/sdk/communication/communication-administration/recordings/node/communicationidentityclient_playbacklive/recording_successfully_creates_a_user.js new file mode 100644 index 000000000000..43503a3a7da2 --- /dev/null +++ b/sdk/communication/communication-administration/recordings/node/communicationidentityclient_playbacklive/recording_successfully_creates_a_user.js @@ -0,0 +1,29 @@ +let nock = require("nock"); + +module.exports.hash = "71dd63e8f90b2c2eb44bc15618466368"; + +module.exports.testInfo = { uniqueName: {}, newDate: {} }; + +nock("https://endpoint", { encodedQueryParams: true }) + .post("/identities") + .query(true) + .reply(200, { id: "sanitized" }, [ + "Transfer-Encoding", + "chunked", + "Content-Type", + "application/json; charset=utf-8", + "MS-CV", + "U+/c6yzuBkqKSc0+kh37Lg.0", + "Strict-Transport-Security", + "max-age=2592000", + "x-ms-client-request-id", + "e3ea5380-0244-42b9-b0a4-a2d63066ad98", + "api-supported-versions", + "2020-07-20-preview1, 2020-07-20-preview2", + "X-Processing-Time", + "82ms", + "X-Azure-Ref", + "0mqNjXwAAAADmbwVtRUg1QoQQ/bHqCd5SWVZSMzBFREdFMDQxMwA5ZmM3YjUxOS1hOGNjLTRmODktOTM1ZS1jOTE0OGFlMDllODE=", + "Date", + "Thu, 17 Sep 2020 17:57:45 GMT" + ]); diff --git a/sdk/communication/communication-administration/recordings/node/communicationidentityclient_playbacklive/recording_successfully_deletes_a_user.js b/sdk/communication/communication-administration/recordings/node/communicationidentityclient_playbacklive/recording_successfully_deletes_a_user.js new file mode 100644 index 000000000000..5d62b3949ae2 --- /dev/null +++ b/sdk/communication/communication-administration/recordings/node/communicationidentityclient_playbacklive/recording_successfully_deletes_a_user.js @@ -0,0 +1,25 @@ +let nock = require("nock"); + +module.exports.hash = "c32f7ebc5af64d902e3e080cc228e00f"; + +module.exports.testInfo = { uniqueName: {}, newDate: {} }; + +nock("https://endpoint", { encodedQueryParams: true }) + .delete("/identities/sanitized") + .query(true) + .reply(204, "", [ + "MS-CV", + "xeaIdBb7TEe5cvxIpes+5A.0", + "Strict-Transport-Security", + "max-age=2592000", + "x-ms-client-request-id", + "5314f3f9-ab0d-4d3c-8373-98e2743d89cd", + "api-supported-versions", + "2020-07-20-preview1, 2020-07-20-preview2", + "X-Processing-Time", + "445ms", + "X-Azure-Ref", + "0vDBhXwAAAABiUEnMD06IS60LcrViuM6+WVZSMzBFREdFMDQxNQA5ZmM3YjUxOS1hOGNjLTRmODktOTM1ZS1jOTE0OGFlMDllODE=", + "Date", + "Tue, 15 Sep 2020 21:23:08 GMT" + ]); diff --git a/sdk/communication/communication-administration/recordings/node/communicationidentityclient_playbacklive/recording_successfully_issues_a_token_for_a_user_multiple_scopes.js b/sdk/communication/communication-administration/recordings/node/communicationidentityclient_playbacklive/recording_successfully_issues_a_token_for_a_user_multiple_scopes.js new file mode 100644 index 000000000000..46d1f356d450 --- /dev/null +++ b/sdk/communication/communication-administration/recordings/node/communicationidentityclient_playbacklive/recording_successfully_issues_a_token_for_a_user_multiple_scopes.js @@ -0,0 +1,33 @@ +let nock = require("nock"); + +module.exports.hash = "f30fde667c7b7a14ab32826e4d83a221"; + +module.exports.testInfo = { uniqueName: {}, newDate: {} }; + +nock("https://endpoint", { encodedQueryParams: true }) + .post("/identities/sanitized/token", { scopes: ["chat", "pstn"] }) + .query(true) + .reply( + 200, + { id: "sanitized", token: "sanitized", expiresOn: "2020-09-18T17:57:45.5545875+00:00" }, + [ + "Transfer-Encoding", + "chunked", + "Content-Type", + "application/json; charset=utf-8", + "MS-CV", + "E+sS3wKjfUSheriVQSe2QA.0", + "Strict-Transport-Security", + "max-age=2592000", + "x-ms-client-request-id", + "9f35ed20-f1ac-46a2-bc6d-0af9b4e06c78", + "api-supported-versions", + "2020-07-20-preview1, 2020-07-20-preview2", + "X-Processing-Time", + "120ms", + "X-Azure-Ref", + "0mqNjXwAAAABMcDEBNfteQKjGaHEc+xytWVZSMzBFREdFMDQwOAA5ZmM3YjUxOS1hOGNjLTRmODktOTM1ZS1jOTE0OGFlMDllODE=", + "Date", + "Thu, 17 Sep 2020 17:57:46 GMT" + ] + ); diff --git a/sdk/communication/communication-administration/recordings/node/communicationidentityclient_playbacklive/recording_successfully_issues_a_token_for_a_user_single_scope.js b/sdk/communication/communication-administration/recordings/node/communicationidentityclient_playbacklive/recording_successfully_issues_a_token_for_a_user_single_scope.js new file mode 100644 index 000000000000..86dfce393e0b --- /dev/null +++ b/sdk/communication/communication-administration/recordings/node/communicationidentityclient_playbacklive/recording_successfully_issues_a_token_for_a_user_single_scope.js @@ -0,0 +1,33 @@ +let nock = require("nock"); + +module.exports.hash = "1c880cc35f2f3b240445a35a012e7bab"; + +module.exports.testInfo = { uniqueName: {}, newDate: {} }; + +nock("https://endpoint", { encodedQueryParams: true }) + .post("/identities/sanitized/token", { scopes: ["chat"] }) + .query(true) + .reply( + 200, + { id: "sanitized", token: "sanitized", expiresOn: "2020-09-18T17:57:45.3830734+00:00" }, + [ + "Transfer-Encoding", + "chunked", + "Content-Type", + "application/json; charset=utf-8", + "MS-CV", + "f94y+F9y70yOnKIRo9ewAA.0", + "Strict-Transport-Security", + "max-age=2592000", + "x-ms-client-request-id", + "76b35c64-7a2c-4876-81a0-0396f8f65f32", + "api-supported-versions", + "2020-07-20-preview1, 2020-07-20-preview2", + "X-Processing-Time", + "70ms", + "X-Azure-Ref", + "0mqNjXwAAAAD+AWsEKavdTbytYp800w86WVZSMzBFREdFMDMwOQA5ZmM3YjUxOS1hOGNjLTRmODktOTM1ZS1jOTE0OGFlMDllODE=", + "Date", + "Thu, 17 Sep 2020 17:57:46 GMT" + ] + ); diff --git a/sdk/communication/communication-administration/recordings/node/communicationidentityclient_playbacklive/recording_successfully_revokes_tokens_issued_for_a_user.js b/sdk/communication/communication-administration/recordings/node/communicationidentityclient_playbacklive/recording_successfully_revokes_tokens_issued_for_a_user.js new file mode 100644 index 000000000000..a12a8c76093a --- /dev/null +++ b/sdk/communication/communication-administration/recordings/node/communicationidentityclient_playbacklive/recording_successfully_revokes_tokens_issued_for_a_user.js @@ -0,0 +1,25 @@ +let nock = require("nock"); + +module.exports.hash = "e10098ac22e2857510889e9c31a45559"; + +module.exports.testInfo = { uniqueName: {}, newDate: {} }; + +nock("https://endpoint", { encodedQueryParams: true }) + .patch("/identities/sanitized", { tokensValidFrom: "2020-10-10T00:00:00.000Z" }) + .query(true) + .reply(204, "", [ + "MS-CV", + "KhF9I7PNKEmPXCM8o/2rzg.0", + "Strict-Transport-Security", + "max-age=2592000", + "x-ms-client-request-id", + "c8722972-96df-49bd-80f3-956313c647b7", + "api-supported-versions", + "2020-07-20-preview1, 2020-07-20-preview2", + "X-Processing-Time", + "645ms", + "X-Azure-Ref", + "0mqNjXwAAAAD2aqka/gd+TYiOFoj9xCZrWVZSMzBFREdFMDMwNwA5ZmM3YjUxOS1hOGNjLTRmODktOTM1ZS1jOTE0OGFlMDllODE=", + "Date", + "Thu, 17 Sep 2020 17:57:46 GMT" + ]); diff --git a/sdk/communication/communication-administration/review/communication-administration.api.md b/sdk/communication/communication-administration/review/communication-administration.api.md new file mode 100644 index 000000000000..7e9329a433a2 --- /dev/null +++ b/sdk/communication/communication-administration/review/communication-administration.api.md @@ -0,0 +1,64 @@ +## API Report File for "@azure/communication-administration" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +import { CommunicationUser } from '@azure/communication-common'; +import { HttpResponse } from '@azure/core-http'; +import { KeyCredential } from '@azure/core-auth'; +import { OperationOptions } from '@azure/core-http'; +import { PipelineOptions } from '@azure/core-http'; + +// @public +export class CommunicationIdentityClient { + constructor(connectionString: string, options?: CommunicationIdentityOptions); + constructor(url: string, credential: KeyCredential, options?: CommunicationIdentityOptions); + createUser(options?: OperationOptions): Promise; + deleteUser(user: CommunicationUser, options?: OperationOptions): Promise; + issueToken(user: CommunicationUser, scopes: TokenScope[], options?: OperationOptions): Promise; + revokeTokens(user: CommunicationUser, tokensValidFrom?: Date, options?: OperationOptions): Promise; +} + +// @public +export interface CommunicationIdentityOptions extends PipelineOptions { +} + +// @public +export interface CommunicationIdentityToken { + expiresOn: Date; + id: string; + token: string; +} + +// @public +export interface CommunicationTokenRequest { + scopes: string[]; +} + +// @public +export interface CommunicationUserToken extends Pick { + user: CommunicationUser; +} + +// @public +export type CreateUserResponse = WithResponse; + +// @public +export type IssueTokenResponse = WithResponse; + +// @public +export type TokenScope = "chat" | "voip" | "pstn"; + +// @public +export type VoidResponse = WithResponse<{}>; + +// @public +export type WithResponse = T & { + _response: HttpResponse; +}; + + +// (No @packageDocumentation comment for this package) + +``` diff --git a/sdk/communication/communication-administration/rollup.base.config.js b/sdk/communication/communication-administration/rollup.base.config.js new file mode 100644 index 000000000000..0e556ce1f12e --- /dev/null +++ b/sdk/communication/communication-administration/rollup.base.config.js @@ -0,0 +1,131 @@ +import path from "path"; +import nodeResolve from "@rollup/plugin-node-resolve"; +import multiEntry from "@rollup/plugin-multi-entry"; +import cjs from "@rollup/plugin-commonjs"; +import replace from "@rollup/plugin-replace"; +import { terser } from "rollup-plugin-terser"; +import sourcemaps from "rollup-plugin-sourcemaps"; +import viz from "rollup-plugin-visualizer"; +import shim from "rollup-plugin-shim"; + +const pkg = require("./package.json"); +const depNames = Object.keys(pkg.dependencies); +const devDepNames = Object.keys(pkg.devDependencies); +const input = "dist-esm/src/index.js"; +const production = process.env.NODE_ENV === "production"; + +export function nodeConfig(test = false) { + const externalNodeBuiltins = ["events", "crypto"]; + const baseConfig = { + input: input, + external: depNames.concat(externalNodeBuiltins), + output: { file: "dist/index.js", format: "cjs", sourcemap: true }, + preserveSymlinks: false, + plugins: [ + sourcemaps(), + replace({ + delimiters: ["", ""], + values: { + // replace dynamic checks with if (true) since this is for node only. + // Allows rollup's dead code elimination to be more aggressive. + "if (isNode)": "if (true)" + } + }), + nodeResolve({ preferBuiltins: true }), + cjs() + ] + }; + + if (test) { + // Entry points - test files under the `test` folder(common for both browser and node), node specific test files + baseConfig.input = ["dist-esm/test/*.spec.js", "dist-esm/test/node/*.spec.js"]; + baseConfig.plugins.unshift(multiEntry({ exports: false })); + + // different output file + baseConfig.output.file = "dist-test/index.node.js"; + + // mark assert as external + baseConfig.external.push("assert", ...devDepNames); + + // Disable tree-shaking of test code. In rollup-plugin-node-resolve@5.0.0, rollup started respecting + // the "sideEffects" field in package.json. Since our package.json sets "sideEffects=false", this also + // applies to test code, which causes all tests to be removed by tree-shaking. + baseConfig.treeshake = false; + } else if (production) { + baseConfig.plugins.push(terser()); + } + + return baseConfig; +} + +export function browserConfig(test = false) { + const baseConfig = { + input: input, + external: ["crypto", "fs-extra"], + output: { + file: "dist-browser/azure-communication-administration.js", + format: "umd", + name: "Azure.Communication.Administration", + sourcemap: true, + globals: { "@azure/core-http": "Azure.Core.HTTP" } + }, + preserveSymlinks: false, + plugins: [ + sourcemaps(), + replace({ + delimiters: ["", ""], + values: { + // replace dynamic checks with if (false) since this is for + // browser only. Rollup's dead code elimination will remove + // any code guarded by if (isNode) { ... } + "if (isNode)": "if (false)" + } + }), + shim({ + constants: `export default {}`, + fs: `export default {}`, + os: `export default {}`, + dotenv: `export function config() { }`, + path: `export default {}` + }), + nodeResolve({ + mainFields: ["module", "browser"], + preferBuiltins: false + }), + cjs({ + namedExports: { + chai: ["assert"], + events: ["EventEmitter"], + "@opentelemetry/api": ["CanonicalCode", "SpanKind", "TraceFlags"] + } + }), + viz({ filename: "dist-browser/browser-stats.html", sourcemap: false }) + ] + }; + + if (test) { + // Entry points - test files under the `test` folder(common for both browser and node), browser specific test files + baseConfig.input = ["dist-esm/test/*.spec.js", "dist-esm/test/browser/*.spec.js"]; + baseConfig.plugins.unshift(multiEntry({ exports: false })); + baseConfig.output.file = "dist-test/index.browser.js"; + + baseConfig.onwarn = (warning) => { + if ( + warning.code === "CIRCULAR_DEPENDENCY" && + warning.importer.indexOf(path.normalize("node_modules/chai/lib") === 0) + ) { + // Chai contains circular references, but they are not fatal and can be ignored. + return; + } + + console.error(`(!) ${warning.message}`); + }; + + // Disable tree-shaking of test code. In rollup-plugin-node-resolve@5.0.0, rollup started respecting + // the "sideEffects" field in package.json. Since our package.json sets "sideEffects=false", this also + // applies to test code, which causes all tests to be removed by tree-shaking. + baseConfig.treeshake = false; + } + + return baseConfig; +} diff --git a/sdk/communication/communication-administration/rollup.config.js b/sdk/communication/communication-administration/rollup.config.js new file mode 100644 index 000000000000..14652aa67ed8 --- /dev/null +++ b/sdk/communication/communication-administration/rollup.config.js @@ -0,0 +1,13 @@ +import * as base from "./rollup.base.config"; + +const inputs = []; + +if (!process.env.ONLY_BROWSER) { + inputs.push(base.nodeConfig()); +} + +if (!process.env.ONLY_NODE) { + inputs.push(base.browserConfig()); +} + +export default inputs; diff --git a/sdk/communication/communication-administration/rollup.test.config.js b/sdk/communication/communication-administration/rollup.test.config.js new file mode 100644 index 000000000000..925a4421a53e --- /dev/null +++ b/sdk/communication/communication-administration/rollup.test.config.js @@ -0,0 +1,3 @@ +import * as base from "./rollup.base.config"; + +export default [base.nodeConfig(true), base.browserConfig(true)]; diff --git a/sdk/communication/communication-administration/sample.env b/sdk/communication/communication-administration/sample.env new file mode 100644 index 000000000000..ed6fa2af13e8 --- /dev/null +++ b/sdk/communication/communication-administration/sample.env @@ -0,0 +1,7 @@ +# Used in most samples. Retrieve these values from a Cognitive Services instance +# in the Azure Portal. +COMMUNICATION_CONNECTION_STRING="endpoint=;accessKey=" + +# Our tests assume that TEST_MODE is "playback" by default. You can +# change it to "record" to generate new recordings, or "live" to bypass the recorder entirely. +# TEST_MODE=playback diff --git a/sdk/communication/communication-administration/samples/.gitignore b/sdk/communication/communication-administration/samples/.gitignore new file mode 100644 index 000000000000..0c348f50aebf --- /dev/null +++ b/sdk/communication/communication-administration/samples/.gitignore @@ -0,0 +1 @@ +.npmrc \ No newline at end of file diff --git a/sdk/communication/communication-administration/samples/javascript/README.md b/sdk/communication/communication-administration/samples/javascript/README.md new file mode 100644 index 000000000000..f1dc1eb76834 --- /dev/null +++ b/sdk/communication/communication-administration/samples/javascript/README.md @@ -0,0 +1,67 @@ +--- +page_type: sample +languages: + - javascript +products: + - azure + - azure-communication-service + - azure-communication-administration +urlFragment: communication-administration-identity-javascript +--- + +# Azure Communication Service Administration Identity client library sample for JavaScript + +These sample programs show how to use the JavaScript client libraries for Azure Communication Service Administration Identity to issue and refresh tokens. + +| **File Name** | **Description** | +| --------------------------------------- | ---------------------------------------------------------------------------------------------------------- | +| [issueToken.js] | uses the CommunicationIdentityClient to create a user and issue a token for this user | +| [revokeTokens.js] | uses the CommunicationIdentityClient to create a user, issue tokens for this user, and revoke these tokens | + +## Prerequisites + +The sample is compatible with Node.js >= 8.0.0. + +You need [an Azure subscription][freesub] and [an Azure Communication Service Instance][azcomsvc] to run these sample program. + +Adapting the samples to run in the browser may require some additional consideration. For details, please see the [package README]. + +## Setup + +To run the sample using the published version of the package: + +1. Install the dependencies using `npm`: + +```bash +npm install +``` + +2. Edit the file `sample.env`, adding the correct credentials to access the Azure service and run the samples. Then rename the file from `sample.env` to just `.env`. The sample programs will read this file automatically. + +3. Run whichever samples you like (note that some samples may require additional setup, see the table above): + +```bash +node issueToken.js +``` + +Alternatively, run a single sample with the correct environment variables set (step 3 is not required if you do this), for example (cross-platform): + +```bash +npx cross-env CONNECTION_STRING="" node issueToken.js +``` + +## Next Steps + +Take a look at our [API Documentation] for more information about the APIs that are available in the clients. + +[issuetoken]: https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/communication/communication-administration/samples/javascript/issueToken.js +[revoketokens]: https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/communication/communication-administration/samples/javascript/revokeTokens.js +[apiref]: https://docs.microsoft.com/javascript/api/@azure/communication-administration +[azcomsvc]: https://docs.microsoft.com/azure +[freesub]: https://azure.microsoft.com/free/ +[package]: https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/communication/communication-administration/README.md + +## ! TODO + +- Get correct url for azcomsvc +- Uncomment urls when merged and apirefs available diff --git a/sdk/communication/communication-administration/samples/javascript/issueToken.js b/sdk/communication/communication-administration/samples/javascript/issueToken.js new file mode 100644 index 000000000000..db295a7913c7 --- /dev/null +++ b/sdk/communication/communication-administration/samples/javascript/issueToken.js @@ -0,0 +1,44 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +/** + * Demonstrates how to use the CommunicationIdentityClient to + * issue a user token. + */ + +const { CommunicationIdentityClient } = require("@azure/communication-administration"); + +// Load the .env file if it exists +const dotenv = require("dotenv"); +dotenv.config(); + +// You will need to set this environment variables or edit the following values +const connectionString = + process.env["CONNECTION_STRING"] || ""; + +async function main() { + console.log("== Issue Token Sample =="); + + const client = new CommunicationIdentityClient(connectionString); + const scopes = ["chat"]; + + // Create user + console.log("Creating User"); + + const user = await client.createUser(); + + console.log(`Created user with id: ${user.communicationUserId}`); + console.log("Issuing Token"); + + // Issue token and get token from response + const { token } = await client.issueToken(user, scopes); + + console.log(`Issued token: ${token}`); +} + +main().catch((error) => { + console.error("Encountered an error while issuing token: "); + console.error("Request: \n", error.request); + console.error("\nResponse: \n", error.response); + console.error(error); +}); diff --git a/sdk/communication/communication-administration/samples/javascript/package.json b/sdk/communication/communication-administration/samples/javascript/package.json new file mode 100644 index 000000000000..268ddee07c85 --- /dev/null +++ b/sdk/communication/communication-administration/samples/javascript/package.json @@ -0,0 +1,29 @@ +{ + "name": "azure-communication-configuration-user-token-samples-js", + "version": "0.1.0", + "description": "Azure Communication Service User Token Management client library samples for JavaScript", + "engine": { + "node": ">=8.0.0" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/Azure/azure-sdk-for-js.git" + }, + "keywords": [ + "Azure", + "Communication", + "Node.js", + "JavaScript" + ], + "author": "Microsoft Corporation", + "license": "MIT", + "bugs": { + "url": "https://github.com/Azure/azure-sdk-for-js/issues" + }, + "homepage": "https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/communication/communication-configuration", + "sideEffects": false, + "dependencies": { + "@azure/communication-administration": "latest", + "dotenv": "^8.2.0" + } +} diff --git a/sdk/communication/communication-administration/samples/javascript/revokeTokens.js b/sdk/communication/communication-administration/samples/javascript/revokeTokens.js new file mode 100644 index 000000000000..13dabb722451 --- /dev/null +++ b/sdk/communication/communication-administration/samples/javascript/revokeTokens.js @@ -0,0 +1,57 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +/** + * Demonstrates how to use the CommunicationIdentityClient to + * revoke a user's tokens. + */ + +const { CommunicationIdentityClient } = require("@azure/communication-administration"); + +// Load the .env file if it exists +const dotenv = require("dotenv"); +dotenv.config(); + +// You will need to set this environment variables or edit the following values +const connectionString = + process.env["CONNECTION_STRING"] || ""; + +async function main() { + console.log("== Issue Token Sample =="); + + const client = new CommunicationIdentityClient(connectionString); + const scopes = ["chat"]; + + // Create user + console.log("Creating User"); + + const user = await client.createUser(); + + console.log(`Created user with id: ${user.communicationUserId}`); + + console.log("Issuing Tokens"); + + // Issue tokens + const { token: token1 } = await client.issueToken(user, scopes); + const { token: token2 } = await client.issueToken(user, scopes); + const { token: token3 } = await client.issueToken(user, scopes); + + console.log("Issued tokens:"); + console.log(token1); + console.log(token2); + console.log(token3); + + // Revoke tokens + console.log("Revoking Tokens"); + + await client.revokeTokens(user, new Date()); + + console.log("Tokens Revoked"); +} + +main().catch((error) => { + console.error("Encountered an error while revoking tokens: "); + console.error("Request: \n", error.request); + console.error("\nResponse: \n", error.response); + console.error(error); +}); diff --git a/sdk/communication/communication-administration/samples/javascript/sample.env b/sdk/communication/communication-administration/samples/javascript/sample.env new file mode 100644 index 000000000000..1ba7d7b92f1f --- /dev/null +++ b/sdk/communication/communication-administration/samples/javascript/sample.env @@ -0,0 +1,3 @@ +# Used in most samples. Retrieve these values from a Communication Service instance +# in the Azure Portal. +CONNECTION_STRING="endpoint=https://.communication.azure.net/;accessKey=" \ No newline at end of file diff --git a/sdk/communication/communication-administration/samples/tsconfig.json b/sdk/communication/communication-administration/samples/tsconfig.json new file mode 100644 index 000000000000..8c89eac7173a --- /dev/null +++ b/sdk/communication/communication-administration/samples/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "module": "commonjs", + "outDir": "typescript/dist", + "lib": ["DOM", "ES6"] + }, + "include": ["typescript/src/**.ts"], + "exclude": ["typescript/*.json", "**/node_modules/", "../node_modules", "../typings"] +} diff --git a/sdk/communication/communication-administration/samples/typescript/README.md b/sdk/communication/communication-administration/samples/typescript/README.md new file mode 100644 index 000000000000..cc996d2c6b8e --- /dev/null +++ b/sdk/communication/communication-administration/samples/typescript/README.md @@ -0,0 +1,73 @@ +--- +page_type: sample +languages: + - typescript +products: + - azure + - azure-communication-service + - azure-communication-administration +urlFragment: communication-administration-identity-typescript +--- + +# Azure Communication Service Communication Identity client library sample for TypeScript + +These sample programs show how to use the TypeScript client libraries for Azure Communication Service Communication Identity to issue and refresh tokens. + +| **File Name** | **Description** | +| -------------------------------------- | ---------------------------------------------------------------------------------------------------------- | +| [issueToken.ts] | uses the CommunicationIdentityClient to create a user and issue a token for this user | +| [revokeTokens.ts] | uses the CommunicationIdentityClient to create a user, issue tokens for this user, and revoke these tokens | + +## Prerequisites + +The sample is compatible with Node.js >= 8.0.0. + +You need [an Azure subscription][freesub] and [an Azure Communication Service Instance][azcomsvc] to run these sample program. + +Adapting the samples to run in the browser may require some additional consideration. For details, please see the [package README]. + +## Setup + +To run the sample using the published version of the package: + +1. Install the dependencies using `npm`: + +```bash +npm install +``` + +2. Compile the sample + +```bash +npm run build +``` + +3. Edit the file `sample.env`, adding the correct credentials to access the Azure service and run the samples. Then rename the file from `sample.env` to just `.env`. The sample programs will read this file automatically. + +4. Run whichever samples you like (note that some samples may require additional setup, see the table above): + +```bash +node dist/issueToken.js +``` + +Alternatively, run a single sample with the correct environment variables set (step 3 is not required if you do this), for example (cross-platform): + +```bash +npx cross-env CONNECTION_STRING="" node dist/issueToken.js +``` + +## Next Steps + +Take a look at our [API Documentation] for more information about the APIs that are available in the clients. + +[issuetoken]: https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/communication/communication-administration/samples/typescript/src/issueToken.ts +[revoketokens]: https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/communication/communication-administration/samples/typescript/src/revokeTokens.ts +[apiref]: https://docs.microsoft.com/javascript/api/@azure/communication-administration +[azcomsvc]: https://docs.microsoft.com/azure +[freesub]: https://azure.microsoft.com/free/ +[package]: https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/communication/communication-administration/README.md + +## ! TODO + +- Get correct url for azcomsvc +- Uncomment urls when merged and apirefs available diff --git a/sdk/communication/communication-administration/samples/typescript/package.json b/sdk/communication/communication-administration/samples/typescript/package.json new file mode 100644 index 000000000000..a2a3941de76d --- /dev/null +++ b/sdk/communication/communication-administration/samples/typescript/package.json @@ -0,0 +1,38 @@ +{ + "name": "azure-communication-configuration-user-token-samples-ts", + "version": "0.1.0", + "description": "Azure Communication Service User Token Management client library samples for TypeScript", + "engine": { + "node": ">=8.0.0" + }, + "scripts": { + "build": "tsc", + "prebuild": "rimraf dist/" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/Azure/azure-sdk-for-js.git" + }, + "keywords": [ + "Azure", + "Communication", + "Node.js", + "JavaScript" + ], + "author": "Microsoft Corporation", + "license": "MIT", + "bugs": { + "url": "https://github.com/Azure/azure-sdk-for-js/issues" + }, + "homepage": "https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/communication/communication-configuration", + "sideEffects": false, + "dependencies": { + "@azure/communication-administration": "latest", + "dotenv": "^8.2.0" + }, + "devDependencies": { + "@types/node": "^8.0.0", + "rimraf": "^3.0.0", + "typescript": "~3.6.4" + } +} diff --git a/sdk/communication/communication-administration/samples/typescript/sample.env b/sdk/communication/communication-administration/samples/typescript/sample.env new file mode 100644 index 000000000000..1ba7d7b92f1f --- /dev/null +++ b/sdk/communication/communication-administration/samples/typescript/sample.env @@ -0,0 +1,3 @@ +# Used in most samples. Retrieve these values from a Communication Service instance +# in the Azure Portal. +CONNECTION_STRING="endpoint=https://.communication.azure.net/;accessKey=" \ No newline at end of file diff --git a/sdk/communication/communication-administration/samples/typescript/src/issueToken.ts b/sdk/communication/communication-administration/samples/typescript/src/issueToken.ts new file mode 100644 index 000000000000..a185e04adfd5 --- /dev/null +++ b/sdk/communication/communication-administration/samples/typescript/src/issueToken.ts @@ -0,0 +1,44 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +/** + * Demonstrates how to use the CommunicationIdentityClient to + * issue a new user token. + */ + +import { CommunicationIdentityClient, TokenScope } from "@azure/communication-administration"; + +// Load the .env file if it exists +import * as dotenv from "dotenv"; +dotenv.config(); + +// You will need to set this environment variables or edit the following values +const connectionString = + process.env["CONNECTION_STRING"] || ""; + +export const main = async () => { + console.log("== Issue Token Sample =="); + + const client = new CommunicationIdentityClient(connectionString); + const scopes: TokenScope[] = ["chat"]; + + // Create user + console.log("Creating User"); + + const user = await client.createUser(); + + console.log(`Created user with id: ${user.communicationUserId}`); + console.log("Issuing Token"); + + // Issue token and get token from response + const { token } = await client.issueToken(user, scopes); + + console.log(`Issued token: ${token}`); +}; + +main().catch((error) => { + console.error("Encountered an error while issuing token: "); + console.error("Request: \n", error.request); + console.error("\nResponse: \n", error.response); + console.error(error); +}); diff --git a/sdk/communication/communication-administration/samples/typescript/src/revokeTokens.ts b/sdk/communication/communication-administration/samples/typescript/src/revokeTokens.ts new file mode 100644 index 000000000000..4e4e6cbf0255 --- /dev/null +++ b/sdk/communication/communication-administration/samples/typescript/src/revokeTokens.ts @@ -0,0 +1,56 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +/** + * Demonstrates how to use the CommunicationIdentityClient to + * issue a new user token. + */ + +import { CommunicationIdentityClient } from "@azure/communication-administration"; + +// Load the .env file if it exists +import * as dotenv from "dotenv"; +dotenv.config(); + +// You will need to set this environment variables or edit the following values +const connectionString = + process.env["CONNECTION_STRING"] || ""; + +export const main = async () => { + console.log("== Issue Token Sample =="); + + const client = new CommunicationIdentityClient(connectionString); + + // Create user + console.log("Creating User"); + + const user = await client.createUser(); + + console.log(`Created user with id: ${user.communicationUserId}`); + + console.log("Issuing Tokens"); + + // Issue tokens + const { token: token1 } = await client.issueToken(user, ["chat"]); + const { token: token2 } = await client.issueToken(user, ["pstn"]); + const { token: token3 } = await client.issueToken(user, ["voip"]); + + console.log("Issued tokens:"); + console.log(token1); + console.log(token2); + console.log(token3); + + // Revoke tokens + console.log("Revoking Tokens"); + + await client.revokeTokens(user, new Date()); + + console.log("Tokens Revoked"); +}; + +main().catch((error) => { + console.error("Encountered an error while issuing/refreshing token: "); + console.error("Request: \n", error.request); + console.error("\nResponse: \n", error.response); + console.error(error); +}); diff --git a/sdk/communication/communication-administration/samples/typescript/tsconfig.json b/sdk/communication/communication-administration/samples/typescript/tsconfig.json new file mode 100644 index 000000000000..9e7ca6c9974b --- /dev/null +++ b/sdk/communication/communication-administration/samples/typescript/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "module": "commonjs", + "moduleResolution": "node", + "allowSyntheticDefaultImports": true, + "strict": true, + "alwaysStrict": true, + "outDir": "dist", + "rootDir": "src" + }, + "include": ["src/**.ts"], + "exclude": ["node_modules"] +} diff --git a/sdk/communication/communication-administration/src/common/logger.ts b/sdk/communication/communication-administration/src/common/logger.ts new file mode 100644 index 000000000000..ea6fd2a63671 --- /dev/null +++ b/sdk/communication/communication-administration/src/common/logger.ts @@ -0,0 +1,9 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { createClientLogger } from "@azure/logger"; + +/** + * The @azure/logger configuration for this package. + */ +export const logger = createClientLogger("communication-administration"); diff --git a/sdk/communication/communication-administration/src/common/mappers.ts b/sdk/communication/communication-administration/src/common/mappers.ts new file mode 100644 index 000000000000..52c5be668df3 --- /dev/null +++ b/sdk/communication/communication-administration/src/common/mappers.ts @@ -0,0 +1,18 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { HttpOperationResponse, HttpResponse } from "@azure/core-http"; +import { WithResponse } from ".."; + +/** + * Attach http response to a model + */ +export const attachHttpResponse = ( + model: T, + httpResponse: (HttpResponse & { bodyAsText: string; parsedBody: any }) | HttpOperationResponse +): WithResponse => { + const { parsedBody, bodyAsText, ...r } = httpResponse; + return Object.defineProperty(model, "_response", { + value: r + }); +}; diff --git a/sdk/communication/communication-administration/src/common/tracing.ts b/sdk/communication/communication-administration/src/common/tracing.ts new file mode 100644 index 000000000000..bd42a3471fb5 --- /dev/null +++ b/sdk/communication/communication-administration/src/common/tracing.ts @@ -0,0 +1,57 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { OperationOptions } from "@azure/core-http"; +import { getTracer } from "@azure/core-tracing"; +import { Span, SpanOptions, SpanKind } from "@opentelemetry/api"; + +type OperationTracingOptions = OperationOptions["tracingOptions"]; + +/** + * Creates a span using the global tracer. + * @ignore + * @param name The name of the operation being performed. + * @param tracingOptions The options for the underlying http request. + */ +export function createSpan( + operationName: string, + operationOptions: T +): { span: Span; updatedOptions: T } { + const tracer = getTracer(); + const tracingOptions = operationOptions.tracingOptions || {}; + const spanOptions: SpanOptions = { + ...tracingOptions.spanOptions, + kind: SpanKind.INTERNAL + }; + + const span = tracer.startSpan(`Azure.Communication.${operationName}`, spanOptions); + + span.setAttribute("az.namespace", "Microsoft.Communication"); + + let newSpanOptions = tracingOptions.spanOptions || {}; + if (span.isRecording()) { + newSpanOptions = { + ...tracingOptions.spanOptions, + parent: span.context(), + attributes: { + ...spanOptions.attributes, + "az.namespace": "Microsoft.Communication" + } + }; + } + + const newTracingOptions: OperationTracingOptions = { + ...tracingOptions, + spanOptions: newSpanOptions + }; + + const newOperationOptions: T = { + ...operationOptions, + tracingOptions: newTracingOptions + }; + + return { + span, + updatedOptions: newOperationOptions + }; +} diff --git a/sdk/communication/communication-administration/src/communicationIdentity/communicationIdentityClient.ts b/sdk/communication/communication-administration/src/communicationIdentity/communicationIdentityClient.ts new file mode 100644 index 000000000000..29952d7d2f14 --- /dev/null +++ b/sdk/communication/communication-administration/src/communicationIdentity/communicationIdentityClient.ts @@ -0,0 +1,237 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { + createCommunicationAccessKeyCredentialPolicy, + parseClientArguments, + isKeyCredential, + CommunicationUser +} from "@azure/communication-common"; +import { KeyCredential } from "@azure/core-auth"; +import { + InternalPipelineOptions, + createPipelineFromOptions, + OperationOptions, + operationOptionsToRequestOptionsBase +} from "@azure/core-http"; +import { CanonicalCode } from "@opentelemetry/api"; +import { GeneratedCommunicationIdentityClient } from "./generated/src/generatedCommunicationIdentityClient"; +import { CommunicationIdentityOperations } from "./generated/src/operations/communicationIdentityOperations"; +import { SDK_VERSION } from "./constants"; +import { logger } from "../common/logger"; +import { createSpan } from "../common/tracing"; +import { + CommunicationIdentityOptions, + TokenScope, + IssueTokenResponse, + CreateUserResponse, + CommunicationUserToken, + VoidResponse +} from "./models"; +import { attachHttpResponse } from "../common/mappers"; + +const isCommunicationIdentityOptions = (options: any): options is CommunicationIdentityOptions => + options && !isKeyCredential(options); + +/** + * Client class for interacting with Azure Communication Services User Token Management. + */ +export class CommunicationIdentityClient { + /** + * A reference to the auto-generated UserToken HTTP client. + */ + private readonly client: CommunicationIdentityOperations; + + /** + * The base URL to which requests are made + */ + private readonly endpoint: string; + + /** + * Initializes a new instance of the CommunicationIdentity class. + * @param connectionString Connection string to connect to an Azure Communication Service resource. + * Example: "endpoint=https://contoso.eastus.communications.azure.net/;accesskey=secret"; + * @param options Optional. Options to configure the HTTP pipeline. + */ + public constructor(connectionString: string, options?: CommunicationIdentityOptions); + + /** + * Initializes a new instance of the CommunicationIdentity class using an Azure KeyCredential. + * @param url The endpoint of the service (ex: https://contoso.eastus.communications.azure.net). + * @param credential An object that is used to authenticate requests to the service. Use the AzureKeyCredential or `@azure/identity` to create a credential. + * @param options Optional. Options to configure the HTTP pipeline. + */ + public constructor( + url: string, + credential: KeyCredential, + options?: CommunicationIdentityOptions + ); + + /** + * Creates an instance of CommunicationIdentity. + * + * @param {string} url The endpoint to the service + * @param {KeyCredential} credential An object that is used to authenticate requests to the service. Use the AzureKeyCredential or `@azure/identity` to create a credential. + * @param {CommunicationIdentityOptions} [options={}] Options to configure the HTTP pipeline. + */ + public constructor( + connectionStringOrUrl: string, + credentialOrOptions?: KeyCredential | CommunicationIdentityOptions, + maybeOptions: CommunicationIdentityOptions = {} + ) { + const { url, credential } = parseClientArguments(connectionStringOrUrl, credentialOrOptions); + const options = isCommunicationIdentityOptions(credentialOrOptions) + ? credentialOrOptions + : maybeOptions; + const libInfo = `azsdk-js-communication-administration/${SDK_VERSION}`; + + if (!options.userAgentOptions) { + options.userAgentOptions = {}; + } + + if (options.userAgentOptions.userAgentPrefix) { + options.userAgentOptions.userAgentPrefix = `${options.userAgentOptions.userAgentPrefix} ${libInfo}`; + } else { + options.userAgentOptions.userAgentPrefix = libInfo; + } + + const internalPipelineOptions: InternalPipelineOptions = { + ...options, + ...{ + loggingOptions: { + logger: logger.info + } + } + }; + + const authPolicy = createCommunicationAccessKeyCredentialPolicy(credential); + const pipeline = createPipelineFromOptions(internalPipelineOptions, authPolicy); + + this.endpoint = url; + this.client = new GeneratedCommunicationIdentityClient(pipeline).communicationIdentity; + } + + /** + * Creates a scoped user token. + * + * @param {CommunicationUser} user The user whose tokens are being revoked. + * @param {TokenScope[]} scopes Scopes to include in the token. + * @param {OperationOptions} [options={}] Additional options for the request. + */ + public async issueToken( + user: CommunicationUser, + scopes: TokenScope[], + options: OperationOptions = {} + ): Promise { + const { span, updatedOptions } = createSpan("CommunicationIdentity-issueToken", options); + try { + const { token, id, expiresOn, _response } = await this.client.issueToken( + this.endpoint, + user.communicationUserId, + scopes, + { ...operationOptionsToRequestOptionsBase(updatedOptions) } + ); + const results: CommunicationUserToken = { + token, + expiresOn, + user: { communicationUserId: id } + }; + return attachHttpResponse(results, _response); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Revokes all data and tokens created for a user. + * + * @param {CommunicationUser} user The user whose tokens are being revoked. + * @param {Date} tokensValidFrom Tokens issued before this time will be revoked. + * @param {OperationOptions} [options={}] Additional options for the request. + */ + public async revokeTokens( + user: CommunicationUser, + tokensValidFrom: Date = new Date(), + options: OperationOptions = {} + ): Promise { + const { span, updatedOptions } = createSpan("CommunicationIdentity-revokeTokens", options); + try { + const { _response } = await this.client.update(this.endpoint, user.communicationUserId, { + tokensValidFrom, + ...operationOptionsToRequestOptionsBase(updatedOptions) + }); + return attachHttpResponse({}, _response); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Creates a single user. + * + * @param {OperationOptions} [options={}] Additional options for the request. + */ + public async createUser(options: OperationOptions = {}): Promise { + const { span, updatedOptions } = createSpan("CommunicationIdentity-createUser", options); + try { + const { id, _response } = await this.client.create(this.endpoint, { + ...operationOptionsToRequestOptionsBase(updatedOptions) + }); + const user: CommunicationUser = { communicationUserId: id }; + return attachHttpResponse(user, _response); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Triggers revocation event for user and deletes all its data. + * + * @param {CommunicationUser} user The user being deleted. + * @param {OperationOptions} [options={}] Additional options for the request. + */ + public async deleteUser( + user: CommunicationUser, + options: OperationOptions = {} + ): Promise { + const { span, updatedOptions } = createSpan("CommunicationIdentity-deleteUser", options); + try { + const { _response } = await this.client.deleteMethod( + this.endpoint, + user.communicationUserId, + { + ...operationOptionsToRequestOptionsBase(updatedOptions) + } + ); + return attachHttpResponse({}, _response); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } +} + +export { CommunicationTokenRequest, CommunicationIdentityToken } from "./generated/src/models"; diff --git a/sdk/communication/communication-administration/src/communicationIdentity/constants.ts b/sdk/communication/communication-administration/src/communicationIdentity/constants.ts new file mode 100644 index 000000000000..d95eaa576529 --- /dev/null +++ b/sdk/communication/communication-administration/src/communicationIdentity/constants.ts @@ -0,0 +1,6 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { apiVersion } from "./generated/src/models/parameters"; + +export const SDK_VERSION: string = apiVersion.mapper.defaultValue; diff --git a/sdk/communication/communication-administration/src/communicationIdentity/generated/src/generatedCommunicationIdentityClient.ts b/sdk/communication/communication-administration/src/communicationIdentity/generated/src/generatedCommunicationIdentityClient.ts new file mode 100644 index 000000000000..c359cfc5a5b5 --- /dev/null +++ b/sdk/communication/communication-administration/src/communicationIdentity/generated/src/generatedCommunicationIdentityClient.ts @@ -0,0 +1,39 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is + * regenerated. + */ + +import * as coreHttp from "@azure/core-http"; +import * as Models from "./models"; +import * as Mappers from "./models/mappers"; +import * as operations from "./operations"; +import { GeneratedCommunicationIdentityClientContext } from "./generatedCommunicationIdentityClientContext"; + +class GeneratedCommunicationIdentityClient extends GeneratedCommunicationIdentityClientContext { + // Operation groups + communicationIdentity: operations.CommunicationIdentityOperations; + + /** + * Initializes a new instance of the GeneratedCommunicationIdentityClient class. + * @param [options] The parameter options + */ + constructor(options?: coreHttp.ServiceClientOptions) { + super(options); + this.communicationIdentity = new operations.CommunicationIdentityOperations(this); + } +} + +// Operation Specifications + +export { + GeneratedCommunicationIdentityClient, + GeneratedCommunicationIdentityClientContext, + Models as GeneratedCommunicationIdentityModels, + Mappers as GeneratedCommunicationIdentityMappers +}; +export * from "./operations"; diff --git a/sdk/communication/communication-administration/src/communicationIdentity/generated/src/generatedCommunicationIdentityClientContext.ts b/sdk/communication/communication-administration/src/communicationIdentity/generated/src/generatedCommunicationIdentityClientContext.ts new file mode 100644 index 000000000000..39ffe3f42ed3 --- /dev/null +++ b/sdk/communication/communication-administration/src/communicationIdentity/generated/src/generatedCommunicationIdentityClientContext.ts @@ -0,0 +1,36 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is + * regenerated. + */ + +import * as coreHttp from "@azure/core-http"; + +const packageName = "azure-communication-administration-identity"; +const packageVersion = "1.0.0-beta.1"; + +export class GeneratedCommunicationIdentityClientContext extends coreHttp.ServiceClient { + /** + * Initializes a new instance of the GeneratedCommunicationIdentityClientContext class. + * @param [options] The parameter options + */ + constructor(options?: coreHttp.ServiceClientOptions) { + if (!options) { + options = {}; + } + + if (!options.userAgent) { + const defaultUserAgent = coreHttp.getDefaultUserAgentValue(); + options.userAgent = `${packageName}/${packageVersion} ${defaultUserAgent}`; + } + + super(undefined, options); + + this.baseUri = "{endpoint}"; + this.requestContentType = "application/json; charset=utf-8"; + } +} diff --git a/sdk/communication/communication-administration/src/communicationIdentity/generated/src/models/communicationIdentityOperationsMappers.ts b/sdk/communication/communication-administration/src/communicationIdentity/generated/src/models/communicationIdentityOperationsMappers.ts new file mode 100644 index 000000000000..36b7cd50c0b3 --- /dev/null +++ b/sdk/communication/communication-administration/src/communicationIdentity/generated/src/models/communicationIdentityOperationsMappers.ts @@ -0,0 +1,14 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is regenerated. + */ + +export { + CommunicationIdentity, + CommunicationIdentityToken, + CommunicationIdentityUpdateRequest, + CommunicationTokenRequest +} from "../models/mappers"; diff --git a/sdk/communication/communication-administration/src/communicationIdentity/generated/src/models/index.ts b/sdk/communication/communication-administration/src/communicationIdentity/generated/src/models/index.ts new file mode 100644 index 000000000000..86d8f18d964b --- /dev/null +++ b/sdk/communication/communication-administration/src/communicationIdentity/generated/src/models/index.ts @@ -0,0 +1,107 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is regenerated. + */ + +import * as coreHttp from "@azure/core-http"; + +/** + * A communication identity. + */ +export interface CommunicationIdentity { + /** + * Identifier of the identity. + */ + id: string; +} + +/** + * An interface representing CommunicationIdentityUpdateRequest. + */ +export interface CommunicationIdentityUpdateRequest { + /** + * All tokens that are issued prior to this time will be revoked. + */ + tokensValidFrom?: Date; +} + +/** + * An interface representing CommunicationTokenRequest. + */ +export interface CommunicationTokenRequest { + /** + * List of scopes attached to the token. + */ + scopes: string[]; +} + +/** + * An interface representing CommunicationIdentityToken. + */ +export interface CommunicationIdentityToken { + /** + * Identifier of the identity owning the token. + */ + id: string; + /** + * The token issued for the identity. + */ + token: string; + /** + * The expiry time of the token. + */ + expiresOn: Date; +} + +/** + * Optional Parameters. + */ +export interface CommunicationIdentityUpdateOptionalParams extends coreHttp.RequestOptionsBase { + /** + * All tokens that are issued prior to this time will be revoked. + */ + tokensValidFrom?: Date; +} + +/** + * Contains response data for the create operation. + */ +export type CommunicationIdentityCreateResponse = CommunicationIdentity & { + /** + * The underlying HTTP response. + */ + _response: coreHttp.HttpResponse & { + /** + * The response body as text (string format) + */ + bodyAsText: string; + + /** + * The response body as parsed JSON or XML + */ + parsedBody: CommunicationIdentity; + }; +}; + +/** + * Contains response data for the issueToken operation. + */ +export type CommunicationIdentityIssueTokenResponse = CommunicationIdentityToken & { + /** + * The underlying HTTP response. + */ + _response: coreHttp.HttpResponse & { + /** + * The response body as text (string format) + */ + bodyAsText: string; + + /** + * The response body as parsed JSON or XML + */ + parsedBody: CommunicationIdentityToken; + }; +}; diff --git a/sdk/communication/communication-administration/src/communicationIdentity/generated/src/models/mappers.ts b/sdk/communication/communication-administration/src/communicationIdentity/generated/src/models/mappers.ts new file mode 100644 index 000000000000..dbcc264adfac --- /dev/null +++ b/sdk/communication/communication-administration/src/communicationIdentity/generated/src/models/mappers.ts @@ -0,0 +1,95 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is regenerated. + */ + +import * as coreHttp from "@azure/core-http"; + +export const CommunicationIdentity: coreHttp.CompositeMapper = { + serializedName: "CommunicationIdentity", + type: { + name: "Composite", + className: "CommunicationIdentity", + modelProperties: { + id: { + required: true, + serializedName: "id", + type: { + name: "String" + } + } + } + } +}; + +export const CommunicationIdentityUpdateRequest: coreHttp.CompositeMapper = { + serializedName: "CommunicationIdentityUpdateRequest", + type: { + name: "Composite", + className: "CommunicationIdentityUpdateRequest", + modelProperties: { + tokensValidFrom: { + serializedName: "tokensValidFrom", + type: { + name: "DateTime" + } + } + } + } +}; + +export const CommunicationTokenRequest: coreHttp.CompositeMapper = { + serializedName: "CommunicationTokenRequest", + type: { + name: "Composite", + className: "CommunicationTokenRequest", + modelProperties: { + scopes: { + required: true, + serializedName: "scopes", + type: { + name: "Sequence", + element: { + type: { + name: "String" + } + } + } + } + } + } +}; + +export const CommunicationIdentityToken: coreHttp.CompositeMapper = { + serializedName: "CommunicationIdentityToken", + type: { + name: "Composite", + className: "CommunicationIdentityToken", + modelProperties: { + id: { + required: true, + serializedName: "id", + type: { + name: "String" + } + }, + token: { + required: true, + serializedName: "token", + type: { + name: "String" + } + }, + expiresOn: { + required: true, + serializedName: "expiresOn", + type: { + name: "DateTime" + } + } + } + } +}; diff --git a/sdk/communication/communication-administration/src/communicationIdentity/generated/src/models/parameters.ts b/sdk/communication/communication-administration/src/communicationIdentity/generated/src/models/parameters.ts new file mode 100644 index 000000000000..f7ac50fdfb24 --- /dev/null +++ b/sdk/communication/communication-administration/src/communicationIdentity/generated/src/models/parameters.ts @@ -0,0 +1,46 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is + * regenerated. + */ + +import * as coreHttp from "@azure/core-http"; + +export const apiVersion: coreHttp.OperationQueryParameter = { + parameterPath: "apiVersion", + mapper: { + required: true, + isConstant: true, + serializedName: "api-version", + defaultValue: "2020-07-20-preview2", + type: { + name: "String" + } + } +}; +export const endpoint: coreHttp.OperationURLParameter = { + parameterPath: "endpoint", + mapper: { + required: true, + serializedName: "endpoint", + defaultValue: "", + type: { + name: "String" + } + }, + skipEncoding: true +}; +export const id: coreHttp.OperationURLParameter = { + parameterPath: "id", + mapper: { + required: true, + serializedName: "id", + type: { + name: "String" + } + } +}; diff --git a/sdk/communication/communication-administration/src/communicationIdentity/generated/src/operations/communicationIdentityOperations.ts b/sdk/communication/communication-administration/src/communicationIdentity/generated/src/operations/communicationIdentityOperations.ts new file mode 100644 index 000000000000..a033787129b6 --- /dev/null +++ b/sdk/communication/communication-administration/src/communicationIdentity/generated/src/operations/communicationIdentityOperations.ts @@ -0,0 +1,296 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is + * regenerated. + */ + +import * as coreHttp from "@azure/core-http"; +import * as Models from "../models"; +import * as Mappers from "../models/communicationIdentityOperationsMappers"; +import * as Parameters from "../models/parameters"; +import { GeneratedCommunicationIdentityClientContext } from "../generatedCommunicationIdentityClientContext"; + +/** Class representing a CommunicationIdentityOperations. */ +export class CommunicationIdentityOperations { + private readonly client: GeneratedCommunicationIdentityClientContext; + + /** + * Create a CommunicationIdentityOperations. + * @param {GeneratedCommunicationIdentityClientContext} client Reference to the service client. + */ + constructor(client: GeneratedCommunicationIdentityClientContext) { + this.client = client; + } + + /** + * @summary Create a new identity. + * @param endpoint Auth and Identity endpoint + * @param [options] The optional parameters + * @returns Promise + */ + create( + endpoint: string, + options?: coreHttp.RequestOptionsBase + ): Promise; + /** + * @param endpoint Auth and Identity endpoint + * @param callback The callback + */ + create(endpoint: string, callback: coreHttp.ServiceCallback): void; + /** + * @param endpoint Auth and Identity endpoint + * @param options The optional parameters + * @param callback The callback + */ + create( + endpoint: string, + options: coreHttp.RequestOptionsBase, + callback: coreHttp.ServiceCallback + ): void; + create( + endpoint: string, + options?: coreHttp.RequestOptionsBase | coreHttp.ServiceCallback, + callback?: coreHttp.ServiceCallback + ): Promise { + return this.client.sendOperationRequest( + { + endpoint, + options + }, + createOperationSpec, + callback + ) as Promise; + } + + /** + * @summary Delete the identity, revoke all tokens of the identity and delete all associated data. + * @param endpoint Auth and Identity endpoint + * @param id Identifier of the identity to be deleted. + * @param [options] The optional parameters + * @returns Promise + */ + deleteMethod( + endpoint: string, + id: string, + options?: coreHttp.RequestOptionsBase + ): Promise; + /** + * @param endpoint Auth and Identity endpoint + * @param id Identifier of the identity to be deleted. + * @param callback The callback + */ + deleteMethod(endpoint: string, id: string, callback: coreHttp.ServiceCallback): void; + /** + * @param endpoint Auth and Identity endpoint + * @param id Identifier of the identity to be deleted. + * @param options The optional parameters + * @param callback The callback + */ + deleteMethod( + endpoint: string, + id: string, + options: coreHttp.RequestOptionsBase, + callback: coreHttp.ServiceCallback + ): void; + deleteMethod( + endpoint: string, + id: string, + options?: coreHttp.RequestOptionsBase | coreHttp.ServiceCallback, + callback?: coreHttp.ServiceCallback + ): Promise { + return this.client.sendOperationRequest( + { + endpoint, + id, + options + }, + deleteMethodOperationSpec, + callback + ); + } + + /** + * @summary Update an Identity. + * @param endpoint Auth and Identity endpoint + * @param id Identifier of the identity. + * @param [options] The optional parameters + * @returns Promise + */ + update( + endpoint: string, + id: string, + options?: Models.CommunicationIdentityUpdateOptionalParams + ): Promise; + /** + * @param endpoint Auth and Identity endpoint + * @param id Identifier of the identity. + * @param callback The callback + */ + update(endpoint: string, id: string, callback: coreHttp.ServiceCallback): void; + /** + * @param endpoint Auth and Identity endpoint + * @param id Identifier of the identity. + * @param options The optional parameters + * @param callback The callback + */ + update( + endpoint: string, + id: string, + options: Models.CommunicationIdentityUpdateOptionalParams, + callback: coreHttp.ServiceCallback + ): void; + update( + endpoint: string, + id: string, + options?: Models.CommunicationIdentityUpdateOptionalParams | coreHttp.ServiceCallback, + callback?: coreHttp.ServiceCallback + ): Promise { + return this.client.sendOperationRequest( + { + endpoint, + id, + options + }, + updateOperationSpec, + callback + ); + } + + /** + * @summary Generate a new token for an identity. + * @param endpoint Auth and Identity endpoint + * @param id Identifier of the identity to issue token for. + * @param scopes List of scopes attached to the token. + * @param [options] The optional parameters + * @returns Promise + */ + issueToken( + endpoint: string, + id: string, + scopes: string[], + options?: coreHttp.RequestOptionsBase + ): Promise; + /** + * @param endpoint Auth and Identity endpoint + * @param id Identifier of the identity to issue token for. + * @param scopes List of scopes attached to the token. + * @param callback The callback + */ + issueToken( + endpoint: string, + id: string, + scopes: string[], + callback: coreHttp.ServiceCallback + ): void; + /** + * @param endpoint Auth and Identity endpoint + * @param id Identifier of the identity to issue token for. + * @param scopes List of scopes attached to the token. + * @param options The optional parameters + * @param callback The callback + */ + issueToken( + endpoint: string, + id: string, + scopes: string[], + options: coreHttp.RequestOptionsBase, + callback: coreHttp.ServiceCallback + ): void; + issueToken( + endpoint: string, + id: string, + scopes: string[], + options?: + | coreHttp.RequestOptionsBase + | coreHttp.ServiceCallback, + callback?: coreHttp.ServiceCallback + ): Promise { + return this.client.sendOperationRequest( + { + endpoint, + id, + scopes, + options + }, + issueTokenOperationSpec, + callback + ) as Promise; + } +} + +// Operation Specifications +const serializer = new coreHttp.Serializer(Mappers); +const createOperationSpec: coreHttp.OperationSpec = { + httpMethod: "POST", + path: "identities", + urlParameters: [Parameters.endpoint], + queryParameters: [Parameters.apiVersion], + responses: { + 200: { + bodyMapper: Mappers.CommunicationIdentity + }, + default: {} + }, + serializer +}; + +const deleteMethodOperationSpec: coreHttp.OperationSpec = { + httpMethod: "DELETE", + path: "identities/{id}", + urlParameters: [Parameters.endpoint, Parameters.id], + queryParameters: [Parameters.apiVersion], + responses: { + 204: {}, + default: {} + }, + serializer +}; + +const updateOperationSpec: coreHttp.OperationSpec = { + httpMethod: "PATCH", + path: "identities/{id}", + urlParameters: [Parameters.endpoint, Parameters.id], + queryParameters: [Parameters.apiVersion], + requestBody: { + parameterPath: { + tokensValidFrom: ["options", "tokensValidFrom"] + }, + mapper: { + ...Mappers.CommunicationIdentityUpdateRequest, + required: true + } + }, + contentType: "application/merge-patch+json", + responses: { + 204: {}, + default: {} + }, + serializer +}; + +const issueTokenOperationSpec: coreHttp.OperationSpec = { + httpMethod: "POST", + path: "identities/{id}/token", + urlParameters: [Parameters.endpoint, Parameters.id], + queryParameters: [Parameters.apiVersion], + requestBody: { + parameterPath: { + scopes: "scopes" + }, + mapper: { + ...Mappers.CommunicationTokenRequest, + required: true + } + }, + responses: { + 200: { + bodyMapper: Mappers.CommunicationIdentityToken + }, + default: {} + }, + serializer +}; diff --git a/sdk/communication/communication-administration/src/communicationIdentity/generated/src/operations/index.ts b/sdk/communication/communication-administration/src/communicationIdentity/generated/src/operations/index.ts new file mode 100644 index 000000000000..bda865874f7c --- /dev/null +++ b/sdk/communication/communication-administration/src/communicationIdentity/generated/src/operations/index.ts @@ -0,0 +1,11 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is + * regenerated. + */ + +export * from "./communicationIdentityOperations"; diff --git a/sdk/communication/communication-administration/src/communicationIdentity/models.ts b/sdk/communication/communication-administration/src/communicationIdentity/models.ts new file mode 100644 index 000000000000..bef1654e887a --- /dev/null +++ b/sdk/communication/communication-administration/src/communicationIdentity/models.ts @@ -0,0 +1,48 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { HttpResponse, PipelineOptions } from "@azure/core-http"; +import { CommunicationUser } from "@azure/communication-common"; +import { CommunicationIdentityToken } from "./generated/src/models"; + +/** + * Represents the scope of the token. + */ +export type TokenScope = "chat" | "voip" | "pstn"; + +/** + * Client options used to configure the CommunicationIdentity API requests. + */ +export interface CommunicationIdentityOptions extends PipelineOptions {} + +/** + * Represents an object with a non-enumerable _response property which provides + * information about the HTTP response. + */ +export type WithResponse = T & { _response: HttpResponse }; + +/** + * Represents a generic HTTP response + */ +export type VoidResponse = WithResponse<{}>; + +/** + * The issued token and the user it was issued for. + */ +export interface CommunicationUserToken + extends Pick { + /** + * Represents the user the token was issued for + */ + user: CommunicationUser; +} + +/** + * Represents the response from creating a user + */ +export type CreateUserResponse = WithResponse; + +/** + * Represents the response from issuing a token + */ +export type IssueTokenResponse = WithResponse; diff --git a/sdk/communication/communication-administration/src/index.ts b/sdk/communication/communication-administration/src/index.ts new file mode 100644 index 000000000000..145213d3f1e5 --- /dev/null +++ b/sdk/communication/communication-administration/src/index.ts @@ -0,0 +1,5 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +export * from "./communicationIdentity/communicationIdentityClient"; +export * from "./communicationIdentity/models"; diff --git a/sdk/communication/communication-administration/swagger/CommunicationIdentity.md b/sdk/communication/communication-administration/swagger/CommunicationIdentity.md new file mode 100644 index 000000000000..f82df99de6e7 --- /dev/null +++ b/sdk/communication/communication-administration/swagger/CommunicationIdentity.md @@ -0,0 +1,22 @@ +# Azure Communication Services Configuration Module + +> see https://aka.ms/autorest + +## Configuration + +```yaml +package-name: azure-communication-administration-identity +title: CommunicationIdentityConfigurationClient +override-client-name: GeneratedCommunicationIdentityClient +description: Communication identity configuration client +package-version: 1.0.0-beta.1 +generate-metadata: false +license-header: MICROSOFT_MIT_NO_VERSION +output-folder: ../src/communicationIdentity/generated +input-file: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/838c5092f11e8ca26e262b1f1099d5c5cdfedc3f/specification/communication/data-plane/Microsoft.CommunicationServicesIdentity/preview/2020-07-20-preview2/CommunicationIdentity.json +model-date-time-as-string: false +optional-response-headers: true +payload-flattening-threshold: 10 +use: "@microsoft.azure/autorest.typescript@5.0.1" +azure-arm: false +``` diff --git a/sdk/communication/communication-administration/test/README.md b/sdk/communication/communication-administration/test/README.md new file mode 100644 index 000000000000..219d112a3086 --- /dev/null +++ b/sdk/communication/communication-administration/test/README.md @@ -0,0 +1,19 @@ +# Testing + +To test this project, make sure to build it by following our [building instructions](https://github.com/Azure/azure-sdk-for-js/blob/master/CONTRIBUTING.md#building), then follow the [testing instructions](https://github.com/Azure/azure-sdk-for-js/blob/master/CONTRIBUTING.md#testing). + +You can use existing Azure resources for the live tests, or generate new ones by using our [New-TestResources.ps1](https://github.com/Azure/azure-sdk-for-js/blob/master/eng/common/TestResources/New-TestResources.ps1) script, which will use an [ARM template](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/textanalytics/test-resources.json) that already has all of the the necessary configurations. + +The Azure resource that is used by the tests in this project is: + +- An existing Communication Services resource. If you need to create the resource, you can use the [Azure Portal][azure_portal] or [Azure CLI][azure_cli]. + +To run the live tests, you will need to set the below environment variables: + +- `TEST_MODE`: Should have `live` assigned if you want to run live without recording. Assign `record` to run live with recording. +- `COMMUNICATION_CONNECTION_STRING`: The primary connection string of the Communication Services resource in your account. + +[azure_sub]: https://azure.microsoft.com/free/ +[azure_portal]: https://portal.azure.com + +![Impressions](https://azure-sdk-impressions.azurewebsites.net/api/impressions/azure-sdk-for-js%2Fsdk%2Fcommunication%2Fcommunication-administration%2FREADME.png) diff --git a/sdk/communication/communication-administration/test/communicationIdentityClient.mocked.spec.ts b/sdk/communication/communication-administration/test/communicationIdentityClient.mocked.spec.ts new file mode 100644 index 000000000000..4d8f6dca3b27 --- /dev/null +++ b/sdk/communication/communication-administration/test/communicationIdentityClient.mocked.spec.ts @@ -0,0 +1,109 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { isNode } from "@azure/core-http"; +import { CommunicationUser, isCommunicationUser } from "@azure/communication-common"; +import { assert } from "chai"; +import sinon from "sinon"; +import { CommunicationIdentityClient } from "../src"; +import { TestCommunicationIdentityClient } from "./utils/testCommunicationIdentityClient"; +import { issueTokenHttpClient, revokeTokensHttpClient } from "./utils/mockHttpClients"; + +describe("CommunicationIdentityClient [Mocked]", () => { + const dateHeader = isNode ? "date" : "x-ms-date"; + const user: CommunicationUser = { communicationUserId: "ACS_ID" }; + + afterEach(() => { + sinon.restore(); + }); + + it("creates instance of CommunicationIdentityClient", () => { + const client = new CommunicationIdentityClient( + "endpoint=https://contoso.spool.azure.local;accesskey=banana" + ); + assert.instanceOf(client, CommunicationIdentityClient); + }); + + it("sets correct headers", async () => { + const client = new TestCommunicationIdentityClient(); + const spy = sinon.spy(issueTokenHttpClient, "sendRequest"); + + await client.issueTokenTest(user, ["chat"]); + sinon.assert.calledOnce(spy); + + const request = spy.getCall(0).args[0]; + + if (isNode) { + assert.equal(request.headers.get("host"), "contoso.spool.azure.local"); + } + + assert.typeOf(request.headers.get(dateHeader), "string"); + assert.isDefined(request.headers.get("authorization")); + assert.match( + request.headers.get("authorization") as string, + /HMAC-SHA256 SignedHeaders=.+&Signature=.+/ + ); + }); + + it("sends scopes in issue token request", async () => { + const client = new TestCommunicationIdentityClient(); + const spy = sinon.spy(issueTokenHttpClient, "sendRequest"); + const response = await client.issueTokenTest(user, ["chat"]); + + assert.equal(response.user.communicationUserId, "identity"); + assert.equal(response.token, "token"); + assert.equal(response.expiresOn.toDateString(), new Date("2011/11/30").toDateString()); + sinon.assert.calledOnce(spy); + + const request = spy.getCall(0).args[0]; + assert.deepEqual(JSON.parse(request.body), { scopes: ["chat"] }); + }); + + it("[issueToken] excludes _response from results when stringified", async () => { + const client = new TestCommunicationIdentityClient(); + const response = await client.issueTokenTest(user, ["chat"]); + + assert.isDefined(response._response); + assert.isTrue(JSON.stringify(response).indexOf("token") > -1); + assert.isFalse(JSON.stringify(response).indexOf("_response") > -1); + }); + + it("[createUser] excludes _response from results when stringified", async () => { + const client = new TestCommunicationIdentityClient(); + const user = await client.createUserTest(); + + assert.isTrue(isCommunicationUser(user)); + assert.equal(user.communicationUserId, "identity"); + assert.isDefined(user._response); + assert.isTrue(JSON.stringify(user).indexOf("id") > -1); + assert.isFalse(JSON.stringify(user).indexOf("_response") > -1); + }); + + it("sends current datetime as value of tokensValidFrom if not passed to revokeTokens", async () => { + const client = new TestCommunicationIdentityClient(); + const spy = sinon.spy(revokeTokensHttpClient, "sendRequest"); + + await client.revokeTokensTest(user); + sinon.assert.calledOnce(spy); + + const request = spy.getCall(0).args[0]; + const { tokensValidFrom: received } = JSON.parse(request.body); + + assert.isNotNaN(Date.parse(received)); + }); + + it("sends tokensValidFrom in revoke tokens request", async () => { + const client = new TestCommunicationIdentityClient(); + const spy = sinon.spy(revokeTokensHttpClient, "sendRequest"); + const tokensValidFrom = new Date("2011/11/30"); + + await client.revokeTokensTest(user, tokensValidFrom); + sinon.assert.calledOnce(spy); + + const request = spy.getCall(0).args[0]; + const { tokensValidFrom: received } = JSON.parse(request.body); + const expected = tokensValidFrom.toISOString(); + + assert.equal(received, expected); + }); +}); diff --git a/sdk/communication/communication-administration/test/communicationIdentityClient.spec.ts b/sdk/communication/communication-administration/test/communicationIdentityClient.spec.ts new file mode 100644 index 000000000000..40e11d38bbaf --- /dev/null +++ b/sdk/communication/communication-administration/test/communicationIdentityClient.spec.ts @@ -0,0 +1,63 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { CommunicationUser } from "@azure/communication-common"; +import { assert } from "chai"; +import { isPlaybackMode, Recorder } from "@azure/test-utils-recorder"; +import { CommunicationIdentityClient } from "../src"; +import { createRecordedCommunicationIdentityClient } from "./utils/recordedClient"; + +describe("CommunicationIdentityClient [Playback/Live]", function() { + let user: CommunicationUser; + let recorder: Recorder; + let client: CommunicationIdentityClient; + + beforeEach(function() { + ({ client, recorder } = createRecordedCommunicationIdentityClient(this)); + }); + + afterEach(async function() { + if (!this.currentTest?.isPending()) { + await recorder.stop(); + } + }); + + it("successfully creates a user", async function() { + user = await client.createUser(); + assert.isString(user.communicationUserId); + }); + + it("successfully issues a token for a user [single scope]", async function() { + const { token, expiresOn, user: receivedUser } = await client.issueToken(user, ["chat"]); + assert.isString(token); + assert.instanceOf(expiresOn, Date); + assert.deepEqual(receivedUser, user); + }); + + it("successfully issues a token for a user [multiple scopes]", async function() { + const { token, expiresOn, user: receivedUser } = await client.issueToken(user, [ + "chat", + "pstn" + ]); + assert.isString(token); + assert.instanceOf(expiresOn, Date); + assert.deepEqual(receivedUser, user); + }); + + it("successfully revokes tokens issued for a user", async function() { + const { _response: response } = await client.revokeTokens( + user, + // Must set tokensValidFrom if in playback mode so date strings will match + // when Nock searches for requests + isPlaybackMode() ? new Date("2020-10-10T00:00:00.000Z") : undefined + ); + assert.equal(response.status, 204); + const { tokensValidFrom } = JSON.parse(response.request.body); + assert.isNotNaN(Date.parse(tokensValidFrom)); + }); + + it("successfully deletes a user", async function() { + const { _response: response } = await client.deleteUser(user); + assert.equal(response.status, 204); + }).timeout(20000); +}); diff --git a/sdk/communication/communication-administration/test/utils/mockHttpClients.ts b/sdk/communication/communication-administration/test/utils/mockHttpClients.ts new file mode 100644 index 000000000000..3a07f402b634 --- /dev/null +++ b/sdk/communication/communication-administration/test/utils/mockHttpClients.ts @@ -0,0 +1,33 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { HttpClient, WebResourceLike, HttpOperationResponse, HttpHeaders } from "@azure/core-http"; +import { CommunicationIdentityToken } from "../../src"; +import { CommunicationIdentity } from "../../src/communicationIdentity/generated/src/models"; + +export const createMockHttpClient = (status: number = 200, parsedBody?: T): HttpClient => { + return { + async sendRequest(httpRequest: WebResourceLike): Promise { + return { + status, + headers: new HttpHeaders(), + request: httpRequest, + parsedBody + }; + } + }; +}; + +const tokenResponse = { + id: "identity", + token: "token", + expiresOn: new Date("2011/11/30") +}; +export const issueTokenHttpClient: HttpClient = createMockHttpClient( + 200, + tokenResponse +); +export const revokeTokensHttpClient: HttpClient = createMockHttpClient(204); +export const createUserHttpClient: HttpClient = createMockHttpClient(200, { + id: "identity" +}); diff --git a/sdk/communication/communication-administration/test/utils/recordedClient.ts b/sdk/communication/communication-administration/test/utils/recordedClient.ts new file mode 100644 index 000000000000..48dde8b490b7 --- /dev/null +++ b/sdk/communication/communication-administration/test/utils/recordedClient.ts @@ -0,0 +1,69 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { Context } from "mocha"; +import * as dotenv from "dotenv"; + +import { env, Recorder, record, RecorderEnvironmentSetup } from "@azure/test-utils-recorder"; +import { isNode } from "@azure/core-http"; +import { CommunicationIdentityClient } from "../../src"; + +if (isNode) { + dotenv.config(); +} + +export interface RecordedClient { + client: CommunicationIdentityClient; + recorder: Recorder; +} + +const replaceableVariables: { [k: string]: string } = { + COMMUNICATION_CONNECTION_STRING: "endpoint=https://endpoint/;accesskey=banana" +}; + +export const testEnv = new Proxy(replaceableVariables, { + get: (target, key: string) => { + return env[key] || target[key]; + } +}); + +export const environmentSetup: RecorderEnvironmentSetup = { + replaceableVariables, + customizationsOnRecordings: [ + (recording: string): string => + recording.replace(/"token"\s?:\s?"[^"]*"/g, `"token":"sanitized"`), + (recording: string): string => recording.replace(/(https:\/\/)([^\/',]*)/, "$1endpoint"), + /** + * Must replace date saved to tokensValidFrom as to not + * break playback tests. + */ + (recording: string): string => { + return recording.replace( + /"tokensValidFrom"\s?:\s?"[^"]*"/g, + `"tokensValidFrom":"2020-10-10T00:00:00.000Z"` + ); + }, + (recording: string): string => recording.replace(/"id"\s?:\s?"[^"]*"/g, `"id":"sanitized"`), + (recording: string): string => { + return recording.replace( + /(https:\/\/[^\/',]*\/identities\/)[^\/',]*(\/token)/, + "$1sanitized$2" + ); + }, + (recording: string): string => + recording.replace(/\/identities\/[^\/'",]*/, "/identities/sanitized") + ], + queryParametersToSkip: [] +}; + +export function createRecordedCommunicationIdentityClient( + context: Context, + connectionString: string = testEnv.COMMUNICATION_CONNECTION_STRING +): RecordedClient { + const recorder = record(context, environmentSetup); + + return { + client: new CommunicationIdentityClient(connectionString), + recorder + }; +} diff --git a/sdk/communication/communication-administration/test/utils/testCommunicationIdentityClient.ts b/sdk/communication/communication-administration/test/utils/testCommunicationIdentityClient.ts new file mode 100644 index 000000000000..73c08cfc9e99 --- /dev/null +++ b/sdk/communication/communication-administration/test/utils/testCommunicationIdentityClient.ts @@ -0,0 +1,49 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { OperationOptions, RestResponse } from "@azure/core-http"; +import { CommunicationUser } from "@azure/communication-common"; +import { + CommunicationIdentityClient, + TokenScope, + IssueTokenResponse, + CreateUserResponse +} from "../../src"; +import { + issueTokenHttpClient, + createUserHttpClient, + revokeTokensHttpClient +} from "./mockHttpClients"; + +export class TestCommunicationIdentityClient { + private connectionString: string = "endpoint=https://contoso.spool.azure.local;accesskey=banana"; + + public async issueTokenTest( + user: CommunicationUser, + scopes: TokenScope[], + options: OperationOptions = {} + ): Promise { + const client = new CommunicationIdentityClient(this.connectionString, { + httpClient: issueTokenHttpClient + }); + return client.issueToken(user, scopes, options); + } + + public async revokeTokensTest( + user: CommunicationUser, + revocationTime?: Date, + options: OperationOptions = {} + ): Promise { + const client = new CommunicationIdentityClient(this.connectionString, { + httpClient: revokeTokensHttpClient + }); + return client.revokeTokens(user, revocationTime, options); + } + + public async createUserTest(options: OperationOptions = {}): Promise { + const client = new CommunicationIdentityClient(this.connectionString, { + httpClient: createUserHttpClient + }); + return client.createUser(options); + } +} diff --git a/sdk/communication/communication-administration/tests.yml b/sdk/communication/communication-administration/tests.yml new file mode 100644 index 000000000000..b9277f1edcc7 --- /dev/null +++ b/sdk/communication/communication-administration/tests.yml @@ -0,0 +1,8 @@ +trigger: none + +extends: + template: ../../../eng/pipelines/templates/jobs/archetype-sdk-integration.yml + parameters: + PackageName: "@azure/communication-administration" + ResourceServiceDirectory: communication + \ No newline at end of file diff --git a/sdk/communication/communication-administration/tsconfig.json b/sdk/communication/communication-administration/tsconfig.json new file mode 100644 index 000000000000..01b339f5a963 --- /dev/null +++ b/sdk/communication/communication-administration/tsconfig.json @@ -0,0 +1,17 @@ +{ + "extends": "../../../tsconfig.package", + "compilerOptions": { + "outDir": "./dist-esm", + "declarationDir": "./types" + }, + "exclude": [ + "node_modules", + "types", + "temp", + "browser", + "dist", + "dist-esm", + "dist-samples", + "./samples/**/*.ts" + ] +} diff --git a/sdk/communication/communication-chat/.eslintrc.json b/sdk/communication/communication-chat/.eslintrc.json new file mode 100644 index 000000000000..9bd67fdc87a5 --- /dev/null +++ b/sdk/communication/communication-chat/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "plugins": ["@azure/azure-sdk"], + "extends": ["plugin:@azure/azure-sdk/azure-sdk-base"], + "rules": { + "@azure/azure-sdk/ts-naming-options": "off" + // "@azure/azure-sdk/ts-config-declaration": "off", + // "@azure/azure-sdk/ts-config-allowsyntheticdefaultimports": "off", + // "@azure/azure-sdk/ts-config-esmoduleinterop": "off", + // "@azure/azure-sdk/ts-config-forceconsistentcasinginfilenames": "off", + // "@azure/azure-sdk/ts-config-importhelpers": "off", + // "@azure/azure-sdk/ts-config-module": "off", + // "@azure/azure-sdk/ts-config-moduleresolution": "off", + // "@azure/azure-sdk/ts-config-sourcemap": "off", + // "@azure/azure-sdk/ts-config-strict": "off", + // "@azure/azure-sdk/ts-config-target": "off", + // "@azure/azure-sdk/ts-config-lib": "off" + } +} diff --git a/sdk/communication/communication-chat/.gitignore b/sdk/communication/communication-chat/.gitignore new file mode 100644 index 000000000000..e35e6c4bbeb0 --- /dev/null +++ b/sdk/communication/communication-chat/.gitignore @@ -0,0 +1 @@ +/**/code-model-v* \ No newline at end of file diff --git a/sdk/communication/communication-chat/.vscode/launch.json b/sdk/communication/communication-chat/.vscode/launch.json new file mode 100644 index 000000000000..458b9b5c32c6 --- /dev/null +++ b/sdk/communication/communication-chat/.vscode/launch.json @@ -0,0 +1,45 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "node", + "request": "launch", + "name": "Debug Mocha Test [Without Rollup]", + "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha", + "args": [ + "-r", + "ts-node/register", + "--timeout", + "999999", + "--colors", + "${workspaceFolder}/test/*.spec.ts", + "${workspaceFolder}/test/node/*.spec.ts" + ], + "env": { + "TS_NODE_COMPILER_OPTIONS": "{\"module\": \"commonjs\"}" + }, + "console": "integratedTerminal", + "internalConsoleOptions": "neverOpen", + "protocol": "inspector" + }, + { + "type": "node", + "request": "launch", + "name": "Debug Unit Tests", + "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha", + "args": [ + "-u", + "tdd", + "--timeout", + "999999", + "--colors", + "${workspaceFolder}/dist-test/index.node.js" + ], + "internalConsoleOptions": "openOnSessionStart", + "preLaunchTask": "npm: build:test" + } + ] +} diff --git a/sdk/communication/communication-chat/.vscode/tasks.json b/sdk/communication/communication-chat/.vscode/tasks.json new file mode 100644 index 000000000000..83bb44526db4 --- /dev/null +++ b/sdk/communication/communication-chat/.vscode/tasks.json @@ -0,0 +1,16 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "Build Node", + "type": "npm", + "script": "build:node", + "group": { + "kind": "build", + "isDefault": true + } + } + ] +} diff --git a/sdk/communication/communication-chat/CHANGELOG.md b/sdk/communication/communication-chat/CHANGELOG.md new file mode 100644 index 000000000000..b2c7e4ac4197 --- /dev/null +++ b/sdk/communication/communication-chat/CHANGELOG.md @@ -0,0 +1,13 @@ +# Release History + +## 1.0.0-beta.1 (2020-09-22) + +The first preview of the Azure Communication Chat Client has the following features: + +- create/get/update/delete a chat thread +- list all chat threads the user join +- create/get/update/delete a chat message +- list all chat messages in a chat thread +- add members in a chat thread +- delete a member in a chat thread +- list all members in a chat thread diff --git a/sdk/communication/communication-chat/LICENSE b/sdk/communication/communication-chat/LICENSE new file mode 100644 index 000000000000..ea8fb1516028 --- /dev/null +++ b/sdk/communication/communication-chat/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2020 Microsoft + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/sdk/communication/communication-chat/README.md b/sdk/communication/communication-chat/README.md new file mode 100644 index 000000000000..c4b112c92c77 --- /dev/null +++ b/sdk/communication/communication-chat/README.md @@ -0,0 +1,190 @@ +# Azure Communication Chat client library for JavaScript + +Azure Communication Services for Chat let developers add Chat capabilities to their app. Use this client library to manage chat threads and their users, and send and receive Chat messages. + +Read more about Azure Communication Services [here](https://review.docs.microsoft.com/azure/project-spool/overview?branch=pr-en-us-104477) + +## Getting started + +## Prerequisites + +- An [Azure subscription][azure_sub]. +- An existing Communication Services resource. If you need to create the resource, you can use the [Azure Portal][azure_portal] or [Azure CLI][azure_cli]. +- [Node.js](https://nodejs.org) + +### Installing + +```bash +npm install @azure/communication-chat +``` + +## Key concepts + +A chat conversation is represented by a thread. Each user in the thread is called a thread member. Thread members can chat with one another privately in a 1:1 chat or huddle up in a 1:N group chat. Users also get near-real time updates for when others are typing and when they have read the messages. + +### ChatClient + +`ChatClient` is the primary interface for developers using this client library. It provides asynchronous methods to create and delete a thread. + +### ChatThreadClient + +`ChatThreadClient` provides asynchronous methods to do the message and chat thread members operations within the chat thread. + +## Examples + +### Initialize ChatClient + +Use resource url and user access token to initialize chat client. + +```JavaScript +import { ChatClient } from '@azure/communicationservices-chat'; +import { AzureCommunicationUserCredential } from "@azure/communication-common"; + +// Your unique Azure Communication service endpoint +let endpointUrl = ''; +let userAccessToken = ''; +let userCredential = new AzureCommunicationUserCredential(userAccessToken); +let chatClient = new ChatClient(endpointUrl, userCredential); + +``` + +### Create a thread with two users + +Use the `createThread` method to create a chat thread. + +`createThreadRequest` is used to describe the thread request: + +- Use `topic` to give a thread topic; +- Use `members` to list the thread members to be added to the thread; + +`chatThreadClient` is the response returned from creating a thread, it contains an `threadId` which is the unique ID of the thread. + +```Javascript +let createThreadRequest = +{ + topic: 'Preparation for London conference', + members: + [ + { + user: { communicationUserId: '' }, + displayName: 'Jack' + }, + { + user: { communicationUserId: '' }, + displayName: 'Geeta' + } + ] +}; +let chatThreadClient= await chatClient.createChatThread(createThreadRequest); +let threadId = chatThreadClient.threadId; +``` + +### Send a message to the thread + +Use `sendMessage` method to sends a message to a thread identified by threadId. + +`sendMessageRequest` is used to describe the message request: + +- Use `content` to provide the chat message content; + +`sendMessageOptions` is used to describe the operation optional params: + +- Use `priority` to specify the message priority level, such as 'Normal' or 'High' ; +- Use `senderDisplayName` to specify the display name of the sender; + +`sendChatMessageResult` is the response returned from sending a message, it contains an ID, which is the unique ID of the message. + +```JavaScript +let sendMessageRequest = +{ + content: 'Hello Geeta! Can you share the deck for the conference?' +}; +let sendMessageOptions = +{ + priority: 'Normal', + senderDisplayName : 'Jack' +}; +let sendChatMessageResult = await chatThreadClient.sendMessage(sendMessageRequest, sendMessageOptions); +let messageId = sendChatMessageResult.id; +``` + +### Receive messages from a thread + +With real-time signaling, you can subscribe to listen for new incoming messages and update the current messages in memory accordingly. + +```JavaScript + +// open notifications channel +await chatClient.startRealtimeNotifications(); +// subscribe to new notification +chatClient.on("chatMessageReceived", (e) => { + console.log("Notification chatMessageReceived!"); + // your code here +}); + +``` + +Alternatively you can retrieve chat messages by polling the `listMessages` method at specified intervals. + +```JavaScript +for await (const chatMessage of chatThreadClient.listMessages()) { + // your code here +} +``` + +### Add Users to a thread + +Once a thread is created, you can then add and remove users from that thread. By adding users, you give them access to be able to send messages to the thread. +You will need to start by getting a new access token and identity for that user. The user will need that access token in order to initialize their chat client. +More information on tokens here: [Authenticate to Azure Communication Services](https://review.docs.microsoft.com/azure/project-spool/concepts/authentication?branch=pr-en-us-104477&tabs=javascript) + +```JavaScript +// Get a new token created for the user. The token response will contain a token and an identity for the user. +let userTokenResponse = await myTokenFunction(); + +let addMembersRequest = +{ + members: [ + { + user: { communicationUserId: userTokenResponse.identity }, + displayName: '', + shareHistoryTime: '