diff --git a/assets/openapi.json b/assets/openapi.json index f7bc123..a06d0d7 100644 --- a/assets/openapi.json +++ b/assets/openapi.json @@ -4082,7 +4082,6 @@ "type": "object", "properties": { "name": { - "maxLength": 100, "type": "string" }, "type": { @@ -6831,7 +6830,6 @@ "type": "object", "properties": { "name": { - "maxLength": 100, "type": "string" }, "type": { @@ -13373,9 +13371,14 @@ "maxWebhooks": { "type": "integer", "default": 100 + }, + "maxName": { + "type": "integer", + "default": 32 } }, "required": [ + "maxName", "maxPins", "maxTopic", "maxWebhooks" diff --git a/assets/schemas.json b/assets/schemas.json index 3d4b744..f10afc4 100644 --- a/assets/schemas.json +++ b/assets/schemas.json @@ -4325,7 +4325,6 @@ "type": "object", "properties": { "name": { - "maxLength": 100, "type": "string" }, "type": { @@ -7277,7 +7276,6 @@ "type": "object", "properties": { "name": { - "maxLength": 100, "type": "string" }, "type": { @@ -14193,10 +14191,15 @@ "maxWebhooks": { "type": "integer", "default": 100 + }, + "maxName": { + "type": "integer", + "default": 32 } }, "additionalProperties": false, "required": [ + "maxName", "maxPins", "maxTopic", "maxWebhooks" diff --git "a/src/api/routes/channels/\043channel_id/index.ts" "b/src/api/routes/channels/\043channel_id/index.ts" index a1db913..3776757 100644 --- "a/src/api/routes/channels/\043channel_id/index.ts" +++ "b/src/api/routes/channels/\043channel_id/index.ts" @@ -17,7 +17,19 @@ */ import { route } from "@spacebar/api"; -import { Channel, ChannelDeleteEvent, ChannelUpdateEvent, Recipient, emitEvent, handleFile } from "@spacebar/util"; +import { + Channel, + ChannelDeleteEvent, + ChannelUpdateEvent, + Recipient, + emitEvent, + handleFile, + Config, + FieldError, + ErrorList, + ObjectErrorContent, + makeObjectErrorContent, +} from "@spacebar/util"; import { Request, Response, Router } from "express"; import { ChannelModifySchema, ChannelType } from "@spacebar/schemas"; @@ -174,6 +186,7 @@ channel.available_tags = channel.available_tags.filter((_) => filter.has(_.id)); } } + if (payload.applied_tags) { if (channel.isThread()) { const parent = await Channel.findOneOrFail({ @@ -201,6 +214,19 @@ if (payload.icon) payload.icon = await handleFile(`/channel-icons/${channel_id}`, payload.icon); + const channelLimits = Config.get().limits.channel; + + const errors: ErrorList = {}; + if (payload.name && (payload.name.length < 1 || payload.name.length > channelLimits.maxName)) + errors["name"] = makeObjectErrorContent("BASE_TYPE_BAD_LENGTH", `Channel name must be between 1 and ${channelLimits.maxName} characters`); + if (payload.topic !== undefined && payload.topic.length > channelLimits.maxTopic) + errors["topic"] = makeObjectErrorContent("BASE_TYPE_BAD_LENGTH", `Channel topic must be less than ${channelLimits.maxTopic} characters`); + if (payload.user_limit !== undefined && payload.user_limit < 0) errors["user_limit"] = makeObjectErrorContent("BASE_TYPE_BAD_VALUE", "User limit must be 0 or higher"); + + if (Object.keys(errors).length) { + throw new FieldError(400, "Invalid form body", errors); + } + channel.assign(payload); if (channel.thread_metadata) { if (payload.archived !== undefined) { diff --git a/src/schemas/uncategorised/ChannelModifySchema.ts b/src/schemas/uncategorised/ChannelModifySchema.ts index b83dc12..093da8e 100644 --- a/src/schemas/uncategorised/ChannelModifySchema.ts +++ b/src/schemas/uncategorised/ChannelModifySchema.ts @@ -19,9 +19,6 @@ import { ChannelPermissionOverwriteType, ChannelType, TagCreateSchema } from "@spacebar/schemas"; export interface ChannelModifySchema { - /** - * @maxLength 100 - */ name?: string; type?: ChannelType; topic?: string; diff --git a/src/util/config/types/subconfigurations/limits/ChannelLimits.ts b/src/util/config/types/subconfigurations/limits/ChannelLimits.ts index 266e6a3..6d5d28f 100644 --- a/src/util/config/types/subconfigurations/limits/ChannelLimits.ts +++ b/src/util/config/types/subconfigurations/limits/ChannelLimits.ts @@ -20,4 +20,5 @@ maxPins: number = 500; maxTopic: number = 1024; maxWebhooks: number = 100; + maxName: number = 32; } diff --git a/src/util/util/FieldError.ts b/src/util/util/FieldError.ts index eb91a0e..f0ba4ae 100644 --- a/src/util/util/FieldError.ts +++ b/src/util/util/FieldError.ts @@ -28,6 +28,10 @@ export type ErrorContent = { code: string; message: string }; export type ObjectErrorContent = { _errors: ErrorContent[] }; +export function makeObjectErrorContent(code: string, message: string): ObjectErrorContent { + return { _errors: [{ code, message }] }; +} + export function FieldErrors(fields: Record, errors?: ErrorObject[]) { const errorObj: ErrorList = {}; for (const [key, { message, code }] of Object.entries(fields)) {