liefern
Version:
Node Webserver without dependencies
107 lines • 4.39 kB
JavaScript
import { HeaderFields } from './utils/constants.js';
import { forbidden, methodNotAllow, ok } from './utils/sendHelper.js';
export const cors = (config) => {
return ({ response, request }) => {
handlePreFlight(config, request, response);
if (response.writableEnded) {
return;
}
if (config.origin &&
config.origin !== '*' &&
(!request.headers.host || !config.origin.includes(request.headers.host))) {
return forbidden(response);
}
if (config.allowMethods !== '*' &&
!config.allowMethods
.map((method) => method.toLowerCase())
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
.includes(request.method.toLowerCase())) {
return methodNotAllow(response);
}
// handle "credentials"
if (config.credentials) {
response.setHeader(HeaderFields.AccessControlAllowCredentials, 'true');
}
// handle "credentials"
if (config.secureContext) {
response.setHeader(HeaderFields.CrossOriginOpenerPolicy, 'same-origin');
response.setHeader(HeaderFields.CrossOriginEmbedderPolicy, 'require-corp');
}
};
};
const handlePreFlight = (config, request, response) => {
// console.log('request headers', request.headers)
// console.log('config', config)
const requestMethod = request.method?.toLowerCase();
const requestHeaderOrigin = request.headers.origin;
const requestHeaderRequestMethod = request.headers['access-control-request-method']?.toLowerCase();
const requestHeaderRequestHeaders = request.headers['access-control-request-headers']?.toLowerCase();
const isPreFlight = requestMethod === 'options' &&
!!requestHeaderOrigin &&
!!requestHeaderRequestMethod; // && !!requestHeaderRequestHeaders
if (!isPreFlight) {
return;
}
// console.log(config.origin, request.headers)
if (!config.origin ||
config.origin === '*' ||
config.origin.includes(requestHeaderOrigin)) {
response.setHeader(HeaderFields.AccessControlAllowOrigin, requestHeaderOrigin);
}
else {
return forbidden(response);
}
//
if (!config.allowMethods) {
response.setHeader(HeaderFields.AccessControlAllowMethods, '*');
}
else if (config.allowMethods === '*') {
response.setHeader(HeaderFields.AccessControlAllowMethods, '*');
}
else {
const lowerCaseList = config.allowMethods.map((method) => method.toLowerCase());
if (lowerCaseList.includes(requestHeaderRequestMethod)) {
response.setHeader(HeaderFields.AccessControlAllowMethods, config.allowMethods.join(', '));
}
else {
return forbidden(response);
}
}
if (requestHeaderRequestHeaders) {
if (!config.allowHeaders) {
response.setHeader(HeaderFields.AccessControlAllowHeaders, '*');
}
else if (config.allowHeaders === '*') {
response.setHeader(HeaderFields.AccessControlAllowHeaders, '*');
}
else {
response.setHeader(HeaderFields.AccessControlAllowHeaders, config.allowHeaders.join(', '));
}
}
// handle "exposeHeaders"
if (config.exposeHeaders) {
response.setHeader(HeaderFields.AccessControlExposeHeaders, config.exposeHeaders.join(', '));
}
// handle "allowHeaders"
if (request.headers[HeaderFields.AccessControlRequestHeaders.toLowerCase()] ||
config.allowHeaders) {
response.setHeader(HeaderFields.AccessControlAllowHeaders, !config.allowHeaders || config.allowHeaders === '*'
? '*'
: config.allowHeaders.join(', '));
}
// handle "maxAge"
if (config.maxAge) {
response.setHeader(HeaderFields.AccessControlMaxAge, config.maxAge);
}
// handle "credentials"
if (config.credentials) {
response.setHeader(HeaderFields.AccessControlAllowCredentials, 'true');
}
// handle "privateNetworkAccess"
if (config.privateNetworkAccess &&
request.headers[HeaderFields.AccessControlRequestPrivateNetwork.toLowerCase()]) {
response.setHeader(HeaderFields.AccessControlAllowPrivateNetwork, 'true');
}
return ok(response);
};
//# sourceMappingURL=handleCORS.js.map