@saltcorn/server 0.6.1-beta.0 → 0.6.1
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/app.js +7 -0
- package/auth/admin.js +120 -5
- package/auth/index.js +7 -0
- package/auth/resetpw.js +22 -0
- package/auth/roleadmin.js +52 -0
- package/auth/routes.js +211 -2
- package/auth/testhelp.js +69 -0
- package/errors.js +14 -1
- package/fixture_persons.js +14 -0
- package/index.js +6 -0
- package/load_plugins.js +4 -3
- package/locales/en.json +7 -1
- package/markup/admin.js +97 -1
- package/markup/blockly.js +15 -0
- package/markup/expression_blurb.js +45 -0
- package/markup/forms.js +24 -0
- package/markup/index.js +7 -0
- package/markup/plugin-store.js +36 -0
- package/package.json +6 -6
- package/public/saltcorn-builder.css +1 -0
- package/public/saltcorn.js +5 -1
- package/routes/actions.js +53 -1
- package/routes/admin.js +97 -1
- package/routes/api.js +45 -10
- package/routes/config.js +18 -0
- package/routes/crashlog.js +31 -0
- package/routes/delete.js +19 -0
- package/routes/edit.js +19 -0
- package/routes/eventlog.js +65 -1
- package/routes/events.js +19 -0
- package/routes/fields.js +88 -0
- package/routes/files.js +62 -0
- package/routes/homepage.js +175 -80
- package/routes/index.js +7 -1
- package/routes/infoarch.js +56 -0
- package/routes/library.js +32 -0
- package/routes/list.js +28 -1
- package/routes/menu.js +45 -0
- package/routes/packs.js +53 -0
- package/routes/page.js +26 -0
- package/routes/pageedit.js +129 -3
- package/routes/plugins.js +156 -5
- package/routes/scapi.js +79 -23
- package/routes/search.js +51 -0
- package/routes/settings.js +27 -0
- package/routes/tables.js +148 -19
- package/routes/tenant.js +123 -31
- package/routes/utils.js +60 -1
- package/routes/view.js +37 -0
- package/routes/viewedit.js +114 -1
- package/serve.js +138 -88
- package/systemd.js +18 -1
- package/wrapper.js +4 -0
package/auth/routes.js
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @category server
|
|
3
|
+
* @module auth/routes
|
|
4
|
+
* @subcategory auth
|
|
5
|
+
*/
|
|
1
6
|
const Router = require("express-promise-router");
|
|
2
7
|
|
|
3
8
|
const db = require("@saltcorn/data/db");
|
|
@@ -45,9 +50,22 @@ const { restore } = require("@saltcorn/data/models/backup");
|
|
|
45
50
|
const load_plugins = require("../load_plugins");
|
|
46
51
|
const fs = require("fs");
|
|
47
52
|
|
|
53
|
+
/**
|
|
54
|
+
* @type {object}
|
|
55
|
+
* @const
|
|
56
|
+
* @namespace routesRouter
|
|
57
|
+
* @category server
|
|
58
|
+
* @subcategory auth
|
|
59
|
+
*/
|
|
60
|
+
|
|
48
61
|
const router = new Router();
|
|
49
62
|
module.exports = router;
|
|
50
63
|
|
|
64
|
+
/**
|
|
65
|
+
* @param {object} req
|
|
66
|
+
* @param {boolean} isCreating
|
|
67
|
+
* @returns {Form}
|
|
68
|
+
*/
|
|
51
69
|
const loginForm = (req, isCreating) => {
|
|
52
70
|
const postAuthMethods = Object.entries(getState().auth_methods)
|
|
53
71
|
// TBD unresolved parameter K
|
|
@@ -84,6 +102,11 @@ const loginForm = (req, isCreating) => {
|
|
|
84
102
|
submitLabel: req.__("Login"),
|
|
85
103
|
});
|
|
86
104
|
};
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* @param {object} req
|
|
108
|
+
* @returns {Form}
|
|
109
|
+
*/
|
|
87
110
|
const forgotForm = (req) =>
|
|
88
111
|
new Form({
|
|
89
112
|
blurb: req.__(
|
|
@@ -104,6 +127,11 @@ const forgotForm = (req) =>
|
|
|
104
127
|
submitLabel: req.__("Reset password"),
|
|
105
128
|
});
|
|
106
129
|
|
|
130
|
+
/**
|
|
131
|
+
* @param {object} body
|
|
132
|
+
* @param {object} req
|
|
133
|
+
* @returns {Form}
|
|
134
|
+
*/
|
|
107
135
|
const resetForm = (body, req) => {
|
|
108
136
|
const form = new Form({
|
|
109
137
|
blurb: req.__("Enter your new password below"),
|
|
@@ -129,6 +157,12 @@ const resetForm = (body, req) => {
|
|
|
129
157
|
form.values.token = body && body.token;
|
|
130
158
|
return form;
|
|
131
159
|
};
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* @param {string} current
|
|
163
|
+
* @param {boolean} noMethods
|
|
164
|
+
* @returns {object}
|
|
165
|
+
*/
|
|
132
166
|
const getAuthLinks = (current, noMethods) => {
|
|
133
167
|
const links = { methods: [] };
|
|
134
168
|
const state = getState();
|
|
@@ -152,6 +186,11 @@ const getAuthLinks = (current, noMethods) => {
|
|
|
152
186
|
return links;
|
|
153
187
|
};
|
|
154
188
|
|
|
189
|
+
/**
|
|
190
|
+
* @name get/login
|
|
191
|
+
* @function
|
|
192
|
+
* @memberof module:auth/routes~routesRouter
|
|
193
|
+
*/
|
|
155
194
|
router.get(
|
|
156
195
|
"/login",
|
|
157
196
|
setTenant,
|
|
@@ -175,6 +214,11 @@ router.get(
|
|
|
175
214
|
})
|
|
176
215
|
);
|
|
177
216
|
|
|
217
|
+
/**
|
|
218
|
+
* @name get/logout
|
|
219
|
+
* @function
|
|
220
|
+
* @memberof module:auth/routes~routesRouter
|
|
221
|
+
*/
|
|
178
222
|
router.get("/logout", setTenant, (req, res, next) => {
|
|
179
223
|
req.logout();
|
|
180
224
|
if (req.session.destroy)
|
|
@@ -190,6 +234,11 @@ router.get("/logout", setTenant, (req, res, next) => {
|
|
|
190
234
|
}
|
|
191
235
|
});
|
|
192
236
|
|
|
237
|
+
/**
|
|
238
|
+
* @name get/forgot
|
|
239
|
+
* @function
|
|
240
|
+
* @memberof module:auth/routes~routesRouter
|
|
241
|
+
*/
|
|
193
242
|
router.get(
|
|
194
243
|
"/forgot",
|
|
195
244
|
setTenant,
|
|
@@ -210,6 +259,11 @@ router.get(
|
|
|
210
259
|
})
|
|
211
260
|
);
|
|
212
261
|
|
|
262
|
+
/**
|
|
263
|
+
* @name get/reset
|
|
264
|
+
* @function
|
|
265
|
+
* @memberof module:auth/routes~routesRouter
|
|
266
|
+
*/
|
|
213
267
|
router.get(
|
|
214
268
|
"/reset",
|
|
215
269
|
setTenant,
|
|
@@ -219,6 +273,11 @@ router.get(
|
|
|
219
273
|
})
|
|
220
274
|
);
|
|
221
275
|
|
|
276
|
+
/**
|
|
277
|
+
* @name get/verify
|
|
278
|
+
* @function
|
|
279
|
+
* @memberof module:auth/routes~routesRouter
|
|
280
|
+
*/
|
|
222
281
|
router.get(
|
|
223
282
|
"/verify",
|
|
224
283
|
setTenant,
|
|
@@ -238,6 +297,11 @@ router.get(
|
|
|
238
297
|
})
|
|
239
298
|
);
|
|
240
299
|
|
|
300
|
+
/**
|
|
301
|
+
* @name post/reset
|
|
302
|
+
* @function
|
|
303
|
+
* @memberof module:auth/routes~routesRouter
|
|
304
|
+
*/
|
|
241
305
|
router.post(
|
|
242
306
|
"/reset",
|
|
243
307
|
setTenant,
|
|
@@ -258,6 +322,12 @@ router.post(
|
|
|
258
322
|
res.redirect("/auth/login");
|
|
259
323
|
})
|
|
260
324
|
);
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* @name post/forgot
|
|
328
|
+
* @function
|
|
329
|
+
* @memberof module:auth/routes~routesRouter
|
|
330
|
+
*/
|
|
261
331
|
router.post(
|
|
262
332
|
"/forgot",
|
|
263
333
|
setTenant,
|
|
@@ -286,6 +356,12 @@ router.post(
|
|
|
286
356
|
}
|
|
287
357
|
})
|
|
288
358
|
);
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* @name get/signup
|
|
362
|
+
* @function
|
|
363
|
+
* @memberof module:auth/routes~routesRouter
|
|
364
|
+
*/
|
|
289
365
|
router.get(
|
|
290
366
|
"/signup",
|
|
291
367
|
setTenant,
|
|
@@ -325,6 +401,11 @@ router.get(
|
|
|
325
401
|
})
|
|
326
402
|
);
|
|
327
403
|
|
|
404
|
+
/**
|
|
405
|
+
* @name get/create_first_user
|
|
406
|
+
* @function
|
|
407
|
+
* @memberof module:auth/routes~routesRouter
|
|
408
|
+
*/
|
|
328
409
|
router.get(
|
|
329
410
|
"/create_first_user",
|
|
330
411
|
setTenant,
|
|
@@ -350,6 +431,11 @@ router.get(
|
|
|
350
431
|
})
|
|
351
432
|
);
|
|
352
433
|
|
|
434
|
+
/**
|
|
435
|
+
* @name post/create_from_restore
|
|
436
|
+
* @function
|
|
437
|
+
* @memberof module:auth/routes~routesRouter
|
|
438
|
+
*/
|
|
353
439
|
router.post(
|
|
354
440
|
"/create_from_restore",
|
|
355
441
|
setTenant,
|
|
@@ -373,6 +459,12 @@ router.post(
|
|
|
373
459
|
}
|
|
374
460
|
})
|
|
375
461
|
);
|
|
462
|
+
|
|
463
|
+
/**
|
|
464
|
+
* @name post/create_first_user
|
|
465
|
+
* @function
|
|
466
|
+
* @memberof module:auth/routes~routesRouter
|
|
467
|
+
*/
|
|
376
468
|
router.post(
|
|
377
469
|
"/create_first_user",
|
|
378
470
|
setTenant,
|
|
@@ -417,6 +509,13 @@ router.post(
|
|
|
417
509
|
})
|
|
418
510
|
);
|
|
419
511
|
|
|
512
|
+
/**
|
|
513
|
+
* @param {string} new_user_view_name
|
|
514
|
+
* @param {object} req
|
|
515
|
+
* @param {boolean} askEmail
|
|
516
|
+
* @returns {Promise<Form>}
|
|
517
|
+
* @throws {InvalidConfiguration}
|
|
518
|
+
*/
|
|
420
519
|
const getNewUserForm = async (new_user_view_name, req, askEmail) => {
|
|
421
520
|
const view = await View.findOne({ name: new_user_view_name });
|
|
422
521
|
if (!view)
|
|
@@ -488,6 +587,12 @@ const getNewUserForm = async (new_user_view_name, req, askEmail) => {
|
|
|
488
587
|
return form;
|
|
489
588
|
};
|
|
490
589
|
|
|
590
|
+
/**
|
|
591
|
+
* @param {object} u
|
|
592
|
+
* @param {object} req
|
|
593
|
+
* @param {object} res
|
|
594
|
+
* @returns {void}
|
|
595
|
+
*/
|
|
491
596
|
const signup_login_with_user = (u, req, res) =>
|
|
492
597
|
req.login(
|
|
493
598
|
{
|
|
@@ -508,6 +613,11 @@ const signup_login_with_user = (u, req, res) =>
|
|
|
508
613
|
}
|
|
509
614
|
);
|
|
510
615
|
|
|
616
|
+
/**
|
|
617
|
+
* @name get/signup_final_ext
|
|
618
|
+
* @function
|
|
619
|
+
* @memberof module:auth/routes~routesRouter
|
|
620
|
+
*/
|
|
511
621
|
router.get(
|
|
512
622
|
"/signup_final_ext",
|
|
513
623
|
setTenant,
|
|
@@ -525,6 +635,11 @@ router.get(
|
|
|
525
635
|
})
|
|
526
636
|
);
|
|
527
637
|
|
|
638
|
+
/**
|
|
639
|
+
* @name post/signup_final_ext
|
|
640
|
+
* @function
|
|
641
|
+
* @memberof module:auth/routes~routesRouter
|
|
642
|
+
*/
|
|
528
643
|
router.post(
|
|
529
644
|
"/signup_final_ext",
|
|
530
645
|
setTenant,
|
|
@@ -572,6 +687,12 @@ router.post(
|
|
|
572
687
|
}
|
|
573
688
|
})
|
|
574
689
|
);
|
|
690
|
+
|
|
691
|
+
/**
|
|
692
|
+
* @name post/signup_final
|
|
693
|
+
* @function
|
|
694
|
+
* @memberof module:auth/routes~routesRouter
|
|
695
|
+
*/
|
|
575
696
|
router.post(
|
|
576
697
|
"/signup_final",
|
|
577
698
|
setTenant,
|
|
@@ -629,6 +750,11 @@ router.post(
|
|
|
629
750
|
})
|
|
630
751
|
);
|
|
631
752
|
|
|
753
|
+
/**
|
|
754
|
+
* @name post/signup
|
|
755
|
+
* @function
|
|
756
|
+
* @memberof module:auth/routes~routesRouter
|
|
757
|
+
*/
|
|
632
758
|
router.post(
|
|
633
759
|
"/signup",
|
|
634
760
|
setTenant,
|
|
@@ -741,6 +867,11 @@ router.post(
|
|
|
741
867
|
})
|
|
742
868
|
);
|
|
743
869
|
|
|
870
|
+
/**
|
|
871
|
+
* @param {object} req
|
|
872
|
+
* @param {object} res
|
|
873
|
+
* @returns {void}
|
|
874
|
+
*/
|
|
744
875
|
function handler(req, res) {
|
|
745
876
|
console.log(
|
|
746
877
|
`Failed login attempt for: ${req.body.email} from ${req.ip} UA ${req.get(
|
|
@@ -754,7 +885,12 @@ function handler(req, res) {
|
|
|
754
885
|
);
|
|
755
886
|
res.redirect("/auth/login"); // brute force protection triggered, send them back to the login page
|
|
756
887
|
}
|
|
757
|
-
|
|
888
|
+
|
|
889
|
+
/**
|
|
890
|
+
* try to find a unique user id in login submit
|
|
891
|
+
* @param {object} body
|
|
892
|
+
* @returns {string}
|
|
893
|
+
*/
|
|
758
894
|
const userIdKey = (body) => {
|
|
759
895
|
if (body.email) return body.email;
|
|
760
896
|
const { remember, password, _csrf, passwordRepeat, ...rest } = body;
|
|
@@ -777,6 +913,11 @@ const userLimiter = rateLimit({
|
|
|
777
913
|
handler,
|
|
778
914
|
});
|
|
779
915
|
|
|
916
|
+
/**
|
|
917
|
+
* @name post/login
|
|
918
|
+
* @function
|
|
919
|
+
* @memberof module:auth/routes~routesRouter
|
|
920
|
+
*/
|
|
780
921
|
router.post(
|
|
781
922
|
"/login",
|
|
782
923
|
setTenant,
|
|
@@ -805,6 +946,12 @@ router.post(
|
|
|
805
946
|
res.redirect("/");
|
|
806
947
|
})
|
|
807
948
|
);
|
|
949
|
+
|
|
950
|
+
/**
|
|
951
|
+
* @name get/login-with/:method
|
|
952
|
+
* @function
|
|
953
|
+
* @memberof module:auth/routes~routesRouter
|
|
954
|
+
*/
|
|
808
955
|
router.get(
|
|
809
956
|
"/login-with/:method",
|
|
810
957
|
setTenant,
|
|
@@ -822,6 +969,12 @@ router.get(
|
|
|
822
969
|
}
|
|
823
970
|
})
|
|
824
971
|
);
|
|
972
|
+
|
|
973
|
+
/**
|
|
974
|
+
* @name post/login-with/:method
|
|
975
|
+
* @function
|
|
976
|
+
* @memberof module:auth/routes~routesRouter
|
|
977
|
+
*/
|
|
825
978
|
router.post(
|
|
826
979
|
"/login-with/:method",
|
|
827
980
|
setTenant,
|
|
@@ -845,6 +998,11 @@ router.post(
|
|
|
845
998
|
})
|
|
846
999
|
);
|
|
847
1000
|
|
|
1001
|
+
/**
|
|
1002
|
+
* @param {object}} req
|
|
1003
|
+
* @param {object} res
|
|
1004
|
+
* @returns {void}
|
|
1005
|
+
*/
|
|
848
1006
|
const loginCallback = (req, res) => () => {
|
|
849
1007
|
if (!req.user) return;
|
|
850
1008
|
if (!req.user.id) {
|
|
@@ -859,6 +1017,11 @@ const loginCallback = (req, res) => () => {
|
|
|
859
1017
|
}
|
|
860
1018
|
};
|
|
861
1019
|
|
|
1020
|
+
/**
|
|
1021
|
+
* @name get/callback/:method
|
|
1022
|
+
* @function
|
|
1023
|
+
* @memberof module:auth/routes~routesRouter
|
|
1024
|
+
*/
|
|
862
1025
|
router.get(
|
|
863
1026
|
"/callback/:method",
|
|
864
1027
|
setTenant,
|
|
@@ -875,6 +1038,10 @@ router.get(
|
|
|
875
1038
|
})
|
|
876
1039
|
);
|
|
877
1040
|
|
|
1041
|
+
/**
|
|
1042
|
+
* @param {object} req
|
|
1043
|
+
* @returns {Form}
|
|
1044
|
+
*/
|
|
878
1045
|
const changPwForm = (req) =>
|
|
879
1046
|
new Form({
|
|
880
1047
|
action: "/auth/settings",
|
|
@@ -895,6 +1062,12 @@ const changPwForm = (req) =>
|
|
|
895
1062
|
},
|
|
896
1063
|
],
|
|
897
1064
|
});
|
|
1065
|
+
|
|
1066
|
+
/**
|
|
1067
|
+
* @param {object} req
|
|
1068
|
+
* @param {object} user
|
|
1069
|
+
* @returns {Form}
|
|
1070
|
+
*/
|
|
898
1071
|
const setLanguageForm = (req, user) =>
|
|
899
1072
|
form(
|
|
900
1073
|
{
|
|
@@ -916,6 +1089,14 @@ const setLanguageForm = (req, user) =>
|
|
|
916
1089
|
)
|
|
917
1090
|
);
|
|
918
1091
|
|
|
1092
|
+
/**
|
|
1093
|
+
* @param {object} opts
|
|
1094
|
+
* @param {object} opts.req
|
|
1095
|
+
* @param {object} opts.res
|
|
1096
|
+
* @param {object} opts.pwform
|
|
1097
|
+
* @param {object} opts.user
|
|
1098
|
+
* @returns {Promise<object>}
|
|
1099
|
+
*/
|
|
919
1100
|
const userSettings = async ({ req, res, pwform, user }) => {
|
|
920
1101
|
let usersets;
|
|
921
1102
|
const user_settings_form = getState().getConfig("user_settings_form", "");
|
|
@@ -962,8 +1143,12 @@ const userSettings = async ({ req, res, pwform, user }) => {
|
|
|
962
1143
|
],
|
|
963
1144
|
};
|
|
964
1145
|
};
|
|
1146
|
+
|
|
965
1147
|
/**
|
|
966
1148
|
* Set language
|
|
1149
|
+
* @name post/setlanguage
|
|
1150
|
+
* @function
|
|
1151
|
+
* @memberof module:auth/routes~routesRouter
|
|
967
1152
|
*/
|
|
968
1153
|
router.post(
|
|
969
1154
|
"/setlanguage",
|
|
@@ -998,6 +1183,12 @@ router.post(
|
|
|
998
1183
|
}
|
|
999
1184
|
})
|
|
1000
1185
|
);
|
|
1186
|
+
|
|
1187
|
+
/**
|
|
1188
|
+
* @name get/settings
|
|
1189
|
+
* @function
|
|
1190
|
+
* @memberof module:auth/routes~routesRouter
|
|
1191
|
+
*/
|
|
1001
1192
|
router.get(
|
|
1002
1193
|
"/settings",
|
|
1003
1194
|
setTenant,
|
|
@@ -1010,9 +1201,10 @@ router.get(
|
|
|
1010
1201
|
);
|
|
1011
1202
|
})
|
|
1012
1203
|
);
|
|
1204
|
+
|
|
1013
1205
|
/**
|
|
1014
1206
|
* Define set email form for user
|
|
1015
|
-
* @param req
|
|
1207
|
+
* @param {object} req
|
|
1016
1208
|
* @returns {Form}
|
|
1017
1209
|
*/
|
|
1018
1210
|
const setEmailForm = (req) =>
|
|
@@ -1031,8 +1223,12 @@ const setEmailForm = (req) =>
|
|
|
1031
1223
|
},
|
|
1032
1224
|
],
|
|
1033
1225
|
});
|
|
1226
|
+
|
|
1034
1227
|
/**
|
|
1035
1228
|
* Render form for set email for user
|
|
1229
|
+
* @name get/set-email
|
|
1230
|
+
* @function
|
|
1231
|
+
* @memberof module:auth/routes~routesRouter
|
|
1036
1232
|
*/
|
|
1037
1233
|
router.get(
|
|
1038
1234
|
"/set-email",
|
|
@@ -1044,8 +1240,12 @@ router.get(
|
|
|
1044
1240
|
);
|
|
1045
1241
|
})
|
|
1046
1242
|
);
|
|
1243
|
+
|
|
1047
1244
|
/**
|
|
1048
1245
|
* Execute set email for user
|
|
1246
|
+
* @name post/set-email
|
|
1247
|
+
* @function
|
|
1248
|
+
* @memberof module:auth/routes~routesRouter
|
|
1049
1249
|
*/
|
|
1050
1250
|
router.post(
|
|
1051
1251
|
"/set-email",
|
|
@@ -1090,8 +1290,12 @@ router.post(
|
|
|
1090
1290
|
);
|
|
1091
1291
|
})
|
|
1092
1292
|
);
|
|
1293
|
+
|
|
1093
1294
|
/**
|
|
1094
1295
|
* Execute Change Password for User
|
|
1296
|
+
* @name post/settings
|
|
1297
|
+
* @function
|
|
1298
|
+
* @memberof module:auth/routes~routesRouter
|
|
1095
1299
|
*/
|
|
1096
1300
|
router.post(
|
|
1097
1301
|
"/settings",
|
|
@@ -1139,6 +1343,11 @@ router.post(
|
|
|
1139
1343
|
})
|
|
1140
1344
|
);
|
|
1141
1345
|
|
|
1346
|
+
/**
|
|
1347
|
+
* @name all/verification-flow
|
|
1348
|
+
* @function
|
|
1349
|
+
* @memberof module:auth/routes~routesRouter
|
|
1350
|
+
*/
|
|
1142
1351
|
router.all(
|
|
1143
1352
|
"/verification-flow",
|
|
1144
1353
|
setTenant,
|
package/auth/testhelp.js
CHANGED
|
@@ -1,9 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @category server
|
|
3
|
+
* @module auth/testhelp
|
|
4
|
+
* @subcategory auth
|
|
5
|
+
*/
|
|
1
6
|
const request = require("supertest");
|
|
2
7
|
const app = require("../app");
|
|
3
8
|
const getApp = require("../app");
|
|
4
9
|
const fixtures = require("@saltcorn/data/db/fixtures");
|
|
5
10
|
const reset = require("@saltcorn/data/db/reset_schema");
|
|
6
11
|
|
|
12
|
+
/**
|
|
13
|
+
*
|
|
14
|
+
* @param {string} loc
|
|
15
|
+
* @returns {void}
|
|
16
|
+
* @throws {Error}
|
|
17
|
+
*/
|
|
7
18
|
const toRedirect = (loc) => (res) => {
|
|
8
19
|
if (res.statusCode !== 302) {
|
|
9
20
|
console.log(res.text);
|
|
@@ -15,6 +26,13 @@ const toRedirect = (loc) => (res) => {
|
|
|
15
26
|
}
|
|
16
27
|
};
|
|
17
28
|
|
|
29
|
+
/**
|
|
30
|
+
*
|
|
31
|
+
* @param {number} txt
|
|
32
|
+
* @param {number} expCode
|
|
33
|
+
* @returns {void}
|
|
34
|
+
* @throws {Error}
|
|
35
|
+
*/
|
|
18
36
|
const toInclude = (txt, expCode = 200) => (res) => {
|
|
19
37
|
if (res.statusCode !== expCode) {
|
|
20
38
|
console.log(res.text);
|
|
@@ -29,6 +47,12 @@ const toInclude = (txt, expCode = 200) => (res) => {
|
|
|
29
47
|
}
|
|
30
48
|
};
|
|
31
49
|
|
|
50
|
+
/**
|
|
51
|
+
*
|
|
52
|
+
* @param {number} expCode
|
|
53
|
+
* @returns {void}
|
|
54
|
+
* @throws {Error}
|
|
55
|
+
*/
|
|
32
56
|
const toSucceed = (expCode = 200) => (res) => {
|
|
33
57
|
if (res.statusCode !== expCode) {
|
|
34
58
|
console.log(res.text);
|
|
@@ -36,6 +60,13 @@ const toSucceed = (expCode = 200) => (res) => {
|
|
|
36
60
|
}
|
|
37
61
|
};
|
|
38
62
|
|
|
63
|
+
/**
|
|
64
|
+
*
|
|
65
|
+
* @param {number} txt
|
|
66
|
+
* @param {number} expCode
|
|
67
|
+
* @returns {void}
|
|
68
|
+
* @throws {Error}
|
|
69
|
+
*/
|
|
39
70
|
const toNotInclude = (txt, expCode = 200) => (res) => {
|
|
40
71
|
if (res.statusCode !== expCode) {
|
|
41
72
|
console.log(res.text);
|
|
@@ -49,6 +80,11 @@ const toNotInclude = (txt, expCode = 200) => (res) => {
|
|
|
49
80
|
throw new Error(`Expected text ${txt} to be absent, but was present`);
|
|
50
81
|
}
|
|
51
82
|
};
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
*
|
|
86
|
+
* @returns {Promise<void>}
|
|
87
|
+
*/
|
|
52
88
|
const getStaffLoginCookie = async () => {
|
|
53
89
|
const app = await getApp({ disableCsrf: true });
|
|
54
90
|
const res = await request(app)
|
|
@@ -59,6 +95,10 @@ const getStaffLoginCookie = async () => {
|
|
|
59
95
|
return res.headers["set-cookie"][0];
|
|
60
96
|
};
|
|
61
97
|
|
|
98
|
+
/**
|
|
99
|
+
*
|
|
100
|
+
* @returns {Promise<void>}
|
|
101
|
+
*/
|
|
62
102
|
const getAdminLoginCookie = async () => {
|
|
63
103
|
const app = await getApp({ disableCsrf: true });
|
|
64
104
|
const res = await request(app)
|
|
@@ -70,6 +110,12 @@ const getAdminLoginCookie = async () => {
|
|
|
70
110
|
return res.headers["set-cookie"][0];
|
|
71
111
|
};
|
|
72
112
|
|
|
113
|
+
/**
|
|
114
|
+
*
|
|
115
|
+
* @param {string} path
|
|
116
|
+
* @param {string} dest
|
|
117
|
+
* @returns {void}
|
|
118
|
+
*/
|
|
73
119
|
const itShouldRedirectUnauthToLogin = (path, dest) => {
|
|
74
120
|
it(`should redirect unauth ${path} to ${dest || "login"}`, async () => {
|
|
75
121
|
const app = await getApp({ disableCsrf: true });
|
|
@@ -82,11 +128,20 @@ const itShouldRedirectUnauthToLogin = (path, dest) => {
|
|
|
82
128
|
});
|
|
83
129
|
};
|
|
84
130
|
|
|
131
|
+
/**
|
|
132
|
+
* @returns {Promise<void>}
|
|
133
|
+
*/
|
|
85
134
|
const resetToFixtures = async () => {
|
|
86
135
|
await reset();
|
|
87
136
|
await fixtures();
|
|
88
137
|
};
|
|
89
138
|
|
|
139
|
+
/**
|
|
140
|
+
*
|
|
141
|
+
* @param {*} pred
|
|
142
|
+
* @returns {void}
|
|
143
|
+
* @throws {Error}
|
|
144
|
+
*/
|
|
90
145
|
const succeedJsonWith = (pred) => (res) => {
|
|
91
146
|
if (res.statusCode !== 200) {
|
|
92
147
|
console.log(res.text);
|
|
@@ -99,6 +154,13 @@ const succeedJsonWith = (pred) => (res) => {
|
|
|
99
154
|
}
|
|
100
155
|
};
|
|
101
156
|
|
|
157
|
+
/**
|
|
158
|
+
*
|
|
159
|
+
* @param {number} code
|
|
160
|
+
* @param {number} pred
|
|
161
|
+
* @returns {void}
|
|
162
|
+
* @throws {Error}
|
|
163
|
+
*/
|
|
102
164
|
const respondJsonWith = (code, pred) => (res) => {
|
|
103
165
|
if (res.statusCode !== code) {
|
|
104
166
|
console.log(res.text);
|
|
@@ -110,6 +172,13 @@ const respondJsonWith = (code, pred) => (res) => {
|
|
|
110
172
|
throw new Error(`Not satisfied`);
|
|
111
173
|
}
|
|
112
174
|
};
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
*
|
|
178
|
+
* @param {object} res
|
|
179
|
+
* @returns {void}
|
|
180
|
+
* @throws {Error}
|
|
181
|
+
*/
|
|
113
182
|
const notAuthorized = (res) => {
|
|
114
183
|
if (res.statusCode !== 401) {
|
|
115
184
|
console.log(res.text);
|
package/errors.js
CHANGED
|
@@ -1,9 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @category server
|
|
3
|
+
* @module errors
|
|
4
|
+
*/
|
|
1
5
|
const db = require("@saltcorn/data/db");
|
|
2
6
|
const { pre, p, text, h3 } = require("@saltcorn/markup/tags");
|
|
3
7
|
const Crash = require("@saltcorn/data/models/crash");
|
|
4
8
|
const { getState } = require("@saltcorn/data/db/state");
|
|
5
9
|
|
|
6
|
-
module.exports =
|
|
10
|
+
module.exports =
|
|
11
|
+
/**
|
|
12
|
+
*
|
|
13
|
+
* @param {object} err
|
|
14
|
+
* @param {object} req
|
|
15
|
+
* @param {object} res
|
|
16
|
+
* @param {*} next
|
|
17
|
+
* @returns {Promise<void>}
|
|
18
|
+
*/
|
|
19
|
+
async function (err, req, res, next) {
|
|
7
20
|
if (!req.__) req.__ = (s) => s;
|
|
8
21
|
|
|
9
22
|
const devmode = getState().getConfig("development_mode", false);
|
package/fixture_persons.js
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @category server
|
|
3
|
+
* @module fixture_persons
|
|
4
|
+
*/
|
|
1
5
|
const db = require("@saltcorn/data/db");
|
|
2
6
|
const { getState } = require("@saltcorn/data/db/state");
|
|
3
7
|
const Table = require("@saltcorn/data/models/table");
|
|
@@ -8,8 +12,15 @@ const basePlugin = require("@saltcorn/base-plugin");
|
|
|
8
12
|
|
|
9
13
|
getState().registerPlugin("base", basePlugin);
|
|
10
14
|
|
|
15
|
+
/**
|
|
16
|
+
* @param {object[]} vs
|
|
17
|
+
* @returns {object}
|
|
18
|
+
*/
|
|
11
19
|
const rndElem = (vs) => vs[Math.floor(Math.random() * vs.length)];
|
|
12
20
|
|
|
21
|
+
/**
|
|
22
|
+
* @returns {object}
|
|
23
|
+
*/
|
|
13
24
|
const randomPerson = () => {
|
|
14
25
|
const gender = Math.random() > 0.5 ? "Female" : "Male";
|
|
15
26
|
const last_name = rndElem(
|
|
@@ -27,6 +38,9 @@ const randomPerson = () => {
|
|
|
27
38
|
return { gender, last_name, first_name, age };
|
|
28
39
|
};
|
|
29
40
|
|
|
41
|
+
/**
|
|
42
|
+
* @returns {Promise<void>}
|
|
43
|
+
*/
|
|
30
44
|
const fixturePersons = async () => {
|
|
31
45
|
await db.query(`drop table if exists persons`);
|
|
32
46
|
const table = await Table.create("persons");
|
package/index.js
ADDED
package/load_plugins.js
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
* Load plugins
|
|
3
3
|
* File: load_plugins.js
|
|
4
4
|
*
|
|
5
|
+
* @category server
|
|
6
|
+
* @module load_plugins
|
|
5
7
|
*/
|
|
6
8
|
const db = require("@saltcorn/data/db");
|
|
7
9
|
const { PluginManager } = require("live-plugin-manager");
|
|
@@ -42,12 +44,12 @@ const manager = new PluginManager({
|
|
|
42
44
|
"@saltcorn/data/models/workflow": require("@saltcorn/data/models/workflow"),
|
|
43
45
|
},
|
|
44
46
|
});
|
|
47
|
+
|
|
45
48
|
/**
|
|
46
49
|
* Load one plugin
|
|
47
50
|
* TODO correct names for functions loadPlugin, requirePlugin - currently uncler
|
|
48
51
|
* @param plugin - plugin to load
|
|
49
52
|
* @param force - force flag
|
|
50
|
-
* @returns {Promise<{plugin_module: *}|{readonly name: string, readonly location: string, plugin_module: *, readonly mainFile: string, readonly version: string, readonly dependencies: {[p: string]: string}}|{readonly name: string, readonly location: string, plugin_module: *, readonly mainFile: string, readonly version: string, readonly dependencies: {[p: string]: string}}|{readonly name: string, readonly location: string, plugin_module: *, readonly mainFile: string, readonly version: string, readonly dependencies: {[p: string]: string}}|{readonly name: string, readonly location: string, plugin_module: *, readonly mainFile: string, readonly version: string, readonly dependencies: {[p: string]: string}}|{readonly name: string, readonly location: string, plugin_module: *, readonly mainFile: string, readonly version: string, readonly dependencies: {[p: string]: string}}>}
|
|
51
53
|
*/
|
|
52
54
|
const loadPlugin = async (plugin, force) => {
|
|
53
55
|
// load pluging
|
|
@@ -69,13 +71,12 @@ const loadPlugin = async (plugin, force) => {
|
|
|
69
71
|
}
|
|
70
72
|
return res;
|
|
71
73
|
};
|
|
74
|
+
|
|
72
75
|
/**
|
|
73
76
|
*
|
|
74
77
|
* @param plugin
|
|
75
78
|
* @param force
|
|
76
|
-
* @returns {Promise<{plugin_module: *}|{readonly name: string, readonly location: string, plugin_module: any, readonly mainFile: string, readonly version: string, readonly dependencies: {[p: string]: string}}>}
|
|
77
79
|
*/
|
|
78
|
-
|
|
79
80
|
const gitPullOrClone = async (plugin) => {
|
|
80
81
|
await fs.promises.mkdir("git_plugins", { recursive: true });
|
|
81
82
|
let keyfnm,
|