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 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 --production` and fix any audit issues.
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.37",
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.35 && 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.35 && 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",
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.35 && 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",
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 --headless --browser edge"
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.0",
143
- "@babel/preset-env": "^7.22.20",
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.1",
149
+ "concurrently": "^8.2.2",
151
150
  "convert-hrtime": "^5.0.0",
152
- "cypress": "^13.3.0",
153
- "eslint": "^8.50.0",
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.88.2",
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
- id,
40
- function (p1) {
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
- // console.trace(error);
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
- global.axiosOptions = {};
4
- global.corsOrigins = [];
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
- const dns = require('node:dns');
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
- let postHeaders = null;
255
- if (fd.getHeaders != null)
256
- {
257
- postHeaders = fd.getHeaders();
258
- postHeaders["Content-Type"] = null;
259
- }
260
- else
261
- postHeaders = {
262
- "Content-Type": null
263
- }
264
- if (fd.getLengthSync != null)
265
- postHeaders["content-length"] = fd.getLengthSync();
266
- if (headers !== undefined && headers != null)
267
- for (let header in headers) postHeaders[header] = headers[header];
268
-
269
- let p = axios.post(url, fd, {
270
- ...getAxiosOptions(url),
271
- headers: postHeaders,
272
- maxContentLength: Infinity,
273
- maxBodyLength: Infinity
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
- else global.auditLogger.report(global.auditLogger.LogCategory.NETWORK, global.auditLogger.Severity.ERROR, "EcRemotePostInner", "Internal error in Axios?");
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 = axios
325
- .get(url,getAxiosOptions(url))
326
- .then((response) => {
327
- global.auditLogger.report(global.auditLogger.LogCategory.NETWORK, global.auditLogger.Severity.INFO, "EcRemoteGetExpectString", response.request.socket ? response.request.socket.remoteAddress : '', url);
328
- return response.data;
329
- })
330
- .catch((err) => {
331
- global.auditLogger.report(global.auditLogger.LogCategory.NETWORK, global.auditLogger.Severity.ERROR, "EcRemoteGetExpectString", err && err.response && err.response.request && err.response.request.socket ? err.response.request.socket.remoteAddress : '', url, err);
332
- if (err) {
333
- if (err.response) {
334
- if (err.response.data)
335
- throw err.response.data;
336
- }
337
- throw err.response;
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
- throw err;
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
- let p = axios
369
- .delete(url, {
370
- ...getAxiosOptions(url),
371
- headers: { signatureSheet: signatureSheet }
372
- })
373
- .then((response) => {
374
- return response.data;
375
- })
376
- .catch((err) => {
377
- global.auditLogger.report(global.auditLogger.LogCategory.NETWORK, global.auditLogger.Severity.ERROR, "EcRemoteDelete", err && err.response && err.response.request && err.response.request.socket ? err.response.request.socket.remoteAddress : '', url, signatureSheet, err);
378
- if (err) {
379
- if (err.response) {
380
- if (err.response.data)
381
- throw err.response.data;
382
- }
383
- throw err.response;
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
- throw err;
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
- let FormData = require("form-data");
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
- const envHttp2 = process.env.HTTP2 != null ? process.env.HTTP2.trim() == 'true' : true;
2
- if (!envHttp2)
1
+ if (typeof process !== 'undefined' && process.version && process.version.startsWith("v16"))
3
2
  {
4
- global.axios = require("axios"); //Pre-empt http2 use.
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");
@@ -1,3 +1,4 @@
1
+
1
2
  const EcRemote = require("../../../../com/eduworks/ec/remote/EcRemote.js");
2
3
  const EcFramework = require("../../../../org/cass/competency/EcFramework.js");
3
4
  const EcRepository = require("../../../../org/cassproject/ebac/repository/EcRepository.js");