Skip to content

Commit

Permalink
feat(type-safe-api): automatically add header parameters to cors allo…
Browse files Browse the repository at this point in the history
…wed headers

Header parameters from your model are now automatically added to the Access-Control-Allow-Headers
CORS header if CORS is enabled.

Fixes #578
  • Loading branch information
cogwirrel committed Sep 20, 2023
1 parent 33e2490 commit abe46bc
Show file tree
Hide file tree
Showing 3 changed files with 2,235 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,25 @@ const validateAuthorizerReference = (
}
};

/**
* Find all unique header parameters used in operations
*/
const findHeaderParameters = (spec: OpenAPIV3.Document): string[] => {
const allHeaderParameters = Object.values(spec.paths).flatMap((pathDetails) =>
Object.values(HttpMethods).flatMap((method) =>
(pathDetails?.[method]?.parameters ?? []).flatMap((parameter) =>
"in" in parameter && parameter.in === "header" ? [parameter.name] : []
)
)
);
const headerParameterSet = new Set<string>();
return allHeaderParameters.filter((p) => {
const seen = headerParameterSet.has(p);
headerParameterSet.add(p);
return !seen;
});
};

/**
* Prepares the api spec for deployment by adding integrations, configuring auth, etc
*/
Expand Down Expand Up @@ -498,6 +517,23 @@ export const prepareApiSpec = (
spec.security
);

// If there are cors options, add any header parameters defined in the spec as allowed headers to
// save users from having to manually specify these (or face cors issues!)
const corsOptions: SerializedCorsOptions | undefined = options.corsOptions
? {
...options.corsOptions,
allowHeaders: [
...options.corsOptions.allowHeaders,
...findHeaderParameters(spec),
],
}
: undefined;

const updatedOptions: PrepareApiSpecOptions = {
...options,
corsOptions,
};

return {
...spec,
// https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-swagger-extensions-request-validators.html
Expand All @@ -516,10 +552,10 @@ export const prepareApiSpec = (
"application/json":
'{"message": "$context.error.validationErrorString"}',
},
...(options.corsOptions
...(corsOptions
? {
responseParameters: generateCorsResponseParameters(
options.corsOptions,
corsOptions,
"gatewayresponse.header"
),
}
Expand All @@ -530,7 +566,7 @@ export const prepareApiSpec = (
...Object.fromEntries(
Object.entries(spec.paths).map(([path, pathDetails]) => [
path,
preparePathSpec(path, pathDetails!, options, getOperationName),
preparePathSpec(path, pathDetails!, updatedOptions, getOperationName),
])
),
},
Expand All @@ -540,13 +576,14 @@ export const prepareApiSpec = (
// Apply any security schemes that already exist in the spec
...spec.components?.securitySchemes,
// Construct security schemes override any in the spec with the same id
...options.securitySchemes,
...updatedOptions.securitySchemes,
},
},
...(options.apiKeyOptions
...(updatedOptions.apiKeyOptions
? {
// https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-swagger-extensions-api-key-source.html
"x-amazon-apigateway-api-key-source": options.apiKeyOptions.source,
"x-amazon-apigateway-api-key-source":
updatedOptions.apiKeyOptions.source,
}
: {}),
} as any;
Expand Down
Loading

0 comments on commit abe46bc

Please sign in to comment.