All files / lib/lambda/middleware handlers.ts

100% Statements 14/14
66.66% Branches 4/6
100% Functions 2/2
100% Lines 14/14

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79                                  11x                               11x 11x   11x   11x         11x 10x   10x 8x       11x                                       11x 9x   9x   9x    
import { zodValidator } from "@dannywrayuk/middy-zod-validator";
import middy from "@middy/core";
import httpErrorHandler from "@middy/http-error-handler";
import httpJsonBodyParser from "@middy/http-json-body-parser";
import { z } from "zod";
 
import {
  isAuthenticated,
  IsAuthenticatedOptions,
  normalizeEvent,
  NormalizeEventOptions,
} from "./index";
 
export type NonAuthenticatedMiddyOptions = NormalizeEventOptions & {
  eventSchema?: z.ZodTypeAny;
};
 
const defaults: NonAuthenticatedMiddyOptions = {
  eventSchema: undefined,
  body: true,
};
 
/**
 * Base Middy handler for non-authenticated endpoints. Sets up the error handler. Runs the event normalization.
 * If applicable, it parses the event body and validates it against the schema.
 * @param {object} opts Options for the Middy handler
 * @param {boolean} opts.opensearch [false] if true, validate opensearch environment variables
 * @param {boolean} opts.kafka [false] if true, validate kafka topic name environment variable
 * @param {boolean} opts.disableCors [false] if true, disable the CORS headers on the response
 * @param {boolean} opts.body [true] if false, skips validating the event body in normalization and schema
 * @param {z.ZodTypeAny} options.eventSchema [undefined] if not undefined, validates the event body using the schema
 * @returns {middy.MiddyfiedHandler<unknown, any, Error, Context, {}>} base Middy handler
 */
export const nonAuthenticatedMiddy = (opts: NonAuthenticatedMiddyOptions = {}) => {
  const options = { ...defaults, ...opts };
 
  const { eventSchema, ...normalizeEventOptions } = options;
 
  let handler = middy()
    .use(
      httpErrorHandler({ fallbackMessage: JSON.stringify({ message: "Internal server error" }) }),
    )
    .use(normalizeEvent(normalizeEventOptions));
  if (options.body) {
    handler = handler.use(httpJsonBodyParser({ disableContentTypeError: true }));
 
    if (eventSchema) {
      handler = handler.use(zodValidator({ eventSchema }));
    }
  }
 
  return handler;
};
 
export type AuthenticatedMiddyOptions = NormalizeEventOptions &
  IsAuthenticatedOptions & {
    eventSchema?: z.ZodTypeAny;
  };
 
/**
 * Base Middy handler for authenticated endpoints. Sets up the error handler. Runs the event normalization.
 * If applicable, it parses the event body and validates it against the schema. Authenticates the current user.
 * @param {object} opts Options for the Middy handler
 * @param {boolean} opts.opensearch [false] if true, validate opensearch environment variables
 * @param {boolean} opts.kafka [false] if true, validate kafka topic name environment variable
 * @param {boolean} opts.disableCors [false] if true, disable the CORS headers on the response
 * @param {boolean} opts.body [true] if false, skips validating the event body in normalization and schema
 * @param {z.ZodTypeAny} options.eventSchema [undefined] if not undefined, validates the event body using the schema
 * @param {boolean} opts.setToContext [false] if true, also stores the package in context, so it can be accessed in the handler
 * @returns {middy.MiddyfiedHandler<unknown, any, Error, Context, {}>} base Middy handler
 */
export const authenticatedMiddy = (opts: AuthenticatedMiddyOptions = {}) => {
  const options = { ...defaults, ...opts };
 
  const { setToContext, ...baseMiddyOptions } = options;
 
  return nonAuthenticatedMiddy(baseMiddyOptions).use(isAuthenticated({ setToContext }));
};