@saltcorn/server 0.8.0-beta.4 → 0.8.0
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/app.js +7 -6
- package/auth/admin.js +226 -217
- package/auth/index.js +20 -20
- package/auth/roleadmin.js +2 -9
- package/auth/routes.js +193 -139
- package/auth/testhelp.js +62 -55
- package/fixture_persons.js +1 -1
- package/index.js +22 -22
- package/locales/en.json +3 -1
- package/locales/ru.json +25 -19
- package/markup/admin.js +22 -15
- package/markup/blockly.js +1 -1
- package/markup/expression_blurb.js +15 -15
- package/markup/forms.js +21 -22
- package/markup/index.js +20 -20
- package/markup/plugin-store.js +4 -4
- package/package.json +8 -8
- package/public/diagram_utils.js +22 -9
- package/public/saltcorn.css +6 -0
- package/restart_watcher.js +157 -157
- package/routes/actions.js +4 -11
- package/routes/admin.js +8 -5
- package/routes/api.js +9 -9
- package/routes/common_lists.js +127 -130
- package/routes/delete.js +2 -2
- package/routes/edit.js +1 -1
- package/routes/fields.js +4 -2
- package/routes/files.js +112 -94
- package/routes/homepage.js +1 -1
- package/routes/infoarch.js +1 -1
- package/routes/list.js +6 -5
- package/routes/packs.js +1 -2
- package/routes/pageedit.js +1 -1
- package/routes/tag_entries.js +1 -1
- package/routes/utils.js +3 -1
- package/s3storage.js +6 -7
- package/serve.js +35 -31
- package/systemd.js +23 -21
- package/wrapper.js +44 -45
package/app.js
CHANGED
|
@@ -125,7 +125,7 @@ const getApp = async (opts = {}) => {
|
|
|
125
125
|
// no jwt and session id at the same time
|
|
126
126
|
if (!(jwt_extractor(req) && req.cookies && req.cookies["connect.sid"]))
|
|
127
127
|
next();
|
|
128
|
-
|
|
128
|
+
});
|
|
129
129
|
app.use(flash());
|
|
130
130
|
|
|
131
131
|
//static serving
|
|
@@ -171,7 +171,8 @@ const getApp = async (opts = {}) => {
|
|
|
171
171
|
app.use(
|
|
172
172
|
`/static_assets/${version_tag}`,
|
|
173
173
|
express.static(
|
|
174
|
-
path.dirname(require.resolve("@saltcorn/filemanager/package.json")) +
|
|
174
|
+
path.dirname(require.resolve("@saltcorn/filemanager/package.json")) +
|
|
175
|
+
"/public/build",
|
|
175
176
|
{
|
|
176
177
|
maxAge: development_mode ? 0 : "100d",
|
|
177
178
|
}
|
|
@@ -348,13 +349,13 @@ Sitemap: ${base}sitemap.xml
|
|
|
348
349
|
<urlset
|
|
349
350
|
xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
350
351
|
${urls
|
|
351
|
-
|
|
352
|
-
|
|
352
|
+
.map(
|
|
353
|
+
(url) => `<url>
|
|
353
354
|
<loc>${url}</loc>
|
|
354
355
|
<lastmod>${now}</lastmod>
|
|
355
356
|
</url>`
|
|
356
|
-
|
|
357
|
-
|
|
357
|
+
)
|
|
358
|
+
.join("")}
|
|
358
359
|
|
|
359
360
|
</urlset>`);
|
|
360
361
|
})
|
package/auth/admin.js
CHANGED
|
@@ -12,7 +12,14 @@ const User = require("@saltcorn/data/models/user");
|
|
|
12
12
|
const View = require("@saltcorn/data/models/view");
|
|
13
13
|
const Field = require("@saltcorn/data/models/field");
|
|
14
14
|
const Form = require("@saltcorn/data/models/form");
|
|
15
|
-
const {
|
|
15
|
+
const {
|
|
16
|
+
mkTable,
|
|
17
|
+
renderForm,
|
|
18
|
+
link,
|
|
19
|
+
post_btn,
|
|
20
|
+
settingsDropdown,
|
|
21
|
+
post_dropdown_item,
|
|
22
|
+
} = require("@saltcorn/markup");
|
|
16
23
|
const { isAdmin, error_catcher } = require("../routes/utils");
|
|
17
24
|
const { send_reset_email } = require("./resetpw");
|
|
18
25
|
const { getState } = require("@saltcorn/data/db/state");
|
|
@@ -50,8 +57,10 @@ const getUserFields = async (req) => {
|
|
|
50
57
|
(signup_form.configuration.columns || []).forEach((f) => {
|
|
51
58
|
const uf = userFields.find((uff) => uff.name === f.field_name);
|
|
52
59
|
if (uf) {
|
|
53
|
-
|
|
54
|
-
|
|
60
|
+
if (!f?.fieldview?.unsuitableAsAdminDefault) {
|
|
61
|
+
uf.fieldview = f.fieldview;
|
|
62
|
+
uf.attributes = { ...f.configuration, ...uf.attributes };
|
|
63
|
+
}
|
|
55
64
|
}
|
|
56
65
|
});
|
|
57
66
|
}
|
|
@@ -159,33 +168,33 @@ const user_dropdown = (user, req, can_reset) =>
|
|
|
159
168
|
req
|
|
160
169
|
),
|
|
161
170
|
can_reset &&
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
171
|
+
post_dropdown_item(
|
|
172
|
+
`/useradmin/reset-password/${user.id}`,
|
|
173
|
+
'<i class="fas fa-envelope"></i> ' +
|
|
174
|
+
req.__("Send password reset email"),
|
|
175
|
+
req
|
|
176
|
+
),
|
|
168
177
|
can_reset &&
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
178
|
+
!user.verified_on &&
|
|
179
|
+
getState().getConfig("verification_view", "") &&
|
|
180
|
+
post_dropdown_item(
|
|
181
|
+
`/useradmin/send-verification/${user.id}`,
|
|
182
|
+
'<i class="fas fa-envelope"></i> ' +
|
|
183
|
+
req.__("Send verification email"),
|
|
184
|
+
req
|
|
185
|
+
),
|
|
177
186
|
user.disabled &&
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
187
|
+
post_dropdown_item(
|
|
188
|
+
`/useradmin/enable/${user.id}`,
|
|
189
|
+
'<i class="fas fa-play"></i> ' + req.__("Enable"),
|
|
190
|
+
req
|
|
191
|
+
),
|
|
183
192
|
!user.disabled &&
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
193
|
+
post_dropdown_item(
|
|
194
|
+
`/useradmin/disable/${user.id}`,
|
|
195
|
+
'<i class="fas fa-pause"></i> ' + req.__("Disable"),
|
|
196
|
+
req
|
|
197
|
+
),
|
|
189
198
|
div({ class: "dropdown-divider" }),
|
|
190
199
|
post_dropdown_item(
|
|
191
200
|
`/useradmin/delete/${user.id}`,
|
|
@@ -209,7 +218,7 @@ router.get(
|
|
|
209
218
|
const users = await User.find({}, { orderBy: "id" });
|
|
210
219
|
const roles = await User.get_roles();
|
|
211
220
|
let roleMap = {};
|
|
212
|
-
roles.forEach(r => {
|
|
221
|
+
roles.forEach((r) => {
|
|
213
222
|
roleMap[r.id] = r.role;
|
|
214
223
|
});
|
|
215
224
|
const can_reset = getState().getConfig("smtp_host", "") !== "";
|
|
@@ -238,10 +247,10 @@ router.get(
|
|
|
238
247
|
{
|
|
239
248
|
label: req.__("Verified"),
|
|
240
249
|
key: (r) =>
|
|
241
|
-
|
|
250
|
+
r.verified_on
|
|
242
251
|
? i({
|
|
243
|
-
|
|
244
|
-
|
|
252
|
+
class: "fas fa-check-circle text-success",
|
|
253
|
+
})
|
|
245
254
|
: "",
|
|
246
255
|
},
|
|
247
256
|
{ label: req.__("Role"), key: (r) => roleMap[r.role_id] },
|
|
@@ -291,23 +300,23 @@ router.get(
|
|
|
291
300
|
* @returns {Form}
|
|
292
301
|
*/
|
|
293
302
|
const auth_settings_form = async (req) =>
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
303
|
+
await config_fields_form({
|
|
304
|
+
req,
|
|
305
|
+
field_names: [
|
|
306
|
+
"allow_signup",
|
|
307
|
+
"login_menu",
|
|
308
|
+
"allow_forgot",
|
|
309
|
+
"new_user_form",
|
|
310
|
+
"login_form",
|
|
311
|
+
"signup_form",
|
|
312
|
+
"user_settings_form",
|
|
313
|
+
"verification_view",
|
|
314
|
+
"elevate_verified",
|
|
315
|
+
"email_mask",
|
|
316
|
+
],
|
|
317
|
+
action: "/useradmin/settings",
|
|
318
|
+
submitLabel: req.__("Save"),
|
|
319
|
+
});
|
|
311
320
|
|
|
312
321
|
/**
|
|
313
322
|
* HTTP Settings Form
|
|
@@ -315,19 +324,18 @@ const auth_settings_form = async (req) =>
|
|
|
315
324
|
* @returns {Form}
|
|
316
325
|
*/
|
|
317
326
|
const http_settings_form = async (req) =>
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
327
|
+
await config_fields_form({
|
|
328
|
+
req,
|
|
329
|
+
field_names: [
|
|
330
|
+
"timeout",
|
|
331
|
+
"cookie_duration",
|
|
332
|
+
"cookie_duration_remember",
|
|
333
|
+
"cookie_sessions",
|
|
334
|
+
"custom_http_headers",
|
|
335
|
+
],
|
|
336
|
+
action: "/useradmin/http",
|
|
337
|
+
submitLabel: req.__("Save"),
|
|
338
|
+
});
|
|
331
339
|
|
|
332
340
|
/**
|
|
333
341
|
* Permissions Setting Form
|
|
@@ -335,16 +343,16 @@ const http_settings_form = async (req) =>
|
|
|
335
343
|
* @returns {Form}
|
|
336
344
|
*/
|
|
337
345
|
const permissions_settings_form = async (req) =>
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
//hidden "exttables_min_role_read",
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
346
|
+
await config_fields_form({
|
|
347
|
+
req,
|
|
348
|
+
field_names: [
|
|
349
|
+
"min_role_upload",
|
|
350
|
+
"min_role_apikeygen",
|
|
351
|
+
//hidden "exttables_min_role_read",
|
|
352
|
+
],
|
|
353
|
+
action: "/useradmin/permissions",
|
|
354
|
+
submitLabel: req.__("Save"),
|
|
355
|
+
});
|
|
348
356
|
|
|
349
357
|
/**
|
|
350
358
|
* HTTP GET for /useradmin/settings
|
|
@@ -360,7 +368,7 @@ router.get(
|
|
|
360
368
|
send_users_page({
|
|
361
369
|
res,
|
|
362
370
|
req,
|
|
363
|
-
active_sub: "
|
|
371
|
+
active_sub: "Login and Signup",
|
|
364
372
|
contents: {
|
|
365
373
|
type: "card",
|
|
366
374
|
title: req.__("Authentication settings"),
|
|
@@ -409,21 +417,21 @@ router.post(
|
|
|
409
417
|
* @memberof module:auth/admin~auth/adminRouter
|
|
410
418
|
*/
|
|
411
419
|
router.get(
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
420
|
+
"/http",
|
|
421
|
+
isAdmin,
|
|
422
|
+
error_catcher(async (req, res) => {
|
|
423
|
+
const form = await http_settings_form(req);
|
|
424
|
+
send_users_page({
|
|
425
|
+
res,
|
|
426
|
+
req,
|
|
427
|
+
active_sub: "HTTP",
|
|
428
|
+
contents: {
|
|
429
|
+
type: "card",
|
|
430
|
+
title: req.__("HTTP settings"),
|
|
431
|
+
contents: [renderForm(form, req.csrfToken())],
|
|
432
|
+
},
|
|
433
|
+
});
|
|
434
|
+
})
|
|
427
435
|
);
|
|
428
436
|
|
|
429
437
|
/**
|
|
@@ -433,29 +441,29 @@ router.get(
|
|
|
433
441
|
* @memberof module:auth/admin~auth/adminRouter
|
|
434
442
|
*/
|
|
435
443
|
router.post(
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
444
|
+
"/http",
|
|
445
|
+
isAdmin,
|
|
446
|
+
error_catcher(async (req, res) => {
|
|
447
|
+
const form = await http_settings_form(req);
|
|
448
|
+
form.validate(req.body);
|
|
449
|
+
if (form.hasErrors) {
|
|
450
|
+
send_users_page({
|
|
451
|
+
res,
|
|
452
|
+
req,
|
|
453
|
+
active_sub: "HTTP",
|
|
454
|
+
contents: {
|
|
455
|
+
type: "card",
|
|
456
|
+
title: req.__("HTTP settings"),
|
|
457
|
+
contents: [renderForm(form, req.csrfToken())],
|
|
458
|
+
},
|
|
459
|
+
});
|
|
460
|
+
} else {
|
|
461
|
+
await save_config_from_form(form);
|
|
462
|
+
req.flash("success", req.__("HTTP settings updated"));
|
|
463
|
+
if (!req.xhr) res.redirect("/useradmin/http");
|
|
464
|
+
else res.json({ success: "ok" });
|
|
465
|
+
}
|
|
466
|
+
})
|
|
459
467
|
);
|
|
460
468
|
|
|
461
469
|
/**
|
|
@@ -465,21 +473,21 @@ router.post(
|
|
|
465
473
|
* @memberof module:auth/admin~auth/adminRouter
|
|
466
474
|
*/
|
|
467
475
|
router.get(
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
476
|
+
"/permissions",
|
|
477
|
+
isAdmin,
|
|
478
|
+
error_catcher(async (req, res) => {
|
|
479
|
+
const form = await permissions_settings_form(req);
|
|
480
|
+
send_users_page({
|
|
481
|
+
res,
|
|
482
|
+
req,
|
|
483
|
+
active_sub: "Permissions",
|
|
484
|
+
contents: {
|
|
485
|
+
type: "card",
|
|
486
|
+
title: req.__("Permissions settings"),
|
|
487
|
+
contents: [renderForm(form, req.csrfToken())],
|
|
488
|
+
},
|
|
489
|
+
});
|
|
490
|
+
})
|
|
483
491
|
);
|
|
484
492
|
|
|
485
493
|
/**
|
|
@@ -489,29 +497,29 @@ router.get(
|
|
|
489
497
|
* @memberof module:auth/admin~auth/adminRouter
|
|
490
498
|
*/
|
|
491
499
|
router.post(
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
500
|
+
"/permissions",
|
|
501
|
+
isAdmin,
|
|
502
|
+
error_catcher(async (req, res) => {
|
|
503
|
+
const form = await permissions_settings_form(req);
|
|
504
|
+
form.validate(req.body);
|
|
505
|
+
if (form.hasErrors) {
|
|
506
|
+
send_users_page({
|
|
507
|
+
res,
|
|
508
|
+
req,
|
|
509
|
+
active_sub: "Permissions",
|
|
510
|
+
contents: {
|
|
511
|
+
type: "card",
|
|
512
|
+
title: req.__("Permissions settings"),
|
|
513
|
+
contents: [renderForm(form, req.csrfToken())],
|
|
514
|
+
},
|
|
515
|
+
});
|
|
516
|
+
} else {
|
|
517
|
+
await save_config_from_form(form);
|
|
518
|
+
req.flash("success", req.__("Permissions settings updated"));
|
|
519
|
+
if (!req.xhr) res.redirect("/useradmin/permissions");
|
|
520
|
+
else res.json({ success: "ok" });
|
|
521
|
+
}
|
|
522
|
+
})
|
|
515
523
|
);
|
|
516
524
|
|
|
517
525
|
/**
|
|
@@ -549,15 +557,15 @@ router.get(
|
|
|
549
557
|
above: [
|
|
550
558
|
...(letsencrypt && has_custom
|
|
551
559
|
? [
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
560
|
+
{
|
|
561
|
+
type: "card",
|
|
562
|
+
contents: p(
|
|
563
|
+
req.__(
|
|
564
|
+
"You have enabled both Let's Encrypt certificates and custom SSL certificates. Let's Encrypt takes priority and the custom certificates will be ignored."
|
|
565
|
+
)
|
|
566
|
+
),
|
|
567
|
+
},
|
|
568
|
+
]
|
|
561
569
|
: []),
|
|
562
570
|
{
|
|
563
571
|
type: "card",
|
|
@@ -578,33 +586,33 @@ router.get(
|
|
|
578
586
|
),
|
|
579
587
|
letsencrypt
|
|
580
588
|
? post_btn(
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
589
|
+
"/config/delete/letsencrypt",
|
|
590
|
+
req.__("Disable LetsEncrypt HTTPS"),
|
|
591
|
+
req.csrfToken(),
|
|
592
|
+
{ btnClass: "btn-danger", req }
|
|
593
|
+
)
|
|
586
594
|
: post_btn(
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
595
|
+
"/admin/enable-letsencrypt",
|
|
596
|
+
req.__("Enable LetsEncrypt HTTPS"),
|
|
597
|
+
req.csrfToken(),
|
|
598
|
+
{ confirm: true, req }
|
|
599
|
+
),
|
|
592
600
|
!letsencrypt &&
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
601
|
+
show_warning &&
|
|
602
|
+
!has_custom &&
|
|
603
|
+
div(
|
|
604
|
+
{ class: "mt-3 alert alert-danger" },
|
|
605
|
+
p(
|
|
606
|
+
req.__(
|
|
607
|
+
"The address you are using to reach Saltcorn does not match the Base URL."
|
|
608
|
+
)
|
|
609
|
+
),
|
|
610
|
+
p(
|
|
611
|
+
req.__(
|
|
612
|
+
"The DNS A records (for * and @, or a subdomain) should point to this server's IP address before enabling LetsEncrypt"
|
|
613
|
+
)
|
|
600
614
|
)
|
|
601
615
|
),
|
|
602
|
-
p(
|
|
603
|
-
req.__(
|
|
604
|
-
"The DNS A records (for * and @, or a subdomain) should point to this server's IP address before enabling LetsEncrypt"
|
|
605
|
-
)
|
|
606
|
-
)
|
|
607
|
-
),
|
|
608
616
|
],
|
|
609
617
|
},
|
|
610
618
|
{
|
|
@@ -641,11 +649,11 @@ router.get(
|
|
|
641
649
|
* @returns {Form}
|
|
642
650
|
*/
|
|
643
651
|
const ssl_form = async (req) =>
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
652
|
+
await config_fields_form({
|
|
653
|
+
req,
|
|
654
|
+
field_names: ["custom_ssl_certificate", "custom_ssl_private_key"],
|
|
655
|
+
action: "/useradmin/ssl/custom",
|
|
656
|
+
});
|
|
649
657
|
|
|
650
658
|
/**
|
|
651
659
|
* HTTP GET for /useradmin/ssl/custom
|
|
@@ -701,8 +709,8 @@ router.post(
|
|
|
701
709
|
req.flash(
|
|
702
710
|
"success",
|
|
703
711
|
req.__("Custom SSL enabled. Restart for changes to take effect.") +
|
|
704
|
-
|
|
705
|
-
|
|
712
|
+
" " +
|
|
713
|
+
a({ href: "/admin/system" }, req.__("Restart here"))
|
|
706
714
|
);
|
|
707
715
|
if (!req.xhr) {
|
|
708
716
|
res.redirect("/useradmin/ssl");
|
|
@@ -721,15 +729,15 @@ router.get(
|
|
|
721
729
|
"/table-access",
|
|
722
730
|
isAdmin,
|
|
723
731
|
error_catcher(async (req, res) => {
|
|
724
|
-
const tables = await Table.find()
|
|
732
|
+
const tables = await Table.find();
|
|
725
733
|
const roleOptions = (await User.get_roles()).map((r) => ({
|
|
726
734
|
value: r.id,
|
|
727
735
|
label: r.role,
|
|
728
736
|
}));
|
|
729
737
|
|
|
730
|
-
const contents = []
|
|
738
|
+
const contents = [];
|
|
731
739
|
for (const table of tables) {
|
|
732
|
-
if (table.external) continue
|
|
740
|
+
if (table.external) continue;
|
|
733
741
|
const fields = await table.getFields();
|
|
734
742
|
const userFields = fields
|
|
735
743
|
.filter((f) => f.reftable_name === "users")
|
|
@@ -773,7 +781,7 @@ router.get(
|
|
|
773
781
|
name: "min_role_read",
|
|
774
782
|
input_type: "select",
|
|
775
783
|
options: roleOptions,
|
|
776
|
-
attributes: { asideNext: true }
|
|
784
|
+
attributes: { asideNext: true },
|
|
777
785
|
},
|
|
778
786
|
{
|
|
779
787
|
label: req.__("Minimum role to write"),
|
|
@@ -784,16 +792,18 @@ router.get(
|
|
|
784
792
|
),
|
|
785
793
|
options: roleOptions,
|
|
786
794
|
},
|
|
787
|
-
]
|
|
788
|
-
})
|
|
795
|
+
],
|
|
796
|
+
});
|
|
789
797
|
form.hidden("id", "name");
|
|
790
|
-
form.values = table
|
|
798
|
+
form.values = table;
|
|
791
799
|
if (table.ownership_formula && !table.ownership_field_id)
|
|
792
800
|
form.values.ownership_field_id = "_formula";
|
|
793
|
-
contents.push(
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
801
|
+
contents.push(
|
|
802
|
+
div(
|
|
803
|
+
h5(a({ href: `/table/${table.id}` }, table.name)),
|
|
804
|
+
renderForm(form, req.csrfToken())
|
|
805
|
+
)
|
|
806
|
+
);
|
|
797
807
|
}
|
|
798
808
|
send_users_page({
|
|
799
809
|
res,
|
|
@@ -802,13 +812,12 @@ router.get(
|
|
|
802
812
|
contents: {
|
|
803
813
|
type: "card",
|
|
804
814
|
title: req.__("Table access"),
|
|
805
|
-
contents
|
|
815
|
+
contents,
|
|
806
816
|
},
|
|
807
817
|
});
|
|
808
818
|
})
|
|
809
819
|
);
|
|
810
820
|
|
|
811
|
-
|
|
812
821
|
/**
|
|
813
822
|
* @name get/:id
|
|
814
823
|
* @function
|
|
@@ -842,9 +851,9 @@ router.get(
|
|
|
842
851
|
div(
|
|
843
852
|
user.api_token
|
|
844
853
|
? span(
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
854
|
+
{ class: "me-1" },
|
|
855
|
+
req.__("API token for this user: ")
|
|
856
|
+
) + code(user.api_token)
|
|
848
857
|
: req.__("No API token issued")
|
|
849
858
|
),
|
|
850
859
|
// button for reset or generate api token
|
|
@@ -858,16 +867,16 @@ router.get(
|
|
|
858
867
|
),
|
|
859
868
|
// button for remove api token
|
|
860
869
|
user.api_token &&
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
870
|
+
div(
|
|
871
|
+
{ class: "mt-4 ms-2 d-inline-block" },
|
|
872
|
+
post_btn(
|
|
873
|
+
`/useradmin/remove-api-token/${user.id}`,
|
|
874
|
+
// TBD localization
|
|
875
|
+
user.api_token ? req.__("Remove") : req.__("Generate"),
|
|
876
|
+
req.csrfToken(),
|
|
877
|
+
{ req: req, confirm: true }
|
|
878
|
+
)
|
|
879
|
+
),
|
|
871
880
|
],
|
|
872
881
|
},
|
|
873
882
|
],
|
|
@@ -989,10 +998,10 @@ router.post(
|
|
|
989
998
|
// todo add test case
|
|
990
999
|
const result = await send_verification_email(u, req);
|
|
991
1000
|
if (result.error)
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
1001
|
+
req.flash(
|
|
1002
|
+
"danger",
|
|
1003
|
+
req.__(`Verification email sender error:`, result.error)
|
|
1004
|
+
);
|
|
996
1005
|
else
|
|
997
1006
|
req.flash(
|
|
998
1007
|
"success",
|