@saltcorn/server 0.8.0-beta.2 → 0.8.0-beta.4

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/auth/admin.js CHANGED
@@ -7,20 +7,12 @@
7
7
  // todo refactor to few modules + rename to be in sync with router url
8
8
  const Router = require("express-promise-router");
9
9
  const { contract, is } = require("contractis");
10
-
11
10
  const db = require("@saltcorn/data/db");
12
11
  const User = require("@saltcorn/data/models/user");
13
12
  const View = require("@saltcorn/data/models/view");
14
13
  const Field = require("@saltcorn/data/models/field");
15
14
  const Form = require("@saltcorn/data/models/form");
16
- const {
17
- mkTable,
18
- renderForm,
19
- link,
20
- post_btn,
21
- settingsDropdown,
22
- post_dropdown_item,
23
- } = require("@saltcorn/markup");
15
+ const { mkTable, renderForm, link, post_btn, settingsDropdown, post_dropdown_item } = require("@saltcorn/markup");
24
16
  const { isAdmin, error_catcher } = require("../routes/utils");
25
17
  const { send_reset_email } = require("./resetpw");
26
18
  const { getState } = require("@saltcorn/data/db/state");
@@ -35,16 +27,7 @@ const {
35
27
  is_hsts_tld,
36
28
  } = require("../markup/admin");
37
29
  const { send_verification_email } = require("@saltcorn/data/models/email");
38
- const {
39
- expressionValidator,
40
- } = require("@saltcorn/data/models/expression");
41
- /**
42
- * @type {object}
43
- * @const
44
- * @namespace auth/adminRouter
45
- * @category server
46
- * @subcategory auth
47
- */
30
+ const { expressionValidator } = require("@saltcorn/data/models/expression");
48
31
  const router = new Router();
49
32
  module.exports = router;
50
33
 
@@ -357,6 +340,7 @@ const permissions_settings_form = async (req) =>
357
340
  field_names: [
358
341
  "min_role_upload",
359
342
  "min_role_apikeygen",
343
+ //hidden "exttables_min_role_read",
360
344
  ],
361
345
  action: "/useradmin/permissions",
362
346
  submitLabel: req.__("Save"),
package/locales/en.json CHANGED
@@ -1046,6 +1046,14 @@
1046
1046
  "<p>You have views with a role to access lower than the table role to read, \n with no table ownership. In the next version of Saltcorn, this may cause a\n denial of access. Users will need to have table read access to any data displayed.</p> \n Views potentially affected: %s": "<p>You have views with a role to access lower than the table role to read, \n with no table ownership. In the next version of Saltcorn, this may cause a\n denial of access. Users will need to have table read access to any data displayed.</p> \n Views potentially affected: %s",
1047
1047
  "If the parent row is deleted, do this to the child rows.": "If the parent row is deleted, do this to the child rows.",
1048
1048
  "On delete": "On delete",
1049
- "Database name": "Database name",
1050
- "Database schema": "Database schema"
1049
+ "Permissions": "Permissions",
1050
+ "Permissions settings": "Permissions settings",
1051
+ "Files accept filter ": "Files accept filter ",
1052
+ "Specifies a filter for what file types the user can pick from the file input dialog box. Example is `.doc,audio/*,video/*,image/*`": "Specifies a filter for what file types the user can pick from the file input dialog box. Example is `.doc,audio/*,video/*,image/*`",
1053
+ "Permissions settings updated": "Permissions settings updated",
1054
+ "Upload file(s)": "Upload file(s)",
1055
+ "Specifies a filter for what file types the user can pick from the file input dialog box. Example is `text/csv,audio/*,video/*,image/*`": "Specifies a filter for what file types the user can pick from the file input dialog box. Example is `text/csv,audio/*,video/*,image/*`",
1056
+ "Default Files accept filter": "Default Files accept filter",
1057
+ "Specifies a default filter for what file types the user can pick from the file input dialog box. Example is `.doc, text/csv,audio/*,video/*,image/*`": "Specifies a default filter for what file types the user can pick from the file input dialog box. Example is `.doc, text/csv,audio/*,video/*,image/*`",
1058
+ "Destination page": "Destination page"
1051
1059
  }
package/locales/it.json CHANGED
@@ -484,5 +484,5 @@
484
484
  "Table access": "Table access",
485
485
  "HTTP": "HTTP",
486
486
  "Rights": "Rights",
487
- "Table access": "Table access"
487
+ "Permissions": "Permissions"
488
488
  }
package/locales/ru.json CHANGED
@@ -919,5 +919,29 @@
919
919
  "File not found": "Файл не найден",
920
920
  "Permissions settings": "Настройки разрешений",
921
921
  "Permissions": "Разрешения",
