@saltcorn/server 0.9.6-beta.2 → 0.9.6-beta.20

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 (49) hide show
  1. package/app.js +6 -1
  2. package/auth/admin.js +55 -53
  3. package/auth/routes.js +28 -10
  4. package/auth/testhelp.js +86 -0
  5. package/help/Field label.tmd +11 -0
  6. package/help/Field types.tmd +39 -0
  7. package/help/Ownership field.tmd +76 -0
  8. package/help/Ownership formula.tmd +75 -0
  9. package/help/Table roles.tmd +20 -0
  10. package/help/User groups.tmd +35 -0
  11. package/load_plugins.js +33 -5
  12. package/locales/en.json +29 -1
  13. package/locales/it.json +3 -2
  14. package/markup/admin.js +1 -0
  15. package/markup/forms.js +5 -1
  16. package/package.json +9 -9
  17. package/public/log_viewer_utils.js +32 -0
  18. package/public/mermaid.min.js +705 -306
  19. package/public/saltcorn-builder.css +23 -0
  20. package/public/saltcorn-common.js +248 -80
  21. package/public/saltcorn.css +80 -0
  22. package/public/saltcorn.js +86 -2
  23. package/restart_watcher.js +1 -0
  24. package/routes/actions.js +27 -0
  25. package/routes/admin.js +175 -64
  26. package/routes/api.js +6 -0
  27. package/routes/common_lists.js +42 -32
  28. package/routes/fields.js +70 -42
  29. package/routes/homepage.js +2 -0
  30. package/routes/index.js +2 -0
  31. package/routes/menu.js +69 -4
  32. package/routes/notifications.js +90 -10
  33. package/routes/pageedit.js +18 -13
  34. package/routes/plugins.js +11 -2
  35. package/routes/registry.js +289 -0
  36. package/routes/search.js +10 -4
  37. package/routes/tables.js +51 -27
  38. package/routes/tenant.js +4 -15
  39. package/routes/utils.js +25 -8
  40. package/routes/view.js +1 -1
  41. package/routes/viewedit.js +11 -7
  42. package/serve.js +27 -5
  43. package/tests/edit.test.js +426 -0
  44. package/tests/fields.test.js +21 -0
  45. package/tests/filter.test.js +68 -0
  46. package/tests/page.test.js +2 -2
  47. package/tests/plugins.test.js +2 -0
  48. package/tests/sync.test.js +59 -0
  49. package/wrapper.js +4 -1
package/load_plugins.js CHANGED
@@ -8,6 +8,8 @@
8
8
  const db = require("@saltcorn/data/db");
9
9
  const { getState, getRootState } = require("@saltcorn/data/db/state");
10
10
  const Plugin = require("@saltcorn/data/models/plugin");
11
+ const { isRoot } = require("@saltcorn/data/utils");
12
+ const { eachTenant } = require("@saltcorn/admin-models/models/tenant");
11
13
 
12
14
  const PluginInstaller = require("@saltcorn/plugins-loader/plugin_installer");
13
15
 
@@ -60,9 +62,23 @@ const loadPlugin = async (plugin, force) => {
60
62
  console.error(error); // todo i think that situation is not resolved
61
63
  }
62
64
  }
65
+
66
+ if (isRoot() && res.plugin_module.authentication)
67
+ await eachTenant(reloadAuthFromRoot);
63
68
  return res;
64
69
  };
65
70
 
