lesgo 0.7.7 → 1.0.0
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 +1 -1
- package/bin/lesgo-scripts.sh +52 -7
- package/package.json +2 -2
- package/src/middlewares/__tests__/basicAuthMiddleware.spec.js +264 -0
- package/src/middlewares/__tests__/clientAuthMiddleware.spec.js +235 -0
- package/src/middlewares/__tests__/errorHttpResponseMiddleware.spec.js +43 -0
- package/src/middlewares/__tests__/gzipHttpResponse.spec.js +1 -1
- package/src/middlewares/__tests__/httpNoOutputMiddleware.spec.js +201 -0
- package/src/middlewares/__tests__/normalizeSQSMessageMiddleware.spec.js +18 -0
- package/src/middlewares/__tests__/successHttpResponseMiddleware.spec.js +13 -0
- package/src/middlewares/__tests__/verifyJwtMiddleware.spec.js +187 -64
- package/src/middlewares/basicAuthMiddleware.js +125 -0
- package/src/middlewares/clientAuthMiddleware.js +103 -0
- package/src/middlewares/errorHttpResponseMiddleware.js +3 -1
- package/src/middlewares/httpNoOutputMiddleware.js +91 -0
- package/src/middlewares/index.js +4 -0
- package/src/middlewares/normalizeSQSMessageMiddleware.js +5 -3
- package/src/middlewares/successHttpResponseMiddleware.js +7 -5
- package/src/middlewares/verifyJwtMiddleware.js +23 -7
- package/src/services/LoggerService.js +10 -3
- package/src/services/__tests__/LoggerService.spec.js +17 -2
- package/src/utils/__tests__/validateFields.spec.js +223 -32
- package/src/utils/validateFields.js +85 -44
- package/CHANGELOG.md +0 -9
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Lesgo!
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+

