Skip to content

Commit

Permalink
feat: adjust validation logic for tag value (#11)
Browse files Browse the repository at this point in the history
  • Loading branch information
CodyTseng authored Jan 31, 2024
1 parent d3c7f42 commit 764af94
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 50 deletions.
47 changes: 40 additions & 7 deletions packages/validator/__test__/validator.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ describe('Validator', () => {
).toEqual(eventMessage);
});

it('should throw error if event message is invalid', () => {
it('should throw error if event message is invalid', async () => {
const event = {
id: '0',
pubkey:
Expand All @@ -48,16 +48,16 @@ describe('Validator', () => {
};
const eventMessage = [MessageType.EVENT, event];

expect(validator.validateIncomingMessage(eventMessage)).rejects.toThrow(
'invalid:',
);
await expect(
validator.validateIncomingMessage(eventMessage),
).rejects.toThrow('invalid:');

jest
.spyOn(validator['incomingMessageSchema'], 'parseAsync')
.mockRejectedValue(new Error('test'));
expect(validator.validateIncomingMessage(eventMessage)).rejects.toThrow(
'test',
);
await expect(
validator.validateIncomingMessage(eventMessage),
).rejects.toThrow('test');
});

it('should validate req message', async () => {
Expand Down Expand Up @@ -180,5 +180,38 @@ describe('Validator', () => {

expect(await validator.validateEvent(event)).toEqual(event);
});

it('should validate tag value correctly', async () => {
const specValidator = new Validator({ maxTagValueLength: 1 });
const event1 = {
id: '0000000000000000000000000000000000000000000000000000000000000000',
pubkey:
'0000000000000000000000000000000000000000000000000000000000000000',
kind: 1,
content: 'hello nostr',
tags: [
['hello', 'world'],
['a', 'b', 'ccc'],
],
created_at: 0,
sig: '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
};
expect(await specValidator.validateEvent(event1)).toEqual(event1);

const event2 = {
id: '0000000000000000000000000000000000000000000000000000000000000000',
pubkey:
'0000000000000000000000000000000000000000000000000000000000000000',
kind: 1,
content: 'hello nostr',
tags: [
['hello', 'world'],
['a', 'bb'],
],
created_at: 0,
sig: '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
};
await expect(specValidator.validateEvent(event2)).rejects.toThrow();
});
});
});
5 changes: 1 addition & 4 deletions packages/validator/src/schemas/auth-message.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@ import { RequiredValidatorOptions } from '../types';
export function createAuthMessageSchema(
options: Pick<
RequiredValidatorOptions,
| 'maxItemsPerTag'
| 'maxLengthPerTagItem'
| 'maxNumberOfTags'
| 'maxContentLength'
'maxTagValueLength' | 'maxNumberOfTags' | 'maxContentLength'
>,
): z.ZodType<IncomingAuthMessage> {
return z.tuple([z.literal(MessageType.AUTH), createEventSchema(options)]);
Expand Down
28 changes: 11 additions & 17 deletions packages/validator/src/schemas/common.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,23 +28,17 @@ export const EventSigSchema = HexStringSchema.length(128, {
});

export function createEventTagSchema({
maxItemsPerTag,
maxLengthPerTagItem,
}: Pick<
RequiredValidatorOptions,
'maxItemsPerTag' | 'maxLengthPerTagItem'
>): z.ZodType<string[]> {
return z
.array(
z
.string({ invalid_type_error: 'must be a string' })
.max(maxLengthPerTagItem, {
message: `must be less than ${maxLengthPerTagItem} chars`,
}),
)
.max(maxItemsPerTag, {
message: `must be less than or equal to ${maxItemsPerTag} tag items`,
});
maxTagValueLength,
}: Pick<RequiredValidatorOptions, 'maxTagValueLength'>): z.ZodType<string[]> {
return z.array(z.string({ invalid_type_error: 'must be a string' })).refine(
tag => {
if (tag.length <= 1 || tag[0].length > 1) return true;
return tag[1].length <= maxTagValueLength;
},
{
message: `tag value must be less than ${maxTagValueLength} chars`,
},
);
}

export function createEventContentSchema({
Expand Down
10 changes: 2 additions & 8 deletions packages/validator/src/schemas/event-message.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,7 @@ import { RequiredValidatorOptions } from '../types';
export function createEventSchema(
options: Pick<
RequiredValidatorOptions,
| 'maxItemsPerTag'
| 'maxLengthPerTagItem'
| 'maxNumberOfTags'
| 'maxContentLength'
'maxTagValueLength' | 'maxNumberOfTags' | 'maxContentLength'
>,
): z.ZodType<Event> {
return z.object({
Expand All @@ -36,10 +33,7 @@ export function createEventSchema(
export function createEventMessageSchema(
options: Pick<
RequiredValidatorOptions,
| 'maxItemsPerTag'
| 'maxLengthPerTagItem'
| 'maxNumberOfTags'
| 'maxContentLength'
'maxTagValueLength' | 'maxNumberOfTags' | 'maxContentLength'
>,
): z.ZodType<IncomingEventMessage> {
return z.tuple([z.literal(MessageType.EVENT), createEventSchema(options)]);
Expand Down
12 changes: 6 additions & 6 deletions packages/validator/src/schemas/req-message.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,17 @@ import {

function createGenericTagFilterValuesSchema({
maxFilterGenericTagsLength,
maxLengthPerTagItem,
maxTagValueLength,
}: Pick<
RequiredValidatorOptions,
'maxFilterGenericTagsLength' | 'maxLengthPerTagItem'
'maxFilterGenericTagsLength' | 'maxTagValueLength'
>): z.ZodType<string[]> {
return z
.array(
z
.string({ invalid_type_error: 'must be a string' })
.max(maxLengthPerTagItem, {
message: `must be less than or equal to ${maxLengthPerTagItem} characters`,
.max(maxTagValueLength, {
message: `must be less than or equal to ${maxTagValueLength} characters`,
}),
)
.min(1, { message: 'must be greater than or equal to 1 tagValues' })
Expand All @@ -39,7 +39,7 @@ export function createFilterSchema(
| 'maxFilterAuthorsLength'
| 'maxFilterKindsLength'
| 'maxFilterGenericTagsLength'
| 'maxLengthPerTagItem'
| 'maxTagValueLength'
| 'maxFilterSearchStringLength'
>,
): z.ZodType<Filter> {
Expand Down Expand Up @@ -128,7 +128,7 @@ export function createReqMessageSchema(
| 'maxFilterAuthorsLength'
| 'maxFilterKindsLength'
| 'maxFilterGenericTagsLength'
| 'maxLengthPerTagItem'
| 'maxTagValueLength'
| 'maxFilterSearchStringLength'
>,
): z.ZodType<IncomingReqMessage> {
Expand Down
8 changes: 2 additions & 6 deletions packages/validator/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,9 @@ export type RawData = Buffer | ArrayBuffer | Buffer[] | string | object;
*/
export type ValidatorOptions = {
/**
* maximum number of items per tag. `Default: 10`
* maximum length of tag value. `Default: 1024`
*/
maxItemsPerTag?: number;
/**
* maximum length of each tag item. `Default: 1024`
*/
maxLengthPerTagItem?: number;
maxTagValueLength?: number;
/**
* maximum number of tags. `Default: 2000`
*/
Expand Down
3 changes: 1 addition & 2 deletions packages/validator/src/validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,7 @@ export class Validator {

private defaultOptions(options: ValidatorOptions): RequiredValidatorOptions {
return {
maxItemsPerTag: 10,
maxLengthPerTagItem: 1024,
maxTagValueLength: 1024,
maxNumberOfTags: 2000,
maxContentLength: 100 * 1024,
maxSubscriptionIdLength: 128,
Expand Down

0 comments on commit 764af94

Please sign in to comment.