lesgo 0.7.8 → 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/bin/lesgo-scripts.sh +52 -7
- package/package.json +1 -1
- package/src/middlewares/__tests__/basicAuthMiddleware.spec.js +114 -75
- package/src/middlewares/__tests__/clientAuthMiddleware.spec.js +104 -6
- package/src/middlewares/__tests__/errorHttpResponseMiddleware.spec.js +13 -0
- package/src/middlewares/__tests__/gzipHttpResponse.spec.js +1 -1
- package/src/middlewares/__tests__/httpNoOutputMiddleware.spec.js +50 -48
- package/src/middlewares/__tests__/successHttpResponseMiddleware.spec.js +13 -0
- package/src/middlewares/__tests__/verifyJwtMiddleware.spec.js +140 -65
- package/src/middlewares/basicAuthMiddleware.js +44 -64
- package/src/middlewares/clientAuthMiddleware.js +41 -20
- package/src/middlewares/errorHttpResponseMiddleware.js +3 -1
- package/src/middlewares/httpNoOutputMiddleware.js +14 -10
- package/src/middlewares/index.js +4 -0
- package/src/middlewares/successHttpResponseMiddleware.js +7 -5
- package/src/middlewares/verifyJwtMiddleware.js +15 -4
- package/src/services/LoggerService.js +10 -3
- package/src/services/__tests__/LoggerService.spec.js +17 -2
- package/CHANGELOG.md +0 -9
- package/src/middlewares/__tests__/serverAuthMiddleware.spec.js +0 -170
- package/src/middlewares/serverAuthMiddleware.js +0 -29
|
@@ -15,7 +15,7 @@ describe('MiddlewareGroup: test successHttpNoOutputResponseAfterHandler', () =>
|
|
|
15
15
|
response: 'Some message',
|
|
16
16
|
});
|
|
17
17
|
expect(handler.response).toHaveProperty('statusCode', 200);
|
|
18
|
-
expect(handler.response).toHaveProperty('body',
|
|
18
|
+
expect(handler.response).toHaveProperty('body', '');
|
|
19
19
|
});
|
|
20
20
|
|
|
21
21
|
it('should return the body when debug is enabled via query string parameters', async () => {
|
|
@@ -43,7 +43,7 @@ describe('MiddlewareGroup: test successHttpNoOutputResponseAfterHandler', () =>
|
|
|
43
43
|
);
|
|
44
44
|
});
|
|
45
45
|
|
|
46
|
-
it('should have
|
|
46
|
+
it('should have empty body even when enabled when configuration has is disabled', async () => {
|
|
47
47
|
app.debug = false;
|
|
48
48
|
|
|
49
49
|
const handler = {
|
|
@@ -60,36 +60,43 @@ describe('MiddlewareGroup: test successHttpNoOutputResponseAfterHandler', () =>
|
|
|
60
60
|
response: 'Some message',
|
|
61
61
|
});
|
|
62
62
|
expect(handler.response).toHaveProperty('statusCode', 200);
|
|
63
|
-
expect(handler.response).toHaveProperty('body',
|
|
63
|
+
expect(handler.response).toHaveProperty('body', '');
|
|
64
64
|
app.debug = true;
|
|
65
65
|
});
|
|
66
66
|
|
|
67
|
-
it
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
67
|
+
it.each`
|
|
68
|
+
debug | allowResponse | body
|
|
69
|
+
${false} | ${() => true} | ${JSON.stringify({ status: 'success', data: 'Some message', _meta: {} })}
|
|
70
|
+
${true} | ${() => true} | ${JSON.stringify({ status: 'success', data: 'Some message', _meta: {} })}
|
|
71
|
+
${false} | ${() => false} | ${''}
|
|
72
|
+
${true} | ${() => false} | ${''}
|
|
73
|
+
${true} | ${undefined} | ${JSON.stringify({ status: 'success', data: 'Some message', _meta: {} })}
|
|
74
|
+
${false} | ${undefined} | ${''}
|
|
75
|
+
`(
|
|
76
|
+
'should return a specific response when allowResponse is $allowResponse and debug is $debug passed via options',
|
|
77
|
+
async ({ debug, allowResponse, body }) => {
|
|
78
|
+
app.debug = debug;
|
|
79
|
+
|
|
80
|
+
const handler = {
|
|
81
|
+
response: {},
|
|
82
|
+
event: {
|
|
83
|
+
someEventKey: 'someEventValue',
|
|
84
|
+
queryStringParameters: {
|
|
85
|
+
debug: 1,
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
await successHttpNoOutputResponseAfterHandler(handler, () => {}, {
|
|
91
|
+
response: 'Some message',
|
|
92
|
+
allowResponse,
|
|
93
|
+
});
|
|
94
|
+
expect(handler.response).toHaveProperty('statusCode', 200);
|
|
95
|
+
expect(handler.response).toHaveProperty('body', body);
|
|
96
|
+
|
|
97
|
+
app.debug = true;
|
|
98
|
+
}
|
|
99
|
+
);
|
|
93
100
|
});
|
|
94
101
|
|
|
95
102
|
describe('MiddlewareGroup: test errorHttpNoOutputResponseAfterHandler', () => {
|
|
@@ -103,7 +110,7 @@ describe('MiddlewareGroup: test errorHttpNoOutputResponseAfterHandler', () => {
|
|
|
103
110
|
error: new Error('Test validation error'),
|
|
104
111
|
});
|
|
105
112
|
expect(handler.response).toHaveProperty('statusCode', 200);
|
|
106
|
-
expect(handler.response).toHaveProperty('body',
|
|
113
|
+
expect(handler.response).toHaveProperty('body', '');
|
|
107
114
|
});
|
|
108
115
|
|
|
109
116
|
it('should return the body when debug is enabled via query string parameters', async () => {
|
|
@@ -141,7 +148,7 @@ describe('MiddlewareGroup: test errorHttpNoOutputResponseAfterHandler', () => {
|
|
|
141
148
|
);
|
|
142
149
|
});
|
|
143
150
|
|
|
144
|
-
it('should have
|
|
151
|
+
it('should have empty body even when enabled when configuration has is disabled', async () => {
|
|
145
152
|
app.debug = false;
|
|
146
153
|
|
|
147
154
|
const handler = {
|
|
@@ -158,11 +165,11 @@ describe('MiddlewareGroup: test errorHttpNoOutputResponseAfterHandler', () => {
|
|
|
158
165
|
error: new Error('Test validation error'),
|
|
159
166
|
});
|
|
160
167
|
expect(handler.response).toHaveProperty('statusCode', 200);
|
|
161
|
-
expect(handler.response).toHaveProperty('body',
|
|
168
|
+
expect(handler.response).toHaveProperty('body', '');
|
|
162
169
|
app.debug = true;
|
|
163
170
|
});
|
|
164
171
|
|
|
165
|
-
it('should
|
|
172
|
+
it('should have a response when allowResponse override is passed via options', async () => {
|
|
166
173
|
app.debug = false;
|
|
167
174
|
|
|
168
175
|
const handler = {
|
|
@@ -180,20 +187,15 @@ describe('MiddlewareGroup: test errorHttpNoOutputResponseAfterHandler', () => {
|
|
|
180
187
|
allowResponse: () => true,
|
|
181
188
|
});
|
|
182
189
|
expect(handler.response).toHaveProperty('statusCode', 500);
|
|
183
|
-
expect(handler.response).
|
|
184
|
-
'
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
_meta: {},
|
|
194
|
-
})
|
|
195
|
-
);
|
|
196
|
-
|
|
197
|
-
app.debug = false;
|
|
190
|
+
expect(JSON.parse(handler.response.body)).toStrictEqual({
|
|
191
|
+
status: 'error',
|
|
192
|
+
data: null,
|
|
193
|
+
error: {
|
|
194
|
+
code: 'UNHANDLED_ERROR',
|
|
195
|
+
message: 'Error: Test validation error',
|
|
196
|
+
details: '',
|
|
197
|
+
},
|
|
198
|
+
_meta: expect.anything(),
|
|
199
|
+
});
|
|
198
200
|
});
|
|
199
201
|
});
|
|
@@ -73,6 +73,19 @@ describe('MiddlewareGroup: test successHttpResponseHandler middleware', () => {
|
|
|
73
73
|
});
|
|
74
74
|
});
|
|
75
75
|
|
|
76
|
+
it('test with formatSuccess argument', async () => {
|
|
77
|
+
const data = await successHttpResponseHandler({
|
|
78
|
+
response: 'Some message',
|
|
79
|
+
formatSuccess: options => {
|
|
80
|
+
return options.response;
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
expect(data.statusCode).toBe(200);
|
|
85
|
+
|
|
86
|
+
expect(data.body).toBe('Some message');
|
|
87
|
+
});
|
|
88
|
+
|
|
76
89
|
it('test with configurable header', async () => {
|
|
77
90
|
const data = await successHttpResponseHandler({
|
|
78
91
|
response: 'Some message',
|
|
@@ -2,7 +2,6 @@ import config from 'Config/jwt'; // eslint-disable-line import/no-unresolved
|
|
|
2
2
|
import verifyJwtMiddleware, {
|
|
3
3
|
verifyJwtMiddlewareBeforeHandler,
|
|
4
4
|
} from '../verifyJwtMiddleware';
|
|
5
|
-
import LesgoException from '../../exceptions/LesgoException';
|
|
6
5
|
|
|
7
6
|
describe('MiddlewareGroup: test verifyJwtMiddleware middleware', () => {
|
|
8
7
|
const handler = {
|
|
@@ -28,17 +27,20 @@ describe('MiddlewareGroup: test verifyJwtMiddleware middleware', () => {
|
|
|
28
27
|
expect(result).toHaveProperty('before');
|
|
29
28
|
});
|
|
30
29
|
|
|
31
|
-
it('test without authorization header', () => {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
)
|
|
38
|
-
|
|
30
|
+
it('test without authorization header', async () => {
|
|
31
|
+
try {
|
|
32
|
+
expect(
|
|
33
|
+
await verifyJwtMiddlewareBeforeHandler(handler, () => {})
|
|
34
|
+
).toThrow();
|
|
35
|
+
} catch (e) {
|
|
36
|
+
expect(e.name).toEqual('LesgoException');
|
|
37
|
+
expect(e.message).toEqual('Authorization Header is required!');
|
|
38
|
+
expect(e.code).toEqual('JWT_MISSING_AUTHORIZATION_HEADER');
|
|
39
|
+
expect(e.statusCode).toEqual(403);
|
|
40
|
+
}
|
|
39
41
|
});
|
|
40
42
|
|
|
41
|
-
it('test with missing bearer token', () => {
|
|
43
|
+
it('test with missing bearer token', async () => {
|
|
42
44
|
const newHandler = {
|
|
43
45
|
event: {
|
|
44
46
|
...handler.event,
|
|
@@ -48,18 +50,19 @@ describe('MiddlewareGroup: test verifyJwtMiddleware middleware', () => {
|
|
|
48
50
|
},
|
|
49
51
|
};
|
|
50
52
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
)
|
|
59
|
-
|
|
53
|
+
try {
|
|
54
|
+
expect(
|
|
55
|
+
await verifyJwtMiddlewareBeforeHandler(newHandler, () => {})
|
|
56
|
+
).toThrow();
|
|
57
|
+
} catch (e) {
|
|
58
|
+
expect(e.name).toEqual('LesgoException');
|
|
59
|
+
expect(e.message).toEqual('Authorization Header is required!');
|
|
60
|
+
expect(e.code).toEqual('JWT_MISSING_AUTHORIZATION_HEADER');
|
|
61
|
+
expect(e.statusCode).toEqual(403);
|
|
62
|
+
}
|
|
60
63
|
});
|
|
61
64
|
|
|
62
|
-
it('test with invalid token', () => {
|
|
65
|
+
it('test with invalid token', async () => {
|
|
63
66
|
const newHandler = {
|
|
64
67
|
event: {
|
|
65
68
|
...handler.event,
|
|
@@ -69,18 +72,19 @@ describe('MiddlewareGroup: test verifyJwtMiddleware middleware', () => {
|
|
|
69
72
|
},
|
|
70
73
|
};
|
|
71
74
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
)
|
|
80
|
-
|
|
75
|
+
try {
|
|
76
|
+
expect(
|
|
77
|
+
await verifyJwtMiddlewareBeforeHandler(newHandler, () => {})
|
|
78
|
+
).toThrow();
|
|
79
|
+
} catch (e) {
|
|
80
|
+
expect(e.name).toEqual('LesgoException');
|
|
81
|
+
expect(e.message).toEqual('Missing Bearer token!');
|
|
82
|
+
expect(e.code).toEqual('JWT_MISSING_BEARER_TOKEN');
|
|
83
|
+
expect(e.statusCode).toEqual(403);
|
|
84
|
+
}
|
|
81
85
|
});
|
|
82
86
|
|
|
83
|
-
it('test with malformed token', () => {
|
|
87
|
+
it('test with malformed token', async () => {
|
|
84
88
|
const newHandler = {
|
|
85
89
|
event: {
|
|
86
90
|
...handler.event,
|
|
@@ -90,12 +94,19 @@ describe('MiddlewareGroup: test verifyJwtMiddleware middleware', () => {
|
|
|
90
94
|
},
|
|
91
95
|
};
|
|
92
96
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
97
|
+
try {
|
|
98
|
+
expect(
|
|
99
|
+
await verifyJwtMiddlewareBeforeHandler(newHandler, () => {})
|
|
100
|
+
).toThrow();
|
|
101
|
+
} catch (e) {
|
|
102
|
+
expect(e.name).toEqual('LesgoException');
|
|
103
|
+
expect(e.message).toEqual('jwt malformed');
|
|
104
|
+
expect(e.code).toEqual('JWT_ERROR');
|
|
105
|
+
expect(e.statusCode).toEqual(403);
|
|
106
|
+
}
|
|
96
107
|
});
|
|
97
108
|
|
|
98
|
-
it('test with incorrect secret key', () => {
|
|
109
|
+
it('test with incorrect secret key', async () => {
|
|
99
110
|
const newHandler = {
|
|
100
111
|
event: {
|
|
101
112
|
...handler.event,
|
|
@@ -106,12 +117,19 @@ describe('MiddlewareGroup: test verifyJwtMiddleware middleware', () => {
|
|
|
106
117
|
},
|
|
107
118
|
};
|
|
108
119
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
120
|
+
try {
|
|
121
|
+
expect(
|
|
122
|
+
await verifyJwtMiddlewareBeforeHandler(newHandler, () => {})
|
|
123
|
+
).toThrow();
|
|
124
|
+
} catch (e) {
|
|
125
|
+
expect(e.name).toEqual('LesgoException');
|
|
126
|
+
expect(e.message).toEqual('invalid signature');
|
|
127
|
+
expect(e.code).toEqual('JWT_ERROR');
|
|
128
|
+
expect(e.statusCode).toEqual(403);
|
|
129
|
+
}
|
|
112
130
|
});
|
|
113
131
|
|
|
114
|
-
it('test with invalid ISS', () => {
|
|
132
|
+
it('test with invalid ISS', async () => {
|
|
115
133
|
const newHandler = {
|
|
116
134
|
event: {
|
|
117
135
|
...handler.event,
|
|
@@ -122,18 +140,19 @@ describe('MiddlewareGroup: test verifyJwtMiddleware middleware', () => {
|
|
|
122
140
|
},
|
|
123
141
|
};
|
|
124
142
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
)
|
|
133
|
-
|
|
143
|
+
try {
|
|
144
|
+
expect(
|
|
145
|
+
await verifyJwtMiddlewareBeforeHandler(newHandler, () => {})
|
|
146
|
+
).toThrow();
|
|
147
|
+
} catch (e) {
|
|
148
|
+
expect(e.name).toEqual('LesgoException');
|
|
149
|
+
expect(e.message).toEqual("Token's [iss] is not valid!");
|
|
150
|
+
expect(e.code).toEqual('JWT_ISS_NOT_VALID');
|
|
151
|
+
expect(e.statusCode).toEqual(403);
|
|
152
|
+
}
|
|
134
153
|
});
|
|
135
154
|
|
|
136
|
-
it('test with missing custom claim', () => {
|
|
155
|
+
it('test with missing custom claim', async () => {
|
|
137
156
|
const newHandler = {
|
|
138
157
|
event: {
|
|
139
158
|
...handler.event,
|
|
@@ -144,18 +163,21 @@ describe('MiddlewareGroup: test verifyJwtMiddleware middleware', () => {
|
|
|
144
163
|
},
|
|
145
164
|
};
|
|
146
165
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
166
|
+
try {
|
|
167
|
+
expect(
|
|
168
|
+
await verifyJwtMiddlewareBeforeHandler(newHandler, () => {})
|
|
169
|
+
).toThrow();
|
|
170
|
+
} catch (e) {
|
|
171
|
+
expect(e.name).toEqual('LesgoException');
|
|
172
|
+
expect(e.message).toEqual(
|
|
173
|
+
`Token's custom claim [${config.customClaims.data[0]}] not found!`
|
|
174
|
+
);
|
|
175
|
+
expect(e.code).toEqual('JWT_CUSTOM_CLAIM_NOT_FOUND');
|
|
176
|
+
expect(e.statusCode).toEqual(403);
|
|
177
|
+
}
|
|
156
178
|
});
|
|
157
179
|
|
|
158
|
-
it('test with expired token', () => {
|
|
180
|
+
it('test with expired token', async () => {
|
|
159
181
|
const newHandler = {
|
|
160
182
|
event: {
|
|
161
183
|
...handler.event,
|
|
@@ -166,12 +188,19 @@ describe('MiddlewareGroup: test verifyJwtMiddleware middleware', () => {
|
|
|
166
188
|
},
|
|
167
189
|
};
|
|
168
190
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
191
|
+
try {
|
|
192
|
+
expect(
|
|
193
|
+
await verifyJwtMiddlewareBeforeHandler(newHandler, () => {})
|
|
194
|
+
).toThrow();
|
|
195
|
+
} catch (e) {
|
|
196
|
+
expect(e.name).toEqual('LesgoException');
|
|
197
|
+
expect(e.message).toEqual('jwt expired');
|
|
198
|
+
expect(e.code).toEqual('JWT_EXPIRED');
|
|
199
|
+
expect(e.statusCode).toEqual(403);
|
|
200
|
+
}
|
|
172
201
|
});
|
|
173
202
|
|
|
174
|
-
it('test with valid token', () => {
|
|
203
|
+
it('test with valid token', async () => {
|
|
175
204
|
const newHandler = {
|
|
176
205
|
event: {
|
|
177
206
|
...handler.event,
|
|
@@ -182,14 +211,60 @@ describe('MiddlewareGroup: test verifyJwtMiddleware middleware', () => {
|
|
|
182
211
|
},
|
|
183
212
|
};
|
|
184
213
|
|
|
185
|
-
verifyJwtMiddlewareBeforeHandler(newHandler, () => {});
|
|
214
|
+
await verifyJwtMiddlewareBeforeHandler(newHandler, () => {});
|
|
186
215
|
expect(newHandler.event.decodedJwt).toMatchObject({
|
|
187
216
|
sub: '1234567890',
|
|
188
217
|
iss: config.iss.data[0],
|
|
189
218
|
});
|
|
190
219
|
});
|
|
191
220
|
|
|
192
|
-
it('test with
|
|
221
|
+
it('test with secret as a function argument', async () => {
|
|
222
|
+
const { secret } = config;
|
|
223
|
+
config.secret = secretHandler => {
|
|
224
|
+
return `111${secretHandler.key}`;
|
|
225
|
+
};
|
|
226
|
+
const newHandler = {
|
|
227
|
+
key: '1',
|
|
228
|
+
event: {
|
|
229
|
+
...handler.event,
|
|
230
|
+
headers: {
|
|
231
|
+
Authorization:
|
|
232
|
+
'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJpc3MiOiJkb21haW4uY29tIiwiZGVwYXJ0bWVudF9pZCI6MX0.7RdbXJhzrn_yV7CPqkuX0Yvtms0xaIw1q4LPe8O0BDY',
|
|
233
|
+
},
|
|
234
|
+
},
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
await verifyJwtMiddlewareBeforeHandler(newHandler, () => {});
|
|
238
|
+
expect(newHandler.event.decodedJwt).toMatchObject({
|
|
239
|
+
sub: '1234567890',
|
|
240
|
+
iss: config.iss.data[0],
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
config.secret = secret;
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
it('test with callback argument', async () => {
|
|
247
|
+
const callback = jest.fn();
|
|
248
|
+
config.callback = callback;
|
|
249
|
+
const newHandler = {
|
|
250
|
+
event: {
|
|
251
|
+
...handler.event,
|
|
252
|
+
headers: {
|
|
253
|
+
Authorization:
|
|
254
|
+
'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJpc3MiOiJkb21haW4uY29tIiwiZGVwYXJ0bWVudF9pZCI6MX0.pa2TBRqdVSFUhmiglB8SD8ImthqhqZBn0stAdNRcJ3w',
|
|
255
|
+
},
|
|
256
|
+
},
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
await verifyJwtMiddlewareBeforeHandler(newHandler, () => {});
|
|
260
|
+
expect(newHandler.event.decodedJwt).toMatchObject({
|
|
261
|
+
sub: '1234567890',
|
|
262
|
+
iss: config.iss.data[0],
|
|
263
|
+
});
|
|
264
|
+
expect(callback).toHaveBeenCalledWith(newHandler);
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
it('test with custom config', async () => {
|
|
193
268
|
const newHandler = {
|
|
194
269
|
event: {
|
|
195
270
|
...handler.event,
|
|
@@ -200,7 +275,7 @@ describe('MiddlewareGroup: test verifyJwtMiddleware middleware', () => {
|
|
|
200
275
|
},
|
|
201
276
|
};
|
|
202
277
|
|
|
203
|
-
verifyJwtMiddlewareBeforeHandler(newHandler, () => {}, {
|
|
278
|
+
await verifyJwtMiddlewareBeforeHandler(newHandler, () => {}, {
|
|
204
279
|
jwtConfig: {
|
|
205
280
|
secret:
|
|
206
281
|
'c4156b94c80b7f163feabd4ff268c99eb11ce8995df370a4fd872afb4377b273',
|
|
@@ -1,50 +1,19 @@
|
|
|
1
1
|
import client from 'Config/client'; // eslint-disable-line import/no-unresolved
|
|
2
|
-
import crypto from 'crypto';
|
|
3
2
|
import LesgoException from '../exceptions/LesgoException';
|
|
4
|
-
import { errorHttpResponseAfterHandler } from './errorHttpResponseMiddleware';
|
|
5
3
|
|
|
6
4
|
const FILE = 'Middlewares/basicAuthMiddleware';
|
|
7
5
|
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
return crypto
|
|
18
|
-
.createHash('sha1')
|
|
19
|
-
.update(`${key}:${secret}`)
|
|
20
|
-
.digest('hex');
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
const getSiteId = event => {
|
|
24
|
-
let siteId;
|
|
25
|
-
|
|
26
|
-
if (event.site && event.site.id) {
|
|
27
|
-
siteId = event.site.id;
|
|
28
|
-
} else if (
|
|
29
|
-
event.requestContext &&
|
|
30
|
-
event.requestContext.site &&
|
|
31
|
-
event.requestContext.site.id
|
|
32
|
-
) {
|
|
33
|
-
siteId = event.requestContext.site.id;
|
|
34
|
-
} else if (event.platform) {
|
|
35
|
-
siteId = event.platform;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
if (typeof siteId === 'undefined') {
|
|
39
|
-
throw new LesgoException(
|
|
40
|
-
'Site ID could not be found',
|
|
41
|
-
`${FILE}::SITE_ID_NOT_FOUND`,
|
|
42
|
-
403,
|
|
43
|
-
'Ensure that clientAuthMiddleware() is called before this Middleware'
|
|
44
|
-
);
|
|
45
|
-
}
|
|
6
|
+
export const generateBasicAuthorizationHash = (key, secret, opts = {}) => {
|
|
7
|
+
const { getPreHashString } = {
|
|
8
|
+
...client,
|
|
9
|
+
...opts,
|
|
10
|
+
};
|
|
11
|
+
const preHashString =
|
|
12
|
+
typeof getPreHashString === 'function'
|
|
13
|
+
? getPreHashString(key, secret)
|
|
14
|
+
: `${key}:${secret}`;
|
|
46
15
|
|
|
47
|
-
return
|
|
16
|
+
return Buffer.from(preHashString).toString('base64');
|
|
48
17
|
};
|
|
49
18
|
|
|
50
19
|
const getClient = opts => {
|
|
@@ -52,22 +21,13 @@ const getClient = opts => {
|
|
|
52
21
|
return opts.client;
|
|
53
22
|
}
|
|
54
23
|
|
|
55
|
-
return client;
|
|
24
|
+
return client.clients;
|
|
56
25
|
};
|
|
57
26
|
|
|
58
|
-
const getHashFromHeaders =
|
|
27
|
+
const getHashFromHeaders = headers => {
|
|
59
28
|
const basicAuth = headers.Authorization || headers.authorization;
|
|
60
29
|
|
|
61
30
|
if (typeof basicAuth === 'undefined') {
|
|
62
|
-
if (blacklistMode(opts)) {
|
|
63
|
-
throw new LesgoException(
|
|
64
|
-
'Authorization header not found',
|
|
65
|
-
`${FILE}::AUTHORIZATION_HEADER_NOT_FOUND`,
|
|
66
|
-
403,
|
|
67
|
-
'Ensure you are have provided the basic authentication code using Authorization header'
|
|
68
|
-
);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
31
|
return '';
|
|
72
32
|
}
|
|
73
33
|
|
|
@@ -97,23 +57,22 @@ const getHashFromHeaders = (headers, opts) => {
|
|
|
97
57
|
);
|
|
98
58
|
}
|
|
99
59
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
return buff.toString('utf-8');
|
|
60
|
+
return authEncoded;
|
|
103
61
|
};
|
|
104
62
|
|
|
105
|
-
const validateBasicAuth = (hash,
|
|
63
|
+
const validateBasicAuth = (hash, clientObject, opts, siteId = undefined) => {
|
|
106
64
|
const site = Object.keys(clientObject).find(clientCode => {
|
|
107
65
|
const hashIsEquals =
|
|
108
66
|
generateBasicAuthorizationHash(
|
|
109
67
|
clientObject[clientCode].key,
|
|
110
|
-
clientObject[clientCode].secret
|
|
68
|
+
clientObject[clientCode].secret,
|
|
69
|
+
opts
|
|
111
70
|
) === hash;
|
|
112
71
|
|
|
113
|
-
return siteId === clientCode && hashIsEquals;
|
|
72
|
+
return siteId ? siteId === clientCode && hashIsEquals : hashIsEquals;
|
|
114
73
|
});
|
|
115
74
|
|
|
116
|
-
if (!site
|
|
75
|
+
if (!site) {
|
|
117
76
|
throw new LesgoException(
|
|
118
77
|
'Invalid client key or secret provided',
|
|
119
78
|
`${FILE}::AUTH_INVALID_CLIENT_OR_SECRET_KEY`,
|
|
@@ -123,12 +82,34 @@ const validateBasicAuth = (hash, siteId, clientObject, opts) => {
|
|
|
123
82
|
}
|
|
124
83
|
};
|
|
125
84
|
|
|
126
|
-
export const verifyBasicAuthBeforeHandler = (handler, next, opts) => {
|
|
127
|
-
const
|
|
85
|
+
export const verifyBasicAuthBeforeHandler = async (handler, next, opts) => {
|
|
86
|
+
const { headers, platform } = handler.event;
|
|
128
87
|
const finalClient = getClient(opts);
|
|
129
|
-
const hashFromHeader = getHashFromHeaders(
|
|
88
|
+
const hashFromHeader = getHashFromHeaders(headers);
|
|
89
|
+
let isAuthOptional = platform ? platform.isAuthOptional : false;
|
|
90
|
+
if (isAuthOptional && typeof isAuthOptional.then === 'function') {
|
|
91
|
+
isAuthOptional = await isAuthOptional;
|
|
92
|
+
}
|
|
130
93
|
|
|
131
|
-
|
|
94
|
+
if (hashFromHeader) {
|
|
95
|
+
validateBasicAuth(
|
|
96
|
+
hashFromHeader,
|
|
97
|
+
finalClient,
|
|
98
|
+
opts,
|
|
99
|
+
platform ? platform.id : undefined
|
|
100
|
+
);
|
|
101
|
+
} else if (!platform || !isAuthOptional) {
|
|
102
|
+
/**
|
|
103
|
+
* An error will occur only when either the platform could not be determined, assuming a basic auth is needed.
|
|
104
|
+
* Or whenever the platform could be determined, but `isAuthOptional` is not true for that platform
|
|
105
|
+
*/
|
|
106
|
+
throw new LesgoException(
|
|
107
|
+
'Authorization header not found',
|
|
108
|
+
`${FILE}::AUTHORIZATION_HEADER_NOT_FOUND`,
|
|
109
|
+
403,
|
|
110
|
+
'Ensure you are have provided the basic authentication code using Authorization header'
|
|
111
|
+
);
|
|
112
|
+
}
|
|
132
113
|
|
|
133
114
|
next();
|
|
134
115
|
};
|
|
@@ -138,7 +119,6 @@ const basicAuthMiddleware = opts => {
|
|
|
138
119
|
return {
|
|
139
120
|
before: (handler, next) =>
|
|
140
121
|
verifyBasicAuthBeforeHandler(handler, next, opts),
|
|
141
|
-
onError: (handler, next) => errorHttpResponseAfterHandler(handler, next),
|
|
142
122
|
};
|
|
143
123
|
};
|
|
144
124
|
|