@azteam/express 1.2.150 → 1.2.151
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
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 {
|
|
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({
|
|
144
|
-
app.use(bodyParser.json({
|
|
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
|
-
|
|
184
|
-
|
|
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
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
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
|
-
|
|
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
|
-
'
|
|
204
|
-
'
|
|
205
|
-
'
|
|
206
|
-
'
|
|
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
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
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.ttl);
|
|
245
|
+
}
|
|
242
246
|
|
|
243
|
-
|
|
244
|
-
|
|
247
|
+
return this.json(resData);
|
|
248
|
+
};
|
|
245
249
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
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
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
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 {
|
|
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({
|
|
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
|
-
|
|
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
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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,17 @@
|
|
|
1
|
-
export default function(key) {
|
|
1
|
+
export default function(key, ttl = 5) {
|
|
2
2
|
return async function(req, res, next) {
|
|
3
|
-
|
|
4
|
-
const {redis} = req;
|
|
5
|
-
|
|
3
|
+
const {redis} = req;
|
|
6
4
|
if (redis) {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
5
|
+
const cacheData = await redis.get(key);
|
|
6
|
+
if (cacheData) {
|
|
7
|
+
return res.json(cacheData);
|
|
8
|
+
} else {
|
|
9
|
+
res.cache = {
|
|
10
|
+
key,
|
|
11
|
+
ttl
|
|
12
|
+
};
|
|
13
|
+
}
|
|
12
14
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
15
|
return next();
|
|
16
|
-
}
|
|
17
|
-
}
|
|
16
|
+
};
|
|
17
|
+
}
|
package/src/middleware/index.js
CHANGED
|
@@ -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
|
-
|
|
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
|
+
}
|