UNPKG

@shopify/shopify-api

Version:

Shopify API Library for Node - accelerate development with support for authentication, graphql proxy, webhooks

1 lines 10.1 kB
{"version":3,"file":"validate.mjs","sources":["../../../../../../lib/webhooks/validate.ts"],"sourcesContent":["import {logger} from '../logger';\nimport {validateHmacFromRequestFactory} from '../utils/hmac-validator';\nimport {HmacValidationType, ValidationErrorReason} from '../utils/types';\nimport {\n abstractConvertRequest,\n getHeader,\n Headers,\n NormalizedRequest,\n} from '../../runtime/http';\nimport {ConfigInterface} from '../base-types';\n\nimport {\n EventsWebhookFields,\n WEBHOOK_HEADER_NAMES,\n WebhooksWebhookFields,\n WebhookType,\n WebhookTypeValue,\n WebhookValidateParams,\n WebhookValidation,\n WebhookValidationErrorReason,\n WebhookValidationMissingHeaders,\n WebhookValidationValid,\n} from './types';\nimport {topicForStorage} from './registry';\n\nfunction detectWebhookType(headers: Headers): WebhookTypeValue {\n const eventsHmac = getHeader(\n headers,\n WEBHOOK_HEADER_NAMES[WebhookType.Events].hmac,\n );\n if (eventsHmac) {\n return WebhookType.Events;\n }\n\n const webhooksHmac = getHeader(\n headers,\n WEBHOOK_HEADER_NAMES[WebhookType.Webhooks].hmac,\n );\n if (webhooksHmac) {\n return WebhookType.Webhooks;\n }\n\n return WebhookType.Webhooks;\n}\n\nexport function validateFactory(config: ConfigInterface) {\n return async function validate({\n rawBody,\n ...adapterArgs\n }: WebhookValidateParams): Promise<WebhookValidation> {\n const request: NormalizedRequest =\n await abstractConvertRequest(adapterArgs);\n\n const webhookType = detectWebhookType(request.headers);\n\n const validHmacResult = await validateHmacFromRequestFactory(config)({\n type: HmacValidationType.Webhook,\n rawBody,\n webhookType,\n ...adapterArgs,\n });\n\n if (!validHmacResult.valid) {\n if (validHmacResult.reason === ValidationErrorReason.InvalidHmac) {\n const log = logger(config);\n await log.debug(\n \"Webhook HMAC validation failed. Please note that events manually triggered from a store's Notifications settings will fail this validation. To test this, please use the CLI or trigger the actual event in a development store.\",\n );\n }\n return validHmacResult;\n }\n\n return checkWebhookHeaders(request.headers, webhookType);\n };\n}\n\nfunction getRequiredHeader(\n headers: Headers,\n headerName: string,\n missingHeaders: string[],\n): string | undefined {\n const value = getHeader(headers, headerName);\n if (!value) {\n missingHeaders.push(headerName);\n }\n return value;\n}\n\nfunction checkWebhookHeaders(\n headers: Headers,\n webhookType: WebhookTypeValue,\n): WebhookValidationMissingHeaders | WebhookValidationValid {\n if (webhookType === WebhookType.Webhooks) {\n return checkWebhooksHeaders(headers);\n }\n return checkEventsHeaders(headers);\n}\n\nfunction checkWebhooksHeaders(\n headers: Headers,\n): WebhookValidationMissingHeaders | WebhookValidationValid {\n const headerNames = WEBHOOK_HEADER_NAMES[WebhookType.Webhooks];\n const missingHeaders: string[] = [];\n\n const hmac = getRequiredHeader(headers, headerNames.hmac, missingHeaders);\n const topic = getRequiredHeader(headers, headerNames.topic, missingHeaders);\n const domain = getRequiredHeader(headers, headerNames.domain, missingHeaders);\n const apiVersion = getRequiredHeader(\n headers,\n headerNames.apiVersion,\n missingHeaders,\n );\n const webhookId = getRequiredHeader(\n headers,\n headerNames.webhookId,\n missingHeaders,\n );\n\n if (missingHeaders.length) {\n return {\n valid: false,\n reason: WebhookValidationErrorReason.MissingHeaders,\n missingHeaders,\n };\n }\n\n const fields: WebhooksWebhookFields = {\n webhookType: WebhookType.Webhooks,\n hmac: hmac!,\n topic: topicForStorage(topic!),\n domain: domain!,\n apiVersion: apiVersion!,\n webhookId: webhookId!,\n };\n\n const subTopic = getHeader(headers, headerNames.subTopic);\n if (subTopic) fields.subTopic = subTopic;\n\n const name = getHeader(headers, headerNames.name);\n if (name) fields.name = name;\n\n const triggeredAt = getHeader(headers, headerNames.triggeredAt);\n if (triggeredAt) fields.triggeredAt = triggeredAt;\n\n const eventId = getHeader(headers, headerNames.eventId);\n if (eventId) fields.eventId = eventId;\n\n return {valid: true, ...fields};\n}\n\nfunction checkEventsHeaders(\n headers: Headers,\n): WebhookValidationMissingHeaders | WebhookValidationValid {\n const headerNames = WEBHOOK_HEADER_NAMES[WebhookType.Events];\n const missingHeaders: string[] = [];\n\n const hmac = getRequiredHeader(headers, headerNames.hmac, missingHeaders);\n const topic = getRequiredHeader(headers, headerNames.topic, missingHeaders);\n const domain = getRequiredHeader(headers, headerNames.domain, missingHeaders);\n const apiVersion = getRequiredHeader(\n headers,\n headerNames.apiVersion,\n missingHeaders,\n );\n const eventId = getRequiredHeader(\n headers,\n headerNames.eventId,\n missingHeaders,\n );\n\n if (missingHeaders.length) {\n return {\n valid: false,\n reason: WebhookValidationErrorReason.MissingHeaders,\n missingHeaders,\n };\n }\n\n const fields: EventsWebhookFields = {\n webhookType: WebhookType.Events,\n hmac: hmac!,\n topic: topicForStorage(topic!),\n domain: domain!,\n apiVersion: apiVersion!,\n eventId: eventId!,\n };\n\n const handle = getHeader(headers, headerNames.handle);\n if (handle) fields.handle = handle;\n\n const action = getHeader(headers, headerNames.action);\n if (action) fields.action = action;\n\n const resourceId = getHeader(headers, headerNames.resourceId);\n if (resourceId) fields.resourceId = resourceId;\n\n const triggeredAt = getHeader(headers, headerNames.triggeredAt);\n if (triggeredAt) fields.triggeredAt = triggeredAt;\n\n return {valid: true, ...fields};\n}\n"],"names":[],"mappings":"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"}