backend: add autoDeletionPolicy and related schemas to room validation and add new fileds when creating Meet room
This commit is contained in:
parent
04f828f82e
commit
e7fae2b3be
@ -2,6 +2,9 @@ import {
|
|||||||
MeetChatPreferences,
|
MeetChatPreferences,
|
||||||
MeetRecordingAccess,
|
MeetRecordingAccess,
|
||||||
MeetRecordingPreferences,
|
MeetRecordingPreferences,
|
||||||
|
MeetRoomAutoDeletionPolicy,
|
||||||
|
MeetRoomDeletionPolicyWithMeeting,
|
||||||
|
MeetRoomDeletionPolicyWithRecordings,
|
||||||
MeetRoomFilters,
|
MeetRoomFilters,
|
||||||
MeetRoomOptions,
|
MeetRoomOptions,
|
||||||
MeetRoomPreferences,
|
MeetRoomPreferences,
|
||||||
@ -55,17 +58,6 @@ export const nonEmptySanitizedRoomId = (fieldName: string) =>
|
|||||||
message: `${fieldName} cannot be empty after sanitization`
|
message: `${fieldName} cannot be empty after sanitization`
|
||||||
});
|
});
|
||||||
|
|
||||||
const validForceQueryParam = () =>
|
|
||||||
z
|
|
||||||
.preprocess((val) => {
|
|
||||||
if (typeof val === 'string') {
|
|
||||||
return val.toLowerCase() === 'true';
|
|
||||||
}
|
|
||||||
|
|
||||||
return val;
|
|
||||||
}, z.boolean())
|
|
||||||
.default(false);
|
|
||||||
|
|
||||||
const RecordingAccessSchema: z.ZodType<MeetRecordingAccess> = z.enum([
|
const RecordingAccessSchema: z.ZodType<MeetRecordingAccess> = z.enum([
|
||||||
MeetRecordingAccess.ADMIN,
|
MeetRecordingAccess.ADMIN,
|
||||||
MeetRecordingAccess.ADMIN_MODERATOR,
|
MeetRecordingAccess.ADMIN_MODERATOR,
|
||||||
@ -102,6 +94,23 @@ const RoomPreferencesSchema: z.ZodType<MeetRoomPreferences> = z.object({
|
|||||||
virtualBackgroundPreferences: VirtualBackgroundPreferencesSchema
|
virtualBackgroundPreferences: VirtualBackgroundPreferencesSchema
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const RoomDeletionPolicyWithMeetingSchema: z.ZodType<MeetRoomDeletionPolicyWithMeeting> = z.enum([
|
||||||
|
MeetRoomDeletionPolicyWithMeeting.FORCE,
|
||||||
|
MeetRoomDeletionPolicyWithMeeting.WHEN_MEETING_ENDS,
|
||||||
|
MeetRoomDeletionPolicyWithMeeting.FAIL
|
||||||
|
]);
|
||||||
|
|
||||||
|
const RoomDeletionPolicyWithRecordingsSchema: z.ZodType<MeetRoomDeletionPolicyWithRecordings> = z.enum([
|
||||||
|
MeetRoomDeletionPolicyWithRecordings.FORCE,
|
||||||
|
MeetRoomDeletionPolicyWithRecordings.CLOSE,
|
||||||
|
MeetRoomDeletionPolicyWithRecordings.FAIL
|
||||||
|
]);
|
||||||
|
|
||||||
|
const RoomAutoDeletionPolicySchema: z.ZodType<MeetRoomAutoDeletionPolicy> = z.object({
|
||||||
|
withMeeting: RoomDeletionPolicyWithMeetingSchema,
|
||||||
|
withRecordings: RoomDeletionPolicyWithRecordingsSchema
|
||||||
|
});
|
||||||
|
|
||||||
const RoomRequestOptionsSchema: z.ZodType<MeetRoomOptions> = z.object({
|
const RoomRequestOptionsSchema: z.ZodType<MeetRoomOptions> = z.object({
|
||||||
roomName: z
|
roomName: z
|
||||||
.string()
|
.string()
|
||||||
@ -117,6 +126,10 @@ const RoomRequestOptionsSchema: z.ZodType<MeetRoomOptions> = z.object({
|
|||||||
`autoDeletionDate must be at least ${INTERNAL_CONFIG.MIN_FUTURE_TIME_FOR_ROOM_AUTODELETION_DATE} in the future`
|
`autoDeletionDate must be at least ${INTERNAL_CONFIG.MIN_FUTURE_TIME_FOR_ROOM_AUTODELETION_DATE} in the future`
|
||||||
)
|
)
|
||||||
.optional(),
|
.optional(),
|
||||||
|
autoDeletionPolicy: RoomAutoDeletionPolicySchema.optional().default({
|
||||||
|
withMeeting: MeetRoomDeletionPolicyWithMeeting.WHEN_MEETING_ENDS,
|
||||||
|
withRecordings: MeetRoomDeletionPolicyWithRecordings.CLOSE
|
||||||
|
}),
|
||||||
preferences: RoomPreferencesSchema.optional().default({
|
preferences: RoomPreferencesSchema.optional().default({
|
||||||
recordingPreferences: { enabled: true, allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER },
|
recordingPreferences: { enabled: true, allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER },
|
||||||
chatPreferences: { enabled: true },
|
chatPreferences: { enabled: true },
|
||||||
@ -146,6 +159,11 @@ const GetRoomFiltersSchema: z.ZodType<MeetRoomFilters> = z.object({
|
|||||||
fields: z.string().optional()
|
fields: z.string().optional()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const DeleteRoomQueryParamsSchema = z.object({
|
||||||
|
withMeeting: RoomDeletionPolicyWithMeetingSchema.optional().default(MeetRoomDeletionPolicyWithMeeting.FAIL),
|
||||||
|
withRecordings: RoomDeletionPolicyWithRecordingsSchema.optional().default(MeetRoomDeletionPolicyWithRecordings.FAIL)
|
||||||
|
});
|
||||||
|
|
||||||
const BulkDeleteRoomsSchema = z.object({
|
const BulkDeleteRoomsSchema = z.object({
|
||||||
roomIds: z.preprocess(
|
roomIds: z.preprocess(
|
||||||
(arg) => {
|
(arg) => {
|
||||||
@ -181,7 +199,8 @@ const BulkDeleteRoomsSchema = z.object({
|
|||||||
message: 'At least one valid roomId is required after sanitization'
|
message: 'At least one valid roomId is required after sanitization'
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
force: validForceQueryParam()
|
withMeeting: RoomDeletionPolicyWithMeetingSchema.optional().default(MeetRoomDeletionPolicyWithMeeting.FAIL),
|
||||||
|
withRecordings: RoomDeletionPolicyWithRecordingsSchema.optional().default(MeetRoomDeletionPolicyWithRecordings.FAIL)
|
||||||
});
|
});
|
||||||
|
|
||||||
const UpdateRoomPreferencesSchema = z.object({
|
const UpdateRoomPreferencesSchema = z.object({
|
||||||
@ -250,18 +269,6 @@ export const withValidRoomId = (req: Request, res: Response, next: NextFunction)
|
|||||||
next();
|
next();
|
||||||
};
|
};
|
||||||
|
|
||||||
export const withValidRoomBulkDeleteRequest = (req: Request, res: Response, next: NextFunction) => {
|
|
||||||
const { success, error, data } = BulkDeleteRoomsSchema.safeParse(req.query);
|
|
||||||
|
|
||||||
if (!success) {
|
|
||||||
return rejectUnprocessableRequest(res, error);
|
|
||||||
}
|
|
||||||
|
|
||||||
req.query.roomIds = data.roomIds as any;
|
|
||||||
req.query.force = data.force ? 'true' : 'false';
|
|
||||||
next();
|
|
||||||
};
|
|
||||||
|
|
||||||
export const withValidRoomDeleteRequest = (req: Request, res: Response, next: NextFunction) => {
|
export const withValidRoomDeleteRequest = (req: Request, res: Response, next: NextFunction) => {
|
||||||
const roomIdResult = nonEmptySanitizedRoomId('roomId').safeParse(req.params.roomId);
|
const roomIdResult = nonEmptySanitizedRoomId('roomId').safeParse(req.params.roomId);
|
||||||
|
|
||||||
@ -271,13 +278,24 @@ export const withValidRoomDeleteRequest = (req: Request, res: Response, next: Ne
|
|||||||
|
|
||||||
req.params.roomId = roomIdResult.data;
|
req.params.roomId = roomIdResult.data;
|
||||||
|
|
||||||
const forceResult = validForceQueryParam().safeParse(req.query.force);
|
const queryParamsResult = DeleteRoomQueryParamsSchema.safeParse(req.query);
|
||||||
|
|
||||||
if (!forceResult.success) {
|
if (!queryParamsResult.success) {
|
||||||
return rejectUnprocessableRequest(res, forceResult.error);
|
return rejectUnprocessableRequest(res, queryParamsResult.error);
|
||||||
}
|
}
|
||||||
|
|
||||||
req.query.force = forceResult.data ? 'true' : 'false';
|
req.query = queryParamsResult.data;
|
||||||
|
next();
|
||||||
|
};
|
||||||
|
|
||||||
|
export const withValidRoomBulkDeleteRequest = (req: Request, res: Response, next: NextFunction) => {
|
||||||
|
const { success, error, data } = BulkDeleteRoomsSchema.safeParse(req.query);
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
return rejectUnprocessableRequest(res, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
req.query = data;
|
||||||
next();
|
next();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,11 @@
|
|||||||
import {
|
import {
|
||||||
|
MeetingEndAction,
|
||||||
MeetRecordingAccess,
|
MeetRecordingAccess,
|
||||||
MeetRoom,
|
MeetRoom,
|
||||||
MeetRoomFilters,
|
MeetRoomFilters,
|
||||||
MeetRoomOptions,
|
MeetRoomOptions,
|
||||||
MeetRoomPreferences,
|
MeetRoomPreferences,
|
||||||
|
MeetRoomStatus,
|
||||||
ParticipantRole,
|
ParticipantRole,
|
||||||
RecordingPermissions
|
RecordingPermissions
|
||||||
} from '@typings-ce';
|
} from '@typings-ce';
|
||||||
@ -15,6 +17,7 @@ import { uid } from 'uid/single';
|
|||||||
import INTERNAL_CONFIG from '../config/internal-config.js';
|
import INTERNAL_CONFIG from '../config/internal-config.js';
|
||||||
import { MEET_NAME_ID } from '../environment.js';
|
import { MEET_NAME_ID } from '../environment.js';
|
||||||
import { MeetRoomHelper, UtilsHelper } from '../helpers/index.js';
|
import { MeetRoomHelper, UtilsHelper } from '../helpers/index.js';
|
||||||
|
import { validateRecordingTokenMetadata } from '../middlewares/index.js';
|
||||||
import {
|
import {
|
||||||
errorInvalidRoomSecret,
|
errorInvalidRoomSecret,
|
||||||
errorRoomMetadataNotFound,
|
errorRoomMetadataNotFound,
|
||||||
@ -23,15 +26,14 @@ import {
|
|||||||
} from '../models/error.model.js';
|
} from '../models/error.model.js';
|
||||||
import {
|
import {
|
||||||
DistributedEventService,
|
DistributedEventService,
|
||||||
|
FrontendEventService,
|
||||||
IScheduledTask,
|
IScheduledTask,
|
||||||
LiveKitService,
|
LiveKitService,
|
||||||
LoggerService,
|
LoggerService,
|
||||||
MeetStorageService,
|
MeetStorageService,
|
||||||
TaskSchedulerService,
|
TaskSchedulerService,
|
||||||
TokenService,
|
TokenService
|
||||||
FrontendEventService
|
|
||||||
} from './index.js';
|
} from './index.js';
|
||||||
import { validateRecordingTokenMetadata } from '../middlewares/index.js';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service for managing OpenVidu Meet rooms.
|
* Service for managing OpenVidu Meet rooms.
|
||||||
@ -70,7 +72,7 @@ export class RoomService {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
async createMeetRoom(baseUrl: string, roomOptions: MeetRoomOptions): Promise<MeetRoom> {
|
async createMeetRoom(baseUrl: string, roomOptions: MeetRoomOptions): Promise<MeetRoom> {
|
||||||
const { roomName, autoDeletionDate, preferences } = roomOptions;
|
const { roomName, autoDeletionDate, autoDeletionPolicy, preferences } = roomOptions;
|
||||||
const roomIdPrefix = roomName!.replace(/\s+/g, ''); // Remove all spaces
|
const roomIdPrefix = roomName!.replace(/\s+/g, ''); // Remove all spaces
|
||||||
const roomId = `${roomIdPrefix}-${uid(15)}`; // Generate a unique room ID based on the room name
|
const roomId = `${roomIdPrefix}-${uid(15)}`; // Generate a unique room ID based on the room name
|
||||||
|
|
||||||
@ -80,13 +82,15 @@ export class RoomService {
|
|||||||
creationDate: Date.now(),
|
creationDate: Date.now(),
|
||||||
// maxParticipants,
|
// maxParticipants,
|
||||||
autoDeletionDate,
|
autoDeletionDate,
|
||||||
preferences,
|
autoDeletionPolicy,
|
||||||
|
preferences: preferences!,
|
||||||
moderatorUrl: `${baseUrl}/room/${roomId}?secret=${secureUid(10)}`,
|
moderatorUrl: `${baseUrl}/room/${roomId}?secret=${secureUid(10)}`,
|
||||||
speakerUrl: `${baseUrl}/room/${roomId}?secret=${secureUid(10)}`
|
speakerUrl: `${baseUrl}/room/${roomId}?secret=${secureUid(10)}`,
|
||||||
|
status: MeetRoomStatus.OPEN,
|
||||||
|
meetingEndAction: MeetingEndAction.NONE
|
||||||
};
|
};
|
||||||
|
|
||||||
await this.storageService.saveMeetRoom(meetRoom);
|
await this.storageService.saveMeetRoom(meetRoom);
|
||||||
|
|
||||||
return meetRoom;
|
return meetRoom;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user