922
- "Permissions settings updated": "Настройки разрешений обновлены"
922
+ "Permissions settings updated": "Настройки разрешений обновлены",
923
+ "Upload file(s)": "Upload file(s)",
924
+ "Split paste": "Split paste",
925
+ "Separate paste content into separate inputs": "Separate paste content into separate inputs",
926
+ "Preview": "Preview",
927
+ "Create new row": "Create new row",
928
+ "Descending?": "Descending?",
929
+ "Only include rows where this formula is true. ": "Only include rows where this formula is true. ",
930
+ "Use %s to access current user ID": "Use %s to access current user ID",
931
+ "Formula value": "Formula value",
932
+ "Units": "Units",
933
+ "%s view - %s on %s": "%s view - %s on %s",
934
+ "Password Repeat": "Password Repeat",
935
+ "Remember me": "Remember me",
936
+ "Files accept filter ": "Files accept filter ",
937
+ "Specifies a filter for what file types the user can pick from the file input dialog box. Example is `text/csv,audio/*,video/*,image/*`": "Specifies a filter for what file types the user can pick from the file input dialog box. Example is `text/csv,audio/*,video/*,image/*`",
938
+ "Home Page by Role": "Home Page by Role",
939
+ "Files accept filter": "Files accept filter",
940
+ "Specify how to create a new row": "Specify how to create a new row",
941
+ "Cascade delete to file": "Cascade delete to file",
942
+ "Deleting a row will also delete the file referenced by this field": "Deleting a row will also delete the file referenced by this field",
943
+ "Specifies a filter for what file types the user can pick from the file input dialog box. Example is `.doc,audio/*,video/*,image/*`": "Specifies a filter for what file types the user can pick from the file input dialog box. Example is `.doc,audio/*,video/*,image/*`",
944
+ "Default Files accept filter": "Default Files accept filter",
945
+ "Specifies a default filter for what file types the user can pick from the file input dialog box. Example is `.doc, text/csv,audio/*,video/*,image/*`": "Specifies a default filter for what file types the user can pick from the file input dialog box. Example is `.doc, text/csv,audio/*,video/*,image/*`",
946
+ "No file found": "No file found"
923
947
  }
package/markup/admin.js CHANGED
@@ -7,7 +7,6 @@
7
7
 