|
|
4
4
|
[](https://coveralls.io/github/reflex-media/lesgo-framework?branch=master)
|
|
5
5
|
|
|
6
6
|
Bootstrap your next microservice with a lightweight node.js serverless framework.
|
package/bin/lesgo-scripts.sh
CHANGED
|
@@ -93,6 +93,21 @@ NC='\033[0m';
|
|
|
93
93
|
# FUNCTION DECLARATIONS #
|
|
94
94
|
# #
|
|
95
95
|
###############################################################################
|
|
96
|
+
LOCAL_SERVERLESS_VERSION=`npm ls --depth=0 serverless | grep -o "serverless@.*" || true`
|
|
97
|
+
GLOBAL_SERVERLESS_VERSION=`npm ls -g --depth=0 serverless | grep -o "serverless@.*" || true`
|
|
98
|
+
LATEST_SERVERLESS_VERSION_NUMBER=3
|
|
99
|
+
|
|
100
|
+
if [ -z "$LOCAL_SERVERLESS_VERSION" ]
|
|
101
|
+
then
|
|
102
|
+
CURRENT_SERVERLESS_VERSION=$GLOBAL_SERVERLESS_VERSION
|
|
103
|
+
else
|
|
104
|
+
CURRENT_SERVERLESS_VERSION=$LOCAL_SERVERLESS_VERSION
|
|
105
|
+
fi
|
|
106
|
+
SERVERLESS_VERSION=${CURRENT_SERVERLESS_VERSION#*@}
|
|
107
|
+
SERVERLESS_VERSION_NUMBER=${SERVERLESS_VERSION%%.*}
|
|
108
|
+
|
|
109
|
+
echo -e "Running Serverless version:\n${CURRENT_SERVERLESS_VERSION}\n"
|
|
110
|
+
echo -e "Current Serverless version: ${SERVERLESS_VERSION_NUMBER}\n"
|
|
96
111
|
|
|
97
112
|
function deploy_func_check ()
|
|
98
113
|
{
|
|
@@ -106,7 +121,12 @@ function deploy_func_check ()
|
|
|
106
121
|
function deploy_func ()
|
|
107
122
|
{
|
|
108
123
|
echo -e "${YELLOW}Deploying ${FUNCTION} to ${STAGE}${NC} using ${CONFIG}"
|
|
109
|
-
|
|
124
|
+
|
|
125
|
+
if [ ${SERVERLESS_VERSION_NUMBER} -ge ${LATEST_SERVERLESS_VERSION_NUMBER} ]; then
|
|
126
|
+
sls deploy function -f ${FUNCTION} --stage ${STAGE} --param="env=${ENVFILE}" --config ${CONFIG}
|
|
127
|
+
else
|
|
128
|
+
sls deploy -f ${FUNCTION} --stage ${STAGE} --env ${ENVFILE} --config ${CONFIG}
|
|
129
|
+
fi
|
|
110
130
|
}
|
|
111
131
|
|
|
112
132
|
function prompt_confirmation_deploy_all ()
|
|
@@ -140,29 +160,50 @@ function prompt_confirmation_deploy_function ()
|
|
|
140
160
|
function deploy_full ()
|
|
141
161
|
{
|
|
142
162
|
echo -e "${YELLOW}Deploying service to ${STAGE}${NC}"
|
|
143
|
-
|
|
163
|
+
if [ ${SERVERLESS_VERSION_NUMBER} -ge ${LATEST_SERVERLESS_VERSION_NUMBER} ]; then
|
|
164
|
+
sls deploy --stage ${STAGE} --param="env=${ENVFILE}" --config ${CONFIG}
|
|
165
|
+
else
|
|
166
|
+
sls deploy --stage ${STAGE} --env ${ENVFILE} --config ${CONFIG}
|
|
167
|
+
fi
|
|
144
168
|
}
|
|
145
169
|
|
|
146
170
|
function invoke_func ()
|
|
147
171
|
{
|
|
148
172
|
echo -e "${YELLOW}Invoking function ${FUNCTION} on ${STAGE}${NC} using ${CONFIG}"
|
|
149
173
|
if [ ${INVOKE_LOCAL} == 1 ]; then
|
|
150
|
-
|
|
174
|
+
if [ ${SERVERLESS_VERSION_NUMBER} -ge ${LATEST_SERVERLESS_VERSION_NUMBER} ]; then
|
|
175
|
+
sls invoke local function -f ${FUNCTION} --stage ${STAGE} --param="env=${ENVFILE}" -d ${DATA} -l --config ${CONFIG}
|
|
176
|
+
else
|
|
177
|
+
sls invoke local -f ${FUNCTION} --stage ${STAGE} --env ${ENVFILE} -d ${DATA} -l --config ${CONFIG}
|
|
178
|
+
fi
|
|
179
|
+
|
|
151
180
|
else
|
|
152
|
-
|
|
181
|
+
if [ ${SERVERLESS_VERSION_NUMBER} -ge ${LATEST_SERVERLESS_VERSION_NUMBER} ]; then
|
|
182
|
+
sls invoke function -f ${FUNCTION} --stage ${STAGE} --param="env=${ENVFILE}" -d ${DATA} -l --config ${CONFIG}
|
|
183
|
+
else
|
|
184
|
+
sls invoke -f ${FUNCTION} --stage ${STAGE} --env ${ENVFILE} -d ${DATA} -l --config ${CONFIG}
|
|
185
|
+
fi
|
|
153
186
|
fi
|
|
154
187
|
}
|
|
155
188
|
|
|
156
189
|
function log_stream_func ()
|
|
157
190
|
{
|
|
158
191
|
echo -e "${YELLOW}Log Streaming function ${FUNCTION} on ${STAGE}${NC} using ${CONFIG}"
|
|
159
|
-
|
|
192
|
+
if [ ${SERVERLESS_VERSION_NUMBER} -ge ${LATEST_SERVERLESS_VERSION_NUMBER} ]; then
|
|
193
|
+
sls logs function -f ${FUNCTION} --stage ${STAGE} --param="env=${ENVFILE}" -t --config ${CONFIG}
|
|
194
|
+
else
|
|
195
|
+
sls logs -f ${FUNCTION} --stage ${STAGE} --env ${ENVFILE} -t --config ${CONFIG}
|
|
196
|
+
fi
|
|
160
197
|
}
|
|
161
198
|
|
|
162
199
|
function build ()
|
|
163
200
|
{
|
|
164
201
|
echo -e "${YELLOW}Building bundle without deployment${NC} using ${CONFIG}"
|
|
165
|
-
|
|
202
|
+
if [ ${SERVERLESS_VERSION_NUMBER} -ge ${LATEST_SERVERLESS_VERSION_NUMBER} ]; then
|
|
203
|
+
sls webpack --stage ${STAGE} --param="env=${ENVFILE}" --config ${CONFIG}
|
|
204
|
+
else
|
|
205
|
+
sls webpack --stage ${STAGE} --env ${ENVFILE} --config ${CONFIG}
|
|
206
|
+
fi
|
|
166
207
|
}
|
|
167
208
|
|
|
168
209
|
function prompt_confirmation_destroy_service ()
|
|
@@ -180,7 +221,11 @@ function prompt_confirmation_destroy_service ()
|
|
|
180
221
|
function destroy_service ()
|
|
181
222
|
{
|
|
182
223
|
echo -e "${YELLOW}Removing service to ${STAGE}${NC}"
|
|
183
|
-
|
|
224
|
+
if [ ${SERVERLESS_VERSION_NUMBER} -ge ${LATEST_SERVERLESS_VERSION_NUMBER} ]; then
|
|
225
|
+
sls remove --stage ${STAGE} --param="env=${ENVFILE}" --config ${CONFIG}
|
|
226
|
+
else
|
|
227
|
+
sls remove --stage ${STAGE} --env ${ENVFILE} --config ${CONFIG}
|
|
228
|
+
fi
|
|
184
229
|
}
|
|
185
230
|
|
|
186
231
|
###############################################################################
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lesgo",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "Core framework for lesgo node.js serverless framework.",
|
|
5
5
|
"main": "./src/index.js",
|
|
6
6
|
"author": "Sufiyan Rahmat",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"lesgo-scripts": "./bin/lesgo-scripts.sh"
|
|
31
31
|
},
|
|
32
32
|
"engines": {
|
|
33
|
-
"node": "12.
|
|
33
|
+
"node": ">=12.0.0"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@babel/cli": "^7.17.6",
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
import basicAuthMiddleware, {
|
|
2
|
+
generateBasicAuthorizationHash,
|
|
3
|
+
verifyBasicAuthBeforeHandler,
|
|
4
|
+
} from '../basicAuthMiddleware';
|
|
5
|
+
import client from '../../../tests/__mocks__/config/client';
|
|
6
|
+
|
|
7
|
+
describe('test generateBasicAuthorizationHash', () => {
|
|
8
|
+
test('should return custom when overriden through opts', () => {
|
|
9
|
+
expect(
|
|
10
|
+
generateBasicAuthorizationHash(
|
|
11
|
+
'e5bb52b012ad4a4e9d862a3410e7013d',
|
|
12
|
+
'4cd19af8f7ca4448bcb2c427754095b5',
|
|
13
|
+
{
|
|
14
|
+
getPreHashString: key => {
|
|
15
|
+
return `=${key}=`;
|
|
16
|
+
},
|
|
17
|
+
}
|
|
18
|
+
)
|
|
19
|
+
).toBe('PWU1YmI1MmIwMTJhZDRhNGU5ZDg2MmEzNDEwZTcwMTNkPQ==');
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
test('should return basic auth by default', () => {
|
|
23
|
+
const { getPreHashString } = client;
|
|
24
|
+
client.getPreHashString = null;
|
|
25
|
+
|
|
26
|
+
expect(
|
|
27
|
+
generateBasicAuthorizationHash(
|
|
28
|
+
'e5bb52b012ad4a4e9d862a3410e7013d',
|
|
29
|
+
'4cd19af8f7ca4448bcb2c427754095b5'
|
|
30
|
+
)
|
|
31
|
+
).toBe(
|
|
32
|
+
'ZTViYjUyYjAxMmFkNGE0ZTlkODYyYTM0MTBlNzAxM2Q6NGNkMTlhZjhmN2NhNDQ0OGJjYjJjNDI3NzU0MDk1YjU='
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
client.getPreHashString = getPreHashString;
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
describe('test basicAuthMiddleware middleware', () => {
|
|
40
|
+
test.each`
|
|
41
|
+
clientObj
|
|
42
|
+
${undefined}
|
|
43
|
+
${{}}
|
|
44
|
+
${{
|
|
45
|
+
default: {
|
|
46
|
+
key: '1111-1111-1111-1111',
|
|
47
|
+
secret: '1111-1111-1111-1111',
|
|
48
|
+
},
|
|
49
|
+
}}
|
|
50
|
+
`('should return object', ({ clientObj }) => {
|
|
51
|
+
const result = basicAuthMiddleware({
|
|
52
|
+
client: clientObj,
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
expect(result).toHaveProperty('before');
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// eslint-disable-next-line
|
|
60
|
+
const next = () => {};
|
|
61
|
+
|
|
62
|
+
describe('test verifyBasicAuthBeforeHandler error handling', () => {
|
|
63
|
+
const invalidClientKey = Buffer.from('client_key:secret_key').toString(
|
|
64
|
+
'base64'
|
|
65
|
+
);
|
|
66
|
+
const invalidSecretKey = Buffer.from(
|
|
67
|
+
`${client.clients.platform_2.key}:secret_key`
|
|
68
|
+
).toString('base64');
|
|
69
|
+
|
|
70
|
+
test.each`
|
|
71
|
+
headers | errorName | errorMessage | errorStatusCode | errorCode | platform
|
|
72
|
+
${{}} | ${'LesgoException'} | ${'Authorization header not found'} | ${403} | ${'Middlewares/basicAuthMiddleware::AUTHORIZATION_HEADER_NOT_FOUND'} | ${undefined}
|
|
73
|
+
${{ Authorization: 'auth' }} | ${'LesgoException'} | ${'Invalid authorization type provided'} | ${403} | ${'Middlewares/basicAuthMiddleware::AUTH_INVALID_AUTHORIZATION_TYPE'} | ${undefined}
|
|
74
|
+
${{ Authorization: 'basic ' }} | ${'LesgoException'} | ${'Empty basic authentication hash provided'} | ${403} | ${'Middlewares/basicAuthMiddleware::AUTH_EMPTY_BASIC_HASH'} | ${undefined}
|
|
75
|
+
${{ Authorization: `basic ${invalidClientKey}` }} | ${'LesgoException'} | ${'Invalid client key or secret provided'} | ${403} | ${'Middlewares/basicAuthMiddleware::AUTH_INVALID_CLIENT_OR_SECRET_KEY'} | ${undefined}
|
|
76
|
+
${{ Authorization: `basic ${invalidSecretKey}` }} | ${'LesgoException'} | ${'Invalid client key or secret provided'} | ${403} | ${'Middlewares/basicAuthMiddleware::AUTH_INVALID_CLIENT_OR_SECRET_KEY'} | ${undefined}
|
|
77
|
+
${{ Authorization: `Basic ${invalidSecretKey}` }} | ${'LesgoException'} | ${'Invalid client key or secret provided'} | ${403} | ${'Middlewares/basicAuthMiddleware::AUTH_INVALID_CLIENT_OR_SECRET_KEY'} | ${undefined}
|
|
78
|
+
${{}} | ${'LesgoException'} | ${'Authorization header not found'} | ${403} | ${'Middlewares/basicAuthMiddleware::AUTHORIZATION_HEADER_NOT_FOUND'} | ${'platform_1'}
|
|
79
|
+
${{ Authorization: 'auth' }} | ${'LesgoException'} | ${'Invalid authorization type provided'} | ${403} | ${'Middlewares/basicAuthMiddleware::AUTH_INVALID_AUTHORIZATION_TYPE'} | ${'platform_1'}
|
|
80
|
+
${{ Authorization: 'basic ' }} | ${'LesgoException'} | ${'Empty basic authentication hash provided'} | ${403} | ${'Middlewares/basicAuthMiddleware::AUTH_EMPTY_BASIC_HASH'} | ${'platform_1'}
|
|
81
|
+
${{ Authorization: `basic ${invalidClientKey}` }} | ${'LesgoException'} | ${'Invalid client key or secret provided'} | ${403} | ${'Middlewares/basicAuthMiddleware::AUTH_INVALID_CLIENT_OR_SECRET_KEY'} | ${'platform_1'}
|
|
82
|
+
${{ Authorization: `basic ${invalidSecretKey}` }} | ${'LesgoException'} | ${'Invalid client key or secret provided'} | ${403} | ${'Middlewares/basicAuthMiddleware::AUTH_INVALID_CLIENT_OR_SECRET_KEY'} | ${'platform_1'}
|
|
83
|
+
${{ Authorization: `Basic ${invalidSecretKey}` }} | ${'LesgoException'} | ${'Invalid client key or secret provided'} | ${403} | ${'Middlewares/basicAuthMiddleware::AUTH_INVALID_CLIENT_OR_SECRET_KEY'} | ${'platform_1'}
|
|
84
|
+
${{ Authorization: 'auth' }} | ${'LesgoException'} | ${'Invalid authorization type provided'} | ${403} | ${'Middlewares/basicAuthMiddleware::AUTH_INVALID_AUTHORIZATION_TYPE'} | ${'blacklist_platform'}
|
|
85
|
+
${{ Authorization: 'basic ' }} | ${'LesgoException'} | ${'Empty basic authentication hash provided'} | ${403} | ${'Middlewares/basicAuthMiddleware::AUTH_EMPTY_BASIC_HASH'} | ${'blacklist_platform'}
|
|
86
|
+
${{ Authorization: `basic ${invalidClientKey}` }} | ${'LesgoException'} | ${'Invalid client key or secret provided'} | ${403} | ${'Middlewares/basicAuthMiddleware::AUTH_INVALID_CLIENT_OR_SECRET_KEY'} | ${'blacklist_platform'}
|
|
87
|
+
${{ Authorization: `basic ${invalidSecretKey}` }} | ${'LesgoException'} | ${'Invalid client key or secret provided'} | ${403} | ${'Middlewares/basicAuthMiddleware::AUTH_INVALID_CLIENT_OR_SECRET_KEY'} | ${'blacklist_platform'}
|
|
88
|
+
${{ Authorization: `Basic ${invalidSecretKey}` }} | ${'LesgoException'} | ${'Invalid client key or secret provided'} | ${403} | ${'Middlewares/basicAuthMiddleware::AUTH_INVALID_CLIENT_OR_SECRET_KEY'} | ${'blacklist_platform'}
|
|
89
|
+
${{ Authorization: 'auth' }} | ${'LesgoException'} | ${'Invalid authorization type provided'} | ${403} | ${'Middlewares/basicAuthMiddleware::AUTH_INVALID_AUTHORIZATION_TYPE'} | ${'blacklist_platform_1'}
|
|
90
|
+
${{ Authorization: 'basic ' }} | ${'LesgoException'} | ${'Empty basic authentication hash provided'} | ${403} | ${'Middlewares/basicAuthMiddleware::AUTH_EMPTY_BASIC_HASH'} | ${'blacklist_platform_1'}
|
|
91
|
+
${{ Authorization: `basic ${invalidClientKey}` }} | ${'LesgoException'} | ${'Invalid client key or secret provided'} | ${403} | ${'Middlewares/basicAuthMiddleware::AUTH_INVALID_CLIENT_OR_SECRET_KEY'} | ${'blacklist_platform_1'}
|
|
92
|
+
${{ Authorization: `basic ${invalidSecretKey}` }} | ${'LesgoException'} | ${'Invalid client key or secret provided'} | ${403} | ${'Middlewares/basicAuthMiddleware::AUTH_INVALID_CLIENT_OR_SECRET_KEY'} | ${'blacklist_platform_1'}
|
|
93
|
+
${{ Authorization: `Basic ${invalidSecretKey}` }} | ${'LesgoException'} | ${'Invalid client key or secret provided'} | ${403} | ${'Middlewares/basicAuthMiddleware::AUTH_INVALID_CLIENT_OR_SECRET_KEY'} | ${'blacklist_platform_1'}
|
|
94
|
+
`(
|
|
95
|
+
'should throw $errorMessage when authorization header is $headers',
|
|
96
|
+
async ({
|
|
97
|
+
headers,
|
|
98
|
+
errorName,
|
|
99
|
+
errorMessage,
|
|
100
|
+
errorStatusCode,
|
|
101
|
+
errorCode,
|
|
102
|
+
platform,
|
|
103
|
+
}) => {
|
|
104
|
+
const handler = {
|
|
105
|
+
event: {
|
|
106
|
+
headers,
|
|
107
|
+
platform: {
|
|
108
|
+
id: platform,
|
|
109
|
+
...client.clients[platform],
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
try {
|
|
115
|
+
expect(await verifyBasicAuthBeforeHandler(handler, next)).toThrow();
|
|
116
|
+
} catch (error) {
|
|
117
|
+
expect(error.name).toBe(errorName);
|
|
118
|
+
expect(error.message).toBe(errorMessage);
|
|
119
|
+
expect(error.statusCode).toBe(errorStatusCode);
|
|
120
|
+
expect(error.code).toBe(errorCode);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
describe('test verifyBasicAuthBeforeHandler with valid credentials', () => {
|
|
127
|
+
const validBasicAuth = generateBasicAuthorizationHash(
|
|
128
|
+
client.clients.platform_2.key,
|
|
129
|
+
client.clients.platform_2.secret
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
test.each`
|
|
133
|
+
clientObj
|
|
134
|
+
${undefined}
|
|
135
|
+
${{}}
|
|
136
|
+
${{
|
|
137
|
+
platform_2: {
|
|
138
|
+
key: '2222-2222-2222-2222',
|
|
139
|
+
secret: '2222-2222-2222-2222',
|
|
140
|
+
},
|
|
141
|
+
}}
|
|
142
|
+
`('should return undefined when successful', async ({ clientObj }) => {
|
|
143
|
+
const handler = {
|
|
144
|
+
event: {
|
|
145
|
+
headers: {
|
|
146
|
+
Authorization: `basic ${validBasicAuth}`,
|
|
147
|
+
},
|
|
148
|
+
site: {
|
|
149
|
+
id: 'platform_2',
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
let hasError = false;
|
|
155
|
+
|
|
156
|
+
try {
|
|
157
|
+
await verifyBasicAuthBeforeHandler(handler, next, {
|
|
158
|
+
client: clientObj,
|
|
159
|
+
});
|
|
160
|
+
} catch (e) {
|
|
161
|
+
hasError = true;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
expect(hasError).toBeFalsy();
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
test.each`
|
|
168
|
+
clientObj
|
|
169
|
+
${undefined}
|
|
170
|
+
${{}}
|
|
171
|
+
${{
|
|
172
|
+
platform_2: {
|
|
173
|
+
key: '2222-2222-2222-2222',
|
|
174
|
+
secret: '2222-2222-2222-2222',
|
|
175
|
+
},
|
|
176
|
+
}}
|
|
177
|
+
`('should return undefined when successful', async ({ clientObj }) => {
|
|
178
|
+
const handler = {
|
|
179
|
+
event: {
|
|
180
|
+
headers: {
|
|
181
|
+
Authorization: `basic ${validBasicAuth}`,
|
|
182
|
+
},
|
|
183
|
+
site: {
|
|
184
|
+
id: 'platform_2',
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
let hasError = false;
|
|
190
|
+
|
|
191
|
+
try {
|
|
192
|
+
await verifyBasicAuthBeforeHandler(handler, next, {
|
|
193
|
+
client: clientObj,
|
|
194
|
+
});
|
|
195
|
+
} catch (e) {
|
|
196
|
+
hasError = true;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
expect(hasError).toBeFalsy();
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
test.each`
|
|
203
|
+
Authorization | platform
|
|
204
|
+
${undefined} | ${'blacklist_platform'}
|
|
205
|
+
${undefined} | ${'blacklist_platform_1'}
|
|
206
|
+
${`basic ${validBasicAuth}`} | ${'platform_2'}
|
|
207
|
+
${`Basic ${validBasicAuth}`} | ${'platform_2'}
|
|
208
|
+
${`basic ${validBasicAuth}`} | ${'platform_2'}
|
|
209
|
+
${`Basic ${validBasicAuth}`} | ${'platform_2'}
|
|
210
|
+
`(
|
|
211
|
+
'test Exception with valid credentials',
|
|
212
|
+
async ({ Authorization, platform }) => {
|
|
213
|
+
const handler = {
|
|
214
|
+
event: {
|
|
215
|
+
headers: {
|
|
216
|
+
Authorization,
|
|
217
|
+
},
|
|
218
|
+
platform: {
|
|
219
|
+
id: platform,
|
|
220
|
+
...client.clients[platform],
|
|
221
|
+
},
|
|
222
|
+
},
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
let hasError = false;
|
|
226
|
+
|
|
227
|
+
try {
|
|
228
|
+
await verifyBasicAuthBeforeHandler(handler, next);
|
|
229
|
+
} catch (e) {
|
|
230
|
+
hasError = true;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
expect(hasError).toBeFalsy();
|
|
234
|
+
}
|
|
235
|
+
);
|
|
236
|
+
|
|
237
|
+
test.each`
|
|
238
|
+
siteObjects
|
|
239
|
+
${{ platform: {
|
|
240
|
+
id: 'platform_2',
|
|
241
|
+
...client.clients.platform_2,
|
|
242
|
+
} }}
|
|
243
|
+
${{}}
|
|
244
|
+
`('valid site ids', async ({ siteObjects }) => {
|
|
245
|
+
const handler = {
|
|
246
|
+
event: {
|
|
247
|
+
headers: {
|
|
248
|
+
Authorization: `basic ${validBasicAuth}`,
|
|
249
|
+
},
|
|
250
|
+
...siteObjects,
|
|
251
|
+
},
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
let hasError = false;
|
|
255
|
+
|
|
256
|
+
try {
|
|
257
|
+
await verifyBasicAuthBeforeHandler(handler, next);
|
|
258
|
+
} catch (e) {
|
|
259
|
+
hasError = true;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
expect(hasError).toBeFalsy();
|
|
263
|
+
});
|
|
264
|
+
});
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import clientAuthMiddleware, {
|
|
2
|
+
clientAuthMiddlewareBeforeHandler,
|
|
3
|
+
} from '../clientAuthMiddleware';
|
|
4
|
+
|
|
5
|
+
describe('test authMiddleware', () => {
|
|
6
|
+
test('should return object', async () => {
|
|
7
|
+
// eslint-disable-next-line no-unused-vars
|
|
8
|
+
const result = clientAuthMiddleware();
|
|
9
|
+
expect(result).toHaveProperty('before');
|
|
10
|
+
});
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
const next = () => {};
|
|
14
|
+
|
|
15
|
+
describe('test clientMiddlewareBeforeHandler', () => {
|
|
16
|
+
test('should throw LesgoException when invalid api key is provided', async () => {
|
|
17
|
+
const handler = {
|
|
18
|
+
event: {
|
|
19
|
+
headers: {
|
|
20
|
+
'X-Api-Key': '123',
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
try {
|
|
26
|
+
expect(await clientAuthMiddlewareBeforeHandler(handler, next)).toThrow();
|
|
27
|
+
} catch (error) {
|
|
28
|
+
expect(error.name).toBe('LesgoException');
|
|
29
|
+
expect(error.message).toBe("Missing required 'clientKey'");
|
|
30
|
+
expect(error.statusCode).toBe(403);
|
|
31
|
+
expect(error.code).toBe(
|
|
32
|
+
'Middlewares/clientAuthMiddleware::INVALID_AUTH_DATA'
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test('should throw LesgoException when x-client-id is incorrect', async () => {
|
|
38
|
+
const handler = {
|
|
39
|
+
event: {
|
|
40
|
+
headers: {
|
|
41
|
+
'x-client-id': 'notexisting',
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
try {
|
|
47
|
+
expect(await clientAuthMiddlewareBeforeHandler(handler, next)).toThrow();
|
|
48
|
+
} catch (error) {
|
|
49
|
+
expect(error.name).toBe('LesgoException');
|
|
50
|
+
expect(error.message).toBe('Invalid ClientId provided');
|
|
51
|
+
expect(error.statusCode).toBe(403);
|
|
52
|
+
expect(error.code).toBe(
|
|
53
|
+
'Middlewares/clientAuthMiddleware::INVALID_CLIENT_ID'
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
test('should be able to validate from multiple header keys', async () => {
|
|
59
|
+
const handler = {
|
|
60
|
+
event: {
|
|
61
|
+
headers: {
|
|
62
|
+
'X-Client-Id': '1111-1111-1111-1111',
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
let hasError = false;
|
|
68
|
+
|
|
69
|
+
try {
|
|
70
|
+
await clientAuthMiddlewareBeforeHandler(handler, next);
|
|
71
|
+
} catch (e) {
|
|
72
|
+
hasError = e;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
expect(hasError).toBe(false);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
test('should allow getting from query string parameters', async () => {
|
|
79
|
+
const handler = {
|
|
80
|
+
event: {
|
|
81
|
+
queryStringParameters: {
|
|
82
|
+
'x-client-id': '1111-1111-1111-1111',
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
let hasError = false;
|
|
88
|
+
|
|
89
|
+
try {
|
|
90
|
+
await clientAuthMiddlewareBeforeHandler(handler, next);
|
|
91
|
+
} catch (e) {
|
|
92
|
+
hasError = e;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
expect(hasError).toBe(false);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
test('should return success with valid client id', async () => {
|
|
99
|
+
const handler = {
|
|
100
|
+
event: {
|
|
101
|
+
headers: {
|
|
102
|
+
'x-client-id': '1111-1111-1111-1111',
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
let hasError = false;
|
|
108
|
+
|
|
109
|
+
try {
|
|
110
|
+
await clientAuthMiddlewareBeforeHandler(handler, next);
|
|
111
|
+
} catch (e) {
|
|
112
|
+
hasError = true;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
expect(hasError).toBe(false);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
test('should return success with valid client id on input', async () => {
|
|
119
|
+
const handler = {
|
|
120
|
+
event: {
|
|
121
|
+
headers: {},
|
|
122
|
+
input: {
|
|
123
|
+
clientid: '1111-1111-1111-1111',
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
let hasError = false;
|
|
129
|
+
|
|
130
|
+
try {
|
|
131
|
+
await clientAuthMiddlewareBeforeHandler(handler, next);
|
|
132
|
+
} catch (e) {
|
|
133
|
+
hasError = true;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
expect(hasError).toBe(false);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
test('should set handler.event.platform with valid client id on input', async () => {
|
|
140
|
+
const handler = {
|
|
141
|
+
event: {
|
|
142
|
+
headers: {},
|
|
143
|
+
input: {
|
|
144
|
+
clientid: '1111-1111-1111-1111',
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
let hasError = false;
|
|
150
|
+
|
|
151
|
+
try {
|
|
152
|
+
await clientAuthMiddlewareBeforeHandler(handler, next);
|
|
153
|
+
} catch (e) {
|
|
154
|
+
hasError = true;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
expect(hasError).toBe(false);
|
|
158
|
+
expect(handler.event.platform).toStrictEqual({
|
|
159
|
+
id: 'platform_1',
|
|
160
|
+
key: '1111-1111-1111-1111',
|
|
161
|
+
secret: '1111-1111-1111-1111',
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
test('should execute passed callback function', async () => {
|
|
166
|
+
const handler = {
|
|
167
|
+
event: {
|
|
168
|
+
headers: {},
|
|
169
|
+
input: {
|
|
170
|
+
clientid: '1111-1111-1111-1111',
|
|
171
|
+
},
|
|
172
|
+
},
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
await clientAuthMiddlewareBeforeHandler(handler, next, h => {
|
|
176
|
+
// eslint-disable-next-line no-param-reassign
|
|
177
|
+
h.event.created_obj = 'created_obj';
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
expect(handler.event).toHaveProperty('created_obj');
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
test('should execute with callback function from config', async () => {
|
|
184
|
+
const handler = {
|
|
185
|
+
event: {
|
|
186
|
+
headers: {},
|
|
187
|
+
input: {
|
|
188
|
+
clientid: '1111-1111-1111-1111',
|
|
189
|
+
},
|
|
190
|
+
},
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
await clientAuthMiddlewareBeforeHandler(handler, next);
|
|
194
|
+
|
|
195
|
+
expect(handler.event).toHaveProperty('created_obj');
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
test('should execute passed opt object with async callback function', async () => {
|
|
199
|
+
const handler = {
|
|
200
|
+
event: {
|
|
201
|
+
headers: {},
|
|
202
|
+
input: {
|
|
203
|
+
clientid: '1111-1111-1111-1111',
|
|
204
|
+
},
|
|
205
|
+
},
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
await clientAuthMiddlewareBeforeHandler(handler, next, {
|
|
209
|
+
callback: async h => {
|
|
210
|
+
await new Promise(resolve => setTimeout(resolve, 500));
|
|
211
|
+
// eslint-disable-next-line no-param-reassign
|
|
212
|
+
h.event.created_obj_async = 'created_obj_async';
|
|
213
|
+
},
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
expect(handler.event).toHaveProperty('created_obj_async');
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
test('should not execute passed opt object with callback function if not a function', async () => {
|
|
220
|
+
const handler = {
|
|
221
|
+
event: {
|
|
222
|
+
headers: {},
|
|
223
|
+
input: {
|
|
224
|
+
clientid: '1111-1111-1111-1111',
|
|
225
|
+
},
|
|
226
|
+
},
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
await clientAuthMiddlewareBeforeHandler(handler, next, {
|
|
230
|
+
callback: 'not_function',
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
expect(handler.event).not.toHaveProperty('created_obj');
|
|
234
|
+
});
|
|
235
|
+
});
|
|
@@ -45,6 +45,19 @@ describe('MiddlewareGroup: test errorHandler middleware', () => {
|
|
|
45
45
|
expect(dataBody).toHaveProperty('error.details', '');
|
|
46
46
|
});
|
|
47
47
|
|
|
48
|
+
it('test with formatSuccess argument', async () => {
|
|
49
|
+
const data = await errorHttpResponseHandler({
|
|
50
|
+
error: new ValidationErrorException('Test validation error'),
|
|
51
|
+
formatError: options => {
|
|
52
|
+
return options.error.code;
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
expect(data.statusCode).toBe(400);
|
|
57
|
+
|
|
58
|
+
expect(data.body).toBe('VALIDATION_ERROR');
|
|
59
|
+
});
|
|
60
|
+
|
|
48
61
|
it('test with thrown custom Error with given parameters', async () => {
|
|
49
62
|
const data = await errorHttpResponseHandler({
|
|
50
63
|
error: new ValidationErrorException(
|
|
@@ -145,6 +158,36 @@ describe('MiddlewareGroup: test errorHandler middleware', () => {
|
|
|
145
158
|
|
|
146
159
|
expect(end).toHaveBeenCalledTimes(1);
|
|
147
160
|
});
|
|
161
|
+
|
|
162
|
+
it('should call cache.end() whenever a cache options is set', async () => {
|
|
163
|
+
const end = jest.fn().mockResolvedValue();
|
|
164
|
+
await errorHttpResponseHandler({
|
|
165
|
+
error: 'Test error message',
|
|
166
|
+
event: {
|
|
167
|
+
someEventKey: 'someEventValue',
|
|
168
|
+
},
|
|
169
|
+
cache: {
|
|
170
|
+
end,
|
|
171
|
+
},
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
expect(end).toHaveBeenCalledTimes(1);
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
it('should call dbRead.end() whenever a dbRead options is set', async () => {
|
|
178
|
+
const end = jest.fn().mockResolvedValue();
|
|
179
|
+
await errorHttpResponseHandler({
|
|
180
|
+
error: 'Test error message',
|
|
181
|
+
event: {
|
|
182
|
+
someEventKey: 'someEventValue',
|
|
183
|
+
},
|
|
184
|
+
dbRead: {
|
|
185
|
+
end,
|
|
186
|
+
},
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
expect(end).toHaveBeenCalledTimes(1);
|
|
190
|
+
});
|
|
148
191
|
});
|
|
149
192
|
|
|
150
193
|
describe('MiddlewareGroup: test errorHttpResponseAfterHandler', () => {
|
|
@@ -97,7 +97,7 @@ describe('test gzipHttpResponse gzip', () => {
|
|
|
97
97
|
expect(resp).toThrow();
|
|
98
98
|
} catch (err) {
|
|
99
99
|
expect(err.name).toEqual('LesgoException');
|
|
100
|
-
expect(err.code).
|
|
100
|
+
expect(err.code).toMatch(/^GZIP_[A-Z]+_ERROR$/);
|
|
101
101
|
}
|
|
102
102
|
});
|
|
103
103
|
});
|