jxp 3.0.0 → 4.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.
Files changed (219) hide show
  1. package/.env.sample +31 -6
  2. package/README.md +27 -13
  3. package/dist/bin/init_db.d.ts +3 -0
  4. package/dist/bin/init_db.d.ts.map +1 -0
  5. package/dist/bin/init_db.js +48 -0
  6. package/dist/bin/init_db.js.map +1 -0
  7. package/dist/bin/server.d.ts +4 -0
  8. package/dist/bin/server.d.ts.map +1 -0
  9. package/dist/bin/server.js +132 -0
  10. package/dist/bin/server.js.map +1 -0
  11. package/dist/bin/setup.d.ts +3 -0
  12. package/dist/bin/setup.d.ts.map +1 -0
  13. package/dist/bin/setup.js +185 -0
  14. package/dist/bin/setup.js.map +1 -0
  15. package/dist/globals.d.ts +14 -0
  16. package/dist/globals.d.ts.map +1 -0
  17. package/dist/globals.js +3 -0
  18. package/dist/globals.js.map +1 -0
  19. package/dist/libs/aggregate_guard.d.ts +5 -0
  20. package/dist/libs/aggregate_guard.d.ts.map +1 -0
  21. package/dist/libs/aggregate_guard.js +58 -0
  22. package/dist/libs/aggregate_guard.js.map +1 -0
  23. package/dist/libs/bulkwrite_guard.d.ts +5 -0
  24. package/dist/libs/bulkwrite_guard.d.ts.map +1 -0
  25. package/dist/libs/bulkwrite_guard.js +44 -0
  26. package/dist/libs/bulkwrite_guard.js.map +1 -0
  27. package/dist/libs/cache.d.ts +2 -0
  28. package/dist/libs/cache.d.ts.map +1 -0
  29. package/dist/libs/cache.js +94 -0
  30. package/dist/libs/cache.js.map +1 -0
  31. package/dist/libs/call_guard.d.ts +3 -0
  32. package/dist/libs/call_guard.d.ts.map +1 -0
  33. package/dist/libs/call_guard.js +17 -0
  34. package/dist/libs/call_guard.js.map +1 -0
  35. package/dist/libs/connection_string.d.ts +3 -0
  36. package/dist/libs/connection_string.d.ts.map +1 -0
  37. package/dist/libs/connection_string.js +4 -0
  38. package/dist/libs/connection_string.js.map +1 -0
  39. package/dist/libs/datamunging.d.ts +2 -0
  40. package/dist/libs/datamunging.d.ts.map +1 -0
  41. package/dist/libs/datamunging.js +320 -0
  42. package/dist/libs/datamunging.js.map +1 -0
  43. package/dist/libs/docs.d.ts +2 -0
  44. package/dist/libs/docs.d.ts.map +1 -0
  45. package/dist/libs/docs.js +307 -0
  46. package/dist/libs/docs.js.map +1 -0
  47. package/dist/libs/groups.d.ts +2 -0
  48. package/dist/libs/groups.d.ts.map +1 -0
  49. package/dist/libs/groups.js +136 -0
  50. package/dist/libs/groups.js.map +1 -0
  51. package/dist/libs/jxp.d.ts +4 -0
  52. package/dist/libs/jxp.d.ts.map +1 -0
  53. package/dist/libs/jxp.js +1157 -0
  54. package/dist/libs/jxp.js.map +1 -0
  55. package/dist/libs/link_index.d.ts +14 -0
  56. package/dist/libs/link_index.d.ts.map +1 -0
  57. package/dist/libs/link_index.js +37 -0
  58. package/dist/libs/link_index.js.map +1 -0
  59. package/dist/libs/load-config.d.ts +16 -0
  60. package/dist/libs/load-config.d.ts.map +1 -0
  61. package/dist/libs/load-config.js +155 -0
  62. package/dist/libs/load-config.js.map +1 -0
  63. package/dist/libs/login.d.ts +2 -0
  64. package/dist/libs/login.d.ts.map +1 -0
  65. package/dist/libs/login.js +244 -0
  66. package/dist/libs/login.js.map +1 -0
  67. package/dist/libs/modeldir.d.ts +5 -0
  68. package/dist/libs/modeldir.d.ts.map +1 -0
  69. package/dist/libs/modeldir.js +15 -0
  70. package/dist/libs/modeldir.js.map +1 -0
  71. package/dist/libs/query_limits.d.ts +2 -0
  72. package/dist/libs/query_limits.d.ts.map +1 -0
  73. package/dist/libs/query_limits.js +84 -0
  74. package/dist/libs/query_limits.js.map +1 -0
  75. package/dist/libs/query_manipulation.d.ts +3 -0
  76. package/dist/libs/query_manipulation.d.ts.map +1 -0
  77. package/{libs → dist/libs}/query_manipulation.js +22 -21
  78. package/dist/libs/query_manipulation.js.map +1 -0
  79. package/dist/libs/query_sanitize.d.ts +5 -0
  80. package/dist/libs/query_sanitize.d.ts.map +1 -0
  81. package/dist/libs/query_sanitize.js +109 -0
  82. package/dist/libs/query_sanitize.js.map +1 -0
  83. package/dist/libs/response_sanitize.d.ts +7 -0
  84. package/dist/libs/response_sanitize.d.ts.map +1 -0
  85. package/dist/libs/response_sanitize.js +57 -0
  86. package/dist/libs/response_sanitize.js.map +1 -0
  87. package/dist/libs/safe_error.d.ts +3 -0
  88. package/dist/libs/safe_error.d.ts.map +1 -0
  89. package/dist/libs/safe_error.js +14 -0
  90. package/dist/libs/safe_error.js.map +1 -0
  91. package/dist/libs/schema.d.ts +14 -0
  92. package/dist/libs/schema.d.ts.map +1 -0
  93. package/dist/libs/schema.js +98 -0
  94. package/dist/libs/schema.js.map +1 -0
  95. package/dist/libs/schema_description.d.ts +3 -0
  96. package/dist/libs/schema_description.d.ts.map +1 -0
  97. package/{libs → dist/libs}/schema_description.js +12 -21
  98. package/dist/libs/schema_description.js.map +1 -0
  99. package/dist/libs/security.d.ts +2 -0
  100. package/dist/libs/security.d.ts.map +1 -0
  101. package/dist/libs/security.js +428 -0
  102. package/dist/libs/security.js.map +1 -0
  103. package/dist/libs/setup.d.ts +2 -0
  104. package/dist/libs/setup.d.ts.map +1 -0
  105. package/dist/libs/setup.js +87 -0
  106. package/dist/libs/setup.js.map +1 -0
  107. package/dist/libs/startup-deprecations.d.ts +2 -0
  108. package/dist/libs/startup-deprecations.d.ts.map +1 -0
  109. package/dist/libs/startup-deprecations.js +21 -0
  110. package/dist/libs/startup-deprecations.js.map +1 -0
  111. package/dist/libs/startup.d.ts +16 -0
  112. package/dist/libs/startup.d.ts.map +1 -0
  113. package/dist/libs/startup.js +63 -0
  114. package/dist/libs/startup.js.map +1 -0
  115. package/dist/libs/ws.d.ts +2 -0
  116. package/dist/libs/ws.d.ts.map +1 -0
  117. package/{libs → dist/libs}/ws.js +91 -73
  118. package/dist/libs/ws.js.map +1 -0
  119. package/dist/models/apikey_model.d.ts +10 -0
  120. package/dist/models/apikey_model.d.ts.map +1 -0
  121. package/dist/models/apikey_model.js +14 -0
  122. package/dist/models/apikey_model.js.map +1 -0
  123. package/dist/models/link_model.d.ts +9 -0
  124. package/dist/models/link_model.d.ts.map +1 -0
  125. package/dist/models/link_model.js +20 -0
  126. package/dist/models/link_model.js.map +1 -0
  127. package/dist/models/refreshtoken_model.d.ts +11 -0
  128. package/dist/models/refreshtoken_model.d.ts.map +1 -0
  129. package/dist/models/refreshtoken_model.js +22 -0
  130. package/dist/models/refreshtoken_model.js.map +1 -0
  131. package/dist/models/test_model.d.ts +24 -0
  132. package/dist/models/test_model.d.ts.map +1 -0
  133. package/dist/models/test_model.js +44 -0
  134. package/dist/models/test_model.js.map +1 -0
  135. package/dist/models/token_model.d.ts +14 -0
  136. package/dist/models/token_model.d.ts.map +1 -0
  137. package/dist/models/token_model.js +25 -0
  138. package/dist/models/token_model.js.map +1 -0
  139. package/dist/models/user_model.d.ts +15 -0
  140. package/dist/models/user_model.d.ts.map +1 -0
  141. package/dist/models/user_model.js +38 -0
  142. package/dist/models/user_model.js.map +1 -0
  143. package/dist/models/usergroups_model.d.ts +9 -0
  144. package/dist/models/usergroups_model.d.ts.map +1 -0
  145. package/dist/models/usergroups_model.js +18 -0
  146. package/dist/models/usergroups_model.js.map +1 -0
  147. package/dist/types/jxp-config.d.ts +134 -0
  148. package/dist/types/jxp-config.d.ts.map +1 -0
  149. package/dist/types/jxp-config.js +3 -0
  150. package/dist/types/jxp-config.js.map +1 -0
  151. package/dist/types/schema-fields.d.ts +43 -0
  152. package/dist/types/schema-fields.d.ts.map +1 -0
  153. package/dist/types/schema-fields.js +3 -0
  154. package/dist/types/schema-fields.js.map +1 -0
  155. package/docs/aggregations.md +40 -21
  156. package/docs/api.md +55 -15
  157. package/docs/authentication.md +60 -37
  158. package/docs/bulk_writes.md +11 -8
  159. package/docs/caching.md +28 -11
  160. package/docs/changelog.md +237 -31
  161. package/docs/configuration.md +99 -118
  162. package/docs/hooks.md +12 -8
  163. package/docs/index.md +17 -17
  164. package/docs/installation.md +23 -18
  165. package/docs/permissions.md +33 -19
  166. package/docs/queries.md +9 -5
  167. package/docs/schemas.md +21 -10
  168. package/docs/special.md +4 -4
  169. package/docs/typescript.md +86 -0
  170. package/docs/websocket.md +99 -1
  171. package/mkdocs.yml +1 -0
  172. package/package.json +121 -69
  173. package/templates/api.pug +32 -0
  174. package/templates/app-server.js +43 -0
  175. package/templates/app.env.sample +8 -0
  176. package/templates/assets/api-console.js +133 -0
  177. package/templates/assets/docs.css +227 -0
  178. package/templates/index.pug +62 -2
  179. package/templates/layout.pug +17 -11
  180. package/templates/md.pug +1 -1
  181. package/templates/model.pug +117 -68
  182. package/templates/navbar.pug +14 -21
  183. package/templates/sidebar.pug +30 -0
  184. package/.env +0 -9
  185. package/.eslintrc.json +0 -20
  186. package/.jshintrc +0 -4
  187. package/.vscode/launch.json +0 -34
  188. package/.vscode/settings.json +0 -3
  189. package/Dockerfile +0 -7
  190. package/bin/init_db.js +0 -54
  191. package/bin/server.js +0 -131
  192. package/bin/setup.js +0 -190
  193. package/config_sample.json +0 -10
  194. package/docker-compose.yml +0 -32
  195. package/libs/cache.js +0 -92
  196. package/libs/connection_string.js +0 -24
  197. package/libs/datamunging.js +0 -335
  198. package/libs/docs.js +0 -162
  199. package/libs/groups.js +0 -133
  200. package/libs/jxp.js +0 -1208
  201. package/libs/login.js +0 -222
  202. package/libs/modeldir.js +0 -14
  203. package/libs/schema.js +0 -99
  204. package/libs/security.js +0 -410
  205. package/libs/setup.js +0 -90
  206. package/models/apikey_model.js +0 -10
  207. package/models/link_model.js +0 -17
  208. package/models/refreshtoken_model.js +0 -20
  209. package/models/test_model.js +0 -50
  210. package/models/token_model.js +0 -23
  211. package/models/user_model.js +0 -38
  212. package/models/usergroups_model.js +0 -15
  213. package/setup.sh +0 -3
  214. package/test/.eslintrc.json +0 -13
  215. package/test/auth.js +0 -190
  216. package/test/init.js +0 -92
  217. package/test/setup.test.js +0 -62
  218. package/test/test.js +0 -1527
  219. package/test/wstest.js.old +0 -124