8
8
  const {
9
9
  div,
10
- //hr,
11
10
  form,
12
11
  input,
13
12
  label,
@@ -18,16 +17,8 @@ const {
18
17
  li,
19
18
  } = require("@saltcorn/markup/tags");
20
19
  const db = require("@saltcorn/data/db");
21
- const {
22
- //getConfig,
23
- //setConfig,
24
- //getAllConfigOrDefaults,
25
- //deleteConfig,
26
- configTypes,
27
- isFixedConfig,
28
- } = require("@saltcorn/data/models/config");
20
+ const { configTypes, isFixedConfig } = require("@saltcorn/data/models/config");
29
21
  const { getState } = require("@saltcorn/data/db/state");
30
-
31
22
  const Form = require("@saltcorn/data/models/form");
32
23
  const Table = require("@saltcorn/data/models/table");
33
24
  const View = require("@saltcorn/data/models/view");
@@ -77,14 +68,40 @@ const restore_backup = (csrf, inner, action = `/admin/restore`) =>
77
68
  * @param {*} opts.req
78
69
  * @returns {object}
79
70
  */
80
- const add_edit_bar = ({ role, title, contents, what, url, req }) => {
71
+ const add_edit_bar = ({
72
+ role,
73
+ title,
74
+ contents,
75
+ what,
76
+ url,
77
+ req,
78
+ viewtemplate,
79
+ table,
80
+ cfgUrl,
81
+ }) => {
81
82
  if (role > 1 && req && req.xhr) return { above: [contents] }; //make sure not put in card
82
83
  if (role > 1) return contents;
84
+ let viewSpec = "";
85
+ if (viewtemplate) viewSpec = viewtemplate;
86
+ if (table) {
87
+ const tbl = Table.findOne(table);
88
+ if (tbl)
89
+ viewSpec = `${viewSpec} on <a href="/table/${table}">${tbl.name}</a>`;
90
+ }
91
+
83
92
  const bar = div(
84
93
  { class: "alert alert-light d-print-none admin-edit-bar" },
85
94
  title,
86
- what && span({ class: "ms-1 badge bg-primary" }, what),
87
- a({ class: "ms-4", href: url }, "Edit&nbsp;", i({ class: "fas fa-edit" }))
95
+ what && span({ class: "ms-1 me-2 badge bg-primary" }, what),
96
+ viewSpec,
97
+ a({ class: "ms-2", href: url }, "Edit&nbsp;", i({ class: "fas fa-edit" })),
98
+ cfgUrl
99
+ ? a(
100
+ { class: "ms-1", href: cfgUrl },
101
+ "Configure&nbsp;",
102
+ i({ class: "fas fa-cog" })
103
+ )
104
+ : ""
88
105
  );
89
106
 
90
107
  if (contents.above) {
@@ -122,35 +139,35 @@ const send_settings_page = ({
122
139
  const pillCard = no_nav_pills
123
140
  ? []
124
141
  : [
125
- {
126
- type: "card",
127
- class: "mt-0",
128
- contents: div(
129
- { class: "d-flex" },
130
- ul(
131
- { class: "nav nav-pills plugin-section" },
132
- sub_sections.map(({ text, href }) =>
133
- li(
134
- { class: "nav-item" },
135
- a(
136
- {
137
- href,
138
- class: ["nav-link", active_sub === text && "active"],
139
- },
140
- req.__(text)
142
+ {
143
+ type: "card",
144
+ class: "mt-0",
145
+ contents: div(
146
+ { class: "d-flex" },
147
+ ul(
148
+ { class: "nav nav-pills plugin-section" },
149
+ sub_sections.map(({ text, href }) =>
150
+ li(
151
+ { class: "nav-item" },
152
+ a(
153
+ {
154
+ href,
155
+ class: ["nav-link", active_sub === text && "active"],
156
+ },
157
+ req.__(text)
158
+ )
141
159
  )
142
160
  )
143
161
  )
144
- )
145
- ),
146
- },
147
- ];
162
+ ),
163
+ },
164
+ ];
148
165
  // headers
149
166
  const title = headers
150
167
  ? {
151
- title: req.__(active_sub),
152
- headers,
153
- }
168
+ title: req.__(active_sub),
169
+ headers,
170
+ }
154
171
  : req.__(active_sub);
155
172
  res.sendWrap(title, {
156
173
  above: [
@@ -167,10 +184,10 @@ const send_settings_page = ({
167
184
  },
168
185
  ...(sub2_page
169
186
  ? [
170
- {
171
- text: sub2_page,
172
- },
173
- ]
187
+ {
188
+ text: sub2_page,
189
+ },
190
+ ]
174
191
  : []),
175
192
  ],
176
193
  },
@@ -199,9 +216,9 @@ const send_infoarch_page = (args) => {
199
216
  { text: "Languages", href: "/site-structure/localizer" },
200
217
  ...(tenant_list
201
218
  ? [
202
- { text: "Tenants", href: "/tenant/list" },
203
- { text: "Multitenancy", href: "/tenant/settings" },
204
- ]
219
+ { text: "Tenants", href: "/tenant/list" },
220
+ { text: "Multitenancy", href: "/tenant/settings" },
221
+ ]
205
222
  : []),
206
223
  { text: "Tags", href: "/tag" },
207
224
  { text: "Diagram", href: "/diagram" },
@@ -245,6 +262,7 @@ const send_files_page = (args) => {
245
262
  sub_sections: [
246
263
  { text: "Files", href: "/files" },
247
264
  { text: "Storage", href: "/files/storage" },
265
+ { text: "Settings", href: "/files/settings" },
248
266
  ],
249
267
  ...args,
250
268
  });
@@ -343,8 +361,8 @@ const flash_restart = (req) => {
343
361
  req.flash(
344
362
  "warning",
345
363
  req.__(`Restart required for changes to take effect.`) +
346
- " " +
347
- a({ href: "/admin/system" }, req.__("Restart here"))
364
+ " " +
365
+ a({ href: "/admin/system" }, req.__("Restart here"))
348
366
  );
349
367
  };
350
368
 
@@ -369,7 +387,7 @@ const config_fields_form = async ({
369
387
 
370
388
  for (const name of field_names) {
371
389
  values[name] = state.getConfig(name);
372
- //console.log(`config field name: %s`,name);
390
+ // console.log(`config field name: %s`,name);
373
391
  if (configTypes[name].root_only && tenant !== db.connectObj.default_schema)
374
392
  continue;
375
393
  const isView = (configTypes[name].type || "").startsWith("View ");
@@ -397,16 +415,16 @@ const config_fields_form = async ({
397
415
  isView || isRole || isTenant
398
416
  ? "String"
399
417
  : configTypes[name].input_type
400
- ? undefined
401
- : configTypes[name].type,
418
+ ? undefined
419
+ : configTypes[name].type,
402
420
  input_type: configTypes[name].input_type,
403
421
  attributes: isView
404
422
  ? await viewAttributes(name)
405
423
  : isRole
406
- ? roleAttribs
407
- : isTenant
408
- ? await getTenants()
409
- : configTypes[name].attributes,
424
+ ? roleAttribs
425
+ : isTenant
426
+ ? await getTenants()
427
+ : configTypes[name].attributes,
410
428
  });
411
429
  }
412
430
  const form = new Form({
package/markup/forms.js CHANGED
@@ -11,13 +11,11 @@ const {
11
11
  text,
12
12
  label,
13
13
  input,
14
- div,
15
- i,
16
- h5,
17
14
  } = require("@saltcorn/markup/tags");
18
15
  const { csrfField } = require("../routes/utils");
19
16
 
20
17
  /**
18
+ * Edit Role form (for admin)
21
19
  * @param {object} opts
22
20
  * @param {string} opts.url
23
21
  * @param {Role} opts.current_role
@@ -47,30 +45,36 @@ const editRoleForm = ({ url, current_role, roles, req }) =>
47
45
  );
48
46
 
49
47
  /**
50
- * @param {object} req
48
+ * File upload form (for admin)
49
+ * @param {object} req
50
+ * @param folder
51
51
  * @returns {Form}
52
52
  */
53
- const fileUploadForm = (req, folder) =>
54
- form(
55
- {
56
- action: "/files/upload",
57
- method: "post",
58
- encType: "multipart/form-data",
59
- },
60
- csrfField(req),
61
- label(req.__("Upload file ")),
62
- input({
63
- name: "file",
64
- class: "form-control ms-1 w-unset d-inline",
65
- type: "file",
66
- onchange: "form.submit()",
67
- multiple: true,
68
- }),
69
- folder && input({ type: "hidden", name: "folder", value: folder })
70
- );
53
+ const fileUploadForm = (req, folder
54
+ ) => {
55
+ const frm = form(
56
+ {
57
+ action: "/files/upload",
58
+ method: "post",
59
+ enctype: "multipart/form-data",
60
+ },
61
+ csrfField(req),
62
+ label(req.__("Upload file(s)")),
63
+ input({
64
+ name: "file",
65
+ class: "form-control ms-1 w-unset d-inline",
66
+ type: "file",
67
+ onchange: "form.submit()",
68
+ multiple: true,
69
+ }),
70
+ folder && input({type: "hidden", name: "folder", value: folder})
71
+ );
72
+ return frm;
73
+ };
71
74
 
72
75
  /**
73
- * @param {string} wizardTitle
76
+ * Get Wizard Card Title
77
+ * @param {string} wizardTitle
74
78
  * @param {*} wf
75
79
  * @param {object} wfres
76
80
  * @returns {string}
package/package.json CHANGED
@@ -1,18 +1,18 @@
1
1
  {
2
2
  "name": "@saltcorn/server",
3
- "version": "0.8.0-beta.2",
3
+ "version": "0.8.0-beta.4",
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
- "@saltcorn/base-plugin": "0.8.0-beta.2",
10
- "@saltcorn/builder": "0.8.0-beta.2",
11
- "@saltcorn/data": "0.8.0-beta.2",
12
- "@saltcorn/admin-models": "0.8.0-beta.2",
13
- "@saltcorn/filemanager": "0.8.0-beta.2",
14
- "@saltcorn/markup": "0.8.0-beta.2",
15
- "@saltcorn/sbadmin2": "0.8.0-beta.2",
9
+ "@saltcorn/base-plugin": "0.8.0-beta.4",
10
+ "@saltcorn/builder": "0.8.0-beta.4",
11
+ "@saltcorn/data": "0.8.0-beta.4",
12
+ "@saltcorn/admin-models": "0.8.0-beta.4",
13
+ "@saltcorn/filemanager": "0.8.0-beta.4",
14
+ "@saltcorn/markup": "0.8.0-beta.4",
15
+ "@saltcorn/sbadmin2": "0.8.0-beta.4",
16
16
  "@socket.io/cluster-adapter": "^0.1.0",
17
17
  "@socket.io/sticky": "^1.0.1",
18
18
  "aws-sdk": "^2.1037.0",
@@ -201,12 +201,12 @@ function view_post(viewname, route, data, onDone) {
201
201
  notifyAlert({ type: "danger", text: res.responseText });
202
202
  });
203
203
  }
204
- var logged_errors = [];
204
+ let logged_errors = [];
205
205
  function globalErrorCatcher(message, source, lineno, colno, error) {
206
206
  if (error && error.preventDefault) error.preventDefault();
207
207
  if (logged_errors.includes(message)) return;
208
208
  logged_errors.push(message);
209
- var data = { message, stack: (error && error.stack) || "" };
209
+ const data = { message, stack: (error && error.stack) || "" };
210
210
  $.ajax("/crashlog/", {
211
211
  dataType: "json",
212
212
  type: "POST",