Skip to content

Commit

Permalink
fix(meeting): fetching captcha details within meeting object (#337)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kesari3008 authored Jun 28, 2024
1 parent 201a007 commit 34a8a18
Show file tree
Hide file tree
Showing 4 changed files with 155 additions and 1 deletion.
41 changes: 40 additions & 1 deletion src/MeetingsSDKAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,7 @@ export default class MeetingsSDKAdapter extends MeetingsAdapter {
remoteAudio: null,
remoteVideo: null,
remoteShare: null,
requiredCaptcha: {},
showRoster: null,
settings: {
visible: false,
Expand Down Expand Up @@ -634,7 +635,26 @@ export default class MeetingsSDKAdapter extends MeetingsAdapter {
const sdkMeeting = this.fetchMeeting(ID);

if (sdkMeeting.passwordStatus === 'REQUIRED') {
await sdkMeeting.verifyPassword(options.hostKey || options.password);
const res = await sdkMeeting
.verifyPassword(options.hostKey || options.password, options.captcha);

if (!res.isPasswordValid) {
this.updateMeeting(ID, () => (
{
failureReason: res.failureReason,
invalidPassword: true,
...(res.requiredCaptcha && {
requiredCaptcha: {
captchaId: res.requiredCaptcha.captchaId,
refreshURL: res.requiredCaptcha.refreshURL,
verificationAudioURL: res.requiredCaptcha.verificationAudioURL,
verificationImageURL: res.requiredCaptcha.verificationImageURL,
},
}),
}));
} else {
logger.info('MEETING', ID, 'joinMeeting()', 'Password successfully verified');
}
}
sdkMeeting.meetingFiniteStateMachine.reset();
logger.debug('MEETING', ID, 'joinMeeting()', ['calling sdkMeeting.join() with', {pin: options.password, moderator: false, name: options.name}]);
Expand Down Expand Up @@ -1353,6 +1373,7 @@ export default class MeetingsSDKAdapter extends MeetingsAdapter {
deepMerge(meeting, updates);

logger.debug('MEETING', ID, 'updateMeeting()', ['meeting updated with', EVENT_MEETING_UPDATED, 'event', 'meeting object', {meeting}]);

sdkMeeting.emit(EVENT_MEETING_UPDATED, meeting);
}

Expand Down Expand Up @@ -1406,4 +1427,22 @@ export default class MeetingsSDKAdapter extends MeetingsAdapter {
async clearInvalidHostKeyFlag(ID) {
await this.updateMeeting(ID, async () => ({invalidHostKey: false}));
}

/**
* Refreshes the captcha code.
*
* @async
* @param {string} ID Id of the meeting
*/
async refreshCaptcha(ID) {
logger.debug('MEETING', ID, 'refreshCaptcha()', ['called with', {ID}]);
const sdkMeeting = this.fetchMeeting(ID);

sdkMeeting.refreshCaptcha();
await this.updateMeeting(ID, () => (
{
requiredCaptcha: sdkMeeting.requiredCaptcha,
}
));
}
}
110 changes: 110 additions & 0 deletions src/MeetingsSDKAdapter.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1087,4 +1087,114 @@ describe('Meetings SDK Adapter', () => {
expect(mockSDKMeeting.emit.mock.calls[0][1]).toMatchObject({invalidHostKey: false});
});
});

describe('refreshCaptcha()', () => {
const mockCaptcha = {
captchaId: 'Captcha_c57280d4-6baf-4a27-87e9-290757754bb6',
verificationImageURL: 'https://cisco.webex.com/captchaservice/v1/captchas/Captcha_c57280d4-6baf-4a27-87e9-290757754bb6/verificationCodeImage',
refreshURL: 'https://cisco.webex.com/captchaservice/v1/captchas/refresh?siteurl=cisco&captchaID=Captcha_c57280d4-6baf-4a27-87e9-290757754bb6',
verificationAudioURL: 'https://cisco.webex.com/captchaservice/v1/captchas/Captcha_c57280d4-6baf-4a27-87e9-290757754bb6/verificationCodeAudio',
};

it('refreshes the captcha', async () => {
meetingsSDKAdapter.meetings[meetingID].requiredCaptcha = {
captchaId: 'Captcha_b40798d4-6baf-4a27-bf77-2907577524d6',
verificationImageURL: 'https://cisco.webex.com/captchaservice/v1/captchas/Captcha_b40798d4-6baf-4a27-bf77-2907577524d6/verificationCodeImage',
refreshURL: 'https://cisco.webex.com/captchaservice/v1/captchas/refresh?siteurl=cisco&captchaID=Captcha_b40798d4-6baf-4a27-bf77-2907577524d6',
verificationAudioURL: 'https://cisco.webex.com/captchaservice/v1/captchas/Captcha_b40798d4-6baf-4a27-bf77-2907577524d6/verificationCodeAudio',
};

mockSDKMeeting.requiredCaptcha = mockCaptcha;

await meetingsSDKAdapter.refreshCaptcha(meetingID);

expect(mockSDKMeeting.refreshCaptcha).toHaveBeenCalledWith();
expect(mockSDKMeeting.emit).toHaveBeenCalledTimes(1);
expect(mockSDKMeeting.emit.mock.calls[0][0]).toBe('adapter:meeting:updated');
expect(mockSDKMeeting.emit.mock.calls[0][1]).toMatchObject({requiredCaptcha: mockCaptcha});
});
});

describe('joinMeeting()', () => {
const verifyPasswordRes1 = {
failureReason: 'WRONG_PASSWORD',
isPasswordValid: false,
requiredCaptcha: {
captchaId: 'Captcha_c3c3009f-c844-4305-b1c4-6aed2a251247',
refreshURL: 'https://cisco.webex.com/captchaservice/v1/captchas/refresh?siteurl=cisco&captchaID=Captcha_c3c3009f-c844-4305-b1c4-6aed2a251247',
verificationAudioURL: 'https://cisco.webex.com/captchaservice/v1/captchas/Captcha_c3c3009f-c844-4305-b1c4-6aed2a251247/verificationCodeAudio',
verificationImageURL: 'https://cisco.webex.com/captchaservice/v1/captchas/Captcha_c3c3009f-c844-4305-b1c4-6aed2a251247/verificationCodeImage',
},
};

const mockResponse1 = {
failureReason: 'WRONG_PASSWORD',
invalidPassword: true,
requiredCaptcha: {
captchaId: 'Captcha_c3c3009f-c844-4305-b1c4-6aed2a251247',
refreshURL: 'https://cisco.webex.com/captchaservice/v1/captchas/refresh?siteurl=cisco&captchaID=Captcha_c3c3009f-c844-4305-b1c4-6aed2a251247',
verificationAudioURL: 'https://cisco.webex.com/captchaservice/v1/captchas/Captcha_c3c3009f-c844-4305-b1c4-6aed2a251247/verificationCodeAudio',
verificationImageURL: 'https://cisco.webex.com/captchaservice/v1/captchas/Captcha_c3c3009f-c844-4305-b1c4-6aed2a251247/verificationCodeImage',
},
};

const verifyPasswordRes2 = {
failureReason: 'WRONG_CAPTCHA',
isPasswordValid: false,
requiredCaptcha: {
captchaId: 'Captcha_e34a56d8-c75e-4424-9a34-b1dd28badd68',
refreshURL: 'https://cisco.webex.com/captchaservice/v1/captchas/refresh?siteurl=cisco&captchaID=Captcha_e34a56d8-c75e-4424-9a34-b1dd28badd68',
verificationAudioURL: 'https://cisco.webex.com/captchaservice/v1/captchas/Captcha_e34a56d8-c75e-4424-9a34-b1dd28badd68/verificationCodeAudio',
verificationImageURL: 'https://cisco.webex.com/captchaservice/v1/captchas/Captcha_e34a56d8-c75e-4424-9a34-b1dd28badd68/verificationCodeImage',
},
};

const mockResponse2 = {
failureReason: 'WRONG_CAPTCHA',
invalidPassword: true,
requiredCaptcha: {
captchaId: 'Captcha_e34a56d8-c75e-4424-9a34-b1dd28badd68',
refreshURL: 'https://cisco.webex.com/captchaservice/v1/captchas/refresh?siteurl=cisco&captchaID=Captcha_e34a56d8-c75e-4424-9a34-b1dd28badd68',
verificationAudioURL: 'https://cisco.webex.com/captchaservice/v1/captchas/Captcha_e34a56d8-c75e-4424-9a34-b1dd28badd68/verificationCodeAudio',
verificationImageURL: 'https://cisco.webex.com/captchaservice/v1/captchas/Captcha_e34a56d8-c75e-4424-9a34-b1dd28badd68/verificationCodeImage',
},
};

it('joinMeeting with correct password with no captcha needed', async () => {
mockSDKMeeting.verifyPassword = jest.fn(() => Promise.resolve({
failureReason: 'NONE',
isPasswordValid: true,
requiredCaptcha: null,
}));
await meetingsSDKAdapter.joinMeeting(meetingID, {password: 'BJzbHDKd347'});

expect(mockSDKMeeting.verifyPassword).toHaveBeenCalledWith('BJzbHDKd347', undefined);
expect(mockSDKMeeting.emit).not.toHaveBeenCalled();
expect(mockSDKMeeting.join).toHaveBeenCalledTimes(1);
});

it('joinMeeting with incorrect password multiple times and receiving captcha code to be entered', async () => {
mockSDKMeeting.verifyPassword = jest.fn(() => Promise.resolve(verifyPasswordRes1));
mockSDKMeeting.requiredCaptcha = verifyPasswordRes1.requiredCaptcha;

await meetingsSDKAdapter.joinMeeting(meetingID, {password: 'fahdkwlr'});

expect(mockSDKMeeting.verifyPassword).toHaveBeenCalledWith('fahdkwlr', undefined);
expect(mockSDKMeeting.emit).toHaveBeenCalledTimes(1);
expect(mockSDKMeeting.emit.mock.calls[0][0]).toBe('adapter:meeting:updated');
expect(mockSDKMeeting.emit.mock.calls[0][1]).toMatchObject(mockResponse1);
});

it('joinMeeting with correct password and incorrect captcha', async () => {
mockSDKMeeting.verifyPassword = jest.fn(() => Promise.resolve(verifyPasswordRes2));
mockSDKMeeting.requiredCaptcha = verifyPasswordRes2.requiredCaptcha;

await meetingsSDKAdapter.joinMeeting(meetingID, {password: 'BJzbHDKd347', captcha: 'pfucip'});

expect(mockSDKMeeting.verifyPassword).toHaveBeenCalledWith('BJzbHDKd347', 'pfucip');
expect(mockSDKMeeting.emit).toHaveBeenCalledTimes(1);
expect(mockSDKMeeting.emit.mock.calls[0][0]).toBe('adapter:meeting:updated');
expect(mockSDKMeeting.emit.mock.calls[0][1]).toMatchObject(mockResponse2);
});
});
});
1 change: 1 addition & 0 deletions src/MeetingsSDKAdapter/testHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export function createTestMeetingsSDKAdapter() {
remoteAudio: null,
remoteVideo: null,
remoteShare: null,
requiredCaptcha: {},
showRoster: null,
settings: {
visible: false,
Expand Down
4 changes: 4 additions & 0 deletions src/mockSdk.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ export const createMockSDKMeeting = () => ({
meetingInfo: {
isWebexScheduled: true,
},
meetingFiniteStateMachine: {
reset: jest.fn(),
},
members: {
membersCollection: {
members: {
Expand Down Expand Up @@ -174,6 +177,7 @@ export const createMockSDKMeeting = () => ({
canUpdateMedia: jest.fn(() => true),
updateShare: jest.fn(() => Promise.resolve()),
changeVideoLayout: jest.fn(() => Promise.resolve()),
refreshCaptcha: jest.fn(),
});

export const mockSDKMembership = {
Expand Down

0 comments on commit 34a8a18

Please sign in to comment.