mirror of
https://github.com/serverless/serverless.git
synced 2026-01-18 14:58:43 +00:00
Merge pull request #3692 from serverless/fix-cors-origin-config
Fix CORS origin config
This commit is contained in:
commit
050f968fc7
@ -115,8 +115,7 @@ functions:
|
||||
path: hello
|
||||
method: get
|
||||
cors:
|
||||
origins:
|
||||
- '*'
|
||||
origin: '*'
|
||||
headers:
|
||||
- Content-Type
|
||||
- X-Amz-Date
|
||||
|
||||
@ -12,8 +12,14 @@ module.exports = {
|
||||
const corsMethodLogicalId = this.provider.naming
|
||||
.getMethodLogicalId(resourceName, 'options');
|
||||
|
||||
// TODO remove once "origins" config is deprecated
|
||||
let origin = config.origin;
|
||||
if (config.origins && config.origins.length) {
|
||||
origin = config.origins.join(',');
|
||||
}
|
||||
|
||||
const preflightHeaders = {
|
||||
'Access-Control-Allow-Origin': `'${config.origins.join(',')}'`,
|
||||
'Access-Control-Allow-Origin': `'${origin}'`,
|
||||
'Access-Control-Allow-Headers': `'${config.headers.join(',')}'`,
|
||||
'Access-Control-Allow-Methods': `'${config.methods.join(',')}'`,
|
||||
'Access-Control-Allow-Credentials': `'${config.allowCredentials}'`,
|
||||
|
||||
@ -54,13 +54,13 @@ describe('#compileCors()', () => {
|
||||
it('should create preflight method for CORS enabled resource', () => {
|
||||
awsCompileApigEvents.validated.corsPreflight = {
|
||||
'users/update': {
|
||||
origins: ['*'],
|
||||
origin: 'http://example.com',
|
||||
headers: ['*'],
|
||||
methods: ['OPTIONS', 'PUT'],
|
||||
allowCredentials: false,
|
||||
},
|
||||
'users/create': {
|
||||
origins: ['*'],
|
||||
origins: ['*', 'http://example.com'],
|
||||
headers: ['*'],
|
||||
methods: ['OPTIONS', 'POST'],
|
||||
allowCredentials: true,
|
||||
@ -72,19 +72,20 @@ describe('#compileCors()', () => {
|
||||
allowCredentials: false,
|
||||
},
|
||||
'users/any': {
|
||||
origins: ['*'],
|
||||
origins: ['http://example.com'],
|
||||
headers: ['*'],
|
||||
methods: ['OPTIONS', 'ANY'],
|
||||
allowCredentials: false,
|
||||
},
|
||||
};
|
||||
return awsCompileApigEvents.compileCors().then(() => {
|
||||
// users/create
|
||||
expect(
|
||||
awsCompileApigEvents.serverless.service.provider.compiledCloudFormationTemplate
|
||||
.Resources.ApiGatewayMethodUsersCreateOptions
|
||||
.Properties.Integration.IntegrationResponses[0]
|
||||
.ResponseParameters['method.response.header.Access-Control-Allow-Origin']
|
||||
).to.equal('\'*\'');
|
||||
).to.equal('\'*,http://example.com\'');
|
||||
|
||||
expect(
|
||||
awsCompileApigEvents.serverless.service.provider.compiledCloudFormationTemplate
|
||||
@ -107,12 +108,13 @@ describe('#compileCors()', () => {
|
||||
.ResponseParameters['method.response.header.Access-Control-Allow-Credentials']
|
||||
).to.equal('\'true\'');
|
||||
|
||||
// users/update
|
||||
expect(
|
||||
awsCompileApigEvents.serverless.service.provider.compiledCloudFormationTemplate
|
||||
.Resources.ApiGatewayMethodUsersUpdateOptions
|
||||
.Properties.Integration.IntegrationResponses[0]
|
||||
.ResponseParameters['method.response.header.Access-Control-Allow-Origin']
|
||||
).to.equal('\'*\'');
|
||||
).to.equal('\'http://example.com\'');
|
||||
|
||||
expect(
|
||||
awsCompileApigEvents.serverless.service.provider.compiledCloudFormationTemplate
|
||||
@ -128,6 +130,7 @@ describe('#compileCors()', () => {
|
||||
.ResponseParameters['method.response.header.Access-Control-Allow-Credentials']
|
||||
).to.equal('\'false\'');
|
||||
|
||||
// users/delete
|
||||
expect(
|
||||
awsCompileApigEvents.serverless.service.provider.compiledCloudFormationTemplate
|
||||
.Resources.ApiGatewayMethodUsersDeleteOptions
|
||||
@ -156,12 +159,13 @@ describe('#compileCors()', () => {
|
||||
.ResponseParameters['method.response.header.Access-Control-Allow-Credentials']
|
||||
).to.equal('\'false\'');
|
||||
|
||||
// users/any
|
||||
expect(
|
||||
awsCompileApigEvents.serverless.service.provider.compiledCloudFormationTemplate
|
||||
.Resources.ApiGatewayMethodUsersAnyOptions
|
||||
.Properties.Integration.IntegrationResponses[0]
|
||||
.ResponseParameters['method.response.header.Access-Control-Allow-Origin']
|
||||
).to.equal('\'*\'');
|
||||
).to.equal('\'http://example.com\'');
|
||||
|
||||
expect(
|
||||
awsCompileApigEvents.serverless.service.provider.compiledCloudFormationTemplate
|
||||
|
||||
@ -592,7 +592,7 @@ describe('#compileMethods()', () => {
|
||||
method: 'post',
|
||||
integration: 'AWS',
|
||||
cors: {
|
||||
origins: ['*'],
|
||||
origin: 'http://example.com',
|
||||
},
|
||||
response: {
|
||||
statusCodes: {
|
||||
@ -638,13 +638,12 @@ describe('#compileMethods()', () => {
|
||||
},
|
||||
];
|
||||
return awsCompileApigEvents.compileMethods().then(() => {
|
||||
// Check origin.
|
||||
expect(
|
||||
awsCompileApigEvents.serverless.service.provider.compiledCloudFormationTemplate
|
||||
.Resources.ApiGatewayMethodUsersCreatePost.Properties
|
||||
.Integration.IntegrationResponses[0]
|
||||
.ResponseParameters['method.response.header.Access-Control-Allow-Origin']
|
||||
).to.equal('\'*\'');
|
||||
).to.equal('\'http://example.com\'');
|
||||
|
||||
// CORS not enabled!
|
||||
expect(
|
||||
|
||||
@ -102,8 +102,14 @@ module.exports = {
|
||||
const integrationResponseHeaders = [];
|
||||
|
||||
if (http.cors) {
|
||||
// TODO remove once "origins" config is deprecated
|
||||
let origin = http.cors.origin;
|
||||
if (http.cors.origins && http.cors.origins.length) {
|
||||
origin = http.cors.origins.join(',');
|
||||
}
|
||||
|
||||
_.merge(integrationResponseHeaders, {
|
||||
'Access-Control-Allow-Origin': `'${http.cors.origins.join(',')}'`,
|
||||
'Access-Control-Allow-Origin': `'${origin}'`,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -12,8 +12,14 @@ module.exports = {
|
||||
const methodResponseHeaders = [];
|
||||
|
||||
if (http.cors) {
|
||||
// TODO remove once "origins" config is deprecated
|
||||
let origin = http.cors.origin;
|
||||
if (http.cors.origins && http.cors.origins.length) {
|
||||
origin = http.cors.origins.join(',');
|
||||
}
|
||||
|
||||
_.merge(methodResponseHeaders, {
|
||||
'Access-Control-Allow-Origin': `'${http.cors.origins.join(',')}'`,
|
||||
'Access-Control-Allow-Origin': `'${origin}'`,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -58,6 +58,7 @@ module.exports = {
|
||||
cors.headers = _.union(http.cors.headers, cors.headers);
|
||||
cors.methods = _.union(http.cors.methods, cors.methods);
|
||||
cors.origins = _.union(http.cors.origins, cors.origins);
|
||||
cors.origin = http.cors.origin || '*';
|
||||
cors.allowCredentials = cors.allowCredentials || http.cors.allowCredentials;
|
||||
|
||||
corsPreflight[http.path] = cors;
|
||||
@ -274,6 +275,7 @@ module.exports = {
|
||||
|
||||
let cors = {
|
||||
origins: ['*'],
|
||||
origin: '*',
|
||||
methods: ['OPTIONS'],
|
||||
headers,
|
||||
allowCredentials: false,
|
||||
@ -284,6 +286,15 @@ module.exports = {
|
||||
cors.methods = cors.methods || [];
|
||||
cors.allowCredentials = Boolean(cors.allowCredentials);
|
||||
|
||||
if (cors.origins && cors.origin) {
|
||||
const errorMessage = [
|
||||
'You can only use "origin" or "origins",',
|
||||
' but not both at the same time to configure CORS.',
|
||||
' Please check the docs for more info.',
|
||||
].join('');
|
||||
throw new this.serverless.classes.Error(errorMessage);
|
||||
}
|
||||
|
||||
if (cors.headers) {
|
||||
if (!Array.isArray(cors.headers)) {
|
||||
const errorMessage = [
|
||||
|
||||
@ -415,6 +415,28 @@ describe('#validate()', () => {
|
||||
expect(authorizer.identityValidationExpression).to.equal('foo');
|
||||
});
|
||||
|
||||
it('should throw an error if "origin" and "origins" CORS config is used', () => {
|
||||
awsCompileApigEvents.serverless.service.functions = {
|
||||
first: {
|
||||
events: [
|
||||
{
|
||||
http: {
|
||||
method: 'POST',
|
||||
path: '/foo/bar',
|
||||
cors: {
|
||||
origin: '*',
|
||||
origins: ['*'],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
expect(() => awsCompileApigEvents.validate())
|
||||
.to.throw(Error, 'can only use');
|
||||
});
|
||||
|
||||
it('should process cors defaults', () => {
|
||||
awsCompileApigEvents.serverless.service.functions = {
|
||||
first: {
|
||||
@ -436,6 +458,7 @@ describe('#validate()', () => {
|
||||
headers: ['Content-Type', 'X-Amz-Date', 'Authorization', 'X-Api-Key',
|
||||
'X-Amz-Security-Token', 'X-Amz-User-Agent'],
|
||||
methods: ['OPTIONS', 'POST'],
|
||||
origin: '*',
|
||||
origins: ['*'],
|
||||
allowCredentials: false,
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user