@nsshunt/stsutils 1.3.26 → 1.5.2

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/authutils.js CHANGED
@@ -1,12 +1,20 @@
1
+ const debug = require('debug')(`stsutils`);
1
2
  const jwt = require('jsonwebtoken');
2
3
  const { status } = require('./status');
3
4
  const fs = require('fs');
4
5
  const goptions = require('@nsshunt/stsconfig').$options;
6
+ const tough = require('tough-cookie');
7
+ const Cookie = tough.Cookie;
8
+ const cookiejar = new tough.CookieJar();
9
+ const colors = require('colors');
10
+ const axios = require('axios');
11
+ const http = require('http');
5
12
 
6
13
  class AuthUtils
7
14
  {
8
15
  #privateKey = null;
9
16
  #publicKey = null;
17
+ #httpAgent = null;
10
18
 
11
19
  constructor()
12
20
  {
@@ -14,20 +22,25 @@ class AuthUtils
14
22
  // http://travistidwell.com/jsencrypt/demo/
15
23
  // https://www.csfieldguide.org.nz/en/interactives/rsa-key-generator/
16
24
  // https://jwt.io/
17
-
18
- // This code is for development / non-prod purposes only.
19
- // For production, the keys to come from a secrets store.
20
- this.#privateKey = fs.readFileSync(goptions.asprivatekeypath, 'utf8');
21
- this.#publicKey = fs.readFileSync(goptions.aspublickeypath, 'utf8');
22
25
  }
23
26
 
27
+ // This code is for development / non-prod purposes only.
28
+ // For production, the keys to come from a secrets store.
24
29
  get privateKey()
25
30
  {
31
+ if (this.#privateKey === null) {
32
+ this.#privateKey = fs.readFileSync(goptions.asprivatekeypath, 'utf8');
33
+ }
26
34
  return this.#privateKey;
27
35
  }
28
36
 
37
+ // This code is for development / non-prod purposes only.
38
+ // For production, the keys to come from a secrets store.
29
39
  get publicKey()
30
40
  {
41
+ if (this.#publicKey === null) {
42
+ this.#publicKey = fs.readFileSync(goptions.aspublickeypath, 'utf8');
43
+ }
31
44
  return this.#publicKey;
32
45
  }
33
46
 
@@ -84,7 +97,7 @@ class AuthUtils
84
97
  algorithm: ["RS256"] // RSASSA [ "RS256", "RS384", "RS512" ]
85
98
  };
86
99
 
87
- let retVal = jwt.verify(token, this.#publicKey, verifyOptions);
100
+ let retVal = jwt.verify(token, this.publicKey, verifyOptions);
88
101
 
89
102
  req.stsuser = {
90
103
  email: retVal.user.email,
@@ -105,6 +118,181 @@ class AuthUtils
105
118
  }
106
119
  }
107
120
  }
