@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 +3 -19
- package/locales/en.json +10 -2
- package/locales/it.json +1 -1
- package/locales/ru.json +25 -1
- package/markup/admin.js +70 -52
- package/markup/forms.js +27 -23
- package/package.json +8 -8
- package/public/saltcorn.js +2 -2
- package/routes/admin.js +136 -142
- package/routes/fields.js +15 -4
- package/routes/files.js +83 -22
- package/routes/homepage.js +70 -64
- package/routes/infoarch.js +10 -7
- package/routes/menu.js +22 -12
- package/routes/page.js +6 -1
- package/routes/plugins.js +112 -106
- package/routes/tables.js +173 -164
- package/routes/utils.js +3 -2
- package/routes/view.js +9 -2
- package/s3storage.js +24 -11
package/routes/admin.js
CHANGED
|
@@ -366,7 +366,7 @@ router.get(
|
|
|
366
366
|
post_btn(
|
|
367
367
|
"/admin/backup",
|
|
368
368
|
i({ class: "fas fa-download me-2" }) +
|
|
369
|
-
|
|
369
|
+
req.__("Download a backup"),
|
|
370
370
|
req.csrfToken(),
|
|
371
371
|
{
|
|
372
372
|
btnClass: "btn-outline-primary",
|
|
@@ -385,21 +385,21 @@ router.get(
|
|
|
385
385
|
},
|
|
386
386
|
isRoot
|
|
387
387
|
? {
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
388
|
+
type: "card",
|
|
389
|
+
title: req.__("Automated backup"),
|
|
390
|
+
contents: div(
|
|
391
|
+
renderForm(backupForm, req.csrfToken()),
|
|
392
|
+
a(
|
|
393
|
+
{ href: "/admin/auto-backup-list" },
|
|
394
|
+
req.__("Restore/download automated backups »")
|
|
395
|
+
),
|
|
396
|
+
script(
|
|
397
|
+
domReady(
|
|
398
|
+
`$('#btnBackupNow').prop('disabled', $('#inputauto_backup_frequency').val()==='Never');`
|
|
399
|
+
)
|
|
399
400
|
)
|
|
400
|
-
)
|
|
401
|
-
|
|
402
|
-
}
|
|
401
|
+
),
|
|
402
|
+
}
|
|
403
403
|
: { type: "blank", contents: "" },
|
|
404
404
|
{
|
|
405
405
|
type: "card",
|
|
@@ -407,7 +407,9 @@ router.get(
|
|
|
407
407
|
contents: div(
|
|
408
408
|
p(
|
|
409
409
|
i(
|
|
410
|
-
req.__(
|
|
410
|
+
req.__(
|
|
411
|
+
"Snapshots store your application structure and definition, without the table data. Individual views and pages can be restored from snapshots from the <a href='/viewedit'>view</a> or <a href='/pageedit'>pages</a> overviews (\"Restore\" from individual page or view dropdowns)."
|
|
412
|
+
)
|
|
411
413
|
)
|
|
412
414
|
),
|
|
413
415
|
renderForm(aSnapshotForm, req.csrfToken()),
|
|
@@ -475,12 +477,17 @@ router.get(
|
|
|
475
477
|
ol(
|
|
476
478
|
li(req.__("Download one of the backups above")),
|
|
477
479
|
li(
|
|
478
|
-
a(
|
|
480
|
+
a(
|
|
481
|
+
{ href: "/admin/clear-all" },
|
|
482
|
+
req.__("Clear this application")
|
|
483
|
+
),
|
|
479
484
|
" ",
|
|
480
485
|
req.__("(tick all boxes)")
|
|
481
486
|
),
|
|
482
487
|
li(
|
|
483
|
-
req.__(
|
|
488
|
+
req.__(
|
|
489
|
+
"When prompted to create the first user, click the link to restore a backup"
|
|
490
|
+
)
|
|
484
491
|
),
|
|
485
492
|
li(req.__("Select the downloaded backup file"))
|
|
486
493
|
)
|
|
@@ -768,7 +775,8 @@ router.get(
|
|
|
768
775
|
isAdmin,
|
|
769
776
|
error_catcher(async (req, res) => {
|
|
770
777
|
const isRoot = db.getTenantSchema() === db.connectObj.default_schema;
|
|
771
|
-
const latest =
|
|
778
|
+
const latest =
|
|
779
|
+
isRoot && (await get_latest_npm_version("@saltcorn/cli", 1000));
|
|
772
780
|
const is_latest = packagejson.version === latest;
|
|
773
781
|
const git_commit = getGitRevision();
|
|
774
782
|
const can_update =
|
|
@@ -832,83 +840,71 @@ router.get(
|
|
|
832
840
|
th(req.__("Saltcorn version")),
|
|
833
841
|
td(
|
|
834
842
|
packagejson.version +
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
843
|
+
(isRoot && can_update
|
|
844
|
+
? post_btn(
|
|
845
|
+
"/admin/upgrade",
|
|
846
|
+
req.__("Upgrade"),
|
|
847
|
+
req.csrfToken(),
|
|
848
|
+
{
|
|
849
|
+
btnClass: "btn-primary btn-sm",
|
|
850
|
+
formClass: "d-inline",
|
|
851
|
+
}
|
|
852
|
+
)
|
|
853
|
+
: isRoot && is_latest
|
|
846
854
|
? span(
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
855
|
+
{ class: "badge bg-primary ms-2" },
|
|
856
|
+
req.__("Latest")
|
|
857
|
+
) +
|
|
858
|
+
post_btn(
|
|
859
|
+
"/admin/check-for-upgrade",
|
|
860
|
+
req.__("Check for updates"),
|
|
861
|
+
req.csrfToken(),
|
|
862
|
+
{
|
|
863
|
+
btnClass: "btn-primary btn-sm px-1 py-0",
|
|
864
|
+
formClass: "d-inline",
|
|
865
|
+
}
|
|
866
|
+
)
|
|
859
867
|
: "")
|
|
860
868
|
)
|
|
861
869
|
),
|
|
862
870
|
git_commit &&
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
871
|
+
tr(
|
|
872
|
+
th(req.__("git commit")),
|
|
873
|
+
td(
|
|
874
|
+
a(
|
|
875
|
+
{
|
|
876
|
+
href:
|
|
877
|
+
"https://github.com/saltcorn/saltcorn/commit/" +
|
|
878
|
+
git_commit,
|
|
879
|
+
},
|
|
880
|
+
git_commit.substring(0, 6)
|
|
881
|
+
)
|
|
873
882
|
)
|
|
874
|
-
)
|
|
875
|
-
),
|
|
883
|
+
),
|
|
876
884
|
tr(th(req.__("Node.js version")), td(process.version)),
|
|
877
885
|
tr(
|
|
878
886
|
th(req.__("Database type")),
|
|
879
887
|
td(db.isSQLite ? "SQLite " : "PostgreSQL ", dbversion)
|
|
880
888
|
),
|
|
881
|
-
|
|
882
|
-
tr(
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
)
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
tr(
|
|
889
|
-
th(req.__("Database port")),
|
|
890
|
-
td(db.connectObj.port)
|
|
891
|
-
)
|
|
892
|
-
: ""),
|
|
893
|
-
(isRoot?
|
|
894
|
-
tr(
|
|
889
|
+
isRoot
|
|
890
|
+
? tr(th(req.__("Database host")), td(db.connectObj.host))
|
|
891
|
+
: "",
|
|
892
|
+
isRoot
|
|
893
|
+
? tr(th(req.__("Database port")), td(db.connectObj.port))
|
|
894
|
+
: "",
|
|
895
|
+
isRoot
|
|
896
|
+
? tr(
|
|
895
897
|
th(req.__("Database name")),
|
|
896
898
|
td(db.connectObj.database)
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
)
|
|
904
|
-
: ""),
|
|
905
|
-
tr(
|
|
906
|
-
th(req.__("Database schema")),
|
|
907
|
-
td(db.getTenantSchema())
|
|
908
|
-
),
|
|
899
|
+
)
|
|
900
|
+
: "",
|
|
901
|
+
isRoot
|
|
902
|
+
? tr(th(req.__("Database user")), td(db.connectObj.user))
|
|
903
|
+
: "",
|
|
904
|
+
tr(th(req.__("Database schema")), td(db.getTenantSchema())),
|
|
909
905
|
tr(
|
|
910
|
-
|
|
911
|
-
|
|
906
|
+
th(req.__("Process uptime")),
|
|
907
|
+
td(moment(get_process_init_time()).fromNow(true))
|
|
912
908
|
)
|
|
913
909
|
)
|
|
914
910
|
),
|
|
@@ -974,7 +970,9 @@ router.post(
|
|
|
974
970
|
});
|
|
975
971
|
child.on("exit", function (code, signal) {
|
|
976
972
|
res.end(
|
|
977
|
-
req.__(
|
|
973
|
+
req.__(
|
|
974
|
+
`Upgrade done (if it was available) with code ${code}.\n\nPress the BACK button in your browser, then RELOAD the page.`
|
|
975
|
+
)
|
|
978
976
|
);
|
|
979
977
|
setTimeout(() => {
|
|
980
978
|
if (process.send) process.send("RestartServer");
|
|
@@ -1178,8 +1176,8 @@ router.post(
|
|
|
1178
1176
|
req.__(
|
|
1179
1177
|
"LetsEncrypt SSL enabled. Restart for changes to take effect."
|
|
1180
1178
|
) +
|
|
1181
|
-
|
|
1182
|
-
|
|
1179
|
+
" " +
|
|
1180
|
+
a({ href: "/admin/system" }, req.__("Restart here"))
|
|
1183
1181
|
);
|
|
1184
1182
|
res.redirect("/useradmin/ssl");
|
|
1185
1183
|
} catch (e) {
|
|
@@ -1255,13 +1253,13 @@ router.get(
|
|
|
1255
1253
|
contents: div(
|
|
1256
1254
|
pass
|
|
1257
1255
|
? div(
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1256
|
+
{ class: "alert alert-success", role: "alert" },
|
|
1257
|
+
i({ class: "fas fa-check-circle fa-lg me-2" }),
|
|
1258
|
+
h5(
|
|
1259
|
+
{ class: "d-inline" },
|
|
1260
|
+
req.__("No errors detected during configuration check")
|
|
1261
|
+
)
|
|
1263
1262
|
)
|
|
1264
|
-
)
|
|
1265
1263
|
: errors.map(mkError),
|
|
1266
1264
|
(warnings || []).map(mkWarning)
|
|
1267
1265
|
),
|
|
@@ -1819,15 +1817,11 @@ router.post(
|
|
|
1819
1817
|
* @returns {Promise<Form>} form
|
|
1820
1818
|
*/
|
|
1821
1819
|
const dev_form = async (req) => {
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
"log_level",
|
|
1828
|
-
],
|
|
1829
|
-
action: "/admin/dev",
|
|
1830
|
-
});
|
|
1820
|
+
return await config_fields_form({
|
|
1821
|
+
req,
|
|
1822
|
+
field_names: ["development_mode", "log_sql", "log_level"],
|
|
1823
|
+
action: "/admin/dev",
|
|
1824
|
+
});
|
|
1831
1825
|
};
|
|
1832
1826
|
/**
|
|
1833
1827
|
* Developer Mode page
|
|
@@ -1836,19 +1830,19 @@ const dev_form = async (req) => {
|
|
|
1836
1830
|
* @memberof module:routes/admin~routes/adminRouter
|
|
1837
1831
|
*/
|
|
1838
1832
|
router.get(
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1833
|
+
"/dev",
|
|
1834
|
+
isAdmin,
|
|
1835
|
+
error_catcher(async (req, res) => {
|
|
1836
|
+
const form = await dev_form(req);
|
|
1837
|
+
send_admin_page({
|
|
1838
|
+
res,
|
|
1839
|
+
req,
|
|
1840
|
+
active_sub: "Development",
|
|
1841
|
+
contents: {
|
|
1842
|
+
type: "card",
|
|
1843
|
+
title: req.__("Development settings"),
|
|
1844
|
+
contents: [
|
|
1845
|
+
renderForm(form, req.csrfToken()) /*,
|
|
1852
1846
|
a(
|
|
1853
1847
|
{
|
|
1854
1848
|
id: "testemail",
|
|
@@ -1856,11 +1850,11 @@ router.get(
|
|
|
1856
1850
|
class: "btn btn-primary",
|
|
1857
1851
|
},
|
|
1858
1852
|
req.__("Send test email")
|
|
1859
|
-
)
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1853
|
+
),*/,
|
|
1854
|
+
],
|
|
1855
|
+
},
|
|
1856
|
+
});
|
|
1857
|
+
})
|
|
1864
1858
|
);
|
|
1865
1859
|
|
|
1866
1860
|
/**
|
|
@@ -1870,27 +1864,27 @@ router.get(
|
|
|
1870
1864
|
* @memberof module:routes/admin~routes/adminRouter
|
|
1871
1865
|
*/
|
|
1872
1866
|
router.post(
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
);
|
|
1867
|
+
"/dev",
|
|
1868
|
+
isAdmin,
|
|
1869
|
+
error_catcher(async (req, res) => {
|
|
1870
|
+
const form = await dev_form(req);
|
|
1871
|
+
form.validate(req.body);
|
|
1872
|
+
if (form.hasErrors) {
|
|
1873
|
+
send_admin_page({
|
|
1874
|
+
res,
|
|
1875
|
+
req,
|
|
1876
|
+
active_sub: "Development",
|
|
1877
|
+
contents: {
|
|
1878
|
+
type: "card",
|
|
1879
|
+
title: req.__("Development settings"),
|
|
1880
|
+
contents: [renderForm(form, req.csrfToken())],
|
|
1881
|
+
},
|
|
1882
|
+
});
|
|
1883
|
+
} else {
|
|
1884
|
+
await save_config_from_form(form);
|
|
1885
|
+
req.flash("success", req.__("Development mode settings updated"));
|
|
1886
|
+
if (!req.xhr) res.redirect("/admin/dev");
|
|
1887
|
+
else res.json({ success: "ok" });
|
|
1888
|
+
}
|
|
1889
|
+
})
|
|
1890
|
+
);
|
package/routes/fields.js
CHANGED
|
@@ -66,7 +66,7 @@ const fieldForm = async (req, fkey_opts, existing_names, id, hasData) => {
|
|
|
66
66
|
return new Form({
|
|
67
67
|
action: "/field",
|
|
68
68
|
validator: (vs) => {
|
|
69
|
-
if (vs.calculated && vs.type
|
|
69
|
+
if (vs.calculated && vs.type === "File")
|
|
70
70
|
return req.__("Calculated fields cannot have File type");
|
|
71
71
|
if (vs.calculated && vs.type.startsWith("Key to"))
|
|
72
72
|
return req.__("Calculated fields cannot have Key type");
|
|
@@ -182,8 +182,8 @@ const fieldFlow = (req) =>
|
|
|
182
182
|
new Workflow({
|
|
183
183
|
action: "/field",
|
|
184
184
|
onDone: async (context) => {
|
|
185
|
-
const thetype = getState().types[context.type];
|
|
186
|
-
|
|
185
|
+
//const thetype = getState().types[context.type];
|
|
186
|
+
const attributes = context.attributes || {};
|
|
187
187
|
attributes.default = context.default;
|
|
188
188
|
attributes.summary_field = context.summary_field;
|
|
189
189
|
attributes.include_fts = context.include_fts;
|
|
@@ -291,6 +291,8 @@ const fieldFlow = (req) =>
|
|
|
291
291
|
form: async (context) => {
|
|
292
292
|
if (context.type === "File") {
|
|
293
293
|
const roles = await User.get_roles();
|
|
294
|
+
const default_file_accept_filter = await getState().getConfig("files_accept_filter_default");
|
|
295
|
+
//console.log("default_file_accept_filter",default_file_accept_filter);
|
|
294
296
|
return new Form({
|
|
295
297
|
fields: [
|
|
296
298
|
{
|
|
@@ -310,6 +312,15 @@ const fieldFlow = (req) =>
|
|
|
310
312
|
"Deleting a row will also delete the file referenced by this field"
|
|
311
313
|
),
|
|
312
314
|
},
|
|
315
|
+
{
|
|
316
|
+
name: "files_accept_filter",
|
|
317
|
+
type: "String",
|
|
318
|
+
label: req.__("Files accept filter"),
|
|
319
|
+
sublabel: req.__(
|
|
320
|
+
"Specifies a filter for what file types the user can pick from the file input dialog box. Example is `.doc,audio/*,video/*,image/*`"
|
|
321
|
+
),
|
|
322
|
+
default: default_file_accept_filter,
|
|
323
|
+
},
|
|
313
324
|
],
|
|
314
325
|
});
|
|
315
326
|
} else {
|
|
@@ -634,7 +645,7 @@ router.post(
|
|
|
634
645
|
);
|
|
635
646
|
|
|
636
647
|
/**
|
|
637
|
-
*
|
|
648
|
+
* Test formula
|
|
638
649
|
* @function
|
|
639
650
|
* @memberof module:routes/fields~fieldsRouter
|
|
640
651
|
* @function
|
package/routes/files.js
CHANGED
|
@@ -13,24 +13,12 @@ const s3storage = require("../s3storage");
|
|
|
13
13
|
const resizer = require("resize-with-sharp-or-jimp");
|
|
14
14
|
const db = require("@saltcorn/data/db");
|
|
15
15
|
|
|
16
|
-
const {
|
|
17
|
-
mkTable,
|
|
18
|
-
renderForm,
|
|
19
|
-
link,
|
|
20
|
-
//post_btn,
|
|
21
|
-
post_delete_btn,
|
|
22
|
-
} = require("@saltcorn/markup");
|
|
16
|
+
const { renderForm } = require("@saltcorn/markup");
|
|
23
17
|
const { isAdmin, error_catcher, setTenant } = require("./utils.js");
|
|
24
|
-
const { h1, div, text
|
|
25
|
-
// const { csrfField } = require("./utils");
|
|
18
|
+
const { h1, div, text } = require("@saltcorn/markup/tags");
|
|
26
19
|
const { editRoleForm, fileUploadForm } = require("../markup/forms.js");
|
|
27
20
|
const { strictParseInt } = require("@saltcorn/data/plugin-helper");
|
|
28
|
-
const {
|
|
29
|
-
send_files_page,
|
|
30
|
-
config_fields_form,
|
|
31
|
-
save_config_from_form,
|
|
32
|
-
} = require("../markup/admin");
|
|
33
|
-
// const fsp = require("fs").promises;
|
|
21
|
+
const { send_files_page, config_fields_form, save_config_from_form } = require("../markup/admin");
|
|
34
22
|
const fs = require("fs");
|
|
35
23
|
const path = require("path");
|
|
36
24
|
|
|
@@ -74,7 +62,6 @@ router.get(
|
|
|
74
62
|
const safeDir = File.normalise(dir || "/")
|
|
75
63
|
const rows = await File.find({ folder: dir }, { orderBy: "filename" });
|
|
76
64
|
const roles = await User.get_roles();
|
|
77
|
-
//console.log(rows);
|
|
78
65
|
if (safeDir && safeDir !== "/" && safeDir !== ".") {
|
|
79
66
|
let dirname = path.dirname(safeDir)
|
|
80
67
|
if (dirname === ".") dirname = "/"
|
|
@@ -314,7 +301,7 @@ router.post(
|
|
|
314
301
|
*/
|
|
315
302
|
router.post(
|
|
316
303
|
"/upload",
|
|
317
|
-
setTenant,
|
|
304
|
+
setTenant,
|
|
318
305
|
error_catcher(async (req, res) => {
|
|
319
306
|
let { folder } = req.body
|
|
320
307
|
let jsonResp = {};
|
|
@@ -395,12 +382,12 @@ router.post(
|
|
|
395
382
|
);
|
|
396
383
|
|
|
397
384
|
/**
|
|
398
|
-
* Storage settings form definition
|
|
385
|
+
* S3 Storage settings form definition
|
|
399
386
|
* @param {object} req request
|
|
400
387
|
* @returns {Promise<Form>} form
|
|
401
388
|
*/
|
|
402
389
|
const storage_form = async (req) => {
|
|
403
|
-
|
|
390
|
+
return await config_fields_form({
|
|
404
391
|
req,
|
|
405
392
|
field_names: [
|
|
406
393
|
"storage_s3_enabled",
|
|
@@ -414,11 +401,10 @@ const storage_form = async (req) => {
|
|
|
414
401
|
],
|
|
415
402
|
action: "/files/storage",
|
|
416
403
|
});
|
|
417
|
-
return form;
|
|
418
404
|
};
|
|
419
405
|
|
|
420
406
|
/**
|
|
421
|
-
*
|
|
407
|
+
* Show S3 Settings
|
|
422
408
|
* @function
|
|
423
409
|
* @memberof module:routes/admin~routes/adminRouter
|
|
424
410
|
*/
|
|
@@ -441,7 +427,7 @@ router.get(
|
|
|
441
427
|
);
|
|
442
428
|
|
|
443
429
|
/**
|
|
444
|
-
*
|
|
430
|
+
* Update S3 Settings
|
|
445
431
|
* @function
|
|
446
432
|
* @memberof module:routes/admin~routes/adminRouter
|
|
447
433
|
*/
|
|
@@ -472,3 +458,78 @@ router.post(
|
|
|
472
458
|
}
|
|
473
459
|
})
|
|
474
460
|
);
|
|
461
|
+
|
|
462
|
+
/**
|
|
463
|
+
* Files settings form definition
|
|
464
|
+
* @param {object} req request
|
|
465
|
+
* @returns {Promise<Form>} form
|
|
466
|
+
*/
|
|
467
|
+
const files_settings_form = async (req) => {
|
|
468
|
+
return await config_fields_form({
|
|
469
|
+
req,
|
|
470
|
+
field_names: [
|
|
471
|
+
"min_role_upload",
|
|
472
|
+
"file_accept_filter_default",
|
|
473
|
+
"file_upload_debug",
|
|
474
|
+
"file_upload_limit",
|
|
475
|
+
"file_upload_timeout",
|
|
476
|
+
],
|
|
477
|
+
action: "/files/settings",
|
|
478
|
+
});
|
|
479
|
+
};
|
|
480
|
+
|
|
481
|
+
/**
|
|
482
|
+
* Show Files Settings
|
|
483
|
+
* @function
|
|
484
|
+
* @memberof module:routes/admin~routes/adminRouter
|
|
485
|
+
*/
|
|
486
|
+
router.get(
|
|
487
|
+
"/settings",
|
|
488
|
+
isAdmin,
|
|
489
|
+
error_catcher(async (req, res) => {
|
|
490
|
+
const form = await files_settings_form(req);
|
|
491
|
+
send_files_page({
|
|
492
|
+
res,
|
|
493
|
+
req,
|
|
494
|
+
active_sub: "Settings",
|
|
495
|
+
contents: {
|
|
496
|
+
type: "card",
|
|
497
|
+
title: req.__("Files settings"),
|
|
498
|
+
contents: [renderForm(form, req.csrfToken())],
|
|
499
|
+
},
|
|
500
|
+
});
|
|
501
|
+
})
|
|
502
|
+
);
|
|
503
|
+
|
|
504
|
+
/**
|
|
505
|
+
* Update Files Settings
|
|
506
|
+
* @function
|
|
507
|
+
* @memberof module:routes/admin~routes/adminRouter
|
|
508
|
+
*/
|
|
509
|
+
router.post(
|
|
510
|
+
"/settings",
|
|
511
|
+
isAdmin,
|
|
512
|
+
error_catcher(async (req, res) => {
|
|
513
|
+
const form = await files_settings_form(req);
|
|
514
|
+
form.validate(req.body);
|
|
515
|
+
if (form.hasErrors) {
|
|
516
|
+
send_admin_page({
|
|
517
|
+
res,
|
|
518
|
+
req,
|
|
519
|
+
active_sub: "Settings",
|
|
520
|
+
contents: {
|
|
521
|
+
type: "card",
|
|
522
|
+
title: req.__("Files settings"),
|
|
523
|
+
contents: [renderForm(form, req.csrfToken())],
|
|
524
|
+
},
|
|
525
|
+
});
|
|
526
|
+
} else {
|
|
527
|
+
await save_config_from_form(form);
|
|
528
|
+
|
|
529
|
+
if (!req.xhr) {
|
|
530
|
+
req.flash("success", req.__("Files settings updated"));
|
|
531
|
+
res.redirect("/files/settings");
|
|
532
|
+
} else res.json({ success: "ok" });
|
|
533
|
+
}
|
|
534
|
+
})
|
|
535
|
+
);
|