package/libs/security.js DELETED
@@ -1,410 +0,0 @@
1
- const bcrypt = require("bcryptjs");
2
- const randToken = require("rand-token");
3
- const path = require("path");
4
- const errors = require("restify-errors");
5
- var APIKey = null;
6
- var Token = null;
7
- var Groups = null;
8
- var User = null;
9
- var RefreshToken = null;
10
- var provider = "https://api.workspaceman.nl";
11
-
12
- const init = function (config) {
13
- APIKey = require(path.join(config.model_dir, "apikey_model"));
14
- Groups = require(path.join(config.model_dir, "usergroups_model.js"));
15
- User = require(path.join(config.model_dir, "user_model"));
16
- Token = require(path.join(config.model_dir, "token_model"));
17
- RefreshToken = require(path.join(config.model_dir, "refreshtoken_model"));
18
- if (config.url) provider = config.url;
19
- };
20
-
21
- const basicAuthData = function (req) {
22
- if (!req.headers.authorization) {
23
- return false;
24
- }
25
- try {
26
- const authorization = req.headers.authorization.split(" ")[1];
27
- const decoded = new Buffer.from(authorization, "base64").toString();
28
- return decoded.split(":");
29
- } catch (err) {
30
- return false;
31
- }
32
- };
33
-
34
- const basicAuth = async ba => {
35
- try {
36
- if (!Array.isArray(ba) || ba.length !== 2) {
37
- throw ("Basic Auth incorrectly formatted");
38
- }
39
- var email = ba[0];
40
- var password = ba[1];
41
- const user = await User.findOne({ email }).exec();
42
- if (!user) {
43
- throw (new Date(), `Incorrect username or password for ${email}`);
44
- }
45
- if (!await bcrypt.compare(password, user.password)) {
46
- throw (`Incorrect username or password for ${email}`);
47
- }
48
- return user;
49
- } catch (err) {
50
- console.error(new Date(), err);
51
- throw err;
52
- }
53
- };
54
-
55
- const bearerAuthData = req => {
56
- if (!req.headers.authorization) {
57
- return false;
58
- }
59
- try {
60
- const token = req.headers.authorization.split(" ")[1];
61
- return token;
62
- } catch (err) {
63
- return false;
64
- }
65
- }
66
-
67
- const bearerAuth = async t => {
68
- try {
69
- if (!t) throw ("Token invalid");
70
- const token = await Token.findOne({ access_token: t, provider }).exec();
71
- if (!token) {
72
- throw (`Token ${t} not found`);
73
- }
74
- if (!tokenIsValid(token)) {
75
- throw (`Token is no loger valid`);
76
- }
77
- const user = await User.findOne({ _id: token.user_id }).exec();
78
- if (!user) {
79
- throw (`Could not find user`);
80
- }
81
- return user;
82
- } catch (err) {
83
- console.error(err);
84
- throw err;
85
- }
86
- }
87
-
88
- const apiKeyAuth = async apikey => {
89
- try {
90
- if (!apikey) throw ("Missing apikey");
91
- const result = await APIKey.findOne({ apikey });
92
- if (!result) throw ("Could not find apikey");
93
- const user = User.findOne({ _id: result.user_id });
94
- if (!user) throw ("Could not find user associated to apikey");
95
- return user;
96
- } catch (err) {
97
- console.error(new Date(), err);
98
- throw err;
99
- }
100
- };
101
-
102
- const getGroups = async user_id => {
103
- try {
104
- const userGroup = await Groups.findOne({ user_id });
105
- var groups = userGroup && userGroup.groups ? userGroup.groups : [];
106
- return groups;
107
- } catch (err) {
108
- console.error(new Date(), err);
109
- throw err;
110
- }
111
- };
112
-
113
- const encPassword = password => {
114
- return bcrypt.hashSync(password, 4);
115
- };
116
-
117
- const generateApiKey = async user_id => {
118
- try {
119
- let existing = await APIKey.findOne({ user_id }).sort({ last_accessed: -1 }).exec();
120
- if (existing) {
121
- await existing.updateOne({ last_accessed: new Date() });
122
- return existing;
123
- }
124
- var apikey = new APIKey();
125
- apikey.user_id = user_id;
126
- apikey.apikey = randToken.generate(16);
127
- await apikey.save();
128
- return apikey;
129
- } catch (err) {
130
- console.error(new Date(), err);
131
- throw err;
132
- }
133
- };
134
-
135
- const tokenIsValid = token => {
136
- if (!token) return false;
137
- const now = +new Date();
138
- const expires_at = +new Date(token.createdAt) + (token.expires_in * 1000);
139
- return (expires_at > now);
140
- }
141
-
142
- const tokenExpires = token => {
143
- return new Date(new Date(token.createdAt) + (token.expires_in * 1000));
144
- }
145
-
146
- const generateToken = async user_id => {
147
- try {
148
- var token = new Token();
149
- token.user_id = user_id;
150
- token.access_token = randToken.generate(16);
151
- token.provider = provider;
152
- await token.save();
153
- return token;
154
- } catch (err) {
155
- console.error(new Date(), err);
156
- throw err;
157
- }
158
- };
159
-
160
- const ensureToken = async user_id => {
161
- try {
162
- const token = await Token.findOne({ user_id, provider }).sort({ createdAt: -1 }).exec();
163
- if (tokenIsValid(token)) {
164
- return token;
165
- }
166
- return await generateToken(user_id);
167
- } catch (err) {
168
- console.error(new Date(), err);
169
- throw err;
170
- }
171
- }
172
-
173
- const refreshToken = async user_id => {
174
- await revokeToken(user_id);
175
- return await ensureToken(user_id);
176
- }
177
-
178
- const revokeToken = async user_id => {
179
- await Token.deleteOne({ user_id, provider });
180
- return;
181
- }
182
-
183
- const generateRefreshToken = async user_id => {
184
- try {
185
- var refreshtoken = new RefreshToken();
186
- refreshtoken.user_id = user_id;
187
- refreshtoken.refresh_token = randToken.generate(16);
188
- await refreshtoken.save();
189
- return refreshtoken;
190
- } catch (err) {
191
- console.error(new Date(), err);
192
- throw err;
193
- }
194
- };
195
-
196
- const ensureRefreshToken = async user_id => {
197
- const refreshtoken = await RefreshToken.findOne({ user_id }).sort({ createdAt: -1 }).exec();
198
- if (tokenIsValid(refreshtoken)) {
199
- return refreshtoken;
200
- }
201
- return await generateRefreshToken(user_id);
202
- }
203
-
204
- const revokeRefreshToken = async user_id => {
205
- await RefreshToken.deleteMany({ user_id });
206
- return;
207
- }
208
-
209
- const refresh = async (req, res) => {
210
- try {
211
- if (req.headers.authorization && req.headers.authorization.trim().toLowerCase().indexOf("bearer") === 0) {
212
- const refresh_token = await RefreshToken.findOne({ refresh_token: bearerAuthData(req) }).exec();
213
- if (!refresh_token) throw ("Refresh token not found");
214
- if (!tokenIsValid(refresh_token)) throw ("Refresh token has expired");
215
- const user_id = refresh_token.user_id;
216
- const token = await refreshToken(user_id);
217
- await revokeRefreshToken(user_id);
218
- const new_refresh_token = await generateRefreshToken(user_id);
219
- res.send({
220
- user_id: user_id,
221
- token: token.access_token,
222
- token_expires: tokenExpires(token),
223
- refresh_token: new_refresh_token.refresh_token,
224
- refresh_token_expires: tokenExpires(new_refresh_token)
225
- });
226
- } else {
227
- throw ("Missing refresh token")
228
- }
229
- } catch (err) {
230
- console.error(err);
231
- if (err.code) throw err;
232
- throw new errors.ForbiddenError(err.toString());
233
- }
234
- }
235
-
236
- const login = async (req, res) => {
237
- try {
238
- const authenticate_result = await authenticate(req);
239
- if (!authenticate_result) {
240
- res.user = null;
241
- res.groups = [];
242
- return;
243
- }
244
- res = Object.assign(res, authenticate_result);
245
- } catch (err) {
246
- console.error(err);
247
- if (err.code) throw err;
248
- throw new errors.ForbiddenError(err.toString());
249
- }
250
- };
251
-
252
- const authenticate = async req => {
253
- let user = null;
254
- if (!req.query.apikey && !req.headers.authorization && !(req.headers["X-API-Key"] || req.headers["x-api-key"])) {
255
- return false;
256
- }
257
- if (req.headers.authorization && req.headers.authorization.trim().toLowerCase().indexOf("basic") === 0) {
258
- // Basic Auth
259
- user = await basicAuth(basicAuthData(req));
260
- } else if (req.headers.authorization && req.headers.authorization.trim().toLowerCase().indexOf("bearer") === 0) {
261
- // Token Auth
262
- user = await bearerAuth(bearerAuthData(req));
263
- } else if (req.query.apikey) {
264
- user = await apiKeyAuth(req.query.apikey);
265
- } else if (req.headers["X-API-Key"] || req.headers["x-api-key"]) {
266
- // API Key
267
- user = await apiKeyAuth(req.headers["X-API-Key"] || req.headers["x-api-key"])
268
- } else {
269
- throw ("Could not find any way to authenticate");
270
- }
271
- if (!user) {
272
- throw ("Could not find user");
273
- }
274
- return {
275
- token: await ensureToken(user._id),
276
- refresh_token: await ensureRefreshToken(user._id),
277
- groups: await getGroups(user._id),
278
- username: user.email,
279
- user
280
- }
281
-
282
- }
283
-
284
- const auth = async (req, res) => {
285
- // Check against model as to whether we're allowed to edit this model
286
- if (!req.Model) {
287
- // console.error("Model missing");
288
- throw new errors.BadRequestError("Model missing");
289
- }
290
- try {
291
- var method = null;
292
- // console.log("req.route.name", req.route.name);
293
- if (req.method == "GET" || req.route.name === "postquerymodelname" || req.route.name === "postaggregatemodelname") {
294
- method = "r";
295
- } else if (req.method == "POST") {
296
- method = "c";
297
- } else if (req.method == "PUT") {
298
- method = "u";
299
- } else if (req.method == "DELETE") {
300
- method = "d";
301
- } else {
302
- // console.error("Unsupported operation", req.method);
303
- throw new errors.InternalServerError(`Unsupported operation: ${req.method}`);
304
- }
305
- return await check_perms(res.user, res.groups, req.Model, method, req.params.item_id);
306
- } catch (err) {
307
- console.error(err);
308
- if (err.code) throw err;
309
- throw new errors.ForbiddenError(err.toString());
310
- }
311
- };
312
-
313
- // Bulk auth requires all CRUD permissions
314
- const bulkAuth = async (req, res,) => {
315
- try {
316
- await check_perms(res.user, res.groups, req.Model, "c");
317
- await check_perms(res.user, res.groups, req.Model, "r");
318
- await check_perms(res.user, res.groups, req.Model, "u");
319
- await check_perms(res.user, res.groups, req.Model, "d");
320
- } catch (err) {
321
- console.error(err);
322
- if (err.code) throw err;
323
- throw new errors.ForbiddenError(err.toString());
324
- }
325
- };
326
-
327
- const check_perms = async (user, groups, model, method, item_id) => {
328
- try {
329
- const perms = model.schema.get("_perms");
330
- //If no perms are set, then this isn't an available model
331
- if (!perms.admin) {
332
- console.error("Model permissions not set correctly - add an admin section");
333
- throw new errors.InternalServerError("Model permissions not set correctly - add an admin section");
334
- }
335
- //First check if "all" is able to do this. If so, let's get on with it.
336
- if (perms.all && perms.all.length) {
337
- if (perms.all.indexOf(method) !== -1) {
338
- return;
339
- }
340
- }
341
- //This isn't an 'all' situation, so let's bail if the user isn't logged in
342
- if (!user) {
343
- throw new errors.ForbiddenError("User not logged in");
344
- }
345
- //Let's check perms in this order - admin, user, group, owner
346
- //Admin check
347
- if (user.admin && perms.admin && perms.admin.includes(method)) {
348
- // console.log("Matched permission 'admin':" + method);
349
- return;
350
- }
351
- //User check
352
- if (perms.user && perms.user.includes(method)) {
353
- // console.log("Matched permission 'user':" + method);
354
- return;
355
- }
356
- //Group check
357
- for (let group of groups) {
358
- if (perms[group] && perms[group].includes(method)) {
359
- // console.log("Matched permission '" + group + "':" + method);
360
- return;
361
- }
362
- }
363
- //Owner check
364
- if (!item_id) throw (`Authorization failed - ${method}`);
365
- const item = await model.findById(item_id);
366
- if (item && item._owner_id && item._owner_id.toString() == user._id.toString() && (perms.owner && perms.owner.includes(method))) return;
367
- throw ("Authorization failed");
368
- } catch (err) {
369
- if (err.code) throw err;
370
- throw new errors.ForbiddenError(err.toString());
371
- }
372
- }
373
-
374
- const admin_only = (req, res, next) => { // Chain after login
375
- if (!res.user) {
376
- throw new errors.ForbiddenError("User not logged in");
377
- }
378
- if (!res.user.admin) {
379
- throw new errors.ForbiddenError("User not admin");
380
- }
381
- next();
382
- }
383
-
384
- const Security = {
385
- init,
386
- basicAuthData,
387
- basicAuth,
388
- encPassword,
389
- generateApiKey,
390
- generateToken,
391
- ensureToken,
392
- refreshToken,
393
- revokeToken,
394
- tokenExpires,
395
- generateRefreshToken,
396
- ensureRefreshToken,
397
- revokeRefreshToken,
398
- login,
399
- refresh,
400
- authenticate,
401
- auth,
402
- admin_only,
403
- check_perms,
404
- getGroups,
405
- apiKeyAuth,
406
- bearerAuth,
407
- bulkAuth
408
- };
409
-
410
- module.exports = Security;
package/libs/setup.js DELETED
@@ -1,90 +0,0 @@
1
- const rand_token = require("rand-token");
2
- const path = require("path");
3
- const errors = require("restify-errors");
4
- const security = require("./security");
5
- const ObjectID = require('mongodb').ObjectID;
6
- var User = null;
7
- const connection_string = require("./connection_string");
8
-
9
- const init = config => {
10
- User = require(path.join(config.model_dir, "user_model"));
11
- }
12
-
13
- const checkUserDoesNotExist = async () => {
14
- try {
15
- const count = await User.countDocuments();
16
- if (count) {
17
- throw new errors.ConflictError("Cannot setup if user exists");
18
- }
19
- } catch(err) {
20
- console.error(err);
21
- if (err.code) throw err;
22
- throw new errors.InternalServerError(err.toString());
23
- }
24
- };
25
-
26
- const setup = async (req, res) => {
27
- try {
28
- const password = (req.body && req.body.password) ? req.body.password : rand_token.generate(12);
29
- const user = new User({
30
- password: security.encPassword(password),
31
- email: req.body.email || "admin@example.com",
32
- name: req.body.name || "admin",
33
- admin: true
34
- });
35
- await user.save();
36
- console.log(
37
- "Created admin user",
38
- user.name,
39
- "<" + user.email + ">",
40
- ":",
41
- password
42
- );
43
- res.send({
44
- status: "success",
45
- name: user.name,
46
- email: user.email,
47
- password
48
- });
49
- } catch(err) {
50
- console.error(err);
51
- throw new errors.InternalServerError(err.toString());
52
- }
53
- };
54
-
55
- // Unlike setup, which just automates user creation, you can upload any data you want
56
- const data_setup = async (req, res) => {
57
- try {
58
- const { MongoClient } = require("mongodb");
59
- const client = await MongoClient.connect(connection_string);
60
- const db = client.db(client.databaseName);
61
- const data = req.body;
62
- const results = {};
63
- const _id_reg = new RegExp("_id$");
64
- for (let collection in data) {
65
- for (let row of data[collection]) {
66
- row.createdAt = new Date();
67
- row._deleted = false;
68
- // Ensure all _id's are of type id
69
- for (let field in row) {
70
- if (_id_reg.test(field)) {
71
- row[field] = ObjectID(row[field]);
72
- }
73
- }
74
- }
75
- const result = await db.collection(collection).insertMany(data[collection]);
76
- results[collection] = result;
77
- }
78
- res.send({ status: "success", results });
79
- } catch(err) {
80
- console.error(err);
81
- throw new errors.InternalServerError(err.toString());
82
- }
83
- }
84
-
85
- module.exports = {
86
- init,
87
- checkUserDoesNotExist,
88
- setup,
89
- data_setup
90
- };
@@ -1,10 +0,0 @@
1
- /* global JXPSchema ObjectId */
2
-
3
- var APIKeySchema = new JXPSchema({
4
- user_id: { type: ObjectId, index: true, unique: true },
5
- apikey: { type: String, index: true, unique: true },
6
- last_accessed: { type: Date, default: Date.now, index: true },
7
- });
8
-
9
- const APIKey = JXPSchema.model('APIKey', APIKeySchema);
10
- module.exports = APIKey;
@@ -1,17 +0,0 @@
1
- /* global JXPSchema */
2
-
3
- const LinkSchema = new JXPSchema({
4
- name: String,
5
- val: String,
6
- },
7
- {
8
- perms: {
9
- admin: "crud",
10
- owner: "crud",
11
- user: "cr",
12
- all: "r"
13
- }
14
- });
15
-
16
- const Link = JXPSchema.model('Link', LinkSchema);
17
- module.exports = Link;
@@ -1,20 +0,0 @@
1
- /* global JXPSchema ObjectId */
2
- const config = require("config");
3
-
4
- var RefreshTokenSchema = new JXPSchema({
5
- user_id: { type: ObjectId, index: true },
6
- refresh_token: { type: String, index: true },
7
- expires_in: { type: Number, default: config.refresh_token_expiry || 2678400 }, // In seconds
8
- },
9
- {
10
- perms: {
11
- admin: "crud",
12
- owner: "crud",
13
- user: "",
14
- }
15
- });
16
-
17
- RefreshTokenSchema.index({ "expire_at": 1 }, { expireAfterSeconds: config.refresh_token_expiry || 2678400 });
18
-
19
- const RefreshToken = JXPSchema.model('RefreshToken', RefreshTokenSchema);
20
- module.exports = RefreshToken;
@@ -1,50 +0,0 @@
1
- /* global JXPSchema ObjectId Mixed */
2
- const errors = require("restify-errors");
3
-
4
- const TestSchema = new JXPSchema({
5
- foo: String, // A normal string
6
- bar: { type: String, unique: true, index: true, default: "Some Default" }, // Ah! Some business logic!
7
- user_id: { type: ObjectId, link: "User" },
8
- yack: Mixed, // We can put anything in here, including objects
9
- shmack: [String], // We can store arrays
10
- password: String, // Passwords are automagically encrypted
11
- fulltext: { type: String, index: { text: true } },
12
- link_id: { type: ObjectId, link: "Link", }, // We can populate these links during a query
13
- other_link_id: { type: ObjectId, link: "Link", map_to: "other_link" },
14
- string_array: [String],
15
- array_link_id: [{ type: ObjectId, link: "Link", map_to: "array_link", justOne: false }],
16
- composite_array: [
17
- { afoo: String, abar: Number }
18
- ],
19
- mixed_array: [Mixed],
20
- date_field: { type: Date, index: true } // Added date field for testing date filtering
21
- },
22
- {
23
- perms: {
24
- admin: "crud", // CRUD = Create, Retrieve, Update and Delete
25
- owner: "crud",
26
- user: "cr",
27
- all: "r" // Unauthenticated users will be able to read from test, but that is all
28
- }
29
- }
30
- );
31
-
32
- // Full text index
33
- // TestSchema.index( { "$**": "text" } );
34
-
35
- // We can define useful functions that we can call through the API using our /call endpoint
36
- TestSchema.statics.test = function () {
37
- return "Testing OKAY!";
38
- };
39
-
40
- TestSchema.pre("save", function (next) {
41
- // If we have the setting "error" set to true, we will throw an error
42
- if (this.bar == "Throw an error") {
43
- throw new errors.ImATeapotError("I'm a teapot");
44
- }
45
- next();
46
- });
47
-
48
- // Finally, we export our model. Make sure to change the name!
49
- const Test = JXPSchema.model('Test', TestSchema);
50
- module.exports = Test;
@@ -1,23 +0,0 @@
1
- /* global JXPSchema ObjectId */
2
- const config = require("config");
3
-
4
- var TokenSchema = new JXPSchema({
5
- user_id: { type: ObjectId, index: true },
6
- provider: String,
7
- access_token: { type: String, index: true },
8
- token_type: String,
9
- expires_in: { type: Number, default: config.token_expiry || 86400, required: true }, // In seconds
10
- last_accessed: { type: Date, default: Date.now, index: true },
11
- },
12
- {
13
- perms: {
14
- admin: "crud",
15
- owner: "crud",
16
- user: "",
17
- }
18
- });
19
-
20
- TokenSchema.index({ "expire_at": 1 }, { expireAfterSeconds: config.token_expiry || 86400 });
21
-
22
- const Token = JXPSchema.model('Token', TokenSchema);
23
- module.exports = Token;
@@ -1,38 +0,0 @@
1
- /* global JXPSchema */
2
- var friendly = require("mongoose-friendly");
3
-
4
- var UserSchema = new JXPSchema({
5
- name: { type: String },
6
- urlid: { type: String, unique: true, index: true },
7
- email: { type: String, unique: true, index: true, set: toLower },
8
- password: String,
9
- admin: Boolean,
10
- temp_hash: String,
11
- },
12
- {
13
- perms: {
14
- admin: "crud",
15
- owner: "cru",
16
- user: "r",
17
- member: "r",
18
- api: "r"
19
- }
20
- });
21
-
22
- UserSchema.path('name').validate(function (v) {
23
- return (v) && (v.length > 0);
24
- }, 'Name cannot be empty');
25
-
26
- UserSchema.plugin(friendly, {
27
- source: 'name',
28
- friendly: 'urlid'
29
- });
30
-
31
- function toLower (v) {
32
- if (v)
33
- return v.toLowerCase();
34
- return null;
35
- }
36
-
37
- const UserModel = JXPSchema.model('User', UserSchema);
38
- module.exports = UserModel;
@@ -1,15 +0,0 @@
1
- /* global JXPSchema ObjectId */
2
-
3
- var UserGroupSchema = new JXPSchema({
4
- user_id: { type: ObjectId, index: true, unique: true, link: "User" },
5
- groups: [String],
6
- },
7
- {
8
- perms: {
9
- admin: "crud",
10
- user: "r",
11
- }
12
- });
13
-
14
- const UserGroup = JXPSchema.model('Usergroup', UserGroupSchema);
15
- module.exports = UserGroup;
package/setup.sh DELETED
@@ -1,3 +0,0 @@
1
- #!/bin/sh
2
-
3
- npm install
@@ -1,13 +0,0 @@
1
- {
2
- "env": {
3
- "mocha": true
4
- },
5
- "rules": {
6
- "no-unused-vars": [
7
- "error",
8
- {
9
- "varsIgnorePattern": "should|expect"
10
- }
11
- ]
12
- }
13
- }