Skip to content

Commit

Permalink
implements cors middleware
Browse files Browse the repository at this point in the history
  • Loading branch information
ggazzo committed Jan 22, 2025
1 parent ecab398 commit e241850
Showing 1 changed file with 55 additions and 10 deletions.
65 changes: 55 additions & 10 deletions apps/meteor/app/api/server/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Users } from '@rocket.chat/models';
import { Random } from '@rocket.chat/random';
import type { JoinPathPattern, Method } from '@rocket.chat/rest-typings';
import { tracerSpan } from '@rocket.chat/tracing';
import type express from 'express';
import { Accounts } from 'meteor/accounts-base';
import { DDP } from 'meteor/ddp';
import { DDPCommon } from 'meteor/ddp-common';
Expand All @@ -12,6 +13,7 @@ import type { RateLimiterOptionsToCheck } from 'meteor/rate-limit';
import { RateLimiter } from 'meteor/rate-limit';
import type { Request, Response } from 'meteor/rocketchat:restivus';
import { Restivus } from 'meteor/rocketchat:restivus';
import { WebApp } from 'meteor/webapp';
import semver from 'semver';
import _ from 'underscore';

Expand Down Expand Up @@ -1123,16 +1125,6 @@ export const API: {
default: createApi(),
};

// register the API to be re-created once the CORS-setting changes.
// settings.watchMultiple(['API_Enable_CORS', 'API_CORS_Origin'], () => {
// API.v1 = createApi({
// version: 'v1',
// apiPath: '',
// });

// API.default = createApi();
// });

settings.watch<string>('Accounts_CustomFields', (value) => {
if (!value) {
return API.v1?.setLimitedCustomFields([]);
Expand All @@ -1159,3 +1151,56 @@ settings.watch<number>('API_Enable_Rate_Limiter_Limit_Calls_Default', (value) =>
settings.watch<boolean>('Prometheus_API_User_Agent', (value) => {
prometheusAPIUserAgent = value;
});

Meteor.startup(() => {
const rootRouter = new Router('/')
.use((_req, res, next) => {
res.removeHeader('X-Powered-By');
next();
})
.use(
API.api
.use((req, res, next) => {
if (!settings.get('API_Enable_CORS')) {
return next();
}

if (!req.headers['access-control-request-method'] && !req.headers.origin) {
return next();
}

const CORSOriginSetting = String(settings.get('API_CORS_Origin'));

const defaultHeaders = {
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, HEAD, PATCH',
'Access-Control-Allow-Headers':
'Origin, X-Requested-With, Content-Type, Accept, X-User-Id, X-Auth-Token, x-visitor-token, Authorization',
};

if (CORSOriginSetting === '*') {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', defaultHeaders['Access-Control-Allow-Methods']);
res.setHeader('Access-Control-Allow-Headers', defaultHeaders['Access-Control-Allow-Headers']);
return next();
}

const origins = CORSOriginSetting.trim()
.split(',')
.map((origin) => String(origin).trim().toLocaleLowerCase());

if (!origins.includes(req.headers.origin?.toLocaleLowerCase() || '')) {
res.writeHead(403, 'Forbidden');
return res.end();
}

res.setHeader('Access-Control-Allow-Origin', req.headers.origin ?? '*');
res.setHeader('Access-Control-Allow-Methods', defaultHeaders['Access-Control-Allow-Methods']);
res.setHeader('Access-Control-Allow-Headers', defaultHeaders['Access-Control-Allow-Headers']);
return next();
})
.use(API.v1.router),
)
.use(API.default.router).router;

(WebApp.connectHandlers as ReturnType<typeof express>).use(rootRouter);
});

0 comments on commit e241850

Please sign in to comment.