Skip to content

Commit

Permalink
@azure/communication-common Azure Core 2.0 Migration (#20337)
Browse files Browse the repository at this point in the history
* migrated clientArguments, removed circular deps

* removed the dependency on @azure/core-http

* policy converted to core rest pipeline

* removed the old policy, bumped major version

* added a changelog entry

* added test

* updated pnpm file
  • Loading branch information
petrsvihlik authored Feb 25, 2022
1 parent c2ae230 commit a595cb2
Show file tree
Hide file tree
Showing 23 changed files with 471 additions and 443 deletions.
426 changes: 216 additions & 210 deletions common/config/rush/pnpm-lock.yaml

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion sdk/communication/communication-common/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
# Release History

## 1.2.0 (Unreleased)
## 2.0.0 (Unreleased)

### Features Added

- Optimization added: When the proactive refreshing is enabled and the token refresher fails to provide a token that's not about to expire soon, the subsequent refresh attempts will be scheduled for when the token reaches half of its remaining lifetime until a token with long enough validity (>10 minutes) is obtained.

### Breaking Changes

- Migrated from using `@azure/core-http` to `@azure/core-rest-pipeline` for the handling of HTTP requests. See [Azure Core v1 vs v2](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/core/core-rest-pipeline/documentation/core2.md) for more on the difference and benefits of the move.
- `createCommunicationAccessKeyCredentialPolicy` and `createCommunicationAuthPolicy` newly return `PipelinePolicy` instead of `RequestPolicyFactory`.

### Bugs Fixed

### Other Changes
Expand Down
7 changes: 4 additions & 3 deletions sdk/communication/communication-common/package.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
{
"name": "@azure/communication-common",
"version": "1.2.0",
"version": "2.0.0",
"description": "Common package for Azure Communication services.",
"sdk-type": "client",
"main": "dist/index.js",
"module": "dist-esm/src/index.js",
"types": "types/communication-common.d.ts",
"browser": {
"./dist-esm/src/credential/cryptoUtils.js": "./dist-esm/src/credential/cryptoUtils.browser.js"
"./dist-esm/src/credential/cryptoUtils.js": "./dist-esm/src/credential/cryptoUtils.browser.js",
"./dist-esm/src/credential/isNode.js": "./dist-esm/src/credential/isNode.browser.js"
},
"scripts": {
"audit": "node ../../../common/scripts/rush-audit.js && rimraf node_modules package-lock.json && npm i --package-lock-only 2>&1 && npm audit",
Expand Down Expand Up @@ -63,7 +64,7 @@
"dependencies": {
"@azure/abort-controller": "^1.0.0",
"@azure/core-auth": "^1.3.0",
"@azure/core-http": "^2.0.0",
"@azure/core-rest-pipeline": "^1.3.2",
"@azure/core-tracing": "1.0.0-preview.13",
"events": "^3.0.0",
"jwt-decode": "^3.1.2",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
```ts

import { AbortSignalLike } from '@azure/core-http';
import { AccessToken } from '@azure/core-http';
import { AbortSignalLike } from '@azure/abort-controller';
import { AccessToken } from '@azure/core-auth';
import { KeyCredential } from '@azure/core-auth';
import { RequestPolicyFactory } from '@azure/core-http';
import { PipelinePolicy } from '@azure/core-rest-pipeline';
import { TokenCredential } from '@azure/core-auth';

// @public
Expand All @@ -16,7 +16,7 @@ export class AzureCommunicationTokenCredential implements CommunicationTokenCred
constructor(refreshOptions: CommunicationTokenRefreshOptions);
dispose(): void;
getToken(options?: CommunicationGetTokenOptions): Promise<AccessToken>;
}
}

// @public
export interface CommunicationGetTokenOptions {
Expand Down Expand Up @@ -53,10 +53,10 @@ export interface CommunicationUserKind extends CommunicationUserIdentifier {
}

// @public
export const createCommunicationAccessKeyCredentialPolicy: (credential: KeyCredential) => RequestPolicyFactory;
export function createCommunicationAccessKeyCredentialPolicy(credential: KeyCredential): PipelinePolicy;

// @public
export const createCommunicationAuthPolicy: (credential: KeyCredential | TokenCredential) => RequestPolicyFactory;
export function createCommunicationAuthPolicy(credential: KeyCredential | TokenCredential): PipelinePolicy;

// @public
export const deserializeCommunicationIdentifier: (serializedIdentifier: SerializedCommunicationIdentifier) => CommunicationIdentifierKind;
Expand Down Expand Up @@ -162,7 +162,6 @@ export type UrlWithCredential = {
credential: TokenCredential | KeyCredential;
};


// (No @packageDocumentation comment for this package)

```
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import { AbortSignalLike, AccessToken } from "@azure/core-http";
import { CommunicationGetTokenOptions, TokenCredential } from "./communicationTokenCredential";
import { AbortSignalLike } from "@azure/abort-controller";
import { AccessToken } from "@azure/core-auth";
import { parseToken } from "./tokenParser";
import { TokenCredential, CommunicationGetTokenOptions } from "./communicationTokenCredential";

/**
* Options for auto-refreshing a Communication Token credential.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import {
AutoRefreshTokenCredential,
CommunicationTokenRefreshOptions,
} from "./autoRefreshTokenCredential";
import {
CommunicationGetTokenOptions,
CommunicationTokenCredential,
TokenCredential,
} from "./communicationTokenCredential";
import { AccessToken } from "@azure/core-auth";
import { StaticTokenCredential } from "./staticTokenCredential";
import { parseToken } from "./tokenParser";

/**
* The CommunicationTokenCredential implementation with support for proactive token refresh.
*/

export class AzureCommunicationTokenCredential implements CommunicationTokenCredential {
private readonly tokenCredential: TokenCredential;
private disposed = false;

/**
* Creates an instance of CommunicationTokenCredential with a static token and no proactive refreshing.
* @param token - A user access token issued by Communication Services.
*/
constructor(token: string);
/**
* Creates an instance of CommunicationTokenCredential with a lambda to get a token and options
* to configure proactive refreshing.
* @param refreshOptions - Options to configure refresh and opt-in to proactive refreshing.
*/
constructor(refreshOptions: CommunicationTokenRefreshOptions);
constructor(tokenOrRefreshOptions: string | CommunicationTokenRefreshOptions) {
if (typeof tokenOrRefreshOptions === "string") {
this.tokenCredential = new StaticTokenCredential(parseToken(tokenOrRefreshOptions));
} else {
this.tokenCredential = new AutoRefreshTokenCredential(tokenOrRefreshOptions);
}
}

/**
* Gets an `AccessToken` for the user. Throws if already disposed.
* @param abortSignal - An implementation of `AbortSignalLike` to cancel the operation.
*/
public async getToken(options?: CommunicationGetTokenOptions): Promise<AccessToken> {
this.throwIfDisposed();
const token = await this.tokenCredential.getToken(options);
this.throwIfDisposed();
return token;
}

/**
* Disposes the CommunicationTokenCredential and cancels any internal auto-refresh operation.
*/
public dispose(): void {
this.disposed = true;
this.tokenCredential.dispose();
}

private throwIfDisposed(): void {
if (this.disposed) {
throw new Error("User credential is disposed");
}
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import { AbortSignalLike, AccessToken } from "@azure/core-http";
import { parseToken } from "./tokenParser";
import { StaticTokenCredential } from "./staticTokenCredential";
import {
AutoRefreshTokenCredential,
CommunicationTokenRefreshOptions,
} from "./autoRefreshTokenCredential";
import { AbortSignalLike } from "@azure/abort-controller";
import { AccessToken } from "@azure/core-auth";

export type TokenCredential = Pick<AzureCommunicationTokenCredential, "getToken" | "dispose">;
export type TokenCredential = Pick<CommunicationTokenCredential, "getToken" | "dispose">;

/**
* Options for `CommunicationTokenCredential`'s `getToken` function.
Expand All @@ -35,55 +30,3 @@ export interface CommunicationTokenCredential {
*/
dispose(): void;
}

/**
* The CommunicationTokenCredential implementation with support for proactive token refresh.
*/
export class AzureCommunicationTokenCredential implements CommunicationTokenCredential {
private readonly tokenCredential: TokenCredential;
private disposed = false;

/**
* Creates an instance of CommunicationTokenCredential with a static token and no proactive refreshing.
* @param token - A user access token issued by Communication Services.
*/
constructor(token: string);
/**
* Creates an instance of CommunicationTokenCredential with a lambda to get a token and options
* to configure proactive refreshing.
* @param refreshOptions - Options to configure refresh and opt-in to proactive refreshing.
*/
constructor(refreshOptions: CommunicationTokenRefreshOptions);
constructor(tokenOrRefreshOptions: string | CommunicationTokenRefreshOptions) {
if (typeof tokenOrRefreshOptions === "string") {
this.tokenCredential = new StaticTokenCredential(parseToken(tokenOrRefreshOptions));
} else {
this.tokenCredential = new AutoRefreshTokenCredential(tokenOrRefreshOptions);
}
}

/**
* Gets an `AccessToken` for the user. Throws if already disposed.
* @param abortSignal - An implementation of `AbortSignalLike` to cancel the operation.
*/
public async getToken(options?: CommunicationGetTokenOptions): Promise<AccessToken> {
this.throwIfDisposed();
const token = await this.tokenCredential.getToken(options);
this.throwIfDisposed();
return token;
}

/**
* Disposes the CommunicationTokenCredential and cancels any internal auto-refresh operation.
*/
public dispose(): void {
this.disposed = true;
this.tokenCredential.dispose();
}

private throwIfDisposed(): void {
if (this.disposed) {
throw new Error("User credential is disposed");
}
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import { isTokenCredential, KeyCredential, TokenCredential } from "@azure/core-auth";
import { URLBuilder } from "@azure/core-http";
import { KeyCredential, TokenCredential, isTokenCredential } from "@azure/core-auth";
import { parseConnectionString } from "./connectionString";

const isValidEndpoint = (host: string): boolean => {
const url = URLBuilder.parse(host);
const url = new URL(host);

return (
!!url.getScheme()?.match(/^http[s]?/) &&
url.getHost() !== undefined &&
url.getHost() !== "" &&
(url.getPath() === undefined || url.getPath() === "" || url.getPath() === "/")
!!url.protocol?.match(/^http[s]?/) &&
url.host !== undefined &&
url.host !== "" &&
(url.pathname === undefined || url.pathname === "" || url.pathname === "/")
);
};

Expand Down
Loading

0 comments on commit a595cb2

Please sign in to comment.