UNPKG

@energica-city/shared-amplify-utils

Version:

Shared utilities for AWS Amplify projects

101 lines 15.4 kB
import { logger } from '../../log'; import { WebSocketErrors } from '../../error'; import * as yup from 'yup'; import { buildWebSocketContext, parseJsonBody, isMessageEvent } from './utils'; const VALIDATED_MESSAGE_KEY = Symbol('validatedMessage'); export function getValidatedMessage(event) { return event[VALIDATED_MESSAGE_KEY]; } function extractErrors(error) { return error.inner.map(innerError => ({ field: innerError.path || 'unknown', message: innerError.message, value: innerError.value, type: innerError.type || 'validation', })); } function shouldValidate(input, bodySchema, validateOnlyOnRoutes) { const { event } = input; const { requestContext } = event; if (!isMessageEvent(event)) { return { shouldValidate: false, reason: 'Not a MESSAGE event' }; } if (!bodySchema) { return { shouldValidate: false, reason: 'No validation schema' }; } if (!event.body) { return { shouldValidate: false, reason: 'No message body' }; } if (validateOnlyOnRoutes.length > 0 && !validateOnlyOnRoutes.includes(requestContext.routeKey)) { return { shouldValidate: false, reason: `Route ${requestContext.routeKey} not in validation list`, }; } return { shouldValidate: true }; } export function createWebSocketRequestValidator(config) { const { bodySchema, stripUnknown = true, abortEarly = false, errorMessage = 'Validation failed', errorContext = {}, validateOnlyOnRoutes = ['$default'], logValidationSkipped = false, } = config; return async (input, next) => { const { event } = input; const { requestContext } = event; const validationDecision = shouldValidate(input, bodySchema, validateOnlyOnRoutes); if (!validationDecision.shouldValidate) { if (logValidationSkipped) { logger.debug('WebSocket validation skipped', { connectionId: requestContext.connectionId, routeKey: requestContext.routeKey, reason: validationDecision.reason, }); } return await next(input); } try { const context = buildWebSocketContext(input); const messageData = parseJsonBody(event.body, context); if (messageData === null) { throw WebSocketErrors.badRequest('Invalid JSON in message body', { connectionId: requestContext.connectionId, routeKey: requestContext.routeKey, }); } const validatedData = await bodySchema.validate(messageData, { stripUnknown, abortEarly, }); event[VALIDATED_MESSAGE_KEY] = validatedData; logger.debug('WebSocket message validation successful', { connectionId: requestContext.connectionId, routeKey: requestContext.routeKey, messageId: requestContext.messageId, }); return await next(input); } catch (error) { const context = buildWebSocketContext(input, errorContext); if (error instanceof yup.ValidationError) { const validationErrors = extractErrors(error); logger.error('WebSocket validation failed', { connectionId: requestContext.connectionId, routeKey: requestContext.routeKey, messageId: requestContext.messageId, validationErrors, rawBody: event.body, }); throw WebSocketErrors.badRequest(errorMessage, { ...context, validationErrors, field: validationErrors[0]?.field, }); } else if (error instanceof Error && 'statusCode' in error) { throw error; } else { throw WebSocketErrors.internal('Validation processing error', context); } } }; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiV2ViU29ja2V0UmVxdWVzdFZhbGlkYXRvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL21pZGRsZXdhcmUvd2Vic29ja2V0L1dlYlNvY2tldFJlcXVlc3RWYWxpZGF0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNuQyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQzlDLE9BQU8sS0FBSyxHQUFHLE1BQU0sS0FBSyxDQUFDO0FBVTNCLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxhQUFhLEVBQUUsY0FBYyxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBRS9FLE1BQU0scUJBQXFCLEdBQUcsTUFBTSxDQUFDLGtCQUFrQixDQUFDLENBQUM7QUFFekQsTUFBTSxVQUFVLG1CQUFtQixDQUNqQyxLQUFxQjtJQUVyQixPQUFRLEtBQTBELENBQ2hFLHFCQUFxQixDQUN0QixDQUFDO0FBQ0osQ0FBQztBQUVELFNBQVMsYUFBYSxDQUFDLEtBQTBCO0lBQy9DLE9BQU8sS0FBSyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ3BDLEtBQUssRUFBRSxVQUFVLENBQUMsSUFBSSxJQUFJLFNBQVM7UUFDbkMsT0FBTyxFQUFFLFVBQVUsQ0FBQyxPQUFPO1FBQzNCLEtBQUssRUFBRSxVQUFVLENBQUMsS0FBSztRQUN2QixJQUFJLEVBQUUsVUFBVSxDQUFDLElBQUksSUFBSSxZQUFZO0tBQ3RDLENBQUMsQ0FBQyxDQUFDO0FBQ04sQ0FBQztBQUVELFNBQVMsY0FBYyxDQUNyQixLQUF1QyxFQUN2QyxVQUFrQyxFQUNsQyxvQkFBOEI7SUFFOUIsTUFBTSxFQUFFLEtBQUssRUFBRSxHQUFHLEtBQUssQ0FBQztJQUN4QixNQUFNLEVBQUUsY0FBYyxFQUFFLEdBQUcsS0FBSyxDQUFDO0lBRWpDLElBQUksQ0FBQyxjQUFj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YlNvY2tldEVycm9ycyB9IGZyb20gJy4uLy4uL2Vycm9yJztcbmltcG9ydCAqIGFzIHl1cCBmcm9tICd5dXAnO1xuaW1wb3J0IHR5cGUgeyBNaWRkbGV3YXJlIH0gZnJvbSAnLi4vbWlkZGxld2FyZUNoYWluJztcbmltcG9ydCB0eXBlIHtcbiAgV2ViU29ja2V0RXZlbnQsXG4gIFdlYlNvY2tldFJlc3BvbnNlLFxuICBXZWJTb2NrZXRJbnB1dFdpdGhNb2RlbHMsXG4gIFdlYlNvY2tldFJlcXVlc3RWYWxpZGF0aW9uQ29uZmlnLFxuICBWYWxpZGF0aW9uRXJyb3JEZXRhaWwsXG59IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IHR5cGUgeyBBbXBsaWZ5TW9kZWxUeXBlIH0gZnJvbSAnLi4vLi4vcXVlcmllcy90eXBlcyc7XG5pbXBvcnQgeyBidWlsZFdlYlNvY2tldENvbnRleHQsIHBhcnNlSnNvbkJvZHksIGlzTWVzc2FnZUV2ZW50IH0gZnJvbSAnLi91dGlscyc7XG5cbmNvbnN0IFZBTElEQVRFRF9NRVNTQUdFX0tFWSA9IFN5bWJvbCgndmFsaWRhdGVkTWVzc2FnZScpO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0VmFsaWRhdGVkTWVzc2FnZTxUID0gdW5rbm93bj4oXG4gIGV2ZW50OiBXZWJTb2NrZXRFdmVudCxcbik6IFQgfCB1bmRlZmluZWQge1xuICByZXR1cm4gKGV2ZW50IGFzIFdlYlNvY2tldEV2ZW50ICYgeyBbVkFMSURBVEVEX01FU1NBR0VfS0VZXT86IFQgfSlbXG4gICAgVkFMSURBVEVEX01FU1NBR0VfS0VZXG4gIF07XG59XG5cbmZ1bmN0aW9uIGV4dHJhY3RFcnJvcnMoZXJyb3I6IHl1cC5WYWxpZGF0aW9uRXJyb3IpOiBWYWxpZGF0aW9uRXJyb3JEZXRhaWxbXSB7XG4gIHJldHVybiBlcnJvci5pbm5lci5tYXAoaW5uZXJFcnJvciA9PiAoe1xuICAgIGZpZWxkOiBpbm5lckVycm9yLnBhdGggfHwgJ3Vua25vd24nLFxuICAgIG1lc3NhZ2U6IGlubmVyRXJyb3IubWVzc2FnZSxcbiAgICB2YWx1ZTogaW5uZXJFcnJvci52YWx1ZSxcbiAgICB0eXBlOiBpbm5lckVycm9yLnR5cGUgfHwgJ3ZhbGlkYXRpb24nLFxuICB9KSk7XG59XG5cbmZ1bmN0aW9uIHNob3VsZFZhbGlkYXRlPFRUeXBlcyBleHRlbmRzIFJlY29yZDxzdHJpbmcsIEFtcGxpZnlNb2RlbFR5cGU+PihcbiAgaW5wdXQ6IFdlYlNvY2tldElucHV0V2l0aE1vZGVsczxUVHlwZXM+LFxuICBib2R5U2NoZW1hOiB5dXAuU2NoZW1hIHwgdW5kZWZpbmVkLFxuICB2YWxpZGF0ZU9ubHlPblJvdXRlczogc3RyaW5nW10sXG4pOiB7IHNob3VsZFZhbGlkYXRlOiBib29sZWFuOyByZWFzb24/OiBzdHJpbmcgfSB7XG4gIGNvbnN0IHsgZXZlbnQgfSA9IGlucHV0O1xuICBjb25zdCB7IHJlcXVlc3RDb250ZXh0IH0gPSBldmVudDtcblxuICBpZiAoIWlzTWVzc2FnZUV2ZW50KGV2ZW50KSkge1xuICAgIHJldHVybiB7IHNob3VsZFZhbGlkYXRlOiBmYWxzZSwgcmVhc29uOiAnTm90IGEgTUVTU0FHRSBldmVudCcgfTtcbiAgfVxuXG4gIGlmICghYm9keVNjaGVtYSkge1xuICAgIHJldHVybiB7IHNob3VsZFZhbGlkYXRlOiBmYWxzZSwgcmVhc29uOiAnTm8gdmFsaWRhdGlvbiBzY2hlbWEnIH07XG4gIH1cblxuICBpZiAoIWV2ZW50LmJvZHkpIHtcbiAgICByZXR1cm4geyBzaG91bGRWYWxpZGF0ZTogZmFsc2UsIHJlYXNvbjogJ05vIG1lc3NhZ2UgYm9keScgfTtcbiAgfVxuXG4gIGlmIChcbiAgICB2YWxpZGF0ZU9ubHlPblJvdXRlcy5sZW5ndGggPiAwICYmXG4gICAgIXZhbGlkYXRlT25seU9uUm91dGVzLmluY2x1ZGVzKHJlcXVlc3RDb250ZXh0LnJvdXRlS2V5KVxuICApIHtcbiAgICByZXR1cm4ge1xuICAgICAgc2hvdWxkVmFsaWRhdGU6IGZhbHNlLFxuICAgICAgcmVhc29uOiBgUm91dGUgJHtyZXF1ZXN0Q29udGV4dC5yb3V0ZUtleX0gbm90IGluIHZhbGlkYXRpb24gbGlzdGAsXG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiB7IHNob3VsZFZhbGlkYXRlOiB0cnVlIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVXZWJTb2NrZXRSZXF1ZXN0VmFsaWRhdG9yPFxuICBUVHlwZXMgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCBBbXBsaWZ5TW9kZWxUeXBlPixcbiAgVE91dHB1dCA9IFdlYlNvY2tldFJlc3BvbnNlLFxuPihcbiAgY29uZmlnOiBXZWJTb2NrZXRSZXF1ZXN0VmFsaWRhdGlvbkNvbmZpZyxcbik6IE1pZGRsZXdhcmU8V2ViU29ja2V0SW5wdXRXaXRoTW9kZWxzPFRUeXBlcz4sIFRPdXRwdXQ+IHtcbiAgY29uc3Qge1xuICAgIGJvZHlTY2hlbWEsXG4gICAgc3RyaXBVbmtub3duID0gdHJ1ZSxcbiAgICBhYm9ydEVhcmx5ID0gZmFsc2UsXG4gICAgZXJyb3JNZXNzYWdlID0gJ1ZhbGlkYXRpb24gZmFpbGVkJyxcbiAgICBlcnJvckNvbnRleHQgPSB7fSxcbiAgICB2YWxpZGF0ZU9ubHlPblJvdXRlcyA9IFsnJGRlZmF1bHQnXSxcbiAgICBsb2dWYWxpZGF0aW9uU2tpcHBlZCA9IGZhbHNlLFxuICB9ID0gY29uZmlnO1xuXG4gIHJldHVybiBhc3luYyAoXG4gICAgaW5wdXQ6IFdlYlNvY2tldElucHV0V2l0aE1vZGVsczxUVHlwZXM+LFxuICAgIG5leHQ6IChpbnB1dD86IFdlYlNvY2tldElucHV0V2l0aE1vZGVsczxUVHlwZXM+KSA9PiBQcm9taXNlPFRPdXRwdXQ+LFxuICApOiBQcm9taXNlPFRPdXRwdXQ+ID0+IHtcbiAgICBjb25zdCB7IGV2ZW50IH0gPSBpbnB1dDtcbiAgICBjb25zdCB7IHJlcXVlc3RDb250ZXh0IH0gPSBldmVudDtcblxuICAgIGNvbnN0IHZhbGlkYXRpb25EZWNpc2lvbiA9IHNob3VsZFZhbGlkYXRlKFxuICAgICAgaW5wdXQsXG4gICAgICBib2R5U2NoZW1hLFxuICAgICAgdmFsaWRhdGVPbmx5T25Sb3V0ZXMsXG4gICAgKTtcblxuICAgIGlmICghdmFsaWRhdGlvbkRlY2lzaW9uLnNob3VsZFZhbGlkYXRlKSB7XG4gICAgICBpZiAobG9nVmFsaWRhdGlvblNraXBwZWQpIHtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKCdXZWJTb2NrZXQgdmFsaWRhdGlvbiBza2lwcGVkJywge1xuICAgICAgICAgIGNvbm5lY3Rpb25JZDogcmVxdWVzdENvbnRleHQuY29ubmVjdGlvbklkLFxuICAgICAgICAgIHJvdXRlS2V5OiByZXF1ZXN0Q29udGV4dC5yb3V0ZUtleSxcbiAgICAgICAgICByZWFzb246IHZhbGlkYXRpb25EZWNpc2lvbi5yZWFzb24sXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGF3YWl0IG5leHQoaW5wdXQpO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBjb25zdCBjb250ZXh0ID0gYnVpbGRXZWJTb2NrZXRDb250ZXh0KGlucHV0KTtcbiAgICAgIGNvbnN0IG1lc3NhZ2VEYXRhID0gcGFyc2VKc29uQm9keShldmVudC5ib2R5LCBjb250ZXh0KTtcblxuICAgICAgaWYgKG1lc3NhZ2VEYXRhID09PSBudWxsKSB7XG4gICAgICAgIHRocm93IFdlYlNvY2tldEVycm9ycy5iYWRSZXF1ZXN0KCdJbnZhbGlkIEpTT04gaW4gbWVzc2FnZSBib2R5Jywge1xuICAgICAgICAgIGNvbm5lY3Rpb25JZDogcmVxdWVzdENvbnRleHQuY29ubmVjdGlvbklkLFxuICAgICAgICAgIHJvdXRlS2V5OiByZXF1ZXN0Q29udGV4dC5yb3V0ZUtleSxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHZhbGlkYXRlZERhdGEgPSBhd2FpdCBib2R5U2NoZW1hIS52YWxpZGF0ZShtZXNzYWdlRGF0YSwge1xuICAgICAgICBzdHJpcFVua25vd24sXG4gICAgICAgIGFib3J0RWFybHksXG4gICAgICB9KTtcblxuICAgICAgKGV2ZW50IGFzIFdlYlNvY2tldEV2ZW50ICYgeyBbVkFMSURBVEVEX01FU1NBR0VfS0VZXT86IHVua25vd24gfSlbXG4gICAgICAgIFZBTElEQVRFRF9NRVNTQUdFX0tFWVxuICAgICAgXSA9IHZhbGlkYXRlZERhdGE7XG5cbiAgICAgIGxvZ2dlci5kZWJ1ZygnV2ViU29ja2V0IG1lc3NhZ2UgdmFsaWRhdGlvbiBzdWNjZXNzZnVsJywge1xuICAgICAgICBjb25uZWN0aW9uSWQ6IHJlcXVlc3RDb250ZXh0LmNvbm5lY3Rpb25JZCxcbiAgICAgICAgcm91dGVLZXk6IHJlcXVlc3RDb250ZXh0LnJvdXRlS2V5LFxuICAgICAgICBtZXNzYWdlSWQ6IHJlcXVlc3RDb250ZXh0Lm1lc3NhZ2VJZCxcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gYXdhaXQgbmV4dChpbnB1dCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNvbnN0IGNvbnRleHQgPSBidWlsZFdlYlNvY2tldENvbnRleHQoaW5wdXQsIGVycm9yQ29udGV4dCk7XG5cbiAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIHl1cC5WYWxpZGF0aW9uRXJyb3IpIHtcbiAgICAgICAgY29uc3QgdmFsaWRhdGlvbkVycm9ycyA9IGV4dHJhY3RFcnJvcnMoZXJyb3IpO1xuXG4gICAgICAgIGxvZ2dlci5lcnJvcignV2ViU29ja2V0IHZhbGlkYXRpb24gZmFpbGVkJywge1xuICAgICAgICAgIGNvbm5lY3Rpb25JZDogcmVxdWVzdENvbnRleHQuY29ubmVjdGlvbklkLFxuICAgICAgICAgIHJvdXRlS2V5OiByZXF1ZXN0Q29udGV4dC5yb3V0ZUtleSxcbiAgICAgICAgICBtZXNzYWdlSWQ6IHJlcXVlc3RDb250ZXh0Lm1lc3NhZ2VJZCxcbiAgICAgICAgICB2YWxpZGF0aW9uRXJyb3JzLFxuICAgICAgICAgIHJhd0JvZHk6IGV2ZW50LmJvZHksXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRocm93IFdlYlNvY2tldEVycm9ycy5iYWRSZXF1ZXN0KGVycm9yTWVzc2FnZSwge1xuICAgICAgICAgIC4uLmNvbnRleHQsXG4gICAgICAgICAgdmFsaWRhdGlvbkVycm9ycyxcbiAgICAgICAgICBmaWVsZDogdmFsaWRhdGlvbkVycm9yc1swXT8uZmllbGQsXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIGlmIChlcnJvciBpbnN0YW5jZW9mIEVycm9yICYmICdzdGF0dXNDb2RlJyBpbiBlcnJvcikge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IFdlYlNvY2tldEVycm9ycy5pbnRlcm5hbCgnVmFsaWRhdGlvbiBwcm9jZXNzaW5nIGVycm9yJywgY29udGV4dCk7XG4gICAgICB9XG4gICAgfVxuICB9O1xufVxuIl19