Merge pull request #411 from omnivore-app/feature/validate-label-color-input

validate color as rgb hex value in create label input
This commit is contained in:
Jackson Harper 2022-04-13 13:41:00 -07:00 committed by GitHub
commit eab3428c4c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 35 additions and 13 deletions

View file

@ -1,32 +1,41 @@
import { mapSchema, getDirective, MapperKind } from '@graphql-tools/utils'
import { getDirective, MapperKind, mapSchema } from '@graphql-tools/utils'
import { GraphQLNonNull, GraphQLScalarType, GraphQLSchema } from 'graphql'
import { SanitizedString } from './scalars'
export const sanitizeDirectiveTransformer = (schema: GraphQLSchema) => {
return mapSchema(schema, {
[MapperKind.FIELD]: (fieldConfig) => {
const sanitizeDirective = getDirective(schema, fieldConfig, 'sanitize')
if (!sanitizeDirective || sanitizeDirective.length < 1) {
const sanitizeDirective = getDirective(
schema,
fieldConfig,
'sanitize'
)?.[0]
if (!sanitizeDirective) {
return fieldConfig
}
const maxLength = sanitizeDirective[0].maxLength as number | undefined
const allowedTags = sanitizeDirective[0].allowedTags as
| string[]
| undefined
const maxLength = sanitizeDirective.maxLength as number | undefined
const allowedTags = sanitizeDirective.allowedTags as string[] | undefined
const pattern = sanitizeDirective.pattern as string | undefined
if (
fieldConfig.type instanceof GraphQLNonNull &&
fieldConfig.type.ofType instanceof GraphQLScalarType
) {
fieldConfig.type = new GraphQLNonNull(
new SanitizedString(fieldConfig.type.ofType, allowedTags, maxLength)
new SanitizedString(
fieldConfig.type.ofType,
allowedTags,
maxLength,
pattern
)
)
} else if (fieldConfig.type instanceof GraphQLScalarType) {
fieldConfig.type = new SanitizedString(
fieldConfig.type,
allowedTags,
maxLength
maxLength,
pattern
)
} else {
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions

View file

@ -2501,6 +2501,7 @@ export type ResolversParentTypes = {
export type SanitizeDirectiveArgs = {
allowedTags?: Maybe<Array<Maybe<Scalars['String']>>>;
maxLength?: Maybe<Scalars['Int']>;
pattern?: Maybe<Scalars['String']>;
};
export type SanitizeDirectiveResolver<Result, Parent, ContextType = ResolverContext, Args = SanitizeDirectiveArgs> = DirectiveResolverFn<Result, Parent, ContextType, Args>;

View file

@ -1,4 +1,4 @@
directive @sanitize(allowedTags: [String], maxLength: Int) on INPUT_FIELD_DEFINITION
directive @sanitize(allowedTags: [String], maxLength: Int, pattern: String) on INPUT_FIELD_DEFINITION
type ArchiveLinkError {
errorCodes: [ArchiveLinkErrorCode!]!

View file

@ -8,10 +8,15 @@ export class SanitizedString extends GraphQLScalarType {
constructor(
type: GraphQLScalarType,
allowedTags?: string[],
maxLength?: number
maxLength?: number,
pattern?: string
) {
super({
name: `SanitizedString_${allowedTags}_${maxLength}`,
// Names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/ as per graphql-js
name: `SanitizedString_${allowedTags}_${maxLength}_${pattern}`.replace(
/\W/g,
''
),
description: 'Source string that was sanitized',
serialize(value: string) {
@ -25,6 +30,9 @@ export class SanitizedString extends GraphQLScalarType {
`Specified value cannot be longer than ${maxLength} characters`
)
}
if (pattern && !new RegExp(pattern).test(value)) {
throw new Error(`Specified value does not match pattern`)
}
return sanitize(value, { allowedTags: allowedTags || [] })
},
@ -36,6 +44,9 @@ export class SanitizedString extends GraphQLScalarType {
`Specified value cannot be longer than ${maxLength} characters`
)
}
if (pattern && !new RegExp(pattern).test(value)) {
throw new Error(`Specified value does not match pattern`)
}
return sanitize(value, { allowedTags: allowedTags || [] })
},
})

View file

@ -8,6 +8,7 @@ const schema = gql`
directive @sanitize(
allowedTags: [String]
maxLength: Int
pattern: String
) on INPUT_FIELD_DEFINITION
enum SortOrder {
@ -1273,7 +1274,7 @@ const schema = gql`
input CreateLabelInput {
name: String! @sanitize(maxLength: 64)
color: String!
color: String! @sanitize(pattern: "^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$")
description: String @sanitize(maxLength: 100)
}