@63klabs/cache-data 1.3.9 → 1.3.11

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.
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Centralized generic response module factory.
3
+ *
4
+ * Encapsulates the shared STATUS_CODE_MAP, response object generation, and
5
+ * response() lookup function used by all five format-specific generic response
6
+ * files (HTML, JSON, RSS, Text, XML).
7
+ *
8
+ * @module generic.response
9
+ */
10
+
11
+ /**
12
+ * Map of HTTP status codes to their default message strings.
13
+ *
14
+ * @type {Object.<number, string>}
15
+ */
16
+ const STATUS_CODE_MAP = {
17
+ 200: "Success",
18
+ 400: "Bad Request",
19
+ 401: "Unauthorized",
20
+ 403: "Forbidden",
21
+ 404: "Not Found",
22
+ 405: "Method Not Allowed",
23
+ 408: "Request Timeout",
24
+ 418: "I'm a teapot",
25
+ 427: "Too Many Requests",
26
+ 500: "Internal Server Error"
27
+ };
28
+
29
+ /**
30
+ * Create a complete generic response module for a given content type and body formatter.
31
+ *
32
+ * Iterates over STATUS_CODE_MAP, calls bodyFormatter(statusCode, message) for each
33
+ * entry, and builds the response objects. Attaches a response() function that parses
34
+ * the status code to an integer and looks up the matching response object, falling
35
+ * back to response500 for unknown codes.
36
+ *
37
+ * @param {string} contentType - MIME content type string (e.g., "application/json")
38
+ * @param {function(number, string): *} bodyFormatter - Function that transforms (statusCode, message) into format-specific body
39
+ * @returns {{contentType: string, headers: Object, response200: Object, response400: Object, response401: Object, response403: Object, response404: Object, response405: Object, response408: Object, response418: Object, response427: Object, response500: Object, response: function(number|string): Object}}
40
+ * @example
41
+ * const { createGenericResponseModule } = require("./generic.response");
42
+ *
43
+ * const mod = createGenericResponseModule("application/json", (statusCode, message) => ({ message }));
44
+ * console.log(mod.response200.body); // { message: "Success" }
45
+ * console.log(mod.response(404).statusCode); // 404
46
+ */
47
+ function createGenericResponseModule(contentType, bodyFormatter) {
48
+ const headers = { "Content-Type": contentType };
49
+
50
+ const mod = {
51
+ contentType: contentType,
52
+ headers: headers
53
+ };
54
+
55
+ for (const code in STATUS_CODE_MAP) {
56
+ const statusCode = parseInt(code, 10);
57
+ const message = STATUS_CODE_MAP[code];
58
+ mod["response" + statusCode] = {
59
+ statusCode: statusCode,
60
+ headers: headers,
61
+ body: bodyFormatter(statusCode, message)
62
+ };
63
+ }
64
+
65
+ mod.response = function (statusCode) {
66
+ statusCode = parseInt(statusCode, 10);
67
+ return this["response" + statusCode] || this.response500;
68
+ };
69
+
70
+ return mod;
71
+ }
72
+
73
+ module.exports = { createGenericResponseModule };
@@ -1,141 +1,11 @@
1
- contentType = "application/json"
1
+ const { createGenericResponseModule } = require("./generic.response");
2
2
 
3
- headers = {
4
- "Content-Type": contentType
5
- };
3
+ const jsonBodyFormatter = (statusCode, message) => ({ message });
6
4
 
