test: update tests and helpers to reflect code changes

This commit is contained in:
juancarmore 2025-07-11 12:14:15 +02:00
parent 98de6fe0e8
commit 169030a995
9 changed files with 291 additions and 135 deletions

View File

@ -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);
};

View File

@ -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');

View File

@ -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({

View File

@ -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');
});
});

View File

@ -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);
});
});

View File

@ -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);
});
});

View File

@ -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);
});
});

View File

@ -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);
});
});

View File

@ -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);
});
});