lemon-core 4.1.15 → 4.2.1

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 (156) hide show
  1. package/README.md +2 -0
  2. package/dist/common/test-helper.d.ts +2 -2
  3. package/dist/common/test-helper.js +24 -26
  4. package/dist/common/test-helper.js.map +1 -1
  5. package/dist/controllers/dummy-controller.js +39 -46
  6. package/dist/controllers/dummy-controller.js.map +1 -1
  7. package/dist/controllers/general-api-controller.js +95 -100
  8. package/dist/controllers/general-api-controller.js.map +1 -1
  9. package/dist/controllers/general-controller.js +81 -82
  10. package/dist/controllers/general-controller.js.map +1 -1
  11. package/dist/cores/api/api-service.d.ts +1 -1
  12. package/dist/cores/api/api-service.js +228 -269
  13. package/dist/cores/api/api-service.js.map +1 -1
  14. package/dist/cores/aws/aws-kms-service.d.ts +1 -2
  15. package/dist/cores/aws/aws-kms-service.js +143 -153
  16. package/dist/cores/aws/aws-kms-service.js.map +1 -1
  17. package/dist/cores/aws/aws-s3-service.d.ts +2 -4
  18. package/dist/cores/aws/aws-s3-service.js +306 -330
  19. package/dist/cores/aws/aws-s3-service.js.map +1 -1
  20. package/dist/cores/aws/aws-sns-service.js +147 -153
  21. package/dist/cores/aws/aws-sns-service.js.map +1 -1
  22. package/dist/cores/aws/aws-sqs-service.js +149 -170
  23. package/dist/cores/aws/aws-sqs-service.js.map +1 -1
  24. package/dist/cores/aws/index.js +10 -20
  25. package/dist/cores/aws/index.js.map +1 -1
  26. package/dist/cores/cache/cache-service.d.ts +2 -2
  27. package/dist/cores/cache/cache-service.js +435 -499
  28. package/dist/cores/cache/cache-service.js.map +1 -1
  29. package/dist/cores/config/config-service.d.ts +1 -1
  30. package/dist/cores/config/config-service.js +56 -63
  31. package/dist/cores/config/config-service.js.map +1 -1
  32. package/dist/cores/config/index.js +14 -24
  33. package/dist/cores/config/index.js.map +1 -1
  34. package/dist/cores/core-services.d.ts +1 -1
  35. package/dist/cores/dynamo/dynamo-query-service.js +37 -51
  36. package/dist/cores/dynamo/dynamo-query-service.js.map +1 -1
  37. package/dist/cores/dynamo/dynamo-scan-service.d.ts +2 -2
  38. package/dist/cores/dynamo/dynamo-scan-service.js +29 -40
  39. package/dist/cores/dynamo/dynamo-scan-service.js.map +1 -1
  40. package/dist/cores/dynamo/dynamo-service.d.ts +3 -3
  41. package/dist/cores/dynamo/dynamo-service.js +540 -605
  42. package/dist/cores/dynamo/dynamo-service.js.map +1 -1
  43. package/dist/cores/dynamo/tools/expressions.js +17 -7
  44. package/dist/cores/dynamo/tools/expressions.js.map +1 -1
  45. package/dist/cores/dynamo/tools/query.js +142 -127
  46. package/dist/cores/dynamo/tools/query.js.map +1 -1
  47. package/dist/cores/dynamo/tools/scan.js +111 -97
  48. package/dist/cores/dynamo/tools/scan.js.map +1 -1
  49. package/dist/cores/dynamo/tools/serializer.js +17 -7
  50. package/dist/cores/dynamo/tools/serializer.js.map +1 -1
  51. package/dist/cores/dynamo/tools/utils.d.ts +0 -2
  52. package/dist/cores/dynamo/tools/utils.js.map +1 -1
  53. package/dist/cores/elastic/elastic6-query-service.js +307 -324
  54. package/dist/cores/elastic/elastic6-query-service.js.map +1 -1
  55. package/dist/cores/elastic/elastic6-service.d.ts +3 -3
  56. package/dist/cores/elastic/elastic6-service.js +568 -647
  57. package/dist/cores/elastic/elastic6-service.js.map +1 -1
  58. package/dist/cores/elastic/hangul-service.js +52 -54
  59. package/dist/cores/elastic/hangul-service.js.map +1 -1
  60. package/dist/cores/lambda/index.js +42 -36
  61. package/dist/cores/lambda/index.js.map +1 -1
  62. package/dist/cores/lambda/lambda-alb-handler.d.ts +2 -2
  63. package/dist/cores/lambda/lambda-alb-handler.js +59 -72
  64. package/dist/cores/lambda/lambda-alb-handler.js.map +1 -1
  65. package/dist/cores/lambda/lambda-cognito-handler.js +10 -19
  66. package/dist/cores/lambda/lambda-cognito-handler.js.map +1 -1
  67. package/dist/cores/lambda/lambda-cron-handler.d.ts +1 -1
  68. package/dist/cores/lambda/lambda-cron-handler.js +14 -23
  69. package/dist/cores/lambda/lambda-cron-handler.js.map +1 -1
  70. package/dist/cores/lambda/lambda-dynamo-stream-handler.d.ts +2 -2
  71. package/dist/cores/lambda/lambda-dynamo-stream-handler.js +57 -67
  72. package/dist/cores/lambda/lambda-dynamo-stream-handler.js.map +1 -1
  73. package/dist/cores/lambda/lambda-handler.d.ts +22 -22
  74. package/dist/cores/lambda/lambda-handler.js +93 -106
  75. package/dist/cores/lambda/lambda-handler.js.map +1 -1
  76. package/dist/cores/lambda/lambda-notification-handler.d.ts +1 -1
  77. package/dist/cores/lambda/lambda-notification-handler.js +39 -50
  78. package/dist/cores/lambda/lambda-notification-handler.js.map +1 -1
  79. package/dist/cores/lambda/lambda-sns-handler.js +79 -88
  80. package/dist/cores/lambda/lambda-sns-handler.js.map +1 -1
  81. package/dist/cores/lambda/lambda-sqs-handler.js +79 -88
  82. package/dist/cores/lambda/lambda-sqs-handler.js.map +1 -1
  83. package/dist/cores/lambda/lambda-web-handler.d.ts +6 -6
  84. package/dist/cores/lambda/lambda-web-handler.js +387 -412
  85. package/dist/cores/lambda/lambda-web-handler.js.map +1 -1
  86. package/dist/cores/lambda/lambda-wss-handler.js +23 -32
  87. package/dist/cores/lambda/lambda-wss-handler.js.map +1 -1
  88. package/dist/cores/protocol/index.js +10 -20
  89. package/dist/cores/protocol/index.js.map +1 -1
  90. package/dist/cores/protocol/protocol-service.d.ts +3 -3
  91. package/dist/cores/protocol/protocol-service.js +235 -227
  92. package/dist/cores/protocol/protocol-service.js.map +1 -1
  93. package/dist/cores/storage/http-storage-service.js +65 -85
  94. package/dist/cores/storage/http-storage-service.js.map +1 -1
  95. package/dist/cores/storage/model-manager.js +66 -85
  96. package/dist/cores/storage/model-manager.js.map +1 -1
  97. package/dist/cores/storage/proxy-storage-service.d.ts +2 -2
  98. package/dist/cores/storage/proxy-storage-service.js +562 -599
  99. package/dist/cores/storage/proxy-storage-service.js.map +1 -1
  100. package/dist/cores/storage/redis-storage-service.js +163 -177
  101. package/dist/cores/storage/redis-storage-service.js.map +1 -1
  102. package/dist/cores/storage/storage-service.d.ts +8 -1
  103. package/dist/cores/storage/storage-service.js +359 -324
  104. package/dist/cores/storage/storage-service.js.map +1 -1
  105. package/dist/engine/builder.d.ts +1 -1
  106. package/dist/engine/builder.js +59 -63
  107. package/dist/engine/builder.js.map +1 -1
  108. package/dist/engine/engine.d.ts +4 -4
  109. package/dist/engine/engine.js +9 -18
  110. package/dist/engine/engine.js.map +1 -1
  111. package/dist/engine/types.d.ts +1 -1
  112. package/dist/engine/utilities.d.ts +5 -5
  113. package/dist/engine/utilities.js +301 -293
  114. package/dist/engine/utilities.js.map +1 -1
  115. package/dist/environ.js +4 -6
  116. package/dist/environ.js.map +1 -1
  117. package/dist/extended/abstract-service.js +595 -645
  118. package/dist/extended/abstract-service.js.map +1 -1
  119. package/dist/extended/libs/sig-v4.js.map +1 -1
  120. package/dist/generated/field-registry.d.ts +10 -0
  121. package/dist/generated/field-registry.js +17 -0
  122. package/dist/generated/field-registry.js.map +1 -0
  123. package/dist/helpers/helpers.d.ts +17 -9
  124. package/dist/helpers/helpers.js +88 -78
  125. package/dist/helpers/helpers.js.map +1 -1
  126. package/dist/index.js +17 -7
  127. package/dist/index.js.map +1 -1
  128. package/dist/lib/dynamodb-value.js +2 -3
  129. package/dist/lib/dynamodb-value.js.map +1 -1
  130. package/dist/tools/express.js +4 -5
  131. package/dist/tools/express.js.map +1 -1
  132. package/dist/tools/tools.d.ts +3 -1
  133. package/dist/tools/tools.js +14 -21
  134. package/dist/tools/tools.js.map +1 -1
  135. package/package.json +25 -24
  136. package/dist/exec-cli.d.ts +0 -2
  137. package/dist/exec-cli.js +0 -211
  138. package/dist/exec-cli.js.map +0 -1
  139. package/dist/lib/dynamo/expressions.d.ts +0 -14
  140. package/dist/lib/dynamo/expressions.js +0 -212
  141. package/dist/lib/dynamo/expressions.js.map +0 -1
  142. package/dist/lib/dynamo/query.d.ts +0 -43
  143. package/dist/lib/dynamo/query.js +0 -246
  144. package/dist/lib/dynamo/query.js.map +0 -1
  145. package/dist/lib/dynamo/scan.d.ts +0 -33
  146. package/dist/lib/dynamo/scan.js +0 -172
  147. package/dist/lib/dynamo/scan.js.map +0 -1
  148. package/dist/lib/dynamo/serializer.d.ts +0 -12
  149. package/dist/lib/dynamo/serializer.js +0 -243
  150. package/dist/lib/dynamo/serializer.js.map +0 -1
  151. package/dist/lib/dynamo/utils.d.ts +0 -15
  152. package/dist/lib/dynamo/utils.js +0 -129
  153. package/dist/lib/dynamo/utils.js.map +0 -1
  154. package/dist/tools/shared.d.ts +0 -28
  155. package/dist/tools/shared.js +0 -143
  156. package/dist/tools/shared.js.map +0 -1
