diff --git a/packages/api/src/directives.ts b/packages/api/src/directives.ts index 435166539..292a546b8 100644 --- a/packages/api/src/directives.ts +++ b/packages/api/src/directives.ts @@ -15,6 +15,7 @@ export const sanitizeDirectiveTransformer = (schema: GraphQLSchema) => { } const maxLength = sanitizeDirective.maxLength as number | undefined + const minLength = sanitizeDirective.minLength as number | undefined const allowedTags = sanitizeDirective.allowedTags as string[] | undefined const pattern = sanitizeDirective.pattern as string | undefined @@ -27,6 +28,7 @@ export const sanitizeDirectiveTransformer = (schema: GraphQLSchema) => { fieldConfig.type.ofType, allowedTags, maxLength, + minLength, pattern ) ) @@ -35,6 +37,7 @@ export const sanitizeDirectiveTransformer = (schema: GraphQLSchema) => { fieldConfig.type, allowedTags, maxLength, + minLength, pattern ) } else { diff --git a/packages/api/src/generated/graphql.ts b/packages/api/src/generated/graphql.ts index d3bfcc675..3334b1968 100644 --- a/packages/api/src/generated/graphql.ts +++ b/packages/api/src/generated/graphql.ts @@ -4062,6 +4062,7 @@ export type ResolversParentTypes = { export type SanitizeDirectiveArgs = { allowedTags?: Maybe>>; maxLength?: Maybe; + minLength?: Maybe; pattern?: Maybe; }; diff --git a/packages/api/src/generated/schema.graphql b/packages/api/src/generated/schema.graphql index 96d6b560c..629d64e48 100644 --- a/packages/api/src/generated/schema.graphql +++ b/packages/api/src/generated/schema.graphql @@ -1,4 +1,4 @@ -directive @sanitize(allowedTags: [String], maxLength: Int, pattern: String) on INPUT_FIELD_DEFINITION +directive @sanitize(allowedTags: [String], maxLength: Int, minLength: Int, pattern: String) on INPUT_FIELD_DEFINITION type AddPopularReadError { errorCodes: [AddPopularReadErrorCode!]! diff --git a/packages/api/src/scalars.ts b/packages/api/src/scalars.ts index 22404534f..aa74cddb7 100644 --- a/packages/api/src/scalars.ts +++ b/packages/api/src/scalars.ts @@ -9,6 +9,7 @@ export class SanitizedString extends GraphQLScalarType { type: GraphQLScalarType, allowedTags?: string[], maxLength?: number, + minLength?: number, pattern?: string ) { super({ @@ -25,11 +26,7 @@ export class SanitizedString extends GraphQLScalarType { // invoked when a query is passed as a JSON object (for example, when Apollo Client makes a request parseValue(value) { - if (maxLength && maxLength < value.length) { - throw new Error( - `Specified value cannot be longer than ${maxLength} characters` - ) - } + checkLength(value) if (pattern && !new RegExp(pattern).test(value)) { throw new Error(`Specified value does not match pattern`) } @@ -39,17 +36,26 @@ export class SanitizedString extends GraphQLScalarType { // invoked when a query is passed as a string parseLiteral(ast) { const value = type.parseLiteral(ast, {}) - if (maxLength && maxLength < value.length) { - throw new Error( - `Specified value cannot be longer than ${maxLength} characters` - ) - } + checkLength(value) if (pattern && !new RegExp(pattern).test(value)) { throw new Error(`Specified value does not match pattern`) } return sanitize(value, { allowedTags: allowedTags || [] }) }, }) + + function checkLength(value: any) { + if (maxLength && maxLength < value.length) { + throw new Error( + `Specified value cannot be longer than ${maxLength} characters` + ) + } + if (minLength && minLength > value.length) { + throw new Error( + `Specified value cannot be shorter than ${minLength} characters` + ) + } + } } } diff --git a/packages/api/src/schema.ts b/packages/api/src/schema.ts index 1c43b4e22..c298c856a 100755 --- a/packages/api/src/schema.ts +++ b/packages/api/src/schema.ts @@ -8,6 +8,7 @@ const schema = gql` directive @sanitize( allowedTags: [String] maxLength: Int + minLength: Int pattern: String ) on INPUT_FIELD_DEFINITION @@ -688,7 +689,7 @@ const schema = gql` shortId: String! articleId: ID! patch: String! - quote: String! @sanitize(maxLength: 6000) + quote: String! @sanitize(maxLength: 6000, minLength: 1) prefix: String @sanitize suffix: String @sanitize annotation: String @sanitize(maxLength: 4000) @@ -720,7 +721,7 @@ const schema = gql` shortId: ID! articleId: ID! patch: String! - quote: String! @sanitize(maxLength: 6000) + quote: String! @sanitize(maxLength: 6000, minLength: 1) prefix: String @sanitize suffix: String @sanitize annotation: String @sanitize(maxLength: 8000) @@ -752,7 +753,7 @@ const schema = gql` highlightId: ID! annotation: String @sanitize(maxLength: 4000) sharedAt: Date - quote: String @sanitize(maxLength: 6000) + quote: String @sanitize(maxLength: 6000, minLength: 1) } type UpdateHighlightSuccess {