Skip to content

Commit 543f70c

Browse files
authored
port: [#6813][#6798] Not able to create instance of BlobsTranscriptStore using TokenCredential instead of connectionString and containerName (#4720)
* add token credential authentication * added constructor validations * update botbuilder-azure-blobs.api
1 parent 364fae8 commit 543f70c

File tree

3 files changed

+60
-14
lines changed

3 files changed

+60
-14
lines changed

libraries/botbuilder-azure-blobs/etc/botbuilder-azure-blobs.api.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,20 +30,19 @@ export interface BlobsStorageOptions {
3030

3131
// @public
3232
export class BlobsTranscriptStore implements TranscriptStore {
33-
constructor(connectionString: string, containerName: string, options?: BlobsTranscriptStoreOptions);
33+
constructor(connectionString: string, containerName: string, options?: BlobsTranscriptStoreOptions, blobServiceUri?: string, tokenCredential?: StorageSharedKeyCredential | AnonymousCredential | TokenCredential);
3434
deleteTranscript(channelId: string, conversationId: string): Promise<void>;
3535
getTranscriptActivities(channelId: string, conversationId: string, continuationToken?: string, startDate?: Date): Promise<PagedResult<Activity>>;
3636
listTranscripts(channelId: string, continuationToken?: string): Promise<PagedResult<TranscriptInfo>>;
3737
logActivity(activity: Activity, options?: BlobsTranscriptStoreOptions): Promise<void>;
38-
}
38+
}
3939

4040
// @public
4141
export interface BlobsTranscriptStoreOptions {
4242
decodeTranscriptKey?: boolean;
4343
storagePipelineOptions?: StoragePipelineOptions;
4444
}
4545

46-
4746
// (No @packageDocumentation comment for this package)
4847

4948
```

libraries/botbuilder-azure-blobs/src/blobsTranscriptStore.ts

Lines changed: 52 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,13 @@ import { maybeCast } from 'botbuilder-stdlib';
99
import { sanitizeBlobKey } from './sanitizeBlobKey';
1010

1111
import {
12+
AnonymousCredential,
1213
ContainerClient,
1314
ContainerListBlobHierarchySegmentResponse,
1415
StoragePipelineOptions,
16+
StorageSharedKeyCredential,
1517
} from '@azure/storage-blob';
18+
import { isTokenCredential, TokenCredential } from '@azure/core-http';
1619

1720
// Formats a timestamp in a way that is consistent with the C# SDK
1821
function formatTicks(timestamp: Date): string {
@@ -45,6 +48,12 @@ function getBlobKey(activity: Activity, options?: BlobsTranscriptStoreOptions):
4548
);
4649
}
4750

51+
function isCredentialType(value: any): value is TokenCredential {
52+
return (
53+
isTokenCredential(value) || value instanceof StorageSharedKeyCredential || value instanceof AnonymousCredential
54+
);
55+
}
56+
4857
// Max number of results returned in a single Azure API call
4958
const MAX_PAGE_SIZE = 20;
5059

@@ -85,21 +94,54 @@ export class BlobsTranscriptStore implements TranscriptStore {
8594
* @param {string} connectionString Azure Blob Storage connection string
8695
* @param {string} containerName Azure Blob Storage container name
8796
* @param {BlobsTranscriptStoreOptions} options Other options for BlobsTranscriptStore
97+
* @param {string} blobServiceUri A Uri referencing the blob container that includes the name of the account and the name of the container
98+
* @param {StorageSharedKeyCredential | AnonymousCredential | TokenCredential} tokenCredential The token credential to authenticate to the Azure storage
8899
*/
89-
constructor(connectionString: string, containerName: string, options?: BlobsTranscriptStoreOptions) {
90-
z.object({ connectionString: z.string(), containerName: z.string() }).parse({
91-
connectionString,
92-
containerName,
93-
});
100+
constructor(
101+
connectionString: string,
102+
containerName: string,
103+
options?: BlobsTranscriptStoreOptions,
104+
blobServiceUri = '',
105+
tokenCredential?: StorageSharedKeyCredential | AnonymousCredential | TokenCredential
106+
) {
107+
if (blobServiceUri != '' && tokenCredential != null) {
108+
z.object({ blobServiceUri: z.string() }).parse({
109+
blobServiceUri,
110+
});
94111

95-
this._containerClient = new ContainerClient(connectionString, containerName, options?.storagePipelineOptions);
112+
if (typeof tokenCredential != 'object' || !isCredentialType(tokenCredential)) {
113+
throw new ReferenceError('Invalid credential type.');
114+
}
96115

97-
this._isDecodeTranscriptKey = options?.decodeTranscriptKey;
116+
this._containerClient = new ContainerClient(
117+
blobServiceUri,
118+
tokenCredential,
119+
options?.storagePipelineOptions
120+
);
98121

99-
// At most one promise at a time to be friendly to local emulator users
100-
if (connectionString.trim() === 'UseDevelopmentStorage=true;') {
101-
this._concurrency = 1;
122+
// At most one promise at a time to be friendly to local emulator users
123+
if (blobServiceUri.trim() === 'UseDevelopmentStorage=true;') {
124+
this._concurrency = 1;
125+
}
126+
} else {
127+
z.object({ connectionString: z.string(), containerName: z.string() }).parse({
128+
connectionString,
129+
containerName,
130+
});
131+
132+
this._containerClient = new ContainerClient(
133+
connectionString,
134+
containerName,
135+
options?.storagePipelineOptions
136+
);
137+
138+
// At most one promise at a time to be friendly to local emulator users
139+
if (connectionString.trim() === 'UseDevelopmentStorage=true;') {
140+
this._concurrency = 1;
141+
}
102142
}
143+
144+
this._isDecodeTranscriptKey = options?.decodeTranscriptKey;
103145
}
104146

105147
// Protects against JSON.stringify cycles

libraries/botbuilder-azure-blobs/tests/blobsTranscriptStore.test.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ const containerName = process.env.AZURE_BLOB_STORAGE_CONTAINER;
1111
const maybeClient = () =>
1212
connectionString && containerName ? new BlobsTranscriptStore(connectionString, containerName) : null;
1313

14-
describe('BlobsStorage', function () {
14+
describe('BlobsTranscriptStore', function () {
1515
const client = maybeClient();
1616
const maybeIt = client ? it : it.skip;
1717

@@ -69,6 +69,11 @@ describe('BlobsStorage', function () {
6969
it('throws for bad args', function () {
7070
assert.throws(() => new BlobsTranscriptStore(), 'throws for missing connectionString');
7171
assert.throws(() => new BlobsTranscriptStore('connectionString'), 'throws for missing containerName');
72+
assert.throws(() => new BlobsTranscriptStore(null, null, null, [], {}), 'throws for missing url');
73+
assert.throws(
74+
() => new BlobsTranscriptStore(null, null, null, 'url', {}),
75+
ReferenceError('Invalid credential type.')
76+
);
7277
});
7378

7479
it('succeeds for good args', function () {

0 commit comments

Comments
 (0)