7
- json = function (data = null) {
5
+ const json = function (data = null) {
8
6
  return data ? data : {};
9
7
  };
10
8
 
11
- response200 = {
12
- statusCode: 200,
13
- headers: headers,
14
- body: {
15
- message: "Success"
16
- }
17
- };
18
-
19
- response400 = {
20
- statusCode: 400,
21
- headers: headers,
22
- body: {
23
- message: "Bad Request"
24
- }
25
- };
26
-
27
- response401 = {
28
- statusCode: 401,
29
- headers: headers,
30
- body: {
31
- message: "Unauthorized"
32
- }
33
- };
34
-
35
- response403 = {
36
- statusCode: 403,
37
- headers: headers,
38
- body: {
39
- message: "Forbidden"
40
- }
41
- };
42
-
43
- response404 = {
44
- statusCode: 404,
45
- headers: headers,
46
- body: {
47
- message: "Not Found"
48
- }
49
- };
50
-
51
- response405 = {
52
- statusCode: 405,
53
- headers: headers,
54
- body: {
55
- message: "Method Not Allowed"
56
- }
57
- };
58
-
59
- response408 = {
60
- statusCode: 408,
61
- headers: headers,
62
- body: {
63
- message: "Request Timeout"
64
- }
65
- };
66
-
67
- response418 = {
68
- statusCode: 418,
69
- headers: headers,
70
- body: {
71
- message: "I'm a teapot"
72
- }
73
- };
74
-
75
- response427 = {
76
- statusCode: 427,
77
- headers: headers,
78
- body: {
79
- message: "Too Many Requests"
80
- }
81
- };
82
-
83
- response500 = {
84
- statusCode: 500,
85
- headers: headers,
86
- body: {
87
- message: "Internal Server Error"
88
- }
89
- };
90
-
91
- /**
92
- *
93
- * @param {number|string} statusCode
94
- * @returns {{statusCode: number, headers: object, body: Array|Object|string}}
95
- */
96
- const response = function (statusCode) {
97
- // convert to int
98
- statusCode = parseInt(statusCode, 10);
99
-
100
- switch (statusCode) {
101
- case 200:
102
- return this.response200;
103
- case 400:
104
- return this.response400;
105
- case 401:
106
- return this.response401;
107
- case 403:
108
- return this.response403;
109
- case 404:
110
- return this.response404;
111
- case 405:
112
- return this.response405;
113
- case 408:
114
- return this.response408;
115
- case 418:
116
- return this.response418;
117
- case 427:
118
- return this.response427;
119
- case 500:
120
- return this.response500;
121
- default:
122
- return this.response500;
123
- }
124
- };
9
+ const mod = createGenericResponseModule("application/json", jsonBodyFormatter);
125
10
 
126
- module.exports = {
127
- contentType,
128
- headers,
129
- json,
130
- response200,
131
- response400,
132
- response401,
133
- response403,
134
- response404,
135
- response405,
136
- response408,
137
- response418,
138
- response427,
139
- response500,
140
- response
141
- }
11
+ module.exports = { ...mod, json };
@@ -1,121 +1,17 @@
1
- contentType = "application/rss+xml";
1
+ const { createGenericResponseModule } = require("./generic.response");
2
2
 
3
- headers = {
4
- "Content-Type": contentType
5
- };
6
-
7
- rss = (body) => {
3
+ const rss = (body) => {
8
4
  return `<?xml version="1.0" encoding="UTF-8" ?><rss version="2.0">${body}</rss>`;
9
- }
10
-
11
- response200 = {
12
- statusCode: 200,
13
- headers: headers,
14
- body: rss("<hello>Success</hello>")
15
- };
16
-
17
- response400 = {
18
- statusCode: 400,
19
- headers: headers,
20
- body: rss("<error>Bad Request</error>")
21
- };
22
-
23
- response401 = {
24
- statusCode: 401,
25
- headers: headers,
26
- body: rss("<error>Unauthorized</error>")
27
- };
28
-
29
- response403 = {
30
- statusCode: 403,
31
- headers: headers,
32
- body: rss("<error>Forbidden</error>")
33
5
  };
34
6
 
35
- response404 = {
36
- statusCode: 404,
37
- headers: headers,
38
- body: rss("<error>Not Found</error>")
39
- };
40
-
41
- response405 = {
42
- statusCode: 405,
43
- headers: headers,
44
- body: rss("<error>Method Not Allowed</error>")
45
- };
46
-
47
- response408 = {
48
- statusCode: 408,
49
- headers: headers,
50
- body: rss("<error>Request Timeout</error>")
51
- };
52
-
53
- response418 = {
54
- statusCode: 418,
55
- headers: headers,
56
- body: rss("<error>418 I'm a teapot</error>")
57
- };
58
-
59
- response427 = {
60
- statusCode: 427,
61
- headers: headers,
62
- body: rss("<error>Too Many Requests</error>")
63
- };
64
-
65
- response500 = {
66
- statusCode: 500,
67
- headers: headers,
68
- body: rss("<error>Internal Server Error</error>")
69
- };
70
-
71
- /**
72
- *
73
- * @param {number|string} statusCode
74
- * @returns {{statusCode: number, headers: object, body: Array|Object|string}}
75
- */
76
- response = function (statusCode) {
77
- // convert to int
78
- statusCode = parseInt(statusCode, 10);
79
-
80
- switch (statusCode) {
81
- case 200:
82
- return this.response200;
83
- case 400:
84
- return this.response400;
85
- case 401:
86
- return this.response401;
87
- case 403:
88
- return this.response403;
89
- case 404:
90
- return this.response404;
91
- case 405:
92
- return this.response405;
93
- case 408:
94
- return this.response408;
95
- case 418:
96
- return this.response418;
97
- case 427:
98
- return this.response427;
99
- case 500:
100
- return this.response500;
101
- default:
102
- return this.response500;
7
+ const rssBodyFormatter = (statusCode, message) => {
8
+ if (statusCode === 200) {
9
+ return rss("<hello>" + message + "</hello>");
103
10
  }
11
+ const msg = statusCode === 418 ? "418 " + message : message;
12
+ return rss("<error>" + msg + "</error>");
104
13
  };
105
14
 
106
- module.exports = {
107
- contentType,
108
- headers,
109
- rss,
110
- response200,
111
- response400,
112
- response401,
113
- response403,
114
- response404,
115
- response405,
116
- response408,
117
- response418,
118
- response427,
119
- response500,
120
- response
121
- }
15
+ const mod = createGenericResponseModule("application/rss+xml", rssBodyFormatter);
16
+
17
+ module.exports = { ...mod, rss };
@@ -1,119 +1,9 @@
1
- contentType = "text/plain";
1
+ const { createGenericResponseModule } = require("./generic.response");
2
2
 
3
- headers = {
4
- "Content-Type": contentType
5
- };
3
+ const textBodyFormatter = (statusCode, message) => message;
6
4
 
7
- text = (text) => { return text; }
5
+ const text = (text) => { return text; };
8
6
 
9
- response200 = {
10
- statusCode: 200,
11
- headers: headers,
12
- body: text("Success")
13
- };
7
+ const mod = createGenericResponseModule("text/plain", textBodyFormatter);
14
8
 
15
- response400 = {
16
- statusCode: 400,
17
- headers: headers,
18
- body: text("Bad Request")
19
- };
20
-
21
- response401 = {
22
- statusCode: 401,
23
- headers: headers,
24
- body: text("Unauthorized")
25
- };
26
-
27
- response403 = {
28
- statusCode: 403,
29
- headers: headers,
30
- body: text("Forbidden")
31
- };
32
-
33
- response404 = {
34
- statusCode: 404,
35
- headers: headers,
36
- body: text("Not Found")
37
- };
38
-
39
- response405 = {
40
- statusCode: 405,
41
- headers: headers,
42
- body: text("Method Not Allowed")
43
- };
44
-
45
- response408 = {
46
- statusCode: 408,
47
- headers: headers,
48
- body: text("Request Timeout")
49
- };
50
-
51
- response418 = {
52
- statusCode: 418,
53
- headers: headers,
54
- body: text("I'm a teapot")
55
- };
56
-
57
- response427 = {
58
- statusCode: 427,
59
- headers: headers,
60
- body: text("Too Many Requests")
61
- };
62
-
63
- response500 = {
64
- statusCode: 500,
65
- headers: headers,
66
- body: text("Internal Server Error")
67
- };
68
-
69
- /**
70
- *
71
- * @param {number|string} statusCode
72
- * @returns {{statusCode: number, headers: object, body: Array|Object|string}}
73
- */
74
- const response = function (statusCode) {
75
- // convert to int
76
- statusCode = parseInt(statusCode, 10);
77
-
78
- switch (statusCode) {
79
- case 200:
80
- return this.response200;
81
- case 400:
82
- return this.response400;
83
- case 401:
84
- return this.response401;
85
- case 403:
86
- return this.response403;
87
- case 404:
88
- return this.response404;
89
- case 405:
90
- return this.response405;
91
- case 408:
92
- return this.response408;
93
- case 418:
94
- return this.response418;
95
- case 427:
96
- return this.response427;
97
- case 500:
98
- return this.response500;
99
- default:
100
- return this.response500;
101
- }
102
- };
103
-
104
- module.exports = {
105
- contentType,
106
- headers,
107
- text,
108
- response200,
109
- response400,
110
- response401,
111
- response403,
112
- response404,
113
- response405,
114
- response408,
115
- response418,
116
- response427,
117
- response500,
118
- response
119
- }
9
+ module.exports = { ...mod, text };
@@ -1,121 +1,17 @@
1
- contentType = "application/xml";
1
+ const { createGenericResponseModule } = require("./generic.response");
2
2
 
3
- headers = {
4
- "Content-Type": contentType
5
- };
6
-
7
- xml = (body) => {
3
+ const xml = (body) => {
8
4
  return `<?xml version="1.0" encoding="UTF-8" ?>${body}`;
9
- }
10
-
11
- response200 = {
12
- statusCode: 200,
13
- headers: headers,
14
- body: xml("<hello>Success</hello>")
15
- };
16
-
17
- response400 = {
18
- statusCode: 400,
19
- headers: headers,
20
- body: xml("<error>Bad Request</error>")
21
- };
22
-
23
- response401 = {
24
- statusCode: 401,
25
- headers: headers,
26
- body: xml("<error>Unauthorized</error>")
27
- };
28
-
29
- response403 = {
30
- statusCode: 403,
31
- headers: headers,
32
- body: xml("<error>Forbidden</error>")
33
5
  };
34
6
 
35
- response404 = {
36
- statusCode: 404,
37
- headers: headers,
38
- body: xml("<error>Not Found</error>")
39
- };
40
-
41
- response405 = {
42
- statusCode: 405,
43
- headers: headers,
44
- body: xml("<error>Method Not Allowed</error>")
45
- };
46
-
47
- response408 = {
48
- statusCode: 408,
49
- headers: headers,
50
- body: xml("<error>Request Timeout</error>")
51
- };
52
-
53
- response418 = {
54
- statusCode: 418,
55
- headers: headers,
56
- body: xml("<error>418 I'm a teapot</error>")
57
- };
58
-
59
- response427 = {
60
- statusCode: 427,
61
- headers: headers,
62
- body: xml("<error>Too Many Requests</error>")
63
- };
64
-
65
- response500 = {
66
- statusCode: 500,
67
- headers: headers,
68
- body: xml("<error>Internal Server Error</error>")
69
- };
70
-
71
- /**
72
- *
73
- * @param {number|string} statusCode
74
- * @returns {{statusCode: number, headers: object, body: Array|Object|string}}
75
- */
76
- response = function (statusCode) {
77
- // convert to int
78
- statusCode = parseInt(statusCode, 10);
79
-
80
- switch (statusCode) {
81
- case 200:
82
- return this.response200;
83
- case 400:
84
- return this.response400;
85
- case 401:
86
- return this.response401;
87
- case 403:
88
- return this.response403;
89
- case 404:
90
- return this.response404;
91
- case 405:
92
- return this.response405;
93
- case 408:
94
- return this.response408;
95
- case 418:
96
- return this.response418;
97
- case 427:
98
- return this.response427;
99
- case 500:
100
- return this.response500;
101
- default:
102
- return this.response500;
7
+ const xmlBodyFormatter = (statusCode, message) => {
8
+ if (statusCode === 200) {
9
+ return xml("<hello>" + message + "</hello>");
103
10
  }
11
+ const msg = statusCode === 418 ? "418 " + message : message;
12
+ return xml("<error>" + msg + "</error>");
104
13
  };
105
14
 
106
- module.exports = {
107
- contentType,
108
- headers,
109
- xml,
110
- response200,
111
- response400,
112
- response401,
113
- response403,
114
- response404,
115
- response405,
116
- response408,
117
- response418,
118
- response427,
119
- response500,
120
- response
121
- }
15
+ const mod = createGenericResponseModule("application/xml", xmlBodyFormatter);
16
+
17
+ module.exports = { ...mod, xml };
@@ -20,7 +20,7 @@
20
20
 
21
21
  const { nodeVer, nodeVerMajor, nodeVerMinor, nodeVerMajorMinor } = require('./vars');
22
22
  const { AWS, AWSXRay } = require('./AWS.classes');
23
- const APIRequest = require("./APIRequest.class");
23
+ const ApiRequest = require("./ApiRequest.class");
24
24
  const RequestInfo = require("./RequestInfo.class");
25
25
  const ClientRequest = require("./ClientRequest.class");
26
26
  const ResponseDataModel = require("./ResponseDataModel.class");
@@ -34,7 +34,7 @@ const xmlGenericResponse = require('./generic.response.xml');
34
34
  const rssGenericResponse = require('./generic.response.rss');
35
35
  const textGenericResponse = require('./generic.response.text');
36
36
  const { printMsg, sanitize, obfuscate, hashThisData} = require('./utils');
37
- const { CachedParameterSecrets, CachedParameterSecret, CachedSSMParameter, CachedSecret } = require('./CachedParametersSecrets.classes')
37
+ const { CachedParameterSecrets, CachedParameterSecret, CachedSsmParameter, CachedSecret } = require('./CachedParametersSecrets.classes')
38
38
  const { Connections, Connection, ConnectionRequest, ConnectionAuthentication } = require('./Connections.classes')
39
39
 
40
40
  /*
@@ -295,7 +295,7 @@ class AppConfig {
295
295
  * const conn = Config.getConn('myConnection');
296
296
  * const cacheObj = await CacheableDataAccess.getData(
297
297
  * cacheProfile,
298
- * endpoint.get
298
+ * endpoint.send
299
299
  * conn
300
300
  * )
301
301
  * */
@@ -322,7 +322,7 @@ class AppConfig {
322
322
  * const { conn, cacheProfile } = Config.getConnCacheProfile('myConnection', 'myCacheProfile');
323
323
  * const cacheObj = await CacheableDataAccess.getData(
324
324
  * cacheProfile,
325
- * endpoint.get
325
+ * endpoint.send
326
326
  * conn
327
327
  * )
328
328
  */
@@ -463,6 +463,14 @@ class AppConfig {
463
463
  // put the parameter into its group
464
464
  const obj = parameters.find(o => o.path === groupPath);
465
465
  const group = obj.group;
466
+
467
+ // >! Guard against prototype pollution (CWE-471)
468
+ const DANGEROUS_KEYS = ['__proto__', 'constructor', 'prototype'];
469
+ if (DANGEROUS_KEYS.includes(group) || DANGEROUS_KEYS.includes(name)) {
470
+ DebugAndLog.warn(`Skipping dangerous parameter key: group="${group}", name="${name}"`);
471
+ return;
472
+ }
473
+
466
474
  if ( !(group in paramstore)) {
467
475
  paramstore[group] = {};
468
476
  }
@@ -534,8 +542,9 @@ module.exports = {
534
542
  Aws: AWS,
535
543
  AWSXRay,
536
544
  AwsXRay: AWSXRay, // Alias
537
- APIRequest,
538
- ApiRequest: APIRequest, // Alias
545
+ ApiRequest,
546
+ /** @deprecated Use ApiRequest instead */
547
+ APIRequest: ApiRequest, // Alias
539
548
  ImmutableObject,
540
549
  Timer,
541
550
  DebugAndLog,
@@ -548,9 +557,11 @@ module.exports = {
548
557
  ResponseDataModel,
549
558
  Response,
550
559
  AppConfig,
560
+ /** @deprecated Use AppConfig instead */
551
561
  _ConfigSuperClass: AppConfig, // Alias
552
- CachedSSMParameter,
553
- CachedSsmParameter: CachedSSMParameter, // Alias
562
+ CachedSsmParameter,
563
+ /** @deprecated Use CachedSsmParameter instead */
564
+ CachedSSMParameter: CachedSsmParameter, // Alias
554
565
  CachedSecret,
555
566
  CachedParameterSecret,
556
567
  CachedParameterSecrets,