Skip to content

Commit 8480abf

Browse files
committed
generalize cors policy
1 parent d26e7c0 commit 8480abf

File tree

3 files changed

+15
-15
lines changed

3 files changed

+15
-15
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ to format all typescript files.
5353
| `MSAL_CLIENT_ID` | The client id for the web api from Azure. | |
5454
| `MSAL_TENANT_ID` | The Tenant ID from your Azure instance | |
5555
| `APP_NAME` | The name of the app. Used for the cookie name prefix `{APP_NAME}ApiKey` | `xyzTeaching`, default: `twa` |
56-
| `WITH_DEPLOY_PREVIEW` | When set to `true`, the app will allow requests from `https://deploy-preview-\d+--teaching-dev.netlify.app` and use `sameSite=none` instead of strict. | |
56+
| `NETLIFY_PROJECT_NAME` | When set to the netlify project name (e.g. `teaching-dev`), the app will allow requests from `https://deploy-preview-\d+--teaching-dev.netlify.app` and use `sameSite=none` instead of strict. | |
5757
| `ADMIN_USER_GROUP_ID` | The UUID of the group that should be used as the admin group. For this group a RW-Permission will be always added to a newly created document root when it's access is not RW | default: "" |
5858
| `GITHUB_CLIENT_SECRET` | Used for the CMS to work properly. Register an app under https://github.com/settings/apps. | |
5959
| `GITHUB_CLIENT_ID` | | |

src/app.ts

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,14 @@ const app = express();
2929
export const API_VERSION = 'v1';
3030
export const API_URL = `/api/${API_VERSION}`;
3131

32+
33+
const HOSTNAME = new URL(process.env.FRONTEND_URL || 'http://localhost:3000').hostname;
34+
const domainParts = HOSTNAME.split('.');
35+
const domain = domainParts.slice(domainParts.length - 2).join('.'); /** foo.bar.ch --> domain is bar.ch */
36+
const CORS_APP = new RegExp(`https://(.*\.)?${domain.split('.')[0]}\.${domain.split('.')[1] || ':3000'}$`, 'i')
37+
const CORS_NETLIFY = process.env.NETLIFY_PROJECT_NAME ? new RegExp(`https://deploy-preview-\\d+--${process.env.NETLIFY_PROJECT_NAME}\\.netlify\\.app$`, 'i') : undefined;
38+
export const CORS_ORIGIN = [HOSTNAME, CORS_APP, CORS_NETLIFY].filter(rule => !!rule) as (string | RegExp)[];
39+
3240
/**
3341
* this is not needed when running behind a reverse proxy
3442
* as is the case with dokku (nginx)
@@ -39,10 +47,9 @@ export const API_URL = `/api/${API_VERSION}`;
3947
app.use(
4048
cors({
4149
credentials: true,
42-
origin: process.env.WITH_DEPLOY_PREVIEW
43-
? [process.env.FRONTEND_URL || true, /https:\/\/deploy-preview-\d+--teaching-dev.netlify.app/]
44-
: process.env.FRONTEND_URL || true /* true = strict origin */,
45-
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'HEAD']
50+
origin: CORS_ORIGIN,
51+
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'HEAD'],
52+
4653
})
4754
);
4855

@@ -56,10 +63,6 @@ const store = new (connectPgSimple(session))({
5663
tableName: 'sessions'
5764
});
5865

59-
const HOSTNAME = new URL(process.env.FRONTEND_URL || 'http://localhost:3000').hostname;
60-
const domainParts = HOSTNAME.split('.');
61-
const domain = domainParts.slice(domainParts.length - 2).join('.'); /** foo.bar.ch --> domain is bar.ch */
62-
6366
const SESSION_MAX_AGE = 2592000000 as const; // 1000 * 60 * 60 * 24 * 30 = 2592000000 = 30 days
6467

6568
/** make sure to have 1 (reverse) proxy in front of the application
@@ -80,7 +83,7 @@ export const sessionMiddleware = session({
8083
cookie: {
8184
secure: process.env.NODE_ENV === 'production',
8285
httpOnly: true,
83-
sameSite: process.env.WITH_DEPLOY_PREVIEW ? 'none' : 'strict',
86+
sameSite: process.env.NETLIFY_PROJECT_NAME ? 'none' : 'strict',
8487
domain: domain.length > 0 ? domain : undefined,
8588
maxAge: SESSION_MAX_AGE // 30 days
8689
}

src/server.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import app, { configure, sessionMiddleware } from './app';
1+
import app, { configure, CORS_ORIGIN, sessionMiddleware } from './app';
22
import http from 'http';
33
import Logger from './utils/logger';
44
import { Server } from 'socket.io';
@@ -12,13 +12,10 @@ import { HTTP403Error } from './utils/errors/Errors';
1212
const PORT = process.env.PORT || 3002;
1313

1414
const server = http.createServer(app);
15-
const corsOrigin = process.env.WITH_DEPLOY_PREVIEW
16-
? [process.env.FRONTEND_URL || true, /https:\/\/deploy-preview-\d+--teaching-dev.netlify.app/]
17-
: process.env.FRONTEND_URL || true; /* true = strict origin */
1815

1916
const io = new Server<ClientToServerEvents, ServerToClientEvents>(server, {
2017
cors: {
21-
origin: corsOrigin,
18+
origin: CORS_ORIGIN,
2219
credentials: true,
2320
methods: ['GET', 'POST', 'PUT', 'DELETE']
2421
},

0 commit comments

Comments
 (0)