71
+ const reloadAuthFromRoot = () => {
72
+ if (isRoot()) return;
73
+ const rootState = getRootState();
74
+ const tenantState = getState();
75
+ if (!rootState || !tenantState || rootState === tenantState) return;
76
+ tenantState.auth_methods = {};
77
+ for (const [k, v] of Object.entries(rootState.auth_methods)) {
78
+ if (v.shareWithTenants) tenantState.auth_methods[k] = v;
79
+ }
80
+ };
81
+
66
82
  /**
67
83
  * Install plugin
68
84
  * @param plugin - plugin name
@@ -90,6 +106,7 @@ const loadAllPlugins = async (force) => {
90
106
  }
91
107
  await getState().refreshUserLayouts();
92
108
  await getState().refresh(true);
109
+ if (!isRoot()) reloadAuthFromRoot();
93
110
  };
94
111
 
95
112
  /**
@@ -104,14 +121,14 @@ const loadAndSaveNewPlugin = async (
104
121
  plugin,
105
122
  force,
106
123
  noSignalOrDB,
107
- __ = (str) => str
124
+ __ = (str) => str,
125
+ allowUnsafeOnTenantsWithoutConfigSetting
108
126
  ) => {
109
127
  const tenants_unsafe_plugins = getRootState().getConfig(
110
128
  "tenants_unsafe_plugins",
111
129
  false
112
130
  );
113
- const isRoot = db.getTenantSchema() === db.connectObj.default_schema;
114
- if (!isRoot && !tenants_unsafe_plugins) {
131
+ if (!isRoot() && !tenants_unsafe_plugins) {
115
132
  if (plugin.source !== "npm") {
116
133
  console.error("\nWARNING: Skipping unsafe plugin ", plugin.name);
117
134
  return;
@@ -126,7 +143,10 @@ const loadAndSaveNewPlugin = async (
126
143
 
127
144
  const instore = getRootState().getConfig("available_plugins", []);
128
145
  const safes = instore.filter((p) => !p.unsafe).map((p) => p.location);
129
- if (!safes.includes(plugin.location)) {
146
+ if (
147
+ !safes.includes(plugin.location) &&
148
+ !allowUnsafeOnTenantsWithoutConfigSetting
149
+ ) {
130
150
  console.error("\nWARNING: Skipping unsafe plugin ", plugin.name);
131
151
  return;
132
152
  }
@@ -141,7 +161,11 @@ const loadAndSaveNewPlugin = async (
141
161
  const existing = await Plugin.findOne({ location: loc });
142
162
  if (!existing && loc !== plugin.location) {
143
163
  await loadAndSaveNewPlugin(
144
- new Plugin({ name: loc, location: loc, source: "npm" }),
164
+ new Plugin({
165
+ name: loc.replace("@saltcorn/", ""),
166
+ location: loc,
167
+ source: "npm",
168
+ }),
145
169
  force,
146
170
  noSignalOrDB
147
171
  );
@@ -192,6 +216,10 @@ const loadAndSaveNewPlugin = async (
192
216
  }
193
217
  }
194
218
  if (version) plugin.version = version;
219
+
220
+ if (isRoot() && plugin_module.authentication)
221
+ await eachTenant(reloadAuthFromRoot);
222
+
195
223
  if (!noSignalOrDB) {
196
224
  await plugin.upsert();
197
225
  getState().processSend({
package/locales/en.json CHANGED
@@ -1425,5 +1425,33 @@
1425
1425
  "Keystore Alias": "Keystore Alias",
1426
1426
  "Keystore Password": "Keystore Password",
1427
1427
  "xcodebuild": "xcodebuild",
1428
- "Provisioning Profile": "Provisioning Profile"
1428
+ "Provisioning Profile": "Provisioning Profile",
1429
+ "Registry editor": "Registry editor",
1430
+ "Mobile HTML": "Mobile HTML",
1431
+ "HTML for the item in the bottom navigation bar. Currently, only supported by the metronic theme.": "HTML for the item in the bottom navigation bar. Currently, only supported by the metronic theme.",
1432
+ "A short name that will be in the page URL": "A short name that will be in the page URL",
1433
+ "A longer description that is not visible but appears in the page header and is indexed by search engines": "A longer description that is not visible but appears in the page header and is indexed by search engines",
1434
+ "User role required to access page": "User role required to access page",
1435
+ "Example: <code>`/view/TheOtherView?id=${id}`</code>": "Example: <code>`/view/TheOtherView?id=${id}`</code>",
1436
+ "Older": "Older",
1437
+ "Newest": "Newest",
1438
+ "Delete all read": "Delete all read",
1439
+ "Trigger %s duplicated as %s": "Trigger %s duplicated as %s",
1440
+ "Tooltip": "Tooltip",
1441
+ "Tooltip formula": "Tooltip formula",
1442
+ "Install a different version": "Install a different version",
1443
+ "Page group": "Page group",
1444
+ "Starting upgrade, please wait...\n": "Starting upgrade, please wait...\n",
1445
+ "Upgrade done (if it was available) with code 0.\n\nPress the BACK button in your browser, then RELOAD the page.": "Upgrade done (if it was available) with code 0.\n\nPress the BACK button in your browser, then RELOAD the page.",
1446
+ "Installing %s, please wait...\n": "Installing %s, please wait...\n",
1447
+ "Install done with code 0.\n\nPress the BACK button in your browser, then RELOAD the page.": "Install done with code 0.\n\nPress the BACK button in your browser, then RELOAD the page.",
1448
+ "Pulling the cordova-builder docker image...": "Pulling the cordova-builder docker image...",
1449
+ "Check updates": "Check updates",
1450
+ "Choose version": "Choose version",
1451
+ "Unknown authentication method %s": "Unknown authentication method %s",
1452
+ "Card rows": "Card rows",
1453
+ "Each row in a card. Not supported by all themes": "Each row in a card. Not supported by all themes",
1454
+ "Prune session interval (seconds)": "Prune session interval (seconds)",
1455
+ "Interval in seconds to check for expred sessions in the postgres db. 0, empty or a negative number to disable": "Interval in seconds to check for expred sessions in the postgres db. 0, empty or a negative number to disable",
1456
+ "Progressive Web Application is not enabled": "Progressive Web Application is not enabled"
1429
1457
  }
package/locales/it.json CHANGED
@@ -518,5 +518,6 @@
518
518
  "Save before going back": "Save before going back",
519
519
  "Reload after going back": "Reload after going back",
520
520
  "Steps to go back": "Steps to go back",
521
- "%s configuration": "%s configuration"
522
- }
521
+ "%s configuration": "%s configuration",
522
+ "The current theme has no user specific settings": "The current theme has no user specific settings"
523
+ }
package/markup/admin.js CHANGED
@@ -241,6 +241,7 @@ const send_infoarch_page = (args) => {
241
241
  { text: "Pagegroups", href: "/page_group/settings" },
242
242
  { text: "Tags", href: "/tag" },
243
243
  { text: "Diagram", href: "/diagram" },
244
+ { text: "Registry editor", href: "/registry-editor" },
244
245
  ],
245
246
  ...args,
246
247
  });
package/markup/forms.js CHANGED
@@ -28,10 +28,14 @@ const editRoleForm = ({ url, current_role, roles, req }) =>
28
28
  {
29
29
  action: url,
30
30
  method: "post",
31
+ onchange: "saveAndContinue(this)",
31
32
  },
32
33
  csrfField(req),
33
34
  select(
34
- { name: "role", onchange: "form.submit()" },
35
+ {
36
+ name: "role",
37
+ class: "w-unset form-select form-select-sm",
38
+ },
35
39
  roles.map((role) =>
36
40
  option(
37
41
  {
package/package.json CHANGED
@@ -1,20 +1,20 @@
1
1
  {
2
2
  "name": "@saltcorn/server",
3
- "version": "0.9.6-beta.2",
3
+ "version": "0.9.6-beta.20",
4
4
  "description": "Server app for Saltcorn, open-source no-code platform",
5
5
  "homepage": "https://saltcorn.com",
6
6
  "main": "index.js",
7
7
  "license": "MIT",
8
8
  "dependencies": {
9
9
  "@aws-sdk/client-s3": "^3.451.0",
10
- "@saltcorn/base-plugin": "0.9.6-beta.2",
11
- "@saltcorn/builder": "0.9.6-beta.2",
12
- "@saltcorn/data": "0.9.6-beta.2",
13
- "@saltcorn/admin-models": "0.9.6-beta.2",
14
- "@saltcorn/filemanager": "0.9.6-beta.2",
15
- "@saltcorn/markup": "0.9.6-beta.2",
16
- "@saltcorn/plugins-loader": "0.9.6-beta.2",
17
- "@saltcorn/sbadmin2": "0.9.6-beta.2",
10
+ "@saltcorn/base-plugin": "0.9.6-beta.20",
11
+ "@saltcorn/builder": "0.9.6-beta.20",
12
+ "@saltcorn/data": "0.9.6-beta.20",
13
+ "@saltcorn/admin-models": "0.9.6-beta.20",
14
+ "@saltcorn/filemanager": "0.9.6-beta.20",
15
+ "@saltcorn/markup": "0.9.6-beta.20",
16
+ "@saltcorn/plugins-loader": "0.9.6-beta.20",
17
+ "@saltcorn/sbadmin2": "0.9.6-beta.20",
18
18
  "@socket.io/cluster-adapter": "^0.2.1",
19
19
  "@socket.io/sticky": "^1.0.1",
20
20
  "adm-zip": "0.5.10",
@@ -10,6 +10,9 @@ var logViewerHelpers = (() => {
10
10
  second: "2-digit",
11
11
  };
12
12
  let lostConnection = false;
13
+ let waitingForTestMessage = false;
14
+ let startedWaitingAt = null;
15
+ let waitTimeout = false;
13
16
 
14
17
  const logLevelColor = (level) => {
15
18
  switch (parseInt(level)) {
@@ -94,6 +97,17 @@ var logViewerHelpers = (() => {
94
97
  });
95
98
  };
96
99
 
100
+ const testMsgWaiter = (waiterStartedAt) => () => {
101
+ if (waitingForTestMessage && waiterStartedAt === startedWaitingAt) {
102
+ emptyAlerts();
103
+ waitTimeout = true;
104
+ notifyAlert({
105
+ type: "danger",
106
+ text: "You are connected but not receiving any messages",
107
+ });
108
+ }
109
+ };
110
+
97
111
  const handleConnect = (socket) => {
98
112
  socket.emit("join_log_room", (ack) => {
99
113
  if (ack) {
@@ -109,6 +123,10 @@ var logViewerHelpers = (() => {
109
123
  text: "You are connected again",
110
124
  });
111
125
  }
126
+ waitingForTestMessage = true;
127
+ waitTimeout = false;
128
+ startedWaitingAt = new Date().valueOf();
129
+ setTimeout(testMsgWaiter(startedWaitingAt), 5000);
112
130
  } else if (ack.status === "error" && ack.msg) {
113
131
  notifyAlert({
114
132
  type: "danger",
@@ -129,6 +147,19 @@ var logViewerHelpers = (() => {
129
147
  });
130
148
  };
131
149
 
150
+ const handleTestConnMsg = () => {
151
+ waitingForTestMessage = false;
152
+ startedWaitingAt = null;
153
+ if (waitTimeout) {
154
+ emptyAlerts();
155
+ notifyAlert({
156
+ type: "success",
157
+ text: "You are connected and receiving messages",
158
+ });
159
+ waitTimeout = false;
160
+ }
161
+ };
162
+
132
163
  return {
133
164
  init_log_socket: () => {
134
165
  let socket = null;
@@ -152,6 +183,7 @@ var logViewerHelpers = (() => {
152
183
  socket.on("connect", () => handleConnect(socket));
153
184
  socket.on("disconnect", handleDisconnect);
154
185
  socket.on("log_msg", handleLogMsg);
186
+ socket.on("test_conn_msg", handleTestConnMsg);
155
187
  },
156
188
  goToLogsPage: (n) => {
157
189
  currentPage = n;