mirror of
https://github.com/omnivore-app/omnivore.git
synced 2026-03-11 08:54:26 +00:00
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:
commit
eab3428c4c
5 changed files with 35 additions and 13 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>;
|
||||
|
|
|
|||
|
|
@ -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!]!
|
||||
|
|
|
|||
|
|
@ -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 || [] })
|
||||
},
|
||||
})
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue