Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 56 additions & 6 deletions backend/src/iac/backend-stack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -445,12 +445,62 @@ export class BackendStack extends cdk.Stack {

// Add CORS to all resources
api.root.addCorsPreflight(corsOptions);
apiResource.addCorsPreflight(corsOptions);
reportsResource.addCorsPreflight(corsOptions);
latestResource.addCorsPreflight(corsOptions);
reportIdResource.addCorsPreflight(corsOptions);
reportStatusResource.addCorsPreflight(corsOptions);
docsResource.addCorsPreflight(corsOptions);
apiResource.addCorsPreflight({
...corsOptions,
allowCredentials: false, // This is crucial - make sure OPTIONS requests don't require credentials
});
reportsResource.addCorsPreflight({
...corsOptions,
allowCredentials: false,
});
latestResource.addCorsPreflight({
...corsOptions,
allowCredentials: false,
});
reportIdResource.addCorsPreflight({
...corsOptions,
allowCredentials: false,
});
reportStatusResource.addCorsPreflight({
...corsOptions,
allowCredentials: false,
});
docsResource.addCorsPreflight({
...corsOptions,
allowCredentials: false,
});

// Configure Gateway Responses to add CORS headers to error responses
const gatewayResponseTypes = [
apigateway.ResponseType.UNAUTHORIZED,
apigateway.ResponseType.ACCESS_DENIED,
apigateway.ResponseType.DEFAULT_4XX,
apigateway.ResponseType.DEFAULT_5XX,
apigateway.ResponseType.RESOURCE_NOT_FOUND,
apigateway.ResponseType.MISSING_AUTHENTICATION_TOKEN,
apigateway.ResponseType.INVALID_API_KEY,
apigateway.ResponseType.THROTTLED,
apigateway.ResponseType.INTEGRATION_FAILURE,
apigateway.ResponseType.INTEGRATION_TIMEOUT,
];

gatewayResponseTypes.forEach(responseType => {
new apigateway.CfnGatewayResponse(
this,
`${appName}GatewayResponse-${responseType.responseType.toString()}-${props.environment}`,
{
restApiId: api.restApiId,
responseType: responseType.responseType.toString(),
responseParameters: {
'gatewayresponse.header.Access-Control-Allow-Origin': "'*'",
'gatewayresponse.header.Access-Control-Allow-Headers':
"'Content-Type,Authorization,X-Amz-Date,X-Api-Key'",
'gatewayresponse.header.Access-Control-Allow-Methods':
"'GET,POST,PUT,PATCH,DELETE,OPTIONS'",
},
},
);
});

// Create API Gateway execution role with required permissions
new iam.Role(this, `${appName}APIGatewayRole-${props.environment}`, {
Expand Down
49 changes: 28 additions & 21 deletions backend/src/iac/update-api-policy.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,29 +62,36 @@ async function main() {
const policy = {
Version: '2012-10-17',
Statement: [
// Allow authenticated Cognito users
{
Effect: 'Allow',
Principal: '*',
Action: 'execute-api:Invoke',
Resource: `arn:aws:execute-api:${REGION}:*:${api.id}/*/*`,
Condition: {
StringEquals: {
'cognito-identity.amazonaws.com:aud': cognitoUserPoolId
"Version": "2012-10-17",
"Statement": [
// Allow OPTIONS requests
{
"Effect": "Allow",
"Principal": "*",
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:us-east-1:*:xhvwo6wp66/*/OPTIONS/*"
},
{
// Allow all other requests - authentication will be handled by Cognito
"Effect": "Allow",
"Principal": "*",
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:us-east-1:*:xhvwo6wp66/*/*"
},
{
// Deny non-HTTPS requests
"Effect": "Deny",
"Principal": "*",
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:us-east-1:*:xhvwo6wp66/*/*",
"Condition": {
"Bool": {
"aws:SecureTransport": "false"
}
}
}
}
},
// Deny non-HTTPS requests
{
Effect: 'Deny',
Principal: '*',
Action: 'execute-api:Invoke',
Resource: `arn:aws:execute-api:${REGION}:*:${api.id}/*/*`,
Condition: {
Bool: {
'aws:SecureTransport': 'false'
}
}
]
}
]
};
Expand Down
5 changes: 3 additions & 2 deletions backend/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@ async function bootstrap() {
// Enable CORS
app.enableCors({
origin: [
'http://localhost:5173', // Vite default dev server
'http://localhost:5173',
'http://localhost:3000',
'http://localhost:4173', // Vite preview
'http://localhost:4173',
'https://localhost', // Add this for Capacitor
...(process.env.FRONTEND_URL ? [process.env.FRONTEND_URL] : []),
],
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS',
Expand Down