mirror of
https://github.com/sasjs/server.git
synced 2025-12-11 19:44:35 +00:00
Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e059bee7dc | ||
|
|
6f56aafab1 | ||
|
|
8734489cf0 | ||
|
|
7e6635f40f | ||
|
|
c0022a22f4 | ||
|
|
3fa2a7e2e3 | ||
| 8a617a73ae | |||
|
|
e7babb9f55 | ||
|
|
5ab35b02c4 | ||
|
|
ad82ee7106 | ||
|
|
d2e9456d81 | ||
|
|
e6d1989847 | ||
|
|
7a932383b4 | ||
|
|
576e18347e | ||
|
|
61815f8ae1 | ||
|
|
afff27fd21 | ||
|
|
a8ba378fd1 |
43
CHANGELOG.md
43
CHANGELOG.md
@@ -1,3 +1,46 @@
|
|||||||
|
## [0.3.9](https://github.com/sasjs/server/compare/v0.3.8...v0.3.9) (2022-06-14)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* forcing utf 8 encoding. Closes [#76](https://github.com/sasjs/server/issues/76) ([8734489](https://github.com/sasjs/server/commit/8734489cf014aedaca3f325e689493e4fe0b71ca))
|
||||||
|
|
||||||
|
## [0.3.8](https://github.com/sasjs/server/compare/v0.3.7...v0.3.8) (2022-06-13)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* execution controller better error handling ([8a617a7](https://github.com/sasjs/server/commit/8a617a73ae63233332f5788c90f173d6cd5e1283))
|
||||||
|
* execution controller error details ([3fa2a7e](https://github.com/sasjs/server/commit/3fa2a7e2e32f90050f6b09e30ce3ef725eb0b15f))
|
||||||
|
|
||||||
|
## [0.3.7](https://github.com/sasjs/server/compare/v0.3.6...v0.3.7) (2022-06-08)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **appstream:** redirect to relative + nested resource should be accessed ([5ab35b0](https://github.com/sasjs/server/commit/5ab35b02c4417132dddb5a800982f31d0d50ef66))
|
||||||
|
|
||||||
|
## [0.3.6](https://github.com/sasjs/server/compare/v0.3.5...v0.3.6) (2022-06-02)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **appstream:** should serve only new files for same app stream name with new deployment ([e6d1989](https://github.com/sasjs/server/commit/e6d1989847761fbe562d7861ffa0ee542839b125))
|
||||||
|
|
||||||
|
## [0.3.5](https://github.com/sasjs/server/compare/v0.3.4...v0.3.5) (2022-05-30)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* bumping sasjs/core library ([61815f8](https://github.com/sasjs/server/commit/61815f8ae18be132e17c199cd8e3afbcc2fa0b60))
|
||||||
|
|
||||||
|
## [0.3.4](https://github.com/sasjs/server/compare/v0.3.3...v0.3.4) (2022-05-30)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **web:** system username for DESKTOP mode ([a8ba378](https://github.com/sasjs/server/commit/a8ba378fd1ff374ba025a96fdfae5c6c36954465))
|
||||||
|
|
||||||
## [0.3.3](https://github.com/sasjs/server/compare/v0.3.2...v0.3.3) (2022-05-30)
|
## [0.3.3](https://github.com/sasjs/server/compare/v0.3.2...v0.3.3) (2022-05-30)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
82
api/package-lock.json
generated
82
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.23.1",
|
"@sasjs/core": "^4.27.3",
|
||||||
"@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",
|
||||||
@@ -24,7 +24,8 @@
|
|||||||
"mongoose-sequence": "^5.3.1",
|
"mongoose-sequence": "^5.3.1",
|
||||||
"morgan": "^1.10.0",
|
"morgan": "^1.10.0",
|
||||||
"multer": "^1.4.3",
|
"multer": "^1.4.3",
|
||||||
"swagger-ui-express": "4.3.0"
|
"swagger-ui-express": "4.3.0",
|
||||||
|
"url": "^0.10.3"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"api": "build/src/server.js"
|
"api": "build/src/server.js"
|
||||||
@@ -1385,9 +1386,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@sasjs/core": {
|
"node_modules/@sasjs/core": {
|
||||||
"version": "4.23.1",
|
"version": "4.27.3",
|
||||||
"resolved": "https://registry.npmjs.org/@sasjs/core/-/core-4.23.1.tgz",
|
"resolved": "https://registry.npmjs.org/@sasjs/core/-/core-4.27.3.tgz",
|
||||||
"integrity": "sha512-9d6yEPJRRvPLMUkpyaiQ62SXNMMyt2l815jxWgFjnVOxKeUQv9TPyZqZ0FpmWdVe6EY8dv8GLlyaBpOLDnY6Vg=="
|
"integrity": "sha512-8AaPPRGMwhmjw244CDSnTqHXdp/77ZBjIJMgwqw4wTrCf8Vzs2Y5hVihbvAniIGQctZHLMR6X5a3X4ccn9gRjg=="
|
||||||
},
|
},
|
||||||
"node_modules/@sasjs/utils": {
|
"node_modules/@sasjs/utils": {
|
||||||
"version": "2.42.1",
|
"version": "2.42.1",
|
||||||
@@ -2883,7 +2884,7 @@
|
|||||||
"node_modules/busboy": {
|
"node_modules/busboy": {
|
||||||
"version": "0.2.14",
|
"version": "0.2.14",
|
||||||
"resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz",
|
"resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz",
|
||||||
"integrity": "sha1-bCpiLvz0fFe7vh4qnDetNseSVFM=",
|
"integrity": "sha512-InWFDomvlkEj+xWLBfU3AvnbVYqeTWmQopiW0tWWEy5yehYm2YkGEc59sUmw/4ty5Zj/b0WHGs1LgecuBSBGrg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"dicer": "0.2.5",
|
"dicer": "0.2.5",
|
||||||
"readable-stream": "1.1.x"
|
"readable-stream": "1.1.x"
|
||||||
@@ -3677,7 +3678,7 @@
|
|||||||
"node_modules/dicer": {
|
"node_modules/dicer": {
|
||||||
"version": "0.2.5",
|
"version": "0.2.5",
|
||||||
"resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz",
|
"resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz",
|
||||||
"integrity": "sha1-WZbAhrszIYyBLAkL3cCc0S+stw8=",
|
"integrity": "sha512-FDvbtnq7dzlPz0wyYlOExifDEZcu8h+rErEXgfxqmLfRfC/kJidEFh4+effJRO3P0xmfqyPbSMG0LveNRfTKVg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"readable-stream": "1.1.x",
|
"readable-stream": "1.1.x",
|
||||||
"streamsearch": "0.1.2"
|
"streamsearch": "0.1.2"
|
||||||
@@ -7590,9 +7591,10 @@
|
|||||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||||
},
|
},
|
||||||
"node_modules/multer": {
|
"node_modules/multer": {
|
||||||
"version": "1.4.3",
|
"version": "1.4.4",
|
||||||
"resolved": "https://registry.npmjs.org/multer/-/multer-1.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/multer/-/multer-1.4.4.tgz",
|
||||||
"integrity": "sha512-np0YLKncuZoTzufbkM6wEKp68EhWJXcU6fq6QqrSwkckd2LlMgd1UqhUJLj6NS/5sZ8dE8LYDWslsltJznnXlg==",
|
"integrity": "sha512-2wY2+xD4udX612aMqMcB8Ws2Voq6NIUPEtD1be6m411T4uDH/VtL9i//xvcyFlTVfRdaBsk7hV5tgrGQqhuBiw==",
|
||||||
|
"deprecated": "Multer 1.x is affected by CVE-2022-24434. This is fixed in v1.4.4-lts.1 which drops support for versions of Node.js before 6. Please upgrade to at least Node.js 6 and version 1.4.4-lts.1 of Multer. If you need support for older versions of Node.js, we are open to accepting patches that would fix the CVE on the main 1.x release line, whilst maintaining compatibility with Node.js 0.10.",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"append-field": "^1.0.0",
|
"append-field": "^1.0.0",
|
||||||
"busboy": "^0.2.11",
|
"busboy": "^0.2.11",
|
||||||
@@ -8552,6 +8554,15 @@
|
|||||||
"node": ">=0.6"
|
"node": ">=0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/querystring": {
|
||||||
|
"version": "0.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
|
||||||
|
"integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=",
|
||||||
|
"deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.4.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/queue-microtask": {
|
"node_modules/queue-microtask": {
|
||||||
"version": "1.2.3",
|
"version": "1.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
||||||
@@ -9942,6 +9953,15 @@
|
|||||||
"url": "https://github.com/yeoman/update-notifier?sponsor=1"
|
"url": "https://github.com/yeoman/update-notifier?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/url": {
|
||||||
|
"version": "0.10.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz",
|
||||||
|
"integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=",
|
||||||
|
"dependencies": {
|
||||||
|
"punycode": "1.3.2",
|
||||||
|
"querystring": "0.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/url-parse-lax": {
|
"node_modules/url-parse-lax": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz",
|
||||||
@@ -9954,6 +9974,11 @@
|
|||||||
"node": ">=4"
|
"node": ">=4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/url/node_modules/punycode": {
|
||||||
|
"version": "1.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
|
||||||
|
"integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0="
|
||||||
|
},
|
||||||
"node_modules/util-deprecate": {
|
"node_modules/util-deprecate": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||||
@@ -11364,9 +11389,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@sasjs/core": {
|
"@sasjs/core": {
|
||||||
"version": "4.23.1",
|
"version": "4.27.3",
|
||||||
"resolved": "https://registry.npmjs.org/@sasjs/core/-/core-4.23.1.tgz",
|
"resolved": "https://registry.npmjs.org/@sasjs/core/-/core-4.27.3.tgz",
|
||||||
"integrity": "sha512-9d6yEPJRRvPLMUkpyaiQ62SXNMMyt2l815jxWgFjnVOxKeUQv9TPyZqZ0FpmWdVe6EY8dv8GLlyaBpOLDnY6Vg=="
|
"integrity": "sha512-8AaPPRGMwhmjw244CDSnTqHXdp/77ZBjIJMgwqw4wTrCf8Vzs2Y5hVihbvAniIGQctZHLMR6X5a3X4ccn9gRjg=="
|
||||||
},
|
},
|
||||||
"@sasjs/utils": {
|
"@sasjs/utils": {
|
||||||
"version": "2.42.1",
|
"version": "2.42.1",
|
||||||
@@ -12629,7 +12654,7 @@
|
|||||||
"busboy": {
|
"busboy": {
|
||||||
"version": "0.2.14",
|
"version": "0.2.14",
|
||||||
"resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz",
|
"resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz",
|
||||||
"integrity": "sha1-bCpiLvz0fFe7vh4qnDetNseSVFM=",
|
"integrity": "sha512-InWFDomvlkEj+xWLBfU3AvnbVYqeTWmQopiW0tWWEy5yehYm2YkGEc59sUmw/4ty5Zj/b0WHGs1LgecuBSBGrg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"dicer": "0.2.5",
|
"dicer": "0.2.5",
|
||||||
"readable-stream": "1.1.x"
|
"readable-stream": "1.1.x"
|
||||||
@@ -13267,7 +13292,7 @@
|
|||||||
"dicer": {
|
"dicer": {
|
||||||
"version": "0.2.5",
|
"version": "0.2.5",
|
||||||
"resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz",
|
"resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz",
|
||||||
"integrity": "sha1-WZbAhrszIYyBLAkL3cCc0S+stw8=",
|
"integrity": "sha512-FDvbtnq7dzlPz0wyYlOExifDEZcu8h+rErEXgfxqmLfRfC/kJidEFh4+effJRO3P0xmfqyPbSMG0LveNRfTKVg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"readable-stream": "1.1.x",
|
"readable-stream": "1.1.x",
|
||||||
"streamsearch": "0.1.2"
|
"streamsearch": "0.1.2"
|
||||||
@@ -16220,9 +16245,9 @@
|
|||||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||||
},
|
},
|
||||||
"multer": {
|
"multer": {
|
||||||
"version": "1.4.3",
|
"version": "1.4.4",
|
||||||
"resolved": "https://registry.npmjs.org/multer/-/multer-1.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/multer/-/multer-1.4.4.tgz",
|
||||||
"integrity": "sha512-np0YLKncuZoTzufbkM6wEKp68EhWJXcU6fq6QqrSwkckd2LlMgd1UqhUJLj6NS/5sZ8dE8LYDWslsltJznnXlg==",
|
"integrity": "sha512-2wY2+xD4udX612aMqMcB8Ws2Voq6NIUPEtD1be6m411T4uDH/VtL9i//xvcyFlTVfRdaBsk7hV5tgrGQqhuBiw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"append-field": "^1.0.0",
|
"append-field": "^1.0.0",
|
||||||
"busboy": "^0.2.11",
|
"busboy": "^0.2.11",
|
||||||
@@ -16933,6 +16958,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
|
||||||
"integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
|
"integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
|
||||||
},
|
},
|
||||||
|
"querystring": {
|
||||||
|
"version": "0.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
|
||||||
|
"integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA="
|
||||||
|
},
|
||||||
"queue-microtask": {
|
"queue-microtask": {
|
||||||
"version": "1.2.3",
|
"version": "1.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
||||||
@@ -17963,6 +17993,22 @@
|
|||||||
"xdg-basedir": "^4.0.0"
|
"xdg-basedir": "^4.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"url": {
|
||||||
|
"version": "0.10.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz",
|
||||||
|
"integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=",
|
||||||
|
"requires": {
|
||||||
|
"punycode": "1.3.2",
|
||||||
|
"querystring": "0.2.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"punycode": {
|
||||||
|
"version": "1.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
|
||||||
|
"integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"url-parse-lax": {
|
"url-parse-lax": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz",
|
||||||
|
|||||||
@@ -47,7 +47,7 @@
|
|||||||
},
|
},
|
||||||
"author": "4GL Ltd",
|
"author": "4GL Ltd",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sasjs/core": "^4.23.1",
|
"@sasjs/core": "^4.27.3",
|
||||||
"@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",
|
||||||
@@ -63,7 +63,8 @@
|
|||||||
"mongoose-sequence": "^5.3.1",
|
"mongoose-sequence": "^5.3.1",
|
||||||
"morgan": "^1.10.0",
|
"morgan": "^1.10.0",
|
||||||
"multer": "^1.4.3",
|
"multer": "^1.4.3",
|
||||||
"swagger-ui-express": "4.3.0"
|
"swagger-ui-express": "4.3.0",
|
||||||
|
"url": "^0.10.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/bcryptjs": "^2.4.2",
|
"@types/bcryptjs": "^2.4.2",
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ export class ExecutionController {
|
|||||||
session?: Session
|
session?: Session
|
||||||
) {
|
) {
|
||||||
if (!(await fileExists(programPath)))
|
if (!(await fileExists(programPath)))
|
||||||
throw 'ExecutionController: SAS file does not exist.'
|
throw `The Stored Program at (${vars._program}) does not exist, or you do not have permission to view it.`
|
||||||
|
|
||||||
const program = await readFile(programPath)
|
const program = await readFile(programPath)
|
||||||
|
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ ${autoExecContent}`
|
|||||||
session.path,
|
session.path,
|
||||||
'-AUTOEXEC',
|
'-AUTOEXEC',
|
||||||
autoExecPath,
|
autoExecPath,
|
||||||
|
'-ENCODING UTF-8',
|
||||||
process.platform === 'win32' ? '-nosplash' : ''
|
process.platform === 'win32' ? '-nosplash' : ''
|
||||||
])
|
])
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { RequestHandler, Request } from 'express'
|
import { RequestHandler, Request } from 'express'
|
||||||
|
import { userInfo } from 'os'
|
||||||
import { RequestUser } from '../types'
|
import { RequestUser } from '../types'
|
||||||
import { ModeType } from '../utils'
|
import { ModeType } from '../utils'
|
||||||
|
|
||||||
@@ -29,8 +30,8 @@ export const desktopRestrict: RequestHandler = (req, res, next) => {
|
|||||||
export const desktopUser: RequestUser = {
|
export const desktopUser: RequestUser = {
|
||||||
userId: 12345,
|
userId: 12345,
|
||||||
clientId: 'desktop_app',
|
clientId: 'desktop_app',
|
||||||
username: 'DESKTOPusername',
|
username: userInfo().username,
|
||||||
displayName: 'DESKTOP User',
|
displayName: userInfo().username,
|
||||||
isAdmin: true,
|
isAdmin: true,
|
||||||
isActive: true
|
isActive: true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
import path from 'path'
|
import path from 'path'
|
||||||
import express from 'express'
|
import express, { Request } from 'express'
|
||||||
import { folderExists } from '@sasjs/utils'
|
import { folderExists } from '@sasjs/utils'
|
||||||
|
|
||||||
import { addEntryToAppStreamConfig, getFilesFolder } from '../../utils'
|
import { addEntryToAppStreamConfig, getFilesFolder } from '../../utils'
|
||||||
import { appStreamHtml } from './appStreamHtml'
|
import { appStreamHtml } from './appStreamHtml'
|
||||||
|
|
||||||
|
const appStreams: { [key: string]: string } = {}
|
||||||
|
|
||||||
const router = express.Router()
|
const router = express.Router()
|
||||||
|
|
||||||
router.get('/', async (req, res) => {
|
router.get('/', async (req, res) => {
|
||||||
@@ -44,7 +46,7 @@ export const publishAppStream = async (
|
|||||||
streamServiceName = `AppStreamName${appCount + 1}`
|
streamServiceName = `AppStreamName${appCount + 1}`
|
||||||
}
|
}
|
||||||
|
|
||||||
router.use(`/${streamServiceName}`, express.static(pathToDeployment))
|
appStreams[streamServiceName] = pathToDeployment
|
||||||
|
|
||||||
addEntryToAppStreamConfig(
|
addEntryToAppStreamConfig(
|
||||||
streamServiceName,
|
streamServiceName,
|
||||||
@@ -64,4 +66,26 @@ export const publishAppStream = async (
|
|||||||
return {}
|
return {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
router.get(`/*`, function (req: Request, res, next) {
|
||||||
|
const reqPath = req.path.replace(/^\//, '')
|
||||||
|
|
||||||
|
// Redirecting to url with trailing slash for appStream base URL only
|
||||||
|
if (reqPath.split('/').length === 1 && !reqPath.endsWith('/'))
|
||||||
|
// navigating to same url with slash at start
|
||||||
|
return res.redirect(301, `${reqPath}/`)
|
||||||
|
|
||||||
|
const appStream = reqPath.split('/')[0]
|
||||||
|
const appStreamFilesPath = appStreams[appStream]
|
||||||
|
if (appStreamFilesPath) {
|
||||||
|
// resourcePath is without appStream base path
|
||||||
|
const resourcePath = reqPath.split('/').slice(1).join('/') || 'index.html'
|
||||||
|
|
||||||
|
req.url = resourcePath
|
||||||
|
|
||||||
|
return express.static(appStreamFilesPath)(req, res, next)
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.send("There's no App Stream available here.")
|
||||||
|
})
|
||||||
|
|
||||||
export default router
|
export default router
|
||||||
|
|||||||
15
api/src/utils/getServerUrl.ts
Normal file
15
api/src/utils/getServerUrl.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import express from 'express'
|
||||||
|
import url from 'url'
|
||||||
|
|
||||||
|
export const getFullUrl = (req: express.Request) =>
|
||||||
|
url.format({
|
||||||
|
protocol: req.protocol,
|
||||||
|
host: req.get('host'),
|
||||||
|
pathname: req.originalUrl
|
||||||
|
})
|
||||||
|
|
||||||
|
export const getServerUrl = (req: express.Request) =>
|
||||||
|
url.format({
|
||||||
|
protocol: req.protocol,
|
||||||
|
host: req.get('x-forwarded-host') || req.get('host')
|
||||||
|
})
|
||||||
@@ -10,6 +10,7 @@ export * from './generateRefreshToken'
|
|||||||
export * from './getCertificates'
|
export * from './getCertificates'
|
||||||
export * from './getDesktopFields'
|
export * from './getDesktopFields'
|
||||||
export * from './getPreProgramVariables'
|
export * from './getPreProgramVariables'
|
||||||
|
export * from './getServerUrl'
|
||||||
export * from './instantiateLogger'
|
export * from './instantiateLogger'
|
||||||
export * from './isDebugOn'
|
export * from './isDebugOn'
|
||||||
export * from './parseLogToArray'
|
export * from './parseLogToArray'
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import {
|
|||||||
} from '@mui/material'
|
} from '@mui/material'
|
||||||
import { toast } from 'react-toastify'
|
import { toast } from 'react-toastify'
|
||||||
|
|
||||||
import { AppContext } from '../../context/appContext'
|
import { AppContext, ModeType } from '../../context/appContext'
|
||||||
|
|
||||||
const Profile = () => {
|
const Profile = () => {
|
||||||
const [isLoading, setIsLoading] = useState(false)
|
const [isLoading, setIsLoading] = useState(false)
|
||||||
@@ -89,6 +89,7 @@ const Profile = () => {
|
|||||||
required
|
required
|
||||||
value={user.displayName}
|
value={user.displayName}
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
|
disabled={appContext.mode === ModeType.Desktop}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
@@ -103,6 +104,7 @@ const Profile = () => {
|
|||||||
required
|
required
|
||||||
value={user.username}
|
value={user.username}
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
|
disabled={appContext.mode === ModeType.Desktop}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,11 @@ import React, {
|
|||||||
} from 'react'
|
} from 'react'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
|
||||||
|
export enum ModeType {
|
||||||
|
Server = 'server',
|
||||||
|
Desktop = 'desktop'
|
||||||
|
}
|
||||||
|
|
||||||
interface AppContextProps {
|
interface AppContextProps {
|
||||||
checkingSession: boolean
|
checkingSession: boolean
|
||||||
loggedIn: boolean
|
loggedIn: boolean
|
||||||
@@ -19,6 +24,7 @@ interface AppContextProps {
|
|||||||
setUsername: Dispatch<SetStateAction<string>> | null
|
setUsername: Dispatch<SetStateAction<string>> | null
|
||||||
displayName: string
|
displayName: string
|
||||||
setDisplayName: Dispatch<SetStateAction<string>> | null
|
setDisplayName: Dispatch<SetStateAction<string>> | null
|
||||||
|
mode: ModeType
|
||||||
logout: (() => void) | null
|
logout: (() => void) | null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,6 +38,7 @@ export const AppContext = createContext<AppContextProps>({
|
|||||||
setUsername: null,
|
setUsername: null,
|
||||||
displayName: '',
|
displayName: '',
|
||||||
setDisplayName: null,
|
setDisplayName: null,
|
||||||
|
mode: ModeType.Server,
|
||||||
logout: null
|
logout: null
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -42,6 +49,7 @@ const AppContextProvider = (props: { children: ReactNode }) => {
|
|||||||
const [userId, setUserId] = useState(0)
|
const [userId, setUserId] = useState(0)
|
||||||
const [username, setUsername] = useState('')
|
const [username, setUsername] = useState('')
|
||||||
const [displayName, setDisplayName] = useState('')
|
const [displayName, setDisplayName] = useState('')
|
||||||
|
const [mode, setMode] = useState(ModeType.Server)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setCheckingSession(true)
|
setCheckingSession(true)
|
||||||
@@ -60,6 +68,14 @@ const AppContextProvider = (props: { children: ReactNode }) => {
|
|||||||
setLoggedIn(false)
|
setLoggedIn(false)
|
||||||
axios.get('/') // get CSRF TOKEN
|
axios.get('/') // get CSRF TOKEN
|
||||||
})
|
})
|
||||||
|
|
||||||
|
axios
|
||||||
|
.get('/SASjsApi/info')
|
||||||
|
.then((res) => res.data)
|
||||||
|
.then((data: any) => {
|
||||||
|
setMode(data.mode)
|
||||||
|
})
|
||||||
|
.catch(() => {})
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const logout = useCallback(() => {
|
const logout = useCallback(() => {
|
||||||
@@ -82,6 +98,7 @@ const AppContextProvider = (props: { children: ReactNode }) => {
|
|||||||
setUsername,
|
setUsername,
|
||||||
displayName,
|
displayName,
|
||||||
setDisplayName,
|
setDisplayName,
|
||||||
|
mode,
|
||||||
logout
|
logout
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
Reference in New Issue
Block a user