@saltcorn/server 1.1.1-beta.5 → 1.1.1-beta.7
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/CHANGELOG.md +6 -0
- package/auth/admin.js +8 -0
- package/locales/en.json +16 -1
- package/markup/admin.js +8 -3
- package/markup/blockly.js +4 -4
- package/package.json +9 -9
- package/public/blockly/blockly_compressed.js +2016 -0
- package/public/blockly/blockly_compressed.js.map +1 -0
- package/public/blockly/blocks_compressed.js +212 -0
- package/public/blockly/blocks_compressed.js.map +1 -0
- package/public/blockly/javascript_compressed.js +121 -0
- package/public/blockly/javascript_compressed.js.map +1 -0
- package/public/blockly/msg/ab.js +440 -0
- package/public/blockly/msg/ace.js +440 -0
- package/public/blockly/msg/af.js +440 -0
- package/public/blockly/msg/am.js +440 -0
- package/public/blockly/msg/ar.js +440 -0
- package/public/blockly/msg/ast.js +440 -0
- package/public/blockly/msg/az.js +440 -0
- package/public/blockly/msg/ba.js +440 -0
- package/public/blockly/msg/bcc.js +440 -0
- package/public/blockly/msg/be-tarask.js +440 -0
- package/public/blockly/msg/be.js +440 -0
- package/public/blockly/msg/bg.js +440 -0
- package/public/blockly/msg/bn.js +440 -0
- package/public/blockly/msg/br.js +440 -0
- package/public/blockly/msg/bs.js +440 -0
- package/public/blockly/msg/ca.js +440 -0
- package/public/blockly/msg/cdo.js +440 -0
- package/public/blockly/msg/cs.js +440 -0
- package/public/blockly/msg/da.js +440 -0
- package/public/blockly/msg/de.js +440 -0
- package/public/blockly/msg/diq.js +440 -0
- package/public/blockly/msg/dty.js +440 -0
- package/public/blockly/msg/ee.js +440 -0
- package/public/blockly/msg/el.js +440 -0
- package/public/blockly/msg/en-gb.js +440 -0
- package/public/blockly/msg/en.js +440 -0
- package/public/blockly/msg/eo.js +440 -0
- package/public/blockly/msg/es.js +440 -0
- package/public/blockly/msg/et.js +440 -0
- package/public/blockly/msg/eu.js +440 -0
- package/public/blockly/msg/fa.js +440 -0
- package/public/blockly/msg/fi.js +440 -0
- package/public/blockly/msg/fo.js +440 -0
- package/public/blockly/msg/fr.js +440 -0
- package/public/blockly/msg/frr.js +440 -0
- package/public/blockly/msg/gl.js +440 -0
- package/public/blockly/msg/gn.js +440 -0
- package/public/blockly/msg/gor.js +440 -0
- package/public/blockly/msg/ha.js +440 -0
- package/public/blockly/msg/hak.js +440 -0
- package/public/blockly/msg/he.js +440 -0
- package/public/blockly/msg/hi.js +440 -0
- package/public/blockly/msg/hr.js +440 -0
- package/public/blockly/msg/hrx.js +440 -0
- package/public/blockly/msg/hu.js +440 -0
- package/public/blockly/msg/hy.js +440 -0
- package/public/blockly/msg/ia.js +440 -0
- package/public/blockly/msg/id.js +440 -0
- package/public/blockly/msg/ig.js +440 -0
- package/public/blockly/msg/inh.js +440 -0
- package/public/blockly/msg/is.js +440 -0
- package/public/blockly/msg/it.js +440 -0
- package/public/blockly/msg/ja.js +440 -0
- package/public/blockly/msg/ka.js +440 -0
- package/public/blockly/msg/kab.js +440 -0
- package/public/blockly/msg/kbd-cyrl.js +440 -0
- package/public/blockly/msg/km.js +440 -0
- package/public/blockly/msg/kn.js +440 -0
- package/public/blockly/msg/ko.js +440 -0
- package/public/blockly/msg/ksh.js +440 -0
- package/public/blockly/msg/ku-latn.js +440 -0
- package/public/blockly/msg/ky.js +440 -0
- package/public/blockly/msg/la.js +440 -0
- package/public/blockly/msg/lb.js +440 -0
- package/public/blockly/msg/lki.js +440 -0
- package/public/blockly/msg/lo.js +440 -0
- package/public/blockly/msg/lrc.js +440 -0
- package/public/blockly/msg/lt.js +440 -0
- package/public/blockly/msg/lv.js +440 -0
- package/public/blockly/msg/mg.js +440 -0
- package/public/blockly/msg/mk.js +440 -0
- package/public/blockly/msg/ml.js +440 -0
- package/public/blockly/msg/mnw.js +440 -0
- package/public/blockly/msg/ms.js +440 -0
- package/public/blockly/msg/msg.d.ts +444 -0
- package/public/blockly/msg/my.js +440 -0
- package/public/blockly/msg/mzn.js +440 -0
- package/public/blockly/msg/nb.js +440 -0
- package/public/blockly/msg/ne.js +440 -0
- package/public/blockly/msg/nl.js +440 -0
- package/public/blockly/msg/oc.js +440 -0
- package/public/blockly/msg/olo.js +440 -0
- package/public/blockly/msg/pa.js +440 -0
- package/public/blockly/msg/pl.js +440 -0
- package/public/blockly/msg/pms.js +440 -0
- package/public/blockly/msg/ps.js +440 -0
- package/public/blockly/msg/pt-br.js +440 -0
- package/public/blockly/msg/pt.js +440 -0
- package/public/blockly/msg/ro.js +440 -0
- package/public/blockly/msg/ru.js +440 -0
- package/public/blockly/msg/sc.js +440 -0
- package/public/blockly/msg/sco.js +440 -0
- package/public/blockly/msg/sd.js +440 -0
- package/public/blockly/msg/shn.js +440 -0
- package/public/blockly/msg/si.js +440 -0
- package/public/blockly/msg/sk.js +440 -0
- package/public/blockly/msg/skr-arab.js +440 -0
- package/public/blockly/msg/sl.js +440 -0
- package/public/blockly/msg/smn.js +440 -0
- package/public/blockly/msg/sq.js +440 -0
- package/public/blockly/msg/sr-latn.js +440 -0
- package/public/blockly/msg/sr.js +440 -0
- package/public/blockly/msg/sv.js +440 -0
- package/public/blockly/msg/sw.js +440 -0
- package/public/blockly/msg/ta.js +440 -0
- package/public/blockly/msg/tcy.js +440 -0
- package/public/blockly/msg/te.js +440 -0
- package/public/blockly/msg/th.js +440 -0
- package/public/blockly/msg/ti.js +440 -0
- package/public/blockly/msg/tl.js +440 -0
- package/public/blockly/msg/tlh.js +440 -0
- package/public/blockly/msg/tr.js +440 -0
- package/public/blockly/msg/ug-arab.js +440 -0
- package/public/blockly/msg/uk.js +440 -0
- package/public/blockly/msg/ur.js +440 -0
- package/public/blockly/msg/uz.js +440 -0
- package/public/blockly/msg/vi.js +440 -0
- package/public/blockly/msg/xmf.js +440 -0
- package/public/blockly/msg/yo.js +440 -0
- package/public/blockly/msg/yue.js +440 -0
- package/public/blockly/msg/zgh.js +440 -0
- package/public/blockly/msg/zh-hans.js +440 -0
- package/public/blockly/msg/zh-hant.js +440 -0
- package/public/saltcorn-common.js +8 -1
- package/public/saltcorn.js +12 -0
- package/routes/actions.js +32 -25
- package/routes/admin.js +90 -63
- package/routes/common_lists.js +46 -24
- package/routes/fields.js +31 -9
- package/routes/list.js +17 -4
- package/routes/notifications.js +27 -20
- package/routes/pageedit.js +14 -13
- package/routes/plugins.js +0 -32
- package/routes/tables.js +173 -92
- package/routes/utils.js +27 -0
- package/routes/view.js +2 -1
- package/routes/viewedit.js +14 -13
- package/serve.js +52 -1
- package/tests/api.test.js +0 -18
- package/tests/plugins.test.js +2 -2
- package/wrapper.js +80 -42
package/routes/actions.js
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
const Router = require("express-promise-router");
|
|
8
8
|
const {
|
|
9
9
|
isAdmin,
|
|
10
|
+
isAdminOrHasConfigMinRole,
|
|
10
11
|
error_catcher,
|
|
11
12
|
addOnDoneRedirect,
|
|
12
13
|
is_relative_url,
|
|
@@ -85,7 +86,7 @@ const {
|
|
|
85
86
|
*/
|
|
86
87
|
router.get(
|
|
87
88
|
"/",
|
|
88
|
-
|
|
89
|
+
isAdminOrHasConfigMinRole("min_role_edit_triggers"),
|
|
89
90
|
error_catcher(async (req, res) => {
|
|
90
91
|
let triggers = await Trigger.findAllWithTableName();
|
|
91
92
|
let filterOnTag;
|
|
@@ -347,7 +348,7 @@ const triggerForm = async (req, trigger) => {
|
|
|
347
348
|
*/
|
|
348
349
|
router.get(
|
|
349
350
|
"/new",
|
|
350
|
-
|
|
351
|
+
isAdminOrHasConfigMinRole("min_role_edit_triggers"),
|
|
351
352
|
error_catcher(async (req, res) => {
|
|
352
353
|
const form = await triggerForm(req);
|
|
353
354
|
if (req.query.table) {
|
|
@@ -388,7 +389,7 @@ router.get(
|
|
|
388
389
|
*/
|
|
389
390
|
router.get(
|
|
390
391
|
"/edit/:id",
|
|
391
|
-
|
|
392
|
+
isAdminOrHasConfigMinRole("min_role_edit_triggers"),
|
|
392
393
|
error_catcher(async (req, res) => {
|
|
393
394
|
const { id } = req.params;
|
|
394
395
|
const trigger = await Trigger.findOne({ id });
|
|
@@ -419,7 +420,7 @@ router.get(
|
|
|
419
420
|
*/
|
|
420
421
|
router.post(
|
|
421
422
|
"/new",
|
|
422
|
-
|
|
423
|
+
isAdminOrHasConfigMinRole("min_role_edit_triggers"),
|
|
423
424
|
error_catcher(async (req, res) => {
|
|
424
425
|
const form = await triggerForm(req);
|
|
425
426
|
|
|
@@ -462,7 +463,7 @@ router.post(
|
|
|
462
463
|
*/
|
|
463
464
|
router.post(
|
|
464
465
|
"/edit/:id",
|
|
465
|
-
|
|
466
|
+
isAdminOrHasConfigMinRole("min_role_edit_triggers"),
|
|
466
467
|
error_catcher(async (req, res) => {
|
|
467
468
|
const { id } = req.params;
|
|
468
469
|
const trigger = await Trigger.findOne({ id });
|
|
@@ -523,7 +524,7 @@ function genWorkflowDiagram(steps) {
|
|
|
523
524
|
);
|
|
524
525
|
if (stepNames.includes(step.next_step)) {
|
|
525
526
|
linkLines.push(
|
|
526
|
-
` ${step.mmname}-- <i class="fas fa-plus add-btw-nodes btw-nodes-${step.id}-${step.next_step}"></i>
|
|
527
|
+
` ${step.mmname} -- <i class="fas fa-plus add-btw-nodes btw-nodes-${step.id}-${step.next_step}"></i> --- ${step.mmnext}`
|
|
527
528
|
);
|
|
528
529
|
} else if (step.next_step) {
|
|
529
530
|
let found = false;
|
|
@@ -928,7 +929,7 @@ const getMultiStepForm = async (req, id, table) => {
|
|
|
928
929
|
*/
|
|
929
930
|
router.get(
|
|
930
931
|
"/configure/:idorname",
|
|
931
|
-
|
|
932
|
+
isAdminOrHasConfigMinRole("min_role_edit_triggers"),
|
|
932
933
|
error_catcher(async (req, res) => {
|
|
933
934
|
const { idorname } = req.params;
|
|
934
935
|
let trigger;
|
|
@@ -1130,7 +1131,7 @@ router.get(
|
|
|
1130
1131
|
*/
|
|
1131
1132
|
router.post(
|
|
1132
1133
|
"/configure/:id",
|
|
1133
|
-
|
|
1134
|
+
isAdminOrHasConfigMinRole("min_role_edit_triggers"),
|
|
1134
1135
|
error_catcher(async (req, res) => {
|
|
1135
1136
|
const { id } = req.params;
|
|
1136
1137
|
const trigger = await Trigger.findOne({ id });
|
|
@@ -1202,7 +1203,7 @@ router.post(
|
|
|
1202
1203
|
*/
|
|
1203
1204
|
router.post(
|
|
1204
1205
|
"/delete/:id",
|
|
1205
|
-
|
|
1206
|
+
isAdminOrHasConfigMinRole("min_role_edit_triggers"),
|
|
1206
1207
|
error_catcher(async (req, res) => {
|
|
1207
1208
|
const { id } = req.params;
|
|
1208
1209
|
const trigger = await Trigger.findOne({ id });
|
|
@@ -1211,7 +1212,13 @@ router.post(
|
|
|
1211
1212
|
entity_name: trigger.name,
|
|
1212
1213
|
});
|
|
1213
1214
|
await trigger.delete();
|
|
1214
|
-
|
|
1215
|
+
req.flash("success", req.__(`Trigger %s deleted`, trigger.name));
|
|
1216
|
+
let redirectTarget =
|
|
1217
|
+
req.query.on_done_redirect &&
|
|
1218
|
+
is_relative_url("/" + req.query.on_done_redirect)
|
|
1219
|
+
? `/${req.query.on_done_redirect}`
|
|
1220
|
+
: "/actions/";
|
|
1221
|
+
res.redirect(redirectTarget);
|
|
1215
1222
|
})
|
|
1216
1223
|
);
|
|
1217
1224
|
|
|
@@ -1222,7 +1229,7 @@ router.post(
|
|
|
1222
1229
|
*/
|
|
1223
1230
|
router.get(
|
|
1224
1231
|
"/testrun/:id",
|
|
1225
|
-
|
|
1232
|
+
isAdminOrHasConfigMinRole("min_role_edit_triggers"),
|
|
1226
1233
|
error_catcher(async (req, res) => {
|
|
1227
1234
|
const { id } = req.params;
|
|
1228
1235
|
const trigger = await Trigger.findOne({ id });
|
|
@@ -1333,7 +1340,7 @@ router.get(
|
|
|
1333
1340
|
*/
|
|
1334
1341
|
router.post(
|
|
1335
1342
|
"/clone/:id",
|
|
1336
|
-
|
|
1343
|
+
isAdminOrHasConfigMinRole("min_role_edit_triggers"),
|
|
1337
1344
|
error_catcher(async (req, res) => {
|
|
1338
1345
|
const { id } = req.params;
|
|
1339
1346
|
const trig = await Trigger.findOne({ id });
|
|
@@ -1358,7 +1365,7 @@ router.post(
|
|
|
1358
1365
|
*/
|
|
1359
1366
|
router.get(
|
|
1360
1367
|
"/stepedit/:trigger_id/:step_id?",
|
|
1361
|
-
|
|
1368
|
+
isAdminOrHasConfigMinRole("min_role_edit_triggers"),
|
|
1362
1369
|
error_catcher(async (req, res) => {
|
|
1363
1370
|
const { trigger_id, step_id } = req.params;
|
|
1364
1371
|
const { initial_step, after_step, before_step } = req.query;
|
|
@@ -1400,7 +1407,7 @@ router.get(
|
|
|
1400
1407
|
|
|
1401
1408
|
router.post(
|
|
1402
1409
|
"/stepedit/:trigger_id",
|
|
1403
|
-
|
|
1410
|
+
isAdminOrHasConfigMinRole("min_role_edit_triggers"),
|
|
1404
1411
|
error_catcher(async (req, res) => {
|
|
1405
1412
|
const { trigger_id } = req.params;
|
|
1406
1413
|
const trigger = await Trigger.findOne({ id: trigger_id });
|
|
@@ -1499,7 +1506,7 @@ router.post(
|
|
|
1499
1506
|
|
|
1500
1507
|
router.post(
|
|
1501
1508
|
"/gen-copilot/:trigger_id",
|
|
1502
|
-
|
|
1509
|
+
isAdminOrHasConfigMinRole("min_role_edit_triggers"),
|
|
1503
1510
|
error_catcher(async (req, res) => {
|
|
1504
1511
|
const { trigger_id } = req.params;
|
|
1505
1512
|
const trigger = await Trigger.findOne({ id: trigger_id });
|
|
@@ -1525,18 +1532,18 @@ router.post(
|
|
|
1525
1532
|
|
|
1526
1533
|
router.post(
|
|
1527
1534
|
"/delete-step/:step_id",
|
|
1528
|
-
|
|
1535
|
+
isAdminOrHasConfigMinRole("min_role_edit_triggers"),
|
|
1529
1536
|
error_catcher(async (req, res) => {
|
|
1530
1537
|
const { step_id } = req.params;
|
|
1531
1538
|
const step = await WorkflowStep.findOne({ id: step_id });
|
|
1532
|
-
await step.delete();
|
|
1539
|
+
await step.delete(true);
|
|
1533
1540
|
res.json({ goto: `/actions/configure/${step.trigger_id}` });
|
|
1534
1541
|
})
|
|
1535
1542
|
);
|
|
1536
1543
|
|
|
1537
1544
|
router.get(
|
|
1538
1545
|
"/runs",
|
|
1539
|
-
|
|
1546
|
+
isAdminOrHasConfigMinRole("min_role_edit_triggers"),
|
|
1540
1547
|
error_catcher(async (req, res) => {
|
|
1541
1548
|
const trNames = {};
|
|
1542
1549
|
const { _page, trigger } = req.query;
|
|
@@ -1563,7 +1570,7 @@ router.get(
|
|
|
1563
1570
|
key: (run) => {
|
|
1564
1571
|
switch (run.status) {
|
|
1565
1572
|
case "Running":
|
|
1566
|
-
return run.
|
|
1573
|
+
return run.current_step_name;
|
|
1567
1574
|
case "Error":
|
|
1568
1575
|
return run.error;
|
|
1569
1576
|
case "Waiting":
|
|
@@ -1571,9 +1578,9 @@ router.get(
|
|
|
1571
1578
|
return a(
|
|
1572
1579
|
{ href: `/actions/fill-workflow-form/${run.id}` },
|
|
1573
1580
|
run.wait_info.output ? "Show " : "Fill ",
|
|
1574
|
-
run.
|
|
1581
|
+
run.current_step_name
|
|
1575
1582
|
);
|
|
1576
|
-
return run.
|
|
1583
|
+
return run.current_step_name;
|
|
1577
1584
|
default:
|
|
1578
1585
|
return "";
|
|
1579
1586
|
}
|
|
@@ -1607,7 +1614,7 @@ router.get(
|
|
|
1607
1614
|
|
|
1608
1615
|
router.get(
|
|
1609
1616
|
"/run/:id",
|
|
1610
|
-
|
|
1617
|
+
isAdminOrHasConfigMinRole("min_role_edit_triggers"),
|
|
1611
1618
|
error_catcher(async (req, res) => {
|
|
1612
1619
|
const { id } = req.params;
|
|
1613
1620
|
|
|
@@ -1730,7 +1737,7 @@ router.get(
|
|
|
1730
1737
|
|
|
1731
1738
|
router.post(
|
|
1732
1739
|
"/delete-run/:id",
|
|
1733
|
-
|
|
1740
|
+
isAdminOrHasConfigMinRole("min_role_edit_triggers"),
|
|
1734
1741
|
error_catcher(async (req, res) => {
|
|
1735
1742
|
const { id } = req.params;
|
|
1736
1743
|
|
|
@@ -1794,7 +1801,7 @@ router.get(
|
|
|
1794
1801
|
const trigger = await Trigger.findOne({ id: run.trigger_id });
|
|
1795
1802
|
const step = await WorkflowStep.findOne({
|
|
1796
1803
|
trigger_id: trigger.id,
|
|
1797
|
-
name: run.
|
|
1804
|
+
name: run.current_step_name,
|
|
1798
1805
|
});
|
|
1799
1806
|
|
|
1800
1807
|
const form = await getWorkflowStepUserForm(run, trigger, step, req);
|
|
@@ -1822,7 +1829,7 @@ router.post(
|
|
|
1822
1829
|
const trigger = await Trigger.findOne({ id: run.trigger_id });
|
|
1823
1830
|
const step = await WorkflowStep.findOne({
|
|
1824
1831
|
trigger_id: trigger.id,
|
|
1825
|
-
name: run.
|
|
1832
|
+
name: run.current_step_name,
|
|
1826
1833
|
});
|
|
1827
1834
|
|
|
1828
1835
|
const form = await getWorkflowStepUserForm(run, trigger, step, req);
|
package/routes/admin.js
CHANGED
|
@@ -13,6 +13,7 @@ const {
|
|
|
13
13
|
admin_config_route,
|
|
14
14
|
get_sys_info,
|
|
15
15
|
tenant_letsencrypt_name,
|
|
16
|
+
isAdminOrHasConfigMinRole,
|
|
16
17
|
} = require("./utils.js");
|
|
17
18
|
const Table = require("@saltcorn/data/models/table");
|
|
18
19
|
const Plugin = require("@saltcorn/data/models/plugin");
|
|
@@ -295,7 +296,7 @@ router.get(
|
|
|
295
296
|
error_catcher(async (req, res) => {
|
|
296
297
|
const fp = path.join(__dirname, "..", "CHANGELOG.md");
|
|
297
298
|
const fileBuf = await fs.promises.readFile(fp);
|
|
298
|
-
const mdContents = fileBuf.toString().replace("# Notable changes\n","");
|
|
299
|
+
const mdContents = fileBuf.toString().replace("# Notable changes\n", "");
|
|
299
300
|
const markup = md.render(mdContents);
|
|
300
301
|
res.sendWrap(`What's new in Saltcorn`, { above: [markup] });
|
|
301
302
|
})
|
|
@@ -626,13 +627,36 @@ router.get(
|
|
|
626
627
|
})
|
|
627
628
|
);
|
|
628
629
|
|
|
630
|
+
const checkEditPermission = (type, user) => {
|
|
631
|
+
if (user.role_id === 1) return true;
|
|
632
|
+
switch (type) {
|
|
633
|
+
case "view":
|
|
634
|
+
return getState().getConfig("min_role_edit_views", 1) >= user.role_id;
|
|
635
|
+
case "page":
|
|
636
|
+
return getState().getConfig("min_role_edit_pages", 1) >= user.role_id;
|
|
637
|
+
case "trigger":
|
|
638
|
+
return getState().getConfig("min_role_edit_triggers", 1) >= user.role_id;
|
|
639
|
+
default:
|
|
640
|
+
return false;
|
|
641
|
+
}
|
|
642
|
+
};
|
|
643
|
+
|
|
629
644
|
router.get(
|
|
630
645
|
"/snapshot-restore/:type/:name",
|
|
631
|
-
|
|
646
|
+
isAdminOrHasConfigMinRole([
|
|
647
|
+
"min_role_edit_views",
|
|
648
|
+
"min_role_edit_pages",
|
|
649
|
+
"min_role_edit_triggers",
|
|
650
|
+
]),
|
|
632
651
|
error_catcher(async (req, res) => {
|
|
633
652
|
const { type, name } = req.params;
|
|
634
653
|
const snaps = await Snapshot.entity_history(type, name);
|
|
635
654
|
const locale = getState().getConfig("default_locale", "en");
|
|
655
|
+
const auth = checkEditPermission(type, req.user);
|
|
656
|
+
if (!auth) {
|
|
657
|
+
res.send("Not authorized");
|
|
658
|
+
return;
|
|
659
|
+
}
|
|
636
660
|
res.set("Page-Title", `Restore ${text(name)}`);
|
|
637
661
|
res.send(
|
|
638
662
|
mkTable(
|
|
@@ -663,17 +687,26 @@ router.get(
|
|
|
663
687
|
|
|
664
688
|
router.post(
|
|
665
689
|
"/snapshot-restore/:type/:name/:id",
|
|
666
|
-
|
|
690
|
+
isAdminOrHasConfigMinRole([
|
|
691
|
+
"min_role_edit_views",
|
|
692
|
+
"min_role_edit_pages",
|
|
693
|
+
"min_role_edit_triggers",
|
|
694
|
+
]),
|
|
667
695
|
error_catcher(async (req, res) => {
|
|
668
696
|
const { type, name, id } = req.params;
|
|
669
|
-
const
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
697
|
+
const auth = checkEditPermission(type, req.user);
|
|
698
|
+
if (!auth) {
|
|
699
|
+
req.flash("error", "Not authorized");
|
|
700
|
+
} else {
|
|
701
|
+
const snap = await Snapshot.findOne({ id });
|
|
702
|
+
await snap.restore_entity(type, name);
|
|
703
|
+
req.flash(
|
|
704
|
+
"success",
|
|
705
|
+
`${type} ${name} restored to snapshot saved ${moment(
|
|
706
|
+
snap.created
|
|
707
|
+
).fromNow()}`
|
|
708
|
+
);
|
|
709
|
+
}
|
|
677
710
|
res.redirect(
|
|
678
711
|
type === "trigger"
|
|
679
712
|
? `/actions`
|
|
@@ -2414,7 +2447,7 @@ router.get(
|
|
|
2414
2447
|
class: "form-control",
|
|
2415
2448
|
name: "appId",
|
|
2416
2449
|
id: "appIdInputId",
|
|
2417
|
-
placeholder: "com.saltcorn.app",
|
|
2450
|
+
placeholder: "com.saltcorn.mobile.app",
|
|
2418
2451
|
value: builderSettings.appId || "",
|
|
2419
2452
|
})
|
|
2420
2453
|
)
|
|
@@ -3114,49 +3147,48 @@ router.get(
|
|
|
3114
3147
|
].join("")
|
|
3115
3148
|
)
|
|
3116
3149
|
)
|
|
3117
|
-
)
|
|
3150
|
+
),
|
|
3118
3151
|
// Share Extension provisioning profile
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
// )
|
|
3152
|
+
div(
|
|
3153
|
+
{ class: "row pb-3" },
|
|
3154
|
+
div(
|
|
3155
|
+
{ class: "col-sm-8" },
|
|
3156
|
+
label(
|
|
3157
|
+
{
|
|
3158
|
+
for: "shareProvisioningProfileInputId",
|
|
3159
|
+
class: "form-label fw-bold",
|
|
3160
|
+
},
|
|
3161
|
+
req.__("Share Extension Provisioning Profile"),
|
|
3162
|
+
a(
|
|
3163
|
+
{
|
|
3164
|
+
href: "javascript:ajax_modal('/admin/help/Provisioning Profile?')",
|
|
3165
|
+
},
|
|
3166
|
+
i({ class: "fas fa-question-circle ps-1" })
|
|
3167
|
+
)
|
|
3168
|
+
),
|
|
3169
|
+
select(
|
|
3170
|
+
{
|
|
3171
|
+
class: "form-select",
|
|
3172
|
+
name: "shareProvisioningProfile",
|
|
3173
|
+
id: "shareProvisioningProfileInputId",
|
|
3174
|
+
},
|
|
3175
|
+
[
|
|
3176
|
+
option({ value: "" }, ""),
|
|
3177
|
+
...provisioningFiles.map((file) =>
|
|
3178
|
+
option(
|
|
3179
|
+
{
|
|
3180
|
+
value: file.location,
|
|
3181
|
+
selected:
|
|
3182
|
+
builderSettings.shareProvisioningProfile ===
|
|
3183
|
+
file.location,
|
|
3184
|
+
},
|
|
3185
|
+
file.filename
|
|
3186
|
+
)
|
|
3187
|
+
),
|
|
3188
|
+
].join("")
|
|
3189
|
+
)
|
|
3190
|
+
)
|
|
3191
|
+
)
|
|
3160
3192
|
)
|
|
3161
3193
|
)
|
|
3162
3194
|
),
|
|
@@ -3425,11 +3457,10 @@ router.post(
|
|
|
3425
3457
|
keystoreAlias,
|
|
3426
3458
|
keystorePassword,
|
|
3427
3459
|
} = req.body;
|
|
3428
|
-
|
|
3429
|
-
|
|
3430
|
-
|
|
3431
|
-
|
|
3432
|
-
let allowShareTo = false; // receiveShareTriggers.length > 0;
|
|
3460
|
+
const receiveShareTriggers = Trigger.find({
|
|
3461
|
+
when_trigger: "ReceiveMobileShareData",
|
|
3462
|
+
});
|
|
3463
|
+
let allowShareTo = receiveShareTriggers.length > 0;
|
|
3433
3464
|
if (allowShareTo && iOSPlatform && !shareProvisioningProfile) {
|
|
3434
3465
|
allowShareTo = false;
|
|
3435
3466
|
msgs.push({
|
|
@@ -4191,10 +4222,6 @@ admin_config_route({
|
|
|
4191
4222
|
{ section_header: "Progressive Web Application" },
|
|
4192
4223
|
"pwa_enabled",
|
|
4193
4224
|
{ name: "pwa_display", showIf: { pwa_enabled: true } },
|
|
4194
|
-
{
|
|
4195
|
-
name: "pwa_share_to_enabled",
|
|
4196
|
-
showIf: { pwa_enabled: true },
|
|
4197
|
-
},
|
|
4198
4225
|
{ name: "pwa_set_colors", showIf: { pwa_enabled: true } },
|
|
4199
4226
|
{
|
|
4200
4227
|
name: "pwa_theme_color",
|
package/routes/common_lists.js
CHANGED
|
@@ -12,6 +12,7 @@ const {
|
|
|
12
12
|
badge,
|
|
13
13
|
} = require("@saltcorn/markup");
|
|
14
14
|
const { get_base_url } = require("./utils.js");
|
|
15
|
+
const { getState } = require("@saltcorn/data/db/state");
|
|
15
16
|
const { h4, p, div, a, i, text, span, nbsp } = require("@saltcorn/markup/tags");
|
|
16
17
|
|
|
17
18
|
/**
|
|
@@ -57,7 +58,9 @@ const tablesList = async (
|
|
|
57
58
|
});
|
|
58
59
|
const tagsById = {};
|
|
59
60
|
tags.forEach((t) => (tagsById[t.id] = t));
|
|
60
|
-
|
|
61
|
+
const user_can_edit_tables =
|
|
62
|
+
req.user.role_id === 1 ||
|
|
63
|
+
getState().getConfig("min_role_edit_tables", 1) >= req.user.role_id;
|
|
61
64
|
const tagBadges = (table) => {
|
|
62
65
|
const myTags = tag_entries.filter((te) => te.table_id === table.id);
|
|
63
66
|
return myTags
|
|
@@ -95,23 +98,27 @@ const tablesList = async (
|
|
|
95
98
|
? `${getRole(t.min_role_read)} (read only)`
|
|
96
99
|
: `${getRole(t.min_role_read)}/${getRole(t.min_role_write)}`,
|
|
97
100
|
},
|
|
98
|
-
|
|
99
|
-
?
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
101
|
+
...(user_can_edit_tables
|
|
102
|
+
? [
|
|
103
|
+
!tagId
|
|
104
|
+
? {
|
|
105
|
+
label: req.__("Delete"),
|
|
106
|
+
key: (r) =>
|
|
107
|
+
r.name === "users" || r.external
|
|
108
|
+
? ""
|
|
109
|
+
: post_delete_btn(`/table/delete/${r.id}`, req, r.name),
|
|
110
|
+
}
|
|
111
|
+
: {
|
|
112
|
+
label: req.__("Remove From Tag"),
|
|
113
|
+
key: (r) =>
|
|
114
|
+
post_delete_btn(
|
|
115
|
+
`/tag-entries/remove/tables/${r.id}/${tagId}`,
|
|
116
|
+
req,
|
|
117
|
+
`${r.name} from this tag`
|
|
118
|
+
),
|
|
119
|
+
},
|
|
120
|
+
]
|
|
121
|
+
: []),
|
|
115
122
|
],
|
|
116
123
|
tables,
|
|
117
124
|
{
|
|
@@ -286,6 +293,10 @@ const viewsList = async (
|
|
|
286
293
|
});
|
|
287
294
|
const tagsById = {};
|
|
288
295
|
tags.forEach((t) => (tagsById[t.id] = t));
|
|
296
|
+
const user_can_inspect_tables =
|
|
297
|
+
req.user.role_id === 1 ||
|
|
298
|
+
getState().getConfig("min_role_edit_tables", 1) >= req.user.role_id ||
|
|
299
|
+
getState().getConfig("min_role_inspect_tables", 1) >= req.user.role_id;
|
|
289
300
|
|
|
290
301
|
const tagBadges = (view) => {
|
|
291
302
|
const myTags = tag_entries.filter((te) => te.view_id === view.id);
|
|
@@ -339,7 +350,10 @@ const viewsList = async (
|
|
|
339
350
|
: [
|
|
340
351
|
{
|
|
341
352
|
label: req.__("Table"),
|
|
342
|
-
key: (r) =>
|
|
353
|
+
key: (r) =>
|
|
354
|
+
user_can_inspect_tables
|
|
355
|
+
? link(`/table/${r.table}`, r.table)
|
|
356
|
+
: r.table,
|
|
343
357
|
sortlink: !tagId
|
|
344
358
|
? `set_state_field('_sortby', 'table', this)`
|
|
345
359
|
: undefined,
|
|
@@ -588,7 +602,7 @@ const getPageGroupList = (rows, roles, req) => {
|
|
|
588
602
|
);
|
|
589
603
|
};
|
|
590
604
|
|
|
591
|
-
const trigger_dropdown = (trigger, req, on_done_redirect_str = "") =>
|
|
605
|
+
const trigger_dropdown = (trigger, req, on_done_redirect_str = "") =>
|
|
592
606
|
settingsDropdown(`dropdownMenuButton${trigger.id}`, [
|
|
593
607
|
a(
|
|
594
608
|
{
|
|
@@ -624,16 +638,22 @@ const trigger_dropdown = (trigger, req, on_done_redirect_str = "") =>
|
|
|
624
638
|
const getTriggerList = async (
|
|
625
639
|
triggers,
|
|
626
640
|
req,
|
|
627
|
-
{ tagId, domId, showList, filterOnTag } = {}
|
|
641
|
+
{ tagId, domId, showList, filterOnTag, on_done_redirect } = {}
|
|
628
642
|
) => {
|
|
629
643
|
const base_url = get_base_url(req);
|
|
630
644
|
const tags = await Tag.find();
|
|
631
|
-
|
|
645
|
+
const on_done_redirect_str = on_done_redirect
|
|
646
|
+
? `?on_done_redirect=${on_done_redirect}`
|
|
647
|
+
: "";
|
|
632
648
|
const tag_entries = await TagEntry.find({
|
|
633
649
|
not: { trigger_id: null },
|
|
634
650
|
});
|
|
635
651
|
const tagsById = {};
|
|
636
652
|
tags.forEach((t) => (tagsById[t.id] = t));
|
|
653
|
+
const user_can_inspect_tables =
|
|
654
|
+
req.user.role_id === 1 ||
|
|
655
|
+
getState().getConfig("min_role_edit_tables", 1) >= req.user.role_id ||
|
|
656
|
+
getState().getConfig("min_role_inspect_tables", 1) >= req.user.role_id;
|
|
637
657
|
|
|
638
658
|
const tagBadges = (trigger) => {
|
|
639
659
|
const myTags = tag_entries.filter((te) => te.trigger_id === trigger.id);
|
|
@@ -682,13 +702,15 @@ const getTriggerList = async (
|
|
|
682
702
|
label: req.__("Table or Channel"),
|
|
683
703
|
key: (r) =>
|
|
684
704
|
r.table_name
|
|
685
|
-
?
|
|
705
|
+
? user_can_inspect_tables
|
|
706
|
+
? a({ href: `/table/${r.table_name}` }, r.table_name)
|
|
707
|
+
: r.table_name
|
|
686
708
|
: r.channel,
|
|
687
709
|
},
|
|
688
710
|
!tagId
|
|
689
711
|
? {
|
|
690
712
|
label: "",
|
|
691
|
-
key: (r) => trigger_dropdown(r, req),
|
|
713
|
+
key: (r) => trigger_dropdown(r, req, on_done_redirect_str),
|
|
692
714
|
}
|
|
693
715
|
: {
|
|
694
716
|
label: req.__("Remove From Tag"),
|
package/routes/fields.js
CHANGED
|
@@ -24,7 +24,11 @@ const {
|
|
|
24
24
|
} = require("@saltcorn/data/models/expression");
|
|
25
25
|
const db = require("@saltcorn/data/db");
|
|
26
26
|
|
|
27
|
-
const {
|
|
27
|
+
const {
|
|
28
|
+
isAdmin,
|
|
29
|
+
error_catcher,
|
|
30
|
+
isAdminOrHasConfigMinRole,
|
|
31
|
+
} = require("./utils.js");
|
|
28
32
|
const expressionBlurb = require("../markup/expression_blurb");
|
|
29
33
|
const {
|
|
30
34
|
readState,
|
|
@@ -774,7 +778,10 @@ const fieldFlow = (req) =>
|
|
|
774
778
|
*/
|
|
775
779
|
router.get(
|
|
776
780
|
"/:id",
|
|
777
|
-
|
|
781
|
+
isAdminOrHasConfigMinRole([
|
|
782
|
+
"min_role_edit_tables",
|
|
783
|
+
"min_role_inspect_tables",
|
|
784
|
+
]),
|
|
778
785
|
error_catcher(async (req, res) => {
|
|
779
786
|
const { id } = req.params;
|
|
780
787
|
const field = await Field.findOne({ id });
|
|
@@ -830,7 +837,7 @@ router.get(
|
|
|
830
837
|
*/
|
|
831
838
|
router.get(
|
|
832
839
|
"/new/:table_id",
|
|
833
|
-
|
|
840
|
+
isAdminOrHasConfigMinRole("min_role_edit_tables"),
|
|
834
841
|
error_catcher(async (req, res) => {
|
|
835
842
|
const { table_id } = req.params;
|
|
836
843
|
const table = Table.findOne({ id: table_id });
|
|
@@ -867,7 +874,7 @@ router.get(
|
|
|
867
874
|
*/
|
|
868
875
|
router.post(
|
|
869
876
|
"/delete/:id",
|
|
870
|
-
|
|
877
|
+
isAdminOrHasConfigMinRole("min_role_edit_tables"),
|
|
871
878
|
error_catcher(async (req, res) => {
|
|
872
879
|
const { id } = req.params;
|
|
873
880
|
const f = await Field.findOne({ id });
|
|
@@ -892,7 +899,7 @@ router.post(
|
|
|
892
899
|
*/
|
|
893
900
|
router.post(
|
|
894
901
|
"/",
|
|
895
|
-
|
|
902
|
+
isAdminOrHasConfigMinRole("min_role_edit_tables"),
|
|
896
903
|
error_catcher(async (req, res) => {
|
|
897
904
|
const wf = fieldFlow(req);
|
|
898
905
|
const wfres = await wf.run(req.body, req);
|
|
@@ -941,7 +948,10 @@ router.post(
|
|
|
941
948
|
*/
|
|
942
949
|
router.post(
|
|
943
950
|
"/test-formula",
|
|
944
|
-
|
|
951
|
+
isAdminOrHasConfigMinRole([
|
|
952
|
+
"min_role_edit_tables",
|
|
953
|
+
"min_role_inspect_tables",
|
|
954
|
+
]),
|
|
945
955
|
error_catcher(async (req, res) => {
|
|
946
956
|
let { formula, tablename, stored } = req.body;
|
|
947
957
|
if (stored === "false") stored = false;
|
|
@@ -1231,7 +1241,11 @@ router.post(
|
|
|
1231
1241
|
*/
|
|
1232
1242
|
router.post(
|
|
1233
1243
|
"/preview/:tableName/:fieldName/:fieldview",
|
|
1234
|
-
|
|
1244
|
+
isAdminOrHasConfigMinRole([
|
|
1245
|
+
"min_role_edit_tables",
|
|
1246
|
+
"min_role_edit_views",
|
|
1247
|
+
"min_role_inspect_tables",
|
|
1248
|
+
]),
|
|
1235
1249
|
error_catcher(async (req, res) => {
|
|
1236
1250
|
const { tableName, fieldName, fieldview } = req.params;
|
|
1237
1251
|
const table = Table.findOne({ name: tableName });
|
|
@@ -1323,7 +1337,11 @@ router.post(
|
|
|
1323
1337
|
*/
|
|
1324
1338
|
router.post(
|
|
1325
1339
|
"/preview/:tableName/:fieldName/",
|
|
1326
|
-
|
|
1340
|
+
isAdminOrHasConfigMinRole([
|
|
1341
|
+
"min_role_edit_tables",
|
|
1342
|
+
"min_role_edit_views",
|
|
1343
|
+
"min_role_inspect_tables",
|
|
1344
|
+
]),
|
|
1327
1345
|
error_catcher(async (req, res) => {
|
|
1328
1346
|
res.send("");
|
|
1329
1347
|
})
|
|
@@ -1331,7 +1349,11 @@ router.post(
|
|
|
1331
1349
|
|
|
1332
1350
|
router.post(
|
|
1333
1351
|
"/fieldviewcfgform/:tableName",
|
|
1334
|
-
|
|
1352
|
+
isAdminOrHasConfigMinRole([
|
|
1353
|
+
"min_role_edit_tables",
|
|
1354
|
+
"min_role_edit_views",
|
|
1355
|
+
"min_role_inspect_tables",
|
|
1356
|
+
]),
|
|
1335
1357
|
error_catcher(async (req, res) => {
|
|
1336
1358
|
const { tableName } = req.params;
|
|
1337
1359
|
let {
|