backend: enhance appearance configuration handling and validation in global settings
This commit is contained in:
parent
8f6af28bc2
commit
3d8a82a18d
@ -1,11 +1,7 @@
|
||||
import { MeetAppearanceConfig } from '@typings-ce';
|
||||
import { Request, Response } from 'express';
|
||||
import { container } from '../../config/index.js';
|
||||
import {
|
||||
errorRoomsAppearanceConfigNotDefined,
|
||||
handleError,
|
||||
rejectRequestFromMeetError
|
||||
} from '../../models/error.model.js';
|
||||
import { handleError } from '../../models/error.model.js';
|
||||
import { LoggerService, MeetStorageService } from '../../services/index.js';
|
||||
|
||||
export const updateRoomsAppearanceConfig = async (req: Request, res: Response) => {
|
||||
@ -17,6 +13,18 @@ export const updateRoomsAppearanceConfig = async (req: Request, res: Response) =
|
||||
|
||||
try {
|
||||
const globalConfig = await storageService.getGlobalConfig();
|
||||
|
||||
if (globalConfig.roomsConfig.appearance.themes.length > 0) {
|
||||
// Preserve existing theme colors if they are not provided in the update
|
||||
const existingTheme = globalConfig.roomsConfig.appearance.themes[0];
|
||||
const newTheme = appearanceConfig.appearance.themes[0];
|
||||
|
||||
newTheme.backgroundColor = newTheme.backgroundColor || existingTheme.backgroundColor;
|
||||
newTheme.primaryColor = newTheme.primaryColor || existingTheme.primaryColor;
|
||||
newTheme.secondaryColor = newTheme.secondaryColor || existingTheme.secondaryColor;
|
||||
newTheme.surfaceColor = newTheme.surfaceColor || existingTheme.surfaceColor;
|
||||
}
|
||||
|
||||
globalConfig.roomsConfig = appearanceConfig;
|
||||
await storageService.saveGlobalConfig(globalConfig);
|
||||
|
||||
@ -34,13 +42,7 @@ export const getRoomsAppearanceConfig = async (_req: Request, res: Response) =>
|
||||
|
||||
try {
|
||||
const globalConfig = await storageService.getGlobalConfig();
|
||||
const appearanceConfig = globalConfig.roomsConfig?.appearance;
|
||||
|
||||
if (!appearanceConfig) {
|
||||
const error = errorRoomsAppearanceConfigNotDefined();
|
||||
return rejectRequestFromMeetError(res, error);
|
||||
}
|
||||
|
||||
const appearanceConfig = globalConfig.roomsConfig.appearance;
|
||||
return res.status(200).json({ appearance: appearanceConfig });
|
||||
} catch (error) {
|
||||
handleError(res, error, 'getting rooms appearance config');
|
||||
|
||||
@ -95,8 +95,12 @@ const ThemeModeSchema: z.ZodType<MeetRoomThemeMode> = z.enum([MeetRoomThemeMode.
|
||||
const hexColorSchema = z.string().regex(/^#([0-9A-Fa-f]{6}|[0-9A-Fa-f]{3})$/, 'Must be a valid hex color code');
|
||||
|
||||
const RoomThemeSchema = z.object({
|
||||
name: z
|
||||
.string()
|
||||
.min(1, 'Theme name cannot be empty')
|
||||
.max(50, 'Theme name cannot exceed 50 characters')
|
||||
.regex(/^[a-z0-9_-]+$/, 'Theme name can only contain lowercase letters, numbers, hyphens and underscores'),
|
||||
enabled: z.boolean(),
|
||||
name: z.string().min(1, 'Theme name cannot be empty').max(50, 'Theme name cannot exceed 50 characters'),
|
||||
baseTheme: ThemeModeSchema,
|
||||
backgroundColor: hexColorSchema.optional(),
|
||||
primaryColor: hexColorSchema.optional(),
|
||||
|
||||
@ -247,12 +247,6 @@ export const errorParticipantIdentityNotProvided = (): OpenViduMeetError => {
|
||||
return new OpenViduMeetError('Participant Error', 'No participant identity provided', 400);
|
||||
};
|
||||
|
||||
// Global config errors
|
||||
|
||||
export const errorRoomsAppearanceConfigNotDefined = (): OpenViduMeetError => {
|
||||
return new OpenViduMeetError('Global Config Error', 'Rooms appearance config not defined', 404);
|
||||
};
|
||||
|
||||
// Webhook errors
|
||||
|
||||
export const errorInvalidWebhookUrl = (url: string, reason: string): OpenViduMeetError => {
|
||||
|
||||
@ -11,7 +11,7 @@ export class GCSStorageProvider implements StorageProvider {
|
||||
constructor(
|
||||
@inject(LoggerService) protected logger: LoggerService,
|
||||
@inject(GCSService) protected gcsService: GCSService
|
||||
) { }
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Retrieves an object from GCS Storage as a JSON object.
|
||||
|
||||
@ -163,6 +163,7 @@ export class GCSService {
|
||||
};
|
||||
|
||||
const [nextFiles] = await bucketObj.getFiles(nextOptions);
|
||||
|
||||
if (nextFiles.length === 0) {
|
||||
NextContinuationToken = undefined;
|
||||
isTruncated = false;
|
||||
|
||||
@ -711,10 +711,10 @@ export class MeetStorageService<
|
||||
* @returns {GConfig}
|
||||
*/
|
||||
protected getDefaultConfig(): GConfig {
|
||||
return {
|
||||
const defaultConfig: GlobalConfig = {
|
||||
projectId: MEET_NAME_ID,
|
||||
webhooksConfig: {
|
||||
enabled: MEET_INITIAL_WEBHOOK_ENABLED === 'true' && MEET_INITIAL_API_KEY,
|
||||
enabled: MEET_INITIAL_WEBHOOK_ENABLED === 'true' && !!MEET_INITIAL_API_KEY,
|
||||
url: MEET_INITIAL_WEBHOOK_URL
|
||||
},
|
||||
securityConfig: {
|
||||
@ -724,8 +724,14 @@ export class MeetStorageService<
|
||||
},
|
||||
authModeToAccessRoom: AuthMode.NONE
|
||||
}
|
||||
},
|
||||
roomsConfig: {
|
||||
appearance: {
|
||||
themes: []
|
||||
}
|
||||
} as GConfig;
|
||||
}
|
||||
};
|
||||
return defaultConfig as GConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -8,7 +8,7 @@ export interface GlobalConfig {
|
||||
projectId: string;
|
||||
securityConfig: SecurityConfig;
|
||||
webhooksConfig: WebhookConfig;
|
||||
roomsConfig?: {
|
||||
roomsConfig: {
|
||||
appearance: MeetAppearanceConfig;
|
||||
};
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@ export interface MeetRoomConfig {
|
||||
chat: MeetChatConfig;
|
||||
recording: MeetRecordingConfig;
|
||||
virtualBackground: MeetVirtualBackgroundConfig;
|
||||
// appearance?: MeetAppearanceConfig;
|
||||
// appearance: MeetAppearanceConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -19,7 +19,7 @@ export interface MeetRecordingConfig {
|
||||
export const enum MeetRecordingAccess {
|
||||
ADMIN = 'admin', // Only admins can access the recording
|
||||
ADMIN_MODERATOR = 'admin_moderator', // Admins and moderators can access
|
||||
ADMIN_MODERATOR_SPEAKER = 'admin_moderator_speaker', // Admins, moderators and speakers can access
|
||||
ADMIN_MODERATOR_SPEAKER = 'admin_moderator_speaker' // Admins, moderators and speakers can access
|
||||
}
|
||||
|
||||
export interface MeetChatConfig {
|
||||
@ -35,8 +35,8 @@ export interface MeetAppearanceConfig {
|
||||
}
|
||||
|
||||
export interface MeetRoomTheme {
|
||||
enabled: boolean;
|
||||
name: string;
|
||||
enabled: boolean;
|
||||
baseTheme: MeetRoomThemeMode;
|
||||
backgroundColor?: string;
|
||||
primaryColor?: string;
|
||||
@ -46,5 +46,5 @@ export interface MeetRoomTheme {
|
||||
|
||||
export const enum MeetRoomThemeMode {
|
||||
LIGHT = 'light',
|
||||
DARK = 'dark',
|
||||
DARK = 'dark'
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user