Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update getMeetingDetailsVerbose Interface #2489

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
10 changes: 9 additions & 1 deletion apps/teams-test-app/e2e-test-data/meeting.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,20 @@
},
{
"title": "getMeetingDetailsVerbose API Call - Success",
"version": ">2.22.0",
TrevorJoelHarris marked this conversation as resolved.
Show resolved Hide resolved
"version": ">2.22.0 && <= 2.28.0",
"type": "callResponse",
"boxSelector": "#box_getMeetingDetailsVerbose",
"expectedAlertValue": "getMeetingDetails called with shouldGetVerboseDetails: true",
"expectedTestAppValue": "{\"details\":{\"scheduledStartTime\":\"testStartTime\",\"joinUrl\":\"testJoinUrl\",\"type\":\"oneOnOneCall\",\"originalCaller\":\"testCallerId\",\"dialedEntity\":\"testDnis\",\"trackingId\":\"testTrackingId\"},\"conversation\":{\"id\":\"testConversationId\"},\"organizer\":{\"id\":\"testOrganizerId\",\"tenantId\":\"testTenantId\"}}"
},
{
"title": "getMeetingDetailsVerbose API Call - Success",
"version": ">2.28.0",
"type": "callResponse",
"boxSelector": "#box_getMeetingDetailsVerbose",
"expectedAlertValue": "getMeetingDetails called with shouldGetVerboseDetails: true",
"expectedTestAppValue": "{\"details\":{\"scheduledStartTime\":\"testStartTime\",\"joinUrl\":\"testJoinUrl\",\"type\":\"oneOnOneCall\",\"originalCallerInfo\":{\"phoneNumber\":\"1234567890\",\"email\":{\"val\":\"[email protected]\"}},\"dialedEntityInfo\":{\"phoneNumber\":\"1234567890\",\"email\":{\"val\":\"[email protected]\"}},\"trackingId\":\"testTrackingId\",\"callId\":\"testCallId\"},\"conversation\":{\"id\":\"testConversationId\"},\"organizer\":{\"id\":\"testOrganizerId\",\"tenantId\":\"testTenantId\"}}"
},
{
"title": "getAuthenticationTokenForAnonymousUser API Call - Success",
"type": "callResponse",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "minor",
"comment": "Added three properties to `ICallDetails`, `originalCallerInfo`, `dialedEntityInfo`, and `callId`, created a new type `ICallParticipantIdentifiers`, and deprecated the `originalCaller` and `dialedEntity` properties",
"packageName": "@microsoft/teams-js",
"email": "[email protected]",
"dependentChangeType": "patch"
}
6 changes: 6 additions & 0 deletions packages/teams-js/src/internal/emailAddressValidation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export function validateEmailAddress(emailString: string): void {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(emailString)) {

Check failure

Code scanning / CodeQL

Polynomial regular expression used on uncontrolled data High

This
regular expression
that depends on
library input
may run slow on strings starting with '!@!.' and with many repetitions of '!.'.
throw new Error('Input email address does not have the correct format.');
}
}
17 changes: 17 additions & 0 deletions packages/teams-js/src/public/emailAddress.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { validateEmailAddress } from '../internal/emailAddressValidation';

/**
* Represents a validated email.
*
* @hidden
* Hide from docs.
*/
export class EmailAddress {
public constructor(private readonly val: string) {
validateEmailAddress(val);
}

public toString(): string {
return this.val;
}
}
1 change: 1 addition & 0 deletions packages/teams-js/src/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export {
} from './interfaces';
export { app } from './app';
export { AppId } from './appId';
export { EmailAddress } from './emailAddress';
export { appInstallDialog } from './appInstallDialog';
export { barCode } from './barCode';
export { chat, OpenGroupChatRequest, OpenSingleChatRequest } from './chat';
Expand Down
42 changes: 41 additions & 1 deletion packages/teams-js/src/public/meeting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { doesHandlerExist, registerHandler, removeHandler } from '../internal/ha
import { ensureInitialized } from '../internal/internalAPIs';
import { ApiName, ApiVersionNumber, getApiVersionTag } from '../internal/telemetry';
import { FrameContexts } from './constants';
import { EmailAddress } from './emailAddress';
import { ErrorCode, SdkError } from './interfaces';
import { runtime } from './runtime';

Expand Down Expand Up @@ -94,29 +95,68 @@ export namespace meeting {
type?: T;
}

/**
* @hidden
* Hide from docs
* Data structure to represent call participant identifiers
*/
interface ICallParticipantIdentifiers {
/**
* Phone number of a PSTN caller
*/
phoneNumber?: string;
TrevorJoelHarris marked this conversation as resolved.
Show resolved Hide resolved

/**
* Email of a VoIP caller
*/
email?: EmailAddress;
}