121
+
122
+ #GetDurationColour(duration)
123
+ {
124
+ if (duration > 250) {
125
+ return colors.red;
126
+ } else if (duration > 150) {
127
+ return colors.magenta;
128
+ } else if (duration > 50) {
129
+ return colors.blue;
130
+ } else if (duration > 10) {
131
+ return colors.green;
132
+ } else {
133
+ return colors.black;
134
+ }
135
+ }
136
+
137
+ LoginBrowser = async (options) => {
138
+ const { authendpoint, authUserName, authUserEMail, authUserPassword, defaultTimeout, publishDebug } = options;
139
+ try {
140
+ let processStart = performance.now();
141
+ let duration = 0;
142
+ let accessToken = null;
143
+ let payload = { name: authUserName, password: authUserPassword, email: authUserEMail }
144
+ let retVal = await axios({
145
+ url: `${authendpoint}/login`
146
+ ,method: 'post'
147
+ ,data: payload
148
+ ,timeout: defaultTimeout
149
+ });
150
+ duration = (performance.now() - processStart).toFixed(4);
151
+ if (publishDebug) debug(this.#GetDurationColour(duration)(`AuthUtils.LoginBrowser request duration: [${duration}]`));
152
+ accessToken = retVal.data.detail.token;
153
+ return {
154
+ accessToken: accessToken,
155
+ duration: duration
156
+ }
157
+ } catch (error) {
158
+ if (publishDebug) debug(`Error (AuthUtils:LoginBrowser): ${error}`.red);
159
+ throw error;
160
+ }
161
+ };
162
+
163
+ // https://stackoverflow.com/questions/43002444/make-axios-send-cookies-in-its-requests-automatically
164
+ // axios.get('some api url', {withCredentials: true});
165
+ // https://medium.com/@adityasrivast/handling-cookies-with-axios-872790241a9b
166
+ // https://www.codegrepper.com/code-examples/javascript/axios+send+cookies
167
+ // http only cookies
168
+ RefreshAuthTokenBrowser = async (options) => {
169
+ const { authendpoint, defaultTimeout, publishDebug } = options;
170
+ try {
171
+ let processStart = performance.now();
172
+ let duration = 0;
173
+ let accessToken = null;
174
+ // https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials
175
+ // https://stackoverflow.com/questions/43002444/make-axios-send-cookies-in-its-requests-automatically
176
+ // axios.get('some api url', {withCredentials: true});
177
+ let retVal = await axios({
178
+ url: `${authendpoint}/refreshtoken`
179
+ ,method: 'post'
180
+ ,timeout: defaultTimeout
181
+ ,withCredentials: true
182
+ });
183
+ duration = (performance.now() - processStart).toFixed(4);
184
+ if (publishDebug) debug(this.#GetDurationColour(duration)(`AuthUtils.RefreshAuthTokenBrowser request duration: [${duration}]`));
185
+ accessToken = retVal.data.detail.token;
186
+ return {
187
+ accessToken: accessToken,
188
+ duration: duration
189
+ }
190
+ } catch (error) {
191
+ if (publishDebug) debug(`Error (AuthUtils:RefreshAuthTokenBrowser): ${error}`.red);
192
+ throw error;
193
+ }
194
+ }
195
+
196
+ #setCookiesToJar = (authendpoint, headers) =>
197
+ {
198
+ let cookies = null;
199
+ if (headers['set-cookie'] instanceof Array)
200
+ cookies = headers['set-cookie'].map(Cookie.parse);
201
+ else
202
+ cookies = [Cookie.parse(headers['set-cookie'])];
203
+
204
+ return cookiejar.setCookie(cookies[0], `${authendpoint}`);
205
+ };
206
+
207
+ #getCookiesFromJar = (authendpoint) =>
208
+ {
209
+ return cookiejar.getCookies(`${authendpoint}`);
210
+ };
211
+
212
+ #getHttpAgent = () =>
213
+ {
214
+ if (this.#httpAgent === null) {
215
+ // https://nodejs.org/api/http.html#class-httpagent
216
+ this.#httpAgent = new http.Agent({
217
+ keepAlive: true,
218
+ maxSockets: 10,
219
+ maxTotalSockets: 10,
220
+ maxFreeSockets: 10,
221
+ timeout: 5000
222
+ });
223
+ }
224
+ return this.#httpAgent;
225
+ }
226
+
227
+ LoginNode = async (options) =>
228
+ {
229
+ const { authendpoint, authUserName, authUserEMail, authUserPassword, defaultTimeout, publishDebug } = options;
230
+ try {
231
+ let processStart = performance.now();
232
+ let duration = 0;
233
+ let accessToken = null;
234
+ let payload = { name: authUserName, password: authUserPassword, email: authUserEMail }
235
+ let retVal = await axios({
236
+ url: `${authendpoint}/login`
237
+ ,method: 'post'
238
+ ,data: payload
239
+ ,timeout: defaultTimeout
240
+ ,httpAgent: this.#getHttpAgent()
241
+ // Use below if using a socket endpoint
242
+ //,socketPath: '/var/run/sts/stsrest01.sock'
243
+ });
244
+ duration = (performance.now() - processStart).toFixed(4);
245
+ if (publishDebug) debug(this.#GetDurationColour(duration)(`AuthUtils.LoginNode request duration: [${duration}]`));
246
+ accessToken = retVal.data.detail.token;
247
+ await this.#setCookiesToJar(authendpoint, retVal.headers);
248
+ return {
249
+ accessToken: accessToken,
250
+ duration: duration
251
+ }
252
+ } catch (error)
253
+ {
254
+ if (publishDebug) debug(`Error (AuthUtils:LoginNode): ${error}`.red);
255
+ throw error;
256
+ }
257
+ }
258
+
259
+ // https://stackoverflow.com/questions/43002444/make-axios-send-cookies-in-its-requests-automatically
260
+ // axios.get('some api url', {withCredentials: true});
261
+ // https://medium.com/@adityasrivast/handling-cookies-with-axios-872790241a9b
262
+ // https://www.codegrepper.com/code-examples/javascript/axios+send+cookies
263
+ // http only cookies
264
+ RefreshAuthTokenNode = async (options) =>
265
+ {
266
+ const { authendpoint, defaultTimeout, publishDebug } = options;
267
+ try {
268
+ let processStart = performance.now();
269
+ let duration = 0;
270
+ let accessToken = null;
271
+ let cookies = await this.#getCookiesFromJar(authendpoint);
272
+ let retVal = await axios({
273
+ url: `${authendpoint}/refreshtoken`
274
+ ,method: 'post'
275
+ ,headers: {
276
+ Cookie: cookies
277
+ }
278
+ ,timeout: defaultTimeout
279
+ ,httpAgent: this.#httpAgent,
280
+ // Use below for socket connections
281
+ //,socketPath: '/var/run/sts/stsrest01.sock'
282
+ });
283
+ duration = (performance.now() - processStart).toFixed(4);
284
+ if (publishDebug) debug(this.#GetDurationColour(duration)(`AuthUtils.RefreshAuthTokenBrowser request duration: [${duration}]`));
285
+ accessToken = retVal.data.detail.token;
286
+ await this.#setCookiesToJar(authendpoint, retVal.headers);
287
+ return {
288
+ accessToken: accessToken,
289
+ duration: duration
290
+ }
291
+ } catch (error) {
292
+ if (publishDebug) debug(`Error (AuthUtils:RefreshAuthTokenBrowser): ${error}`.red);
293
+ throw error;
294
+ }
295
+ }
108
296
  }
109
297
 
110
298
  module.exports = { AuthUtils };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nsshunt/stsutils",
3
- "version": "1.3.26",
3
+ "version": "1.5.2",
4
4
  "description": "",
5
5
  "main": "stsutils.js",
6
6
  "scripts": {
@@ -22,18 +22,19 @@
22
22
  "parser": "@babel/eslint-parser"
23
23
  },
24
24
  "devDependencies": {
25
- "@babel/core": "^7.16.0",
26
- "@babel/eslint-parser": "^7.16.3",
27
- "@babel/plugin-proposal-class-properties": "^7.16.0",
28
- "@babel/plugin-proposal-private-methods": "^7.16.0",
29
- "eslint": "^8.3.0",
30
- "jest": "^27.4.3"
25
+ "@babel/core": "^7.16.5",
26
+ "@babel/eslint-parser": "^7.16.5",
27
+ "@babel/plugin-proposal-class-properties": "^7.16.5",
28
+ "@babel/plugin-proposal-private-methods": "^7.16.5",
29
+ "eslint": "^8.4.1",
30
+ "jest": "^27.4.5"
31
31
  },
32
32
  "dependencies": {
33
- "@nsshunt/stsconfig": "^1.3.22",
33
+ "@nsshunt/stsconfig": "^1.4.0",
34
34
  "colors": "^1.4.0",
35
35
  "debug": "^4.3.3",
36
36
  "express": "^4.17.1",
37
- "jsonwebtoken": "^8.5.1"
37
+ "jsonwebtoken": "^8.5.1",
38
+ "tough-cookie": "^4.0.0"
38
39
  }
39
40
  }
