mirror of
https://github.com/sasjs/server.git
synced 2025-12-13 12:24:36 +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
|
MODE=[desktop|server] default considered as desktop
|
||||||
CORS=[disable|enable] default considered as disable for server MODE & enable for desktop MODE
|
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`>
|
WHITELIST=<space separated urls, each starting with protocol `http` or `https`>
|
||||||
|
|
||||||
PROTOCOL=[http|https] default considered as http
|
PROTOCOL=[http|https] default considered as http
|
||||||
|
|||||||
@@ -3,10 +3,21 @@ import cors from 'cors'
|
|||||||
import { CorsType } from '../utils'
|
import { CorsType } from '../utils'
|
||||||
|
|
||||||
export const configureCors = (app: Express) => {
|
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
|
const { CORS, WHITELIST } = process.env
|
||||||
|
|
||||||
if (CORS === CorsType.ENABLED) {
|
if (CORS === CorsType.ENABLED) {
|
||||||
const whiteList: string[] = []
|
|
||||||
WHITELIST?.split(' ')
|
WHITELIST?.split(' ')
|
||||||
?.filter((url) => !!url)
|
?.filter((url) => !!url)
|
||||||
.forEach((url) => {
|
.forEach((url) => {
|
||||||
@@ -14,8 +25,6 @@ export const configureCors = (app: Express) => {
|
|||||||
// removing trailing slash of URLs listing for CORS
|
// removing trailing slash of URLs listing for CORS
|
||||||
whiteList.push(url.replace(/\/$/, ''))
|
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 mongoose from 'mongoose'
|
||||||
import session from 'express-session'
|
import session from 'express-session'
|
||||||
import MongoStore from 'connect-mongo'
|
import MongoStore from 'connect-mongo'
|
||||||
|
|
||||||
import { ModeType } from '../utils'
|
import { ModeType, ProtocolType } from '../utils'
|
||||||
import { cookieOptions } from '../app'
|
|
||||||
|
|
||||||
export const configureExpressSession = (app: Express) => {
|
export const configureExpressSession = (app: Express) => {
|
||||||
const { MODE } = process.env
|
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(
|
app.use(
|
||||||
session({
|
session({
|
||||||
secret: process.secrets.SESSION_SECRET,
|
secret: process.secrets.SESSION_SECRET,
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
export * from './configureCors'
|
export * from './configureCors'
|
||||||
|
export * from './configureDomains'
|
||||||
export * from './configureExpressSession'
|
export * from './configureExpressSession'
|
||||||
export * from './configureLogger'
|
export * from './configureLogger'
|
||||||
export * from './configureSecurity'
|
export * from './configureSecurity'
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import path from 'path'
|
import path from 'path'
|
||||||
import express, { ErrorRequestHandler, CookieOptions } from 'express'
|
import express, { ErrorRequestHandler } from 'express'
|
||||||
import cookieParser from 'cookie-parser'
|
import cookieParser from 'cookie-parser'
|
||||||
import dotenv from 'dotenv'
|
import dotenv from 'dotenv'
|
||||||
|
|
||||||
@@ -8,7 +8,6 @@ import {
|
|||||||
getWebBuildFolder,
|
getWebBuildFolder,
|
||||||
instantiateLogger,
|
instantiateLogger,
|
||||||
loadAppStreamConfig,
|
loadAppStreamConfig,
|
||||||
ProtocolType,
|
|
||||||
ReturnCode,
|
ReturnCode,
|
||||||
setProcessVariables,
|
setProcessVariables,
|
||||||
setupFolders,
|
setupFolders,
|
||||||
@@ -16,6 +15,7 @@ import {
|
|||||||
} from './utils'
|
} from './utils'
|
||||||
import {
|
import {
|
||||||
configureCors,
|
configureCors,
|
||||||
|
configureDomains,
|
||||||
configureExpressSession,
|
configureExpressSession,
|
||||||
configureLogger,
|
configureLogger,
|
||||||
configureSecurity
|
configureSecurity
|
||||||
@@ -29,15 +29,6 @@ if (verifyEnvVariables()) process.exit(ReturnCode.InvalidEnv)
|
|||||||
|
|
||||||
const app = express()
|
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) => {
|
const onError: ErrorRequestHandler = (err, req, res, next) => {
|
||||||
console.error(err.stack)
|
console.error(err.stack)
|
||||||
res.status(500).send('Something broke!')
|
res.status(500).send('Something broke!')
|
||||||
@@ -58,6 +49,11 @@ export default setProcessVariables().then(async () => {
|
|||||||
***********************************/
|
***********************************/
|
||||||
configureCors(app)
|
configureCors(app)
|
||||||
|
|
||||||
|
/***********************************
|
||||||
|
* Allowed Domains *
|
||||||
|
***********************************/
|
||||||
|
configureDomains(app)
|
||||||
|
|
||||||
/***********************************
|
/***********************************
|
||||||
* DB Connection & *
|
* DB Connection & *
|
||||||
* Express Sessions *
|
* 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 './authenticateToken'
|
||||||
export * from './authorize'
|
export * from './authorize'
|
||||||
|
export * from './checkDomain'
|
||||||
export * from './csrfProtection'
|
export * from './csrfProtection'
|
||||||
export * from './desktop'
|
export * from './desktop'
|
||||||
export * from './verifyAdmin'
|
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
|
logger: import('@sasjs/utils/logger').Logger
|
||||||
runTimes: import('../../utils').RunTimeType[]
|
runTimes: import('../../utils').RunTimeType[]
|
||||||
secrets: import('../../model/Configuration').ConfigurationType
|
secrets: import('../../model/Configuration').ConfigurationType
|
||||||
|
allowedDomains: string[]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -252,7 +252,7 @@ const verifyRUN_TIMES = (): string[] => {
|
|||||||
return errors
|
return errors
|
||||||
}
|
}
|
||||||
|
|
||||||
const verifyExecutablePaths = () => {
|
const verifyExecutablePaths = (): string[] => {
|
||||||
const errors: string[] = []
|
const errors: string[] = []
|
||||||
const { RUN_TIMES, SAS_PATH, NODE_PATH, PYTHON_PATH, R_PATH, MODE } =
|
const { RUN_TIMES, SAS_PATH, NODE_PATH, PYTHON_PATH, R_PATH, MODE } =
|
||||||
process.env
|
process.env
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "es5",
|
"target": "ES6",
|
||||||
"module": "commonjs",
|
"module": "commonjs",
|
||||||
"rootDir": "./",
|
"rootDir": "./",
|
||||||
"outDir": "./build",
|
"outDir": "./build",
|
||||||
|
|||||||
Reference in New Issue
Block a user