From e40eed10297bf7914f7d5b0df12928467959fdb2 Mon Sep 17 00:00:00 2001 From: Dmitry Kolesnikov Date: Sun, 24 May 2026 22:31:42 +0300 Subject: [PATCH 1/2] (fix) bypass OPTIONS method from authorizer --- scud.go | 23 ++++++++++++++++++++--- scud_test.go | 4 ++-- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/scud.go b/scud.go index fc8e94a..379c712 100644 --- a/scud.go +++ b/scud.go @@ -14,7 +14,6 @@ import ( "strings" "github.com/aws/aws-cdk-go/awscdk/v2" - "github.com/aws/aws-cdk-go/awscdk/v2/awsapigateway" apigw2 "github.com/aws/aws-cdk-go/awscdk/v2/awsapigatewayv2" authorizers "github.com/aws/aws-cdk-go/awscdk/v2/awsapigatewayv2authorizers" integrations "github.com/aws/aws-cdk-go/awscdk/v2/awsapigatewayv2integrations" @@ -42,6 +41,15 @@ type Gateway struct { aRecord awsroute53.ARecord } +var httpMethods = &[]apigw2.HttpMethod{ + apigw2.HttpMethod_GET, + apigw2.HttpMethod_HEAD, + apigw2.HttpMethod_PATCH, + apigw2.HttpMethod_POST, + apigw2.HttpMethod_PUT, + apigw2.HttpMethod_DELETE, +} + // NewGateway creates new instance of Gateway func NewGateway(scope constructs.Construct, id *string, props *GatewayProps) *Gateway { gw := &Gateway{Construct: constructs.NewConstruct(scope, id)} @@ -55,8 +63,13 @@ func NewGateway(scope constructs.Construct, id *string, props *GatewayProps) *Ga if props.HttpApiProps.CorsPreflight == nil { props.CorsPreflight = &apigw2.CorsPreflightOptions{ - AllowOrigins: awsapigateway.Cors_ALL_ORIGINS(), - MaxAge: awscdk.Duration_Minutes(jsii.Number(10)), + AllowOrigins: jsii.Strings("*"), + AllowMethods: &[]apigw2.CorsHttpMethod{apigw2.CorsHttpMethod_ANY}, + AllowHeaders: jsii.Strings( + "Authorization", + "Content-Type", + ), + MaxAge: awscdk.Duration_Minutes(jsii.Number(10)), } } @@ -267,6 +280,7 @@ func (api *AuthorizerPublic) AddResource( api.RestAPI.AddRoutes(&apigw2.AddRoutesOptions{ Path: jsii.String(path), Integration: lambda, + Methods: httpMethods, }) } @@ -300,6 +314,7 @@ func (api *AuthorizerBasic) AddResource( Path: jsii.String(path), Integration: lambda, Authorizer: api.authorizer, + Methods: httpMethods, }) } @@ -337,6 +352,7 @@ func (api *AuthorizerIAM) AddResource( Path: jsii.String(path), Integration: lambda, Authorizer: api.authorizer, + Methods: httpMethods, }) (*routes)[0].GrantInvoke(grantee, nil) } @@ -376,6 +392,7 @@ func (api *AuthorizerJwt) AddResource( Integration: lambda, Authorizer: api.authorizer, AuthorizationScopes: jsii.Strings(accessScope...), + Methods: httpMethods, }) } diff --git a/scud_test.go b/scud_test.go index f823d56..0e1b785 100644 --- a/scud_test.go +++ b/scud_test.go @@ -309,7 +309,7 @@ func TestAddResource(t *testing.T) { require := map[*string]*float64{ jsii.String("AWS::ApiGatewayV2::Api"): jsii.Number(1), jsii.String("AWS::ApiGatewayV2::Stage"): jsii.Number(2), - jsii.String("AWS::ApiGatewayV2::Route"): jsii.Number(2), + jsii.String("AWS::ApiGatewayV2::Route"): jsii.Number(12), jsii.String("AWS::ApiGatewayV2::Integration"): jsii.Number(1), } @@ -338,7 +338,7 @@ func TestAddResourceDepthPath(t *testing.T) { require := map[*string]*float64{ jsii.String("AWS::ApiGatewayV2::Api"): jsii.Number(1), jsii.String("AWS::ApiGatewayV2::Stage"): jsii.Number(2), - jsii.String("AWS::ApiGatewayV2::Route"): jsii.Number(4), + jsii.String("AWS::ApiGatewayV2::Route"): jsii.Number(24), jsii.String("AWS::ApiGatewayV2::Integration"): jsii.Number(2), jsii.String("AWS::Lambda::Function"): jsii.Number(1), } From 9666bed29339c4c2af4e9a12f1aa6ec488704a46 Mon Sep 17 00:00:00 2001 From: Dmitry Kolesnikov Date: Sun, 24 May 2026 22:40:44 +0300 Subject: [PATCH 2/2] (fix) explicit CORS enable --- scud.go | 47 ++++++++++++++++++++++++++++++----------------- scud_test.go | 4 ++-- 2 files changed, 32 insertions(+), 19 deletions(-) diff --git a/scud.go b/scud.go index 379c712..4c51a4c 100644 --- a/scud.go +++ b/scud.go @@ -30,8 +30,9 @@ import ( type GatewayProps struct { *apigw2.HttpApiProps - Host *string - TlsArn *string + Host *string + TlsArn *string + AllowOrigins *string } type Gateway struct { @@ -39,15 +40,7 @@ type Gateway struct { RestAPI apigw2.HttpApi domain apigw2.DomainName aRecord awsroute53.ARecord -} - -var httpMethods = &[]apigw2.HttpMethod{ - apigw2.HttpMethod_GET, - apigw2.HttpMethod_HEAD, - apigw2.HttpMethod_PATCH, - apigw2.HttpMethod_POST, - apigw2.HttpMethod_PUT, - apigw2.HttpMethod_DELETE, + methods *[]apigw2.HttpMethod } // NewGateway creates new instance of Gateway @@ -61,9 +54,9 @@ func NewGateway(scope constructs.Construct, id *string, props *GatewayProps) *Ga props.ApiName = awscdk.Aws_STACK_NAME() } - if props.HttpApiProps.CorsPreflight == nil { + if props.HttpApiProps.CorsPreflight == nil && props.AllowOrigins != nil { props.CorsPreflight = &apigw2.CorsPreflightOptions{ - AllowOrigins: jsii.Strings("*"), + AllowOrigins: &[]*string{props.AllowOrigins}, AllowMethods: &[]apigw2.CorsHttpMethod{apigw2.CorsHttpMethod_ANY}, AllowHeaders: jsii.Strings( "Authorization", @@ -73,6 +66,17 @@ func NewGateway(scope constructs.Construct, id *string, props *GatewayProps) *Ga } } + if props.HttpApiProps.CorsPreflight != nil { + gw.methods = &[]apigw2.HttpMethod{ + apigw2.HttpMethod_GET, + apigw2.HttpMethod_HEAD, + apigw2.HttpMethod_PATCH, + apigw2.HttpMethod_POST, + apigw2.HttpMethod_PUT, + apigw2.HttpMethod_DELETE, + } + } + if props.Host != nil && props.TlsArn != nil { gw.domain = apigw2.NewDomainName(gw.Construct, jsii.String("DomainName"), &apigw2.DomainNameProps{ @@ -135,6 +139,7 @@ func (gw *Gateway) createRoute53(host string) *Gateway { func (gw *Gateway) NewAuthorizerPublic() *AuthorizerPublic { return &AuthorizerPublic{ RestAPI: gw.RestAPI, + methods: gw.methods, } } @@ -176,6 +181,7 @@ func (gw *Gateway) NewAuthorizerBasic(access, secret string, source ...string) * return &AuthorizerBasic{ RestAPI: gw.RestAPI, authorizer: authorizer, + methods: gw.methods, } } @@ -188,6 +194,7 @@ func (gw *Gateway) NewAuthorizerIAM() *AuthorizerIAM { return &AuthorizerIAM{ RestAPI: gw.RestAPI, authorizer: authorizers.NewHttpIamAuthorizer(), + methods: gw.methods, } } @@ -229,6 +236,7 @@ func (gw *Gateway) NewAuthorizerCognito(cognitoArn string, clients ...string) *A return &AuthorizerJwt{ RestAPI: gw.RestAPI, authorizer: authorizer, + methods: gw.methods, } } @@ -252,6 +260,7 @@ func (gw *Gateway) NewAuthorizerJwt(iss string, aud ...string) *AuthorizerJwt { return &AuthorizerJwt{ RestAPI: gw.RestAPI, authorizer: authorizer, + methods: gw.methods, } } @@ -259,6 +268,7 @@ func (gw *Gateway) NewAuthorizerJwt(iss string, aud ...string) *AuthorizerJwt { type AuthorizerPublic struct { RestAPI apigw2.HttpApi + methods *[]apigw2.HttpMethod } // Associate a Lambda function with a REST API path. It uses the specified @@ -280,7 +290,7 @@ func (api *AuthorizerPublic) AddResource( api.RestAPI.AddRoutes(&apigw2.AddRoutesOptions{ Path: jsii.String(path), Integration: lambda, - Methods: httpMethods, + Methods: api.methods, }) } @@ -292,6 +302,7 @@ func (api *AuthorizerPublic) AddResource( type AuthorizerBasic struct { RestAPI apigw2.HttpApi authorizer authorizers.HttpLambdaAuthorizer + methods *[]apigw2.HttpMethod } // Associate a Lambda function with a REST API path. It uses the specified @@ -314,7 +325,7 @@ func (api *AuthorizerBasic) AddResource( Path: jsii.String(path), Integration: lambda, Authorizer: api.authorizer, - Methods: httpMethods, + Methods: api.methods, }) } @@ -327,6 +338,7 @@ type AuthorizerIAM struct { constructs.Construct RestAPI apigw2.HttpApi authorizer apigw2.IHttpRouteAuthorizer + methods *[]apigw2.HttpMethod } // Associate a Lambda function with a REST API path. It uses the specified @@ -352,7 +364,7 @@ func (api *AuthorizerIAM) AddResource( Path: jsii.String(path), Integration: lambda, Authorizer: api.authorizer, - Methods: httpMethods, + Methods: api.methods, }) (*routes)[0].GrantInvoke(grantee, nil) } @@ -366,6 +378,7 @@ type AuthorizerJwt struct { constructs.Construct RestAPI apigw2.HttpApi authorizer apigw2.IHttpRouteAuthorizer + methods *[]apigw2.HttpMethod } // Associate a Lambda function with a REST API path. It uses the specified @@ -392,7 +405,7 @@ func (api *AuthorizerJwt) AddResource( Integration: lambda, Authorizer: api.authorizer, AuthorizationScopes: jsii.Strings(accessScope...), - Methods: httpMethods, + Methods: api.methods, }) } diff --git a/scud_test.go b/scud_test.go index 0e1b785..f823d56 100644 --- a/scud_test.go +++ b/scud_test.go @@ -309,7 +309,7 @@ func TestAddResource(t *testing.T) { require := map[*string]*float64{ jsii.String("AWS::ApiGatewayV2::Api"): jsii.Number(1), jsii.String("AWS::ApiGatewayV2::Stage"): jsii.Number(2), - jsii.String("AWS::ApiGatewayV2::Route"): jsii.Number(12), + jsii.String("AWS::ApiGatewayV2::Route"): jsii.Number(2), jsii.String("AWS::ApiGatewayV2::Integration"): jsii.Number(1), } @@ -338,7 +338,7 @@ func TestAddResourceDepthPath(t *testing.T) { require := map[*string]*float64{ jsii.String("AWS::ApiGatewayV2::Api"): jsii.Number(1), jsii.String("AWS::ApiGatewayV2::Stage"): jsii.Number(2), - jsii.String("AWS::ApiGatewayV2::Route"): jsii.Number(24), + jsii.String("AWS::ApiGatewayV2::Route"): jsii.Number(4), jsii.String("AWS::ApiGatewayV2::Integration"): jsii.Number(2), jsii.String("AWS::Lambda::Function"): jsii.Number(1), }