From ef9cca575fb03d1e520801fb4bbed42c8eca351b Mon Sep 17 00:00:00 2001 From: Saad Jutt Date: Tue, 4 Oct 2022 23:47:41 +0500 Subject: [PATCH] fix: added domain check if provided --- api/.env.example | 1 + api/src/app-modules/configureCors.ts | 17 +++++++++++---- api/src/app-modules/configureDomains.ts | 29 +++++++++++++++++++++++++ api/src/app-modules/index.ts | 1 + api/src/app.ts | 6 +++++ api/src/middlewares/checkDomain.ts | 17 +++++++++++++++ api/src/middlewares/index.ts | 1 + api/src/types/system/process.d.ts | 1 + api/src/utils/verifyEnvVariables.ts | 2 +- api/tsconfig.json | 2 +- 10 files changed, 71 insertions(+), 6 deletions(-) create mode 100644 api/src/app-modules/configureDomains.ts create mode 100644 api/src/middlewares/checkDomain.ts diff --git a/api/.env.example b/api/.env.example index 7d509f3..bd2b26c 100644 --- a/api/.env.example +++ b/api/.env.example @@ -1,5 +1,6 @@ MODE=[desktop|server] default considered as desktop CORS=[disable|enable] default considered as disable for server MODE & enable for desktop MODE +ALLOWED_DOMAINS= WHITELIST= PROTOCOL=[http|https] default considered as http diff --git a/api/src/app-modules/configureCors.ts b/api/src/app-modules/configureCors.ts index 631b166..cda57f9 100644 --- a/api/src/app-modules/configureCors.ts +++ b/api/src/app-modules/configureCors.ts @@ -3,10 +3,21 @@ import cors from 'cors' import { CorsType } from '../utils' export const configureCors = (app: Express) => { + const { CORS } = process.env + + if (CORS === CorsType.ENABLED) { + const whiteList = getWhiteListed() + + console.log('All CORS Requests are enabled for:', whiteList) + app.use(cors({ credentials: true, origin: whiteList })) + } +} + +export const getWhiteListed = (): string[] => { + const whiteList: string[] = [] const { CORS, WHITELIST } = process.env if (CORS === CorsType.ENABLED) { - const whiteList: string[] = [] WHITELIST?.split(' ') ?.filter((url) => !!url) .forEach((url) => { @@ -14,8 +25,6 @@ export const configureCors = (app: Express) => { // removing trailing slash of URLs listing for CORS whiteList.push(url.replace(/\/$/, '')) }) - - console.log('All CORS Requests are enabled for:', whiteList) - app.use(cors({ credentials: true, origin: whiteList })) } + return whiteList } diff --git a/api/src/app-modules/configureDomains.ts b/api/src/app-modules/configureDomains.ts new file mode 100644 index 0000000..e9b3478 --- /dev/null +++ b/api/src/app-modules/configureDomains.ts @@ -0,0 +1,29 @@ +import { Express } from 'express' +import { checkDomain } from '../middlewares' +import { getWhiteListed } from './configureCors' + +export const configureDomains = (app: Express) => { + // const domains: string[] = [] + const domains = new Set() + const { ALLOWED_DOMAINS } = process.env + + const allowedDomains = ALLOWED_DOMAINS?.trim().split(' ') ?? [] + + const whiteListed = getWhiteListed() + + const combinedUrls = [...allowedDomains, ...whiteListed] + combinedUrls + .filter((domainName) => !!domainName) + .forEach((url) => { + try { + const domain = new URL(url) + domains.add(domain.hostname) + } catch (_) {} + }) + + if (domains.size) { + process.allowedDomains = [...domains] + console.log('Allowed Domain(s):', process.allowedDomains) + app.use(checkDomain) + } +} diff --git a/api/src/app-modules/index.ts b/api/src/app-modules/index.ts index 39d5216..e7b7fea 100644 --- a/api/src/app-modules/index.ts +++ b/api/src/app-modules/index.ts @@ -1,4 +1,5 @@ export * from './configureCors' +export * from './configureDomains' export * from './configureExpressSession' export * from './configureLogger' export * from './configureSecurity' diff --git a/api/src/app.ts b/api/src/app.ts index 366c5ca..32a0634 100644 --- a/api/src/app.ts +++ b/api/src/app.ts @@ -16,6 +16,7 @@ import { } from './utils' import { configureCors, + configureDomains, configureExpressSession, configureLogger, configureSecurity @@ -58,6 +59,11 @@ export default setProcessVariables().then(async () => { ***********************************/ configureCors(app) + /*********************************** + * Allowed Domains * + ***********************************/ + configureDomains(app) + /*********************************** * DB Connection & * * Express Sessions * diff --git a/api/src/middlewares/checkDomain.ts b/api/src/middlewares/checkDomain.ts new file mode 100644 index 0000000..7c5137c --- /dev/null +++ b/api/src/middlewares/checkDomain.ts @@ -0,0 +1,17 @@ +import { RequestHandler } from 'express' + +export const checkDomain: RequestHandler = (req, res, next) => { + const { allowedDomains } = process + + // pass if no allowed domain is specified + if (!allowedDomains.length) return next() + + if (allowedDomains.includes(req.hostname)) return next() + + console.log('allowedDomains', allowedDomains) + console.log('hostname not allowed', req.hostname) + res.writeHead(404, { + 'Content-Type': 'text/plain' + }) + return res.end('Not found') +} diff --git a/api/src/middlewares/index.ts b/api/src/middlewares/index.ts index 209bda6..ecf447e 100644 --- a/api/src/middlewares/index.ts +++ b/api/src/middlewares/index.ts @@ -1,5 +1,6 @@ export * from './authenticateToken' export * from './authorize' +export * from './checkDomain' export * from './csrfProtection' export * from './desktop' export * from './verifyAdmin' diff --git a/api/src/types/system/process.d.ts b/api/src/types/system/process.d.ts index 1c2077d..82bf521 100644 --- a/api/src/types/system/process.d.ts +++ b/api/src/types/system/process.d.ts @@ -12,5 +12,6 @@ declare namespace NodeJS { logger: import('@sasjs/utils/logger').Logger runTimes: import('../../utils').RunTimeType[] secrets: import('../../model/Configuration').ConfigurationType + allowedDomains: string[] } } diff --git a/api/src/utils/verifyEnvVariables.ts b/api/src/utils/verifyEnvVariables.ts index 9c75852..84662ae 100644 --- a/api/src/utils/verifyEnvVariables.ts +++ b/api/src/utils/verifyEnvVariables.ts @@ -252,7 +252,7 @@ const verifyRUN_TIMES = (): string[] => { return errors } -const verifyExecutablePaths = () => { +const verifyExecutablePaths = (): string[] => { const errors: string[] = [] const { RUN_TIMES, SAS_PATH, NODE_PATH, PYTHON_PATH, R_PATH, MODE } = process.env diff --git a/api/tsconfig.json b/api/tsconfig.json index 9e009ed..a18bc91 100644 --- a/api/tsconfig.json +++ b/api/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "target": "es5", + "target": "ES6", "module": "commonjs", "rootDir": "./", "outDir": "./build",