@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 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.11",
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.11",
12
- "@saltcorn/builder": "1.1.2-beta.11",
13
- "@saltcorn/data": "1.1.2-beta.11",
14
- "@saltcorn/admin-models": "1.1.2-beta.11",
15
- "@saltcorn/filemanager": "1.1.2-beta.11",
16
- "@saltcorn/markup": "1.1.2-beta.11",
17
- "@saltcorn/plugins-loader": "1.1.2-beta.11",
18
- "@saltcorn/sbadmin2": "1.1.2-beta.11",
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
- ? `/${type}edit`
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
- ? 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
- !git_commit &&
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
- res.write(
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
- res.write(req.__("Cleaning node_modules...\n"));
1586
+ res_write(req.__("Cleaning node_modules...\n"));
1577
1587
  try {
1578
1588
  await cleanNodeModules();
1579
1589
  } catch (e) {
1580
- res.write(req.__("Error cleaning node_modules: %s\n", e.message));
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
- res.write(data);
1601
+ res_write(data);
1592
1602
  });
1593
1603
  child.stderr?.on("data", (data) => {
1594
- res.write(data);
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
- res.write(req.__("Installing sd-notify") + "\n");
1609
+ res_write(req.__("Installing sd-notify") + "\n");
1600
1610
  const sdNotifyCode = await tryInstallSdNotify(req, res);
1601
- res.write(
1611
+ res_write(
1602
1612
  req.__("sd-notify install done with code %s", sdNotifyCode) + "\n"
1603
1613
  );
1604
1614
  }
1605
1615
  if (runPull) {
1606
- res.write(
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
- res.write(req.__("Pull done with code %s", pullCode) + "\n");
1620
+ res_write(req.__("Pull done with code %s", pullCode) + "\n");
1611
1621
  if (pullCode === 0) {
1612
- res.write(req.__("Pruning docker...") + "\n");
1622
+ res_write(req.__("Pruning docker...") + "\n");
1613
1623
  const pruneCode = await pruneDocker(req, res);
1614
- res.write(req.__("Prune done with code %s", pruneCode) + "\n");
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 } = await runConfigurationCheck(
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
- ? "_finish_step"
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
- ? "_finish_step"
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({}, { orderBy: "id", forUser: req.user });
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);