mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
feat: Make CorsHandler customizable.
This commit is contained in:
parent
d6c0f89cf5
commit
8dec921c10
@ -6,7 +6,16 @@
|
|||||||
"@type": "AllVoidCompositeHandler",
|
"@type": "AllVoidCompositeHandler",
|
||||||
"AllVoidCompositeHandler:_handlers": [
|
"AllVoidCompositeHandler:_handlers": [
|
||||||
{
|
{
|
||||||
"@type": "CorsHandler"
|
"@type": "CorsHandler",
|
||||||
|
"CorsHandler:_options_methods": [
|
||||||
|
"GET",
|
||||||
|
"HEAD",
|
||||||
|
"OPTIONS",
|
||||||
|
"POST",
|
||||||
|
"PUT",
|
||||||
|
"PATCH",
|
||||||
|
"DELETE"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"@type": "HeaderHandler",
|
"@type": "HeaderHandler",
|
||||||
|
@ -1,21 +1,35 @@
|
|||||||
import cors from 'cors';
|
import cors from 'cors';
|
||||||
|
import type { CorsOptions } from 'cors';
|
||||||
import type { RequestHandler } from 'express';
|
import type { RequestHandler } from 'express';
|
||||||
import { HttpHandler } from '../HttpHandler';
|
import { HttpHandler } from '../HttpHandler';
|
||||||
import type { HttpRequest } from '../HttpRequest';
|
import type { HttpRequest } from '../HttpRequest';
|
||||||
import type { HttpResponse } from '../HttpResponse';
|
import type { HttpResponse } from '../HttpResponse';
|
||||||
|
|
||||||
|
const defaultOptions: CorsOptions = {
|
||||||
|
origin: (origin: any, callback: any): void => callback(null, origin ?? '*'),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Components.js does not support the full CorsOptions yet
|
||||||
|
interface SimpleCorsOptions {
|
||||||
|
origin?: string;
|
||||||
|
methods?: string[];
|
||||||
|
allowedHeaders?: string[];
|
||||||
|
exposedHeaders?: string[];
|
||||||
|
credentials?: boolean;
|
||||||
|
maxAge?: number;
|
||||||
|
preflightContinue?: boolean;
|
||||||
|
optionsSuccessStatus?: number;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handler that sets CORS options on the response.
|
* Handler that sets CORS options on the response.
|
||||||
*/
|
*/
|
||||||
export class CorsHandler extends HttpHandler {
|
export class CorsHandler extends HttpHandler {
|
||||||
private readonly corsHandler: RequestHandler;
|
private readonly corsHandler: RequestHandler;
|
||||||
|
|
||||||
public constructor() {
|
public constructor(options: SimpleCorsOptions = {}) {
|
||||||
super();
|
super();
|
||||||
this.corsHandler = cors({
|
this.corsHandler = cors({ ...defaultOptions, ...options });
|
||||||
origin: (origin, callback): void => callback(null, (origin ?? '*') as any),
|
|
||||||
methods: [ 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT', 'PATCH', 'DELETE' ],
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async handle(input: { request: HttpRequest; response: HttpResponse }): Promise<void> {
|
public async handle(input: { request: HttpRequest; response: HttpResponse }): Promise<void> {
|
||||||
|
@ -3,22 +3,21 @@ import { CorsHandler } from '../../../../src/server/middleware/CorsHandler';
|
|||||||
import { guardStream } from '../../../../src/util/GuardedStream';
|
import { guardStream } from '../../../../src/util/GuardedStream';
|
||||||
|
|
||||||
describe('a CorsHandler', (): void => {
|
describe('a CorsHandler', (): void => {
|
||||||
let handler: CorsHandler;
|
it('sets regular CORS headers.', async(): Promise<void> => {
|
||||||
|
const handler = new CorsHandler();
|
||||||
|
|
||||||
beforeAll(async(): Promise<void> => {
|
|
||||||
handler = new CorsHandler();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('returns CORS headers.', async(): Promise<void> => {
|
|
||||||
const request = guardStream(createRequest());
|
const request = guardStream(createRequest());
|
||||||
const response = createResponse();
|
const response = createResponse();
|
||||||
await handler.handleSafe({ request, response });
|
await handler.handleSafe({ request, response });
|
||||||
|
|
||||||
expect(response.getHeaders()).toEqual(expect.objectContaining({
|
expect(response.getHeaders()).toEqual(expect.objectContaining({
|
||||||
'access-control-allow-origin': '*',
|
'access-control-allow-origin': '*',
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('echoes the origin when specified.', async(): Promise<void> => {
|
it('echoes the origin when specified.', async(): Promise<void> => {
|
||||||
|
const handler = new CorsHandler();
|
||||||
|
|
||||||
const request = guardStream(createRequest({
|
const request = guardStream(createRequest({
|
||||||
headers: {
|
headers: {
|
||||||
origin: 'example.org',
|
origin: 'example.org',
|
||||||
@ -26,8 +25,23 @@ describe('a CorsHandler', (): void => {
|
|||||||
}));
|
}));
|
||||||
const response = createResponse();
|
const response = createResponse();
|
||||||
await handler.handleSafe({ request, response });
|
await handler.handleSafe({ request, response });
|
||||||
|
|
||||||
expect(response.getHeaders()).toEqual(expect.objectContaining({
|
expect(response.getHeaders()).toEqual(expect.objectContaining({
|
||||||
'access-control-allow-origin': 'example.org',
|
'access-control-allow-origin': 'example.org',
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('supports customizations.', async(): Promise<void> => {
|
||||||
|
const handler = new CorsHandler({
|
||||||
|
exposedHeaders: [ 'Custom-Header' ],
|
||||||
|
});
|
||||||
|
|
||||||
|
const request = guardStream(createRequest());
|
||||||
|
const response = createResponse();
|
||||||
|
await handler.handleSafe({ request, response });
|
||||||
|
|
||||||
|
expect(response.getHeaders()).toEqual(expect.objectContaining({
|
||||||
|
'access-control-expose-headers': 'Custom-Header',
|
||||||
|
}));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user