mirror of
https://github.com/sasjs/server.git
synced 2025-12-10 19:34:34 +00:00
Compare commits
2 Commits
vite-built
...
domain-che
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9ed10109c1 | ||
|
|
ef9cca575f |
@@ -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=<space separated urls, each starting with protocol `http` or `https`>
|
||||
WHITELIST=<space separated urls, each starting with protocol `http` or `https`>
|
||||
|
||||
PROTOCOL=[http|https] default considered as http
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
29
api/src/app-modules/configureDomains.ts
Normal file
29
api/src/app-modules/configureDomains.ts
Normal file
@@ -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<string>()
|
||||
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)
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,9 @@
|
||||
import { Express } from 'express'
|
||||
import { Express, CookieOptions } from 'express'
|
||||
import mongoose from 'mongoose'
|
||||
import session from 'express-session'
|
||||
import MongoStore from 'connect-mongo'
|
||||
|
||||
import { ModeType } from '../utils'
|
||||
import { cookieOptions } from '../app'
|
||||
import { ModeType, ProtocolType } from '../utils'
|
||||
|
||||
export const configureExpressSession = (app: Express) => {
|
||||
const { MODE } = process.env
|
||||
@@ -19,6 +18,15 @@ export const configureExpressSession = (app: Express) => {
|
||||
})
|
||||
}
|
||||
|
||||
const { PROTOCOL } = process.env
|
||||
const cookieOptions: CookieOptions = {
|
||||
secure: PROTOCOL === ProtocolType.HTTPS,
|
||||
httpOnly: true,
|
||||
sameSite: PROTOCOL === ProtocolType.HTTPS ? 'none' : undefined,
|
||||
maxAge: 24 * 60 * 60 * 1000, // 24 hours
|
||||
domain: 'sas.4gl.io'
|
||||
}
|
||||
|
||||
app.use(
|
||||
session({
|
||||
secret: process.secrets.SESSION_SECRET,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
export * from './configureCors'
|
||||
export * from './configureDomains'
|
||||
export * from './configureExpressSession'
|
||||
export * from './configureLogger'
|
||||
export * from './configureSecurity'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import path from 'path'
|
||||
import express, { ErrorRequestHandler, CookieOptions } from 'express'
|
||||
import express, { ErrorRequestHandler } from 'express'
|
||||
import cookieParser from 'cookie-parser'
|
||||
import dotenv from 'dotenv'
|
||||
|
||||
@@ -8,7 +8,6 @@ import {
|
||||
getWebBuildFolder,
|
||||
instantiateLogger,
|
||||
loadAppStreamConfig,
|
||||
ProtocolType,
|
||||
ReturnCode,
|
||||
setProcessVariables,
|
||||
setupFolders,
|
||||
@@ -16,6 +15,7 @@ import {
|
||||
} from './utils'
|
||||
import {
|
||||
configureCors,
|
||||
configureDomains,
|
||||
configureExpressSession,
|
||||
configureLogger,
|
||||
configureSecurity
|
||||
@@ -29,15 +29,6 @@ if (verifyEnvVariables()) process.exit(ReturnCode.InvalidEnv)
|
||||
|
||||
const app = express()
|
||||
|
||||
const { PROTOCOL } = process.env
|
||||
|
||||
export const cookieOptions: CookieOptions = {
|
||||
secure: PROTOCOL === ProtocolType.HTTPS,
|
||||
httpOnly: true,
|
||||
sameSite: PROTOCOL === ProtocolType.HTTPS ? 'none' : undefined,
|
||||
maxAge: 24 * 60 * 60 * 1000 // 24 hours
|
||||
}
|
||||
|
||||
const onError: ErrorRequestHandler = (err, req, res, next) => {
|
||||
console.error(err.stack)
|
||||
res.status(500).send('Something broke!')
|
||||
@@ -58,6 +49,11 @@ export default setProcessVariables().then(async () => {
|
||||
***********************************/
|
||||
configureCors(app)
|
||||
|
||||
/***********************************
|
||||
* Allowed Domains *
|
||||
***********************************/
|
||||
configureDomains(app)
|
||||
|
||||
/***********************************
|
||||
* DB Connection & *
|
||||
* Express Sessions *
|
||||
|
||||
17
api/src/middlewares/checkDomain.ts
Normal file
17
api/src/middlewares/checkDomain.ts
Normal file
@@ -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')
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
export * from './authenticateToken'
|
||||
export * from './authorize'
|
||||
export * from './checkDomain'
|
||||
export * from './csrfProtection'
|
||||
export * from './desktop'
|
||||
export * from './verifyAdmin'
|
||||
|
||||
1
api/src/types/system/process.d.ts
vendored
1
api/src/types/system/process.d.ts
vendored
@@ -12,5 +12,6 @@ declare namespace NodeJS {
|
||||
logger: import('@sasjs/utils/logger').Logger
|
||||
runTimes: import('../../utils').RunTimeType[]
|
||||
secrets: import('../../model/Configuration').ConfigurationType
|
||||
allowedDomains: string[]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"target": "ES6",
|
||||
"module": "commonjs",
|
||||
"rootDir": "./",
|
||||
"outDir": "./build",
|
||||
|
||||
Reference in New Issue
Block a user