/**
* @hidden
* Hide from docs
* Data structure to represent call details
*/
export interface ICallDetails extends IMeetingOrCallDetailsBase<CallType> {
/**
* @deprecated please use {@link ICallDetails.originalCallerInfo} instead
*
* @hidden
* Phone number of a PSTN caller or email of a VoIP caller
*/
originalCaller?: string;

/**
* @hidden
* Object representing the original caller
*/
originalCallerInfo?: ICallParticipantIdentifiers;

/**
* @deprecated please use {@link ICallDetails.dialedEntityInfo} instead
*
* @hidden
* Phone number of a PSTN callee or email of a VoIP callee
*/
dialedEntity?: never;

/**
* @hidden
* Object representing the entity the caller dialed
*/
dialedEntityInfo?: never;
TrevorJoelHarris marked this conversation as resolved.
Show resolved Hide resolved

/**
* @hidden
* Tracking identifier for grouping related calls
*/
trackingId?: never;

/**
* @hidden
* Identifier for the current call
*/
callId?: never;
}

/**
Expand Down Expand Up @@ -665,7 +705,7 @@ export namespace meeting {

if (
(response.details?.type == CallType.GroupCall || response.details?.type == CallType.OneOnOneCall) &&
!response.details.originalCaller
!response.details.originalCallerInfo
TrevorJoelHarris marked this conversation as resolved.
Show resolved Hide resolved
) {
throw new Error(ErrorCode.NOT_SUPPORTED_ON_PLATFORM.toString());
}
Expand Down
23 changes: 23 additions & 0 deletions packages/teams-js/test/internal/emailAddressValidation.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { validateEmailAddress } from '../../src/internal/emailAddressValidation';

describe('emailAddressValidation', () => {
const invalidEmails = ['@@domain.com', 'firstname [email protected]', 'name@domain'];
invalidEmails.forEach((invalidEmail) => {
it('should throw errors for invalid email addresses', () => {
expect(() => validateEmailAddress(invalidEmail)).toThrow('Input email address does not have the correct format.');
});
});
const validEmails = [
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
];
validEmails.forEach((validEmail) => {
it('should not throw errors for valid email addresses', () => {
expect(() => validateEmailAddress(validEmail)).not.toThrow(
'Input email address does not have the correct format.',
);
});
});
});
24 changes: 24 additions & 0 deletions packages/teams-js/test/public/emailAddress.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { EmailAddress } from '../../src/public';

describe('emailAddress', () => {
const invalidEmails = ['@@domain.com', 'firstname [email protected]', 'name@domain'];
invalidEmails.forEach((invalidEmail) => {
it('should throw errors for invalid email addresses', () => {
expect(() => new EmailAddress(invalidEmail)).toThrowError(
'Input email address does not have the correct format.',
);
});
});
const validEmails = [
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
];
validEmails.forEach((validEmail) => {
it('should not throw errors for valid email addresses', () => {
const email = new EmailAddress(validEmail);
expect(email.toString()).toBe(validEmail);
});
});
});
12 changes: 9 additions & 3 deletions packages/teams-js/test/public/meeting.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { errorLibraryNotInitialized } from '../../src/internal/constants';
import { GlobalVars } from '../../src/internal/globalVars';
import { DOMMessageEvent } from '../../src/internal/interfaces';
import { MessageRequest } from '../../src/internal/messageObjects';
import { FrameContexts } from '../../src/public';
import { EmailAddress, FrameContexts } from '../../src/public';
import { app } from '../../src/public/app';
import { ErrorCode, SdkError } from '../../src/public/interfaces';
import { meeting } from '../../src/public/meeting';
Expand Down Expand Up @@ -277,7 +277,10 @@ describe('meeting', () => {
'https://teams.microsoft.com/l/meetup-join/19%3ameeting_qwertyuiop[phgfdsasdfghjkjbvcxcvbnmyt1234567890!@#$%^&*(%40thread.v2/0?context=%7b%22Tid%22%3a%2272f988bf-86f1-41af-91ab-2d7cd011db47%22%2c%22Oid%22%3a%226b33ac33-85ae-4995-be29-1d38a77aa8e3%22%7d',
type: meeting.CallType.OneOnOneCall,
// Verbose details
originalCaller: 'testCallerId',
originalCallerInfo: {
phoneNumber: '1234567890',
email: new EmailAddress('[email protected]'),
},
};
const organizer: meeting.IOrganizer = {
id: '8:orgid:6b33ac33-85ae-4995-be29-1d38a77aa8e3',
Expand Down Expand Up @@ -627,7 +630,10 @@ describe('meeting', () => {
'https://teams.microsoft.com/l/meetup-join/19%3ameeting_qwertyuiop[phgfdsasdfghjkjbvcxcvbnmyt1234567890!@#$%^&*(%40thread.v2/0?context=%7b%22Tid%22%3a%2272f988bf-86f1-41af-91ab-2d7cd011db47%22%2c%22Oid%22%3a%226b33ac33-85ae-4995-be29-1d38a77aa8e3%22%7d',
type: meeting.CallType.OneOnOneCall,
// Verbose details
originalCaller: 'testCallerId',
originalCallerInfo: {
phoneNumber: '1234567890',
email: new EmailAddress('[email protected]'),
},
};
const organizer: meeting.IOrganizer = {
id: '8:orgid:6b33ac33-85ae-4995-be29-1d38a77aa8e3',
Expand Down
Loading