UNPKG

@shopify/shopify-api

Version:

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

132 lines (128 loc) 5.47 kB
'use strict'; var index$1 = require('../logger/index.js'); var hmacValidator = require('../utils/hmac-validator.js'); var types = require('../utils/types.js'); var index = require('../../runtime/http/index.js'); var types$1 = require('./types.js'); var registry = require('./registry.js'); var headers = require('../../runtime/http/headers.js'); function detectWebhookType(headers$1) { const eventsHmac = headers.getHeader(headers$1, types$1.WEBHOOK_HEADER_NAMES[types$1.WebhookType.Events].hmac); if (eventsHmac) { return types$1.WebhookType.Events; } const webhooksHmac = headers.getHeader(headers$1, types$1.WEBHOOK_HEADER_NAMES[types$1.WebhookType.Webhooks].hmac); if (webhooksHmac) { return types$1.WebhookType.Webhooks; } return types$1.WebhookType.Webhooks; } function validateFactory(config) { return async function validate({ rawBody, ...adapterArgs }) { const request = await index.abstractConvertRequest(adapterArgs); const webhookType = detectWebhookType(request.headers); const validHmacResult = await hmacValidator.validateHmacFromRequestFactory(config)({ type: types.HmacValidationType.Webhook, rawBody, webhookType, ...adapterArgs, }); if (!validHmacResult.valid) { if (validHmacResult.reason === types.ValidationErrorReason.InvalidHmac) { const log = index$1.logger(config); await log.debug("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."); } return validHmacResult; } return checkWebhookHeaders(request.headers, webhookType); }; } function getRequiredHeader(headers$1, headerName, missingHeaders) { const value = headers.getHeader(headers$1, headerName); if (!value) { missingHeaders.push(headerName); } return value; } function checkWebhookHeaders(headers, webhookType) { if (webhookType === types$1.WebhookType.Webhooks) { return checkWebhooksHeaders(headers); } return checkEventsHeaders(headers); } function checkWebhooksHeaders(headers$1) { const headerNames = types$1.WEBHOOK_HEADER_NAMES[types$1.WebhookType.Webhooks]; const missingHeaders = []; const hmac = getRequiredHeader(headers$1, headerNames.hmac, missingHeaders); const topic = getRequiredHeader(headers$1, headerNames.topic, missingHeaders); const domain = getRequiredHeader(headers$1, headerNames.domain, missingHeaders); const apiVersion = getRequiredHeader(headers$1, headerNames.apiVersion, missingHeaders); const webhookId = getRequiredHeader(headers$1, headerNames.webhookId, missingHeaders); if (missingHeaders.length) { return { valid: false, reason: types$1.WebhookValidationErrorReason.MissingHeaders, missingHeaders, }; } const fields = { webhookType: types$1.WebhookType.Webhooks, hmac: hmac, topic: registry.topicForStorage(topic), domain: domain, apiVersion: apiVersion, webhookId: webhookId, }; const subTopic = headers.getHeader(headers$1, headerNames.subTopic); if (subTopic) fields.subTopic = subTopic; const name = headers.getHeader(headers$1, headerNames.name); if (name) fields.name = name; const triggeredAt = headers.getHeader(headers$1, headerNames.triggeredAt); if (triggeredAt) fields.triggeredAt = triggeredAt; const eventId = headers.getHeader(headers$1, headerNames.eventId); if (eventId) fields.eventId = eventId; return { valid: true, ...fields }; } function checkEventsHeaders(headers$1) { const headerNames = types$1.WEBHOOK_HEADER_NAMES[types$1.WebhookType.Events]; const missingHeaders = []; const hmac = getRequiredHeader(headers$1, headerNames.hmac, missingHeaders); const topic = getRequiredHeader(headers$1, headerNames.topic, missingHeaders); const domain = getRequiredHeader(headers$1, headerNames.domain, missingHeaders); const apiVersion = getRequiredHeader(headers$1, headerNames.apiVersion, missingHeaders); const eventId = getRequiredHeader(headers$1, headerNames.eventId, missingHeaders); if (missingHeaders.length) { return { valid: false, reason: types$1.WebhookValidationErrorReason.MissingHeaders, missingHeaders, }; } const fields = { webhookType: types$1.WebhookType.Events, hmac: hmac, topic: registry.topicForStorage(topic), domain: domain, apiVersion: apiVersion, eventId: eventId, }; const handle = headers.getHeader(headers$1, headerNames.handle); if (handle) fields.handle = handle; const action = headers.getHeader(headers$1, headerNames.action); if (action) fields.action = action; const resourceId = headers.getHeader(headers$1, headerNames.resourceId); if (resourceId) fields.resourceId = resourceId; const triggeredAt = headers.getHeader(headers$1, headerNames.triggeredAt); if (triggeredAt) fields.triggeredAt = triggeredAt; return { valid: true, ...fields }; } exports.validateFactory = validateFactory; //# sourceMappingURL=validate.js.map