test: update tests and helpers to reflect code changes
This commit is contained in:
parent
98de6fe0e8
commit
169030a995
@ -1,5 +1,7 @@
|
||||
import { expect } from '@jest/globals';
|
||||
import { container } from '../../src/config/dependency-injector.config';
|
||||
import INTERNAL_CONFIG from '../../src/config/internal-config';
|
||||
import { TokenService } from '../../src/services';
|
||||
import {
|
||||
MeetRecordingAccess,
|
||||
MeetRecordingInfo,
|
||||
@ -521,7 +523,8 @@ export const expectValidParticipantTokenResponse = (
|
||||
response: any,
|
||||
roomId: string,
|
||||
participantName: string,
|
||||
participantRole: ParticipantRole
|
||||
participantRole: ParticipantRole,
|
||||
otherRoles: ParticipantRole[] = []
|
||||
) => {
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.body).toHaveProperty('token');
|
||||
@ -530,13 +533,24 @@ export const expectValidParticipantTokenResponse = (
|
||||
const decodedToken = decodeJWTToken(token);
|
||||
|
||||
const permissions = getPermissions(roomId, participantRole);
|
||||
const rolesAndPermissions = otherRoles.map((role) => ({
|
||||
role,
|
||||
permissions: getPermissions(roomId, role).openvidu
|
||||
}));
|
||||
|
||||
if (!rolesAndPermissions.some((r) => r.role === participantRole)) {
|
||||
rolesAndPermissions.push({
|
||||
role: participantRole,
|
||||
permissions: permissions.openvidu
|
||||
});
|
||||
}
|
||||
|
||||
expect(decodedToken).toHaveProperty('sub', participantName);
|
||||
expect(decodedToken).toHaveProperty('video', permissions.livekit);
|
||||
expect(decodedToken).toHaveProperty('metadata');
|
||||
const metadata = JSON.parse(decodedToken.metadata);
|
||||
expect(metadata).toHaveProperty('role', participantRole);
|
||||
expect(metadata).toHaveProperty('permissions', permissions.openvidu);
|
||||
const metadata = JSON.parse(decodedToken.metadata || '{}');
|
||||
expect(metadata).toHaveProperty('roles');
|
||||
expect(metadata.roles).toEqual(expect.arrayContaining(rolesAndPermissions));
|
||||
|
||||
// Check that the token is included in a cookie
|
||||
expect(response.headers['set-cookie']).toBeDefined();
|
||||
@ -568,7 +582,7 @@ export const expectValidRecordingTokenResponse = (
|
||||
room: roomId
|
||||
});
|
||||
expect(decodedToken).toHaveProperty('metadata');
|
||||
const metadata = JSON.parse(decodedToken.metadata);
|
||||
const metadata = JSON.parse(decodedToken.metadata || '{}');
|
||||
expect(metadata).toHaveProperty('role', participantRole);
|
||||
expect(metadata).toHaveProperty('recordingPermissions', {
|
||||
canRetrieveRecordings,
|
||||
@ -589,13 +603,6 @@ export const expectValidRecordingTokenResponse = (
|
||||
};
|
||||
|
||||
const decodeJWTToken = (token: string) => {
|
||||
const base64Url = token.split('.')[1];
|
||||
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
|
||||
const jsonPayload = decodeURIComponent(
|
||||
atob(base64)
|
||||
.split('')
|
||||
.map((c) => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2))
|
||||
.join('')
|
||||
);
|
||||
return JSON.parse(jsonPayload);
|
||||
const tokenService = container.get(TokenService);
|
||||
return tokenService.getClaimsIgnoringExpiration(token);
|
||||
};
|
||||
|
||||
@ -21,6 +21,7 @@ import {
|
||||
MeetRecordingAccess,
|
||||
MeetRoom,
|
||||
MeetRoomOptions,
|
||||
ParticipantRole,
|
||||
WebhookPreferences
|
||||
} from '../../src/typings/ce/index.js';
|
||||
|
||||
@ -233,12 +234,13 @@ export const getRoom = async (roomId: string, fields?: string) => {
|
||||
.query({ fields });
|
||||
};
|
||||
|
||||
export const getRoomPreferences = async (roomId: string, cookie: string) => {
|
||||
export const getRoomPreferences = async (roomId: string, cookie: string, role: ParticipantRole) => {
|
||||
checkAppIsRunning();
|
||||
|
||||
return await request(app)
|
||||
.get(`${INTERNAL_CONFIG.INTERNAL_API_BASE_PATH_V1}/rooms/${roomId}/preferences`)
|
||||
.set('Cookie', cookie)
|
||||
.set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, role)
|
||||
.send();
|
||||
};
|
||||
|
||||
@ -357,7 +359,7 @@ export const getRoomRoleBySecret = async (roomId: string, secret: string) => {
|
||||
return response;
|
||||
};
|
||||
|
||||
export const generateParticipantToken = async (participantOptions: any) => {
|
||||
export const generateParticipantToken = async (participantOptions: any, cookie?: string) => {
|
||||
checkAppIsRunning();
|
||||
|
||||
// Disable authentication to generate the token
|
||||
@ -366,6 +368,7 @@ export const generateParticipantToken = async (participantOptions: any) => {
|
||||
// Generate the participant token
|
||||
const response = await request(app)
|
||||
.post(`${INTERNAL_CONFIG.INTERNAL_API_BASE_PATH_V1}/participants/token`)
|
||||
.set('Cookie', cookie || '')
|
||||
.send(participantOptions);
|
||||
return response;
|
||||
};
|
||||
@ -376,14 +379,18 @@ export const generateParticipantToken = async (participantOptions: any) => {
|
||||
export const generateParticipantTokenCookie = async (
|
||||
roomId: string,
|
||||
participantName: string,
|
||||
secret: string
|
||||
secret: string,
|
||||
cookie?: string
|
||||
): Promise<string> => {
|
||||
// Generate the participant token
|
||||
const response = await generateParticipantToken({
|
||||
roomId,
|
||||
participantName,
|
||||
secret
|
||||
});
|
||||
const response = await generateParticipantToken(
|
||||
{
|
||||
roomId,
|
||||
participantName,
|
||||
secret
|
||||
},
|
||||
cookie
|
||||
);
|
||||
expect(response.status).toBe(200);
|
||||
|
||||
// Return the participant token cookie
|
||||
@ -394,7 +401,7 @@ export const generateParticipantTokenCookie = async (
|
||||
return participantTokenCookie;
|
||||
};
|
||||
|
||||
export const refreshParticipantToken = async (participantOptions: any) => {
|
||||
export const refreshParticipantToken = async (participantOptions: any, cookie: string) => {
|
||||
checkAppIsRunning();
|
||||
|
||||
// Disable authentication to generate the token
|
||||
@ -402,6 +409,7 @@ export const refreshParticipantToken = async (participantOptions: any) => {
|
||||
|
||||
const response = await request(app)
|
||||
.post(`${INTERNAL_CONFIG.INTERNAL_API_BASE_PATH_V1}/participants/token/refresh`)
|
||||
.set('Cookie', cookie)
|
||||
.send(participantOptions);
|
||||
return response;
|
||||
};
|
||||
@ -496,6 +504,7 @@ export const deleteParticipant = async (roomId: string, participantName: string,
|
||||
const response = await request(app)
|
||||
.delete(`${INTERNAL_CONFIG.INTERNAL_API_BASE_PATH_V1}/meetings/${roomId}/participants/${participantName}`)
|
||||
.set('Cookie', moderatorCookie)
|
||||
.set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.MODERATOR)
|
||||
.send();
|
||||
return response;
|
||||
};
|
||||
@ -506,6 +515,7 @@ export const endMeeting = async (roomId: string, moderatorCookie: string) => {
|
||||
const response = await request(app)
|
||||
.delete(`${INTERNAL_CONFIG.INTERNAL_API_BASE_PATH_V1}/meetings/${roomId}`)
|
||||
.set('Cookie', moderatorCookie)
|
||||
.set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.MODERATOR)
|
||||
.send();
|
||||
await sleep('1s');
|
||||
return response;
|
||||
@ -547,6 +557,7 @@ export const startRecording = async (roomId: string, moderatorCookie = '') => {
|
||||
return await request(app)
|
||||
.post(`${INTERNAL_CONFIG.INTERNAL_API_BASE_PATH_V1}/recordings`)
|
||||
.set('Cookie', moderatorCookie)
|
||||
.set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.MODERATOR)
|
||||
.send({
|
||||
roomId
|
||||
});
|
||||
@ -558,6 +569,7 @@ export const stopRecording = async (recordingId: string, moderatorCookie = '') =
|
||||
const response = await request(app)
|
||||
.post(`${INTERNAL_CONFIG.INTERNAL_API_BASE_PATH_V1}/recordings/${recordingId}/stop`)
|
||||
.set('Cookie', moderatorCookie)
|
||||
.set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.MODERATOR)
|
||||
.send();
|
||||
await sleep('2.5s');
|
||||
|
||||
|
||||
@ -5,6 +5,7 @@ import {
|
||||
deleteAllRooms,
|
||||
disconnectFakeParticipants,
|
||||
generateParticipantToken,
|
||||
generateParticipantTokenCookie,
|
||||
startTestServer
|
||||
} from '../../../helpers/request-helpers.js';
|
||||
import { RoomData, setupSingleRoom } from '../../../helpers/test-scenarios.js';
|
||||
@ -53,6 +54,30 @@ describe('Participant API Tests', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it(`should generate a participant token with both publisher and moderator permissions
|
||||
when using the publisher secret after having a moderator token`, async () => {
|
||||
const moderatorCookie = await generateParticipantTokenCookie(
|
||||
roomData.room.roomId,
|
||||
`${participantName}_MODERATOR`,
|
||||
roomData.moderatorSecret
|
||||
);
|
||||
const publisherResponse = await generateParticipantToken(
|
||||
{
|
||||
roomId: roomData.room.roomId,
|
||||
participantName: `${participantName}_PUBLISHER`,
|
||||
secret: roomData.publisherSecret
|
||||
},
|
||||
moderatorCookie
|
||||
);
|
||||
expectValidParticipantTokenResponse(
|
||||
publisherResponse,
|
||||
roomData.room.roomId,
|
||||
`${participantName}_PUBLISHER`,
|
||||
ParticipantRole.PUBLISHER,
|
||||
[ParticipantRole.MODERATOR]
|
||||
);
|
||||
});
|
||||
|
||||
it('should fail with 409 when participant already exists in the room', async () => {
|
||||
roomData = await setupSingleRoom(true);
|
||||
const response = await generateParticipantToken({
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
import { afterAll, beforeAll, describe, expect, it } from '@jest/globals';
|
||||
import INTERNAL_CONFIG from '../../../../src/config/internal-config.js';
|
||||
import { ParticipantRole } from '../../../../src/typings/ce/participant.js';
|
||||
import { expectValidationError, expectValidParticipantTokenResponse } from '../../../helpers/assertion-helpers.js';
|
||||
import {
|
||||
deleteAllRooms,
|
||||
disconnectFakeParticipants,
|
||||
refreshParticipantToken,
|
||||
sleep,
|
||||
startTestServer
|
||||
} from '../../../helpers/request-helpers.js';
|
||||
import { RoomData, setupSingleRoom } from '../../../helpers/test-scenarios.js';
|
||||
@ -16,7 +18,16 @@ describe('Participant API Tests', () => {
|
||||
|
||||
beforeAll(async () => {
|
||||
startTestServer();
|
||||
|
||||
// Set short expiration for testing
|
||||
const initialTokenExpiration = INTERNAL_CONFIG.PARTICIPANT_TOKEN_EXPIRATION;
|
||||
INTERNAL_CONFIG.PARTICIPANT_TOKEN_EXPIRATION = '1s';
|
||||
|
||||
roomData = await setupSingleRoom(true);
|
||||
await sleep('2s'); // Ensure the token is expired
|
||||
|
||||
// Restore original expiration after setup
|
||||
INTERNAL_CONFIG.PARTICIPANT_TOKEN_EXPIRATION = initialTokenExpiration;
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
@ -26,11 +37,14 @@ describe('Participant API Tests', () => {
|
||||
|
||||
describe('Refresh Participant Token Tests', () => {
|
||||
it('should refresh participant token with moderator permissions when using the moderator secret', async () => {
|
||||
const response = await refreshParticipantToken({
|
||||
roomId: roomData.room.roomId,
|
||||
participantName,
|
||||
secret: roomData.moderatorSecret
|
||||
});
|
||||
const response = await refreshParticipantToken(
|
||||
{
|
||||
roomId: roomData.room.roomId,
|
||||
participantName,
|
||||
secret: roomData.moderatorSecret
|
||||
},
|
||||
roomData.moderatorCookie
|
||||
);
|
||||
expectValidParticipantTokenResponse(
|
||||
response,
|
||||
roomData.room.roomId,
|
||||
@ -40,11 +54,14 @@ describe('Participant API Tests', () => {
|
||||
});
|
||||
|
||||
it('should refresh participant token with publisher permissions when using the publisher secret', async () => {
|
||||
const response = await refreshParticipantToken({
|
||||
roomId: roomData.room.roomId,
|
||||
participantName,
|
||||
secret: roomData.publisherSecret
|
||||
});
|
||||
const response = await refreshParticipantToken(
|
||||
{
|
||||
roomId: roomData.room.roomId,
|
||||
participantName,
|
||||
secret: roomData.publisherSecret
|
||||
},
|
||||
roomData.publisherCookie
|
||||
);
|
||||
expectValidParticipantTokenResponse(
|
||||
response,
|
||||
roomData.room.roomId,
|
||||
@ -53,78 +70,126 @@ describe('Participant API Tests', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should fail with 404 when participant does not exist in the room', async () => {
|
||||
roomData = await setupSingleRoom();
|
||||
const response = await refreshParticipantToken({
|
||||
roomId: roomData.room.roomId,
|
||||
participantName,
|
||||
secret: roomData.moderatorSecret
|
||||
});
|
||||
expect(response.status).toBe(404);
|
||||
it('should fail with 400 when secret is invalid', async () => {
|
||||
const response = await refreshParticipantToken(
|
||||
{
|
||||
roomId: roomData.room.roomId,
|
||||
participantName,
|
||||
secret: 'invalid_secret'
|
||||
},
|
||||
roomData.moderatorCookie
|
||||
);
|
||||
expect(response.status).toBe(400);
|
||||
});
|
||||
|
||||
// Recreate the room with participant
|
||||
roomData = await setupSingleRoom(true);
|
||||
it('should fail with 400 when previous token is not provided', async () => {
|
||||
const response = await refreshParticipantToken(
|
||||
{
|
||||
roomId: roomData.room.roomId,
|
||||
participantName,
|
||||
secret: roomData.moderatorSecret
|
||||
},
|
||||
''
|
||||
);
|
||||
expect(response.status).toBe(400);
|
||||
expect(response.body.message).toBe('No participant token provided');
|
||||
});
|
||||
|
||||
it('should fail with 404 when participant does not exist in the room', async () => {
|
||||
const newRoomData = await setupSingleRoom();
|
||||
const response = await refreshParticipantToken(
|
||||
{
|
||||
roomId: newRoomData.room.roomId,
|
||||
participantName,
|
||||
secret: newRoomData.moderatorSecret
|
||||
},
|
||||
roomData.moderatorCookie
|
||||
);
|
||||
expect(response.status).toBe(404);
|
||||
});
|
||||
|
||||
it('should fail with 404 when room does not exist', async () => {
|
||||
const response = await refreshParticipantToken({
|
||||
roomId: 'non_existent_room',
|
||||
participantName,
|
||||
secret: roomData.moderatorSecret
|
||||
});
|
||||
const response = await refreshParticipantToken(
|
||||
{
|
||||
roomId: 'non_existent_room',
|
||||
participantName,
|
||||
secret: roomData.moderatorSecret
|
||||
},
|
||||
roomData.moderatorCookie
|
||||
);
|
||||
expect(response.status).toBe(404);
|
||||
});
|
||||
|
||||
it('should fail with 400 when secret is invalid', async () => {
|
||||
const response = await refreshParticipantToken({
|
||||
roomId: roomData.room.roomId,
|
||||
participantName,
|
||||
secret: 'invalid_secret'
|
||||
});
|
||||
expect(response.status).toBe(400);
|
||||
it('should fail with 409 when participant token is still valid', async () => {
|
||||
const newRoomData = await setupSingleRoom(true);
|
||||
const response = await refreshParticipantToken(
|
||||
{
|
||||
roomId: newRoomData.room.roomId,
|
||||
participantName,
|
||||
secret: newRoomData.moderatorSecret
|
||||
},
|
||||
newRoomData.moderatorCookie
|
||||
);
|
||||
expect(response.status).toBe(409);
|
||||
expect(response.body.message).toBe('Participant token is still valid');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Refresh Participant Token Validation Tests', () => {
|
||||
it('should fail when roomId is not provided', async () => {
|
||||
const response = await refreshParticipantToken({
|
||||
participantName,
|
||||
secret: roomData.moderatorSecret
|
||||
});
|
||||
const response = await refreshParticipantToken(
|
||||
{
|
||||
participantName,
|
||||
secret: roomData.moderatorSecret
|
||||
},
|
||||
roomData.moderatorCookie
|
||||
);
|
||||
expectValidationError(response, 'roomId', 'Required');
|
||||
});
|
||||
|
||||
it('should fail when participantName is not provided', async () => {
|
||||
const response = await refreshParticipantToken({
|
||||
roomId: roomData.room.roomId,
|
||||
secret: roomData.moderatorSecret
|
||||
});
|
||||
const response = await refreshParticipantToken(
|
||||
{
|
||||
roomId: roomData.room.roomId,
|
||||
secret: roomData.moderatorSecret
|
||||
},
|
||||
roomData.moderatorCookie
|
||||
);
|
||||
expectValidationError(response, 'participantName', 'Required');
|
||||
});
|
||||
|
||||
it('should fail when secret is not provided', async () => {
|
||||
const response = await refreshParticipantToken({
|
||||
roomId: roomData.room.roomId,
|
||||
participantName
|
||||
});
|
||||
const response = await refreshParticipantToken(
|
||||
{
|
||||
roomId: roomData.room.roomId,
|
||||
participantName
|
||||
},
|
||||
roomData.moderatorCookie
|
||||
);
|
||||
expectValidationError(response, 'secret', 'Required');
|
||||
});
|
||||
|
||||
it('should fail when participantName is empty', async () => {
|
||||
const response = await refreshParticipantToken({
|
||||
roomId: roomData.room.roomId,
|
||||
participantName: '',
|
||||
secret: roomData.moderatorSecret
|
||||
});
|
||||
const response = await refreshParticipantToken(
|
||||
{
|
||||
roomId: roomData.room.roomId,
|
||||
participantName: '',
|
||||
secret: roomData.moderatorSecret
|
||||
},
|
||||
roomData.moderatorCookie
|
||||
);
|
||||
expectValidationError(response, 'participantName', 'Participant name is required');
|
||||
});
|
||||
|
||||
it('should fail when secret is empty', async () => {
|
||||
const response = await refreshParticipantToken({
|
||||
roomId: roomData.room.roomId,
|
||||
participantName,
|
||||
secret: ''
|
||||
});
|
||||
const response = await refreshParticipantToken(
|
||||
{
|
||||
roomId: roomData.room.roomId,
|
||||
participantName,
|
||||
secret: ''
|
||||
},
|
||||
roomData.moderatorCookie
|
||||
);
|
||||
expectValidationError(response, 'secret', 'Secret is required');
|
||||
});
|
||||
});
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { afterEach, beforeAll, describe, it } from '@jest/globals';
|
||||
import { MeetRecordingAccess } from '../../../../src/typings/ce/index.js';
|
||||
import { MeetRecordingAccess, ParticipantRole } from '../../../../src/typings/ce/index.js';
|
||||
import { expectSuccessRoomPreferencesResponse } from '../../../helpers/assertion-helpers.js';
|
||||
import { deleteAllRooms, getRoomPreferences, startTestServer } from '../../../helpers/request-helpers.js';
|
||||
import { setupSingleRoom } from '../../../helpers/test-scenarios.js';
|
||||
@ -29,7 +29,7 @@ describe('Room API Tests', () => {
|
||||
const roomId = roomData.room.roomId;
|
||||
const cookie = roomData.moderatorCookie;
|
||||
|
||||
const response = await getRoomPreferences(roomId, cookie);
|
||||
const response = await getRoomPreferences(roomId, cookie, ParticipantRole.MODERATOR);
|
||||
expectSuccessRoomPreferencesResponse(response, DEFAULT_PREFERENCES);
|
||||
});
|
||||
|
||||
@ -50,7 +50,7 @@ describe('Room API Tests', () => {
|
||||
const roomId = roomData.room.roomId;
|
||||
const cookie = roomData.moderatorCookie;
|
||||
|
||||
const response = await getRoomPreferences(roomId, cookie);
|
||||
const response = await getRoomPreferences(roomId, cookie, ParticipantRole.MODERATOR);
|
||||
expectSuccessRoomPreferencesResponse(response, payload.preferences);
|
||||
});
|
||||
});
|
||||
|
||||
@ -3,6 +3,7 @@ import { Express } from 'express';
|
||||
import request from 'supertest';
|
||||
import INTERNAL_CONFIG from '../../../../src/config/internal-config.js';
|
||||
import { MEET_API_KEY } from '../../../../src/environment.js';
|
||||
import { ParticipantRole } from '../../../../src/typings/ce';
|
||||
import {
|
||||
deleteAllRooms,
|
||||
disconnectFakeParticipants,
|
||||
@ -50,7 +51,8 @@ describe('Meeting API Security Tests', () => {
|
||||
it('should succeed when participant is moderator', async () => {
|
||||
const response = await request(app)
|
||||
.delete(`${MEETINGS_PATH}/${roomData.room.roomId}`)
|
||||
.set('Cookie', roomData.moderatorCookie);
|
||||
.set('Cookie', roomData.moderatorCookie)
|
||||
.set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.MODERATOR);
|
||||
expect(response.status).toBe(200);
|
||||
});
|
||||
|
||||
@ -59,14 +61,16 @@ describe('Meeting API Security Tests', () => {
|
||||
|
||||
const response = await request(app)
|
||||
.delete(`${MEETINGS_PATH}/${roomData.room.roomId}`)
|
||||
.set('Cookie', newRoomData.moderatorCookie);
|
||||
.set('Cookie', newRoomData.moderatorCookie)
|
||||
.set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.MODERATOR);
|
||||
expect(response.status).toBe(403);
|
||||
});
|
||||
|
||||
it('should fail when participant is publisher', async () => {
|
||||
const response = await request(app)
|
||||
.delete(`${MEETINGS_PATH}/${roomData.room.roomId}`)
|
||||
.set('Cookie', roomData.publisherCookie);
|
||||
.set('Cookie', roomData.publisherCookie)
|
||||
.set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.PUBLISHER);
|
||||
expect(response.status).toBe(403);
|
||||
});
|
||||
});
|
||||
@ -91,7 +95,8 @@ describe('Meeting API Security Tests', () => {
|
||||
it('should succeed when participant is moderator', async () => {
|
||||
const response = await request(app)
|
||||
.delete(`${MEETINGS_PATH}/${roomData.room.roomId}/participants/${PARTICIPANT_NAME}`)
|
||||
.set('Cookie', roomData.moderatorCookie);
|
||||
.set('Cookie', roomData.moderatorCookie)
|
||||
.set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.MODERATOR);
|
||||
expect(response.status).toBe(200);
|
||||
});
|
||||
|
||||
@ -100,14 +105,16 @@ describe('Meeting API Security Tests', () => {
|
||||
|
||||
const response = await request(app)
|
||||
.delete(`${MEETINGS_PATH}/${roomData.room.roomId}/participants/${PARTICIPANT_NAME}`)
|
||||
.set('Cookie', newRoomData.moderatorCookie);
|
||||
.set('Cookie', newRoomData.moderatorCookie)
|
||||
.set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.MODERATOR);
|
||||
expect(response.status).toBe(403);
|
||||
});
|
||||
|
||||
it('should fail when participant is publisher', async () => {
|
||||
const response = await request(app)
|
||||
.delete(`${MEETINGS_PATH}/${roomData.room.roomId}/participants/${PARTICIPANT_NAME}`)
|
||||
.set('Cookie', roomData.publisherCookie);
|
||||
.set('Cookie', roomData.publisherCookie)
|
||||
.set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.PUBLISHER);
|
||||
expect(response.status).toBe(403);
|
||||
});
|
||||
});
|
||||
|
||||
@ -8,6 +8,7 @@ import {
|
||||
deleteAllRooms,
|
||||
disconnectFakeParticipants,
|
||||
loginUser,
|
||||
sleep,
|
||||
startTestServer
|
||||
} from '../../../helpers/request-helpers.js';
|
||||
import { RoomData, setupSingleRoom } from '../../../helpers/test-scenarios.js';
|
||||
@ -141,39 +142,56 @@ describe('Participant API Security Tests', () => {
|
||||
let roomData: RoomData;
|
||||
|
||||
beforeAll(async () => {
|
||||
// Set short expiration for testing
|
||||
const initialTokenExpiration = INTERNAL_CONFIG.PARTICIPANT_TOKEN_EXPIRATION;
|
||||
INTERNAL_CONFIG.PARTICIPANT_TOKEN_EXPIRATION = '1s';
|
||||
|
||||
roomData = await setupSingleRoom(true);
|
||||
await sleep('2s'); // Ensure the token is expired
|
||||
|
||||
// Restore original expiration after setup
|
||||
INTERNAL_CONFIG.PARTICIPANT_TOKEN_EXPIRATION = initialTokenExpiration;
|
||||
});
|
||||
|
||||
it('should succeed when no authentication is required and participant is publisher', async () => {
|
||||
await changeSecurityPreferences(AuthMode.NONE);
|
||||
|
||||
const response = await request(app).post(`${PARTICIPANTS_PATH}/token/refresh`).send({
|
||||
roomId: roomData.room.roomId,
|
||||
participantName: PARTICIPANT_NAME,
|
||||
secret: roomData.publisherSecret
|
||||
});
|
||||
const response = await request(app)
|
||||
.post(`${PARTICIPANTS_PATH}/token/refresh`)
|
||||
.set('Cookie', roomData.publisherCookie)
|
||||
.send({
|
||||
roomId: roomData.room.roomId,
|
||||
participantName: PARTICIPANT_NAME,
|
||||
secret: roomData.publisherSecret
|
||||
});
|
||||
expect(response.status).toBe(200);
|
||||
});
|
||||
|
||||
it('should succeed when no authentication is required and participant is moderator', async () => {
|
||||
await changeSecurityPreferences(AuthMode.NONE);
|
||||
|
||||
const response = await request(app).post(`${PARTICIPANTS_PATH}/token/refresh`).send({
|
||||
roomId: roomData.room.roomId,
|
||||
participantName: PARTICIPANT_NAME,
|
||||
secret: roomData.moderatorSecret
|
||||
});
|
||||
const response = await request(app)
|
||||
.post(`${PARTICIPANTS_PATH}/token/refresh`)
|
||||
.set('Cookie', roomData.moderatorCookie)
|
||||
.send({
|
||||
roomId: roomData.room.roomId,
|
||||
participantName: PARTICIPANT_NAME,
|
||||
secret: roomData.moderatorSecret
|
||||
});
|
||||
expect(response.status).toBe(200);
|
||||
});
|
||||
|
||||
it('should succeed when authentication is required for moderator and participant is publisher', async () => {
|
||||
await changeSecurityPreferences(AuthMode.MODERATORS_ONLY);
|
||||
|
||||
const response = await request(app).post(`${PARTICIPANTS_PATH}/token/refresh`).send({
|
||||
roomId: roomData.room.roomId,
|
||||
participantName: PARTICIPANT_NAME,
|
||||
secret: roomData.publisherSecret
|
||||
});
|
||||
const response = await request(app)
|
||||
.post(`${PARTICIPANTS_PATH}/token/refresh`)
|
||||
.set('Cookie', roomData.publisherCookie)
|
||||
.send({
|
||||
roomId: roomData.room.roomId,
|
||||
participantName: PARTICIPANT_NAME,
|
||||
secret: roomData.publisherSecret
|
||||
});
|
||||
expect(response.status).toBe(200);
|
||||
});
|
||||
|
||||
@ -182,7 +200,7 @@ describe('Participant API Security Tests', () => {
|
||||
|
||||
const response = await request(app)
|
||||
.post(`${PARTICIPANTS_PATH}/token/refresh`)
|
||||
.set('Cookie', adminCookie)
|
||||
.set('Cookie', [adminCookie, roomData.moderatorCookie])
|
||||
.send({
|
||||
roomId: roomData.room.roomId,
|
||||
participantName: PARTICIPANT_NAME,
|
||||
@ -194,11 +212,14 @@ describe('Participant API Security Tests', () => {
|
||||
it('should fail when authentication is required for moderator and participant is moderator but not authenticated', async () => {
|
||||
await changeSecurityPreferences(AuthMode.MODERATORS_ONLY);
|
||||
|
||||
const response = await request(app).post(`${PARTICIPANTS_PATH}/token/refresh`).send({
|
||||
roomId: roomData.room.roomId,
|
||||
participantName: PARTICIPANT_NAME,
|
||||
secret: roomData.moderatorSecret
|
||||
});
|
||||
const response = await request(app)
|
||||
.post(`${PARTICIPANTS_PATH}/token/refresh`)
|
||||
.set('Cookie', roomData.moderatorCookie)
|
||||
.send({
|
||||
roomId: roomData.room.roomId,
|
||||
participantName: PARTICIPANT_NAME,
|
||||
secret: roomData.moderatorSecret
|
||||
});
|
||||
expect(response.status).toBe(401);
|
||||
});
|
||||
|
||||
@ -207,7 +228,7 @@ describe('Participant API Security Tests', () => {
|
||||
|
||||
const response = await request(app)
|
||||
.post(`${PARTICIPANTS_PATH}/token/refresh`)
|
||||
.set('Cookie', adminCookie)
|
||||
.set('Cookie', [adminCookie, roomData.publisherCookie])
|
||||
.send({
|
||||
roomId: roomData.room.roomId,
|
||||
participantName: PARTICIPANT_NAME,
|
||||
@ -219,11 +240,14 @@ describe('Participant API Security Tests', () => {
|
||||
it('should fail when authentication is required for all users and participant is publisher but not authenticated', async () => {
|
||||
await changeSecurityPreferences(AuthMode.ALL_USERS);
|
||||
|
||||
const response = await request(app).post(`${PARTICIPANTS_PATH}/token/refresh`).send({
|
||||
roomId: roomData.room.roomId,
|
||||
participantName: PARTICIPANT_NAME,
|
||||
secret: roomData.publisherSecret
|
||||
});
|
||||
const response = await request(app)
|
||||
.post(`${PARTICIPANTS_PATH}/token/refresh`)
|
||||
.set('Cookie', roomData.publisherCookie)
|
||||
.send({
|
||||
roomId: roomData.room.roomId,
|
||||
participantName: PARTICIPANT_NAME,
|
||||
secret: roomData.publisherSecret
|
||||
});
|
||||
expect(response.status).toBe(401);
|
||||
});
|
||||
|
||||
@ -232,7 +256,7 @@ describe('Participant API Security Tests', () => {
|
||||
|
||||
const response = await request(app)
|
||||
.post(`${PARTICIPANTS_PATH}/token/refresh`)
|
||||
.set('Cookie', adminCookie)
|
||||
.set('Cookie', [adminCookie, roomData.moderatorCookie])
|
||||
.send({
|
||||
roomId: roomData.room.roomId,
|
||||
participantName: PARTICIPANT_NAME,
|
||||
@ -244,11 +268,14 @@ describe('Participant API Security Tests', () => {
|
||||
it('should fail when authentication is required for all users and participant is moderator but not authenticated', async () => {
|
||||
await changeSecurityPreferences(AuthMode.ALL_USERS);
|
||||
|
||||
const response = await request(app).post(`${PARTICIPANTS_PATH}/token/refresh`).send({
|
||||
roomId: roomData.room.roomId,
|
||||
participantName: PARTICIPANT_NAME,
|
||||
secret: roomData.moderatorSecret
|
||||
});
|
||||
const response = await request(app)
|
||||
.post(`${PARTICIPANTS_PATH}/token/refresh`)
|
||||
.set('Cookie', roomData.moderatorCookie)
|
||||
.send({
|
||||
roomId: roomData.room.roomId,
|
||||
participantName: PARTICIPANT_NAME,
|
||||
secret: roomData.moderatorSecret
|
||||
});
|
||||
expect(response.status).toBe(401);
|
||||
});
|
||||
});
|
||||
|
||||
@ -3,7 +3,7 @@ import { Express } from 'express';
|
||||
import request from 'supertest';
|
||||
import INTERNAL_CONFIG from '../../../../src/config/internal-config.js';
|
||||
import { MEET_API_KEY } from '../../../../src/environment.js';
|
||||
import { MeetRecordingAccess } from '../../../../src/typings/ce/index.js';
|
||||
import { MeetRecordingAccess, ParticipantRole } from '../../../../src/typings/ce/index.js';
|
||||
import { expectValidStopRecordingResponse } from '../../../helpers/assertion-helpers.js';
|
||||
import {
|
||||
deleteAllRecordings,
|
||||
@ -63,7 +63,8 @@ describe('Recording API Security Tests', () => {
|
||||
const response = await request(app)
|
||||
.post(INTERNAL_RECORDINGS_PATH)
|
||||
.send({ roomId: roomData.room.roomId })
|
||||
.set('Cookie', roomData.moderatorCookie);
|
||||
.set('Cookie', roomData.moderatorCookie)
|
||||
.set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.MODERATOR);
|
||||
expect(response.status).toBe(201);
|
||||
|
||||
// Stop recording to clean up
|
||||
@ -78,7 +79,8 @@ describe('Recording API Security Tests', () => {
|
||||
const response = await request(app)
|
||||
.post(INTERNAL_RECORDINGS_PATH)
|
||||
.send({ roomId: roomData.room.roomId })
|
||||
.set('Cookie', newRoomData.moderatorCookie);
|
||||
.set('Cookie', newRoomData.moderatorCookie)
|
||||
.set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.MODERATOR);
|
||||
expect(response.status).toBe(403);
|
||||
});
|
||||
|
||||
@ -86,7 +88,8 @@ describe('Recording API Security Tests', () => {
|
||||
const response = await request(app)
|
||||
.post(INTERNAL_RECORDINGS_PATH)
|
||||
.send({ roomId: roomData.room.roomId })
|
||||
.set('Cookie', roomData.publisherCookie);
|
||||
.set('Cookie', roomData.publisherCookie)
|
||||
.set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.PUBLISHER);
|
||||
expect(response.status).toBe(403);
|
||||
});
|
||||
});
|
||||
@ -119,7 +122,8 @@ describe('Recording API Security Tests', () => {
|
||||
it('should succeed when participant is moderator', async () => {
|
||||
const response = await request(app)
|
||||
.post(`${INTERNAL_RECORDINGS_PATH}/${roomData.recordingId}/stop`)
|
||||
.set('Cookie', roomData.moderatorCookie);
|
||||
.set('Cookie', roomData.moderatorCookie)
|
||||
.set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.MODERATOR);
|
||||
expect(response.status).toBe(202);
|
||||
});
|
||||
|
||||
@ -128,14 +132,16 @@ describe('Recording API Security Tests', () => {
|
||||
|
||||
const response = await request(app)
|
||||
.post(`${INTERNAL_RECORDINGS_PATH}/${roomData.recordingId}/stop`)
|
||||
.set('Cookie', newRoomData.moderatorCookie);
|
||||
.set('Cookie', newRoomData.moderatorCookie)
|
||||
.set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.MODERATOR);
|
||||
expect(response.status).toBe(403);
|
||||
});
|
||||
|
||||
it('should fail when participant is publisher', async () => {
|
||||
const response = await request(app)
|
||||
.post(`${INTERNAL_RECORDINGS_PATH}/${roomData.recordingId}/stop`)
|
||||
.set('Cookie', roomData.publisherCookie);
|
||||
.set('Cookie', roomData.publisherCookie)
|
||||
.set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.PUBLISHER);
|
||||
expect(response.status).toBe(403);
|
||||
});
|
||||
});
|
||||
|
||||
@ -3,7 +3,7 @@ import { Express } from 'express';
|
||||
import request from 'supertest';
|
||||
import INTERNAL_CONFIG from '../../../../src/config/internal-config.js';
|
||||
import { MEET_API_KEY } from '../../../../src/environment.js';
|
||||
import { AuthMode, MeetRecordingAccess } from '../../../../src/typings/ce/index.js';
|
||||
import { AuthMode, MeetRecordingAccess, ParticipantRole } from '../../../../src/typings/ce/index.js';
|
||||
import {
|
||||
changeSecurityPreferences,
|
||||
createRoom,
|
||||
@ -127,7 +127,8 @@ describe('Room API Security Tests', () => {
|
||||
it('should succeed when participant is moderator', async () => {
|
||||
const response = await request(app)
|
||||
.get(`${ROOMS_PATH}/${roomData.room.roomId}`)
|
||||
.set('Cookie', roomData.moderatorCookie);
|
||||
.set('Cookie', roomData.moderatorCookie)
|
||||
.set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.MODERATOR);
|
||||
expect(response.status).toBe(200);
|
||||
});
|
||||
|
||||
@ -136,14 +137,16 @@ describe('Room API Security Tests', () => {
|
||||
|
||||
const response = await request(app)
|
||||
.get(`${ROOMS_PATH}/${roomData.room.roomId}`)
|
||||
.set('Cookie', newRoomData.moderatorCookie);
|
||||
.set('Cookie', newRoomData.moderatorCookie)
|
||||
.set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.MODERATOR);
|
||||
expect(response.status).toBe(403);
|
||||
});
|
||||
|
||||
it('should fail when participant is publisher', async () => {
|
||||
const response = await request(app)
|
||||
.get(`${ROOMS_PATH}/${roomData.room.roomId}`)
|
||||
.set('Cookie', roomData.publisherCookie);
|
||||
.set('Cookie', roomData.publisherCookie)
|
||||
.set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.PUBLISHER);
|
||||
expect(response.status).toBe(403);
|
||||
});
|
||||
});
|
||||
@ -227,7 +230,7 @@ describe('Room API Security Tests', () => {
|
||||
expect(response.status).toBe(401);
|
||||
});
|
||||
|
||||
it('should fai when user is authenticated as admin', async () => {
|
||||
it('should fail when user is authenticated as admin', async () => {
|
||||
const response = await request(app)
|
||||
.get(`${INTERNAL_ROOMS_PATH}/${roomData.room.roomId}/preferences`)
|
||||
.set('Cookie', adminCookie);
|
||||
@ -242,7 +245,8 @@ describe('Room API Security Tests', () => {
|
||||
it('should succeed when participant is moderator', async () => {
|
||||
const response = await request(app)
|
||||
.get(`${INTERNAL_ROOMS_PATH}/${roomData.room.roomId}/preferences`)
|
||||
.set('Cookie', roomData.moderatorCookie);
|
||||
.set('Cookie', roomData.moderatorCookie)
|
||||
.set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.MODERATOR);
|
||||
expect(response.status).toBe(200);
|
||||
});
|
||||
|
||||
@ -251,14 +255,16 @@ describe('Room API Security Tests', () => {
|
||||
|
||||
const response = await request(app)
|
||||
.get(`${INTERNAL_ROOMS_PATH}/${roomData.room.roomId}/preferences`)
|
||||
.set('Cookie', newRoomData.moderatorCookie);
|
||||
.set('Cookie', newRoomData.moderatorCookie)
|
||||
.set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.MODERATOR);
|
||||
expect(response.status).toBe(403);
|
||||
});
|
||||
|
||||
it('should succeed when participant is publisher', async () => {
|
||||
const response = await request(app)
|
||||
.get(`${INTERNAL_ROOMS_PATH}/${roomData.room.roomId}/preferences`)
|
||||
.set('Cookie', roomData.publisherCookie);
|
||||
.set('Cookie', roomData.publisherCookie)
|
||||
.set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.PUBLISHER);
|
||||
expect(response.status).toBe(200);
|
||||
});
|
||||
|
||||
@ -267,7 +273,8 @@ describe('Room API Security Tests', () => {
|
||||
|
||||
const response = await request(app)
|
||||
.get(`${INTERNAL_ROOMS_PATH}/${roomData.room.roomId}/preferences`)
|
||||
.set('Cookie', newRoomData.publisherCookie);
|
||||
.set('Cookie', newRoomData.publisherCookie)
|
||||
.set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.PUBLISHER);
|
||||
expect(response.status).toBe(403);
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user