lesgo 0.7.6 → 0.7.8
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/package.json +23 -23
- package/src/middlewares/__tests__/basicAuthMiddleware.spec.js +225 -0
- package/src/middlewares/__tests__/clientAuthMiddleware.spec.js +137 -0
- package/src/middlewares/__tests__/errorHttpResponseMiddleware.spec.js +30 -0
- package/src/middlewares/__tests__/httpNoOutputMiddleware.spec.js +199 -0
- package/src/middlewares/__tests__/normalizeSQSMessageMiddleware.spec.js +89 -1
- package/src/middlewares/__tests__/serverAuthMiddleware.spec.js +170 -0
- package/src/middlewares/__tests__/successHttpResponseMiddleware.spec.js +32 -0
- package/src/middlewares/__tests__/verifyJwtMiddleware.spec.js +49 -1
- package/src/middlewares/basicAuthMiddleware.js +145 -0
- package/src/middlewares/clientAuthMiddleware.js +82 -0
- package/src/middlewares/errorHttpResponseMiddleware.js +9 -2
- package/src/middlewares/httpNoOutputMiddleware.js +87 -0
- package/src/middlewares/normalizeHttpRequestMiddleware.js +2 -1
- package/src/middlewares/normalizeSQSMessageMiddleware.js +30 -1
- package/src/middlewares/serverAuthMiddleware.js +29 -0
- package/src/middlewares/successHttpResponseMiddleware.js +12 -2
- package/src/middlewares/verifyJwtMiddleware.js +10 -4
- package/src/services/AuroraDbRDSProxyService.js +2 -3
- package/src/services/ElastiCacheService.js +3 -3
- package/src/services/__tests__/ElasticsearchService.spec.js +33 -0
- package/src/utils/__tests__/cache.spec.js +88 -44
- package/src/utils/__tests__/db.spec.js +0 -1
- package/src/utils/__tests__/validateFields.spec.js +223 -32
- package/src/utils/cache.js +157 -51
- package/src/utils/validateFields.js +85 -44
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lesgo",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.8",
|
|
4
4
|
"description": "Core framework for lesgo node.js serverless framework.",
|
|
5
5
|
"main": "./src/index.js",
|
|
6
6
|
"author": "Sufiyan Rahmat",
|
|
@@ -30,35 +30,35 @@
|
|
|
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
|
-
"@babel/cli": "^7.
|
|
37
|
-
"@babel/core": "^7.
|
|
38
|
-
"@babel/preset-env": "^7.
|
|
39
|
-
"aws-sdk": "^2.
|
|
36
|
+
"@babel/cli": "^7.17.6",
|
|
37
|
+
"@babel/core": "^7.17.5",
|
|
38
|
+
"@babel/preset-env": "^7.16.11",
|
|
39
|
+
"aws-sdk": "^2.1084.0",
|
|
40
40
|
"babel-jest": "^24.9.0",
|
|
41
|
-
"coveralls": "^3.
|
|
42
|
-
"eslint": "^6.
|
|
43
|
-
"eslint-config-airbnb-base": "^14.
|
|
44
|
-
"eslint-config-prettier": "^6.
|
|
45
|
-
"eslint-plugin-import": "^2.
|
|
46
|
-
"eslint-plugin-jest": "^22.
|
|
47
|
-
"eslint-plugin-prettier": "^3.
|
|
48
|
-
"husky": "^3.0
|
|
41
|
+
"coveralls": "^3.1.1",
|
|
42
|
+
"eslint": "^6.8.0",
|
|
43
|
+
"eslint-config-airbnb-base": "^14.2.1",
|
|
44
|
+
"eslint-config-prettier": "^6.15.0",
|
|
45
|
+
"eslint-plugin-import": "^2.25.4",
|
|
46
|
+
"eslint-plugin-jest": "^22.21.0",
|
|
47
|
+
"eslint-plugin-prettier": "^3.4.1",
|
|
48
|
+
"husky": "^3.1.0",
|
|
49
49
|
"jest": "^24.9.0",
|
|
50
|
-
"lint-staged": "^9.
|
|
51
|
-
"prettier": "^1.
|
|
50
|
+
"lint-staged": "^9.5.0",
|
|
51
|
+
"prettier": "^1.19.1"
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
|
-
"@elastic/elasticsearch": "
|
|
55
|
-
"@firebase/app": "^0.7.
|
|
56
|
-
"data-api-client": "^1.
|
|
57
|
-
"firebase-admin": "^9.
|
|
54
|
+
"@elastic/elasticsearch": "7.13.0",
|
|
55
|
+
"@firebase/app": "^0.7.17",
|
|
56
|
+
"data-api-client": "^1.2.0",
|
|
57
|
+
"firebase-admin": "^9.12.0",
|
|
58
58
|
"jsonwebtoken": "^8.5.1",
|
|
59
|
-
"
|
|
60
|
-
"mysql2": "^2.
|
|
61
|
-
"nanoid": "^3.
|
|
59
|
+
"memcache-plus": "^0.2.22",
|
|
60
|
+
"mysql2": "^2.3.3",
|
|
61
|
+
"nanoid": "^3.3.1"
|
|
62
62
|
},
|
|
63
63
|
"husky": {
|
|
64
64
|
"hooks": {
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import basicAuthMiddleware, {
|
|
2
|
+
generateBasicAuthorizationHash,
|
|
3
|
+
verifyBasicAuthBeforeHandler,
|
|
4
|
+
} from '../basicAuthMiddleware';
|
|
5
|
+
import client from '../../../tests/__mocks__/config/client';
|
|
6
|
+
|
|
7
|
+
describe('test basicAuthMiddleware middleware', () => {
|
|
8
|
+
test.each`
|
|
9
|
+
clientObj
|
|
10
|
+
${undefined}
|
|
11
|
+
${{}}
|
|
12
|
+
${{
|
|
13
|
+
default: {
|
|
14
|
+
key: '1111-1111-1111-1111',
|
|
15
|
+
secret: '1111-1111-1111-1111',
|
|
16
|
+
},
|
|
17
|
+
}}
|
|
18
|
+
`('should return object', ({ clientObj }) => {
|
|
19
|
+
const result = basicAuthMiddleware({
|
|
20
|
+
client: clientObj,
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
expect(result).toHaveProperty('before');
|
|
24
|
+
expect(result).toHaveProperty('onError');
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
// eslint-disable-next-line
|
|
29
|
+
const next = () => {};
|
|
30
|
+
|
|
31
|
+
describe('test verifyBasicAuthBeforeHandler error handling', () => {
|
|
32
|
+
const invalidClientKey = Buffer.from('client_key:secret_key').toString(
|
|
33
|
+
'base64'
|
|
34
|
+
);
|
|
35
|
+
const invalidSecretKey = Buffer.from(
|
|
36
|
+
`${client.platform_2.key}:secret_key`
|
|
37
|
+
).toString('base64');
|
|
38
|
+
|
|
39
|
+
test.each`
|
|
40
|
+
headers | errorName | errorMessage | errorStatusCode | errorCode | blacklistMode
|
|
41
|
+
${{}} | ${'LesgoException'} | ${'Authorization header not found'} | ${403} | ${'Middlewares/basicAuthMiddleware::AUTHORIZATION_HEADER_NOT_FOUND'} | ${undefined}
|
|
42
|
+
${{ Authorization: 'auth' }} | ${'LesgoException'} | ${'Invalid authorization type provided'} | ${403} | ${'Middlewares/basicAuthMiddleware::AUTH_INVALID_AUTHORIZATION_TYPE'} | ${undefined}
|
|
43
|
+
${{ Authorization: 'basic ' }} | ${'LesgoException'} | ${'Empty basic authentication hash provided'} | ${403} | ${'Middlewares/basicAuthMiddleware::AUTH_EMPTY_BASIC_HASH'} | ${undefined}
|
|
44
|
+
${{ Authorization: `basic ${invalidClientKey}` }} | ${'LesgoException'} | ${'Invalid client key or secret provided'} | ${403} | ${'Middlewares/basicAuthMiddleware::AUTH_INVALID_CLIENT_OR_SECRET_KEY'} | ${undefined}
|
|
45
|
+
${{ Authorization: `basic ${invalidSecretKey}` }} | ${'LesgoException'} | ${'Invalid client key or secret provided'} | ${403} | ${'Middlewares/basicAuthMiddleware::AUTH_INVALID_CLIENT_OR_SECRET_KEY'} | ${undefined}
|
|
46
|
+
${{ Authorization: `Basic ${invalidSecretKey}` }} | ${'LesgoException'} | ${'Invalid client key or secret provided'} | ${403} | ${'Middlewares/basicAuthMiddleware::AUTH_INVALID_CLIENT_OR_SECRET_KEY'} | ${undefined}
|
|
47
|
+
${{}} | ${'LesgoException'} | ${'Authorization header not found'} | ${403} | ${'Middlewares/basicAuthMiddleware::AUTHORIZATION_HEADER_NOT_FOUND'} | ${true}
|
|
48
|
+
${{ Authorization: 'auth' }} | ${'LesgoException'} | ${'Invalid authorization type provided'} | ${403} | ${'Middlewares/basicAuthMiddleware::AUTH_INVALID_AUTHORIZATION_TYPE'} | ${true}
|
|
49
|
+
${{ Authorization: 'basic ' }} | ${'LesgoException'} | ${'Empty basic authentication hash provided'} | ${403} | ${'Middlewares/basicAuthMiddleware::AUTH_EMPTY_BASIC_HASH'} | ${true}
|
|
50
|
+
${{ Authorization: `basic ${invalidClientKey}` }} | ${'LesgoException'} | ${'Invalid client key or secret provided'} | ${403} | ${'Middlewares/basicAuthMiddleware::AUTH_INVALID_CLIENT_OR_SECRET_KEY'} | ${true}
|
|
51
|
+
${{ Authorization: `basic ${invalidSecretKey}` }} | ${'LesgoException'} | ${'Invalid client key or secret provided'} | ${403} | ${'Middlewares/basicAuthMiddleware::AUTH_INVALID_CLIENT_OR_SECRET_KEY'} | ${true}
|
|
52
|
+
${{ Authorization: `Basic ${invalidSecretKey}` }} | ${'LesgoException'} | ${'Invalid client key or secret provided'} | ${403} | ${'Middlewares/basicAuthMiddleware::AUTH_INVALID_CLIENT_OR_SECRET_KEY'} | ${true}
|
|
53
|
+
${{ Authorization: 'auth' }} | ${'LesgoException'} | ${'Invalid authorization type provided'} | ${403} | ${'Middlewares/basicAuthMiddleware::AUTH_INVALID_AUTHORIZATION_TYPE'} | ${false}
|
|
54
|
+
${{ Authorization: 'basic ' }} | ${'LesgoException'} | ${'Empty basic authentication hash provided'} | ${403} | ${'Middlewares/basicAuthMiddleware::AUTH_EMPTY_BASIC_HASH'} | ${false}
|
|
55
|
+
${{ Authorization: `basic ${invalidClientKey}` }} | ${'LesgoException'} | ${'Invalid client key or secret provided'} | ${403} | ${'Middlewares/basicAuthMiddleware::AUTH_INVALID_CLIENT_OR_SECRET_KEY'} | ${false}
|
|
56
|
+
${{ Authorization: `basic ${invalidSecretKey}` }} | ${'LesgoException'} | ${'Invalid client key or secret provided'} | ${403} | ${'Middlewares/basicAuthMiddleware::AUTH_INVALID_CLIENT_OR_SECRET_KEY'} | ${false}
|
|
57
|
+
${{ Authorization: `Basic ${invalidSecretKey}` }} | ${'LesgoException'} | ${'Invalid client key or secret provided'} | ${403} | ${'Middlewares/basicAuthMiddleware::AUTH_INVALID_CLIENT_OR_SECRET_KEY'} | ${false}
|
|
58
|
+
`(
|
|
59
|
+
'should throw $errorMessage when authorization header is $headers',
|
|
60
|
+
async ({
|
|
61
|
+
headers,
|
|
62
|
+
errorName,
|
|
63
|
+
errorMessage,
|
|
64
|
+
errorStatusCode,
|
|
65
|
+
errorCode,
|
|
66
|
+
blacklistMode,
|
|
67
|
+
}) => {
|
|
68
|
+
const handler = {
|
|
69
|
+
event: {
|
|
70
|
+
headers,
|
|
71
|
+
site: {
|
|
72
|
+
id: 'platform_1',
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
try {
|
|
78
|
+
expect(
|
|
79
|
+
verifyBasicAuthBeforeHandler(handler, next, {
|
|
80
|
+
blacklistMode,
|
|
81
|
+
})
|
|
82
|
+
).toThrow();
|
|
83
|
+
} catch (error) {
|
|
84
|
+
expect(error.name).toBe(errorName);
|
|
85
|
+
expect(error.message).toBe(errorMessage);
|
|
86
|
+
expect(error.statusCode).toBe(errorStatusCode);
|
|
87
|
+
expect(error.code).toBe(errorCode);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
describe('test verifyBasicAuthBeforeHandler with valid credentials', () => {
|
|
94
|
+
const validBasicAuth = Buffer.from(
|
|
95
|
+
generateBasicAuthorizationHash(
|
|
96
|
+
client.platform_2.key,
|
|
97
|
+
client.platform_2.secret
|
|
98
|
+
)
|
|
99
|
+
).toString('base64');
|
|
100
|
+
|
|
101
|
+
test.each`
|
|
102
|
+
clientObj
|
|
103
|
+
${undefined}
|
|
104
|
+
${{}}
|
|
105
|
+
${{
|
|
106
|
+
platform_2: {
|
|
107
|
+
key: '2222-2222-2222-2222',
|
|
108
|
+
secret: '2222-2222-2222-2222',
|
|
109
|
+
},
|
|
110
|
+
}}
|
|
111
|
+
`('should return undefined when successful', ({ clientObj }) => {
|
|
112
|
+
const handler = {
|
|
113
|
+
event: {
|
|
114
|
+
headers: {
|
|
115
|
+
Authorization: `basic ${validBasicAuth}`,
|
|
116
|
+
},
|
|
117
|
+
site: {
|
|
118
|
+
id: 'platform_2',
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
let hasError = false;
|
|
124
|
+
|
|
125
|
+
try {
|
|
126
|
+
verifyBasicAuthBeforeHandler(handler, next, {
|
|
127
|
+
client: clientObj,
|
|
128
|
+
});
|
|
129
|
+
} catch (e) {
|
|
130
|
+
hasError = true;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
expect(hasError).toBeFalsy();
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
test.each`
|
|
137
|
+
Authorization | blacklistMode
|
|
138
|
+
${undefined} | ${false}
|
|
139
|
+
${`basic ${validBasicAuth}`} | ${false}
|
|
140
|
+
${`Basic ${validBasicAuth}`} | ${false}
|
|
141
|
+
${`basic ${validBasicAuth}`} | ${true}
|
|
142
|
+
${`Basic ${validBasicAuth}`} | ${true}
|
|
143
|
+
`(
|
|
144
|
+
'test Exception with valid credentials',
|
|
145
|
+
({ Authorization, blacklistMode }) => {
|
|
146
|
+
const handler = {
|
|
147
|
+
event: {
|
|
148
|
+
headers: {
|
|
149
|
+
Authorization,
|
|
150
|
+
},
|
|
151
|
+
site: {
|
|
152
|
+
id: 'platform_2',
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
let hasError = false;
|
|
158
|
+
|
|
159
|
+
try {
|
|
160
|
+
verifyBasicAuthBeforeHandler(handler, next, {
|
|
161
|
+
blacklistMode,
|
|
162
|
+
});
|
|
163
|
+
} catch (e) {
|
|
164
|
+
hasError = true;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
expect(hasError).toBeFalsy();
|
|
168
|
+
}
|
|
169
|
+
);
|
|
170
|
+
|
|
171
|
+
test.each`
|
|
172
|
+
siteObjects
|
|
173
|
+
${{}}
|
|
174
|
+
${{ site: { id: undefined } }}
|
|
175
|
+
${{ requestContext: { site: { id: undefined } } }}
|
|
176
|
+
${{ platform: undefined }}
|
|
177
|
+
`('test Exception with no site ID', ({ siteObjects }) => {
|
|
178
|
+
const handler = {
|
|
179
|
+
event: {
|
|
180
|
+
headers: {
|
|
181
|
+
Authorization: `basic ${validBasicAuth}`,
|
|
182
|
+
},
|
|
183
|
+
...siteObjects,
|
|
184
|
+
},
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
try {
|
|
188
|
+
expect(verifyBasicAuthBeforeHandler(handler, next)).toThrow();
|
|
189
|
+
} catch (error) {
|
|
190
|
+
expect(error.name).toBe('LesgoException');
|
|
191
|
+
expect(error.message).toBe('Site ID could not be found');
|
|
192
|
+
expect(error.statusCode).toBe(403);
|
|
193
|
+
expect(error.code).toBe(
|
|
194
|
+
'Middlewares/basicAuthMiddleware::SITE_ID_NOT_FOUND'
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
test.each`
|
|
200
|
+
siteObjects
|
|
201
|
+
${{ site: { id: 'platform_2' } }}
|
|
202
|
+
${{ requestContext: { site: { id: 'platform_2' } } }}
|
|
203
|
+
${{ requestContext: { site: { id: undefined } }, platform: 'platform_2' }}
|
|
204
|
+
${{ platform: 'platform_2' }}
|
|
205
|
+
`('valid site ids', ({ siteObjects }) => {
|
|
206
|
+
const handler = {
|
|
207
|
+
event: {
|
|
208
|
+
headers: {
|
|
209
|
+
Authorization: `basic ${validBasicAuth}`,
|
|
210
|
+
},
|
|
211
|
+
...siteObjects,
|
|
212
|
+
},
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
let hasError = false;
|
|
216
|
+
|
|
217
|
+
try {
|
|
218
|
+
verifyBasicAuthBeforeHandler(handler, next);
|
|
219
|
+
} catch (e) {
|
|
220
|
+
hasError = true;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
expect(hasError).toBeFalsy();
|
|
224
|
+
});
|
|
225
|
+
});
|
|
@@ -0,0 +1,137 @@
|
|
|
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
|
+
expect(result).toHaveProperty('onError');
|
|
11
|
+
});
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
const next = () => {};
|
|
15
|
+
|
|
16
|
+
describe('test clientMiddlewareBeforeHandler', () => {
|
|
17
|
+
test('should throw LesgoException when invalid api key is provided', async () => {
|
|
18
|
+
const handler = {
|
|
19
|
+
event: {
|
|
20
|
+
headers: {
|
|
21
|
+
'X-Api-Key': '123',
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
try {
|
|
27
|
+
expect(await clientAuthMiddlewareBeforeHandler(handler, next)).toThrow();
|
|
28
|
+
} catch (error) {
|
|
29
|
+
expect(error.name).toBe('LesgoException');
|
|
30
|
+
expect(error.message).toBe("Missing required 'x-client-id'");
|
|
31
|
+
expect(error.statusCode).toBe(403);
|
|
32
|
+
expect(error.code).toBe(
|
|
33
|
+
'Middlewares/clientAuthMiddleware::INVALID_AUTH_DATA'
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
test('should throw LesgoException when x-client-id is incorrect', async () => {
|
|
39
|
+
const handler = {
|
|
40
|
+
event: {
|
|
41
|
+
headers: {
|
|
42
|
+
'x-client-id': 'notexisting',
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
try {
|
|
48
|
+
expect(await clientAuthMiddlewareBeforeHandler(handler, next)).toThrow();
|
|
49
|
+
} catch (error) {
|
|
50
|
+
expect(error.name).toBe('LesgoException');
|
|
51
|
+
expect(error.message).toBe('Invalid ClientId provided');
|
|
52
|
+
expect(error.statusCode).toBe(403);
|
|
53
|
+
expect(error.code).toBe(
|
|
54
|
+
'Middlewares/clientAuthMiddleware::INVALID_CLIENT_ID'
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
test('should return success with valid client id', async () => {
|
|
60
|
+
const handler = {
|
|
61
|
+
event: {
|
|
62
|
+
headers: {
|
|
63
|
+
'x-client-id': '1111-1111-1111-1111',
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
let hasError = false;
|
|
69
|
+
|
|
70
|
+
try {
|
|
71
|
+
await clientAuthMiddlewareBeforeHandler(handler, next);
|
|
72
|
+
} catch (e) {
|
|
73
|
+
hasError = true;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
expect(hasError).toBe(false);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
test('should return success with valid client id on input', async () => {
|
|
80
|
+
const handler = {
|
|
81
|
+
event: {
|
|
82
|
+
headers: {},
|
|
83
|
+
input: {
|
|
84
|
+
clientid: '1111-1111-1111-1111',
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
let hasError = false;
|
|
90
|
+
|
|
91
|
+
try {
|
|
92
|
+
await clientAuthMiddlewareBeforeHandler(handler, next);
|
|
93
|
+
} catch (e) {
|
|
94
|
+
hasError = true;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
expect(hasError).toBe(false);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
test('should execute passed callback function', async () => {
|
|
101
|
+
const handler = {
|
|
102
|
+
event: {
|
|
103
|
+
headers: {},
|
|
104
|
+
input: {
|
|
105
|
+
clientid: '1111-1111-1111-1111',
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
await clientAuthMiddlewareBeforeHandler(handler, next, h => {
|
|
111
|
+
// eslint-disable-next-line no-param-reassign
|
|
112
|
+
h.event.created_obj = 'created_obj';
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
expect(handler.event).toHaveProperty('created_obj');
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
test('should execute passed top object with callback function', async () => {
|
|
119
|
+
const handler = {
|
|
120
|
+
event: {
|
|
121
|
+
headers: {},
|
|
122
|
+
input: {
|
|
123
|
+
clientid: '1111-1111-1111-1111',
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
await clientAuthMiddlewareBeforeHandler(handler, next, {
|
|
129
|
+
callback: h => {
|
|
130
|
+
// eslint-disable-next-line no-param-reassign
|
|
131
|
+
h.event.created_obj = 'created_obj';
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
expect(handler.event).toHaveProperty('created_obj');
|
|
136
|
+
});
|
|
137
|
+
});
|
|
@@ -145,6 +145,36 @@ describe('MiddlewareGroup: test errorHandler middleware', () => {
|
|
|
145
145
|
|
|
146
146
|
expect(end).toHaveBeenCalledTimes(1);
|
|
147
147
|
});
|
|
148
|
+
|
|
149
|
+
it('should call cache.end() whenever a cache options is set', async () => {
|
|
150
|
+
const end = jest.fn().mockResolvedValue();
|
|
151
|
+
await errorHttpResponseHandler({
|
|
152
|
+
error: 'Test error message',
|
|
153
|
+
event: {
|
|
154
|
+
someEventKey: 'someEventValue',
|
|
155
|
+
},
|
|
156
|
+
cache: {
|
|
157
|
+
end,
|
|
158
|
+
},
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
expect(end).toHaveBeenCalledTimes(1);
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
it('should call dbRead.end() whenever a dbRead options is set', async () => {
|
|
165
|
+
const end = jest.fn().mockResolvedValue();
|
|
166
|
+
await errorHttpResponseHandler({
|
|
167
|
+
error: 'Test error message',
|
|
168
|
+
event: {
|
|
169
|
+
someEventKey: 'someEventValue',
|
|
170
|
+
},
|
|
171
|
+
dbRead: {
|
|
172
|
+
end,
|
|
173
|
+
},
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
expect(end).toHaveBeenCalledTimes(1);
|
|
177
|
+
});
|
|
148
178
|
});
|
|
149
179
|
|
|
150
180
|
describe('MiddlewareGroup: test errorHttpResponseAfterHandler', () => {
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import app from 'Config/app'; // eslint-disable-line import/no-unresolved
|
|
2
|
+
import {
|
|
3
|
+
successHttpNoOutputResponseAfterHandler,
|
|
4
|
+
errorHttpNoOutputResponseAfterHandler,
|
|
5
|
+
} from '../httpNoOutputMiddleware';
|
|
6
|
+
|
|
7
|
+
describe('MiddlewareGroup: test successHttpNoOutputResponseAfterHandler', () => {
|
|
8
|
+
it('should have no body without debug', async () => {
|
|
9
|
+
const handler = {
|
|
10
|
+
response: {},
|
|
11
|
+
event: {},
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
await successHttpNoOutputResponseAfterHandler(handler, () => {}, {
|
|
15
|
+
response: 'Some message',
|
|
16
|
+
});
|
|
17
|
+
expect(handler.response).toHaveProperty('statusCode', 200);
|
|
18
|
+
expect(handler.response).toHaveProperty('body', null);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('should return the body when debug is enabled via query string parameters', async () => {
|
|
22
|
+
const handler = {
|
|
23
|
+
response: {},
|
|
24
|
+
event: {
|
|
25
|
+
queryStringParameters: {
|
|
26
|
+
debug: '1',
|
|
27
|
+
},
|
|
28
|
+
someEventKey: 'someEventValue',
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
await successHttpNoOutputResponseAfterHandler(handler, () => {}, {
|
|
33
|
+
response: 'Some message',
|
|
34
|
+
});
|
|
35
|
+
expect(handler.response).toHaveProperty('statusCode', 200);
|
|
36
|
+
expect(handler.response).toHaveProperty(
|
|
37
|
+
'body',
|
|
38
|
+
JSON.stringify({
|
|
39
|
+
status: 'success',
|
|
40
|
+
data: 'Some message',
|
|
41
|
+
_meta: {},
|
|
42
|
+
})
|
|
43
|
+
);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('should have null body even when enabled when configuration has is disabled', async () => {
|
|
47
|
+
app.debug = false;
|
|
48
|
+
|
|
49
|
+
const handler = {
|
|
50
|
+
response: {},
|
|
51
|
+
event: {
|
|
52
|
+
queryStringParameters: {
|
|
53
|
+
debug: '1',
|
|
54
|
+
},
|
|
55
|
+
someEventKey: 'someEventValue',
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
await successHttpNoOutputResponseAfterHandler(handler, () => {}, {
|
|
60
|
+
response: 'Some message',
|
|
61
|
+
});
|
|
62
|
+
expect(handler.response).toHaveProperty('statusCode', 200);
|
|
63
|
+
expect(handler.response).toHaveProperty('body', null);
|
|
64
|
+
app.debug = true;
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('should return a response when allowResponse override is passed via options', async () => {
|
|
68
|
+
app.debug = false;
|
|
69
|
+
|
|
70
|
+
const handler = {
|
|
71
|
+
response: {},
|
|
72
|
+
event: {
|
|
73
|
+
someEventKey: 'someEventValue',
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
await successHttpNoOutputResponseAfterHandler(handler, () => {}, {
|
|
78
|
+
response: 'Some message',
|
|
79
|
+
allowResponse: () => true,
|
|
80
|
+
});
|
|
81
|
+
expect(handler.response).toHaveProperty('statusCode', 200);
|
|
82
|
+
expect(handler.response).toHaveProperty(
|
|
83
|
+
'body',
|
|
84
|
+
JSON.stringify({
|
|
85
|
+
status: 'success',
|
|
86
|
+
data: 'Some message',
|
|
87
|
+
_meta: {},
|
|
88
|
+
})
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
app.debug = true;
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
describe('MiddlewareGroup: test errorHttpNoOutputResponseAfterHandler', () => {
|
|
96
|
+
it('should have no body without debug', async () => {
|
|
97
|
+
const handler = {
|
|
98
|
+
response: {},
|
|
99
|
+
event: {},
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
await errorHttpNoOutputResponseAfterHandler(handler, () => {}, {
|
|
103
|
+
error: new Error('Test validation error'),
|
|
104
|
+
});
|
|
105
|
+
expect(handler.response).toHaveProperty('statusCode', 200);
|
|
106
|
+
expect(handler.response).toHaveProperty('body', null);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it('should return the body when debug is enabled via query string parameters', async () => {
|
|
110
|
+
const handler = {
|
|
111
|
+
response: {},
|
|
112
|
+
event: {
|
|
113
|
+
queryStringParameters: {
|
|
114
|
+
debug: '1',
|
|
115
|
+
},
|
|
116
|
+
someEventKey: 'someEventValue',
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
await errorHttpNoOutputResponseAfterHandler(handler, () => {}, {
|
|
121
|
+
error: new Error('Test validation error'),
|
|
122
|
+
});
|
|
123
|
+
expect(handler.response).toHaveProperty('statusCode', 500);
|
|
124
|
+
expect(handler.response).toHaveProperty(
|
|
125
|
+
'body',
|
|
126
|
+
JSON.stringify({
|
|
127
|
+
status: 'error',
|
|
128
|
+
data: null,
|
|
129
|
+
error: {
|
|
130
|
+
code: 'UNHANDLED_ERROR',
|
|
131
|
+
message: 'Error: Test validation error',
|
|
132
|
+
details: '',
|
|
133
|
+
},
|
|
134
|
+
_meta: {
|
|
135
|
+
queryStringParameters: {
|
|
136
|
+
debug: '1',
|
|
137
|
+
},
|
|
138
|
+
someEventKey: 'someEventValue',
|
|
139
|
+
},
|
|
140
|
+
})
|
|
141
|
+
);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
it('should have null body even when enabled when configuration has is disabled', async () => {
|
|
145
|
+
app.debug = false;
|
|
146
|
+
|
|
147
|
+
const handler = {
|
|
148
|
+
response: {},
|
|
149
|
+
event: {
|
|
150
|
+
queryStringParameters: {
|
|
151
|
+
debug: '1',
|
|
152
|
+
},
|
|
153
|
+
someEventKey: 'someEventValue',
|
|
154
|
+
},
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
await errorHttpNoOutputResponseAfterHandler(handler, () => {}, {
|
|
158
|
+
error: new Error('Test validation error'),
|
|
159
|
+
});
|
|
160
|
+
expect(handler.response).toHaveProperty('statusCode', 200);
|
|
161
|
+
expect(handler.response).toHaveProperty('body', null);
|
|
162
|
+
app.debug = true;
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
it('should return a response when allowResponse override is passed via options', async () => {
|
|
166
|
+
app.debug = false;
|
|
167
|
+
|
|
168
|
+
const handler = {
|
|
169
|
+
response: {},
|
|
170
|
+
event: {
|
|
171
|
+
queryStringParameters: {
|
|
172
|
+
debug: '1',
|
|
173
|
+
},
|
|
174
|
+
someEventKey: 'someEventValue',
|
|
175
|
+
},
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
await errorHttpNoOutputResponseAfterHandler(handler, () => {}, {
|
|
179
|
+
error: new Error('Test validation error'),
|
|
180
|
+
allowResponse: () => true,
|
|
181
|
+
});
|
|
182
|
+
expect(handler.response).toHaveProperty('statusCode', 500);
|
|
183
|
+
expect(handler.response).toHaveProperty(
|
|
184
|
+
'body',
|
|
185
|
+
JSON.stringify({
|
|
186
|
+
status: 'error',
|
|
187
|
+
data: null,
|
|
188
|
+
error: {
|
|
189
|
+
code: 'UNHANDLED_ERROR',
|
|
190
|
+
message: 'Error: Test validation error',
|
|
191
|
+
details: '',
|
|
192
|
+
},
|
|
193
|
+
_meta: {},
|
|
194
|
+
})
|
|
195
|
+
);
|
|
196
|
+
|
|
197
|
+
app.debug = false;
|
|
198
|
+
});
|
|
199
|
+
});
|