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.
@@ -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 = next => next({ status: 401, message: 'Unauthorized' });
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 app = async (req, res, next) => {
25
- if (!req.pathParams || !req.pathParams.app) return invalid(next);
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 invalid(next);
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 invalid(next);
36
+ if (!appRecord) return 'App not found';
35
37
  if (appRecord.apiKey !== token) {
36
- return invalid(next);
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 admin = async (req, res, next) => {
53
+ const adminCheck = async req => {
44
54
  const token = getToken({ req });
45
- if (token !== adminKey) return invalid(next);
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 user = async (req, res, next) => {
68
+ const userCheck = async req => {
51
69
  const token = getToken({ req });
52
- if (!token) return invalid(next);
70
+ if (!token) return 'Token not found';
71
+ let userId;
53
72
  try {
54
- const { userId } = jsonwebtoken.verify(token, jwtSecret);
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 invalid(next);
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 frontend = async (req, res, next) => {
93
+ const frontendCheck = async req => {
65
94
  const token = getToken({ req });
66
- if (token !== frontendKey) return invalid(next);
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 adminOrUser = levels => async (req, res, next) => {
71
- const result = await Promise.all(levels.map(
72
- level => level(req, res, err => err),
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 (result.some(val => (!val))) {
114
+ if (results.some(val => !val)) {
75
115
  return next();
76
116
  }
77
- return next(result[0]);
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': adminOrUser([admin, user]),
86
- 'admin,app,user': adminOrUser([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 (isNan(err.status)) return 500;
211
- return parseInt(err.status, 10);
215
+ if (!isNumber(err.status)) return 500;
216
+ return Number(err.status);
212
217
  })()).json({
213
218
  message: err.message || 'Internal Error',
214
219
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ti2",
3
- "version": "1.0.27",
3
+ "version": "1.0.30",
4
4
  "description": "Tourist Industry Exchange (TI2)",
5
5
  "main": "index.js",
6
6
  "scripts": {