package/stsutils.js CHANGED
@@ -1,9 +1,7 @@
1
1
  let sleep = require('./sleep.js');
2
2
  let status = require('./status.js');
3
- let network = require('./network.js');
4
3
  let authutils = require('./authutils.js');
5
4
  let stsoptionsbase = require('./stsoptionsbase.js');
6
5
  let stsrouterbase = require('./stsrouterbase.js');
7
- let log = require('./log.js');
8
6
 
9
- module.exports = { sleep, status, network, authutils, stsoptionsbase, stsrouterbase, log };
7
+ module.exports = { sleep, status, authutils, stsoptionsbase, stsrouterbase };
package/log.js DELETED
@@ -1,33 +0,0 @@
1
- const cluster = require('cluster');
2
- const colors = require('colors');
3
- const debug = require('debug')(`proc:${process.pid}`);
4
-
5
- /**
6
- * Default styles :-
7
- * Worker messages - green
8
- * Master messages - cyan + bold
9
- * IPC Messages - grey. The message command itself will be bold.
10
- * Signals - yellow (e.g. SIGINT or SIGTERM etc.
11
- * @param {*} instruments
12
- * @returns
13
- */
14
- module.exports = (appName, instruments) =>
15
- {
16
- return (msg) =>
17
- {
18
- let prefix = '';
19
- let col = null;
20
-
21
- if (cluster.isMaster)
22
- {
23
- prefix = 'M';
24
- col = colors.bold.cyan;
25
- } else {
26
- prefix = 'W';
27
- col = colors.green;
28
- }
29
- let msgEx = col(`${prefix}(${process.pid}) [${appName}]: ${msg}`);
30
- debug(msgEx);
31
- instruments.logger.LogMessage(msgEx);
32
- };
33
- };
package/network.js DELETED
@@ -1,37 +0,0 @@
1
- const os = require('os');
2
-
3
- const GetNetworkInterfaces = () =>
4
- {
5
- const nets = os.networkInterfaces();
6
- let results = { };
7
- for (const name of Object.keys(nets)) {
8
- for (const net of nets[name]) {
9
- // Skip over non-IPv4 and internal (i.e. 127.0.0.1) addresses
10
- if (net.family === 'IPv4' && !net.internal) {
11
- if (!results[name]) {
12
- results[name] = [];
13
- }
14
- results[name].push(net.address);
15
- }
16
- }
17
- }
18
- return results;
19
- };
20
-
21
- const GetFirstNetworkInterface = () =>
22
- {
23
- let nics = GetNetworkInterfaces();
24
- let hostaddr = null;
25
- for (let nic in nics)
26
- {
27
- let val = nics[nic];
28
- if (val.length > 0)
29
- {
30
- hostaddr = val[0];
31
- break;
32
- }
33
- }
34
- return hostaddr;
35
- }
36
-
37
- module.exports = { GetNetworkInterfaces, GetFirstNetworkInterface }