@@ -1,13 +1,4 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
12
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
4
  };
@@ -65,9 +56,9 @@ const $kmsPool = {};
65
56
  * @returns http response body
66
57
  */
67
58
  const buildResponse = (statusCode, body, options) => {
68
- const contentType = options === null || options === void 0 ? void 0 : options.contentType;
69
- const origin = (options === null || options === void 0 ? void 0 : options.origin) === undefined ? '*' : options === null || options === void 0 ? void 0 : options.origin;
70
- const credentials = (options === null || options === void 0 ? void 0 : options.credentials) === undefined ? true : options === null || options === void 0 ? void 0 : options.credentials;
59
+ const contentType = options?.contentType;
60
+ const origin = options?.origin === undefined ? '*' : options?.origin;
61
+ const credentials = options?.credentials === undefined ? true : options?.credentials;
71
62
  const isBase64Encoded = contentType && !contentType.startsWith('text/') ? true : false;
72
63
  const _isXml = (body) => body.startsWith('<?xml ') && body.trim().endsWith('>');
73
64
  const _isHtml = (body) => body.startsWith('<!DOCTYPE html>') || (body.startsWith('<') && body.endsWith('>'));
@@ -122,28 +113,28 @@ exports.redirect = redirect;
122
113
  * @param event event
123
114
  * @param $ctx context
124
115
  */
125
- const promised = (event, $ctx) => __awaiter(void 0, void 0, void 0, function* () {
116
+ const promised = async (event, $ctx) => {
126
117
  // TO SERVE BINARY. `$ npm i -S serverless-apigw-binary serverless-apigwy-binary`. refer 'https://read.acloud.guru/serverless-image-optimization-and-delivery-510b6c311fe5'
127
118
  if (event && event.httpMethod == 'GET' && event.path == '/favicon.ico') {
128
119
  return () => (0, exports.success)(FAVICON_ICO, 'image/x-icon');
129
120
  }
130
121
  //* transform to protocol-context.
131
122
  const param = protocol_1.default.service.asTransformer('web').transformToParam(event, $ctx);
132
- (0, engine_1._log)(NS, '! protocol-param =', engine_1.$U.json(Object.assign(Object.assign({}, param), { body: undefined }))); // hide `.body` in log.
123
+ (0, engine_1._log)(NS, '! protocol-param =', engine_1.$U.json({ ...param, body: undefined })); // hide `.body` in log.
133
124
  //* returns object..
134
125
  return { event, param, $ctx };
135
- });
126
+ };
136
127
  exports.promised = promised;
137
128
  /**
138
129
  * builder for default handler
139
130
  */
140
- const mxNextHandler = (thiz) => (params) => __awaiter(void 0, void 0, void 0, function* () {
131
+ const mxNextHandler = (thiz) => async (params) => {
141
132
  //* determine if param or func.
142
133
  const fx = typeof params == 'function' ? params : null;
143
134
  const $param = params && typeof params == 'object' ? params : null;
144
135
  const { param, event } = $param || {};
145
136
  //* call the main handler()
146
- const R = $param ? yield thiz.handleProtocol(param, event) : fx;
137
+ const R = $param ? await thiz.handleProtocol(param, event) : fx;
147
138
  //* - if like to override the full response, then return function.
148
139
  if (R && typeof R == 'function')
149
140
  return R();
@@ -155,7 +146,7 @@ const mxNextHandler = (thiz) => (params) => __awaiter(void 0, void 0, void 0, fu
155
146
  }
156
147
  //* returns response..
157
148
  return (0, exports.success)(R);
158
- });
149
+ };
159
150
  exports.mxNextHandler = mxNextHandler;
160
151
  /**
161
152
  * builder for failure promised.
@@ -215,32 +206,15 @@ exports.mxNextFailure = mxNextFailure;
215
206
  * - default WEB Handler w/ event-listeners.
216
207
  */
217
208
  class LambdaWEBHandler extends lambda_handler_1.LambdaSubHandler {
209
+ //* shared config.
210
+ static REPORT_ERROR = lambda_handler_1.LambdaHandler.REPORT_ERROR;
211
+ //* handlers map.
212
+ _handlers = {};
218
213
  /**
219
214
  * default constructor w/ registering self.
220
215
  */
221
216
  constructor(lambda, register) {
222
217
  super(lambda, register ? 'web' : undefined);
223
- //* handlers map.
224
- this._handlers = {};
225
- /**
226
- * Default WEB Handler.
227
- */
228
- this.handle = (event, $ctx) => __awaiter(this, void 0, void 0, function* () {
229
- //* inspect API parameters.
230
- (0, engine_1._log)(NS, `handle()....`);
231
- const $path = event.pathParameters || {};
232
- const $param = event.queryStringParameters || {};
233
- (0, engine_1._log)(NS, '! path =', event.path);
234
- (0, engine_1._log)(NS, '! $path =', engine_1.$U.json($path));
235
- (0, engine_1._log)(NS, '! $param =', engine_1.$U.json($param));
236
- //* start promised..
237
- return (0, exports.promised)(event, $ctx).then((0, exports.mxNextHandler)(this)).catch((0, exports.mxNextFailure)(event, $ctx));
238
- });
239
- /**
240
- * builder of tools for http-headers
241
- * - extracting header content, and parse.
242
- */
243
- this.tools = (headers) => new MyHttpHeaderTool(headers);
244
218
  // _log(NS, `LambdaWEBHandler()..`);
245
219
  }
246
220
  /**
@@ -285,196 +259,202 @@ class LambdaWEBHandler extends lambda_handler_1.LambdaSubHandler {
285
259
  return M;
286
260
  }, {});
287
261
  }
262
+ /**
263
+ * Default WEB Handler.
264
+ */
265
+ handle = async (event, $ctx) => {
266
+ //* inspect API parameters.
267
+ (0, engine_1._log)(NS, `handle()....`);
268
+ const $path = event.pathParameters || {};
269
+ const $param = event.queryStringParameters || {};
270
+ (0, engine_1._log)(NS, '! path =', event.path);
271
+ (0, engine_1._log)(NS, '! $path =', engine_1.$U.json($path));
272
+ (0, engine_1._log)(NS, '! $param =', engine_1.$U.json($param));
273
+ //* start promised..
274
+ return (0, exports.promised)(event, $ctx).then((0, exports.mxNextHandler)(this)).catch((0, exports.mxNextFailure)(event, $ctx));
275
+ };
288
276
  /**
289
277
  * handle param via protocol-service.
290
278
  *
291
279
  * @param param protocol parameters
292
280
  * @param event (optional) origin event object.
293
281
  */
294
- handleProtocol(param, event) {
295
- return __awaiter(this, void 0, void 0, function* () {
296
- if (!param)
297
- throw new Error(`@param (protocol-param) is required!`);
298
- //TODO [Steve] id, cmd can (or should) be null or empty! (support for `/{cmd+}` pattern) @251212
299
- const TYPE = `${param.type || ''}`;
300
- const MODE = `${param.mode || 'GET'}`;
301
- const ID = `${param.id || ''}`;
302
- const CMD = `${param.cmd || ''}`;
303
- const PATH = `${(event && event.path) || ''}`;
304
- const $param = param.param;
305
- const $body = param.body;
306
- const context = param.context;
307
- //* debug print body.
308
- if (!$body) {
309
- (0, engine_1._log)(NS, `#${MODE}:${CMD} (${TYPE}/${ID})....`);
310
- }
311
- else {
312
- (0, engine_1._log)(NS, `#${MODE}:${CMD} (${TYPE}/${ID}).... body.len=`, $body ? engine_1.$U.json($body).length : -1);
282
+ async handleProtocol(param, event) {
283
+ if (!param)
284
+ throw new Error(`@param (protocol-param) is required!`);
285
+ //TODO [Steve] id, cmd can (or should) be null or empty! (support for `/{cmd+}` pattern) @251212
286
+ const TYPE = `${param.type || ''}`;
287
+ const MODE = `${param.mode || 'GET'}`;
288
+ const ID = `${param.id || ''}`;
289
+ const CMD = `${param.cmd || ''}`;
290
+ const PATH = `${(event && event.path) || ''}`;
291
+ const $param = param.param;
292
+ const $body = param.body;
293
+ const context = param.context;
294
+ //* debug print body.
295
+ if (!$body) {
296
+ (0, engine_1._log)(NS, `#${MODE}:${CMD} (${TYPE}/${ID})....`);
297
+ }
298
+ else {
299
+ (0, engine_1._log)(NS, `#${MODE}:${CMD} (${TYPE}/${ID}).... body.len=`, $body ? engine_1.$U.json($body).length : -1);
300
+ }
301
+ //* find target next function
302
+ // const decoder: NextDecoder | CoreWEBController = this._handlers[TYPE];
303
+ const next = ((decoder) => {
304
+ //* as default handler '/', say the current version.
305
+ if (MODE === 'LIST' && TYPE === '' && ID === '' && CMD === '') {
306
+ return async () => {
307
+ const $pack = (0, tools_1.loadJsonSync)('package.json');
308
+ const name = ($pack && $pack.name) || 'LEMON API';
309
+ const version = ($pack && $pack.version) || '0.0.0';
310
+ const modules = [`${name}/${version}`];
311
+ //* shows version of `lemon-core` via `dependencies`.
312
+ const coreVer = $pack && $pack.dependencies && $pack.dependencies['lemon-core'];
313
+ if (coreVer)
314
+ modules.push(`lemon-core/${coreVer.startsWith('^') ? coreVer.substring(1) : coreVer}`);
315
+ return modules.join('\n');
316
+ };
313
317
  }
314
- //* find target next function
315
- // const decoder: NextDecoder | CoreWEBController = this._handlers[TYPE];
316
- const next = ((decoder) => {
317
- //* as default handler '/', say the current version.
318
- if (MODE === 'LIST' && TYPE === '' && ID === '' && CMD === '') {
319
- return () => __awaiter(this, void 0, void 0, function* () {
320
- const $pack = (0, tools_1.loadJsonSync)('package.json');
321
- const name = ($pack && $pack.name) || 'LEMON API';
322
- const version = ($pack && $pack.version) || '0.0.0';
323
- const modules = [`${name}/${version}`];
324
- //* shows version of `lemon-core` via `dependencies`.
325
- const coreVer = $pack && $pack.dependencies && $pack.dependencies['lemon-core'];
326
- if (coreVer)
327
- modules.push(`lemon-core/${coreVer.startsWith('^') ? coreVer.substring(1) : coreVer}`);
328
- return modules.join('\n');
329
- });
330
- }
331
- //* error if no decoder.
332
- if (!decoder)
333
- return null;
334
- //* use decoder() to find target.
335
- if (typeof decoder == 'function')
336
- return decoder(MODE, ID, CMD, PATH);
337
- else if (typeof decoder == 'object') {
338
- const func = decoder.decode(MODE, ID, CMD, PATH);
339
- if (!func)
340
- return null; // avoid 'null' error.
341
- const next = (i, p, b, c) => func.call(decoder, i, p, b, c);
342
- return next;
343
- }
318
+ //* error if no decoder.
319
+ if (!decoder)
344
320
  return null;
345
- })(this._handlers[TYPE]);
346
- //* if no next, then report error.
347
- if (!next || typeof next != 'function') {
348
- (0, engine_1._err)(NS, `! WARN ! MISSING NEXT-HANDLER. event=`, engine_1.$U.json(event));
349
- throw new Error(`404 NOT FOUND - ${MODE} /${TYPE}/${ID}${CMD ? `/${CMD}` : ''}`);
321
+ //* use decoder() to find target.
322
+ if (typeof decoder == 'function')
323
+ return decoder(MODE, ID, CMD, PATH);
324
+ else if (typeof decoder == 'object') {
325
+ const func = decoder.decode(MODE, ID, CMD, PATH);
326
+ if (!func)
327
+ return null; // avoid 'null' error.
328
+ const next = (i, p, b, c) => func.call(decoder, i, p, b, c);
329
+ return next;
350
330
  }
351
- //* call next.. (it will return result or promised)
352
- return (() => {
353
- try {
354
- const R = next(ID, $param, $body, context);
355
- return R instanceof Promise ? R : Promise.resolve(R);
356
- }
357
- catch (e) {
358
- return Promise.reject(e);
359
- }
360
- })();
361
- });
331
+ return null;
332
+ })(this._handlers[TYPE]);
333
+ //* if no next, then report error.
334
+ if (!next || typeof next != 'function') {
335
+ (0, engine_1._err)(NS, `! WARN ! MISSING NEXT-HANDLER. event=`, engine_1.$U.json(event));
336
+ throw new Error(`404 NOT FOUND - ${MODE} /${TYPE}/${ID}${CMD ? `/${CMD}` : ''}`);
337
+ }
338
+ //* call next.. (it will return result or promised)
339
+ return (() => {
340
+ try {
341
+ const R = next(ID, $param, $body, context);
342
+ return R instanceof Promise ? R : Promise.resolve(R);
343
+ }
344
+ catch (e) {
345
+ return Promise.reject(e);
346
+ }
347
+ })();
362
348
  }
349
+ /**
350
+ * builder of tools for http-headers
351
+ * - extracting header content, and parse.
352
+ */
353
+ tools = (headers) => new MyHttpHeaderTool(headers);
363
354
  /**
364
355
  * pack the request context for Http request.
365
356
  *
366
357
  * @param event origin Event.
367
358
  * @param orgContext (optional) original lambda.Context
368
359
  */
369
- packContext(event, orgContext) {
370
- return __awaiter(this, void 0, void 0, function* () {
371
- (0, engine_1._log)(NS, `packContext(${event ? '' : 'null'})..`);
372
- if (!event)
373
- return null;
374
- //* prepare chain object.
375
- const reqContext = event === null || event === void 0 ? void 0 : event.requestContext;
376
- orgContext && (0, engine_1._log)(NS, `> orgContext =`, engine_1.$U.S(orgContext, 256, 32));
377
- reqContext && (0, engine_1._log)(NS, `> reqContext =`, engine_1.$U.S(reqContext, 256, 32));
378
- // STEP.1 support lambda call JWT Token authentication.
379
- const headers = event.headers;
380
- if (headers && headers[protocol_service_1.HEADER_PROTOCOL_CONTEXT]) {
381
- //* if it is protocol request via lambda, then returns valid context.
382
- const $param = protocol_1.default.service.asTransformer('web').transformToParam(event);
383
- return $param === null || $param === void 0 ? void 0 : $param.context;
384
- }
385
- // STEP.2 use internal identity json data via python lambda call.
386
- const $tool = this.tools(headers);
387
- const identity = yield $tool.parseIdentityHeader();
388
- const _prepare = () => {
389
- const cookie = $tool.parseCookiesHeader();
390
- const domain = $tool.getHeader('host');
391
- const referer = $tool.getHeader('referer');
392
- const origin = $tool.getHeader('origin');
393
- const userAgent = $tool.getHeader('user-agent');
394
- const authorization = $tool.getHeader('authorization');
395
- return { identity, cookie, domain, referer, origin, userAgent, authorization };
396
- };
397
- // STEP.3. prepare the final `next-context`.
398
- const $ctx = yield $tool.prepareContext(_prepare(), reqContext);
399
- $ctx.source = protocol_1.default.service.myProtocolURI($ctx); // self service-uri as source
400
- // FINIAL. returns
401
- return $ctx;
402
- });
360
+ async packContext(event, orgContext) {
361
+ (0, engine_1._log)(NS, `packContext(${event ? '' : 'null'})..`);
362
+ if (!event)
363
+ return null;
364
+ //* prepare chain object.
365
+ const reqContext = event?.requestContext;
366
+ orgContext && (0, engine_1._log)(NS, `> orgContext =`, engine_1.$U.S(orgContext, 256, 32));
367
+ reqContext && (0, engine_1._log)(NS, `> reqContext =`, engine_1.$U.S(reqContext, 256, 32));
368
+ // STEP.1 support lambda call JWT Token authentication.
369
+ const headers = event.headers;
370
+ if (headers && headers[protocol_service_1.HEADER_PROTOCOL_CONTEXT]) {
371
+ //* if it is protocol request via lambda, then returns valid context.
372
+ const $param = protocol_1.default.service.asTransformer('web').transformToParam(event);
373
+ return $param?.context;
374
+ }
375
+ // STEP.2 use internal identity json data via python lambda call.
376
+ const $tool = this.tools(headers);
377
+ const identity = await $tool.parseIdentityHeader();
378
+ const _prepare = () => {
379
+ const cookie = $tool.parseCookiesHeader();
380
+ const domain = $tool.getHeader('host');
381
+ const referer = $tool.getHeader('referer');
382
+ const origin = $tool.getHeader('origin');
383
+ const userAgent = $tool.getHeader('user-agent');
384
+ const authorization = $tool.getHeader('authorization');
385
+ return { identity, cookie, domain, referer, origin, userAgent, authorization };
386
+ };
387
+ // STEP.3. prepare the final `next-context`.
388
+ const $ctx = await $tool.prepareContext(_prepare(), reqContext);
389
+ $ctx.source = protocol_1.default.service.myProtocolURI($ctx); // self service-uri as source
390
+ // FINIAL. returns
391
+ return $ctx;
403
392
  }
404
393
  }
405
394
  exports.LambdaWEBHandler = LambdaWEBHandler;
406
- //* shared config.
407
- LambdaWEBHandler.REPORT_ERROR = lambda_handler_1.LambdaHandler.REPORT_ERROR;
408
395
  /**
409
396
  * class: `MyHttpHeaderTool`
410
397
  * - basic implementation of HttpHeaderTool
411
398
  */
412
399
  class MyHttpHeaderTool {
400
+ headers;
401
+ static _accountId;
402
+ static _accountIdPromise;
413
403
  /**
414
404
  * default constructor.
415
405
  * @param headers
416
406
  */
417
407
  constructor(headers, options) {
418
- var _a;
419
- /** expose `onlyDefined` */
420
- this.onlyDefined = test_helper_1.onlyDefined;
421
- /**
422
- * build default JWT secret from AWS account id + magic key.
423
- */
424
- this.buildJwtSecret = () => __awaiter(this, void 0, void 0, function* () {
425
- const accountId = yield this.getAccountId();
426
- const secret = JWT_MAGIC_KEY; // 유출되면 피곤함.
427
- const _hmac = (msg, key = secret) => engine_1.$U.hmac(msg, key, 'sha256', 'base64'); // 기본 로직
428
- return _hmac(_hmac(accountId, _hmac(JWT_SIGN_KEY)), JWT_SIGN_KEY);
429
- });
430
- /**
431
- * get current aws account-id via STS. (once)
432
- */
433
- this.getAccountId = () => __awaiter(this, void 0, void 0, function* () {
434
- if (MyHttpHeaderTool._accountId)
435
- return MyHttpHeaderTool._accountId;
436
- if (!MyHttpHeaderTool._accountIdPromise) {
437
- MyHttpHeaderTool._accountIdPromise = (() => __awaiter(this, void 0, void 0, function* () {
438
- // 1. getHelloArn()에서 ARN을 통해 accountId 추출 시도
439
- try {
440
- const arn = (0, engine_1.getHelloArn)(null, NS);
441
- if (arn && arn.startsWith('arn:aws:')) {
442
- const accountId = arn.split(':')[4];
443
- if (accountId)
444
- return accountId;
445
- }
446
- }
447
- catch (e) {
448
- (0, engine_1._log)(NS, '! getHelloArn failed, fallback to STS');
449
- }
450
- // 2. fallback: STS 호출 (awsConfig 사용)
451
- const cfg = (0, tools_1.awsConfig)(engine_1.$engine);
452
- const sts = new client_sts_1.STSClient(cfg);
453
- const data = yield sts.send(new client_sts_1.GetCallerIdentityCommand({}));
454
- return (data === null || data === void 0 ? void 0 : data.Account) || '000000000000';
455
- }))().catch(err => {
456
- (0, engine_1._err)(NS, '! err@jwt.accountId =', err);
457
- return '000000000000';
458
- });
459
- }
460
- MyHttpHeaderTool._accountId = yield MyHttpHeaderTool._accountIdPromise;
461
- return MyHttpHeaderTool._accountId;
462
- });
463
- /**
464
- * check if this request is from externals (like API-GW)
465
- * @returns true if in external
466
- */
467
- this.isExternal = () => {
468
- const host = this.getHeader('host');
469
- const isExternal = host ? true : false;
470
- return !!isExternal;
471
- };
472
- const isClone = (_a = options === null || options === void 0 ? void 0 : options.isClone) !== null && _a !== void 0 ? _a : true;
473
- this.headers = isClone ? Object.assign({}, headers) : headers;
408
+ const isClone = options?.isClone ?? true;
409
+ this.headers = isClone ? { ...headers } : headers;
474
410
  }
475
411
  hello() {
476
412
  return 'header-tool-by-default';
477
413
  }
414
+ /** expose `onlyDefined` */
415
+ onlyDefined = test_helper_1.onlyDefined;
416
+ /**
417
+ * build default JWT secret from AWS account id + magic key.
418
+ */
419
+ buildJwtSecret = async () => {
420
+ const accountId = await this.getAccountId();
421
+ const secret = JWT_MAGIC_KEY; // 유출되면 피곤함.
422
+ const _hmac = (msg, key = secret) => engine_1.$U.hmac(msg, key, 'sha256', 'base64'); // 기본 로직
423
+ return _hmac(_hmac(accountId, _hmac(JWT_SIGN_KEY)), JWT_SIGN_KEY);
424
+ };
425
+ /**
426
+ * get current aws account-id via STS. (once)
427
+ */
428
+ getAccountId = async () => {
429
+ if (MyHttpHeaderTool._accountId)
430
+ return MyHttpHeaderTool._accountId;
431
+ if (!MyHttpHeaderTool._accountIdPromise) {
432
+ MyHttpHeaderTool._accountIdPromise = (async () => {
433
+ // 1. getHelloArn()에서 ARN을 통해 accountId 추출 시도
434
+ try {
435
+ const arn = (0, engine_1.getHelloArn)(null, NS);
436
+ if (arn && arn.startsWith('arn:aws:')) {
437
+ const accountId = arn.split(':')[4];
438
+ if (accountId)
439
+ return accountId;
440
+ }
441
+ }
442
+ catch (e) {
443
+ (0, engine_1._log)(NS, '! getHelloArn failed, fallback to STS');
444
+ }
445
+ // 2. fallback: STS 호출 (awsConfig 사용)
446
+ const cfg = (0, tools_1.awsConfig)(engine_1.$engine);
447
+ const sts = new client_sts_1.STSClient(cfg);
448
+ const data = await sts.send(new client_sts_1.GetCallerIdentityCommand({}));
449
+ return data?.Account || '000000000000';
450
+ })().catch(err => {
451
+ (0, engine_1._err)(NS, '! err@jwt.accountId =', err);
452
+ return '000000000000';
453
+ });
454
+ }
455
+ MyHttpHeaderTool._accountId = await MyHttpHeaderTool._accountIdPromise;
456
+ return MyHttpHeaderTool._accountId;
457
+ };
478
458
  /**
479
459
  * get values by name
480
460
  * @param name case-insentive name of field
@@ -509,6 +489,15 @@ class MyHttpHeaderTool {
509
489
  const vals = this.getHeaders(name);
510
490
  return vals.length < 1 ? undefined : vals[vals.length - 1];
511
491
  }
492
+ /**
493
+ * check if this request is from externals (like API-GW)
494
+ * @returns true if in external
495
+ */
496
+ isExternal = () => {
497
+ const host = this.getHeader('host');
498
+ const isExternal = host ? true : false;
499
+ return !!isExternal;
500
+ };
512
501
  /**
513
502
  * parse of header[`x-lemon-identity`] to get the instance of `NextIdentity`
514
503
  * - lambda 호출의 2가지 방법이 있음 (interval vs external)
@@ -523,48 +512,43 @@ class MyHttpHeaderTool {
523
512
  * - support ONLY JWT Token authentication (verification).
524
513
  * - iat
525
514
  */
526
- parseIdentityHeader(name = HEADER_LEMON_IDENTITY) {
527
- var _a;
528
- return __awaiter(this, void 0, void 0, function* () {
529
- //* internal means `request from internal services`
530
- const isInternal = !this.isExternal();
531
- const val = this.getHeader(name);
532
- let result = val ? { meta: val } : {};
533
- try {
534
- if (!val) {
535
- //NOP
536
- }
537
- else if (isInternal && val.startsWith('{') && val.endsWith('}')) {
538
- result = yield this.parseIdentityJson(val);
539
- }
540
- else if (typeof val === 'string' && val.split('.').length === 3) {
541
- result = yield this.parseIdentityJWT(val);
542
- }
515
+ async parseIdentityHeader(name = HEADER_LEMON_IDENTITY) {
516
+ //* internal means `request from internal services`
517
+ const isInternal = !this.isExternal();
518
+ const val = this.getHeader(name);
519
+ let result = val ? { meta: val } : {};
520
+ try {
521
+ if (!val) {
522
+ //NOP
543
523
  }
544
- catch (e) {
545
- (0, engine_1._err)(NS, '!WARN! parse.err =', e);
546
- (0, engine_1._err)(NS, '!WARN! identity =', val);
547
- result.error = (0, test_helper_1.GETERR)(e);
524
+ else if (isInternal && val.startsWith('{') && val.endsWith('}')) {
525
+ result = await this.parseIdentityJson(val);
548
526
  }
549
- //* overwrite finally language selection.
550
- const lang = (_a = this.parseLanguageHeader()) !== null && _a !== void 0 ? _a : result === null || result === void 0 ? void 0 : result.lang;
551
- return Object.assign(Object.assign({}, result), { lang });
552
- });
527
+ else if (typeof val === 'string' && val.split('.').length === 3) {
528
+ result = await this.parseIdentityJWT(val);
529
+ }
530
+ }
531
+ catch (e) {
532
+ (0, engine_1._err)(NS, '!WARN! parse.err =', e);
533
+ (0, engine_1._err)(NS, '!WARN! identity =', val);
534
+ result.error = (0, test_helper_1.GETERR)(e);
535
+ }
536
+ //* overwrite finally language selection.
537
+ const lang = this.parseLanguageHeader() ?? result?.lang;
538
+ return { ...result, lang };
553
539
  }
554
540
  /**
555
541
  * parse as identity from json encoded text.
556
542
  */
557
- parseIdentityJson(val) {
558
- return __awaiter(this, void 0, void 0, function* () {
559
- if (typeof val !== 'string')
560
- throw new Error(`@val[${val}] is invalid - not string!`);
561
- //* (ONLY for internal) parse payload as `json`
562
- const data = JSON.parse(val);
563
- // if (typeof data?.ns !== 'string') throw new Error(`.ns[${data?.ns}] is required - IdentityHeader`);
564
- if (typeof (data === null || data === void 0 ? void 0 : data.sid) !== 'string' || !(data === null || data === void 0 ? void 0 : data.sid))
565
- throw new Error(`.sid[${data === null || data === void 0 ? void 0 : data.sid}] is required - IdentityHeader`);
566
- return data;
567
- });
543
+ async parseIdentityJson(val) {
544
+ if (typeof val !== 'string')
545
+ throw new Error(`@val[${val}] is invalid - not string!`);
546
+ //* (ONLY for internal) parse payload as `json`
547
+ const data = JSON.parse(val);
548
+ // if (typeof data?.ns !== 'string') throw new Error(`.ns[${data?.ns}] is required - IdentityHeader`);
549
+ if (typeof data?.sid !== 'string' || !data?.sid)
550
+ throw new Error(`.sid[${data?.sid}] is required - IdentityHeader`);
551
+ return data;
568
552
  }
569
553
  /**
570
554
  * find(or make) the proper KMSService per key
@@ -581,86 +565,85 @@ class MyHttpHeaderTool {
581
565
  /**
582
566
  * encode as JWT string.
583
567
  */
584
- encodeIdentityJWT(identity, params) {
585
- var _a, _b, _c, _d, _e;
586
- return __awaiter(this, void 0, void 0, function* () {
587
- // STEP.0 validate paramters.
588
- if (!identity || typeof identity !== 'object')
589
- throw new Error(`@identity (object) is required - but ${typeof identity}`);
590
- // STEP.1 prepare payload data
591
- const current = (_a = params === null || params === void 0 ? void 0 : params.current) !== null && _a !== void 0 ? _a : engine_1.$U.current_time_ms();
592
- const alias = params === null || params === void 0 ? void 0 : params.alias;
593
- const useHs256 = (_b = params === null || params === void 0 ? void 0 : params.useHs256) !== null && _b !== void 0 ? _b : false;
594
- const service = (_d = (_c = config_1.default === null || config_1.default === void 0 ? void 0 : config_1.default.config) === null || _c === void 0 ? void 0 : _c.getService) === null || _d === void 0 ? void 0 : _d.call(_c);
595
- // service 검증 (useHs256 + alias 없을 때만)
596
- if (useHs256 && !alias && service && !/^[a-z][a-zA-Z0-9-]*$/.test(service)) {
597
- throw new Error(`@service[${service}] is invalid - encodeIdentityJWT()`);
598
- }
599
- // issuer 결정
600
- const iss = alias ? `kms/${alias}` : useHs256 ? `api/${service}` : null;
601
- // alg 헤더 결정
602
- const alg = alias ? 'RS256' : useHs256 ? 'HS256' : 'RS256';
603
- const payload = Object.assign(Object.assign({}, identity), { iss, iat: Math.floor(current / 1000), exp: (_e = params === null || params === void 0 ? void 0 : params.exp) !== null && _e !== void 0 ? _e : Math.floor(current / 1000) + 24 * 60 * 60 });
604
- const base64url = (t) => (0, aws_kms_service_1.fromBase64)(Buffer.from(t).toString('base64'));
605
- const data = {
606
- header: base64url(JSON.stringify({ alg, typ: 'JWT' })),
607
- payload: base64url(JSON.stringify(payload)),
608
- };
609
- // STEP.2 encode and calc signature.
610
- const message = [data.header, data.payload].join('.');
611
- const signature = alias || useHs256 ? yield this.signToken(alias, message) : '';
612
- const token = [message, signature].join('.');
613
- return { signature, message, token };
614
- });
568
+ async encodeIdentityJWT(identity, params) {
569
+ // STEP.0 validate paramters.
570
+ if (!identity || typeof identity !== 'object')
571
+ throw new Error(`@identity (object) is required - but ${typeof identity}`);
572
+ // STEP.1 prepare payload data
573
+ const current = params?.current ?? engine_1.$U.current_time_ms();
574
+ const alias = params?.alias;
575
+ const useHs256 = params?.useHs256 ?? false;
576
+ const service = config_1.default?.config?.getService?.();
577
+ // service 검증 (useHs256 + alias 없을 때만)
578
+ if (useHs256 && !alias && service && !/^[a-z][a-zA-Z0-9-]*$/.test(service)) {
579
+ throw new Error(`@service[${service}] is invalid - encodeIdentityJWT()`);
580
+ }
581
+ // issuer 결정
582
+ const iss = alias ? `kms/${alias}` : useHs256 ? `api/${service}` : null;
583
+ // alg 헤더 결정
584
+ const alg = alias ? 'RS256' : useHs256 ? 'HS256' : 'RS256';
585
+ const payload = {
586
+ ...identity,
587
+ iss, //* issuer name.
588
+ iat: Math.floor(current / 1000), //* issued at
589
+ exp: params?.exp ?? Math.floor(current / 1000) + 24 * 60 * 60, //* max 1 day.
590
+ };
591
+ const base64url = (t) => (0, aws_kms_service_1.fromBase64)(Buffer.from(t).toString('base64'));
592
+ const data = {
593
+ header: base64url(JSON.stringify({ alg, typ: 'JWT' })),
594
+ payload: base64url(JSON.stringify(payload)),
595
+ };
596
+ // STEP.2 encode and calc signature.
597
+ const message = [data.header, data.payload].join('.');
598
+ const signature = alias || useHs256 ? await this.signToken(alias, message) : '';
599
+ const token = [message, signature].join('.');
600
+ return { signature, message, token };
615
601
  }
616
602
  /**
617
603
  * parse as jwt-token, and validate the signature.
618
604
  * - supports both `kms/*` and `api/*` issuers via verifyToken()
619
605
  */
620
- parseIdentityJWT(token, params) {
621
- var _a, _b;
622
- return __awaiter(this, void 0, void 0, function* () {
623
- const isVerify = (_a = params === null || params === void 0 ? void 0 : params.verify) !== null && _a !== void 0 ? _a : true;
624
- const errScope = `verifyJWT(http)`;
625
- //* it must be JWT Token. verify signature, and load.
626
- if (typeof token !== 'string' || !token)
627
- throw new Error(`@token (string) is required (but ${typeof token}) - ${errScope}`);
628
- const sections = token.split('.');
629
- if (sections.length !== 3)
630
- throw new Error(`@token[${token}] is invalid (format) - ${errScope}`);
631
- // STEP.1 decode jwt, and extract { iss, iat, exp }
632
- const current = (_b = params === null || params === void 0 ? void 0 : params.current) !== null && _b !== void 0 ? _b : engine_1.$U.current_time_ms();
633
- const [header, payload, signature] = sections;
634
- const message = [header, payload].join('.');
635
- const data = engine_1.$U.jwt().decode(token, { complete: false, json: true });
636
- if (!data)
637
- throw new Error(`@token[${token}] is invalid (failed to decode) - ${errScope}`);
638
- const { iss, iat, exp } = data;
639
- // STEP.1-1 validate parameters.
640
- if (typeof iss !== 'string' && iss !== null)
641
- throw new Error(`.iss (string) is required - ${errScope}`);
642
- if (typeof iat !== 'number' && iat !== null)
643
- throw new Error(`.iat (number) is required - ${errScope}`);
644
- if (typeof exp !== 'number' && exp !== null)
645
- throw new Error(`.exp (number) is required - ${errScope}`);
646
- //* skip verification if not required
647
- if (!isVerify)
648
- return data;
649
- // STEP.2 verify signature by iss (supports kms/* and api/*)
650
- const verified = yield this.verifyToken(iss, message, signature, { token }).catch(e => {
651
- throw new Error(`@signature[] is invalid (${(0, test_helper_1.GETERR)(e)}) - ${errScope}`);
652
- });
653
- if (!(verified === null || verified === void 0 ? void 0 : verified.valid)) {
654
- const errMsg = (verified === null || verified === void 0 ? void 0 : verified.error) || `failed to verify by ${iss}`;
655
- throw new Error(`@signature[] is invalid (${errMsg}) - ${errScope}`);
656
- }
657
- // STEP.3 validate expiration
658
- if (!exp)
659
- throw new Error(`.exp[${exp}] is invalid (empty) - ${errScope}`);
660
- if (exp * 1000 < current)
661
- throw new Error(`.exp[${engine_1.$U.ts(exp * 1000)}] is invalid (expired) - ${errScope}`);
606
+ async parseIdentityJWT(token, params) {
607
+ const isVerify = params?.verify ?? true;
608
+ const errScope = `verifyJWT(http)`;
609
+ //* it must be JWT Token. verify signature, and load.
610
+ if (typeof token !== 'string' || !token)
611
+ throw new Error(`@token (string) is required (but ${typeof token}) - ${errScope}`);
612
+ const sections = token.split('.');
613
+ if (sections.length !== 3)
614
+ throw new Error(`@token[${token}] is invalid (format) - ${errScope}`);
615
+ // STEP.1 decode jwt, and extract { iss, iat, exp }
616
+ const current = params?.current ?? engine_1.$U.current_time_ms();
617
+ const [header, payload, signature] = sections;
618
+ const message = [header, payload].join('.');
619
+ const data = engine_1.$U.jwt().decode(token, { complete: false, json: true });
620
+ if (!data)
621
+ throw new Error(`@token[${token}] is invalid (failed to decode) - ${errScope}`);
622
+ const { iss, iat, exp } = data;
623
+ // STEP.1-1 validate parameters.
624
+ if (typeof iss !== 'string' && iss !== null)
625
+ throw new Error(`.iss (string) is required - ${errScope}`);
626
+ if (typeof iat !== 'number' && iat !== null)
627
+ throw new Error(`.iat (number) is required - ${errScope}`);
628
+ if (typeof exp !== 'number' && exp !== null)
629
+ throw new Error(`.exp (number) is required - ${errScope}`);
630
+ //* skip verification if not required
631
+ if (!isVerify)
662
632
  return data;
633
+ // STEP.2 verify signature by iss (supports kms/* and api/*)
634
+ const verified = await this.verifyToken(iss, message, signature, { token }).catch(e => {
635
+ throw new Error(`@signature[] is invalid (${(0, test_helper_1.GETERR)(e)}) - ${errScope}`);
663
636
  });
637
+ if (!verified?.valid) {
638
+ const errMsg = verified?.error || `failed to verify by ${iss}`;
639
+ throw new Error(`@signature[] is invalid (${errMsg}) - ${errScope}`);
640
+ }
641
+ // STEP.3 validate expiration
642
+ if (!exp)
643
+ throw new Error(`.exp[${exp}] is invalid (empty) - ${errScope}`);
644
+ if (exp * 1000 < current)
645
+ throw new Error(`.exp[${engine_1.$U.ts(exp * 1000)}] is invalid (expired) - ${errScope}`);
646
+ return data;
664
647
  }
665
648
  /**
666
649
  * parse of header[HEADER_LEMON_LANGUAGE] to get language-type.
@@ -688,99 +671,93 @@ class MyHttpHeaderTool {
688
671
  /**
689
672
  * override with AWS request-context
690
673
  */
691
- prepareContext($org, reqContext) {
692
- var _a, _b, _c, _d;
693
- return __awaiter(this, void 0, void 0, function* () {
694
- const errScope = `web.prepareContext(${(_a = $org === null || $org === void 0 ? void 0 : $org.requestId) !== null && _a !== void 0 ? _a : ''})`;
695
- // STEP.4 override w/ cognito authentication to NextIdentity.
696
- if (((_b = reqContext === null || reqContext === void 0 ? void 0 : reqContext.identity) === null || _b === void 0 ? void 0 : _b.cognitoIdentityPoolId) !== undefined) {
697
- const $idt = $org === null || $org === void 0 ? void 0 : $org.identity;
698
- if (!$idt)
699
- throw new Error(`.identity (NextIdentity) is required - ${errScope}`);
700
- const $req = reqContext.identity;
701
- (0, engine_1._inf)(NS, '! identity(req) :=', engine_1.$U.json($req));
702
- $idt.identityProvider = $req.cognitoAuthenticationProvider; // provider string.
703
- $idt.identityPoolId = $req.cognitoIdentityPoolId; // identity-pool-id like 'ap-northeast-2:618ce9d2-3ad6-49df-b3b3-e248ea51425e'
704
- $idt.identityId = $req.cognitoIdentityId; // identity-id like 'ap-northeast-2:dbd95fb4-7423-48b8-8a04-56e5bc95e444'
705
- $idt.accountId = $req.accountId; // account-id should be same as context.accountId
706
- $idt.userAgent = $req.userAgent; // user-agent string.
707
- if (typeof $req.caller == 'string')
708
- $idt.caller = $req.caller;
709
- if (typeof $req.accessKey == 'string')
710
- $idt.accessKey = $req.accessKey;
711
- if (typeof $req.apiKey == 'string')
712
- $idt.apiKey = $req.apiKey;
713
- (0, engine_1._inf)(NS, '! identity(new) :=', engine_1.$U.json(Object.assign({}, $idt)));
714
- }
715
- // STEP.5 extract additional request infor from req-context.
716
- const clientIp = `${((_c = reqContext === null || reqContext === void 0 ? void 0 : reqContext.identity) === null || _c === void 0 ? void 0 : _c.sourceIp) || ($org === null || $org === void 0 ? void 0 : $org.clientIp) || ''}`;
717
- const userAgent = `${((_d = reqContext === null || reqContext === void 0 ? void 0 : reqContext.identity) === null || _d === void 0 ? void 0 : _d.userAgent) || ($org === null || $org === void 0 ? void 0 : $org.userAgent) || ''}`;
718
- const requestId = `${(reqContext === null || reqContext === void 0 ? void 0 : reqContext.requestId) || ($org === null || $org === void 0 ? void 0 : $org.requestId) || ''}`;
719
- const accountId = `${(reqContext === null || reqContext === void 0 ? void 0 : reqContext.accountId) || ($org === null || $org === void 0 ? void 0 : $org.accountId) || ''}`;
720
- const domain = `${(reqContext === null || reqContext === void 0 ? void 0 : reqContext.domainName) || ($org === null || $org === void 0 ? void 0 : $org.domain) || ''}`; //* chore avoid null of headers
721
- //* save into headers and returns.
722
- const context = Object.assign(Object.assign({}, $org), { userAgent, clientIp, requestId, accountId, domain });
723
- return context;
724
- });
674
+ async prepareContext($org, reqContext) {
675
+ const errScope = `web.prepareContext(${$org?.requestId ?? ''})`;
676
+ // STEP.4 override w/ cognito authentication to NextIdentity.
677
+ if (reqContext?.identity?.cognitoIdentityPoolId !== undefined) {
678
+ const $idt = $org?.identity;
679
+ if (!$idt)
680
+ throw new Error(`.identity (NextIdentity) is required - ${errScope}`);
681
+ const $req = reqContext.identity;
682
+ (0, engine_1._inf)(NS, '! identity(req) :=', engine_1.$U.json($req));
683
+ $idt.identityProvider = $req.cognitoAuthenticationProvider; // provider string.
684
+ $idt.identityPoolId = $req.cognitoIdentityPoolId; // identity-pool-id like 'ap-northeast-2:618ce9d2-3ad6-49df-b3b3-e248ea51425e'
685
+ $idt.identityId = $req.cognitoIdentityId; // identity-id like 'ap-northeast-2:dbd95fb4-7423-48b8-8a04-56e5bc95e444'
686
+ $idt.accountId = $req.accountId; // account-id should be same as context.accountId
687
+ $idt.userAgent = $req.userAgent; // user-agent string.
688
+ if (typeof $req.caller == 'string')
689
+ $idt.caller = $req.caller;
690
+ if (typeof $req.accessKey == 'string')
691
+ $idt.accessKey = $req.accessKey;
692
+ if (typeof $req.apiKey == 'string')
693
+ $idt.apiKey = $req.apiKey;
694
+ (0, engine_1._inf)(NS, '! identity(new) :=', engine_1.$U.json({ ...$idt }));
695
+ }
696
+ // STEP.5 extract additional request infor from req-context.
697
+ const clientIp = `${reqContext?.identity?.sourceIp || $org?.clientIp || ''}`;
698
+ const userAgent = `${reqContext?.identity?.userAgent || $org?.userAgent || ''}`;
699
+ const requestId = `${reqContext?.requestId || $org?.requestId || ''}`;
700
+ const accountId = `${reqContext?.accountId || $org?.accountId || ''}`;
701
+ const domain = `${reqContext?.domainName || $org?.domain || ''}`; //* chore avoid null of headers
702
+ //* save into headers and returns.
703
+ const context = { ...$org, userAgent, clientIp, requestId, accountId, domain };
704
+ return context;
725
705
  }
726
706
  /**
727
707
  * verify token signature by iss.
728
708
  * - `kms/*`: verify by KMS (RS256)
729
709
  * - `api/*`: verify by HS256 (local) or protocol (remote)
730
710
  */
731
- verifyToken(iss, message, signature, options) {
732
- var _a, _b, _c;
733
- return __awaiter(this, void 0, void 0, function* () {
734
- const errScope = `verifyToken(${iss !== null && iss !== void 0 ? iss : ''})`;
735
- const _alias = (iss, prefix) => {
736
- const value = iss.substring(prefix.length);
737
- return value.includes(',') ? value.substring(0, value.indexOf(',')) : value;
738
- };
739
- try {
740
- // KMS verification (RS256) - iss starts with 'kms/'
741
- if (typeof iss === 'string' && iss.startsWith('kms/')) {
742
- const alias = _alias(iss, 'kms/');
743
- if (!alias)
744
- throw new Error(`@alias (string) is required - ${errScope}`);
745
- const $kms = this.findKMSService(`alias/${alias}`);
746
- const valid = yield $kms.verify(message, signature, { throwable: true });
747
- return { valid };
711
+ async verifyToken(iss, message, signature, options) {
712
+ const errScope = `verifyToken(${iss ?? ''})`;
713
+ const _alias = (iss, prefix) => {
714
+ const value = iss.substring(prefix.length);
715
+ return value.includes(',') ? value.substring(0, value.indexOf(',')) : value;
716
+ };
717
+ try {
718
+ // KMS verification (RS256) - iss starts with 'kms/'
719
+ if (typeof iss === 'string' && iss.startsWith('kms/')) {
720
+ const alias = _alias(iss, 'kms/');
721
+ if (!alias)
722
+ throw new Error(`@alias (string) is required - ${errScope}`);
723
+ const $kms = this.findKMSService(`alias/${alias}`);
724
+ const valid = await $kms.verify(message, signature, { throwable: true });
725
+ return { valid };
726
+ }
727
+ // API verification - iss starts with 'api/'
728
+ if (typeof iss === 'string' && iss.startsWith('api/')) {
729
+ const issuer = iss.substring(4);
730
+ // validate issuer format
731
+ if (!/^[a-z][a-zA-Z0-9-]*$/.test(issuer)) {
732
+ throw new Error(`@issuer[${issuer}] is invalid - ${errScope}`);
748
733
  }
749
- // API verification - iss starts with 'api/'
750
- if (typeof iss === 'string' && iss.startsWith('api/')) {
751
- const issuer = iss.substring(4);
752
- // validate issuer format
753
- if (!/^[a-z][a-zA-Z0-9-]*$/.test(issuer)) {
754
- throw new Error(`@issuer[${issuer}] is invalid - ${errScope}`);
755
- }
756
- const currentService = (_b = (_a = config_1.default === null || config_1.default === void 0 ? void 0 : config_1.default.config) === null || _a === void 0 ? void 0 : _a.getService) === null || _b === void 0 ? void 0 : _b.call(_a);
757
- // verify if issued by current service
758
- if (issuer === currentService) {
759
- const secret = yield this.buildJwtSecret();
760
- const expected = (0, aws_kms_service_1.fromBase64)(engine_1.$U.hmac(message, secret, 'sha256', 'base64'));
761
- const valid = expected === signature;
762
- return { valid };
763
- }
764
- // verify via protocol
765
- const token = (_c = options === null || options === void 0 ? void 0 : options.token) !== null && _c !== void 0 ? _c : `${message}.${signature}`;
766
- const body = { token };
767
- const payload = {
768
- service: issuer,
769
- type: 'oauth',
770
- mode: 'POST',
771
- id: 'verify-token',
772
- body,
773
- context: {},
774
- };
775
- const res = yield protocol_1.default.service.execute(payload);
776
- return res;
734
+ const currentService = config_1.default?.config?.getService?.();
735
+ // verify if issued by current service
736
+ if (issuer === currentService) {
737
+ const secret = await this.buildJwtSecret();
738
+ const expected = (0, aws_kms_service_1.fromBase64)(engine_1.$U.hmac(message, secret, 'sha256', 'base64'));
739
+ const valid = expected === signature;
740
+ return { valid };
777
741
  }
778
- throw new Error(`@iss[${iss}] is invalid (unsupportable issuer) - ${errScope}`);
779
- }
780
- catch (e) {
781
- return { valid: false, error: (0, test_helper_1.GETERR)(e) };
742
+ // verify via protocol
743
+ const token = options?.token ?? `${message}.${signature}`;
744
+ const body = { token };
745
+ const payload = {
746
+ service: issuer,
747
+ type: 'oauth',
748
+ mode: 'POST',
749
+ id: 'verify-token',
750
+ body,
751
+ context: {},
752
+ };
753
+ const res = await protocol_1.default.service.execute(payload);
754
+ return res;
782
755
  }
783
- });
756
+ throw new Error(`@iss[${iss}] is invalid (unsupportable issuer) - ${errScope}`);
757
+ }
758
+ catch (e) {
759
+ return { valid: false, error: (0, test_helper_1.GETERR)(e) };
760
+ }
784
761
  }
785
762
  /**
786
763
  * sign the message w/ alias
@@ -789,29 +766,27 @@ class MyHttpHeaderTool {
789
766
  * @param alias kms key alias
790
767
  * @param message the jwt message string
791
768
  */
792
- signToken(alias, message) {
793
- return __awaiter(this, void 0, void 0, function* () {
794
- const errScope = `signToken(${alias !== null && alias !== void 0 ? alias : ''})`;
795
- if (!message)
796
- throw new Error(`@message (string) is required - ${errScope}`);
797
- const useKms = !!alias;
798
- if (useKms) {
799
- // KMS verification (RS256)
800
- if (!alias)
801
- return '';
802
- const $kms = new aws_kms_service_1.AWSKMSService(`alias/${alias}`);
803
- const signature = yield $kms.sign(message, true);
804
- (0, engine_1._inf)(NS, `> signature[${alias}] with KMS =`, signature);
805
- return signature;
806
- }
807
- else {
808
- // HS256: sign directly with secret
809
- const secret = yield this.buildJwtSecret();
810
- const signature = (0, aws_kms_service_1.fromBase64)(engine_1.$U.hmac(message, secret, 'sha256', 'base64'));
811
- (0, engine_1._inf)(NS, `> signature[${alias}] with HS256 =`, signature);
812
- return signature;
813
- }
814
- });
769
+ async signToken(alias, message) {
770
+ const errScope = `signToken(${alias ?? ''})`;
771
+ if (!message)
772
+ throw new Error(`@message (string) is required - ${errScope}`);
773
+ const useKms = !!alias;
774
+ if (useKms) {
775
+ // KMS verification (RS256)
776
+ if (!alias)
777
+ return '';
778
+ const $kms = new aws_kms_service_1.AWSKMSService(`alias/${alias}`);
779
+ const signature = await $kms.sign(message, true);
780
+ (0, engine_1._inf)(NS, `> signature[${alias}] with KMS =`, signature);
781
+ return signature;
782
+ }
783
+ else {
784
+ // HS256: sign directly with secret
785
+ const secret = await this.buildJwtSecret();
786
+ const signature = (0, aws_kms_service_1.fromBase64)(engine_1.$U.hmac(message, secret, 'sha256', 'base64'));
787
+ (0, engine_1._inf)(NS, `> signature[${alias}] with HS256 =`, signature);
788
+ return signature;
789
+ }
815
790
  }
816
791
  }
817
792
  exports.MyHttpHeaderTool = MyHttpHeaderTool;