cassproject 1.5.37 → 1.5.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -1
- package/package.json +16 -16
- package/src/com/eduworks/ec/crypto/EcAesCtrAsync.js +2 -2
- package/src/com/eduworks/ec/crypto/EcRsaOaepAsync.js +1 -1
- package/src/com/eduworks/ec/graph/EcFrameworkGraph.test.js +3 -16
- package/src/com/eduworks/ec/promises/helpers.js +1 -1
- package/src/com/eduworks/ec/remote/EcRemote.js +143 -184
- package/src/org/cass/importer/CTDLASNCSVImport.js +40 -0
- package/src/org/cassproject/ebac/identity/EcIdentityManager.js +1 -1
- package/src/org/cassproject/ebac/identity/remote/EcRemoteIdentityManager.js +2 -2
- package/src/org/cassproject/ebac/identity/remote/OAuth2FileBasedRemoteIdentityManager.js +1 -1
- package/src/org/cassproject/ebac/repository/EcRepository.js +3 -4
- package/src/org/cassproject/ebac/repository/EcRepository.test.js +1 -0
package/README.md
CHANGED
|
@@ -39,7 +39,7 @@ Development unit tests presume you have a CaSS Repository running on `localhost:
|
|
|
39
39
|
* Increment version number in package.json and yuidoc.json.
|
|
40
40
|
* Update changelog.
|
|
41
41
|
* `npm install`
|
|
42
|
-
* `npm audit
|
|
42
|
+
* `npm audit` and fix any audit issues.
|
|
43
43
|
* `npm test` - Must not fail any tests.
|
|
44
44
|
* Document code coverage output by the previous step.
|
|
45
45
|
* Commit changes to GitHub.
|
|
@@ -48,6 +48,18 @@ Development unit tests presume you have a CaSS Repository running on `localhost:
|
|
|
48
48
|
|
|
49
49
|
# Changelog
|
|
50
50
|
|
|
51
|
+
## 1.5.39
|
|
52
|
+
* Removed axios due to incompatibility with http2 and security findings.
|
|
53
|
+
* Now uses fetch for http/s traffic.
|
|
54
|
+
* To use fetch with http2 compatibility or on node 16, `npm install undici` (node's native fetch library, but with more features)
|
|
55
|
+
* Started investigating node 21 compatibility.
|
|
56
|
+
|
|
57
|
+
## 1.5.38
|
|
58
|
+
* Fixed issue with CTDL-ASN import.
|
|
59
|
+
* Use of cassproject library with Vite.js now has appropriate mitigations in place. You will need to include the following libraries
|
|
60
|
+
* `"buffer": "^6.0.3"`
|
|
61
|
+
* `"stream": "npm:stream-browserify@^3.0.0"`
|
|
62
|
+
|
|
51
63
|
## 1.5.37
|
|
52
64
|
* Can now search for and de-duplicate competencies on import.
|
|
53
65
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cassproject",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.39",
|
|
4
4
|
"description": "Competency and Skills Service",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -9,11 +9,11 @@
|
|
|
9
9
|
"multitest": "concurrently --kill-others --kill-others-on-fail \"npm run test15\" \"npm run test14\" \"npm run test13\" \"npm run test12\"",
|
|
10
10
|
"testCassTest": "npm run testkill && docker run -d --name cass-test -p80:80 -e CASS_LOOPBACK cass-test && wait-on http://localhost/api/ping && npm run testNode18 && npm run testNode18Fips && npm run testNode16 && npm run testNode15 && npm run testNode14 && npm run testNode13 && npm run testNode12 && npm run testCypressEdge && npm run testCypress && npm run testkill",
|
|
11
11
|
"testDevHttps": "npm run testkill && docker run -d --name cass-test -p443:80 -e CASS_LOOPBACK -e HTTPS=true cassproject/cass:dev && wait-on https://localhost/api/ping && npm run testNode18HttpsFips && npm run testNode18Https && npm run testNode16Https && npm run testNode15Https && npm run testNode14Https && npm run testNode13Https && npm run testNode12Https && npm run testCypressEdgeHttps && npm run testCypressHttps",
|
|
12
|
-
"test15HttpsFips": "npm run testkill && docker run -d --name cass-test -p443:443 -e CASS_LOOPBACK -e HTTPS=true cassproject/cass:1.5.
|
|
13
|
-
"test15Https11Fips": "npm run testkill && docker run -d --name cass-test -p443:443 -e CASS_LOOPBACK -e HTTPS=true -e HTTP2=false cassproject/cass:1.5.
|
|
12
|
+
"test15HttpsFips": "npm run testkill && docker run -d --name cass-test -p443:443 -e CASS_LOOPBACK -e HTTPS=true cassproject/cass:1.5.37 && wait-on https://localhost/api/ping && concurrently --kill-others-on-fail \"npm run testCypressHttps\" \"npm run testNode20Https\" \"npm run testNode20HttpsFips\" \"npm run testNode20HttpsForceFips\" \"npm run testNode18Https\" \"npm run testNode18HttpsFips\" \"npm run testNode16Https\" && npm run testkill",
|
|
13
|
+
"test15Https11Fips": "npm run testkill && docker run -d --name cass-test -p443:443 -e CASS_LOOPBACK -e HTTPS=true -e HTTP2=false cassproject/cass:1.5.37 && wait-on https://localhost/api/ping && concurrently --kill-others-on-fail \"npm run testCypressHttps\" \"npm run testNode20Https\" \"npm run testNode20HttpsFips\" \"npm run testNode20HttpsForceFips\" \"npm run testNode18Https\" \"npm run testNode18HttpsFips\" \"npm run testNode16Https\" && npm run testkill",
|
|
14
14
|
"test15Https": "npm run testkill && docker run -d --name cass-test -p443:443 -e CASS_LOOPBACK -e HTTPS=true cassproject/cass:1.5.32 && wait-on https://localhost/api/ping && concurrently --kill-others-on-fail \"npm run testCypressHttps\" \"npm run testNode20Https\" \"npm run testNode20HttpsFips\" \"npm run testNode18Https\" \"npm run testNode18HttpsFips\" \"npm run testNode16Https\" && npm run testkill",
|
|
15
15
|
"test15Https11": "npm run testkill && docker run -d --name cass-test -p443:443 -e CASS_LOOPBACK -e HTTPS=true -e HTTP2=false cassproject/cass:1.5.32 && wait-on https://localhost/api/ping && concurrently --kill-others-on-fail \"npm run testCypressHttps\" \"npm run testNode20Https\" \"npm run testNode20HttpsFips\" \"npm run testNode18Https\" \"npm run testNode18HttpsFips\" \"npm run testNode16Https\" && npm run testkill",
|
|
16
|
-
"test15Fips": "export CASS_LOOPBACK=http://localhost/api/|| set CASS_LOOPBACK=http://localhost/api/&& npm run testkill15 && docker run -d -e CASS_LOOPBACK --name cass-test15 -p80:80 cassproject/cass:1.5.
|
|
16
|
+
"test15Fips": "export CASS_LOOPBACK=http://localhost/api/|| set CASS_LOOPBACK=http://localhost/api/&& npm run testkill15 && docker run -d -e CASS_LOOPBACK --name cass-test15 -p80:80 cassproject/cass:1.5.37 && wait-on http://localhost/api/ping && concurrently --kill-others-on-fail \"npm run testCypress\" \"npm run testNode20\" \"npm run testNode20Fips\" \"npm run testNode20ForceFips\" \"npm run testNode18\" \"npm run testNode18Fips\" \"npm run testNode16\" && npm run testkill15",
|
|
17
17
|
"test15": "export CASS_LOOPBACK=http://localhost/api/|| set CASS_LOOPBACK=http://localhost/api/&& npm run testkill15 && docker run -d -e CASS_LOOPBACK --name cass-test15 -p80:80 cassproject/cass:1.5.32 && wait-on http://localhost/api/ping && concurrently --kill-others-on-fail \"npm run testCypress\" \"npm run testNode20\" \"npm run testNode20Fips\" \"npm run testNode18\" \"npm run testNode18Fips\" \"npm run testNode16\" && npm run testkill15",
|
|
18
18
|
"test14": "npm run testkill14 && docker run -d -e CASS_LOOPBACK --name cass-test14 -p80:80 cassproject/cass:1.4.4 && wait-on http://localhost/api/ping && concurrently --kill-others-on-fail \"npm run testCypress\" \"npm run testNode16\" && npm run testkill14",
|
|
19
19
|
"test13": "npm run testkill13 && docker run -d -e CASS_LOOPBACK --name cass-test13 -p80:80 cassproject/cass:1.3.18 && wait-on http://localhost/api/ping && concurrently --kill-others-on-fail \"npm run testCypress\" \"npm run testNode16\" && npm run testkill13",
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"testkill13": "docker kill cass-test13 | exit 0 && docker rm cass-test13 | exit 0",
|
|
24
24
|
"testkill12": "docker kill cass-test12 | exit 0 && docker rm cass-test12 | exit 0",
|
|
25
25
|
"testkill": "docker kill cass-test | exit 0 && docker rm cass-test | exit 0",
|
|
26
|
+
"testNode21Https": "docker build --progress plain -f docker/node21https -t npm-cass21https . & docker run -e CASS_LOOPBACK --rm --network=\"host\" npm-cass21https",
|
|
26
27
|
"testNode20": "docker build --progress plain -f docker/node20 -t npm-cass20 . & docker run -e CASS_LOOPBACK --rm --network=\"host\" npm-cass20",
|
|
27
28
|
"testNode20Https": "docker build --progress plain -f docker/node20https -t npm-cass20https . & docker run -e CASS_LOOPBACK --rm --network=\"host\" npm-cass20https",
|
|
28
29
|
"testNode20HttpsFips": "docker build --progress plain -f docker/node20httpsfips -t npm-cass20httpsfips . & docker run -e CASS_LOOPBACK --rm --network=\"host\" npm-cass20httpsfips",
|
|
@@ -51,7 +52,8 @@
|
|
|
51
52
|
"mochaFips": "mocha -n 'force-fips' --timeout 15000 -b src/**/*.test.js",
|
|
52
53
|
"mocha:httpsNoHttp2": "export HTTP2=false|| set HTTP2=false&& mocha --timeout 15000 -b src/**/*.test.js",
|
|
53
54
|
"mocha:https": "mocha --timeout 15000 -b src/**/*.test.js",
|
|
54
|
-
"mocha:clientSideCertificates": "export CASS_LOOPBACK=https://localhost/api/|| set CASS_LOOPBACK=https://localhost/api/&& mocha --timeout 15000 -b src/**/*.test.js",
|
|
55
|
+
"mocha:clientSideCertificates": "export NODE_EXTRA_CA_CERTS=ca.crt|| set NODE_EXTRA_CA_CERTS=ca.crt&&export CASS_LOOPBACK=https://localhost/api/|| set CASS_LOOPBACK=https://localhost/api/&&export HTTP2=false|| set HTTP2=false&& mocha --timeout 15000 -b src/**/*.test.js",
|
|
56
|
+
"mocha:clientSideCertificatesDangerMouse": "export NODE_EXTRA_CA_CERTS=ca.crt|| set NODE_EXTRA_CA_CERTS=ca.crt&&export CASS_LOOPBACK=https://localhost/api/|| set CASS_LOOPBACK=https://localhost/api/&&export HTTP2=false|| set HTTP2=false&& mocha --timeout 15000 -b src/**/*.test.js",
|
|
55
57
|
"mocha:custom": "export CASS_LOOPBACK=https://tides.eduworks.us/api/|| set CASS_LOOPBACK=https://tides.eduworks.us/api/&& export HTTP2=false|| set HTTP2=false&& mocha --timeout 300000 -b src/**/*.test.js",
|
|
56
58
|
"mocha:dev": "export CASS_LOOPBACK=https://dev.cassproject.org/api/|| set CASS_LOOPBACK=https://dev.cassproject.org/api/&& export HTTP2=false|| set HTTP2=false&& mocha --timeout 300000 -b src/**/*.test.js",
|
|
57
59
|
"mocha:demo": "export CASS_LOOPBACK=https://demo.cassproject.org/api/|| set CASS_LOOPBACK=https://demo.cassproject.org/api/&& export HTTP2=false|| set HTTP2=false&& mocha --timeout 300000 -b src/**/*.test.js",
|
|
@@ -75,7 +77,7 @@
|
|
|
75
77
|
"webpack:cypress": "cypress run --config-file cypressWebpack.config.js --headless --browser chrome",
|
|
76
78
|
"webpack:cypressHttps": "cypress run -e CASS_LOOPBACK=https://localhost/api/ --config-file cypressWebpack.config.js --headless --browser chrome",
|
|
77
79
|
"webpack:cypressEdge": "cypress run --config-file cypressWebpack.config.js --headless --browser edge",
|
|
78
|
-
"webpack:cypressEdgeHttps": "cypress run -e CASS_LOOPBACK=https://localhost/api/ --config-file cypressWebpack.config.js --
|
|
80
|
+
"webpack:cypressEdgeHttps": "cypress run -e CASS_LOOPBACK=https://localhost/api/ --config-file cypressWebpack.config.js --browser edge"
|
|
79
81
|
},
|
|
80
82
|
"contributors": [
|
|
81
83
|
{
|
|
@@ -104,11 +106,8 @@
|
|
|
104
106
|
}
|
|
105
107
|
],
|
|
106
108
|
"dependencies": {
|
|
107
|
-
"axios": "1.1.3",
|
|
108
109
|
"base64-arraybuffer": "^1.0.2",
|
|
109
110
|
"forge": "^2.3.0",
|
|
110
|
-
"form-data": "^4.0.0",
|
|
111
|
-
"http2-wrapper": "^2.2.0",
|
|
112
111
|
"jsonld": "^8.3.1",
|
|
113
112
|
"node-forge": "^1.3.1",
|
|
114
113
|
"papaparse": "^5.4.1",
|
|
@@ -139,24 +138,25 @@
|
|
|
139
138
|
},
|
|
140
139
|
"homepage": "https://github.com/cassproject/cass-npm#readme",
|
|
141
140
|
"devDependencies": {
|
|
142
|
-
"@babel/core": "^7.23.
|
|
143
|
-
"@babel/preset-env": "^7.
|
|
141
|
+
"@babel/core": "^7.23.2",
|
|
142
|
+
"@babel/preset-env": "^7.23.2",
|
|
144
143
|
"@cypress/browserify-preprocessor": "^3.0.2",
|
|
145
144
|
"@cypress/vite-dev-server": "^5.0.6",
|
|
146
145
|
"@cypress/webpack-preprocessor": "^6.0.0",
|
|
147
146
|
"babel-eslint": "^10.1.0",
|
|
148
147
|
"babel-plugin-transform-remove-strict-mode": "^0.0.2",
|
|
149
148
|
"chai": "^4.3.10",
|
|
150
|
-
"concurrently": "^8.2.
|
|
149
|
+
"concurrently": "^8.2.2",
|
|
151
150
|
"convert-hrtime": "^5.0.0",
|
|
152
|
-
"cypress": "^13.3.
|
|
153
|
-
"eslint": "^8.
|
|
151
|
+
"cypress": "^13.3.3",
|
|
152
|
+
"eslint": "^8.52.0",
|
|
154
153
|
"mocha": "^10.2.0",
|
|
155
154
|
"node-polyfill-webpack-plugin": "^2.0.1",
|
|
156
155
|
"nodemon": "^3.0.1",
|
|
157
156
|
"nyc": "^15.1.0",
|
|
158
157
|
"wait-on": "^7.0.1",
|
|
159
|
-
"webpack": "^5.
|
|
160
|
-
"webpack-cli": "^5.1.4"
|
|
158
|
+
"webpack": "^5.89.0",
|
|
159
|
+
"webpack-cli": "^5.1.4",
|
|
160
|
+
"wtfnode": "^0.9.1"
|
|
161
161
|
}
|
|
162
162
|
}
|
|
@@ -27,7 +27,7 @@ let realCrypto = require('crypto');
|
|
|
27
27
|
*/
|
|
28
28
|
module.exports = class EcAesCtrAsync {
|
|
29
29
|
static fipsOn(){
|
|
30
|
-
if (process && process.env && process.env.FIPS)
|
|
30
|
+
if (typeof process !== 'undefined' && process && process.env && process.env.FIPS)
|
|
31
31
|
if (realCrypto.getFips() == 0)
|
|
32
32
|
try {
|
|
33
33
|
realCrypto.setFips(true);
|
|
@@ -39,7 +39,7 @@ module.exports = class EcAesCtrAsync {
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
static fipsOff(){
|
|
42
|
-
if (process && process.env && process.env.FIPS)
|
|
42
|
+
if (typeof process !== 'undefined' && process && process.env && process.env.FIPS)
|
|
43
43
|
if (realCrypto.getFips() == 1)
|
|
44
44
|
try {
|
|
45
45
|
realCrypto.setFips(false);
|
|
@@ -198,7 +198,7 @@ module.exports = class EcRsaOaepAsync {
|
|
|
198
198
|
crypto === undefined ||
|
|
199
199
|
crypto.subtle == null ||
|
|
200
200
|
crypto.subtle === undefined ||
|
|
201
|
-
(process && process.env && process.env.FIPS)
|
|
201
|
+
(typeof process !== 'undefined' && process && process.env && process.env.FIPS)
|
|
202
202
|
) {
|
|
203
203
|
return EcRsaOaepAsyncWorker.sign(ppk, text, success, failure);
|
|
204
204
|
}
|
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
const envHttp2 = process.env.HTTP2 != null ? process.env.HTTP2.trim() == 'true' : true;
|
|
2
|
-
if (!envHttp2)
|
|
3
|
-
{
|
|
4
|
-
global.axios = require("axios"); //Pre-empt http2 use.
|
|
5
|
-
}
|
|
6
1
|
const EcRemote = require("../remote/EcRemote.js");
|
|
7
2
|
let EcFrameworkGraph = require("./EcFrameworkGraph.js");
|
|
8
3
|
const EcFramework = require("../../../../org/cass/competency/EcFramework.js");
|
|
@@ -35,17 +30,9 @@ let assert = chai.assert;
|
|
|
35
30
|
after(()=>EcRsaOaepAsyncWorker.teardown());
|
|
36
31
|
|
|
37
32
|
let deleteById = async function (id) {
|
|
38
|
-
await EcRepository.get(
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
EcRepository._delete(p1, null, function (p1) {
|
|
42
|
-
console.log(p1);
|
|
43
|
-
});
|
|
44
|
-
},
|
|
45
|
-
function (p1) {
|
|
46
|
-
console.log(p1);
|
|
47
|
-
}
|
|
48
|
-
);
|
|
33
|
+
let p1 = await EcRepository.get(id);
|
|
34
|
+
if (p1 != null)
|
|
35
|
+
await EcRepository._delete(p1);
|
|
49
36
|
};
|
|
50
37
|
let failure = function (p1) {
|
|
51
38
|
console.trace(p1);
|
|
@@ -12,7 +12,7 @@ module.exports = {
|
|
|
12
12
|
cassReturnAsPromise: function (o, success, failure, error) {
|
|
13
13
|
let p = new Promise((resolve, reject) => {
|
|
14
14
|
if (o === undefined || o == null) {
|
|
15
|
-
//
|
|
15
|
+
// console.trace(error);
|
|
16
16
|
reject(new Error(error));
|
|
17
17
|
} else
|
|
18
18
|
resolve(o);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
require("../../../../org/cassproject/general/AuditLogger.js");
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
let DEBUG = false;
|
|
4
|
+
|
|
5
5
|
let isNode = false;
|
|
6
6
|
if (typeof process === 'object') {
|
|
7
7
|
if (typeof process.versions === 'object') {
|
|
@@ -10,11 +10,24 @@ if (typeof process === 'object') {
|
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
|
+
if (isNode)
|
|
14
|
+
{
|
|
15
|
+
let undici = eval("require('undici');");
|
|
16
|
+
if (undici != null)
|
|
17
|
+
{
|
|
18
|
+
var {setGlobalDispatcher,Agent,fetch} = undici;
|
|
19
|
+
setGlobalDispatcher(new Agent({
|
|
20
|
+
allowH2: process.env.HTTP2 != null ? process.env.HTTP2.trim() == 'true' : true
|
|
21
|
+
}))
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
if (typeof window !== 'undefined' && window.fetch != null)
|
|
25
|
+
var fetch = window.fetch;
|
|
13
26
|
|
|
14
27
|
if (isNode)
|
|
15
28
|
{
|
|
16
29
|
try{
|
|
17
|
-
|
|
30
|
+
var dns = require('node:dns');
|
|
18
31
|
if (dns && dns.setDefaultResultOrder)
|
|
19
32
|
{
|
|
20
33
|
//Support for Node 18 using Docker containers with a network that doesn't support ipv6 loopback.
|
|
@@ -22,123 +35,12 @@ if (isNode)
|
|
|
22
35
|
}
|
|
23
36
|
}
|
|
24
37
|
catch(ex){
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
global.httpOptions = [];
|
|
29
|
-
global.http2Enabled = {};
|
|
30
|
-
let axios = null;
|
|
31
|
-
if (global.axios == null)
|
|
32
|
-
{
|
|
33
|
-
let axiosModule = require("axios");
|
|
34
|
-
if (axiosModule.default != null)
|
|
35
|
-
axiosModule = axiosModule.default;
|
|
36
|
-
global.axios = axios = axiosModule;
|
|
37
|
-
if (isNode)
|
|
38
|
-
{
|
|
39
|
-
let http2;
|
|
40
|
-
let https;
|
|
41
|
-
try {
|
|
42
|
-
http2 = require("http2-wrapper");
|
|
43
|
-
https = require("https");
|
|
44
|
-
} catch(e) {
|
|
45
|
-
global.auditLogger.report(global.auditLogger.LogCategory.NETWORK, global.auditLogger.Severity.ERROR, "EcRemoteInitHttp2", e);
|
|
46
|
-
}
|
|
47
|
-
function http2AdapterEnhancer(adapter) {
|
|
48
|
-
return async (config) => {
|
|
49
|
-
if (config.http2 && config.url.startsWith("https")) {
|
|
50
|
-
let req;
|
|
51
|
-
if (global.ca != null)
|
|
52
|
-
config.ca = global.ca;
|
|
53
|
-
config.transport = {
|
|
54
|
-
request: function request(options, handleResponse) {
|
|
55
|
-
if (global.ca != null)
|
|
56
|
-
options.ca = global.ca;
|
|
57
|
-
if (http2Enabled[options.hostname])
|
|
58
|
-
req = http2.request(options, handleResponse);
|
|
59
|
-
else
|
|
60
|
-
{
|
|
61
|
-
req = https.request(options, handleResponse);
|
|
62
|
-
if (http2Enabled[options.hostname] == null)
|
|
63
|
-
global.httpOptions.push(options);
|
|
64
|
-
}
|
|
65
|
-
return req;
|
|
66
|
-
},
|
|
67
|
-
};
|
|
68
|
-
const ret = adapter(config);
|
|
69
|
-
while (global.httpOptions.length > 0)
|
|
70
|
-
{
|
|
71
|
-
let options = global.httpOptions.pop();
|
|
72
|
-
if (global.ca != null)
|
|
73
|
-
options.cert = global.ca;
|
|
74
|
-
options.ALPNProtocols = ['h2', 'http/1.1'];
|
|
75
|
-
if (options.port == null || options.port == '')
|
|
76
|
-
options.port = 443;
|
|
77
|
-
if (options.host == null && options.hostname != null)
|
|
78
|
-
options.host = options.hostname;
|
|
79
|
-
let result = await http2.auto.resolveProtocol(options);
|
|
80
|
-
if (result.alpnProtocol == "http/1.1")
|
|
81
|
-
http2Enabled[options.hostname] = false;
|
|
82
|
-
else if (result.alpnProtocol == "h2")
|
|
83
|
-
http2Enabled[options.hostname] = true;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// Remove the axios action `socket.setKeepAlive` because the HTTP/2 sockets should not be directly manipulated
|
|
87
|
-
const listeners = req.listeners("socket");
|
|
88
|
-
if (listeners.length) req.removeListener("socket", listeners[0]);
|
|
89
|
-
return ret;
|
|
90
|
-
} else {
|
|
91
|
-
return adapter(config);
|
|
92
|
-
}
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
axiosOptions.http2 = true;
|
|
96
|
-
axiosOptions.adapter = http2AdapterEnhancer(axios.defaults.adapter);
|
|
97
|
-
}
|
|
98
|
-
} else {
|
|
99
|
-
if (global.axios.default != null)
|
|
100
|
-
global.axios = global.axios.default;
|
|
101
|
-
axios = global.axios;
|
|
102
|
-
if (isNode)
|
|
103
|
-
{
|
|
104
|
-
let https;
|
|
105
|
-
try {
|
|
106
|
-
https = require("https");
|
|
107
|
-
} catch(e) {
|
|
108
|
-
global.auditLogger.report(global.auditLogger.LogCategory.NETWORK, global.auditLogger.Severity.ERROR, "EcRemoteInitHttps", e);
|
|
109
|
-
}
|
|
110
|
-
function httpsAdapterEnhancer(adapter) {
|
|
111
|
-
return async (config) => {
|
|
112
|
-
if (process.env.HTTPS != null ? process.env.HTTPS.trim() == 'true' : false && config.url.startsWith("https")) {
|
|
113
|
-
let req;
|
|
114
|
-
config.transport = {
|
|
115
|
-
request: function request(options, handleResponse) {
|
|
116
|
-
if (global.ca != null)
|
|
117
|
-
options.ca = global.ca;
|
|
118
|
-
req = https.request(options, handleResponse);
|
|
119
|
-
return req;
|
|
120
|
-
},
|
|
121
|
-
};
|
|
122
|
-
const ret = adapter(config);
|
|
123
|
-
return ret;
|
|
124
|
-
} else {
|
|
125
|
-
return adapter(config);
|
|
126
|
-
}
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
axiosOptions.adapter = httpsAdapterEnhancer(axios.defaults.adapter);
|
|
38
|
+
console.log(ex);
|
|
130
39
|
}
|
|
131
40
|
}
|
|
132
41
|
|
|
133
42
|
const { cassPromisify } = require("../promises/helpers");
|
|
134
43
|
|
|
135
|
-
getAxiosOptions = function(url) {
|
|
136
|
-
let newOptions = Object.assign({}, axiosOptions);
|
|
137
|
-
if (corsOrigins.findIndex((x) => url.startsWith(x)) > -1)
|
|
138
|
-
newOptions.withCredentials = true;
|
|
139
|
-
return newOptions;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
44
|
/**
|
|
143
45
|
* Wrapper to handle all remote web service invocations.
|
|
144
46
|
*
|
|
@@ -243,6 +145,8 @@ module.exports = class EcRemote {
|
|
|
243
145
|
successCallback,
|
|
244
146
|
failureCallback
|
|
245
147
|
) {
|
|
148
|
+
if (DEBUG)
|
|
149
|
+
console.log("POST " + server + "" + (service || "") + " " + headers + fd);
|
|
246
150
|
let url = server;
|
|
247
151
|
if (!url.endsWith("/") && service != null && !("" == service)) {
|
|
248
152
|
url += "/";
|
|
@@ -251,42 +155,46 @@ module.exports = class EcRemote {
|
|
|
251
155
|
url += service;
|
|
252
156
|
}
|
|
253
157
|
url = EcRemote.upgradeHttpToHttps(url);
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
})
|
|
275
|
-
.then((response) => {
|
|
276
|
-
return response.data;
|
|
277
|
-
})
|
|
278
|
-
.catch((err) => {
|
|
279
|
-
if (err != null) {
|
|
280
|
-
global.auditLogger.report(global.auditLogger.LogCategory.NETWORK, global.auditLogger.Severity.ERROR, "EcRemotePostInner", err && err.response && err.response.request && err.response.request.socket ? err.response.request.socket.remoteAddress : '', url, postHeaders, err);
|
|
281
|
-
if (err.response != null) {
|
|
282
|
-
if (err.response.data != null)
|
|
283
|
-
throw err.response.data;
|
|
284
|
-
throw err;
|
|
285
|
-
}
|
|
286
|
-
throw err;
|
|
158
|
+
|
|
159
|
+
let p = fetch(url, {
|
|
160
|
+
method: 'POST',
|
|
161
|
+
body: fd,
|
|
162
|
+
headers: headers || {},
|
|
163
|
+
}).then(async (response) => {
|
|
164
|
+
if (!response.ok) {
|
|
165
|
+
throw new Error(response.statusText);
|
|
166
|
+
}
|
|
167
|
+
const contentType = response.headers.get("content-type");
|
|
168
|
+
let result = null;
|
|
169
|
+
if (contentType && contentType.indexOf("application/json") !== -1) {
|
|
170
|
+
result = await response.json();
|
|
171
|
+
} else {
|
|
172
|
+
result = await response.text();
|
|
173
|
+
try{
|
|
174
|
+
result = JSON.parse(result);
|
|
175
|
+
}
|
|
176
|
+
catch(ex) {
|
|
177
|
+
// Text is not json
|
|
287
178
|
}
|
|
288
|
-
|
|
289
|
-
|
|
179
|
+
}
|
|
180
|
+
return result;
|
|
181
|
+
}).catch((err) => {
|
|
182
|
+
if (isNode && typeof dns !== 'undefined') {
|
|
183
|
+
dns.lookup(new URL(url).hostname, ((error, address) => {
|
|
184
|
+
if (error) {
|
|
185
|
+
global.auditLogger.report(global.auditLogger.LogCategory.NETWORK, global.auditLogger.Severity.ERROR, "DNSLookup", url, error);
|
|
186
|
+
global.auditLogger.report(global.auditLogger.LogCategory.NETWORK, global.auditLogger.Severity.ERROR, "EcRemotePostInner", url, headers, err);
|
|
187
|
+
} else {
|
|
188
|
+
global.auditLogger.report(global.auditLogger.LogCategory.NETWORK, global.auditLogger.Severity.ERROR, "EcRemotePostInner", address, url, headers, err);
|
|
189
|
+
}
|
|
190
|
+
}))
|
|
191
|
+
} else {
|
|
192
|
+
global.auditLogger.report(global.auditLogger.LogCategory.NETWORK, global.auditLogger.Severity.ERROR, "EcRemotePostInner", url, headers, err);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
throw err;
|
|
196
|
+
})
|
|
197
|
+
|
|
290
198
|
return cassPromisify(p, successCallback, failureCallback);
|
|
291
199
|
}
|
|
292
200
|
/**
|
|
@@ -319,25 +227,56 @@ module.exports = class EcRemote {
|
|
|
319
227
|
* @static
|
|
320
228
|
*/
|
|
321
229
|
static getExpectingString(server, service, success, failure) {
|
|
230
|
+
if (DEBUG)
|
|
231
|
+
console.log("GET " + server + "" + (service || ""));
|
|
322
232
|
let url = EcRemote.urlAppend(server, service);
|
|
323
233
|
url = EcRemote.upgradeHttpToHttps(url);
|
|
324
|
-
let p =
|
|
325
|
-
.
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
.
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
234
|
+
let p = fetch(url).then(async (response) => {
|
|
235
|
+
if (!response.ok) {
|
|
236
|
+
throw new Error(response.statusText);
|
|
237
|
+
}
|
|
238
|
+
const contentType = response.headers.get("content-type");
|
|
239
|
+
let result = null;
|
|
240
|
+
if (contentType && contentType.indexOf("application/json") !== -1) {
|
|
241
|
+
result = await response.json();
|
|
242
|
+
} else {
|
|
243
|
+
result = await response.text();
|
|
244
|
+
try{
|
|
245
|
+
result = JSON.parse(result);
|
|
246
|
+
}
|
|
247
|
+
catch(ex) {
|
|
248
|
+
// Text is not json
|
|
338
249
|
}
|
|
339
|
-
|
|
340
|
-
|
|
250
|
+
}
|
|
251
|
+
if (isNode && typeof dns !== 'undefined') {
|
|
252
|
+
dns.lookup(new URL(url).hostname, ((error, address) => {
|
|
253
|
+
if (error) {
|
|
254
|
+
global.auditLogger.report(global.auditLogger.LogCategory.NETWORK, global.auditLogger.Severity.ERROR, "DNSLookup", url, error);
|
|
255
|
+
global.auditLogger.report(global.auditLogger.LogCategory.NETWORK, global.auditLogger.Severity.INFO, "EcRemoteGetExpectString", url);
|
|
256
|
+
} else {
|
|
257
|
+
global.auditLogger.report(global.auditLogger.LogCategory.NETWORK, global.auditLogger.Severity.INFO, "EcRemoteGetExpectString", address, url);
|
|
258
|
+
}
|
|
259
|
+
}))
|
|
260
|
+
} else {
|
|
261
|
+
global.auditLogger.report(global.auditLogger.LogCategory.NETWORK, global.auditLogger.Severity.INFO, "EcRemoteGetExpectString", url);
|
|
262
|
+
}
|
|
263
|
+
return result;
|
|
264
|
+
}).catch((err) => {
|
|
265
|
+
if (isNode && typeof dns !== 'undefined') {
|
|
266
|
+
dns.lookup(new URL(url).hostname, ((error, address) => {
|
|
267
|
+
if (error) {
|
|
268
|
+
global.auditLogger.report(global.auditLogger.LogCategory.NETWORK, global.auditLogger.Severity.ERROR, "DNSLookup", url, error);
|
|
269
|
+
global.auditLogger.report(global.auditLogger.LogCategory.NETWORK, global.auditLogger.Severity.ERROR, "EcRemoteGetExpectString", url, err);
|
|
270
|
+
} else {
|
|
271
|
+
global.auditLogger.report(global.auditLogger.LogCategory.NETWORK, global.auditLogger.Severity.INFO, "EcRemoteGetExpectString", address, url, err);
|
|
272
|
+
}
|
|
273
|
+
}))
|
|
274
|
+
} else {
|
|
275
|
+
global.auditLogger.report(global.auditLogger.LogCategory.NETWORK, global.auditLogger.Severity.INFO, "EcRemoteGetExpectString", url, err);
|
|
276
|
+
}
|
|
277
|
+
throw err;
|
|
278
|
+
})
|
|
279
|
+
|
|
341
280
|
return cassPromisify(p, success, failure);
|
|
342
281
|
}
|
|
343
282
|
static urlAppend(server, service) {
|
|
@@ -364,26 +303,46 @@ module.exports = class EcRemote {
|
|
|
364
303
|
* @static
|
|
365
304
|
*/
|
|
366
305
|
static _delete(url, signatureSheet, success, failure) {
|
|
306
|
+
if (DEBUG)
|
|
307
|
+
console.log("DELETE " + url);
|
|
367
308
|
url = EcRemote.upgradeHttpToHttps(url);
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
}
|
|
376
|
-
.
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
309
|
+
|
|
310
|
+
let p = fetch(url, {
|
|
311
|
+
method: 'DELETE',
|
|
312
|
+
headers: { signatureSheet: signatureSheet }
|
|
313
|
+
}).then(async (response) => {
|
|
314
|
+
if (!response.ok) {
|
|
315
|
+
throw new Error(response.statusText);
|
|
316
|
+
}
|
|
317
|
+
const contentType = response.headers.get("content-type");
|
|
318
|
+
let result = null;
|
|
319
|
+
if (contentType && contentType.indexOf("application/json") !== -1) {
|
|
320
|
+
result = await response.json();
|
|
321
|
+
} else {
|
|
322
|
+
result = await response.text();
|
|
323
|
+
try{
|
|
324
|
+
result = JSON.parse(result);
|
|
325
|
+
}
|
|
326
|
+
catch(ex) {
|
|
327
|
+
// Text is not json
|
|
384
328
|
}
|
|
385
|
-
|
|
386
|
-
|
|
329
|
+
}
|
|
330
|
+
return result;
|
|
331
|
+
}).catch((err) => {
|
|
332
|
+
if (isNode && typeof dns !== 'undefined') {
|
|
333
|
+
dns.lookup(new URL(url).hostname, ((error, address) => {
|
|
334
|
+
if (error) {
|
|
335
|
+
global.auditLogger.report(global.auditLogger.LogCategory.NETWORK, global.auditLogger.Severity.ERROR, "DNSLookup", url, signatureSheet, error);
|
|
336
|
+
global.auditLogger.report(global.auditLogger.LogCategory.NETWORK, global.auditLogger.Severity.ERROR, "EcRemoteDelete", url, signatureSheet, err);
|
|
337
|
+
} else {
|
|
338
|
+
global.auditLogger.report(global.auditLogger.LogCategory.NETWORK, global.auditLogger.Severity.INFO, "EcRemoteDelete", address, url, signatureSheet, err);
|
|
339
|
+
}
|
|
340
|
+
}))
|
|
341
|
+
} else {
|
|
342
|
+
global.auditLogger.report(global.auditLogger.LogCategory.NETWORK, global.auditLogger.Severity.INFO, "EcRemoteDelete", url, signatureSheet, err);
|
|
343
|
+
}
|
|
344
|
+
throw err;
|
|
345
|
+
})
|
|
387
346
|
return cassPromisify(p, success, failure);
|
|
388
347
|
}
|
|
389
348
|
static upgradeHttpToHttps(url) {
|
|
@@ -153,6 +153,12 @@ module.exports = class CTDLASNCSVImport {
|
|
|
153
153
|
}
|
|
154
154
|
delete pretranslatedE["ceterms:CTID"];
|
|
155
155
|
}
|
|
156
|
+
// Skip competency if ctid is specified
|
|
157
|
+
if (skip && Array.isArray(skip) && skip.length > 0) {
|
|
158
|
+
if (skip.find((element) => element.ctid ? element.ctid.includes(pretranslatedE["ceterms:ctid"]) : element === pretranslatedE["ceterms:ctid"])) {
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
156
162
|
if (
|
|
157
163
|
pretranslatedE["@type"] ==
|
|
158
164
|
"ceasn:CompetencyFramework"
|
|
@@ -164,6 +170,18 @@ module.exports = class CTDLASNCSVImport {
|
|
|
164
170
|
endpoint,
|
|
165
171
|
repo
|
|
166
172
|
);
|
|
173
|
+
for (let each in translator) {
|
|
174
|
+
// Make replacements for skipped duplicates
|
|
175
|
+
if (skip && Array.isArray(skip) && skip.length > 0) {
|
|
176
|
+
skip.forEach((element) => {
|
|
177
|
+
if (typeof translator[each] === 'string' && element.ctid && element.replaceWith) {
|
|
178
|
+
if (translator[each].contains(element.ctid.replace('ce-', ''))) {
|
|
179
|
+
translator[each] = translator[each].replace(element.ctid.replace('ce-', ''), element.replaceWith.replace('ce-', ''));
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
}
|
|
167
185
|
for (let each in translator) {
|
|
168
186
|
if (terms[each]) {
|
|
169
187
|
translator[terms[each]] = translator[each];
|
|
@@ -246,6 +264,16 @@ module.exports = class CTDLASNCSVImport {
|
|
|
246
264
|
frameworkRows[f.shortId()] = e;
|
|
247
265
|
f["ceasn:hasChild"] = null;
|
|
248
266
|
f["ceasn:hasTopChild"] = null;
|
|
267
|
+
// Remove skipped competencies
|
|
268
|
+
if (skip && Array.isArray(skip) && skip.length > 0 && f.competency) {
|
|
269
|
+
skip.forEach((element) => {
|
|
270
|
+
const id = (element.ctid ? element.ctid : element).replace('ce-', '');
|
|
271
|
+
const index = f.competency.findIndex((comp) => comp.includes(id));
|
|
272
|
+
if (index) {
|
|
273
|
+
f.competency.splice(index, 1);
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
}
|
|
249
277
|
frameworkArray.push(f);
|
|
250
278
|
f.competency = [];
|
|
251
279
|
f.relation = [];
|
|
@@ -259,6 +287,18 @@ module.exports = class CTDLASNCSVImport {
|
|
|
259
287
|
endpoint,
|
|
260
288
|
repo
|
|
261
289
|
);
|
|
290
|
+
for (let each in translator) {
|
|
291
|
+
// Make replacements for skipped duplicates
|
|
292
|
+
if (skip && Array.isArray(skip) && skip.length > 0) {
|
|
293
|
+
skip.forEach((element) => {
|
|
294
|
+
if (typeof translator[each] === 'string' && element.ctid && element.replaceWith) {
|
|
295
|
+
if (translator[each].contains(element.ctid.replace('ce-', ''))) {
|
|
296
|
+
translator[each] = translator[each].replace(element.ctid.replace('ce-', ''), element.replaceWith.replace('ce-', ''));
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
}
|
|
262
302
|
for (let each in translator) {
|
|
263
303
|
if (terms[each]) {
|
|
264
304
|
translator[terms[each]] = translator[each];
|
|
@@ -440,7 +440,7 @@ module.exports = class EcIdentityManager {
|
|
|
440
440
|
* @static
|
|
441
441
|
*/
|
|
442
442
|
createSignature(duration, server, ppk, algorithm) {
|
|
443
|
-
if (process && process.env && process.env.FIPS == null && realCrypto.getFips && realCrypto.getFips() == 1)
|
|
443
|
+
if (typeof process !== 'undefined' && process && process.env && process.env.FIPS == null && realCrypto.getFips && realCrypto.getFips() == 1)
|
|
444
444
|
{
|
|
445
445
|
algorithm = "SHA-256";
|
|
446
446
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
|
|
2
2
|
const {cassPromisify} = require("../../../../../com/eduworks/ec/promises/helpers");
|
|
3
3
|
const EcRemote = require("../../../../../com/eduworks/ec/remote/EcRemote");
|
|
4
4
|
const EbacCredentialCommit = require("../../../../../com/eduworks/schema/ebac/EbacCredentialCommit");
|
|
@@ -35,7 +35,7 @@ require("../../../general/AuditLogger.js")
|
|
|
35
35
|
*/
|
|
36
36
|
module.exports = class EcRemoteIdentityManager extends RemoteIdentityManagerInterface {
|
|
37
37
|
server = null;
|
|
38
|
-
global = null;
|
|
38
|
+
// global = null;
|
|
39
39
|
usernameWithSalt = null;
|
|
40
40
|
passwordWithSalt = null;
|
|
41
41
|
secretWithSalt = null;
|
|
@@ -38,7 +38,7 @@ module.exports = class OAuth2FileBasedRemoteIdentityManager extends
|
|
|
38
38
|
configuration = null;
|
|
39
39
|
oauthLoginResponse = null;
|
|
40
40
|
network = null;
|
|
41
|
-
global = null;
|
|
41
|
+
// global = null;
|
|
42
42
|
/**
|
|
43
43
|
* Returns true if the identity manager is global. Returns false if the identity manager is local to the server.
|
|
44
44
|
*
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
if (!envHttp2)
|
|
1
|
+
if (typeof process !== 'undefined' && process.version && process.version.startsWith("v16"))
|
|
3
2
|
{
|
|
4
|
-
|
|
3
|
+
console.log("Loading polyfill for FormData.");
|
|
4
|
+
FormData = eval("require('undici').FormData");
|
|
5
5
|
}
|
|
6
|
-
let FormData = require("form-data");
|
|
7
6
|
const EcObject = require("../../../../com/eduworks/ec/array/EcObject");
|
|
8
7
|
const EcEncryptedValue = require("./EcEncryptedValue");
|
|
9
8
|
const EcIdentityManager = require("../identity/EcIdentityManager");
|