Skip to content

Commit

Permalink
fix: Cherry picks of security updates and telemetry fix. (#4192)
Browse files Browse the repository at this point in the history
* chore(deps): bump moment from 2.29.1 to 2.29.2 (#4184)

Bumps [moment](https://github.com/moment/moment) from 2.29.1 to 2.29.2.
- [Release notes](https://github.com/moment/moment/releases)
- [Changelog](https://github.com/moment/moment/blob/develop/CHANGELOG.md)
- [Commits](moment/moment@2.29.1...2.29.2)

---
updated-dependencies:
- dependency-name: moment
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore(deps): bump minimist from 1.2.5 to 1.2.6 (#4182)

Bumps [minimist](https://github.com/substack/minimist) from 1.2.5 to 1.2.6.
- [Release notes](https://github.com/substack/minimist/releases)
- [Commits](https://github.com/substack/minimist/compare/1.2.5...1.2.6)

---
updated-dependencies:
- dependency-name: minimist
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore(deps): bump minimist (#4181)

Bumps [minimist](https://github.com/substack/minimist) from 1.2.5 to 1.2.6.
- [Release notes](https://github.com/substack/minimist/releases)
- [Commits](https://github.com/substack/minimist/compare/1.2.5...1.2.6)

---
updated-dependencies:
- dependency-name: minimist
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Update update-versions script to support peerDependencies (#4167)

* fix: Azure Blob transcript key  (#4180)

* Azure Blob sanitizeBlobKey bug fix

* attempt to fix w/ backwards compatibility

* clean up

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Joel Mut <62260472+sw-joelmut@users.noreply.github.com>
Co-authored-by: Ram Fattah <38049078+ramfattah@users.noreply.github.com>
  • Loading branch information
4 people authored Apr 15, 2022
1 parent d6c6880 commit 686761a
Show file tree
Hide file tree
Showing 11 changed files with 54 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,12 @@ export class BlobsTranscriptStore implements TranscriptStore {
deleteTranscript(channelId: string, conversationId: string): Promise<void>;
getTranscriptActivities(channelId: string, conversationId: string, continuationToken?: string, startDate?: Date): Promise<PagedResult<Activity>>;
listTranscripts(channelId: string, continuationToken?: string): Promise<PagedResult<TranscriptInfo>>;
logActivity(activity: Activity): Promise<void>;
logActivity(activity: Activity, options?: BlobsTranscriptStoreOptions): Promise<void>;
}

// @public
export interface BlobsTranscriptStoreOptions {
decodeTranscriptKey?: boolean;
storagePipelineOptions?: StoragePipelineOptions;
}

Expand Down
19 changes: 15 additions & 4 deletions libraries/botbuilder-azure-blobs/src/blobsTranscriptStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,15 @@ function getConversationPrefix(channelId: string, conversationId: string): strin
}

// Formats an activity as a blob key
function getBlobKey(activity: Activity): string {
function getBlobKey(activity: Activity, options?: BlobsTranscriptStoreOptions): string {
const { timestamp } = z
.object({ timestamp: z.instanceof(Date) })
.nonstrict()
.parse(activity);

return sanitizeBlobKey(
[activity.channelId, activity.conversation.id, `${formatTicks(timestamp)}-${activity.id}.json`].join('/')
[activity.channelId, activity.conversation.id, `${formatTicks(timestamp)}-${activity.id}.json`].join('/'),
options
);
}

Expand All @@ -56,6 +57,12 @@ export interface BlobsTranscriptStoreOptions {
* storage client
*/
storagePipelineOptions?: StoragePipelineOptions;

/**
* Optional setting to return a new string representing the decoded version of the given encoded blob transcript key.
* This remains the default behavior to false, but can be overridden by setting decodeTranscriptKey to true.
*/
decodeTranscriptKey?: boolean;
}

/**
Expand All @@ -70,6 +77,7 @@ export class BlobsTranscriptStore implements TranscriptStore {
private readonly _containerClient: ContainerClient;
private readonly _concurrency = Infinity;
private _initializePromise?: Promise<unknown>;
private _isDecodeTranscriptKey?: boolean = false;

/**
* Constructs a BlobsTranscriptStore instance.
Expand All @@ -86,6 +94,8 @@ export class BlobsTranscriptStore implements TranscriptStore {

this._containerClient = new ContainerClient(connectionString, containerName, options?.storagePipelineOptions);

this._isDecodeTranscriptKey = options?.decodeTranscriptKey;

// At most one promise at a time to be friendly to local emulator users
if (connectionString.trim() === 'UseDevelopmentStorage=true;') {
this._concurrency = 1;
Expand Down Expand Up @@ -253,14 +263,15 @@ export class BlobsTranscriptStore implements TranscriptStore {
* Log an activity to the transcript.
*
* @param {Activity} activity activity to log
* @param {BlobsTranscriptStoreOptions} options Optional settings for BlobsTranscriptStore
* @returns {Promise<void>} A promise representing the async operation.
*/
async logActivity(activity: Activity): Promise<void> {
async logActivity(activity: Activity, options?: BlobsTranscriptStoreOptions): Promise<void> {
z.object({ activity: z.record(z.unknown()) }).parse({ activity });

await this._initialize();

const blob = this._containerClient.getBlockBlobClient(getBlobKey(activity));
const blob = this._containerClient.getBlockBlobClient(getBlobKey(activity, options));
const serialized = JSON.stringify(activity);

const metadata: Record<string, string> = {
Expand Down
10 changes: 9 additions & 1 deletion libraries/botbuilder-azure-blobs/src/sanitizeBlobKey.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,26 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import { BlobsTranscriptStoreOptions } from './blobsTranscriptStore';

/**
* Ensures that `key` is a properly sanitized Azure Blob Storage key. It should be URI encoded,
* no longer than 1024 characters, and contain no more than 254 slash ("/") chars.
*
* @param {string} key string blob key to sanitize
* @param {BlobsTranscriptStoreOptions} options Optional settings for BlobsTranscriptStore
* @returns {string} sanitized blob key
*/
export function sanitizeBlobKey(key: string): string {
export function sanitizeBlobKey(key: string, options?: BlobsTranscriptStoreOptions): string {
if (!key || !key.length) {
throw new Error('Please provide a non-empty key');
}

const sanitized = key.split('/').reduce((acc, part, idx) => (part ? [acc, part].join(idx < 255 ? '/' : '') : acc));

// Options settings to decode key in order to support previous Blob
if (options?.decodeTranscriptKey) {
return decodeURIComponent(sanitized).substr(0, 1024);
}
return encodeURIComponent(sanitized).substr(0, 1024);
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ describe('BlobsStorage', function () {
timestamp: new Date(),
};

// Options for BlobsTranscriptStore.
const blobTranscriptOptions = {
decodeTranscriptKey: false,
};

// Constructs a random channel ID and set of activities, and then handles preloading
// and clearing them with beforeEach/afterEach IFF client is defined
const maybePreload = () => {
Expand Down Expand Up @@ -77,7 +82,7 @@ describe('BlobsStorage', function () {
});

maybeIt('should log an activity', async () => {
await client.logActivity(activity);
await client.logActivity(activity, blobTranscriptOptions);
});
});

Expand Down
1 change: 1 addition & 0 deletions libraries/botbuilder-dialogs-adaptive-runtime/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ function addFeatures(services: ServiceCollection, configuration: Configuration):
.object({
connectionString: z.string(),
containerName: z.string(),
decodeTranscriptKey: z.boolean().optional(),
})
.nonstrict()
);
Expand Down
2 changes: 1 addition & 1 deletion libraries/botbuilder-repo-utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"globby": "^11.0.1",
"lodash": "^4.17.20",
"minimatch": "^3.0.4",
"minimist": "^1.2.5",
"minimist": "^1.2.6",
"p-map": "^4.0.0"
},
"devDependencies": {
Expand Down
1 change: 1 addition & 0 deletions libraries/botbuilder-repo-utils/src/package.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export interface Package {

dependencies?: Record<string, string>;
devDependencies?: Record<string, string>;
peerDependencies?: Record<string, string>;

scripts?: Record<string, string>;
}
12 changes: 8 additions & 4 deletions libraries/botbuilder-repo-utils/src/updateVersions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,14 +94,14 @@ export const command = (argv: string[], quiet = false) => async (): Promise<Resu
// Read git commit sha if instructed (JSON.parse properly coerces strings to boolean)
const commitSha = JSON.parse(flags.git) ? await gitSha('HEAD') : undefined;

// Collect all non-private workspaces from the repo root. Returns workspaces with absolute paths.
const workspaces = await collectWorkspacePackages(repoRoot, packageFile.workspaces, { noPrivate: true });
// Collect all workspaces from the repo root. Returns workspaces with absolute paths.
const workspaces = await collectWorkspacePackages(repoRoot, packageFile.workspaces);

// Build an object mapping a package name to its new, updated version
const workspaceVersions = workspaces.reduce<Record<string, string>>(
(acc, { pkg }) => ({
...acc,
[pkg.name]: getPackageVersion(pkg, newVersion, {
[pkg.name]: getPackageVersion(pkg, pkg.private ? pkg.version : newVersion, {
buildLabel: flags.buildLabel,
commitSha,
date,
Expand All @@ -122,7 +122,7 @@ export const command = (argv: string[], quiet = false) => async (): Promise<Resu
return acc;
}, {});

// Rewrite package.json files by updating version as well as dependencies and devDependencies.
// Rewrite package.json files by updating version as well as dependencies, devDependencies and peerDependencies.
const results = await Promise.all<Result>(
workspaces.map(async ({ absPath, pkg }) => {
const newVersion = workspaceVersions[pkg.name];
Expand All @@ -142,6 +142,10 @@ export const command = (argv: string[], quiet = false) => async (): Promise<Resu
pkg.devDependencies = rewriteWithNewVersions(pkg.devDependencies);
}

if (pkg.peerDependencies) {
pkg.peerDependencies = rewriteWithNewVersions(pkg.peerDependencies);
}

try {
await writeJsonFile(absPath, pkg);
return success();
Expand Down
6 changes: 3 additions & 3 deletions testing/browser-functional/browser-echo-bot/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4395,9 +4395,9 @@ minimatch@^3.0.4:
brace-expansion "^1.1.7"

minimist@^1.2.0, minimist@^1.2.5:
version "1.2.5"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
version "1.2.6"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==

mississippi@^3.0.0:
version "3.0.0"
Expand Down
2 changes: 1 addition & 1 deletion testing/consumer-test/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"botframework-connector": "4.1.6",
"botframework-schema": "4.1.6",
"botframework-streaming": "4.1.6",
"minimist": "^1.2.5",
"minimist": "^1.2.6",
"p-map": "^4.0.0"
},
"devDependencies": {
Expand Down
14 changes: 7 additions & 7 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -9183,10 +9183,10 @@ minimist@0.0.8:
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=

minimist@^1.1.0, minimist@^1.1.1, minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5:
version "1.2.5"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
minimist@^1.1.0, minimist@^1.1.1, minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5, minimist@^1.2.6:
version "1.2.6"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==

minipass-collect@^1.0.2:
version "1.0.2"
Expand Down Expand Up @@ -9425,9 +9425,9 @@ mold-source-map@~0.4.0:
through "~2.2.7"

moment@^2.19.3, moment@^2.21.0, moment@^2.22.2:
version "2.29.1"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3"
integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==
version "2.29.2"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.2.tgz#00910c60b20843bcba52d37d58c628b47b1f20e4"
integrity sha512-UgzG4rvxYpN15jgCmVJwac49h9ly9NurikMWGPdVxm8GZD6XjkKPxDTjQQ43gtGgnV3X0cAyWDdP2Wexoquifg==

move-concurrently@^1.0.1:
version "1.0.1"
Expand Down

0 comments on commit 686761a

Please sign in to comment.