From 4221d3baf3986fbdc61f27612cf2057cdf8c49b6 Mon Sep 17 00:00:00 2001 From: BEChiaha Date: Thu, 25 Jul 2024 15:14:06 -0700 Subject: [PATCH 1/7] Update apps/teams-test-app/e2e-test-data/app.json Co-authored-by: Trevor Harris --- apps/teams-test-app/e2e-test-data/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/teams-test-app/e2e-test-data/app.json b/apps/teams-test-app/e2e-test-data/app.json index defb00c1f4..3589f71e4f 100644 --- a/apps/teams-test-app/e2e-test-data/app.json +++ b/apps/teams-test-app/e2e-test-data/app.json @@ -1,6 +1,6 @@ { "name": "App", - "platforms": ["iOS","WEB"], + "platforms": ["iOS","Web"], "testCases": [ { "title": "openLink API Call - Success", From 08943f5cf0eb34de5d501a5a43927ec9b2df5a9d Mon Sep 17 00:00:00 2001 From: BEChiaha Date: Thu, 25 Jul 2024 15:15:08 -0700 Subject: [PATCH 2/7] Update apps/teams-test-app/e2e-test-data/location.json Co-authored-by: Trevor Harris --- apps/teams-test-app/e2e-test-data/location.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/teams-test-app/e2e-test-data/location.json b/apps/teams-test-app/e2e-test-data/location.json index 622d3dfa0c..76de7c0e72 100644 --- a/apps/teams-test-app/e2e-test-data/location.json +++ b/apps/teams-test-app/e2e-test-data/location.json @@ -33,7 +33,7 @@ { "title": "showLocation API Call - Success", "type": "callResponse", - "platformsExcluded": ["iOS","ANDROID"], + "platformsExcluded": ["iOS","Android"], "boxSelector": "#box_showLocation", "requestPermissionBeforeThisCall": { "boxSelector": "#box_requestGeoLocationPermission", From 5debfffa1fcf3f1c07018d373690f5666efda9fb Mon Sep 17 00:00:00 2001 From: Toni Solarin-Sodara Date: Fri, 26 Jul 2024 18:53:39 +0100 Subject: [PATCH 3/7] Video frame capabilities and attributes (#2383) * Allow specifying additional capabilities to be applied to a video frame * Add changefile * Update videoEffectsEx unit tests * Update VideoEffectsExAPI e2e test * Fix formatting * Fix tests * Add tests for attribute parsing logic * Update sharedFrame test json * Test frame attribute parsing through API surface * Revert whitespace change * Update apps/teams-test-app/e2e-test-data/video.sharedFrame.json * Update apps/teams-test-app/e2e-test-data/video.sharedFrame.json --------- Co-authored-by: Trevor Harris --- .../e2e-test-data/video.sharedFrame.json | 15 +++ .../privateApis/VideoEffectsExAPIs.tsx | 4 + ...-a8f9bbfe-abed-45eb-89dd-475510d7eb5a.json | 7 ++ .../src/internal/videoEffectsUtils.ts | 63 +++++++++- .../teams-js/src/private/videoEffectsEx.ts | 18 +++ .../test/private/videoEffectsEx.spec.ts | 119 ++++++++++++++++++ 6 files changed, 223 insertions(+), 3 deletions(-) create mode 100644 change/@microsoft-teams-js-a8f9bbfe-abed-45eb-89dd-475510d7eb5a.json diff --git a/apps/teams-test-app/e2e-test-data/video.sharedFrame.json b/apps/teams-test-app/e2e-test-data/video.sharedFrame.json index d3c3a92b72..7188910e20 100644 --- a/apps/teams-test-app/e2e-test-data/video.sharedFrame.json +++ b/apps/teams-test-app/e2e-test-data/video.sharedFrame.json @@ -17,9 +17,24 @@ "type": "callResponse", "version": ">2.12.0", "boxSelector": "#box_videoExSharedFrameRegisterForVideoFrame1", + "hostSdkVersion": { + "web": "<=4.0.0" + }, "modulesToDisable": ["videoMediaStream"], "expectedTestAppValue": "Registration attempt has been initiated. If successful, this message will change when it is invoked on video frame received.", "expectedAlertValue": "sharedFrame.registerForVideoFrame called with config: {\"format\":\"NV12\",\"requireCameraStream\":false,\"audioInferenceModel\":{}}" + }, + { + "title": "videoEx.sharedFrame.registerForVideoFrame - Success", + "type": "callResponse", + "version": ">2.12.0", + "boxSelector": "#box_videoExSharedFrameRegisterForVideoFrame1", + "hostSdkVersion": { + "web": ">4.0.0" + }, + "modulesToDisable": ["videoMediaStream"], + "expectedTestAppValue": "Registration attempt has been initiated. If successful, this message will change when it is invoked on video frame received.", + "expectedAlertValue": "sharedFrame.registerForVideoFrame called with config: {\"format\":\"NV12\",\"requireCameraStream\":false,\"audioInferenceModel\":{},\"requiredCapabilities\":[]}" } ] } diff --git a/apps/teams-test-app/src/components/privateApis/VideoEffectsExAPIs.tsx b/apps/teams-test-app/src/components/privateApis/VideoEffectsExAPIs.tsx index 953cba8639..9a2889eaf9 100644 --- a/apps/teams-test-app/src/components/privateApis/VideoEffectsExAPIs.tsx +++ b/apps/teams-test-app/src/components/privateApis/VideoEffectsExAPIs.tsx @@ -107,6 +107,7 @@ const MediaStreamRegisterForVideoFrame = (): React.ReactElement => onClick: async (setResult) => { try { const audioInferenceModel = new ArrayBuffer(8); + const requiredCapabilities = []; const view = new Uint8Array(audioInferenceModel); for (let i = 0; i < view.length; i++) { view[i] = i; @@ -121,6 +122,7 @@ const MediaStreamRegisterForVideoFrame = (): React.ReactElement => format: videoEffects.VideoFrameFormat.NV12, requireCameraStream: false, audioInferenceModel, + requiredCapabilities, }, }); } catch (error) { @@ -169,6 +171,7 @@ const SharedFrameRegisterForVideoFrame = (): React.ReactElement => onClick: async (setResult) => { try { const audioInferenceModel = new ArrayBuffer(8); + const requiredCapabilities = []; const view = new Uint8Array(audioInferenceModel); for (let i = 0; i < view.length; i++) { view[i] = i; @@ -184,6 +187,7 @@ const SharedFrameRegisterForVideoFrame = (): React.ReactElement => format: videoEffects.VideoFrameFormat.NV12, requireCameraStream: false, audioInferenceModel, + requiredCapabilities, }, }); } catch (error) { diff --git a/change/@microsoft-teams-js-a8f9bbfe-abed-45eb-89dd-475510d7eb5a.json b/change/@microsoft-teams-js-a8f9bbfe-abed-45eb-89dd-475510d7eb5a.json new file mode 100644 index 0000000000..a3cee39993 --- /dev/null +++ b/change/@microsoft-teams-js-a8f9bbfe-abed-45eb-89dd-475510d7eb5a.json @@ -0,0 +1,7 @@ +{ + "type": "minor", + "comment": "Added new fields to `VideoFrameConfig` and `VideoFrameData` to allow specifying additional capabilities to be applied to a video frame and reading arbitrary attributes on a video frame respectively. The capability is still awaiting support in one or most host applications. To track availability of this capability across different hosts see https://aka.ms/capmatrix", + "packageName": "@microsoft/teams-js", + "email": "olsolari@microsoft.com", + "dependentChangeType": "patch" +} \ No newline at end of file diff --git a/packages/teams-js/src/internal/videoEffectsUtils.ts b/packages/teams-js/src/internal/videoEffectsUtils.ts index e3ba5b85d2..0e723158dd 100644 --- a/packages/teams-js/src/internal/videoEffectsUtils.ts +++ b/packages/teams-js/src/internal/videoEffectsUtils.ts @@ -286,6 +286,7 @@ class OneTextureMetadata { // Stream id for audio inference metadata, which is the 4-byte ASCII string "1dia" hardcoded by the host // (1dia stands for "audio inference data version 1") private readonly AUDIO_INFERENCE_RESULT_STREAM_ID = 0x31646961; + private readonly ATTRIBUTE_ID_MAP_STREAM_ID = 0x4d444941; public constructor(metadataBuffer: ArrayBuffer, streamCount: number) { const metadataDataView = new Uint32Array(metadataBuffer); for (let i = 0, index = 0; i < streamCount; i++) { @@ -300,6 +301,58 @@ class OneTextureMetadata { public get audioInferenceResult(): Uint8Array | undefined { return this.metadataMap.get(this.AUDIO_INFERENCE_RESULT_STREAM_ID); } + + /** + * @hidden + * Additional attributes on the video frame are string-indexed, with their stream Id dynamically generated. + * The mapping of attribute Ids to their stream Ids is itself stored as frame metadata with layout: + * + * | attribute count | attribute stream Id | attribute id | ... | + * | :---: | :---: | :---: | :---: | + * | 4 bytes | 4 bytes | variable length string (null terminated, 4 byte aligned) | ... | + * + * + * @internal + * Limited to Microsoft-internal use + */ + public get attributes(): ReadonlyMap | undefined { + const data = this.metadataMap.get(this.ATTRIBUTE_ID_MAP_STREAM_ID); + if (data === undefined) { + return undefined; + } + + const map: Map = new Map(); + const textDecoder = new TextDecoder('utf-8'); + + let offset = 0; + const count = data[offset] + (data[++offset] << 8) + (data[++offset] << 16) + (data[++offset] << 24); + + for (let i = 0; i < count && offset < data.length - 1; i++) { + const streamId = data[++offset] + (data[++offset] << 8) + (data[++offset] << 16) + (data[++offset] << 24); + + // Find start of null-terminator for the subsequent variable-length string entry + const nullTerminatorStartIndex = data.findIndex((value, index, _) => { + return value == 0 && index > offset; + }); + + const attributeId = textDecoder.decode(data.slice(++offset, nullTerminatorStartIndex)); + + // Read attribute value from metadata map + const metadata = this.metadataMap.get(streamId); + if (metadata !== undefined) { + map.set(attributeId, metadata); + } + + // Variable length attribute Id strings are null-terminated to a 4-byte alignment + const stringByteLength = nullTerminatorStartIndex - offset; + const paddingSize = 4 - (stringByteLength % 4); + + // Set offset to index of last trailing zero + offset = nullTerminatorStartIndex + (paddingSize - 1); + } + + return map; + } } class TransformerWithMetadata { @@ -325,9 +378,9 @@ class TransformerWithMetadata { const timestamp = originalFrame.timestamp; if (timestamp !== null) { try { - const { videoFrame, metadata: { audioInferenceResult } = {} } = + const { videoFrame, metadata: { audioInferenceResult, attributes } = {} } = await this.extractVideoFrameAndMetadata(originalFrame); - const frameProcessedByApp = await this.videoFrameHandler({ videoFrame, audioInferenceResult }); + const frameProcessedByApp = await this.videoFrameHandler({ videoFrame, audioInferenceResult, attributes }); // the current typescript version(4.6.4) dosn't support webcodecs API fully, we have to do type conversion here. const processedFrame = new VideoFrame(frameProcessedByApp as unknown as CanvasImageSource, { // we need the timestamp to be unchanged from the oirginal frame, so we explicitly set it here. @@ -373,7 +426,10 @@ class TransformerWithMetadata { */ private extractVideoFrameAndMetadata = async ( texture: VideoFrame, - ): Promise<{ videoFrame: VideoFrame; metadata: { audioInferenceResult?: Uint8Array } }> => { + ): Promise<{ + videoFrame: VideoFrame; + metadata: { audioInferenceResult?: Uint8Array; attributes?: ReadonlyMap }; + }> => { if (inServerSideRenderingEnvironment()) { throw errorNotSupportedOnPlatform; } @@ -427,6 +483,7 @@ class TransformerWithMetadata { }) as VideoFrame, metadata: { audioInferenceResult: this.shouldDiscardAudioInferenceResult ? undefined : metadata.audioInferenceResult, + attributes: metadata.attributes, }, }; }; diff --git a/packages/teams-js/src/private/videoEffectsEx.ts b/packages/teams-js/src/private/videoEffectsEx.ts index 54a1fa4aaf..f565809f1c 100644 --- a/packages/teams-js/src/private/videoEffectsEx.ts +++ b/packages/teams-js/src/private/videoEffectsEx.ts @@ -71,6 +71,15 @@ export namespace videoEffectsEx { * Limited to Microsoft-internal use */ audioInferenceModel?: ArrayBuffer; + /** + * @hidden + * Specifies additional capabilities that should be applied to the video frame + * @beta + * + * @internal + * Limited to Microsoft-internal use + */ + requiredCapabilities?: string[]; } /** @@ -139,6 +148,15 @@ export namespace videoEffectsEx { * Limited to Microsoft-internal use */ audioInferenceResult?: Uint8Array; + /** + * @hidden + * Additional metadata determined by capabilities specified in {@linkcode VideoFrameConfig.requiredCapabilities} + * @beta + * + * @internal + * Limited to Microsoft-internal use + */ + attributes?: ReadonlyMap; }; /** diff --git a/packages/teams-js/test/private/videoEffectsEx.spec.ts b/packages/teams-js/test/private/videoEffectsEx.spec.ts index 8860eeae40..6dc1a6ca41 100644 --- a/packages/teams-js/test/private/videoEffectsEx.spec.ts +++ b/packages/teams-js/test/private/videoEffectsEx.spec.ts @@ -1,3 +1,5 @@ +import { TextDecoder, TextEncoder } from 'util'; + import { GlobalVars } from '../../src/internal/globalVars'; import { DOMMessageEvent } from '../../src/internal/interfaces'; import { MessageRequest } from '../../src/internal/messageObjects'; @@ -8,6 +10,8 @@ import { errorNotSupportedOnPlatform, FrameContexts } from '../../src/public/con import { videoEffects } from '../../src/public/videoEffects'; import { Utils } from '../utils'; +Object.assign(global, { TextDecoder, TextEncoder }); + /* eslint-disable */ /* As part of enabling eslint on test files, we need to disable eslint checking on the specific files with large numbers of errors. Then, over time, we can fix the errors and reenable eslint on a per file basis. */ @@ -40,6 +44,7 @@ describe('videoEffectsEx', () => { format: videoEffects.VideoFrameFormat.NV12, requireCameraStream: false, audioInferenceModel: new ArrayBuffer(100), + requiredCapabilities: [], }; const registerForVideoFrameParameters: videoEffectsEx.RegisterForVideoFrameParameters = { @@ -80,6 +85,7 @@ describe('videoEffectsEx', () => { const message = utils.findMessageByFunc('video.registerForVideoFrame') as MessageRequest; expect(message).not.toBeNull(); expect(message?.args?.[0]).toHaveProperty('audioInferenceModel'); + expect(message?.args?.[0]).toHaveProperty('requiredCapabilities'); expect(message?.args?.[0].format).toBe(videoEffects.VideoFrameFormat.NV12); expect(message?.args?.[0].requireCameraStream).toBe(false); }); @@ -391,6 +397,36 @@ describe('videoEffectsEx', () => { ); }); + it('should receive attributes with video frame', async () => { + expect.assertions(3); + + // Arrange + const expectedFrameAttributes = window['FrameAttributes'] as ReadonlyMap; + let receivedFrameAttributes; + const videoFrameHandler = (data) => { + receivedFrameAttributes = data.attributes; + return Promise.resolve(data.videoFrame); + }; + + // Act + videoEffectsEx.registerForVideoFrame({ + ...registerForVideoFrameParameters, + videoFrameHandler, + }); + await utils.respondToFramelessMessage({ + data: { + func: 'video.startVideoExtensibilityVideoStream', + args: [{ streamId: 'stream id', metadataInTexture: true }], + }, + } as DOMMessageEvent); + await utils.flushPromises(); + + // Assert + expect(receivedFrameAttributes).not.toEqual(undefined); + expect(receivedFrameAttributes.size).toEqual(expectedFrameAttributes.size); + expect(receivedFrameAttributes).toEqual(expectedFrameAttributes); + }); + it('should get and register stream with streamId received from startVideoExtensibilityVideoStream', async () => { expect.assertions(5); @@ -698,6 +734,7 @@ describe('videoEffectsEx', () => { format: videoEffects.VideoFrameFormat.NV12, requireCameraStream: false, audioInferenceModel: new ArrayBuffer(100), + requiredCapabilities: [], }; const registerForVideoFrameParameters: videoEffectsEx.RegisterForVideoFrameParameters = { videoBufferHandler: (_bufferData, _onSuccess, _onError) => {}, @@ -1166,6 +1203,52 @@ describe('videoEffectsEx', () => { }); }); +function numToByteArray(num: number): Uint8Array { + return new Uint8Array((new Uint32Array([num])).buffer); +} + +function generateOneTextureMetadataMock(attributes: ReadonlyMap, streamCount: number): Uint8Array { + const metadataHeaderSize = 12 * streamCount; + + let streamId = 2; + const headerSegment = new Array(); + const dataSegment = new Array(); + const textEncoder = new TextEncoder(); + + const attributesData = new Array(); + attributesData.push(...numToByteArray(attributes.size)); + + attributes.forEach((attributeData, attributeId, _) => { + const stringBytes = textEncoder.encode(attributeId); + const paddingSize = 4 - (stringBytes.length % 4); // null terminator bytes length + + headerSegment.push(streamId); + headerSegment.push(metadataHeaderSize + dataSegment.length); + headerSegment.push(attributeData.length); + + attributesData.push(...numToByteArray(streamId++)); + attributesData.push(...stringBytes); + attributesData.push(...(new Uint8Array(paddingSize))); + + dataSegment.push(...attributeData); + }); + + headerSegment.push(0x4d444941); // ATTRIBUTE_ID_MAP_STREAM_ID + headerSegment.push(metadataHeaderSize + dataSegment.length); + headerSegment.push(attributesData.length); + + dataSegment.push(...attributesData); + + const headerBuffer = new Uint32Array(headerSegment); + const dataBuffer = new Uint8Array(dataSegment); + + const metadata = new Uint8Array(headerBuffer.byteLength + dataBuffer.byteLength); + metadata.set(new Uint8Array(headerBuffer.buffer)); + metadata.set(dataBuffer, headerBuffer.byteLength); + + return metadata; +} + function mockMediaStreamAPI() { // Jest doesn't support MediaStream API yet, so we need to mock it. // Reference: @@ -1192,6 +1275,33 @@ function mockMediaStreamAPI() { writable: true, }); + const originalVideoFrame = global['VideoFrame']; + + Object.defineProperty(global, 'VideoFrame', { + value: jest.fn().mockImplementation(() => ({})), + writable: true, + }); + + const frameAttributesMock = new Map(); + frameAttributesMock.set('attribute-id-1', new Uint8Array([23, 45, 2, 75, 134])); + frameAttributesMock.set('attribute-id-2', new Uint8Array([76, 145, 9])); + frameAttributesMock.set('attribute-id-3', new Uint8Array([213, 78, 82, 237, 12, 34, 97, 6])); + + window['FrameAttributes'] = frameAttributesMock; + + const oneTextureHeaderMock = new Uint32Array([ + 0x6f746931, // ONE_TEXTURE_INPUT_ID + 1, // version + 2, // frameOffset + 0, // frameFormat + 100, // frameWidth + 90, // frameHeight + 92, // multiStreamHeaderRowOffset (frameRowOffset + frameHeight) + 1 + frameAttributesMock.size, // multiStreamCount + ]); + + const oneTextureMetadataMock = new Uint8Array(generateOneTextureMetadataMock(frameAttributesMock, oneTextureHeaderMock[7])); + const originalReadableStream = window['ReadableStream']; Object.defineProperty(window, 'ReadableStream', { @@ -1205,6 +1315,10 @@ function mockMediaStreamAPI() { timestamp: 0, codedWidth: 100, codedHeight: 100, + format: 'NV12', + copyTo: jest.fn() + .mockImplementationOnce((buffer) => new Uint32Array(buffer).set(oneTextureHeaderMock)) + .mockImplementationOnce((buffer) => new Uint8Array(buffer).set(oneTextureMetadataMock)), // eslint-disable-next-line @typescript-eslint/no-empty-function close: () => {}, }, @@ -1270,6 +1384,11 @@ function mockMediaStreamAPI() { // restore original APIs return () => { + Object.defineProperty(global, 'VideoFrame', { + value: originalVideoFrame, + writable: true, + }); + Object.defineProperties(window, { MediaStream: { value: originalMediaStream, From a8f5866d6338a630e44a102273d1fa328ab310ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?AE=20=28=20=CD=A1=E0=B2=A0=20=CA=96=CC=AF=20=CD=A1?= =?UTF-8?q?=E0=B2=A0=29?= <36546967+AE-MS@users.noreply.github.com> Date: Fri, 26 Jul 2024 15:23:30 -0700 Subject: [PATCH 4/7] Add support for *.cloud.microsoft domains (#2429) * Add support for *.cloud.microsoft domains * Add changefile * Add high-profile validDomains origin validation to unit tests --- ...ams-js-20c797d3-df8d-4eb9-a37c-7269e59c02e8.json | 7 +++++++ .../teams-js/src/artifactsForCDN/validDomains.json | 4 +--- .../teams-js/test/internal/validOrigins.spec.ts | 13 +++++++++++++ packages/teams-js/test/private/privateAPIs.spec.ts | 4 ++++ 4 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 change/@microsoft-teams-js-20c797d3-df8d-4eb9-a37c-7269e59c02e8.json diff --git a/change/@microsoft-teams-js-20c797d3-df8d-4eb9-a37c-7269e59c02e8.json b/change/@microsoft-teams-js-20c797d3-df8d-4eb9-a37c-7269e59c02e8.json new file mode 100644 index 0000000000..ff54e1c17c --- /dev/null +++ b/change/@microsoft-teams-js-20c797d3-df8d-4eb9-a37c-7269e59c02e8.json @@ -0,0 +1,7 @@ +{ + "type": "minor", + "comment": "Added support for any `*.cloud.microsoft` domain to be a valid host", + "packageName": "@microsoft/teams-js", + "email": "36546967+AE-MS@users.noreply.github.com", + "dependentChangeType": "patch" +} diff --git a/packages/teams-js/src/artifactsForCDN/validDomains.json b/packages/teams-js/src/artifactsForCDN/validDomains.json index d74cfbc07e..983eb70b77 100644 --- a/packages/teams-js/src/artifactsForCDN/validDomains.json +++ b/packages/teams-js/src/artifactsForCDN/validDomains.json @@ -29,9 +29,7 @@ "edgeservices.bing.com", "www.bing.com", "www.staging-bing-int.com", - "teams.cloud.microsoft", - "outlook.cloud.microsoft", - "m365.cloud.microsoft", + "*.cloud.microsoft", "copilot.microsoft.com", "windows.msn.com", "fa000000125.resources.office.net", diff --git a/packages/teams-js/test/internal/validOrigins.spec.ts b/packages/teams-js/test/internal/validOrigins.spec.ts index d975b95783..205deb2d09 100644 --- a/packages/teams-js/test/internal/validOrigins.spec.ts +++ b/packages/teams-js/test/internal/validOrigins.spec.ts @@ -123,6 +123,19 @@ describe('validOrigins', () => { GlobalVars.additionalValidOrigins = ['https://*.testdomain.com']; expect(result).toBe(false); }); + it('validateOrigin returns true for high-profile *.cloud.microsoft origins', async () => { + let messageOrigin = new URL('https://teams.cloud.microsoft'); + let result = await validateOrigin(messageOrigin); + expect(result).toBe(true); + + messageOrigin = new URL('https://outlook.cloud.microsoft'); + result = await validateOrigin(messageOrigin); + expect(result).toBe(true); + + messageOrigin = new URL('https://m365.cloud.microsoft'); + result = await validateOrigin(messageOrigin); + expect(result).toBe(true); + }); }); describe('testing main validOrigins flow with invalid json object', () => { let utils: Utils = new Utils(); diff --git a/packages/teams-js/test/private/privateAPIs.spec.ts b/packages/teams-js/test/private/privateAPIs.spec.ts index 886e4aab6c..3f70758294 100644 --- a/packages/teams-js/test/private/privateAPIs.spec.ts +++ b/packages/teams-js/test/private/privateAPIs.spec.ts @@ -117,6 +117,10 @@ describe('AppSDK-privateAPIs', () => { 'https://www.microsoft365.com', 'https://tasks.office.com', 'https://www.example.com', + 'https://teams.cloud.microsoft', + 'https://outlook.cloud.microsoft', + 'https://m365.cloud.microsoft', + 'https://anythingbecauseitsawildcard.cloud.microsoft', ]; supportedDomains.forEach((supportedDomain) => { From 414af38d0779e6baf5deb66ecb5048e20c7b834f Mon Sep 17 00:00:00 2001 From: jadahiya-MSFT <95651173+jadahiya-MSFT@users.noreply.github.com> Date: Fri, 26 Jul 2024 17:29:45 -0700 Subject: [PATCH 5/7] Adding in new domain for WXP (#2430) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Added in WXP domain for unified store * Added in changefile --------- Co-authored-by: AE ( ͡ಠ ʖ̯ ͡ಠ) <36546967+AE-MS@users.noreply.github.com> --- ...soft-teams-js-80426639-8e57-48b5-b260-c80b8ce77169.json | 7 +++++++ packages/teams-js/src/artifactsForCDN/validDomains.json | 3 ++- 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 change/@microsoft-teams-js-80426639-8e57-48b5-b260-c80b8ce77169.json diff --git a/change/@microsoft-teams-js-80426639-8e57-48b5-b260-c80b8ce77169.json b/change/@microsoft-teams-js-80426639-8e57-48b5-b260-c80b8ce77169.json new file mode 100644 index 0000000000..0483079d25 --- /dev/null +++ b/change/@microsoft-teams-js-80426639-8e57-48b5-b260-c80b8ce77169.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "Added in WXP domain for unified store", + "packageName": "@microsoft/teams-js", + "email": "jadahiya@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/packages/teams-js/src/artifactsForCDN/validDomains.json b/packages/teams-js/src/artifactsForCDN/validDomains.json index 983eb70b77..268ee3121d 100644 --- a/packages/teams-js/src/artifactsForCDN/validDomains.json +++ b/packages/teams-js/src/artifactsForCDN/validDomains.json @@ -35,6 +35,7 @@ "fa000000125.resources.office.net", "fa000000129.resources.office.net", "fa000000124.resources.office.net", - "fa000000128.resources.office.net" + "fa000000128.resources.office.net", + "fa000000136.resources.office.net" ] } From 4673be9c470cefb1851713e58373b63690a05a54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?AE=20=28=20=CD=A1=E0=B2=A0=20=CA=96=CC=AF=20=CD=A1?= =?UTF-8?q?=E0=B2=A0=29?= <36546967+AE-MS@users.noreply.github.com> Date: Mon, 29 Jul 2024 09:20:18 -0700 Subject: [PATCH 6/7] Fixed behavior of the `isValidOriginsCacheEmpty` function whose name was backwards (#2431) * Fix inverse function name * changefile --- ...soft-teams-js-f3565dc3-79ee-4e1a-97fb-fd15120450a5.json | 7 +++++++ packages/teams-js/src/internal/validOrigins.ts | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 change/@microsoft-teams-js-f3565dc3-79ee-4e1a-97fb-fd15120450a5.json diff --git a/change/@microsoft-teams-js-f3565dc3-79ee-4e1a-97fb-fd15120450a5.json b/change/@microsoft-teams-js-f3565dc3-79ee-4e1a-97fb-fd15120450a5.json new file mode 100644 index 0000000000..778ad5f83c --- /dev/null +++ b/change/@microsoft-teams-js-f3565dc3-79ee-4e1a-97fb-fd15120450a5.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "Fixed behavior of the `isValidOriginsCacheEmpty` function whose name was backwards of what it was actually doing", + "packageName": "@microsoft/teams-js", + "email": "36546967+AE-MS@users.noreply.github.com", + "dependentChangeType": "patch" +} diff --git a/packages/teams-js/src/internal/validOrigins.ts b/packages/teams-js/src/internal/validOrigins.ts index ea3dc6e422..ebec2773c7 100644 --- a/packages/teams-js/src/internal/validOrigins.ts +++ b/packages/teams-js/src/internal/validOrigins.ts @@ -11,11 +11,11 @@ export async function prefetchOriginsFromCDN(): Promise { } function isValidOriginsCacheEmpty(): boolean { - return validOriginsCache.length !== 0; + return validOriginsCache.length === 0; } async function getValidOriginsListFromCDN(): Promise { - if (isValidOriginsCacheEmpty()) { + if (!isValidOriginsCacheEmpty()) { return validOriginsCache; } if (!inServerSideRenderingEnvironment()) { From 92fc58c40b5ac87d6242fea26542f84c9a192f72 Mon Sep 17 00:00:00 2001 From: Toni Solarin-Sodara Date: Mon, 29 Jul 2024 19:03:54 +0100 Subject: [PATCH 7/7] Update version constraint in video.sharedFrame test (#2433) Co-authored-by: Trevor Harris --- apps/teams-test-app/e2e-test-data/video.sharedFrame.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/teams-test-app/e2e-test-data/video.sharedFrame.json b/apps/teams-test-app/e2e-test-data/video.sharedFrame.json index 7188910e20..6679fdf299 100644 --- a/apps/teams-test-app/e2e-test-data/video.sharedFrame.json +++ b/apps/teams-test-app/e2e-test-data/video.sharedFrame.json @@ -15,7 +15,7 @@ { "title": "videoEx.sharedFrame.registerForVideoFrame - Success", "type": "callResponse", - "version": ">2.12.0", + "version": "<=2.25.0", "boxSelector": "#box_videoExSharedFrameRegisterForVideoFrame1", "hostSdkVersion": { "web": "<=4.0.0" @@ -27,7 +27,7 @@ { "title": "videoEx.sharedFrame.registerForVideoFrame - Success", "type": "callResponse", - "version": ">2.12.0", + "version": ">2.25.0", "boxSelector": "#box_videoExSharedFrameRegisterForVideoFrame1", "hostSdkVersion": { "web": ">4.0.0"