ti2 1.0.27 → 1.0.30
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/auth/authHandler.js +65 -25
- package/index.js +7 -2
- package/package.json +1 -1
package/auth/authHandler.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
const jsonwebtoken = require('jsonwebtoken');
|
|
2
2
|
const Promise = require('bluebird');
|
|
3
|
-
const assert = require('assert');
|
|
4
3
|
|
|
5
4
|
const sqldb = require('../models');
|
|
6
5
|
|
|
@@ -12,7 +11,8 @@ const {
|
|
|
12
11
|
},
|
|
13
12
|
} = process;
|
|
14
13
|
|
|
15
|
-
const invalid =
|
|
14
|
+
const invalid = (res, msg) => res.status(401).json({ error: msg || 'Unauthorized' });
|
|
15
|
+
|
|
16
16
|
const getToken = ({ req }) => {
|
|
17
17
|
if (
|
|
18
18
|
!req.header('Authorization')
|
|
@@ -20,61 +20,101 @@ const getToken = ({ req }) => {
|
|
|
20
20
|
) return null;
|
|
21
21
|
return req.header('Authorization').split(' ')[1];
|
|
22
22
|
};
|
|
23
|
+
|
|
23
24
|
// the authentication middleware
|
|
24
|
-
const
|
|
25
|
-
if (!req.pathParams || !req.pathParams.app)
|
|
25
|
+
const appCheck = async req => {
|
|
26
|
+
if (!req.pathParams || !req.pathParams.app) {
|
|
27
|
+
return 'App parameters not found';
|
|
28
|
+
}
|
|
26
29
|
const token = getToken({ req });
|
|
27
|
-
if (!token) return
|
|
28
|
-
// try {
|
|
30
|
+
if (!token) return 'Api key not found';
|
|
29
31
|
const appRecord = await sqldb.Integration.findOne({
|
|
30
32
|
where: {
|
|
31
33
|
name: req.pathParams.app,
|
|
32
34
|
},
|
|
33
35
|
});
|
|
34
|
-
if (!appRecord) return
|
|
36
|
+
if (!appRecord) return 'App not found';
|
|
35
37
|
if (appRecord.apiKey !== token) {
|
|
36
|
-
return
|
|
38
|
+
return 'Invalid api key';
|
|
37
39
|
}
|
|
38
40
|
req.appRecord = appRecord.dataValues;
|
|
41
|
+
return undefined;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const app = async (req, res, next) => {
|
|
45
|
+
const error = await appCheck(req);
|
|
46
|
+
if (error) {
|
|
47
|
+
return invalid(res, error);
|
|
48
|
+
}
|
|
39
49
|
return next();
|
|
40
50
|
};
|
|
41
51
|
|
|
42
52
|
// The requester is an admin; createApps and other admin tasks
|
|
43
|
-
const
|
|
53
|
+
const adminCheck = async req => {
|
|
44
54
|
const token = getToken({ req });
|
|
45
|
-
if (token !== adminKey) return
|
|
55
|
+
if (token !== adminKey) return 'Invalid admin key';
|
|
56
|
+
return undefined;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const admin = async (req, res, next) => {
|
|
60
|
+
const error = await adminCheck(req);
|
|
61
|
+
if (error) {
|
|
62
|
+
return invalid(res, error);
|
|
63
|
+
}
|
|
46
64
|
return next();
|
|
47
65
|
};
|
|
48
66
|
|
|
49
67
|
// the request is from a user, checke the userId agains the url param
|
|
50
|
-
const
|
|
68
|
+
const userCheck = async req => {
|
|
51
69
|
const token = getToken({ req });
|
|
52
|
-
if (!token) return
|
|
70
|
+
if (!token) return 'Token not found';
|
|
71
|
+
let userId;
|
|
53
72
|
try {
|
|
54
|
-
|
|
55
|
-
assert(userId);
|
|
56
|
-
if (req.params.userId && userId !== req.params.userId) return invalid(next);
|
|
73
|
+
({ userId } = jsonwebtoken.verify(token, jwtSecret));
|
|
57
74
|
} catch (err) {
|
|
58
|
-
return
|
|
75
|
+
return 'Invalid token';
|
|
76
|
+
}
|
|
77
|
+
if (!userId) return 'UserId not found';
|
|
78
|
+
if (req.params.userId && userId !== req.params.userId) {
|
|
79
|
+
return 'Non matching user id';
|
|
80
|
+
}
|
|
81
|
+
return undefined;
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const user = async (req, res, next) => {
|
|
85
|
+
const error = await userCheck(req);
|
|
86
|
+
if (error) {
|
|
87
|
+
return invalid(res, error);
|
|
59
88
|
}
|
|
60
89
|
return next();
|
|
61
90
|
};
|
|
62
91
|
|
|
63
92
|
// The requester comes from frontend; frontend driven tasks
|
|
64
|
-
const
|
|
93
|
+
const frontendCheck = async req => {
|
|
65
94
|
const token = getToken({ req });
|
|
66
|
-
if (token !== frontendKey)
|
|
95
|
+
if (token !== frontendKey) {
|
|
96
|
+
return 'Invalid frontend token';
|
|
97
|
+
}
|
|
98
|
+
return undefined;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
const frontend = async (req, res, next) => {
|
|
102
|
+
const error = await frontendCheck(req);
|
|
103
|
+
if (error) {
|
|
104
|
+
return invalid(res, error);
|
|
105
|
+
}
|
|
67
106
|
return next();
|
|
68
107
|
};
|
|
69
108
|
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
109
|
+
const multipleAuthEval = levels => async (req, res, next) => {
|
|
110
|
+
// res.send = true;
|
|
111
|
+
const results = await Promise.all(levels.map(
|
|
112
|
+
levelCheck => levelCheck(req),
|
|
73
113
|
));
|
|
74
|
-
if (
|
|
114
|
+
if (results.some(val => !val)) {
|
|
75
115
|
return next();
|
|
76
116
|
}
|
|
77
|
-
return
|
|
117
|
+
return invalid(res, results.join(' or '));
|
|
78
118
|
};
|
|
79
119
|
|
|
80
120
|
module.exports = {
|
|
@@ -82,6 +122,6 @@ module.exports = {
|
|
|
82
122
|
frontend,
|
|
83
123
|
admin,
|
|
84
124
|
user,
|
|
85
|
-
'admin,user':
|
|
86
|
-
'admin,app,user':
|
|
125
|
+
'admin,user': multipleAuthEval([adminCheck, userCheck]),
|
|
126
|
+
'admin,app,user': multipleAuthEval([adminCheck, appCheck, userCheck]),
|
|
87
127
|
};
|
package/index.js
CHANGED
|
@@ -24,6 +24,9 @@ const cache = require('./cache');
|
|
|
24
24
|
const rebuild = fn => obj =>
|
|
25
25
|
Object.fromEntries(Object.entries(obj).flatMap(([k, v]) => fn(k, v)));
|
|
26
26
|
|
|
27
|
+
const isNumber = value => !Number.isNaN(Number(value));
|
|
28
|
+
|
|
29
|
+
|
|
27
30
|
module.exports = async ({
|
|
28
31
|
apiDocs = true,
|
|
29
32
|
elasticLogIndex = 'apilog_ti2',
|
|
@@ -121,6 +124,8 @@ module.exports = async ({
|
|
|
121
124
|
);
|
|
122
125
|
const connect = connector(api, allSchema, {
|
|
123
126
|
security: auth,
|
|
127
|
+
notFound: (req, res) => res.sendStatus(404),
|
|
128
|
+
notImplemented: (req, res) => res.sendStatus(501),
|
|
124
129
|
});
|
|
125
130
|
if (elasticLogsClient) { // API request logs are saved on elastic
|
|
126
131
|
// setup the index
|
|
@@ -207,8 +212,8 @@ module.exports = async ({
|
|
|
207
212
|
console.error(err);
|
|
208
213
|
}
|
|
209
214
|
return res.status((() => {
|
|
210
|
-
if (
|
|
211
|
-
return
|
|
215
|
+
if (!isNumber(err.status)) return 500;
|
|
216
|
+
return Number(err.status);
|
|
212
217
|
})()).json({
|
|
213
218
|
message: err.message || 'Internal Error',
|
|
214
219
|
});
|