@bitblit/ratchet-epsilon-common 4.0.115-alpha → 4.0.119-alpha

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.
Files changed (180) hide show
  1. package/lib/background/background-dynamo-log-table-handler.d.ts +1 -1
  2. package/lib/background/background-handler.d.ts +1 -1
  3. package/lib/background/background-http-adapter-handler.d.ts +1 -1
  4. package/lib/background/background-validator.d.ts +1 -1
  5. package/lib/build/ratchet-epsilon-common-info.d.ts +1 -1
  6. package/lib/built-in/daemon/daemon-authorizer-function.d.ts +1 -1
  7. package/lib/built-in/daemon/daemon-handler.d.ts +2 -2
  8. package/lib/built-in/daemon/daemon-process-state-list.d.ts +1 -1
  9. package/lib/built-in/http/built-in-auth-filters.d.ts +1 -1
  10. package/lib/cli/ratchet-cli-handler.d.ts +2 -2
  11. package/lib/config/epsilon-logger-config.d.ts +2 -2
  12. package/lib/config/http/filter-chain-context.d.ts +1 -1
  13. package/lib/config/http/http-config.d.ts +1 -1
  14. package/lib/epsilon-global-handler.d.ts +1 -1
  15. package/lib/epsilon-instance.d.ts +1 -1
  16. package/lib/epsilon-logging-extension-processor.d.ts +2 -2
  17. package/lib/http/auth/auth0-web-token-manipulator.d.ts +1 -1
  18. package/lib/http/auth/google-web-token-manipulator.d.ts +1 -1
  19. package/lib/http/auth/jwt-ratchet-local-web-token-manipulator.d.ts +2 -2
  20. package/lib/http/auth/local-web-token-manipulator.d.ts +3 -3
  21. package/lib/http/auth/web-token-manipulator.d.ts +1 -1
  22. package/lib/http/event-util.d.ts +1 -1
  23. package/lib/http/response-util.d.ts +1 -1
  24. package/lib/http/route/epsilon-router.d.ts +1 -1
  25. package/lib/http/route/router-util.d.ts +2 -2
  26. package/lib/index.d.ts +132 -1
  27. package/lib/index.mjs +344 -0
  28. package/lib/index.mjs.map +1 -0
  29. package/lib/local-container-server.d.ts +1 -1
  30. package/lib/local-server.d.ts +1 -1
  31. package/lib/sample/test-error-server.d.ts +1 -1
  32. package/lib/util/epsilon-config-parser.d.ts +1 -1
  33. package/package.json +18 -19
  34. package/lib/background/background-dynamo-log-table-handler.js +0 -37
  35. package/lib/background/background-entry.js +0 -1
  36. package/lib/background/background-execution-event-type.js +0 -8
  37. package/lib/background/background-execution-event.js +0 -1
  38. package/lib/background/background-execution-listener.js +0 -1
  39. package/lib/background/background-handler.js +0 -273
  40. package/lib/background/background-http-adapter-handler.js +0 -128
  41. package/lib/background/background-meta-response-internal.js +0 -1
  42. package/lib/background/background-process-handling.js +0 -5
  43. package/lib/background/background-process-log-table-entry.js +0 -1
  44. package/lib/background/background-queue-response-internal.js +0 -1
  45. package/lib/background/background-validator.js +0 -86
  46. package/lib/background/epsilon-background-process-error.js +0 -93
  47. package/lib/background/internal-background-entry.js +0 -1
  48. package/lib/background/manager/abstract-background-manager.js +0 -89
  49. package/lib/background/manager/aws-sqs-sns-background-manager.js +0 -153
  50. package/lib/background/manager/background-manager-like.js +0 -1
  51. package/lib/background/manager/background-manager.spec.js +0 -73
  52. package/lib/background/manager/single-thread-local-background-manager.js +0 -45
  53. package/lib/background/s3-background-transaction-logger.js +0 -52
  54. package/lib/build/ratchet-epsilon-common-info.js +0 -14
  55. package/lib/built-in/background/echo-processor.js +0 -15
  56. package/lib/built-in/background/log-and-enqueue-echo-processor.js +0 -12
  57. package/lib/built-in/background/log-message-background-error-processor.js +0 -6
  58. package/lib/built-in/background/no-op-processor.js +0 -9
  59. package/lib/built-in/background/retry-processor.js +0 -40
  60. package/lib/built-in/background/sample-delay-processor.js +0 -13
  61. package/lib/built-in/background/sample-input-validated-processor-data.js +0 -1
  62. package/lib/built-in/background/sample-input-validated-processor.js +0 -12
  63. package/lib/built-in/built-in-trace-id-generators.js +0 -21
  64. package/lib/built-in/daemon/daemon-authorizer-function.js +0 -1
  65. package/lib/built-in/daemon/daemon-config.js +0 -1
  66. package/lib/built-in/daemon/daemon-group-selection-function.js +0 -1
  67. package/lib/built-in/daemon/daemon-handler.js +0 -59
  68. package/lib/built-in/daemon/daemon-process-state-list.js +0 -1
  69. package/lib/built-in/http/apollo-filter.js +0 -59
  70. package/lib/built-in/http/built-in-auth-filters.js +0 -107
  71. package/lib/built-in/http/built-in-authorizers.js +0 -39
  72. package/lib/built-in/http/built-in-filters.js +0 -208
  73. package/lib/built-in/http/built-in-handlers.js +0 -69
  74. package/lib/built-in/http/log-level-manipulation-filter.js +0 -16
  75. package/lib/built-in/http/run-handler-as-filter.js +0 -60
  76. package/lib/built-in/http/run-handler-as-filter.spec.js +0 -40
  77. package/lib/cli/ratchet-cli-handler.js +0 -20
  78. package/lib/cli/run-background-process-from-command-line.js +0 -22
  79. package/lib/config/background/background-aws-config.js +0 -1
  80. package/lib/config/background/background-config.js +0 -1
  81. package/lib/config/background/background-error-processor.js +0 -1
  82. package/lib/config/background/background-processor.js +0 -1
  83. package/lib/config/background/background-transaction-log.js +0 -1
  84. package/lib/config/background/background-transaction-logger.js +0 -1
  85. package/lib/config/cron/abstract-cron-entry.js +0 -1
  86. package/lib/config/cron/cron-background-entry.js +0 -1
  87. package/lib/config/cron/cron-config.js +0 -1
  88. package/lib/config/dynamo-db-config.js +0 -1
  89. package/lib/config/epsilon-config.js +0 -1
  90. package/lib/config/epsilon-lambda-event-handler.js +0 -1
  91. package/lib/config/epsilon-logger-config.js +0 -1
  92. package/lib/config/generic-aws-event-handler-function.js +0 -1
  93. package/lib/config/http/authorizer-function.js +0 -1
  94. package/lib/config/http/epsilon-authorization-context.js +0 -1
  95. package/lib/config/http/extended-api-gateway-event.js +0 -1
  96. package/lib/config/http/filter-chain-context.js +0 -1
  97. package/lib/config/http/filter-function.js +0 -1
  98. package/lib/config/http/handler-function.js +0 -1
  99. package/lib/config/http/http-config.js +0 -1
  100. package/lib/config/http/http-processing-config.js +0 -1
  101. package/lib/config/http/mapped-http-processing-config.js +0 -1
  102. package/lib/config/http/null-returned-object-handling.js +0 -6
  103. package/lib/config/inter-api/inter-api-aws-config.js +0 -1
  104. package/lib/config/inter-api/inter-api-config.js +0 -1
  105. package/lib/config/inter-api/inter-api-process-mapping.js +0 -1
  106. package/lib/config/logging-trace-id-generator.js +0 -1
  107. package/lib/config/open-api/open-api-document-components.js +0 -1
  108. package/lib/config/open-api/open-api-document-path.js +0 -1
  109. package/lib/config/open-api/open-api-document.js +0 -1
  110. package/lib/config/s3-config.js +0 -1
  111. package/lib/config/sns-config.js +0 -1
  112. package/lib/epsilon-build-properties.js +0 -24
  113. package/lib/epsilon-constants.js +0 -46
  114. package/lib/epsilon-global-handler.js +0 -154
  115. package/lib/epsilon-instance.js +0 -1
  116. package/lib/epsilon-logging-extension-processor.js +0 -15
  117. package/lib/http/auth/api-gateway-adapter-authentication-handler.js +0 -72
  118. package/lib/http/auth/auth0-web-token-manipulator.js +0 -61
  119. package/lib/http/auth/basic-auth-token.js +0 -1
  120. package/lib/http/auth/google-web-token-manipulator.js +0 -70
  121. package/lib/http/auth/google-web-token-manipulator.spec.js +0 -10
  122. package/lib/http/auth/jwt-ratchet-local-web-token-manipulator.js +0 -27
  123. package/lib/http/auth/local-web-token-manipulator.js +0 -74
  124. package/lib/http/auth/local-web-token-manipulator.spec.js +0 -24
  125. package/lib/http/auth/web-token-manipulator.js +0 -1
  126. package/lib/http/error/bad-gateway.js +0 -8
  127. package/lib/http/error/bad-request-error.js +0 -8
  128. package/lib/http/error/conflict-error.js +0 -8
  129. package/lib/http/error/epsilon-http-error.js +0 -133
  130. package/lib/http/error/epsilon-http-error.spec.js +0 -11
  131. package/lib/http/error/forbidden-error.js +0 -8
  132. package/lib/http/error/gateway-timeout.js +0 -8
  133. package/lib/http/error/method-not-allowed-error.js +0 -8
  134. package/lib/http/error/misconfigured-error.js +0 -8
  135. package/lib/http/error/not-found-error.js +0 -8
  136. package/lib/http/error/not-implemented.js +0 -8
  137. package/lib/http/error/request-timeout-error.js +0 -8
  138. package/lib/http/error/service-unavailable.js +0 -8
  139. package/lib/http/error/too-many-requests-error.js +0 -8
  140. package/lib/http/error/unauthorized-error.js +0 -8
  141. package/lib/http/event-util.js +0 -176
  142. package/lib/http/event-util.spec.js +0 -161
  143. package/lib/http/response-util.js +0 -141
  144. package/lib/http/response-util.spec.js +0 -92
  145. package/lib/http/route/epsilon-router.js +0 -1
  146. package/lib/http/route/extended-auth-response-context.js +0 -1
  147. package/lib/http/route/route-mapping.js +0 -1
  148. package/lib/http/route/route-validator-config.js +0 -1
  149. package/lib/http/route/router-util.js +0 -233
  150. package/lib/http/route/router-util.spec.js +0 -23
  151. package/lib/http/web-handler.js +0 -117
  152. package/lib/http/web-handler.spec.js +0 -32
  153. package/lib/http/web-v2-handler.js +0 -22
  154. package/lib/index.js +0 -1
  155. package/lib/inter-api/inter-api-entry.js +0 -1
  156. package/lib/inter-api/inter-api-util.js +0 -59
  157. package/lib/inter-api/inter-api-util.spec.js +0 -61
  158. package/lib/inter-api-manager.js +0 -65
  159. package/lib/lambda-event-handler/cron-epsilon-lambda-event-handler.js +0 -73
  160. package/lib/lambda-event-handler/cron-epsilon-lambda-event-handler.spec.js +0 -50
  161. package/lib/lambda-event-handler/dynamo-epsilon-lambda-event-handler.js +0 -33
  162. package/lib/lambda-event-handler/generic-sns-epsilon-lambda-event-handler.js +0 -29
  163. package/lib/lambda-event-handler/inter-api-epsilon-lambda-event-handler.js +0 -23
  164. package/lib/lambda-event-handler/s3-epsilon-lambda-event-handler.js +0 -41
  165. package/lib/local-container-server.js +0 -76
  166. package/lib/local-server-cert.js +0 -67
  167. package/lib/local-server.js +0 -162
  168. package/lib/open-api-util/open-api-doc-modifications.js +0 -1
  169. package/lib/open-api-util/open-api-doc-modifier.js +0 -79
  170. package/lib/open-api-util/open-api-doc-modifier.spec.js +0 -16
  171. package/lib/open-api-util/yaml-combiner.js +0 -27
  172. package/lib/open-api-util/yaml-combiner.spec.js +0 -22
  173. package/lib/sample/sample-server-components.js +0 -185
  174. package/lib/sample/sample-server-static-files.js +0 -593
  175. package/lib/sample/test-error-server.js +0 -44
  176. package/lib/util/aws-util.js +0 -65
  177. package/lib/util/context-util.js +0 -101
  178. package/lib/util/cron-util.js +0 -68
  179. package/lib/util/cron-util.spec.js +0 -124
  180. package/lib/util/epsilon-config-parser.js +0 -65
