UNPKG

@shopify/shopify-api

Version:

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

1 lines 9.83 kB
{"version":3,"file":"process.mjs","sources":["../../../../../../lib/webhooks/process.ts"],"sourcesContent":["import {StatusCode} from '../types';\nimport {\n abstractConvertResponse,\n AdapterResponse,\n isOK,\n NormalizedResponse,\n} from '../../runtime/http';\nimport {ConfigInterface} from '../base-types';\nimport * as ShopifyErrors from '../error';\nimport {logger} from '../logger';\n\nimport {\n DeliveryMethod,\n HttpWebhookHandlerWithCallback,\n WebhookProcessParams,\n WebhookRegistry,\n WebhookValidationErrorReason,\n WebhookValidationInvalid,\n WebhookValidationMissingHeaders,\n WebhookValidationValid,\n} from './types';\nimport {validateFactory} from './validate';\n\ninterface HandlerCallResult {\n statusCode: StatusCode;\n errorMessage?: string;\n}\n\ninterface ErrorCallResult {\n statusCode: StatusCode;\n errorMessage: string;\n}\n\nconst STATUS_TEXT_LOOKUP: Record<string, string> = {\n [StatusCode.Ok]: 'OK',\n [StatusCode.BadRequest]: 'Bad Request',\n [StatusCode.Unauthorized]: 'Unauthorized',\n [StatusCode.NotFound]: 'Not Found',\n [StatusCode.InternalServerError]: 'Internal Server Error',\n};\n\nexport function process(\n config: ConfigInterface,\n webhookRegistry: WebhookRegistry<HttpWebhookHandlerWithCallback>,\n) {\n return async function process({\n context,\n rawBody,\n ...adapterArgs\n }: WebhookProcessParams): Promise<AdapterResponse> {\n const response: NormalizedResponse = {\n statusCode: StatusCode.Ok,\n statusText: STATUS_TEXT_LOOKUP[StatusCode.Ok],\n headers: {},\n };\n\n await logger(config).info('Receiving webhook request');\n\n const webhookCheck = await validateFactory(config)({\n rawBody,\n ...adapterArgs,\n });\n\n let errorMessage = 'Unknown error while handling webhook';\n if (webhookCheck.valid) {\n const handlerResult = await callWebhookHandlers(\n config,\n webhookRegistry,\n webhookCheck,\n rawBody,\n context,\n );\n\n response.statusCode = handlerResult.statusCode;\n if (!isOK(response)) {\n errorMessage = handlerResult.errorMessage || errorMessage;\n }\n } else {\n const errorResult = await handleInvalidWebhook(config, webhookCheck);\n\n response.statusCode = errorResult.statusCode;\n response.statusText = STATUS_TEXT_LOOKUP[response.statusCode];\n errorMessage = errorResult.errorMessage;\n }\n\n const returnResponse = await abstractConvertResponse(response, adapterArgs);\n if (!isOK(response)) {\n throw new ShopifyErrors.InvalidWebhookError({\n message: errorMessage,\n response: returnResponse,\n });\n }\n\n return Promise.resolve(returnResponse);\n };\n}\n\nasync function callWebhookHandlers(\n config: ConfigInterface,\n webhookRegistry: WebhookRegistry<HttpWebhookHandlerWithCallback>,\n webhookCheck: WebhookValidationValid,\n rawBody: string,\n context: any,\n): Promise<HandlerCallResult> {\n const log = logger(config);\n const {hmac: _hmac, valid: _valid, ...loggingContext} = webhookCheck;\n\n await log.debug(\n 'Webhook request is valid, looking for HTTP handlers to call',\n loggingContext,\n );\n\n const handlers = webhookRegistry[webhookCheck.topic] || [];\n\n const response: HandlerCallResult = {statusCode: StatusCode.Ok};\n\n let found = false;\n for (const handler of handlers) {\n if (handler.deliveryMethod !== DeliveryMethod.Http) {\n continue;\n }\n if (!handler.callback) {\n response.statusCode = StatusCode.InternalServerError;\n response.errorMessage =\n \"Cannot call webhooks.process with a webhook handler that doesn't have a callback\";\n\n throw new ShopifyErrors.MissingWebhookCallbackError({\n message: response.errorMessage,\n response,\n });\n }\n\n found = true;\n\n await log.debug('Found HTTP handler, triggering it', loggingContext);\n\n try {\n await handler.callback(\n webhookCheck.topic,\n webhookCheck.domain,\n rawBody,\n webhookCheck.webhookId,\n webhookCheck.apiVersion,\n ...(webhookCheck?.subTopic ? webhookCheck.subTopic : ''),\n context,\n );\n } catch (error) {\n response.statusCode = StatusCode.InternalServerError;\n response.errorMessage = error.message;\n }\n }\n\n if (!found) {\n await log.debug('No HTTP handlers found', loggingContext);\n\n response.statusCode = StatusCode.NotFound;\n response.errorMessage = `No HTTP webhooks registered for topic ${webhookCheck.topic}`;\n }\n\n return response;\n}\n\nasync function handleInvalidWebhook(\n config: ConfigInterface,\n webhookCheck: WebhookValidationInvalid,\n): Promise<ErrorCallResult> {\n const response: ErrorCallResult = {\n statusCode: StatusCode.InternalServerError,\n errorMessage: 'Unknown error while handling webhook',\n };\n\n switch (webhookCheck.reason) {\n case WebhookValidationErrorReason.MissingHeaders:\n response.statusCode = StatusCode.BadRequest;\n response.errorMessage = `Missing one or more of the required HTTP headers to process webhooks: [${(\n webhookCheck as WebhookValidationMissingHeaders\n ).missingHeaders.join(', ')}]`;\n break;\n case WebhookValidationErrorReason.MissingBody:\n response.statusCode = StatusCode.BadRequest;\n response.errorMessage = 'No body was received when processing webhook';\n break;\n case WebhookValidationErrorReason.MissingHmac:\n response.statusCode = StatusCode.BadRequest;\n response.errorMessage = `Missing HMAC header in request`;\n break;\n case WebhookValidationErrorReason.InvalidHmac:\n response.statusCode = StatusCode.Unauthorized;\n response.errorMessage = `Could not validate request HMAC`;\n break;\n }\n\n await logger(config).debug(\n `Webhook request is invalid, returning ${response.statusCode}: ${response.errorMessage}`,\n );\n\n return response;\n}\n"],"names":["ShopifyErrors.InvalidWebhookError","ShopifyErrors.MissingWebhookCallbackError"],"mappings":"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"}