diff --git a/assets/openapi.json b/assets/openapi.json
index f7bc123a..a06d0d78 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 3d4b7447..f10afc4a 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/#channel_id/index.ts b/src/api/routes/channels/#channel_id/index.ts
index a1db9137..37767574 100644
--- a/src/api/routes/channels/#channel_id/index.ts
+++ b/src/api/routes/channels/#channel_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 @@ router.patch(
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 @@ router.patch(
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 b83dc12e..093da8e6 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 266e6a32..6d5d28f8 100644
--- a/src/util/config/types/subconfigurations/limits/ChannelLimits.ts
+++ b/src/util/config/types/subconfigurations/limits/ChannelLimits.ts
@@ -20,4 +20,5 @@ export class ChannelLimits {
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 eb91a0ec..f0ba4aee 100644
--- a/src/util/util/FieldError.ts
+++ b/src/util/util/FieldError.ts
@@ -28,6 +28,10 @@ export type ErrorList = Record<string, ObjectErrorContent>;
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<string, { code?: string; message: string }>, errors?: ErrorObject[]) {
const errorObj: ErrorList = {};
for (const [key, { message, code }] of Object.entries(fields)) {
|