@63klabs/cache-data 1.2.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/CHANGELOG.md +234 -0
- package/LICENSE.txt +21 -0
- package/README.md +1265 -0
- package/SECURITY.md +5 -0
- package/package.json +58 -0
- package/src/index.js +9 -0
- package/src/lib/dao-cache.js +2024 -0
- package/src/lib/dao-endpoint.js +186 -0
- package/src/lib/tools/APIRequest.class.js +673 -0
- package/src/lib/tools/AWS.classes.js +250 -0
- package/src/lib/tools/CachedParametersSecrets.classes.js +492 -0
- package/src/lib/tools/ClientRequest.class.js +567 -0
- package/src/lib/tools/Connections.classes.js +466 -0
- package/src/lib/tools/DebugAndLog.class.js +416 -0
- package/src/lib/tools/ImmutableObject.class.js +71 -0
- package/src/lib/tools/RequestInfo.class.js +323 -0
- package/src/lib/tools/Response.class.js +547 -0
- package/src/lib/tools/ResponseDataModel.class.js +183 -0
- package/src/lib/tools/Timer.class.js +189 -0
- package/src/lib/tools/generic.response.html.js +88 -0
- package/src/lib/tools/generic.response.json.js +102 -0
- package/src/lib/tools/generic.response.rss.js +88 -0
- package/src/lib/tools/generic.response.text.js +86 -0
- package/src/lib/tools/generic.response.xml.js +82 -0
- package/src/lib/tools/index.js +318 -0
- package/src/lib/tools/utils.js +305 -0
- package/src/lib/tools/vars.js +34 -0
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
|
|
2
|
+
const ImmutableObject = require("./ImmutableObject.class");
|
|
3
|
+
|
|
4
|
+
/* ****************************************************************************
|
|
5
|
+
* ClientRequest Data Model
|
|
6
|
+
* ----------------------------------------------------------------------------
|
|
7
|
+
*
|
|
8
|
+
* Provides a class that stores information about the request
|
|
9
|
+
*
|
|
10
|
+
*************************************************************************** */
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Processes the request from the event data. Parses out
|
|
14
|
+
* client details such as ip and user agent. May be extended
|
|
15
|
+
* to provide custom processing for the application.
|
|
16
|
+
*/
|
|
17
|
+
class RequestInfo {
|
|
18
|
+
|
|
19
|
+
_requestInfo = null;
|
|
20
|
+
_isValid = false;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Process the event
|
|
24
|
+
* @param {object} event
|
|
25
|
+
*/
|
|
26
|
+
constructor(event) {
|
|
27
|
+
let req = this._gatherRequest(event);
|
|
28
|
+
this._requestInfo = new ImmutableObject( req , true);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Is the request valid? Validity is set by a series of checks
|
|
33
|
+
* during child class construction.
|
|
34
|
+
* Validity needs to be set by a child class, not this (super)
|
|
35
|
+
* class.
|
|
36
|
+
* @returns {boolean} Whether or not the request is valid.
|
|
37
|
+
*/
|
|
38
|
+
isValid() {
|
|
39
|
+
return this._isValid;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Standard toObject() but by default sensitive information is stripped out.
|
|
44
|
+
* Additional sensitive information may be stripped out by overriding this
|
|
45
|
+
* method. To receive the full object pass true.
|
|
46
|
+
*
|
|
47
|
+
* @param {boolean} full
|
|
48
|
+
* @returns {object} By default sensitive information is stripped out
|
|
49
|
+
*/
|
|
50
|
+
toObject(full = false) {
|
|
51
|
+
let obj = this._requestInfo.toObject();
|
|
52
|
+
|
|
53
|
+
if ( !full ) {
|
|
54
|
+
// strip out any fields we don't want in the logs
|
|
55
|
+
if ("client" in obj) {
|
|
56
|
+
if ("allHeaders" in obj.client) { delete obj.client.allHeaders; }
|
|
57
|
+
if ("headers" in obj.client) { delete obj.client.headers; }
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return obj;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Gets an object with data. So far the only key available is "client"
|
|
66
|
+
* which contains request fields from the client such as ip, user agent,
|
|
67
|
+
* etc.
|
|
68
|
+
* @param {string} key
|
|
69
|
+
* @returns {object} Data relating to the key
|
|
70
|
+
*/
|
|
71
|
+
get(key = "") {
|
|
72
|
+
return this._requestInfo.get(key);
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Get a data object associated with the client request.
|
|
77
|
+
* @param {*} key such as "userAgent", "ip", etc.
|
|
78
|
+
* @returns {*} Return a object ("headers", "userAgent", etc) from the client data
|
|
79
|
+
*/
|
|
80
|
+
getClient(key = "") {
|
|
81
|
+
let value = null;
|
|
82
|
+
let clientObj = this.get("client");
|
|
83
|
+
|
|
84
|
+
if ( key !== "" ) {
|
|
85
|
+
if (key in clientObj) { value = clientObj[key]; }
|
|
86
|
+
} else {
|
|
87
|
+
value = clientObj;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return value;
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* User Agent of client request
|
|
95
|
+
* @returns {string} The user agent string supplied by the client request
|
|
96
|
+
*/
|
|
97
|
+
getClientUserAgent() {
|
|
98
|
+
return this.getClient("userAgent");
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* IP of client request
|
|
103
|
+
* @returns {string} The IP string from the client request
|
|
104
|
+
*/
|
|
105
|
+
getClientIp() {
|
|
106
|
+
return this.getClient("ip");
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* @see getClientIp
|
|
111
|
+
* @returns {string}
|
|
112
|
+
*/
|
|
113
|
+
getClientIP() {
|
|
114
|
+
return this.getClientIp();
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Referrer of client request
|
|
119
|
+
* @param {boolean} full If true, return the full referrer string supplied by the client request. If false (default), return only the domain from the referrer string (no https:// and no path
|
|
120
|
+
* @returns {string} The referrer string supplied by the client request
|
|
121
|
+
*/
|
|
122
|
+
getClientReferrer(full=false) {
|
|
123
|
+
let referrer = this.getClient("referrer");
|
|
124
|
+
if (full) {
|
|
125
|
+
return referrer;
|
|
126
|
+
} else if (referrer !== null && referrer !== undefined) {
|
|
127
|
+
// return only the domain from the referrer string (no https:// and no path)
|
|
128
|
+
// remove 'https://' and 'http://' from the beginning.
|
|
129
|
+
referrer = referrer.replace(/^https?:\/\//, "");
|
|
130
|
+
// remove everything after the first '/'
|
|
131
|
+
referrer = referrer.split("/")[0];
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return referrer;
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* @see getClientReferrer
|
|
139
|
+
* @returns {string} The referrer string supplied by the client request
|
|
140
|
+
*/
|
|
141
|
+
getClientReferer(full=false) {
|
|
142
|
+
return this.getClientReferrer(full);
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Origin of client request
|
|
147
|
+
* @returns {string} The origin string supplied by the client request
|
|
148
|
+
*/
|
|
149
|
+
getClientOrigin() {
|
|
150
|
+
return this.getClient("origin");
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* If client requested data using the if-modified-since header field,
|
|
155
|
+
* the date that was supplied.
|
|
156
|
+
* @returns {string} The if modified since date string supplied by the client request
|
|
157
|
+
*/
|
|
158
|
+
getClientIfModifiedSince() {
|
|
159
|
+
return this.getClient("ifModifiedSince");
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* If client requested data using an eTag header field, the etag that
|
|
164
|
+
* was supplied.
|
|
165
|
+
* @returns {string} eTag supplied by the client for a match
|
|
166
|
+
*/
|
|
167
|
+
getClientIfNoneMatch() {
|
|
168
|
+
return this.getClient("ifNoneMatch");
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Response data format accepted by the client request
|
|
173
|
+
* @returns {string} Response data format accepted by the client request
|
|
174
|
+
*/
|
|
175
|
+
getClientAccept() {
|
|
176
|
+
return this.getClient("accept");
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
*
|
|
181
|
+
* @returns {object} The headers supplied in the client request
|
|
182
|
+
*/
|
|
183
|
+
getClientHeaders() {
|
|
184
|
+
return this.getClient("headers");
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
*
|
|
189
|
+
* @returns {object} The query string parameters supplied in the client request
|
|
190
|
+
*/
|
|
191
|
+
getClientParameters() {
|
|
192
|
+
return this.getClient("parameters");
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* For POST requests, if a body was supplied in the request.
|
|
197
|
+
* @returns {string} The body supplied in the client request
|
|
198
|
+
*/
|
|
199
|
+
getClientBody() {
|
|
200
|
+
return this.getClient("body");
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* There may be headers to pass along to an endpoint if our application
|
|
205
|
+
* is working as a proxy.
|
|
206
|
+
* @param {array} headerKeysToProxy An array of strings listing the header keys/fields to proxy
|
|
207
|
+
* @returns {array} Header keys to proxy
|
|
208
|
+
*/
|
|
209
|
+
getClientHeadersToProxy(headerKeysToProxy = []) {
|
|
210
|
+
let headers = {};
|
|
211
|
+
let clientHeaders = this.getClientHeaders();
|
|
212
|
+
|
|
213
|
+
if ( headerKeysToProxy.length === 0) {
|
|
214
|
+
headerKeysToProxy = ["accept", "if-modified-since", "if-none-match"];
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
headerKeysToProxy.forEach(function( h ) { headers[h] = clientHeaders[h]; });
|
|
218
|
+
|
|
219
|
+
return headers;
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Obtain lambda event request details for logging
|
|
225
|
+
* @param {*} event
|
|
226
|
+
* @returns Information about the requesting client including IP and user agent
|
|
227
|
+
*/
|
|
228
|
+
_clientRequestInfo (event) {
|
|
229
|
+
|
|
230
|
+
let client = { ip: null, userAgent: null, origin: null, referrer: null, ifModifiedSince: null, ifNoneMatch: null, accept: null, headers: {}, parameters: {}, body: null };
|
|
231
|
+
let identity = {};
|
|
232
|
+
let headers = {};
|
|
233
|
+
|
|
234
|
+
// identity data
|
|
235
|
+
if ( "requestContext" in event && "identity" in event.requestContext && event.requestContext.identity !== null ) {
|
|
236
|
+
identity = event.requestContext.identity;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// header data
|
|
240
|
+
if ( "headers" in event && event.headers !== null) {
|
|
241
|
+
// extract just the keys so we can iterate and lowercase
|
|
242
|
+
let hkeys = Object.keys(event.headers);
|
|
243
|
+
|
|
244
|
+
// move each value from event.headers to headers but lowercase the key
|
|
245
|
+
hkeys.forEach( function( k ) { headers[k.toLowerCase()] = event.headers[k]; });
|
|
246
|
+
} else {
|
|
247
|
+
headers = {};
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
client.headers = headers;
|
|
251
|
+
|
|
252
|
+
// set the source IP immediately for logging
|
|
253
|
+
if ( "sourceIp" in identity && identity.sourceIp !== null){
|
|
254
|
+
client.ip = identity.sourceIp;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// if there is a user-agent header, set it
|
|
258
|
+
if ( "userAgent" in identity && identity.userAgent !== null ) {
|
|
259
|
+
client.userAgent = identity.userAgent;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// if there is an origin header, set it
|
|
263
|
+
if ( headers?.origin) {
|
|
264
|
+
client.origin = headers.origin;
|
|
265
|
+
} // otherwise we'll just leave it as the default ""
|
|
266
|
+
|
|
267
|
+
// if there is a referrer header, set it
|
|
268
|
+
if ( headers?.referer) {
|
|
269
|
+
client.referrer = headers.referer.split("?")[0]; // for privacy we don't want the query string
|
|
270
|
+
} else {
|
|
271
|
+
client.referrer = client.origin;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// if there is a if-modified-since header, copy over
|
|
275
|
+
if ( "if-modified-since" in headers && headers['if-modified-since'] !== "" && headers['if-modified-since'] !== null) {
|
|
276
|
+
client.ifModifiedSince = headers['if-modified-since'];
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// if there is a if-none-match header, set it
|
|
280
|
+
if ( "if-none-match" in headers && headers['if-none-match'] !== "" && headers['if-none-match'] !== null ) {
|
|
281
|
+
client.ifNoneMatch = headers['if-none-match'];
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// if there is an accept header, set it
|
|
285
|
+
if ( "accept" in headers && headers.accept !== "" && headers.accept !== null ) {
|
|
286
|
+
client.accept = headers['accept'];
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// if query string parameters were passed, set it
|
|
290
|
+
if ( "queryStringParameters" in event && event.queryStringParameters !== null) {
|
|
291
|
+
client.parameters = event.queryStringParameters
|
|
292
|
+
} else {
|
|
293
|
+
client.parameters = {};
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// TODO:
|
|
297
|
+
// if body was passed in a post request, set it
|
|
298
|
+
if ( false ) {
|
|
299
|
+
client.body = null;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
return client;
|
|
303
|
+
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
*
|
|
308
|
+
* @param {*} event
|
|
309
|
+
* @returns Token and client info of the request. This is the stored object.
|
|
310
|
+
*/
|
|
311
|
+
_gatherRequest (event) {
|
|
312
|
+
|
|
313
|
+
let r = {
|
|
314
|
+
client: this._clientRequestInfo(event)
|
|
315
|
+
};
|
|
316
|
+
|
|
317
|
+
return r;
|
|
318
|
+
|
|
319
|
+
};
|
|
320
|
+
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
module.exports = RequestInfo;
|