feat: zod validation message

This commit is contained in:
abdou6666
2025-02-04 11:05:22 +01:00
parent 42c7d110a2
commit af536a9f48
8 changed files with 356 additions and 226 deletions

View File

@@ -12,103 +12,43 @@ import {
ValidatorConstraint,
ValidatorConstraintInterface,
} from 'class-validator';
import Joi from 'joi';
import { BlockMessage } from '../schemas/types/message';
import {
BlockMessage,
messageRegexSchema,
objectSchema,
textSchema,
} from '../schemas/types/message';
/* eslint-disable no-console */
export function isValidMessage(msg: any) {
if (typeof msg === 'string' && msg !== '') {
// Custom code
const MESSAGE_REGEX = /^function \(context\) \{[^]+\}/;
if (!MESSAGE_REGEX.test(msg)) {
// eslint-disable-next-line
console.error('Block Model : Invalid custom code.', msg);
const result = messageRegexSchema.safeParse(msg);
if (!result.success) {
console.error('Block Model: Invalid custom code.', result.error);
return false;
} else {
return true;
}
return true;
} else if (Array.isArray(msg)) {
// Simple text message
const textSchema = Joi.array().items(Joi.string().max(1000).required());
const textCheck = textSchema.validate(msg);
return !textCheck.error;
} else if (typeof msg === 'object') {
const result = textSchema.safeParse(msg);
if (!result.success) {
console.error('Block Model: Invalid text message array.', result.error);
}
return result.success;
} else if (typeof msg === 'object' && msg !== null) {
if ('plugin' in msg) {
return true;
} else {
const buttonsSchema = Joi.array().items(
Joi.object().keys({
type: Joi.string().valid('postback', 'web_url').required(),
title: Joi.string().max(20),
payload: Joi.alternatives().conditional('type', {
is: 'postback',
then: Joi.string().max(1000).required(),
otherwise: Joi.forbidden(),
}),
url: Joi.alternatives().conditional('type', {
is: 'web_url',
then: Joi.string().uri(),
otherwise: Joi.forbidden(),
}),
messenger_extensions: Joi.alternatives().conditional('type', {
is: 'web_url',
then: Joi.boolean(),
otherwise: Joi.forbidden(),
}),
webview_height_ratio: Joi.alternatives().conditional('type', {
is: 'web_url',
then: Joi.string().valid('compact', 'tall', 'full'),
otherwise: Joi.forbidden(),
}),
}),
);
// Attachment message
const objectSchema = Joi.object().keys({
text: Joi.string().max(1000),
attachment: Joi.object().keys({
type: Joi.string()
.valid('image', 'audio', 'video', 'file', 'unknown')
.required(),
payload: Joi.object().keys({
url: Joi.string().uri(),
id: Joi.string().allow(null),
}),
}),
elements: Joi.boolean(),
cards: Joi.object().keys({
default_action: buttonsSchema.max(1),
buttons: buttonsSchema.max(3),
}),
buttons: buttonsSchema.max(3),
quickReplies: Joi.array()
.items(
Joi.object().keys({
content_type: Joi.string()
.valid('text', 'location', 'user_phone_number', 'user_email')
.required(),
title: Joi.alternatives().conditional('content_type', {
is: 'text',
then: Joi.string().max(20).required(),
}),
payload: Joi.alternatives().conditional('content_type', {
is: 'text',
then: Joi.string().max(1000).required(),
}),
}),
)
.max(11),
});
const objectCheck = objectSchema.validate(msg);
if (objectCheck.error) {
// eslint-disable-next-line
console.log('Message validation failed! ', objectCheck);
}
return !objectCheck.error;
}
} else {
return false;
const result = objectSchema.safeParse(msg);
if (!result.success) {
console.error('Block Model: Object validation failed!', result.error);
}
return result.success;
}
console.log('Validation reached default false');
return false;
}
/* eslint-enable no-console */
@ValidatorConstraint({ async: false })
export class MessageValidator implements ValidatorConstraintInterface {

View File

@@ -1,5 +1,5 @@
/*
* Copyright © 2024 Hexastack. All rights reserved.
* Copyright © 2025 Hexastack. All rights reserved.
*
* Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms:
* 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission.
@@ -11,6 +11,7 @@ import { registerDecorator, ValidationOptions } from 'class-validator';
import {
StdIncomingMessage,
StdOutgoingTextMessage,
validMessageTextSchema,
} from '../schemas/types/message';
export function IsValidMessageText(validationOptions?: ValidationOptions) {
@@ -21,7 +22,7 @@ export function IsValidMessageText(validationOptions?: ValidationOptions) {
options: validationOptions,
validator: {
validate(message: StdOutgoingTextMessage | StdIncomingMessage) {
return !!(message as StdOutgoingTextMessage).text;
return validMessageTextSchema.safeParse(message).success;
},
},
});