@saltcorn/server 1.1.2-beta.11 → 1.1.2-beta.13
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 +8 -0
- package/locales/en.json +2 -1
- package/package.json +9 -9
- package/routes/actions.js +1 -2
- package/routes/admin.js +49 -40
- package/routes/tables.js +9 -1
package/CHANGELOG.md
CHANGED
|
@@ -15,6 +15,14 @@
|
|
|
15
15
|
|
|
16
16
|
* Upgrade a large number of dependencies (express, typescript, oclif, pg, webpack, typescript, axios, mjml, svelte). Node.js 18+ is require for this release.
|
|
17
17
|
|
|
18
|
+
### Security
|
|
19
|
+
|
|
20
|
+
* View roles are now strictly enforced, including when views are embedded.
|
|
21
|
+
|
|
22
|
+
### Fixes
|
|
23
|
+
|
|
24
|
+
* Much work on primary keys not called "id"
|
|
25
|
+
|
|
18
26
|
## 1.1.1 - Released 2 February 2025
|
|
19
27
|
|
|
20
28
|
* Full-text search improvements:
|
package/locales/en.json
CHANGED
|
@@ -1553,5 +1553,6 @@
|
|
|
1553
1553
|
"Search syntax help": "Search syntax help",
|
|
1554
1554
|
"Search syntax": "Search syntax",
|
|
1555
1555
|
"Maximum role": "Maximum role",
|
|
1556
|
-
"Module dependencies": "Module dependencies"
|
|
1556
|
+
"Module dependencies": "Module dependencies",
|
|
1557
|
+
"Prompt": "Prompt"
|
|
1557
1558
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@saltcorn/server",
|
|
3
|
-
"version": "1.1.2-beta.
|
|
3
|
+
"version": "1.1.2-beta.13",
|
|
4
4
|
"description": "Server app for Saltcorn, open-source no-code platform",
|
|
5
5
|
"homepage": "https://saltcorn.com",
|
|
6
6
|
"main": "index.js",
|
|
@@ -8,14 +8,14 @@
|
|
|
8
8
|
"dependencies": {
|
|
9
9
|
"@aws-sdk/client-s3": "^3.735.0",
|
|
10
10
|
"@dr.pogodin/csurf": "^1.14.1",
|
|
11
|
-
"@saltcorn/base-plugin": "1.1.2-beta.
|
|
12
|
-
"@saltcorn/builder": "1.1.2-beta.
|
|
13
|
-
"@saltcorn/data": "1.1.2-beta.
|
|
14
|
-
"@saltcorn/admin-models": "1.1.2-beta.
|
|
15
|
-
"@saltcorn/filemanager": "1.1.2-beta.
|
|
16
|
-
"@saltcorn/markup": "1.1.2-beta.
|
|
17
|
-
"@saltcorn/plugins-loader": "1.1.2-beta.
|
|
18
|
-
"@saltcorn/sbadmin2": "1.1.2-beta.
|
|
11
|
+
"@saltcorn/base-plugin": "1.1.2-beta.13",
|
|
12
|
+
"@saltcorn/builder": "1.1.2-beta.13",
|
|
13
|
+
"@saltcorn/data": "1.1.2-beta.13",
|
|
14
|
+
"@saltcorn/admin-models": "1.1.2-beta.13",
|
|
15
|
+
"@saltcorn/filemanager": "1.1.2-beta.13",
|
|
16
|
+
"@saltcorn/markup": "1.1.2-beta.13",
|
|
17
|
+
"@saltcorn/plugins-loader": "1.1.2-beta.13",
|
|
18
|
+
"@saltcorn/sbadmin2": "1.1.2-beta.13",
|
|
19
19
|
"@socket.io/cluster-adapter": "^0.2.1",
|
|
20
20
|
"@socket.io/sticky": "^1.0.1",
|
|
21
21
|
"adm-zip": "0.5.16",
|
package/routes/actions.js
CHANGED
|
@@ -653,7 +653,7 @@ const getWorkflowStepForm = async (
|
|
|
653
653
|
...(field.showIf || {}),
|
|
654
654
|
},
|
|
655
655
|
};
|
|
656
|
-
if (cfgFld.input_type === "code") cfgFld.input_type = "textarea";
|
|
656
|
+
//if (cfgFld.input_type === "code") cfgFld.input_type = "textarea";
|
|
657
657
|
actionConfigFields.push(cfgFld);
|
|
658
658
|
}
|
|
659
659
|
} catch {}
|
|
@@ -1854,7 +1854,6 @@ interactive workflows for not logged in
|
|
|
1854
1854
|
actions can declare which variables they inject into scope
|
|
1855
1855
|
|
|
1856
1856
|
show unconnected steps
|
|
1857
|
-
why is code not initialising
|
|
1858
1857
|
drag and drop edges
|
|
1859
1858
|
|
|
1860
1859
|
*/
|
package/routes/admin.js
CHANGED
|
@@ -709,8 +709,8 @@ router.post(
|
|
|
709
709
|
type === "trigger"
|
|
710
710
|
? `/actions`
|
|
711
711
|
: /^[a-z]+$/g.test(type)
|
|
712
|
-
|
|
713
|
-
|
|
712
|
+
? `/${type}edit`
|
|
713
|
+
: "/"
|
|
714
714
|
);
|
|
715
715
|
})
|
|
716
716
|
);
|
|
@@ -1195,7 +1195,7 @@ router.get(
|
|
|
1195
1195
|
th({ valign: "top" }, req.__("Saltcorn version")),
|
|
1196
1196
|
td(
|
|
1197
1197
|
packagejson.version,
|
|
1198
|
-
isRoot
|
|
1198
|
+
isRoot && can_update
|
|
1199
1199
|
? post_btn(
|
|
1200
1200
|
"/admin/upgrade",
|
|
1201
1201
|
req.__("Upgrade") + " (latest)",
|
|
@@ -1206,21 +1206,22 @@ router.get(
|
|
|
1206
1206
|
}
|
|
1207
1207
|
)
|
|
1208
1208
|
: isRoot && is_latest
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1209
|
+
? span(
|
|
1210
|
+
{ class: "badge bg-primary ms-2" },
|
|
1211
|
+
req.__("Latest")
|
|
1212
|
+
) +
|
|
1213
|
+
post_btn(
|
|
1214
|
+
"/admin/check-for-upgrade",
|
|
1215
|
+
req.__("Check updates"),
|
|
1216
|
+
req.csrfToken(),
|
|
1217
|
+
{
|
|
1218
|
+
btnClass: "btn-primary btn-sm px-1 py-0",
|
|
1219
|
+
formClass: "d-inline",
|
|
1220
|
+
}
|
|
1221
|
+
)
|
|
1222
|
+
: "",
|
|
1223
|
+
isRoot &&
|
|
1224
|
+
!git_commit &&
|
|
1224
1225
|
a(
|
|
1225
1226
|
{
|
|
1226
1227
|
id: rndid,
|
|
@@ -1563,21 +1564,30 @@ const cleanNodeModules = async () => {
|
|
|
1563
1564
|
};
|
|
1564
1565
|
|
|
1565
1566
|
const doInstall = async (req, res, version, deepClean, runPull) => {
|
|
1567
|
+
const state = getState();
|
|
1568
|
+
let res_write = (s) => {
|
|
1569
|
+
try {
|
|
1570
|
+
res.write(s);
|
|
1571
|
+
state.log(5, s);
|
|
1572
|
+
} catch (e) {
|
|
1573
|
+
console.error("Install write error: ", e?.message || e);
|
|
1574
|
+
}
|
|
1575
|
+
};
|
|
1566
1576
|
if (db.getTenantSchema() !== db.connectObj.default_schema) {
|
|
1567
1577
|
req.flash("error", req.__("Not possible for tenant"));
|
|
1568
1578
|
res.redirect("/admin");
|
|
1569
1579
|
} else {
|
|
1570
|
-
|
|
1580
|
+
res_write(
|
|
1571
1581
|
version === "latest"
|
|
1572
1582
|
? req.__("Starting upgrade, please wait...\n")
|
|
1573
1583
|
: req.__("Installing %s, please wait...\n", version)
|
|
1574
1584
|
);
|
|
1575
1585
|
if (deepClean) {
|
|
1576
|
-
|
|
1586
|
+
res_write(req.__("Cleaning node_modules...\n"));
|
|
1577
1587
|
try {
|
|
1578
1588
|
await cleanNodeModules();
|
|
1579
1589
|
} catch (e) {
|
|
1580
|
-
|
|
1590
|
+
res_write(req.__("Error cleaning node_modules: %s\n", e.message));
|
|
1581
1591
|
}
|
|
1582
1592
|
}
|
|
1583
1593
|
const child = spawn(
|
|
@@ -1588,33 +1598,37 @@ const doInstall = async (req, res, version, deepClean, runPull) => {
|
|
|
1588
1598
|
}
|
|
1589
1599
|
);
|
|
1590
1600
|
child.stdout.on("data", (data) => {
|
|
1591
|
-
|
|
1601
|
+
res_write(data);
|
|
1592
1602
|
});
|
|
1593
1603
|
child.stderr?.on("data", (data) => {
|
|
1594
|
-
|
|
1604
|
+
res_write(data);
|
|
1595
1605
|
});
|
|
1596
1606
|
child.on("exit", async function (code, signal) {
|
|
1597
1607
|
if (code === 0) {
|
|
1598
1608
|
if (deepClean) {
|
|
1599
|
-
|
|
1609
|
+
res_write(req.__("Installing sd-notify") + "\n");
|
|
1600
1610
|
const sdNotifyCode = await tryInstallSdNotify(req, res);
|
|
1601
|
-
|
|
1611
|
+
res_write(
|
|
1602
1612
|
req.__("sd-notify install done with code %s", sdNotifyCode) + "\n"
|
|
1603
1613
|
);
|
|
1604
1614
|
}
|
|
1605
1615
|
if (runPull) {
|
|
1606
|
-
|
|
1616
|
+
res_write(
|
|
1607
1617
|
req.__("Pulling the capacitor-builder docker image...") + "\n"
|
|
1608
1618
|
);
|
|
1609
1619
|
const pullCode = await pullCapacitorBuilder(req, res, version);
|
|
1610
|
-
|
|
1620
|
+
res_write(req.__("Pull done with code %s", pullCode) + "\n");
|
|
1611
1621
|
if (pullCode === 0) {
|
|
1612
|
-
|
|
1622
|
+
res_write(req.__("Pruning docker...") + "\n");
|
|
1613
1623
|
const pruneCode = await pruneDocker(req, res);
|
|
1614
|
-
|
|
1624
|
+
res_write(req.__("Prune done with code %s", pruneCode) + "\n");
|
|
1615
1625
|
}
|
|
1616
1626
|
}
|
|
1617
1627
|
}
|
|
1628
|
+
setTimeout(() => {
|
|
1629
|
+
getState().processSend("RestartServer");
|
|
1630
|
+
process.exit(0);
|
|
1631
|
+
}, 200);
|
|
1618
1632
|
res.end(
|
|
1619
1633
|
version === "latest"
|
|
1620
1634
|
? req.__(
|
|
@@ -1624,10 +1638,6 @@ const doInstall = async (req, res, version, deepClean, runPull) => {
|
|
|
1624
1638
|
`Install done with code ${code}.\n\nPress the BACK button in your browser, then RELOAD the page.`
|
|
1625
1639
|
)
|
|
1626
1640
|
);
|
|
1627
|
-
setTimeout(() => {
|
|
1628
|
-
getState().processSend("RestartServer");
|
|
1629
|
-
process.exit(0);
|
|
1630
|
-
}, 100);
|
|
1631
1641
|
});
|
|
1632
1642
|
}
|
|
1633
1643
|
};
|
|
@@ -1974,9 +1984,8 @@ router.get(
|
|
|
1974
1984
|
const filename = `${moment(start).format("YYYYMMDDHHmm")}.html`;
|
|
1975
1985
|
await File.new_folder("configuration_checks");
|
|
1976
1986
|
const go = async () => {
|
|
1977
|
-
const { passes, errors, pass, warnings } =
|
|
1978
|
-
req
|
|
1979
|
-
);
|
|
1987
|
+
const { passes, errors, pass, warnings } =
|
|
1988
|
+
await runConfigurationCheck(req);
|
|
1980
1989
|
const end = new Date();
|
|
1981
1990
|
const secs = Math.round((end.getTime() - start.getTime()) / 1000);
|
|
1982
1991
|
|
|
@@ -3250,8 +3259,8 @@ router.get(
|
|
|
3250
3259
|
mode === "prepare"
|
|
3251
3260
|
? "_prepare_step"
|
|
3252
3261
|
: mode === "finish"
|
|
3253
|
-
|
|
3254
|
-
|
|
3262
|
+
? "_finish_step"
|
|
3263
|
+
: "";
|
|
3255
3264
|
res.json({
|
|
3256
3265
|
finished: await checkFiles(out_dir_name, [
|
|
3257
3266
|
`logs${stepDesc}.txt`,
|
|
@@ -3326,8 +3335,8 @@ router.get(
|
|
|
3326
3335
|
mode === "prepare"
|
|
3327
3336
|
? "_prepare_step"
|
|
3328
3337
|
: mode === "finish"
|
|
3329
|
-
|
|
3330
|
-
|
|
3338
|
+
? "_finish_step"
|
|
3339
|
+
: "";
|
|
3331
3340
|
const resultMsg = files.find(
|
|
3332
3341
|
(file) => file.filename === `logs${stepDesc}.txt`
|
|
3333
3342
|
)
|
package/routes/tables.js
CHANGED
|
@@ -717,8 +717,12 @@ const attribBadges = (f) => {
|
|
|
717
717
|
let s = "";
|
|
718
718
|
if (f.attributes) {
|
|
719
719
|
Object.entries(f.attributes).forEach(([k, v]) => {
|
|
720
|
+
if (k === "summary_field") s += badge("secondary", "Summary", v);
|
|
721
|
+
if (k === "include_fts" && v)
|
|
722
|
+
s += badge("secondary", "FTS", "Include in full-text search");
|
|
720
723
|
if (
|
|
721
724
|
[
|
|
725
|
+
"include_fts",
|
|
722
726
|
"summary_field",
|
|
723
727
|
"importance",
|
|
724
728
|
"on_delete_cascade",
|
|
@@ -1467,7 +1471,10 @@ router.get(
|
|
|
1467
1471
|
res.redirect(`/table/${table.id}`);
|
|
1468
1472
|
return;
|
|
1469
1473
|
}
|
|
1470
|
-
const rows = await table.getRows(
|
|
1474
|
+
const rows = await table.getRows(
|
|
1475
|
+
{},
|
|
1476
|
+
{ orderBy: table.pk_name, forUser: req.user }
|
|
1477
|
+
);
|
|
1471
1478
|
res.setHeader("Content-Type", "text/csv");
|
|
1472
1479
|
res.setHeader("Content-Disposition", `attachment; filename="${name}.csv"`);
|
|
1473
1480
|
res.setHeader("Cache-Control", "no-cache");
|
|
@@ -2019,6 +2026,7 @@ router.post(
|
|
|
2019
2026
|
if (parse_res.error) req.flash("error", parse_res.error);
|
|
2020
2027
|
else req.flash("success", parse_res.success);
|
|
2021
2028
|
} catch (e) {
|
|
2029
|
+
console.error("CSV upload error", e);
|
|
2022
2030
|
req.flash("error", e.message);
|
|
2023
2031
|
}
|
|
2024
2032
|
await fs.unlink(f.location);
|