lemon-core 3.0.2 → 3.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/dist/common/test-helper.js +19 -11
- package/dist/common/test-helper.js.map +1 -1
- package/dist/controllers/dummy-controller.d.ts +2 -2
- package/dist/controllers/dummy-controller.js +2 -2
- package/dist/controllers/dummy-controller.js.map +1 -1
- package/dist/controllers/general-api-controller.d.ts +2 -2
- package/dist/controllers/general-api-controller.js +5 -5
- package/dist/controllers/general-api-controller.js.map +1 -1
- package/dist/controllers/general-controller.d.ts +1 -1
- package/dist/controllers/general-controller.js +2 -1
- package/dist/controllers/general-controller.js.map +1 -1
- package/dist/controllers/index.js +6 -2
- package/dist/controllers/index.js.map +1 -1
- package/dist/cores/{api-service.d.ts → api/api-service.d.ts} +0 -0
- package/dist/cores/{api-service.js → api/api-service.js} +22 -21
- package/dist/cores/api/api-service.js.map +1 -0
- package/dist/cores/api/index.d.ts +10 -0
- package/dist/cores/api/index.js +27 -0
- package/dist/cores/api/index.js.map +1 -0
- package/dist/cores/aws/aws-kms-service.d.ts +53 -2
- package/dist/cores/aws/aws-kms-service.js +112 -29
- package/dist/cores/aws/aws-kms-service.js.map +1 -1
- package/dist/cores/aws/aws-s3-service.js +19 -18
- package/dist/cores/aws/aws-s3-service.js.map +1 -1
- package/dist/cores/aws/aws-sns-service.js +10 -10
- package/dist/cores/aws/aws-sns-service.js.map +1 -1
- package/dist/cores/aws/aws-sqs-service.js +12 -12
- package/dist/cores/aws/aws-sqs-service.js.map +1 -1
- package/dist/cores/aws/index.js +1 -1
- package/dist/cores/{cache-service.d.ts → cache/cache-service.d.ts} +77 -25
- package/dist/cores/{cache-service.js → cache/cache-service.js} +77 -47
- package/dist/cores/cache/cache-service.js.map +1 -0
- package/dist/cores/cache/index.d.ts +10 -0
- package/dist/cores/cache/index.js +27 -0
- package/dist/cores/cache/index.js.map +1 -0
- package/dist/cores/config/config-service.js +11 -10
- package/dist/cores/config/config-service.js.map +1 -1
- package/dist/cores/core-services.d.ts +1 -2
- package/dist/cores/core-services.js +0 -21
- package/dist/cores/core-services.js.map +1 -1
- package/dist/cores/{dynamo-query-service.d.ts → dynamo/dynamo-query-service.d.ts} +1 -1
- package/dist/cores/{dynamo-query-service.js → dynamo/dynamo-query-service.js} +10 -10
- package/dist/cores/dynamo/dynamo-query-service.js.map +1 -0
- package/dist/cores/{dynamo-scan-service.d.ts → dynamo/dynamo-scan-service.d.ts} +1 -1
- package/dist/cores/{dynamo-scan-service.js → dynamo/dynamo-scan-service.js} +11 -11
- package/dist/cores/dynamo/dynamo-scan-service.js.map +1 -0
- package/dist/cores/{dynamo-service.d.ts → dynamo/dynamo-service.d.ts} +1 -1
- package/dist/cores/{dynamo-service.js → dynamo/dynamo-service.js} +21 -21
- package/dist/cores/dynamo/dynamo-service.js.map +1 -0
- package/dist/cores/dynamo/index.d.ts +12 -0
- package/dist/cores/dynamo/index.js +29 -0
- package/dist/cores/dynamo/index.js.map +1 -0
- package/dist/cores/{elastic6-query-service.d.ts → elastic/elastic6-query-service.d.ts} +1 -1
- package/dist/cores/{elastic6-query-service.js → elastic/elastic6-query-service.js} +8 -8
- package/dist/cores/elastic/elastic6-query-service.js.map +1 -0
- package/dist/cores/{elastic6-service.d.ts → elastic/elastic6-service.d.ts} +1 -1
- package/dist/cores/{elastic6-service.js → elastic/elastic6-service.js} +60 -68
- package/dist/cores/elastic/elastic6-service.js.map +1 -0
- package/dist/cores/{hangul-service.d.ts → elastic/hangul-service.d.ts} +17 -3
- package/dist/cores/{hangul-service.js → elastic/hangul-service.js} +17 -8
- package/dist/cores/elastic/hangul-service.js.map +1 -0
- package/dist/cores/elastic/index.d.ts +12 -0
- package/dist/cores/elastic/index.js +29 -0
- package/dist/cores/elastic/index.js.map +1 -0
- package/dist/cores/index.d.ts +10 -16
- package/dist/cores/index.js +15 -16
- package/dist/cores/index.js.map +1 -1
- package/dist/cores/lambda/index.js +8 -4
- package/dist/cores/lambda/index.js.map +1 -1
- package/dist/cores/lambda/lambda-cognito-handler.js +2 -2
- package/dist/cores/lambda/lambda-cognito-handler.js.map +1 -1
- package/dist/cores/lambda/lambda-cron-handler.d.ts +1 -1
- package/dist/cores/lambda/lambda-cron-handler.js +2 -2
- package/dist/cores/lambda/lambda-cron-handler.js.map +1 -1
- package/dist/cores/lambda/lambda-dynamo-stream-handler.d.ts +3 -3
- package/dist/cores/lambda/lambda-dynamo-stream-handler.js +20 -20
- package/dist/cores/lambda/lambda-dynamo-stream-handler.js.map +1 -1
- package/dist/cores/lambda/lambda-handler.d.ts +2 -1
- package/dist/cores/lambda/lambda-handler.js +12 -11
- package/dist/cores/lambda/lambda-handler.js.map +1 -1
- package/dist/cores/lambda/lambda-notification-handler.d.ts +1 -1
- package/dist/cores/lambda/lambda-notification-handler.js +10 -10
- package/dist/cores/lambda/lambda-notification-handler.js.map +1 -1
- package/dist/cores/lambda/lambda-sns-handler.d.ts +1 -1
- package/dist/cores/lambda/lambda-sns-handler.js +13 -13
- package/dist/cores/lambda/lambda-sns-handler.js.map +1 -1
- package/dist/cores/lambda/lambda-sqs-handler.d.ts +1 -1
- package/dist/cores/lambda/lambda-sqs-handler.js +13 -13
- package/dist/cores/lambda/lambda-sqs-handler.js.map +1 -1
- package/dist/cores/lambda/lambda-web-handler.d.ts +158 -8
- package/dist/cores/lambda/lambda-web-handler.js +330 -119
- package/dist/cores/lambda/lambda-web-handler.js.map +1 -1
- package/dist/cores/lambda/lambda-wss-handler.js +16 -12
- package/dist/cores/lambda/lambda-wss-handler.js.map +1 -1
- package/dist/cores/protocol/protocol-service.d.ts +5 -1
- package/dist/cores/protocol/protocol-service.js +46 -40
- package/dist/cores/protocol/protocol-service.js.map +1 -1
- package/dist/cores/{http-storage-service.d.ts → storage/http-storage-service.d.ts} +1 -1
- package/dist/cores/{http-storage-service.js → storage/http-storage-service.js} +6 -6
- package/dist/cores/storage/http-storage-service.js.map +1 -0
- package/dist/cores/storage/index.d.ts +14 -0
- package/dist/cores/storage/index.js +31 -0
- package/dist/cores/storage/index.js.map +1 -0
- package/dist/cores/{model-manager.d.ts → storage/model-manager.d.ts} +2 -1
- package/dist/cores/{model-manager.js → storage/model-manager.js} +12 -12
- package/dist/cores/storage/model-manager.js.map +1 -0
- package/dist/cores/{proxy-storage-service.d.ts → storage/proxy-storage-service.d.ts} +3 -72
- package/dist/cores/{proxy-storage-service.js → storage/proxy-storage-service.js} +13 -19
- package/dist/cores/storage/proxy-storage-service.js.map +1 -0
- package/dist/cores/{redis-storage-service.d.ts → storage/redis-storage-service.d.ts} +0 -0
- package/dist/cores/{redis-storage-service.js → storage/redis-storage-service.js} +14 -14
- package/dist/cores/storage/redis-storage-service.js.map +1 -0
- package/dist/cores/{storage-service.d.ts → storage/storage-service.d.ts} +6 -19
- package/dist/cores/{storage-service.js → storage/storage-service.js} +9 -19
- package/dist/cores/storage/storage-service.js.map +1 -0
- package/dist/engine/builder.js +27 -20
- package/dist/engine/builder.js.map +1 -1
- package/dist/engine/engine.d.ts +1 -1
- package/dist/engine/engine.js +53 -44
- package/dist/engine/engine.js.map +1 -1
- package/dist/engine/index.js +8 -4
- package/dist/engine/index.js.map +1 -1
- package/dist/engine/utilities.d.ts +4 -3
- package/dist/engine/utilities.js +32 -37
- package/dist/engine/utilities.js.map +1 -1
- package/dist/environ.d.ts +2 -2
- package/dist/environ.js +20 -10
- package/dist/environ.js.map +1 -1
- package/dist/exec-cli.js +26 -26
- package/dist/exec-cli.js.map +1 -1
- package/dist/extended/abstract-service.d.ts +540 -0
- package/dist/extended/abstract-service.js +924 -0
- package/dist/extended/abstract-service.js.map +1 -0
- package/dist/extended/index.d.ts +10 -0
- package/dist/extended/index.js +27 -0
- package/dist/extended/index.js.map +1 -0
- package/dist/helpers/helpers.d.ts +8 -1
- package/dist/helpers/helpers.js +25 -12
- package/dist/helpers/helpers.js.map +1 -1
- package/dist/helpers/index.js +6 -2
- package/dist/helpers/index.js.map +1 -1
- package/dist/index.d.ts +6 -5
- package/dist/index.js +10 -4
- package/dist/index.js.map +1 -1
- package/dist/lib/dynamo/expressions.js +35 -27
- package/dist/lib/dynamo/expressions.js.map +1 -1
- package/dist/lib/dynamo/query.js +24 -20
- package/dist/lib/dynamo/query.js.map +1 -1
- package/dist/lib/dynamo/scan.js +17 -13
- package/dist/lib/dynamo/scan.js.map +1 -1
- package/dist/lib/dynamo/serializer.js +11 -7
- package/dist/lib/dynamo/serializer.js.map +1 -1
- package/dist/lib/dynamo/utils.js +19 -14
- package/dist/lib/dynamo/utils.js.map +1 -1
- package/dist/lib/dynamodb-value.js +3 -3
- package/dist/lib/dynamodb-value.js.map +1 -1
- package/dist/lib/index.js +6 -2
- package/dist/lib/index.js.map +1 -1
- package/dist/tools/express.js +21 -15
- package/dist/tools/express.js.map +1 -1
- package/dist/tools/index.js +6 -2
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/shared.js +12 -6
- package/dist/tools/shared.js.map +1 -1
- package/package.json +18 -15
- package/dist/cores/api-service.js.map +0 -1
- package/dist/cores/cache-service.js.map +0 -1
- package/dist/cores/core-types.d.ts +0 -368
- package/dist/cores/core-types.js +0 -15
- package/dist/cores/core-types.js.map +0 -1
- package/dist/cores/dynamo-query-service.js.map +0 -1
- package/dist/cores/dynamo-scan-service.js.map +0 -1
- package/dist/cores/dynamo-service.js.map +0 -1
- package/dist/cores/elastic6-query-service.js.map +0 -1
- package/dist/cores/elastic6-service.js.map +0 -1
- package/dist/cores/hangul-service.js.map +0 -1
- package/dist/cores/http-storage-service.js.map +0 -1
- package/dist/cores/model-manager.js.map +0 -1
- package/dist/cores/proxy-storage-service.js.map +0 -1
- package/dist/cores/redis-storage-service.js.map +0 -1
- package/dist/cores/storage-service.js.map +0 -1
- package/dist/tools/helpers.d.ts +0 -243
- package/dist/tools/helpers.js +0 -593
- package/dist/tools/helpers.js.map +0 -1
|
@@ -12,7 +12,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.LambdaWEBHandler = exports.mxNextFailure = exports.mxNextHandler = exports.promised = exports.redirect = exports.failure = exports.notfound = exports.success = exports.buildResponse = void 0;
|
|
15
|
+
exports.MyHttpHeaderTool = exports.LambdaWEBHandler = exports.mxNextFailure = exports.mxNextHandler = exports.promised = exports.redirect = exports.failure = exports.notfound = exports.success = exports.buildResponse = void 0;
|
|
16
16
|
/**
|
|
17
17
|
* `lambda-web-handler.ts`
|
|
18
18
|
* - lambda handler to process WEB(API) event.
|
|
@@ -25,6 +25,7 @@ exports.LambdaWEBHandler = exports.mxNextFailure = exports.mxNextHandler = expor
|
|
|
25
25
|
*
|
|
26
26
|
* @author Steve Jung <steve@lemoncloud.io>
|
|
27
27
|
* @date 2019-11-20 initial version via backbone
|
|
28
|
+
* @date 2022-04-07 use env, and opt header-parser
|
|
28
29
|
*
|
|
29
30
|
* @copyright (C) 2019 LemonCloud Co Ltd. - All Rights Reserved.
|
|
30
31
|
*/
|
|
@@ -33,17 +34,28 @@ const engine_1 = require("../../engine/");
|
|
|
33
34
|
const lambda_handler_1 = require("./lambda-handler");
|
|
34
35
|
const shared_1 = require("../../tools/shared");
|
|
35
36
|
const test_helper_1 = require("../../common/test-helper");
|
|
37
|
+
const protocol_service_1 = require("../protocol/protocol-service");
|
|
38
|
+
const aws_kms_service_1 = require("../aws/aws-kms-service");
|
|
36
39
|
const protocol_1 = __importDefault(require("../protocol/"));
|
|
37
40
|
const NS = engine_1.$U.NS('HWEB', 'yellow'); // NAMESPACE TO BE PRINTED.
|
|
38
|
-
//! header
|
|
41
|
+
//! header definitions by environment.
|
|
39
42
|
const HEADER_LEMON_LANGUAGE = engine_1.$U.env('HEADER_LEMON_LANGUAGE', 'x-lemon-language');
|
|
40
43
|
const HEADER_LEMON_IDENTITY = engine_1.$U.env('HEADER_LEMON_IDENTITY', 'x-lemon-identity');
|
|
41
|
-
const HEADER_COOKIE = 'cookie';
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
const HEADER_COOKIE = engine_1.$U.env('HEADER_COOKIE', 'cookie');
|
|
45
|
+
const DEFAULT_FAVICON_ICO = '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';
|
|
46
|
+
const FAVICON_ICO = engine_1.$U.env('FAVICON_ICO', DEFAULT_FAVICON_ICO);
|
|
47
|
+
/**
|
|
48
|
+
* build http response body
|
|
49
|
+
* - if body is string type, then content-type would be text/<some>.
|
|
50
|
+
* - or default type is json
|
|
51
|
+
*
|
|
52
|
+
* @param statusCode http response code like 200
|
|
53
|
+
* @param body string or object
|
|
54
|
+
* @param contentType (optional) the target content-type
|
|
55
|
+
* @param origin (optional) the allow origin (default *)
|
|
56
|
+
* @returns http response body
|
|
57
|
+
*/
|
|
58
|
+
const buildResponse = (statusCode, body, contentType, origin) => {
|
|
47
59
|
const isBase64Encoded = contentType && !contentType.startsWith('text/') ? true : false;
|
|
48
60
|
contentType =
|
|
49
61
|
contentType ||
|
|
@@ -52,55 +64,61 @@ exports.buildResponse = (statusCode, body, contentType, origin) => {
|
|
|
52
64
|
? 'text/html; charset=utf-8'
|
|
53
65
|
: 'text/plain; charset=utf-8'
|
|
54
66
|
: 'application/json; charset=utf-8');
|
|
55
|
-
// @0612 - body 가 string일 경우, 응답형식을 텍스트로 바꿔서 출력한다.
|
|
56
67
|
return {
|
|
57
68
|
statusCode,
|
|
58
69
|
headers: {
|
|
59
70
|
'Content-Type': contentType,
|
|
60
71
|
'Access-Control-Allow-Origin': `${origin || '*'}`,
|
|
61
72
|
'Access-Control-Allow-Credentials': true,
|
|
62
|
-
|
|
73
|
+
// eslint-disable-next-line prettier/prettier
|
|
74
|
+
'Access-Control-Allow-Headers': ['origin', HEADER_LEMON_LANGUAGE, HEADER_LEMON_IDENTITY].filter(s => !!s).join(', '), // custom headers
|
|
63
75
|
},
|
|
64
76
|
body: typeof body === 'string' ? body : JSON.stringify(body),
|
|
65
77
|
isBase64Encoded,
|
|
66
78
|
};
|
|
67
79
|
};
|
|
68
|
-
exports.
|
|
69
|
-
|
|
80
|
+
exports.buildResponse = buildResponse;
|
|
81
|
+
const success = (body, contentType, origin) => {
|
|
82
|
+
return (0, exports.buildResponse)(200, body, contentType, origin);
|
|
70
83
|
};
|
|
71
|
-
exports.
|
|
72
|
-
|
|
84
|
+
exports.success = success;
|
|
85
|
+
const notfound = (body) => {
|
|
86
|
+
return (0, exports.buildResponse)(404, body);
|
|
73
87
|
};
|
|
74
|
-
exports.
|
|
75
|
-
|
|
88
|
+
exports.notfound = notfound;
|
|
89
|
+
const failure = (body, status) => {
|
|
90
|
+
return (0, exports.buildResponse)(status || 503, body);
|
|
76
91
|
};
|
|
77
|
-
exports.
|
|
78
|
-
|
|
92
|
+
exports.failure = failure;
|
|
93
|
+
const redirect = (location, status) => {
|
|
94
|
+
const res = (0, exports.buildResponse)(status || 302, '');
|
|
79
95
|
res.headers['Location'] = location; // set location.
|
|
80
96
|
return res;
|
|
81
97
|
};
|
|
98
|
+
exports.redirect = redirect;
|
|
82
99
|
/**
|
|
83
100
|
* start proxy-chain by event & context.
|
|
84
101
|
* @param event event
|
|
85
102
|
* @param $ctx context
|
|
86
103
|
*/
|
|
87
|
-
|
|
104
|
+
const promised = (event, $ctx) => __awaiter(void 0, void 0, void 0, function* () {
|
|
88
105
|
// TO SERVE BINARY. `$ npm i -S serverless-apigw-binary serverless-apigwy-binary`. refer 'https://read.acloud.guru/serverless-image-optimization-and-delivery-510b6c311fe5'
|
|
89
106
|
if (event && event.httpMethod == 'GET' && event.path == '/favicon.ico') {
|
|
90
|
-
return () => exports.success(FAVICON_ICO, 'image/x-icon');
|
|
107
|
+
return () => (0, exports.success)(FAVICON_ICO, 'image/x-icon');
|
|
91
108
|
}
|
|
92
109
|
//! transform to protocol-context.
|
|
93
|
-
if (event && event.headers && !event.headers[
|
|
94
|
-
event.headers[
|
|
110
|
+
if (event && event.headers && !event.headers[protocol_service_1.HEADER_PROTOCOL_CONTEXT])
|
|
111
|
+
event.headers[protocol_service_1.HEADER_PROTOCOL_CONTEXT] = $ctx ? engine_1.$U.json($ctx) : null;
|
|
95
112
|
const param = protocol_1.default.service.asTransformer('web').transformToParam(event);
|
|
96
|
-
engine_1._log(NS, '! protocol-param =', engine_1.$U.json(Object.assign(Object.assign({}, param), { body: undefined }))); // hide `.body` in log.
|
|
113
|
+
(0, engine_1._log)(NS, '! protocol-param =', engine_1.$U.json(Object.assign(Object.assign({}, param), { body: undefined }))); // hide `.body` in log.
|
|
97
114
|
//! returns object..
|
|
98
115
|
return { event, param };
|
|
99
116
|
});
|
|
117
|
+
exports.promised = promised;
|
|
100
118
|
/**
|
|
101
119
|
* builder for default handler
|
|
102
120
|
*/
|
|
103
|
-
|
|
121
|
+
const mxNextHandler = (thiz) => (params) => __awaiter(void 0, void 0, void 0, function* () {
|
|
104
122
|
//! determine if param or func.
|
|
105
123
|
const fx = typeof params == 'function' ? params : null;
|
|
106
124
|
const $param = params && typeof params == 'object' ? params : null;
|
|
@@ -114,20 +132,21 @@ exports.mxNextHandler = (thiz) => (params) => __awaiter(void 0, void 0, void 0,
|
|
|
114
132
|
const { httpMethod: method, headers } = event || {};
|
|
115
133
|
if (method && method != 'GET') {
|
|
116
134
|
const origin = `${(headers && headers['origin']) || ''}`;
|
|
117
|
-
return exports.success(R, null, origin);
|
|
135
|
+
return (0, exports.success)(R, null, origin);
|
|
118
136
|
}
|
|
119
137
|
//! returns response..
|
|
120
|
-
return exports.success(R);
|
|
138
|
+
return (0, exports.success)(R);
|
|
121
139
|
});
|
|
140
|
+
exports.mxNextHandler = mxNextHandler;
|
|
122
141
|
/**
|
|
123
142
|
* builder for failure promised.
|
|
124
143
|
*/
|
|
125
|
-
|
|
126
|
-
engine_1._err(NS, `! err =`, e instanceof Error ? e : engine_1.$U.json(e));
|
|
144
|
+
const mxNextFailure = (event, $ctx) => (e) => {
|
|
145
|
+
(0, engine_1._err)(NS, `! err =`, e instanceof Error ? e : engine_1.$U.json(e));
|
|
127
146
|
const message = `${e.message || e.reason || engine_1.$U.json(e)}`;
|
|
128
147
|
if (message.startsWith('404 NOT FOUND'))
|
|
129
|
-
return exports.notfound(message);
|
|
130
|
-
engine_1._err(NS, `! err.msg =`, message);
|
|
148
|
+
return (0, exports.notfound)(message);
|
|
149
|
+
(0, engine_1._err)(NS, `! err.msg =`, message);
|
|
131
150
|
//! common format of error.
|
|
132
151
|
if (typeof message == 'string' && /^[1-9][0-9]{2} [A-Z ]+/.test(message)) {
|
|
133
152
|
const status = engine_1.$U.N(message.substring(0, 3), 0);
|
|
@@ -135,36 +154,37 @@ exports.mxNextFailure = (event, $ctx) => (e) => {
|
|
|
135
154
|
if ((status == 301 || status == 302) && message.indexOf(' - ') > 0) {
|
|
136
155
|
const loc = message.substring(message.indexOf(' - ') + 3).trim();
|
|
137
156
|
if (loc)
|
|
138
|
-
return exports.redirect(loc, status);
|
|
157
|
+
return (0, exports.redirect)(loc, status);
|
|
139
158
|
}
|
|
140
159
|
//! handle for `400 SIGNATURE - fail to verify!`. ignore report-error.
|
|
141
160
|
if (status == 400 && message.startsWith('400 SIGNATURE')) {
|
|
142
|
-
return exports.failure(message, status);
|
|
161
|
+
return (0, exports.failure)(message, status);
|
|
143
162
|
}
|
|
144
163
|
//! report error and returns
|
|
145
164
|
if (lambda_handler_1.LambdaHandler.REPORT_ERROR)
|
|
146
|
-
engine_1.doReportError(e, $ctx, event).catch(test_helper_1.GETERR);
|
|
147
|
-
return exports.failure(message, status);
|
|
165
|
+
(0, engine_1.doReportError)(e, $ctx, event).catch(test_helper_1.GETERR);
|
|
166
|
+
return (0, exports.failure)(message, status);
|
|
148
167
|
}
|
|
149
168
|
else if (typeof message == 'string' && /^\.[a-zA-Z0-9_\-]+/.test(message)) {
|
|
150
169
|
//! handle for message `.name () is required!`
|
|
151
170
|
//! report error and returns
|
|
152
171
|
if (lambda_handler_1.LambdaHandler.REPORT_ERROR)
|
|
153
|
-
engine_1.doReportError(e, $ctx, event).catch(test_helper_1.GETERR);
|
|
154
|
-
return exports.failure(message, 400);
|
|
172
|
+
(0, engine_1.doReportError)(e, $ctx, event).catch(test_helper_1.GETERR);
|
|
173
|
+
return (0, exports.failure)(message, 400);
|
|
155
174
|
}
|
|
156
175
|
else if (typeof message == 'string' && /^\@[a-zA-Z0-9_\-]+/.test(message)) {
|
|
157
176
|
//! handle for message `@name () is required!`
|
|
158
177
|
//! report error and returns
|
|
159
178
|
if (lambda_handler_1.LambdaHandler.REPORT_ERROR)
|
|
160
|
-
engine_1.doReportError(e, $ctx, event).catch(test_helper_1.GETERR);
|
|
161
|
-
return exports.failure(message, 400);
|
|
179
|
+
(0, engine_1.doReportError)(e, $ctx, event).catch(test_helper_1.GETERR);
|
|
180
|
+
return (0, exports.failure)(message, 400);
|
|
162
181
|
}
|
|
163
182
|
//! report error and returns
|
|
164
183
|
if (lambda_handler_1.LambdaHandler.REPORT_ERROR)
|
|
165
|
-
engine_1.doReportError(e, $ctx, event).catch(test_helper_1.GETERR);
|
|
166
|
-
return exports.failure(e instanceof Error ? message : e);
|
|
184
|
+
(0, engine_1.doReportError)(e, $ctx, event).catch(test_helper_1.GETERR);
|
|
185
|
+
return (0, exports.failure)(e instanceof Error ? message : e);
|
|
167
186
|
};
|
|
187
|
+
exports.mxNextFailure = mxNextFailure;
|
|
168
188
|
/**
|
|
169
189
|
* class: LambdaWEBHandler
|
|
170
190
|
* - default WEB Handler w/ event-listeners.
|
|
@@ -182,17 +202,20 @@ class LambdaWEBHandler extends lambda_handler_1.LambdaSubHandler {
|
|
|
182
202
|
*/
|
|
183
203
|
this.handle = (event, $ctx) => __awaiter(this, void 0, void 0, function* () {
|
|
184
204
|
//! inspect API parameters.
|
|
185
|
-
engine_1._log(NS, `handle()....`);
|
|
205
|
+
(0, engine_1._log)(NS, `handle()....`);
|
|
186
206
|
const $path = event.pathParameters || {};
|
|
187
207
|
const $param = event.queryStringParameters || {};
|
|
188
|
-
engine_1._log(NS, '! path =', event.path);
|
|
189
|
-
engine_1._log(NS, '! $path =', engine_1.$U.json($path));
|
|
190
|
-
engine_1._log(NS, '! $param =', engine_1.$U.json($param));
|
|
208
|
+
(0, engine_1._log)(NS, '! path =', event.path);
|
|
209
|
+
(0, engine_1._log)(NS, '! $path =', engine_1.$U.json($path));
|
|
210
|
+
(0, engine_1._log)(NS, '! $param =', engine_1.$U.json($param));
|
|
191
211
|
//! start promised..
|
|
192
|
-
return exports.promised(event, $ctx)
|
|
193
|
-
.then(exports.mxNextHandler(this))
|
|
194
|
-
.catch(exports.mxNextFailure(event, $ctx));
|
|
212
|
+
return (0, exports.promised)(event, $ctx).then((0, exports.mxNextHandler)(this)).catch((0, exports.mxNextFailure)(event, $ctx));
|
|
195
213
|
});
|
|
214
|
+
/**
|
|
215
|
+
* builder of tools for http-headers
|
|
216
|
+
* - extracting header content, and parse.
|
|
217
|
+
*/
|
|
218
|
+
this.tools = (headers) => new MyHttpHeaderTool(this, headers);
|
|
196
219
|
// _log(NS, `LambdaWEBHandler()..`);
|
|
197
220
|
}
|
|
198
221
|
/**
|
|
@@ -221,7 +244,7 @@ class LambdaWEBHandler extends lambda_handler_1.LambdaSubHandler {
|
|
|
221
244
|
if (typeof controller !== 'object')
|
|
222
245
|
throw new Error(`@controller (object) is required!`);
|
|
223
246
|
const type = controller.type();
|
|
224
|
-
engine_1._log(NS, `> web-controller[${type}] =`, controller.hello());
|
|
247
|
+
(0, engine_1._log)(NS, `> web-controller[${type}] =`, controller.hello());
|
|
225
248
|
this._handlers[type] = controller;
|
|
226
249
|
}
|
|
227
250
|
/**
|
|
@@ -257,10 +280,10 @@ class LambdaWEBHandler extends lambda_handler_1.LambdaSubHandler {
|
|
|
257
280
|
const context = param.context;
|
|
258
281
|
//! debug print body.
|
|
259
282
|
if (!$body) {
|
|
260
|
-
engine_1._log(NS, `#${MODE}:${CMD} (${TYPE}/${ID})....`);
|
|
283
|
+
(0, engine_1._log)(NS, `#${MODE}:${CMD} (${TYPE}/${ID})....`);
|
|
261
284
|
}
|
|
262
285
|
else {
|
|
263
|
-
engine_1._log(NS, `#${MODE}:${CMD} (${TYPE}/${ID}).... body.len=`, $body ? engine_1.$U.json($body).length : -1);
|
|
286
|
+
(0, engine_1._log)(NS, `#${MODE}:${CMD} (${TYPE}/${ID}).... body.len=`, $body ? engine_1.$U.json($body).length : -1);
|
|
264
287
|
}
|
|
265
288
|
//! find target next function
|
|
266
289
|
// const decoder: NextDecoder | CoreWEBController = this._handlers[TYPE];
|
|
@@ -268,7 +291,7 @@ class LambdaWEBHandler extends lambda_handler_1.LambdaSubHandler {
|
|
|
268
291
|
//! as default handler '/', say the current version.
|
|
269
292
|
if (MODE === 'LIST' && TYPE === '' && ID === '' && CMD === '') {
|
|
270
293
|
return () => __awaiter(this, void 0, void 0, function* () {
|
|
271
|
-
const $pack = shared_1.loadJsonSync('package.json');
|
|
294
|
+
const $pack = (0, shared_1.loadJsonSync)('package.json');
|
|
272
295
|
const name = ($pack && $pack.name) || 'LEMON API';
|
|
273
296
|
const version = ($pack && $pack.version) || '0.0.0';
|
|
274
297
|
const modules = [`${name}/${version}`];
|
|
@@ -296,7 +319,7 @@ class LambdaWEBHandler extends lambda_handler_1.LambdaSubHandler {
|
|
|
296
319
|
})(this._handlers[TYPE]);
|
|
297
320
|
//! if no next, then report error.
|
|
298
321
|
if (!next || typeof next != 'function') {
|
|
299
|
-
engine_1._err(NS, `! WARN ! MISSING NEXT-HANDLER. event=`, engine_1.$U.json(event));
|
|
322
|
+
(0, engine_1._err)(NS, `! WARN ! MISSING NEXT-HANDLER. event=`, engine_1.$U.json(event));
|
|
300
323
|
throw new Error(`404 NOT FOUND - ${MODE} /${TYPE}/${ID}${CMD ? `/${CMD}` : ''}`);
|
|
301
324
|
}
|
|
302
325
|
//! call next.. (it will return result or promised)
|
|
@@ -314,91 +337,279 @@ class LambdaWEBHandler extends lambda_handler_1.LambdaSubHandler {
|
|
|
314
337
|
/**
|
|
315
338
|
* pack the request context for Http request.
|
|
316
339
|
*
|
|
317
|
-
* @param event
|
|
318
|
-
* @param
|
|
340
|
+
* @param event origin Event.
|
|
341
|
+
* @param orgContext (optional) original lambda.Context
|
|
319
342
|
*/
|
|
320
|
-
packContext(event,
|
|
343
|
+
packContext(event, orgContext) {
|
|
321
344
|
return __awaiter(this, void 0, void 0, function* () {
|
|
322
|
-
|
|
323
|
-
const reqContext = event && event.requestContext;
|
|
345
|
+
(0, engine_1._log)(NS, `packContext(${event ? '' : 'null'})..`);
|
|
324
346
|
if (!event)
|
|
325
347
|
return null;
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
engine_1._log(NS, `> orgContext=`, engine_1.$U.S(
|
|
329
|
-
|
|
330
|
-
const res = { identity: null };
|
|
348
|
+
//! prepare chain object.
|
|
349
|
+
const reqContext = event === null || event === void 0 ? void 0 : event.requestContext;
|
|
350
|
+
orgContext && (0, engine_1._log)(NS, `> orgContext =`, engine_1.$U.S(orgContext, 256, 32));
|
|
351
|
+
reqContext && (0, engine_1._log)(NS, `> reqContext =`, engine_1.$U.S(reqContext, 256, 32));
|
|
331
352
|
// STEP.1 support lambda call JWT Token authentication.
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
353
|
+
const headers = event.headers;
|
|
354
|
+
if (headers && headers[protocol_service_1.HEADER_PROTOCOL_CONTEXT]) {
|
|
355
|
+
//! if it is protocol request via lambda, then returns valid context.
|
|
335
356
|
const $param = protocol_1.default.service.asTransformer('web').transformToParam(event);
|
|
336
|
-
return $param.context;
|
|
357
|
+
return $param === null || $param === void 0 ? void 0 : $param.context;
|
|
337
358
|
}
|
|
338
|
-
//
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
//
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
359
|
+
// STEP.2 use internal identity json data via python lambda call.
|
|
360
|
+
const $tool = this.tools(headers);
|
|
361
|
+
const identity = yield $tool.parseIdentityHeader();
|
|
362
|
+
const cookie = $tool.parseCookiesHeader();
|
|
363
|
+
// STEP.3. prepare the final `next-context`.
|
|
364
|
+
const $ctx = yield $tool.prepareContext({ identity, cookie }, reqContext);
|
|
365
|
+
$ctx.source = protocol_1.default.service.myProtocolURI($ctx); // self service-uri as source
|
|
366
|
+
// FINIAL. returns
|
|
367
|
+
return $ctx;
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
exports.LambdaWEBHandler = LambdaWEBHandler;
|
|
372
|
+
//! shared config.
|
|
373
|
+
LambdaWEBHandler.REPORT_ERROR = lambda_handler_1.LambdaHandler.REPORT_ERROR;
|
|
374
|
+
/**
|
|
375
|
+
* class: `MyHttpHeaderTool`
|
|
376
|
+
* - basic implementation of HttpHeaderTool
|
|
377
|
+
*/
|
|
378
|
+
class MyHttpHeaderTool {
|
|
379
|
+
/**
|
|
380
|
+
* default constructor.
|
|
381
|
+
* @param headers
|
|
382
|
+
*/
|
|
383
|
+
constructor(handler, headers) {
|
|
384
|
+
/**
|
|
385
|
+
* get values by name
|
|
386
|
+
* @param name case-insentive name of field
|
|
387
|
+
*/
|
|
388
|
+
this.getHeaders = (name) => Object.entries(this.headers).reduce((L, [key, val]) => {
|
|
389
|
+
if (name === key || key.toLowerCase() === name) {
|
|
390
|
+
if (Array.isArray(val)) {
|
|
391
|
+
val.forEach(val => {
|
|
392
|
+
if (typeof val === 'string') {
|
|
393
|
+
L.push(val.trim());
|
|
394
|
+
}
|
|
395
|
+
else {
|
|
396
|
+
(0, engine_1._err)(NS, `! invalid type @header[${name}] =`, typeof val, val);
|
|
397
|
+
}
|
|
398
|
+
});
|
|
350
399
|
}
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
400
|
+
else if (typeof val === 'string') {
|
|
401
|
+
L.push(val.trim());
|
|
402
|
+
}
|
|
403
|
+
else {
|
|
404
|
+
(0, engine_1._err)(NS, `! invalid type @header[${name}] =`, typeof val, val);
|
|
354
405
|
}
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
406
|
+
}
|
|
407
|
+
return L;
|
|
408
|
+
}, []);
|
|
409
|
+
/**
|
|
410
|
+
* get the last value in header by name
|
|
411
|
+
*/
|
|
412
|
+
this.getHeader = (name) => {
|
|
413
|
+
const vals = this.getHeaders(name);
|
|
414
|
+
return vals.length < 1 ? undefined : vals[vals.length - 1];
|
|
415
|
+
};
|
|
416
|
+
/**
|
|
417
|
+
* check if this request is from externals (like API-GW)
|
|
418
|
+
* @returns true if in external
|
|
419
|
+
*/
|
|
420
|
+
this.isExternal = () => {
|
|
421
|
+
const host = this.getHeader('host');
|
|
422
|
+
const isExternal = host ? true : false;
|
|
423
|
+
return !!isExternal;
|
|
424
|
+
};
|
|
425
|
+
/**
|
|
426
|
+
* parse of header[`x-lemon-identity`] to get the instance of `NextIdentity`
|
|
427
|
+
* - lambda 호출의 2가지 방법이 있음 (interval vs external)
|
|
428
|
+
* - internal는 AWS 같은 계정내 호출로 labmda 직접 호출이 가능함.
|
|
429
|
+
* - external는 API-GW를 통한 호출로 JWT 지원 (since 3.1.2).
|
|
430
|
+
*
|
|
431
|
+
* **[FOR INTERNAL CALL BY LAMBDA]**
|
|
432
|
+
* - `x-lemon-identity` 정보로부터, 계정 정보를 얻음 (for direct call via lambda)
|
|
433
|
+
* - 외부 호출과 구분하기 위해서 headr[host]가 비어 있어야함 (API-GW에서는 무조건 있으므로)
|
|
434
|
+
*
|
|
435
|
+
* **[FOR EXTERNAL CALL BY API-GW]**
|
|
436
|
+
* - support ONLY JWT Token authentication (verification).
|
|
437
|
+
* - iat
|
|
438
|
+
*/
|
|
439
|
+
this.parseIdentityHeader = (name = HEADER_LEMON_IDENTITY) => __awaiter(this, void 0, void 0, function* () {
|
|
440
|
+
var _a;
|
|
441
|
+
//! internal means `request from internal services`
|
|
442
|
+
const isInternal = !this.isExternal();
|
|
443
|
+
const val = this.getHeader(name);
|
|
444
|
+
let result = val ? { meta: val } : {};
|
|
445
|
+
try {
|
|
446
|
+
if (!val) {
|
|
447
|
+
//NOP
|
|
448
|
+
}
|
|
449
|
+
else if (isInternal && val.startsWith('{') && val.endsWith('}')) {
|
|
450
|
+
result = yield this.parseIdentityJson(val);
|
|
451
|
+
}
|
|
452
|
+
else if (typeof val === 'string' && val.split('.').length === 3) {
|
|
453
|
+
result = yield this.parseIdentityJWT(val);
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
catch (e) {
|
|
457
|
+
(0, engine_1._err)(NS, '!WARN! parse.err =', e);
|
|
458
|
+
(0, engine_1._err)(NS, '!WARN! identity =', val);
|
|
459
|
+
result.error = (0, test_helper_1.GETERR)(e);
|
|
460
|
+
}
|
|
461
|
+
//! overwrite finally language selection.
|
|
462
|
+
const lang = (_a = this.parseLanguageHeader()) !== null && _a !== void 0 ? _a : result === null || result === void 0 ? void 0 : result.lang;
|
|
463
|
+
return Object.assign(Object.assign({}, result), { lang });
|
|
464
|
+
});
|
|
465
|
+
/**
|
|
466
|
+
* parse as identity from json encoded text.
|
|
467
|
+
*/
|
|
468
|
+
this.parseIdentityJson = (val) => __awaiter(this, void 0, void 0, function* () {
|
|
469
|
+
if (typeof val !== 'string')
|
|
470
|
+
throw new Error(`@val[${val}] is invalid - not string!`);
|
|
471
|
+
//! (ONLY for internal) parse payload as `json`
|
|
472
|
+
const data = JSON.parse(val);
|
|
473
|
+
// if (typeof data?.ns !== 'string') throw new Error(`.ns[${data?.ns}] is required - IdentityHeader`);
|
|
474
|
+
if (typeof (data === null || data === void 0 ? void 0 : data.sid) !== 'string' || !(data === null || data === void 0 ? void 0 : data.sid))
|
|
475
|
+
throw new Error(`.sid[${data === null || data === void 0 ? void 0 : data.sid}] is required - IdentityHeader`);
|
|
476
|
+
return data;
|
|
477
|
+
});
|
|
478
|
+
/**
|
|
479
|
+
* encode as JWT string.
|
|
480
|
+
*/
|
|
481
|
+
this.encodeIdentityJWT = (identity, params) => __awaiter(this, void 0, void 0, function* () {
|
|
482
|
+
var _b;
|
|
483
|
+
// STEP.1 prepare payload data
|
|
484
|
+
const current = (_b = params === null || params === void 0 ? void 0 : params.current) !== null && _b !== void 0 ? _b : engine_1.$U.current_time_ms();
|
|
485
|
+
const alias = params === null || params === void 0 ? void 0 : params.alias;
|
|
486
|
+
const payload = Object.assign(Object.assign({}, identity), { iss: alias ? `kms/${alias}` : null, iat: Math.floor(current / 1000), exp: Math.floor(current / 1000) + 24 * 60 * 60 });
|
|
487
|
+
const base64url = (t) => (0, aws_kms_service_1.fromBase64)(Buffer.from(t).toString('base64'));
|
|
488
|
+
const data = {
|
|
489
|
+
header: base64url(JSON.stringify({
|
|
490
|
+
alg: 'RS256',
|
|
491
|
+
typ: 'JWT',
|
|
492
|
+
})),
|
|
493
|
+
payload: base64url(JSON.stringify(payload)),
|
|
494
|
+
};
|
|
495
|
+
// STEP.2 encode and calc signature.
|
|
496
|
+
const message = [data.header, data.payload].join('.');
|
|
497
|
+
const $kms = alias ? this.findKMSService(`alias/${alias}`) : null;
|
|
498
|
+
const signature = $kms ? yield $kms.sign(message, true) : '';
|
|
499
|
+
const token = [message, signature].join('.');
|
|
500
|
+
return { signature, message, token };
|
|
501
|
+
});
|
|
502
|
+
/**
|
|
503
|
+
* parse as jwt-token, and validate the signature.
|
|
504
|
+
*/
|
|
505
|
+
this.parseIdentityJWT = (token, params) => __awaiter(this, void 0, void 0, function* () {
|
|
506
|
+
var _c;
|
|
507
|
+
//! it must be JWT Token. verify signature, and load.
|
|
508
|
+
if (typeof token !== 'string' || !token)
|
|
509
|
+
throw new Error(`@token (string) is required - but ${typeof token}`);
|
|
510
|
+
// STEP.1 decode jwt, and extract { iss, iat, exp }
|
|
511
|
+
const current = (_c = params === null || params === void 0 ? void 0 : params.current) !== null && _c !== void 0 ? _c : engine_1.$U.current_time_ms();
|
|
512
|
+
const sections = token.split('.');
|
|
513
|
+
if (sections.length !== 3)
|
|
514
|
+
throw new Error(`@token[${token}] is invalid format!`);
|
|
515
|
+
const [header, payload, signature] = sections;
|
|
516
|
+
const $jwt = engine_1.$U.jwt();
|
|
517
|
+
const data = $jwt.decode(token, { complete: false, json: true });
|
|
518
|
+
if (!data)
|
|
519
|
+
throw new Error(`@token[${token}] is invalid - failed to decode!`);
|
|
520
|
+
const { iss, iat, exp } = data;
|
|
521
|
+
// STEP.1-1 validate parameters.
|
|
522
|
+
if (typeof iss !== 'string' && iss !== null)
|
|
523
|
+
throw new Error(`.iss (string) is required!`);
|
|
524
|
+
if (typeof iat !== 'number' && iat !== null)
|
|
525
|
+
throw new Error(`.iat (number) is required!`);
|
|
526
|
+
if (typeof exp !== 'number' && exp !== null)
|
|
527
|
+
throw new Error(`.exp (number) is required!`);
|
|
528
|
+
// STEP.2 validate signature by KMS(iss).verify()
|
|
529
|
+
if (typeof iss === 'string' && iss.startsWith('kms/')) {
|
|
530
|
+
const alias = iss.substring(4);
|
|
531
|
+
const $kms = alias ? this.findKMSService(`alias/${alias}`) : null;
|
|
532
|
+
const verified = $kms ? yield $kms.verify([header, payload].join('.'), signature) : false;
|
|
533
|
+
if (!verified)
|
|
534
|
+
throw new Error(`@signature[] is invalid - not be verified!`);
|
|
535
|
+
if (!exp || exp * 1000 < current)
|
|
536
|
+
throw new Error(`.exp[${engine_1.$U.ts(exp * 1000)}] is invalid - expired!`);
|
|
537
|
+
return data;
|
|
538
|
+
}
|
|
539
|
+
//! or throw
|
|
540
|
+
throw new Error(`@iss[${iss}] is invalid - unsupportable issuer!`);
|
|
541
|
+
});
|
|
542
|
+
/**
|
|
543
|
+
* parse of header[HEADER_LEMON_LANGUAGE] to get language-type.
|
|
544
|
+
*/
|
|
545
|
+
this.parseLanguageHeader = (name = HEADER_LEMON_LANGUAGE) => {
|
|
546
|
+
const val = this.getHeader(name);
|
|
547
|
+
return typeof val === 'string' ? val.trim().toLowerCase() : undefined;
|
|
548
|
+
};
|
|
549
|
+
/**
|
|
550
|
+
* parse of header[HEADER_LEMON_LANGUAGE] to get cookie-set.
|
|
551
|
+
*/
|
|
552
|
+
this.parseCookiesHeader = (name = HEADER_COOKIE) => {
|
|
553
|
+
const cookie = this.getHeader(name);
|
|
554
|
+
if (!cookie)
|
|
555
|
+
return undefined;
|
|
556
|
+
const parseCookies = (str) => {
|
|
557
|
+
const rx = /([^;=\s]*)=([^;]*)/g;
|
|
558
|
+
const obj = {};
|
|
559
|
+
for (let m; (m = rx.exec(str));)
|
|
560
|
+
obj[m[1]] = decodeURIComponent(m[2]);
|
|
561
|
+
return obj;
|
|
562
|
+
};
|
|
563
|
+
return parseCookies(cookie);
|
|
564
|
+
};
|
|
565
|
+
/**
|
|
566
|
+
* override with AWS request-context
|
|
567
|
+
*/
|
|
568
|
+
this.prepareContext = ($org, reqContext) => __awaiter(this, void 0, void 0, function* () {
|
|
569
|
+
var _d, _e, _f, _g;
|
|
570
|
+
// STEP.4 override w/ cognito authentication to NextIdentity.
|
|
571
|
+
if (((_d = reqContext === null || reqContext === void 0 ? void 0 : reqContext.identity) === null || _d === void 0 ? void 0 : _d.cognitoIdentityPoolId) !== undefined) {
|
|
572
|
+
const identity = $org.identity;
|
|
573
|
+
if (!identity)
|
|
574
|
+
throw new Error(`.identity is required - prepareContext()`);
|
|
379
575
|
const $id = reqContext.identity;
|
|
380
|
-
engine_1._inf(NS, '! identity :=', engine_1.$U.json(
|
|
381
|
-
identity.identityProvider = $id.cognitoAuthenticationProvider;
|
|
576
|
+
(0, engine_1._inf)(NS, '! identity(req) :=', engine_1.$U.json(Object.assign({}, $id)));
|
|
577
|
+
identity.identityProvider = $id.cognitoAuthenticationProvider; // provider string.
|
|
382
578
|
identity.identityPoolId = $id.cognitoIdentityPoolId; // identity-pool-id like 'ap-northeast-2:618ce9d2-3ad6-49df-b3b3-e248ea51425e'
|
|
383
579
|
identity.identityId = $id.cognitoIdentityId; // identity-id like 'ap-northeast-2:dbd95fb4-7423-48b8-8a04-56e5bc95e444'
|
|
384
580
|
identity.accountId = $id.accountId; // account-id should be same as context.accountId
|
|
385
581
|
identity.userAgent = $id.userAgent; // user-agent string.
|
|
386
|
-
|
|
582
|
+
identity.caller = (_e = $id.caller) !== null && _e !== void 0 ? _e : undefined; // caller string.
|
|
583
|
+
(0, engine_1._inf)(NS, '! identity(new) :=', engine_1.$U.json(Object.assign({}, identity)));
|
|
387
584
|
}
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
const
|
|
391
|
-
const
|
|
392
|
-
const
|
|
393
|
-
const
|
|
585
|
+
//TODO - transform to access identity via `lemon-accounts-api` service @200106
|
|
586
|
+
// STEP.5 extract additional request infor from req-context.
|
|
587
|
+
const clientIp = `${((_f = reqContext === null || reqContext === void 0 ? void 0 : reqContext.identity) === null || _f === void 0 ? void 0 : _f.sourceIp) || ''}`;
|
|
588
|
+
const userAgent = `${((_g = reqContext === null || reqContext === void 0 ? void 0 : reqContext.identity) === null || _g === void 0 ? void 0 : _g.userAgent) || ''}`;
|
|
589
|
+
const requestId = `${(reqContext === null || reqContext === void 0 ? void 0 : reqContext.requestId) || ''}`;
|
|
590
|
+
const accountId = `${(reqContext === null || reqContext === void 0 ? void 0 : reqContext.accountId) || ''}`;
|
|
591
|
+
const domain = `${(reqContext === null || reqContext === void 0 ? void 0 : reqContext.domainName) || this.getHeader('host') || ''}`; //! chore avoid null of headers
|
|
394
592
|
//! save into headers and returns.
|
|
395
|
-
const context = Object.assign(Object.assign({},
|
|
396
|
-
context.source = protocol_1.default.service.myProtocolURI(context); // self service-uri as source
|
|
593
|
+
const context = Object.assign(Object.assign({}, $org), { userAgent, clientIp, requestId, accountId, domain });
|
|
397
594
|
return context;
|
|
398
595
|
});
|
|
596
|
+
this.handler = handler;
|
|
597
|
+
this.headers = Object.assign({}, headers);
|
|
598
|
+
}
|
|
599
|
+
hello() {
|
|
600
|
+
return 'header-tool-by-default';
|
|
601
|
+
}
|
|
602
|
+
/**
|
|
603
|
+
* find(or make) the proper KMSService per key
|
|
604
|
+
* @param keyId key of KMS
|
|
605
|
+
* @returns service
|
|
606
|
+
*/
|
|
607
|
+
findKMSService(keyId) {
|
|
608
|
+
// const aws = $engine.module('aws') as AWSModule;
|
|
609
|
+
// return aws?.kms;
|
|
610
|
+
const kms = new aws_kms_service_1.AWSKMSService(keyId);
|
|
611
|
+
return kms;
|
|
399
612
|
}
|
|
400
613
|
}
|
|
401
|
-
exports.
|
|
402
|
-
//! shared config.
|
|
403
|
-
LambdaWEBHandler.REPORT_ERROR = lambda_handler_1.LambdaHandler.REPORT_ERROR;
|
|
614
|
+
exports.MyHttpHeaderTool = MyHttpHeaderTool;
|
|
404
615
|
//# sourceMappingURL=lambda-web-handler.js.map
|