From 34bb338bfc8e2976691a23969baa5fd9d84727e8 Mon Sep 17 00:00:00 2001 From: Robert Djurasaj Date: Mon, 22 Mar 2021 11:23:29 -0600 Subject: [PATCH] fix(apigatewayv2): error while configuring ANY as an allowed method in CORS (#13313) API gateway expects `*` to represent `ANY` HTTP method. `HttpMethod` enum doesn't have a value for that, thus causing errors when passing `HttpMethod` 's `ANY` option. This commit introduces `CorsHttpMethod` enum which has a proper `ANY` mapping to `*`. Closes #13280. Closes #13643. BREAKING CHANGE: The type of `allowMethods` property under `corsPreflight` section is changed from `HttpMethod` to `CorsHttpMethod`. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-apigatewayv2/README.md | 2 +- .../@aws-cdk/aws-apigatewayv2/lib/http/api.ts | 24 ++++++++++++++++++- .../aws-apigatewayv2/lib/http/route.ts | 2 +- .../aws-apigatewayv2/test/http/api.test.ts | 5 ++-- 4 files changed, 28 insertions(+), 5 deletions(-) diff --git a/packages/@aws-cdk/aws-apigatewayv2/README.md b/packages/@aws-cdk/aws-apigatewayv2/README.md index 7a71fc00491a1..0d4d7849fd8df 100644 --- a/packages/@aws-cdk/aws-apigatewayv2/README.md +++ b/packages/@aws-cdk/aws-apigatewayv2/README.md @@ -133,7 +133,7 @@ The `corsPreflight` option lets you specify a CORS configuration for an API. new HttpApi(stack, 'HttpProxyApi', { corsPreflight: { allowHeaders: ['Authorization'], - allowMethods: [HttpMethod.GET, HttpMethod.HEAD, HttpMethod.OPTIONS, HttpMethod.POST], + allowMethods: [CorsHttpMethod.GET, CorsHttpMethod.HEAD, CorsHttpMethod.OPTIONS, CorsHttpMethod.POST], allowOrigins: ['*'], maxAge: Duration.days(10), }, diff --git a/packages/@aws-cdk/aws-apigatewayv2/lib/http/api.ts b/packages/@aws-cdk/aws-apigatewayv2/lib/http/api.ts index 24d250dfd6eda..9675a7654a712 100644 --- a/packages/@aws-cdk/aws-apigatewayv2/lib/http/api.ts +++ b/packages/@aws-cdk/aws-apigatewayv2/lib/http/api.ts @@ -99,6 +99,28 @@ export interface HttpApiProps { readonly defaultAuthorizationScopes?: string[]; } +/** + * Supported CORS HTTP methods + */ +export enum CorsHttpMethod{ + /** HTTP ANY */ + ANY = '*', + /** HTTP DELETE */ + DELETE = 'DELETE', + /** HTTP GET */ + GET = 'GET', + /** HTTP HEAD */ + HEAD = 'HEAD', + /** HTTP OPTIONS */ + OPTIONS = 'OPTIONS', + /** HTTP PATCH */ + PATCH = 'PATCH', + /** HTTP POST */ + POST = 'POST', + /** HTTP PUT */ + PUT = 'PUT', +} + /** * Options for the CORS Configuration */ @@ -119,7 +141,7 @@ export interface CorsPreflightOptions { * Represents a collection of allowed HTTP methods. * @default - No Methods are allowed. */ - readonly allowMethods?: HttpMethod[]; + readonly allowMethods?: CorsHttpMethod[]; /** * Represents a collection of allowed origins. diff --git a/packages/@aws-cdk/aws-apigatewayv2/lib/http/route.ts b/packages/@aws-cdk/aws-apigatewayv2/lib/http/route.ts index c3ef630abbbb5..2252630930c27 100644 --- a/packages/@aws-cdk/aws-apigatewayv2/lib/http/route.ts +++ b/packages/@aws-cdk/aws-apigatewayv2/lib/http/route.ts @@ -61,7 +61,7 @@ export class HttpRouteKey { if (path !== '/' && (!path.startsWith('/') || path.endsWith('/'))) { throw new Error('path must always start with a "/" and not end with a "/"'); } - return new HttpRouteKey(`${method ?? 'ANY'} ${path}`, path); + return new HttpRouteKey(`${method ?? HttpMethod.ANY} ${path}`, path); } /** diff --git a/packages/@aws-cdk/aws-apigatewayv2/test/http/api.test.ts b/packages/@aws-cdk/aws-apigatewayv2/test/http/api.test.ts index 348d8dec9aeb4..72495a3bfde3f 100644 --- a/packages/@aws-cdk/aws-apigatewayv2/test/http/api.test.ts +++ b/packages/@aws-cdk/aws-apigatewayv2/test/http/api.test.ts @@ -4,6 +4,7 @@ import { Metric } from '@aws-cdk/aws-cloudwatch'; import * as ec2 from '@aws-cdk/aws-ec2'; import { Duration, Stack } from '@aws-cdk/core'; import { + CorsHttpMethod, HttpApi, HttpAuthorizer, HttpAuthorizerType, HttpIntegrationType, HttpMethod, HttpRouteAuthorizerBindOptions, HttpRouteAuthorizerConfig, HttpRouteIntegrationBindOptions, HttpRouteIntegrationConfig, IHttpRouteAuthorizer, IHttpRouteIntegration, HttpNoneAuthorizer, PayloadFormatVersion, } from '../../lib'; @@ -106,7 +107,7 @@ describe('HttpApi', () => { new HttpApi(stack, 'HttpApi', { corsPreflight: { allowHeaders: ['Authorization'], - allowMethods: [HttpMethod.GET, HttpMethod.HEAD, HttpMethod.OPTIONS, HttpMethod.POST], + allowMethods: [CorsHttpMethod.GET, CorsHttpMethod.HEAD, CorsHttpMethod.OPTIONS, CorsHttpMethod.POST, CorsHttpMethod.ANY], allowOrigins: ['*'], maxAge: Duration.seconds(36400), }, @@ -115,7 +116,7 @@ describe('HttpApi', () => { expect(stack).toHaveResource('AWS::ApiGatewayV2::Api', { CorsConfiguration: { AllowHeaders: ['Authorization'], - AllowMethods: ['GET', 'HEAD', 'OPTIONS', 'POST'], + AllowMethods: ['GET', 'HEAD', 'OPTIONS', 'POST', '*'], AllowOrigins: ['*'], MaxAge: 36400, },