@@ -1,161 +0,0 @@
1
- import { EventUtil } from './event-util.js';
2
- import fs from 'fs';
3
- import path from 'path';
4
- import { EsmRatchet } from '@bitblit/ratchet-common/lib/lang/esm-ratchet.js';
5
- describe('#eventUtil', function () {
6
- it('should extract pieces', function () {
7
- const evt = {
8
- httpMethod: 'GET',
9
- path: '/cw/meta/server',
10
- body: null,
11
- headers: {
12
- Host: 'api.test.com',
13
- 'X-Forwarded-Proto': 'https',
14
- },
15
- multiValueHeaders: {
16
- Host: ['api.test.com'],
17
- 'X-Forwarded-Proto': ['https'],
18
- },
19
- multiValueQueryStringParameters: null,
20
- isBase64Encoded: false,
21
- pathParameters: null,
22
- queryStringParameters: null,
23
- stageVariables: null,
24
- resource: '/{proxy+}',
25
- requestContext: {
26
- httpMethod: 'GET',
27
- accountId: '1234',
28
- apiId: '7890',
29
- stage: 'v0',
30
- path: '/cw/meta/server',
31
- domainName: 'api.test.com',
32
- identity: null,
33
- requestId: 'asdf1234',
34
- requestTimeEpoch: 1234,
35
- resourceId: '1234',
36
- resourcePath: '/{proxy+}',
37
- },
38
- };
39
- expect(EventUtil.extractStage(evt)).toEqual('cw');
40
- expect(EventUtil.extractApiGatewayStage(evt)).toEqual('v0');
41
- expect(EventUtil.extractFullPrefix(evt)).toEqual('https://api.test.com/cw');
42
- expect(EventUtil.extractFullPath(evt)).toEqual('https://api.test.com/cw/meta/server');
43
- expect(EventUtil.extractHostHeader(evt)).toEqual('api.test.com');
44
- });
45
- it('should fix still encoded query params', function () {
46
- const evt = {
47
- httpMethod: 'GET',
48
- path: '/cw/meta/server',
49
- body: null,
50
- headers: {
51
- Host: 'api.test.com',
52
- 'X-Forwarded-Proto': 'https',
53
- },
54
- multiValueHeaders: {
55
- Host: ['api.test.com'],
56
- 'X-Forwarded-Proto': ['https'],
57
- },
58
- isBase64Encoded: false,
59
- pathParameters: null,
60
- multiValueQueryStringParameters: {
61
- a: ['b'],
62
- 'amp;c': ['d'],
63
- },
64
- queryStringParameters: {
65
- a: 'b',
66
- 'amp;c': 'd',
67
- },
68
- stageVariables: null,
69
- resource: '/{proxy+}',
70
- requestContext: {
71
- httpMethod: 'GET',
72
- accountId: '1234',
73
- apiId: '7890',
74
- stage: 'v0',
75
- path: '/cw/meta/server',
76
- domainName: 'api.test.com',
77
- identity: null,
78
- requestId: 'asdf1234',
79
- requestTimeEpoch: 1234,
80
- resourceId: '1234',
81
- resourcePath: '/{proxy+}',
82
- },
83
- };
84
- expect(evt.queryStringParameters['a']).toBeTruthy();
85
- expect(evt.queryStringParameters['amp;c']).toBeTruthy();
86
- expect(evt.queryStringParameters['c']).toBeUndefined();
87
- EventUtil.fixStillEncodedQueryParams(evt);
88
- expect(evt.queryStringParameters['a']).toBeTruthy();
89
- expect(evt.queryStringParameters['amp;c']).toBeUndefined();
90
- expect(evt.queryStringParameters['c']).toBeTruthy();
91
- });
92
- it('should extract basic auth from headers', function () {
93
- const evt = {
94
- httpMethod: 'GET',
95
- path: '/cw/meta/server',
96
- body: null,
97
- headers: {
98
- Host: 'api.test.com',
99
- 'X-Forwarded-Proto': 'https',
100
- Authorization: 'Basic dGVzdHVzZXI6dGVzdHBhc3M=',
101
- },
102
- multiValueHeaders: {
103
- Host: ['api.test.com'],
104
- 'X-Forwarded-Proto': ['https'],
105
- Authorization: ['Basic dGVzdHVzZXI6dGVzdHBhc3M='],
106
- },
107
- isBase64Encoded: false,
108
- pathParameters: null,
109
- multiValueQueryStringParameters: {
110
- a: ['b'],
111
- 'amp;c': ['d'],
112
- },
113
- queryStringParameters: {
114
- a: 'b',
115
- 'amp;c': 'd',
116
- },
117
- stageVariables: null,
118
- resource: '/{proxy+}',
119
- requestContext: {
120
- httpMethod: 'GET',
121
- accountId: '1234',
122
- apiId: '7890',
123
- stage: 'v0',
124
- path: '/cw/meta/server',
125
- domainName: 'api.test.com',
126
- identity: null,
127
- requestId: 'asdf1234',
128
- requestTimeEpoch: 1234,
129
- resourceId: '1234',
130
- resourcePath: '/{proxy+}',
131
- },
132
- };
133
- const basic = EventUtil.extractBasicAuthenticationToken(evt);
134
- expect(basic).toBeTruthy();
135
- expect(basic.username).toBeTruthy();
136
- expect(basic.password).toBeTruthy();
137
- expect(basic.username).toEqual('testuser');
138
- expect(basic.password).toEqual('testpass');
139
- });
140
- it('should add a token to an event, along with downstream stuff', function () {
141
- const evt = JSON.parse(fs
142
- .readFileSync(path.join(EsmRatchet.fetchDirName(import.meta.url), '../../../../test-data/epsilon/sample-json/sample-request-1.json'))
143
- .toString());
144
- const jwtToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1ODg1MzY3NzU4ODcsImlzcyI6Im5lb24uYWRvbW5pLmNvbSIsInN1YiI6ImJpdGJsaXRAZ21haWwuY29tIiwiaWF0IjoxNTg4NTMzMTc1ODg3LCJ1c2VyIjp7ImlkIjo2LCJmaXJzdE5hbWUiOiJDaHJpcyIsImxhc3ROYW1lIjoiV2Vpc3MiLCJjb21wYW55IjoiQWRvbW5pIiwiZW1haWwiOiJiaXRibGl0QGdtYWlsLmNvbSIsImN1c3RvbWVyVHlwZSI6IkFETUlOIn0sImFjdGluZ1VzZXJJZCI6NiwiZ2xvYmFsIjp0cnVlLCJhZG1pbiI6eyJpZCI6NiwiZmlyc3ROYW1lIjoiQ2hyaXMiLCJsYXN0TmFtZSI6IldlaXNzIiwiY29tcGFueSI6IkFkb21uaSIsImVtYWlsIjoiYml0YmxpdEBnbWFpbC5jb20iLCJjdXN0b21lclR5cGUiOiJBRE1JTiJ9LCJzdWJVc2VycyI6W119.mwRSek5GwkvxpN44UTp49W6_9U_ARsFXThAyiqaF-eQ';
145
- EventUtil.applyTokenToEventForTesting(evt, jwtToken);
146
- const roundTripTokenString = EventUtil.extractBearerTokenFromEvent(evt);
147
- expect(roundTripTokenString).toEqual(jwtToken);
148
- });
149
- it('should check if an event is a graphql introspection', function () {
150
- const evt1 = JSON.parse(fs
151
- .readFileSync(path.join(EsmRatchet.fetchDirName(import.meta.url), '../../../../test-data/epsilon/sample-json/sample-request-1.json'))
152
- .toString());
153
- const evt2 = JSON.parse(fs
154
- .readFileSync(path.join(EsmRatchet.fetchDirName(import.meta.url), '../../../../test-data/epsilon/sample-json/sample-gql-introspection.json'))
155
- .toString());
156
- const res1 = EventUtil.eventIsAGraphQLIntrospection(evt1);
157
- const res2 = EventUtil.eventIsAGraphQLIntrospection(evt2);
158
- expect(res1).toBeFalsy();
159
- expect(res2).toBeTruthy();
160
- });
161
- });
@@ -1,141 +0,0 @@
1
- import { Logger } from '@bitblit/ratchet-common/lib/logger/logger.js';
2
- import { MapRatchet } from '@bitblit/ratchet-common/lib/lang/map-ratchet.js';
3
- import zlib from 'zlib';
4
- export class ResponseUtil {
5
- constructor() { }
6
- static errorResponse(err) {
7
- const body = {
8
- errors: err.errors,
9
- httpStatusCode: err.httpStatusCode,
10
- requestId: err.requestId,
11
- };
12
- if (err.detailErrorCode) {
13
- body['detailErrorCode'] = err.detailErrorCode;
14
- }
15
- if (err.endUserErrors && err.endUserErrors.length > 0) {
16
- body['endUserErrors'] = err.endUserErrors;
17
- }
18
- if (err.details) {
19
- body['details'] = err.details;
20
- }
21
- if (err.wrappedError) {
22
- body['wrappedError'] = err.wrappedError.name + ' : ' + err.wrappedError.message;
23
- }
24
- const errorResponse = {
25
- statusCode: err.httpStatusCode,
26
- isBase64Encoded: false,
27
- headers: {
28
- 'Content-Type': 'application/json',
29
- },
30
- body: JSON.stringify(body),
31
- };
32
- return errorResponse;
33
- }
34
- static redirect(target, code = 301, queryParams = null) {
35
- if (code !== 301 && code !== 302 && code !== 307) {
36
- throw new Error('Code must be 301 or 302 or 307 for a redirect');
37
- }
38
- let redirectTarget = target;
39
- if (queryParams) {
40
- const keys = Object.keys(queryParams);
41
- if (keys.length > 0) {
42
- Logger.silly('Applying params to input target : %j', queryParams);
43
- redirectTarget += redirectTarget.indexOf('?') === -1 ? '?' : '&';
44
- for (let i = 0; i < keys.length; i++) {
45
- const k = keys[i];
46
- redirectTarget += k + '=' + encodeURIComponent(queryParams[k]);
47
- if (i < keys.length - 1) {
48
- redirectTarget += '&';
49
- }
50
- }
51
- }
52
- }
53
- return {
54
- statusCode: code,
55
- body: '{"redirect-target":"' + redirectTarget + '}',
56
- headers: {
57
- 'Content-Type': 'application/json',
58
- Location: redirectTarget,
59
- },
60
- };
61
- }
62
- static coerceToProxyResult(input) {
63
- let rval = null;
64
- if (input != null) {
65
- if (typeof input === 'object') {
66
- if (input.statusCode && input.body !== undefined) {
67
- rval = Object.assign({}, input);
68
- if (typeof input.body === 'string') {
69
- }
70
- else if (Buffer.isBuffer(input.body)) {
71
- rval.body = input.body.toString('base64');
72
- rval.headers = input.headers || {};
73
- rval.headers['Content-Type'] = input.body.contentType;
74
- rval.isBase64Encoded = true;
75
- }
76
- }
77
- else {
78
- const headers = input.headers || {};
79
- headers['Content-Type'] = 'application/json';
80
- rval = ResponseUtil.coerceToProxyResult({
81
- statusCode: 200,
82
- body: JSON.stringify(input),
83
- headers: headers,
84
- isBase64Encoded: false,
85
- });
86
- }
87
- }
88
- else if (typeof input === 'string' || Buffer.isBuffer(input)) {
89
- rval = ResponseUtil.coerceToProxyResult({ statusCode: 200, body: input });
90
- }
91
- else {
92
- const headers = input.headers || {};
93
- headers['Content-Type'] = 'application/json';
94
- rval = ResponseUtil.coerceToProxyResult({
95
- statusCode: 200,
96
- body: JSON.stringify(input),
97
- headers: headers,
98
- isBase64Encoded: false,
99
- });
100
- }
101
- }
102
- return rval;
103
- }
104
- static async applyGzipIfPossible(encodingHeader, proxyResult) {
105
- const rval = proxyResult;
106
- if (encodingHeader && encodingHeader.toLowerCase().indexOf('gzip') > -1) {
107
- const bigEnough = proxyResult.body.length > 1400;
108
- let contentType = MapRatchet.extractValueFromMapIgnoreCase(proxyResult.headers, 'content-type') || '';
109
- contentType = contentType.toLowerCase();
110
- const exemptContent = contentType === 'application/pdf' || contentType === 'application/zip' || contentType.startsWith('image/');
111
- if (bigEnough && !exemptContent) {
112
- const asBuffer = proxyResult.isBase64Encoded ? Buffer.from(proxyResult.body, 'base64') : Buffer.from(proxyResult.body);
113
- const zipped = await this.gzip(asBuffer);
114
- Logger.debug('Comp from %s to %d bytes', asBuffer.length, zipped.length);
115
- const zipped64 = zipped.toString('base64');
116
- rval.body = zipped64;
117
- rval.isBase64Encoded = true;
118
- rval.headers = rval.headers || {};
119
- rval.headers['Content-Encoding'] = 'gzip';
120
- }
121
- else {
122
- Logger.silly('Not gzipping, too small or exempt content');
123
- }
124
- }
125
- else {
126
- Logger.silly('Not gzipping, not an accepted encoding');
127
- }
128
- return rval;
129
- }
130
- static gzip(input) {
131
- const promise = new Promise(function (resolve, reject) {
132
- zlib.gzip(input, function (error, result) {
133
- if (!error)
134
- resolve(result);
135
- else
136
- reject(error);
137
- });
138
- });
139
- return promise;
140
- }
141
- }
@@ -1,92 +0,0 @@
1
- import { ResponseUtil } from './response-util.js';
2
- import path from 'path';
3
- import fs from 'fs';
4
- import { BuiltInFilters } from '../built-in/http/built-in-filters.js';
5
- import { EpsilonConstants } from '../epsilon-constants.js';
6
- import { EsmRatchet } from '@bitblit/ratchet-common/lib/lang/esm-ratchet.js';
7
- describe('#responseUtil', function () {
8
- it('should correctly combine a redirect url and query params', function () {
9
- const evt = {
10
- httpMethod: 'get',
11
- multiValueHeaders: {},
12
- multiValueQueryStringParameters: {},
13
- path: '/v0/meta/server',
14
- body: null,
15
- headers: null,
16
- isBase64Encoded: false,
17
- pathParameters: null,
18
- stageVariables: null,
19
- resource: null,
20
- queryStringParameters: {
21
- a: 'b',
22
- c: 'd',
23
- },
24
- requestContext: {
25
- stage: 'v0',
26
- },
27
- };
28
- const out1 = ResponseUtil.redirect('myTarget?e=f', 301, evt.queryStringParameters);
29
- expect(out1).toBeTruthy();
30
- expect(out1.headers).toBeTruthy();
31
- expect(out1.headers.Location).toEqual('myTarget?e=f&a=b&c=d');
32
- const out2 = ResponseUtil.redirect('myTarget', 301, evt.queryStringParameters);
33
- expect(out2).toBeTruthy();
34
- expect(out2.headers).toBeTruthy();
35
- expect(out2.headers.Location).toEqual('myTarget?a=b&c=d');
36
- });
37
- it('should leave already encoded stuff alone', async () => {
38
- const singlePixel = fs
39
- .readFileSync(path.join(EsmRatchet.fetchDirName(import.meta.url), '../../../../test-data/epsilon/test.png'))
40
- .toString('base64');
41
- const temp = {
42
- body: singlePixel,
43
- statusCode: 200,
44
- isBase64Encoded: true,
45
- headers: {
46
- 'content-type': 'application/zip',
47
- 'content-disposition': 'attachment; filename="adomni_bs_' + new Date().getTime() + '.zip"',
48
- },
49
- };
50
- const cast = ResponseUtil.coerceToProxyResult(temp);
51
- expect(cast.body).toEqual(temp.body);
52
- const gzip = await ResponseUtil.applyGzipIfPossible('gzip', cast);
53
- expect(cast.body).toEqual(gzip.body);
54
- });
55
- it('should add cors to proxy result MATCH 1', async () => {
56
- const evt = JSON.parse(fs
57
- .readFileSync(path.join(EsmRatchet.fetchDirName(import.meta.url), '../../../../test-data/epsilon/sample-json/sample-request-1.json'))
58
- .toString());
59
- const proxy = {};
60
- const fCtx = {
61
- event: evt,
62
- rawResult: null,
63
- context: null,
64
- result: proxy,
65
- routeAndParse: null,
66
- modelValidator: null,
67
- authenticators: null,
68
- };
69
- await BuiltInFilters.addAllowReflectionCORSHeaders(fCtx);
70
- expect(proxy.headers).toBeTruthy();
71
- expect(proxy.headers['Access-Control-Allow-Origin']).toEqual('http://localhost:4200');
72
- expect(proxy.headers['Access-Control-Allow-Methods']).toEqual('GET');
73
- expect(proxy.headers['Access-Control-Allow-Headers']).toEqual(EpsilonConstants.AUTH_HEADER_NAME.toLowerCase());
74
- });
75
- it('should add cors to proxy result MATCH 2', async () => {
76
- const evt = JSON.parse(fs
77
- .readFileSync(path.join(EsmRatchet.fetchDirName(import.meta.url), '../../../../test-data/epsilon/sample-json/sample-request-2.json'))
78
- .toString());
79
- const proxy = {};
80
- const fCtx = {
81
- event: evt,
82
- rawResult: null,
83
- context: null,
84
- result: proxy,
85
- routeAndParse: null,
86
- modelValidator: null,
87
- authenticators: null,
88
- };
89
- await BuiltInFilters.addAllowReflectionCORSHeaders(fCtx);
90
- expect(proxy.headers).toBeTruthy();
91
- });
92
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};
@@ -1,233 +0,0 @@
1
- import { MisconfiguredError } from '../error/misconfigured-error.js';
2
- import { Logger } from '@bitblit/ratchet-common/lib/logger/logger.js';
3
- import { BooleanRatchet } from '@bitblit/ratchet-common/lib/lang/boolean-ratchet.js';
4
- import { NullReturnedObjectHandling } from '../../config/http/null-returned-object-handling.js';
5
- import { BuiltInFilters } from '../../built-in/http/built-in-filters.js';
6
- import { BuiltInHandlers } from '../../built-in/http/built-in-handlers.js';
7
- import { BuiltInAuthFilters } from '../../built-in/http/built-in-auth-filters.js';
8
- import { LogLevelManipulationFilter } from '../../built-in/http/log-level-manipulation-filter.js';
9
- export class RouterUtil {
10
- constructor() { }
11
- static defaultAuthenticationHeaderParsingEpsilonPreFilters(webTokenManipulator) {
12
- return [
13
- (fCtx) => BuiltInAuthFilters.parseAuthorizationHeader(fCtx, webTokenManipulator),
14
- (fCtx) => BuiltInAuthFilters.applyOpenApiAuthorization(fCtx),
15
- ].concat(RouterUtil.defaultEpsilonPreFilters());
16
- }
17
- static defaultEpsilonPreFilters() {
18
- return [
19
- (fCtx) => BuiltInFilters.autoRespondToOptionsRequestWithCors(fCtx),
20
- (fCtx) => BuiltInFilters.ensureEventMaps(fCtx),
21
- (fCtx) => LogLevelManipulationFilter.setLogLevelForTransaction(fCtx),
22
- (fCtx) => BuiltInFilters.parseJsonBodyToObject(fCtx),
23
- (fCtx) => BuiltInFilters.fixStillEncodedQueryParams(fCtx),
24
- (fCtx) => BuiltInFilters.uriDecodeQueryParams(fCtx),
25
- (fCtx) => BuiltInFilters.disallowStringNullAsPathParameter(fCtx),
26
- (fCtx) => BuiltInFilters.disallowStringNullAsQueryStringParameter(fCtx),
27
- (fCtx) => BuiltInFilters.validateInboundBody(fCtx),
28
- (fCtx) => BuiltInFilters.validateInboundQueryParams(fCtx),
29
- (fCtx) => BuiltInFilters.validateInboundQueryParams(fCtx),
30
- ];
31
- }
32
- static defaultEpsilonPostFilters() {
33
- return [
34
- (fCtx) => BuiltInFilters.validateOutboundResponse(fCtx),
35
- (fCtx) => BuiltInFilters.addAWSRequestIdHeader(fCtx),
36
- (fCtx) => BuiltInFilters.addAllowReflectionCORSHeaders(fCtx),
37
- (fCtx) => BuiltInFilters.applyGzipIfPossible(fCtx),
38
- (fCtx) => BuiltInFilters.checkMaximumLambdaBodySize(fCtx),
39
- (fCtx) => LogLevelManipulationFilter.clearLogLevelForTransaction(fCtx),
40
- ];
41
- }
42
- static defaultEpsilonErrorFilters() {
43
- return [
44
- (fCtx) => BuiltInFilters.addAWSRequestIdHeader(fCtx),
45
- (fCtx) => BuiltInFilters.addAllowReflectionCORSHeaders(fCtx),
46
- (fCtx) => LogLevelManipulationFilter.clearLogLevelForTransaction(fCtx),
47
- ];
48
- }
49
- static defaultHttpMetaProcessingConfigWithAuthenticationHeaderParsing(webTokenManipulator) {
50
- const defaults = {
51
- configName: 'EpsilonDefaultHttpMetaProcessingConfig',
52
- timeoutMS: 30_000,
53
- overrideAuthorizerName: null,
54
- preFilters: RouterUtil.defaultAuthenticationHeaderParsingEpsilonPreFilters(webTokenManipulator),
55
- postFilters: RouterUtil.defaultEpsilonPostFilters(),
56
- errorFilters: RouterUtil.defaultEpsilonErrorFilters(),
57
- nullReturnedObjectHandling: NullReturnedObjectHandling.Return404NotFoundResponse,
58
- };
59
- return defaults;
60
- }
61
- static defaultHttpMetaProcessingConfig() {
62
- const defaults = {
63
- configName: 'EpsilonDefaultHttpMetaProcessingConfig',
64
- timeoutMS: 30_000,
65
- overrideAuthorizerName: null,
66
- preFilters: RouterUtil.defaultEpsilonPreFilters(),
67
- postFilters: RouterUtil.defaultEpsilonPostFilters(),
68
- errorFilters: RouterUtil.defaultEpsilonErrorFilters(),
69
- nullReturnedObjectHandling: NullReturnedObjectHandling.Return404NotFoundResponse,
70
- };
71
- return defaults;
72
- }
73
- static assignDefaultsOnHttpConfig(cfg) {
74
- const defaults = {
75
- handlers: new Map(),
76
- authorizers: new Map(),
77
- defaultMetaHandling: this.defaultHttpMetaProcessingConfig(),
78
- staticContentRoutes: {},
79
- prefixesToStripBeforeRouteMatch: [],
80
- filterHandledRouteMatches: ['options .*'],
81
- };
82
- const rval = Object.assign({}, defaults, cfg || {});
83
- return rval;
84
- }
85
- static findApplicableMeta(httpConfig, method, path) {
86
- let rval = null;
87
- if (httpConfig?.overrideMetaHandling) {
88
- for (let i = 0; i < httpConfig.overrideMetaHandling.length && !rval; i++) {
89
- const test = httpConfig.overrideMetaHandling[i];
90
- if (!test.methods ||
91
- test.methods.length === 0 ||
92
- test.methods.map((s) => s.toLocaleLowerCase()).includes(method.toLocaleLowerCase())) {
93
- const matches = !!path.match(test.pathRegex);
94
- if ((matches && !test.invertPathMatching) || (!matches && test.invertPathMatching)) {
95
- rval = test.config;
96
- }
97
- }
98
- }
99
- }
100
- if (!rval) {
101
- rval = httpConfig.defaultMetaHandling || RouterUtil.defaultHttpMetaProcessingConfig();
102
- }
103
- return rval;
104
- }
105
- static openApiYamlToRouterConfig(httpConfig, openApiDoc, modelValidator, backgroundHttpAdapterHandler) {
106
- if (!openApiDoc || !httpConfig) {
107
- throw new MisconfiguredError('Cannot configure, missing either yaml or cfg');
108
- }
109
- const rval = {
110
- routes: [],
111
- openApiModelValidator: modelValidator,
112
- config: RouterUtil.assignDefaultsOnHttpConfig(httpConfig),
113
- };
114
- if (openApiDoc?.components?.securitySchemes) {
115
- Object.keys(openApiDoc.components.securitySchemes).forEach((sk) => {
116
- if (!rval.config.authorizers || !rval.config.authorizers.get(sk)) {
117
- throw new MisconfiguredError().withFormattedErrorMessage('Doc requires authorizer %s but not found in map', sk);
118
- }
119
- });
120
- }
121
- const missingPaths = [];
122
- const filterHandledPathMatches = httpConfig.filterHandledRouteMatches || [];
123
- if (openApiDoc?.paths) {
124
- Object.keys(openApiDoc.paths).forEach((path) => {
125
- Object.keys(openApiDoc.paths[path]).forEach((method) => {
126
- const convertedPath = RouterUtil.openApiPathToRouteParserPath(path);
127
- const finder = method + ' ' + path;
128
- const applicableMeta = RouterUtil.findApplicableMeta(httpConfig, method, path);
129
- const entry = openApiDoc.paths[path][method];
130
- const isBackgroundEndpoint = path.startsWith(backgroundHttpAdapterHandler.httpSubmissionPath);
131
- const isBackgroundMetaEndpoint = path === backgroundHttpAdapterHandler.httpMetaEndpoint;
132
- const isBackgroundStatusEndpoint = path === backgroundHttpAdapterHandler.httpStatusPath;
133
- if (isBackgroundEndpoint) {
134
- rval.config.handlers.set(finder, (evt, ctx) => backgroundHttpAdapterHandler.handleBackgroundSubmission(evt, ctx));
135
- }
136
- if (isBackgroundMetaEndpoint) {
137
- rval.config.handlers.set(finder, (evt, ctx) => backgroundHttpAdapterHandler.handleBackgroundMetaRequest(evt, ctx));
138
- }
139
- if (isBackgroundStatusEndpoint) {
140
- rval.config.handlers.set(finder, (evt, ctx) => backgroundHttpAdapterHandler.handleBackgroundStatusRequest(evt, ctx));
141
- }
142
- if (!rval.config.handlers || !rval.config.handlers.get(finder)) {
143
- const match = filterHandledPathMatches.find((reg) => finder.match(reg));
144
- if (match) {
145
- Logger.debug('Adding filter-handled handler for %s', finder);
146
- rval.config.handlers.set(finder, (evt) => BuiltInHandlers.expectedHandledByFilter(evt));
147
- }
148
- else {
149
- missingPaths.push(finder);
150
- }
151
- }
152
- if (entry && entry['security'] && entry['security'].length > 1) {
153
- throw new MisconfiguredError('Epsilon does not currently support multiple security (path was ' + finder + ')');
154
- }
155
- const authorizerName = entry['security'] && entry['security'].length == 1 ? Object.keys(entry['security'][0])[0] : null;
156
- const newRoute = {
157
- path: convertedPath,
158
- method: method,
159
- function: rval.config.handlers.get(finder),
160
- authorizerName: applicableMeta.overrideAuthorizerName || authorizerName,
161
- metaProcessingConfig: applicableMeta,
162
- validation: null,
163
- outboundValidation: null,
164
- };
165
- if (entry['requestBody'] &&
166
- entry['requestBody']['content'] &&
167
- entry['requestBody']['content']['application/json'] &&
168
- entry['requestBody']['content']['application/json']['schema']) {
169
- const schema = entry['requestBody']['content'];
170
- Logger.silly('Applying schema %j to %s', schema, finder);
171
- const modelName = this.findAndValidateModelName(method, path, schema, rval.config.overrideModelValidator || rval.openApiModelValidator);
172
- const required = BooleanRatchet.parseBool(entry['requestBody']['required']);
173
- const validation = {
174
- extraPropertiesAllowed: true,
175
- emptyAllowed: !required,
176
- modelName: modelName,
177
- };
178
- newRoute.validation = validation;
179
- }
180
- if (entry['responses'] &&
181
- entry['responses']['200'] &&
182
- entry['responses']['200']['content'] &&
183
- entry['responses']['200']['content']['application/json'] &&
184
- entry['responses']['200']['content']['application/json']['schema']) {
185
- const schema = entry['responses']['200']['content'];
186
- Logger.silly('Applying schema %j to %s', schema, finder);
187
- const modelName = this.findAndValidateModelName(method, path, schema, rval.config.overrideModelValidator || rval.openApiModelValidator);
188
- const validation = {
189
- extraPropertiesAllowed: false,
190
- emptyAllowed: false,
191
- modelName: modelName,
192
- };
193
- newRoute.outboundValidation = validation;
194
- }
195
- rval.routes.push(newRoute);
196
- });
197
- });
198
- }
199
- if (missingPaths.length > 0) {
200
- throw new MisconfiguredError().withFormattedErrorMessage('Missing expected handlers : %j', missingPaths);
201
- }
202
- return rval;
203
- }
204
- static findAndValidateModelName(method, path, schema, modelValidator) {
205
- let rval = undefined;
206
- const schemaPath = schema['application/json']['schema']['$ref'];
207
- const inlinePath = schema['application/json']['schema']['type'];
208
- if (schemaPath) {
209
- rval = schemaPath.substring(schemaPath.lastIndexOf('/') + 1);
210
- if (!modelValidator.fetchModel(rval)) {
211
- throw new MisconfiguredError(`Path ${method} ${path} refers to schema ${rval} but its not in the schema section`);
212
- }
213
- }
214
- else if (inlinePath) {
215
- rval = `${method}-${path}-requestBodyModel`;
216
- const model = schema['application/json']['schema'];
217
- modelValidator.addModel(rval, model);
218
- }
219
- return rval;
220
- }
221
- static openApiPathToRouteParserPath(input) {
222
- let rval = input;
223
- if (rval) {
224
- let sIdx = rval.indexOf('{');
225
- while (sIdx > -1) {
226
- const eIdx = rval.indexOf('}');
227
- rval = rval.substring(0, sIdx) + ':' + rval.substring(sIdx + 1, eIdx) + rval.substring(eIdx + 1);
228
- sIdx = rval.indexOf('{');
229
- }
230
- }
231
- return rval;
232
- }
233
- }
@@ -1,23 +0,0 @@
1
- import { RouterUtil } from './router-util.js';
2
- import { SampleServerComponents } from '../../sample/sample-server-components.js';
3
- describe('#routerUtilApplyOpenApiDoc', function () {
4
- it('should create a router config from a yaml file', async () => {
5
- const inst = await SampleServerComponents.createSampleEpsilonGlobalHandler('routerUtilApplyOpenApiDoc-jest');
6
- expect(inst.epsilon.modelValidator).toBeTruthy();
7
- expect(inst.epsilon.modelValidator.fetchModel('AccessTokenRequest')).toBeTruthy();
8
- const evt = {
9
- httpMethod: 'get',
10
- path: '/v0/meta/server',
11
- requestContext: {
12
- stage: 'v0',
13
- },
14
- };
15
- const find = await inst.epsilon.webHandler.findBestMatchingRoute(evt);
16
- expect(find).toBeTruthy();
17
- });
18
- it('should reformat a path to match the other library', function () {
19
- const inString = '/meta/item/{itemId}';
20
- const outString = RouterUtil.openApiPathToRouteParserPath(inString);
21
- expect(outString).toEqual('/meta/item/:itemId');
22
- });
23
- });