mirror of
https://github.com/sasjs/server.git
synced 2025-12-10 19:34:34 +00:00
Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c4212665c8 | ||
|
|
97d9bc191c | ||
|
|
dd2a403985 | ||
|
|
7cfa2398e1 | ||
|
|
45a2a01532 | ||
|
|
c61fec47c4 | ||
| 24d7f00c02 | |||
| b0fdaaaa79 | |||
|
|
2467616296 | ||
|
|
ceefbe48e9 | ||
|
|
426e90471e | ||
|
|
c0b57b9e76 | ||
|
|
4a8e32dd20 | ||
|
|
636301e664 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -11,3 +11,4 @@ sasjscore/
|
|||||||
certificates/
|
certificates/
|
||||||
executables/
|
executables/
|
||||||
.env
|
.env
|
||||||
|
api/csp.config.json
|
||||||
|
|||||||
25
CHANGELOG.md
25
CHANGELOG.md
@@ -2,6 +2,31 @@
|
|||||||
|
|
||||||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
||||||
|
|
||||||
|
### [0.0.74](https://github.com/sasjs/server/compare/v0.0.73...v0.0.74) (2022-05-12)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* csp updates ([7cfa239](https://github.com/sasjs/server/commit/7cfa2398e12c5e515d27c896f36ff91604c2124d))
|
||||||
|
|
||||||
|
### [0.0.73](https://github.com/sasjs/server/compare/v0.0.72...v0.0.73) (2022-05-10)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* helmet config on http mode ([b0fdaaa](https://github.com/sasjs/server/commit/b0fdaaaa79e3135699c51effac0388d8ec5ab23b))
|
||||||
|
|
||||||
|
### [0.0.72](https://github.com/sasjs/server/compare/v0.0.71...v0.0.72) (2022-05-09)
|
||||||
|
|
||||||
|
### [0.0.71](https://github.com/sasjs/server/compare/v0.0.70...v0.0.71) (2022-05-07)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* added more cookies to req ([4a8e32d](https://github.com/sasjs/server/commit/4a8e32dd20b540b6dc92d749fad90d6c7fc69376))
|
||||||
|
* bumping core ([c0b57b9](https://github.com/sasjs/server/commit/c0b57b9e76d6db33fc64a68556a8be979dd69e40))
|
||||||
|
* reqHeadrs.txt will contain headers to access APIs ([636301e](https://github.com/sasjs/server/commit/636301e664416fb085f704d83deb7f39ee0a91a7))
|
||||||
|
|
||||||
### [0.0.70](https://github.com/sasjs/server/compare/v0.0.69...v0.0.70) (2022-05-06)
|
### [0.0.70](https://github.com/sasjs/server/compare/v0.0.69...v0.0.70) (2022-05-06)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ HELMET_COEP=
|
|||||||
#
|
#
|
||||||
# Example config:
|
# Example config:
|
||||||
# {
|
# {
|
||||||
# "img-src": ["'self'", "domain.com"],
|
# "img-src": ["'self'", "data:"],
|
||||||
# "script-src": ["'self'", "'unsafe-inline'"],
|
# "script-src": ["'self'", "'unsafe-inline'"],
|
||||||
# "script-src-attr": ["'self'", "'unsafe-inline'"]
|
# "script-src-attr": ["'self'", "'unsafe-inline'"]
|
||||||
# }
|
# }
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"img-src": ["'self'", "domen.com"],
|
"img-src": ["'self'", "data:"],
|
||||||
"script-src": ["'self'", "'unsafe-inline'"],
|
"script-src": ["'self'", "'unsafe-inline'"],
|
||||||
"script-src-attr": ["'self'", "'unsafe-inline'"]
|
"script-src-attr": ["'self'", "'unsafe-inline'"]
|
||||||
}
|
}
|
||||||
14
api/package-lock.json
generated
14
api/package-lock.json
generated
@@ -8,7 +8,7 @@
|
|||||||
"name": "api",
|
"name": "api",
|
||||||
"version": "0.0.2",
|
"version": "0.0.2",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sasjs/core": "^4.19.0",
|
"@sasjs/core": "^4.23.1",
|
||||||
"@sasjs/utils": "2.42.1",
|
"@sasjs/utils": "2.42.1",
|
||||||
"bcryptjs": "^2.4.3",
|
"bcryptjs": "^2.4.3",
|
||||||
"connect-mongo": "^4.6.0",
|
"connect-mongo": "^4.6.0",
|
||||||
@@ -1385,9 +1385,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@sasjs/core": {
|
"node_modules/@sasjs/core": {
|
||||||
"version": "4.19.0",
|
"version": "4.23.1",
|
||||||
"resolved": "https://registry.npmjs.org/@sasjs/core/-/core-4.19.0.tgz",
|
"resolved": "https://registry.npmjs.org/@sasjs/core/-/core-4.23.1.tgz",
|
||||||
"integrity": "sha512-vG2YHJveQUQqN0YBhapXb8y+Qp4OniHzRedlqKRxyL0Pc+kwXx5co4Vo+dcOI5/MX0p+8oERP2aCR77s4FEUJg=="
|
"integrity": "sha512-9d6yEPJRRvPLMUkpyaiQ62SXNMMyt2l815jxWgFjnVOxKeUQv9TPyZqZ0FpmWdVe6EY8dv8GLlyaBpOLDnY6Vg=="
|
||||||
},
|
},
|
||||||
"node_modules/@sasjs/utils": {
|
"node_modules/@sasjs/utils": {
|
||||||
"version": "2.42.1",
|
"version": "2.42.1",
|
||||||
@@ -11358,9 +11358,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@sasjs/core": {
|
"@sasjs/core": {
|
||||||
"version": "4.19.0",
|
"version": "4.23.1",
|
||||||
"resolved": "https://registry.npmjs.org/@sasjs/core/-/core-4.19.0.tgz",
|
"resolved": "https://registry.npmjs.org/@sasjs/core/-/core-4.23.1.tgz",
|
||||||
"integrity": "sha512-vG2YHJveQUQqN0YBhapXb8y+Qp4OniHzRedlqKRxyL0Pc+kwXx5co4Vo+dcOI5/MX0p+8oERP2aCR77s4FEUJg=="
|
"integrity": "sha512-9d6yEPJRRvPLMUkpyaiQ62SXNMMyt2l815jxWgFjnVOxKeUQv9TPyZqZ0FpmWdVe6EY8dv8GLlyaBpOLDnY6Vg=="
|
||||||
},
|
},
|
||||||
"@sasjs/utils": {
|
"@sasjs/utils": {
|
||||||
"version": "2.42.1",
|
"version": "2.42.1",
|
||||||
|
|||||||
@@ -47,7 +47,7 @@
|
|||||||
},
|
},
|
||||||
"author": "4GL Ltd",
|
"author": "4GL Ltd",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sasjs/core": "^4.19.0",
|
"@sasjs/core": "^4.23.1",
|
||||||
"@sasjs/utils": "2.42.1",
|
"@sasjs/utils": "2.42.1",
|
||||||
"bcryptjs": "^2.4.3",
|
"bcryptjs": "^2.4.3",
|
||||||
"connect-mongo": "^4.6.0",
|
"connect-mongo": "^4.6.0",
|
||||||
|
|||||||
@@ -35,9 +35,12 @@ export const cookieOptions = {
|
|||||||
maxAge: 24 * 60 * 60 * 1000 // 24 hours
|
maxAge: 24 * 60 * 60 * 1000 // 24 hours
|
||||||
}
|
}
|
||||||
|
|
||||||
const cspConfigJson = getEnvCSPDirectives(HELMET_CSP_CONFIG_PATH)
|
const cspConfigJson: { [key: string]: string[] | null } = getEnvCSPDirectives(
|
||||||
|
HELMET_CSP_CONFIG_PATH
|
||||||
|
)
|
||||||
const coepFlag =
|
const coepFlag =
|
||||||
HELMET_COEP === 'true' || HELMET_COEP === undefined ? true : false
|
HELMET_COEP === 'true' || HELMET_COEP === undefined ? true : false
|
||||||
|
if (PROTOCOL === 'http') cspConfigJson['upgrade-insecure-requests'] = null
|
||||||
|
|
||||||
/***********************************
|
/***********************************
|
||||||
* CSRF Protection *
|
* CSRF Protection *
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { Request, Security, Route, Tags, Post, Body } from 'tsoa'
|
|||||||
import { ExecuteReturnJson, ExecutionController } from './internal'
|
import { ExecuteReturnJson, ExecutionController } from './internal'
|
||||||
import { PreProgramVars } from '../types'
|
import { PreProgramVars } from '../types'
|
||||||
import { ExecuteReturnJsonResponse } from '.'
|
import { ExecuteReturnJsonResponse } from '.'
|
||||||
import { parseLogToArray } from '../utils'
|
import { getPreProgramVariables, parseLogToArray } from '../utils'
|
||||||
|
|
||||||
interface ExecuteSASCodePayload {
|
interface ExecuteSASCodePayload {
|
||||||
/**
|
/**
|
||||||
@@ -56,16 +56,3 @@ const executeSASCode = async (req: any, { code }: ExecuteSASCodePayload) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const getPreProgramVariables = (req: any): PreProgramVars => {
|
|
||||||
const host = req.get('host')
|
|
||||||
const protocol = req.protocol + '://'
|
|
||||||
const { user, accessToken } = req
|
|
||||||
return {
|
|
||||||
username: user.username,
|
|
||||||
userId: user.userId,
|
|
||||||
displayName: user.displayName,
|
|
||||||
serverUrl: protocol + host,
|
|
||||||
accessToken
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -75,12 +75,12 @@ export class ExecutionController {
|
|||||||
const logPath = path.join(session.path, 'log.log')
|
const logPath = path.join(session.path, 'log.log')
|
||||||
const headersPath = path.join(session.path, 'stpsrv_header.txt')
|
const headersPath = path.join(session.path, 'stpsrv_header.txt')
|
||||||
const weboutPath = path.join(session.path, 'webout.txt')
|
const weboutPath = path.join(session.path, 'webout.txt')
|
||||||
const tokenFile = path.join(session.path, 'accessToken.txt')
|
const tokenFile = path.join(session.path, 'reqHeaders.txt')
|
||||||
|
|
||||||
await createFile(weboutPath, '')
|
await createFile(weboutPath, '')
|
||||||
await createFile(
|
await createFile(
|
||||||
tokenFile,
|
tokenFile,
|
||||||
preProgramVariables?.accessToken ?? 'accessToken'
|
preProgramVariables?.httpHeaders.join('\n') ?? ''
|
||||||
)
|
)
|
||||||
|
|
||||||
const varStatments = Object.keys(vars).reduce(
|
const varStatments = Object.keys(vars).reduce(
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ import {
|
|||||||
ExecutionController,
|
ExecutionController,
|
||||||
ExecutionVars
|
ExecutionVars
|
||||||
} from './internal'
|
} from './internal'
|
||||||
import { PreProgramVars } from '../types'
|
|
||||||
import {
|
import {
|
||||||
|
getPreProgramVariables,
|
||||||
getTmpFilesFolderPath,
|
getTmpFilesFolderPath,
|
||||||
HTTPHeaders,
|
HTTPHeaders,
|
||||||
isDebugOn,
|
isDebugOn,
|
||||||
@@ -210,16 +210,3 @@ const executeReturnJson = async (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const getPreProgramVariables = (req: any): PreProgramVars => {
|
|
||||||
const host = req.get('host')
|
|
||||||
const protocol = req.protocol + '://'
|
|
||||||
const { user, accessToken } = req
|
|
||||||
return {
|
|
||||||
username: user.username,
|
|
||||||
userId: user.userId,
|
|
||||||
displayName: user.displayName,
|
|
||||||
serverUrl: protocol + host,
|
|
||||||
accessToken
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -3,5 +3,5 @@ export interface PreProgramVars {
|
|||||||
userId: number
|
userId: number
|
||||||
displayName: string
|
displayName: string
|
||||||
serverUrl: string
|
serverUrl: string
|
||||||
accessToken: string
|
httpHeaders: string[]
|
||||||
}
|
}
|
||||||
|
|||||||
29
api/src/utils/getPreProgramVariables.ts
Normal file
29
api/src/utils/getPreProgramVariables.ts
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import { PreProgramVars } from '../types'
|
||||||
|
|
||||||
|
export const getPreProgramVariables = (req: any): PreProgramVars => {
|
||||||
|
const host = req.get('host')
|
||||||
|
const protocol = req.protocol + '://'
|
||||||
|
const { user, accessToken } = req
|
||||||
|
const csrfToken = req.headers['x-xsrf-token']
|
||||||
|
const sessionId = req.cookies['connect.sid']
|
||||||
|
const { _csrf } = req.cookies
|
||||||
|
|
||||||
|
const httpHeaders: string[] = []
|
||||||
|
|
||||||
|
if (accessToken) httpHeaders.push(`Authorization: Bearer ${accessToken}`)
|
||||||
|
if (csrfToken) httpHeaders.push(`x-xsrf-token: ${csrfToken}`)
|
||||||
|
|
||||||
|
const cookies: string[] = []
|
||||||
|
if (sessionId) cookies.push(`connect.sid=${sessionId}`)
|
||||||
|
if (_csrf) cookies.push(`_csrf=${_csrf}`)
|
||||||
|
|
||||||
|
if (cookies.length) httpHeaders.push(`cookie: ${cookies.join('; ')}`)
|
||||||
|
|
||||||
|
return {
|
||||||
|
username: user.username,
|
||||||
|
userId: user.userId,
|
||||||
|
displayName: user.displayName,
|
||||||
|
serverUrl: protocol + host,
|
||||||
|
httpHeaders
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,6 +8,7 @@ export * from './generateAuthCode'
|
|||||||
export * from './generateRefreshToken'
|
export * from './generateRefreshToken'
|
||||||
export * from './getCertificates'
|
export * from './getCertificates'
|
||||||
export * from './getDesktopFields'
|
export * from './getDesktopFields'
|
||||||
|
export * from './getPreProgramVariables'
|
||||||
export * from './isDebugOn'
|
export * from './isDebugOn'
|
||||||
export * from './parseLogToArray'
|
export * from './parseLogToArray'
|
||||||
export * from './removeTokensInDB'
|
export * from './removeTokensInDB'
|
||||||
|
|||||||
@@ -5,7 +5,9 @@ export const getEnvCSPDirectives = (
|
|||||||
HELMET_CSP_CONFIG_PATH: string | undefined
|
HELMET_CSP_CONFIG_PATH: string | undefined
|
||||||
) => {
|
) => {
|
||||||
let cspConfigJson = {
|
let cspConfigJson = {
|
||||||
'script-src': ["'self'", "'unsafe-inline'"]
|
'img-src': ["'self'", 'data:'],
|
||||||
|
'script-src': ["'self'", "'unsafe-inline'"],
|
||||||
|
'script-src-attr': ["'self'", "'unsafe-inline'"]
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
|||||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "server",
|
"name": "server",
|
||||||
"version": "0.0.70",
|
"version": "0.0.74",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "server",
|
"name": "server",
|
||||||
"version": "0.0.70",
|
"version": "0.0.74",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"prettier": "^2.3.1",
|
"prettier": "^2.3.1",
|
||||||
"standard-version": "^9.3.2"
|
"standard-version": "^9.3.2"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "server",
|
"name": "server",
|
||||||
"version": "0.0.70",
|
"version": "0.0.74",
|
||||||
"description": "NodeJS wrapper for calling the SAS binary executable",
|
"description": "NodeJS wrapper for calling the SAS binary executable",
|
||||||
"repository": "https://github.com/sasjs/server",
|
"repository": "https://github.com/sasjs/server",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
### Get current user's info via access token
|
### Get current user's info via session ID
|
||||||
GET http://localhost:5000/SASjsApi/session
|
GET http://localhost:5000/SASjsApi/session
|
||||||
|
cookie: connect.sid=s:G2DeFdKuWhnmTOsTHmTWrxAXPx2P6TLD.JyNLxfACC1w3NlFQFfL5chyxtrqbPYmS6iButRc1goE
|
||||||
Reference in New Issue
Block a user