@schibsted/middy-cors
Version:
Middy middleware for adding CORS headers to success response and errors
309 lines (283 loc) • 9.32 kB
JavaScript
const middy = require('@middy/core');
const createError = require('http-errors');
const middleware = require('./index');
test('Does nothing if has no config', async () => {
const handler = middy(async () => ({
statusCode: 200,
body: JSON.stringify({ foo: 'bar' }),
headers: {
someHeader: 'someValue',
},
}));
handler.use(middleware());
const response = await handler({}, {});
expect(response).toEqual({
statusCode: 200,
headers: {
someHeader: 'someValue',
},
body: JSON.stringify({ foo: 'bar' }),
});
});
test('Adds CORS headers on success from disallowed origin', async () => {
const handler = middy(async () => ({
statusCode: 200,
body: JSON.stringify({ foo: 'bar' }),
headers: {
someHeader: 'someValue',
},
}));
handler.use(
middleware({
allowedOrigins: ['https://www.vg.no', 'https://www.tek.no'],
exposeHeaders: ['x-my-header'],
maxAge: 2628000, // 1 month
credentials: true,
allowMethods: ['GET', 'POST'],
allowHeaders: ['Content-Type', 'Accept', 'X-Forwarded-For'],
})
);
const response = await handler(
{
headers: {
origin: 'https://www.google.com',
},
},
{}
);
expect(response).toEqual({
statusCode: 200,
headers: {
'access-control-allow-credentials': true,
'access-control-allow-headers': 'Content-Type, Accept, X-Forwarded-For',
'access-control-allow-methods': 'GET, POST',
'access-control-expose-headers': 'x-my-header',
'access-control-max-age': 2628000,
someHeader: 'someValue',
},
body: JSON.stringify({ foo: 'bar' }),
});
});
test('Adds CORS headers on success from allowed origin', async () => {
const handler = middy(async () => ({
statusCode: 200,
body: JSON.stringify({ foo: 'bar' }),
headers: {
someHeader: 'someValue',
},
}));
handler.use(
middleware({
allowedOrigins: ['https://www.vg.no', 'https://www.tek.no'],
exposeHeaders: ['x-my-header'],
maxAge: 2628000, // 1 month
credentials: true,
allowMethods: ['GET', 'POST'],
allowHeaders: ['Content-Type', 'Accept', 'X-Forwarded-For'],
})
);
const response = await handler(
{
headers: {
origin: 'https://www.tek.no',
},
},
{}
);
expect(response).toEqual({
statusCode: 200,
headers: {
'access-control-allow-credentials': true,
'access-control-allow-headers': 'Content-Type, Accept, X-Forwarded-For',
'access-control-allow-methods': 'GET, POST',
'access-control-allow-origin': 'https://www.tek.no',
'access-control-expose-headers': 'x-my-header',
'access-control-max-age': 2628000,
someHeader: 'someValue',
},
body: JSON.stringify({ foo: 'bar' }),
});
});
test('Adds CORS headers on success when all origins allowed', async () => {
const handler = middy(async () => ({
statusCode: 200,
body: JSON.stringify({ foo: 'bar' }),
headers: {
someHeader: 'someValue',
},
}));
handler.use(
middleware({
allowedOrigins: ['*'],
exposeHeaders: ['x-my-header'],
maxAge: 2628000, // 1 month
credentials: true,
allowMethods: ['GET', 'POST'],
allowHeaders: ['Content-Type', 'Accept', 'X-Forwarded-For'],
})
);
const response = await handler(
{
headers: {
origin: 'https://www.tek.no',
},
},
{}
);
expect(response).toEqual({
statusCode: 200,
headers: {
'access-control-allow-headers': 'Content-Type, Accept, X-Forwarded-For',
'access-control-allow-methods': 'GET, POST',
'access-control-allow-origin': 'https://www.tek.no',
'access-control-expose-headers': 'x-my-header',
'access-control-max-age': 2628000,
someHeader: 'someValue',
},
body: JSON.stringify({ foo: 'bar' }),
});
});
test('Adds CORS headers on error from disallowed origin', async () => {
const handler = middy(async () => {
throw new createError.InternalServerError('whoops');
});
handler.use(
middleware({
allowedOrigins: ['https://www.vg.no', 'https://www.tek.no'],
exposeHeaders: ['x-my-header'],
maxAge: 2628000, // 1 month
credentials: true,
allowMethods: ['GET', 'POST'],
allowHeaders: ['Content-Type', 'Accept', 'X-Forwarded-For'],
})
);
await expect(
handler(
{
headers: {
origin: 'https://www.google.com',
},
},
{}
)
).resolves.toMatchObject({
headers: {
'access-control-allow-credentials': true,
'access-control-allow-headers': 'Content-Type, Accept, X-Forwarded-For',
'access-control-allow-methods': 'GET, POST',
'access-control-expose-headers': 'x-my-header',
'access-control-max-age': 2628000,
},
});
});
test('Adds CORS headers on error from allowed origin', async () => {
const handler = middy(async () => {
throw new createError.InternalServerError('whoops');
});
handler.use(
middleware({
allowedOrigins: ['https://www.vg.no', 'https://www.tek.no'],
exposeHeaders: ['x-my-header'],
maxAge: 2628000, // 1 month
credentials: true,
allowMethods: ['GET', 'POST'],
allowHeaders: ['Content-Type', 'Accept', 'X-Forwarded-For'],
})
);
await expect(
handler(
{
headers: {
origin: 'https://www.tek.no',
},
},
{}
)
).resolves.toMatchObject({
headers: {
'access-control-allow-credentials': true,
'access-control-allow-headers': 'Content-Type, Accept, X-Forwarded-For',
'access-control-allow-methods': 'GET, POST',
'access-control-allow-origin': 'https://www.tek.no',
'access-control-expose-headers': 'x-my-header',
'access-control-max-age': 2628000,
},
});
});
test('Adds CORS headers on error when all origins allowed', async () => {
const handler = middy(async () => {
throw new createError.InternalServerError('whoops');
});
handler.use(
middleware({
allowedOrigins: ['*'],
exposeHeaders: ['x-my-header'],
maxAge: 2628000, // 1 month
credentials: true,
allowMethods: ['GET', 'POST'],
allowHeaders: ['Content-Type', 'Accept', 'X-Forwarded-For'],
})
);
await expect(
handler(
{
headers: {
origin: 'https://www.tek.no',
},
},
{}
)
).resolves.toMatchObject({
headers: {
'access-control-allow-headers': 'Content-Type, Accept, X-Forwarded-For',
'access-control-allow-methods': 'GET, POST',
'access-control-allow-origin': 'https://www.tek.no',
'access-control-expose-headers': 'x-my-header',
'access-control-max-age': 2628000,
},
});
});
test('Keep headers already present in the response on error from disallowed origin', async () => {
const handler = middy(async () => {
throw new createError.InternalServerError('whoops');
});
handler.use(
middleware({
allowedOrigins: ['https://www.vg.no', 'https://www.tek.no'],
exposeHeaders: ['x-my-header'],
maxAge: 2628000, // 1 month
credentials: true,
allowMethods: ['GET', 'POST'],
allowHeaders: ['Content-Type', 'Accept', 'X-Forwarded-For'],
})
);
// eslint-disable-next-line no-shadow
handler.onError(async (handler) => {
// eslint-disable-next-line no-param-reassign
handler.response = {
headers: {
someHeader: 'someValue',
},
};
});
await expect(
handler(
{
headers: {
origin: 'https://www.tek.no',
},
},
{}
)
).resolves.toMatchObject({
headers: {
'access-control-allow-credentials': true,
'access-control-allow-headers': 'Content-Type, Accept, X-Forwarded-For',
'access-control-allow-methods': 'GET, POST',
'access-control-allow-origin': 'https://www.tek.no',
'access-control-expose-headers': 'x-my-header',
'access-control-max-age': 2628000,
someHeader: 'someValue',
},
});
});