@azteam/express 1.2.150 → 1.2.153

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@azteam/express",
3
- "version": "1.2.150",
3
+ "version": "1.2.153",
4
4
  "description": "",
5
5
  "main": "src/index.js",
6
6
  "repository": {
@@ -26,8 +26,6 @@
26
26
  "@azteam/crypto": "latest",
27
27
  "@azteam/error": "latest",
28
28
  "@azteam/http-client": "latest",
29
- "@azteam/rabbitmq-async": "latest",
30
- "@azteam/redis-async": "latest",
31
29
  "@grpc/grpc-js": "1.6.7",
32
30
  "@grpc/proto-loader": "0.6.12",
33
31
  "body-parser": "1.19.0",
@@ -41,6 +39,7 @@
41
39
  "fastest-validator": "1.8.0",
42
40
  "helmet": "3.21.2",
43
41
  "jsonwebtoken": "8.2.1",
42
+ "lodash": "4.17.21",
44
43
  "method-override": "3.0.0",
45
44
  "morgan": "1.10.0",
46
45
  "socket.io": "4.4.1",
package/src/Server.js CHANGED
@@ -10,7 +10,7 @@ import morgan from 'morgan';
10
10
  import cors from 'cors';
11
11
  import _ from 'lodash';
12
12
  import 'express-async-errors';
13
- import { errorCatch, ErrorException, NOT_FOUND, UNKNOWN } from '@azteam/error';
13
+ import {errorCatch, ErrorException, NOT_FOUND, UNKNOWN} from '@azteam/error';
14
14
 
15
15
 
16
16
  const RES_TYPE = {
@@ -65,10 +65,12 @@ class Server {
65
65
 
66
66
  setMessageQueue(messageQueue) {
67
67
  this.messageQueue = messageQueue;
68
+ return this;
68
69
  }
69
70
 
70
71
  setRedis(redis) {
71
72
  this.redis = redis;
73
+ return this;
72
74
  }
73
75
 
74
76
  setCookieOptions(cookieOptions) {
@@ -128,6 +130,7 @@ class Server {
128
130
 
129
131
 
130
132
  startAPI(port) {
133
+
131
134
  if (!_.isEmpty(this.controllers)) {
132
135
 
133
136
  const WHITE_LIST = this.whiteList;
@@ -140,8 +143,8 @@ class Server {
140
143
  }));
141
144
 
142
145
  app.use(methodOverride());
143
- app.use(bodyParser.urlencoded({ limit: '5mb', extended: true }));
144
- app.use(bodyParser.json({ limit: '5mb' }));
146
+ app.use(bodyParser.urlencoded({limit: '5mb', extended: true}));
147
+ app.use(bodyParser.json({limit: '5mb'}));
145
148
 
146
149
  app.set('trust proxy', 1);
147
150
 
@@ -171,96 +174,108 @@ class Server {
171
174
  });
172
175
  app.get('/favicon.ico', (req, res) => res.status(204).json({}));
173
176
 
174
- app.use(async function(req, res, next) {
175
- req.trackDevice = {
176
- ip: req.ip,
177
- device: req.get('X-DEVICE') || req.get('User-Agent'),
178
- device_id: req.get('X-DEVICE-ID') || 'web',
179
- os: req.get('X-OS') || 'web'
180
- };
181
177
 
178
+ const {redis} = this;
182
179
 
183
- res.error = function(code, errors = []) {
184
- throw new ErrorException(code, errors);
185
- };
180
+ if (redis) {
181
+ app.request.redis = redis;
182
+ app.response.redis = redis;
183
+ }
184
+
185
+
186
+ app.response.error = function(code, errors = []) {
187
+ throw new ErrorException(code, errors);
188
+ };
186
189
 
187
- res.success = function(data = {}, guard = [], allows = []) {
188
- let guardData = data;
189
- if (data) {
190
- let resType = null;
191
- if (_.isArray(data)) {
192
- resType = RES_TYPE.ARRAY;
193
- } else if (_.isObject(data)) {
194
- resType = RES_TYPE.OBJECT;
195
- if (data.docs) {
196
- resType = RES_TYPE.DOCS;
197
- }
190
+ app.response.success = function(data = {}, guard = [], allows = []) {
191
+
192
+ let guardData = data;
193
+ if (data) {
194
+ let resType = null;
195
+ if (_.isArray(data)) {
196
+ resType = RES_TYPE.ARRAY;
197
+ } else if (_.isObject(data)) {
198
+ resType = RES_TYPE.OBJECT;
199
+ if (data.docs) {
200
+ resType = RES_TYPE.DOCS;
198
201
  }
202
+ }
199
203
 
200
- if (_.isArray(guard)) {
204
+ if (_.isArray(guard)) {
205
+ guard = [
206
+ ...guard,
207
+ '__v',
208
+ '_id',
209
+ 'deleted_at',
210
+ 'updated_at',
211
+ 'created_id',
212
+ 'modified_id'
213
+ ];
214
+ if (resType === RES_TYPE.ARRAY || resType === RES_TYPE.DOCS) {
201
215
  guard = [
202
216
  ...guard,
203
- '__v',
204
- '_id',
205
- 'deleted_at',
206
- 'updated_at',
207
- 'created_id',
208
- 'modified_id'
217
+ 'metadata_disable',
218
+ 'metadata_keywords',
219
+ 'metadata_description',
220
+ 'metadata_image_url'
209
221
  ];
210
- if (resType === RES_TYPE.ARRAY || resType === RES_TYPE.DOCS) {
211
- guard = [
212
- ...guard,
213
- 'metadata_disable',
214
- 'metadata_keywords',
215
- 'metadata_description',
216
- 'metadata_image_url'
217
- ];
218
- }
219
222
  }
220
- if (resType === RES_TYPE.DOCS) {
221
- guardData.docs = _.map(data.docs, item => {
222
- return omitItem(item, guard, allows);
223
- });
224
- } else if (resType === RES_TYPE.ARRAY) {
225
- guardData = _.map(data, item => {
226
- return omitItem(item, guard, allows);
227
- });
228
- } else if (resType === RES_TYPE.OBJECT) {
229
- guardData = omitItem(data, guard, allows);
230
- }
231
-
232
-
233
223
  }
224
+ if (resType === RES_TYPE.DOCS) {
225
+ guardData.docs = _.map(data.docs, item => {
226
+ return omitItem(item, guard, allows);
227
+ });
228
+ } else if (resType === RES_TYPE.ARRAY) {
229
+ guardData = _.map(data, item => {
230
+ return omitItem(item, guard, allows);
231
+ });
232
+ } else if (resType === RES_TYPE.OBJECT) {
233
+ guardData = omitItem(data, guard, allows);
234
+ }
235
+ }
234
236
 
235
- const resData = {
236
- success: true,
237
- data: guardData,
238
- options: req.resOptions
239
- };
240
-
237
+ const resData = {
238
+ success: true,
239
+ data: guardData,
240
+ options: this.resOptions
241
+ };
241
242
 
243
+ if (this.redis && this.cache) {
244
+ this.redis.set(this.cache.key, resData, this.cache.ttl);
245
+ }
242
246
 
243
- return res.json(resData);
244
- };
247
+ return this.json(resData);
248
+ };
245
249
 
246
- res.cleanCookie = function(data) {
247
- _.map(data, (name) => {
248
- res.clearCookie(name, {
249
- domain: COOKIE_OPTIONS.domain
250
- });
250
+ app.response.cleanCookie = function(data) {
251
+ _.map(data, (name) => {
252
+ this.clearCookie(name, {
253
+ domain: COOKIE_OPTIONS.domain
251
254
  });
252
- };
253
-
254
- res.addCookie = function(data) {
255
- _.map(data, (value, key) => {
256
- const maxAge = 86400000 * 365; // 1 year
257
- res.cookie(key, value, {
258
- ...COOKIE_OPTIONS,
259
- maxAge,
260
- expires: new Date(Date.now() + maxAge)
261
- });
255
+ });
256
+ };
257
+
258
+ app.response.addCookie = function(data) {
259
+ _.map(data, (value, key) => {
260
+ const maxAge = 86400000 * 365; // 1 year
261
+ this.cookie(key, value, {
262
+ ...COOKIE_OPTIONS,
263
+ maxAge,
264
+ expires: new Date(Date.now() + maxAge)
262
265
  });
266
+ });
267
+ };
268
+
269
+ app.use(async function(req, res, next) {
270
+ delete res.cache;
271
+
272
+ req.trackDevice = {
273
+ ip: req.ip,
274
+ device: req.get('X-DEVICE') || req.get('User-Agent'),
275
+ device_id: req.get('X-DEVICE-ID') || 'web',
276
+ os: req.get('X-OS') || 'web'
263
277
  };
278
+
264
279
  next();
265
280
  });
266
281
 
@@ -277,7 +292,7 @@ class Server {
277
292
  const listPublicRouter = controller.publicRouter();
278
293
 
279
294
  _.map(listPublicRouter, (method) => {
280
- const { name, type } = method;
295
+ const {name, type} = method;
281
296
 
282
297
  const router = controller[name]();
283
298
 
@@ -318,7 +333,7 @@ class Server {
318
333
  this.callbackError(error);
319
334
  }
320
335
 
321
- return res.status(error.status).json({ success: false, errors: error.errors });
336
+ return res.status(error.status).json({success: false, errors: error.errors});
322
337
  });
323
338
 
324
339
  const server = http.Server(app);
@@ -383,4 +398,4 @@ class Server {
383
398
  }
384
399
  }
385
400
 
386
- export default Server;
401
+ export default Server;
@@ -1,12 +1,64 @@
1
- export default function(mTimeout = 5) {
1
+ import { ErrorException } from '@azteam/error';
2
+ import jwt from 'jsonwebtoken';
3
+
4
+ function systemLogin(userData = null) {
5
+ let user = {};
6
+ if (userData) {
7
+ try {
8
+ user = JSON.parse(userData);
9
+ } catch (e) {}
10
+ }
11
+ return user;
12
+ }
13
+
14
+ export default function(cbRefreshToken, cbLoginAPI) {
2
15
  return async function(req, res, next) {
3
- if (req.method === 'GET') {
4
- const etag_hash = etag(req.url + floorToMinute(Math.floor(Date.now() / 1000), mTimeout));
5
- if (req.headers['if-none-match'] === etag_hash) {
6
- return res.status(304).send();
16
+
17
+ const { headers, signedCookies } = req;
18
+
19
+ if (headers['x-app-secret'] === process.env.SECRET_KEY) {
20
+ req.user = systemLogin(headers['x-app-user']);
21
+ } else {
22
+ let token = signedCookies.access_token;
23
+
24
+ if (headers.authorization && signedCookies.api_key != headers.authorization) {
25
+ token = headers.authorization;
26
+ }
27
+
28
+ if (token) {
29
+ token = token.replace('Bearer ', '');
30
+ return jwt.verify(token, process.env.SECRET_KEY, async (error, jwtData) => {
31
+ if (error) {
32
+ try {
33
+ let data = null;
34
+ if (error.name === 'TokenExpiredError') {
35
+ if (signedCookies.refresh_token) {
36
+ data = await cbRefreshToken(signedCookies.refresh_token);
37
+ } else if (signedCookies.api_key) {
38
+ data = await cbLoginAPI(signedCookies.api_key);
39
+ }
40
+ } else if (error.name === 'JsonWebTokenError') {
41
+ data = await cbLoginAPI(token);
42
+ }
43
+ if (data) {
44
+ jwtData = jwt.decode(data.access_token);
45
+ res.addCookie({
46
+ 'access_token': data.access_token
47
+ });
48
+ res.set('Auth-Token', data.access_token);
49
+ }
50
+ } catch (e) {}
51
+ }
52
+ if (jwtData) {
53
+ req.user = jwtData;
54
+ }
55
+ return next();
56
+ });
7
57
  }
8
- res.setHeader('ETag', etag_hash);
9
58
  }
59
+
60
+
10
61
  return next();
11
- }
62
+ };
63
+
12
64
  }
@@ -1,17 +1,37 @@
1
- export default function(key) {
2
- return async function(req, res, next) {
3
-
4
- const {redis} = req;
1
+ import _ from 'lodash';
2
+ import qs from 'querystring';
5
3
 
4
+ export default function(key, options = {}) {
5
+ options = {
6
+ ttl: 300,
7
+ limitPage: 5,
8
+ ...options
9
+ };
10
+ return async function(req, res, next) {
11
+ const {redis} = req;
6
12
  if (redis) {
13
+ let cacheKey = key;
7
14
 
8
- if(res.get(key)){
9
-
10
- }
11
-
15
+ if (options.query) {
16
+ cacheKey += `${cacheKey}:${_.get(req, options.query)}`;
17
+ }
18
+ if (req.paginate) {
19
+ if (_.isEmpty(req.query) && req.paginate.page <= options.limitPage) {
20
+ cacheKey = `${cacheKey}:${qs.stringify(req.paginate)}`;
21
+ } else {
22
+ return next();
23
+ }
24
+ }
25
+ const cacheData = await redis.get(cacheKey);
26
+ if (cacheData) {
27
+ return res.json(cacheData);
28
+ } else {
29
+ res.cache = {
30
+ key: cacheKey,
31
+ ttl: options.ttl
32
+ };
33
+ }
12
34
  }
13
-
14
-
15
35
  return next();
16
- }
17
- }
36
+ };
37
+ }
@@ -5,4 +5,5 @@ export {default as roleMiddleware} from './roleMiddleware';
5
5
  export {default as paginateMiddleware} from './paginateMiddleware';
6
6
  export {default as validateMiddleware} from './validateMiddleware';
7
7
  export {default as limitRequestMiddleware} from './limitRequestMiddleware';
8
+ export {default as cacheMiddleware} from './cacheMiddleware';
8
9
 
@@ -36,7 +36,7 @@ export default function(options = {}) {
36
36
  return async function(req, res, next) {
37
37
  req.query = omitData(req.query);
38
38
 
39
- req.resOptions = options;
39
+ res.resOptions = options;
40
40
  req.paginate = {
41
41
  limit: options.limit
42
42
  };
@@ -71,14 +71,14 @@ export default function(options = {}) {
71
71
  req.query[newKey] = {
72
72
  ...req.query[newKey],
73
73
  $gte: value
74
- }
74
+ };
75
75
  } else if (key.endsWith('_end')) {
76
76
  const newKey = key.replace('_end', '');
77
77
 
78
78
  req.query[newKey] = {
79
79
  ...req.query[newKey],
80
80
  $lt: value
81
- }
81
+ };
82
82
  }
83
83
 
84
84
 
@@ -102,5 +102,5 @@ export default function(options = {}) {
102
102
  }
103
103
 
104
104
  return next();
105
- }
106
- }
105
+ };
106
+ }