@galadrim/galadmin 0.2.8 → 0.2.9
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/README.md +0 -3
- package/dist/api.js +20 -3
- package/dist/api.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/examples/rich-text-upload/server.cjs +42 -0
- package/package.json +1 -1
- package/src/api.ts +25 -8
- package/src/front/build/asset-manifest.json +3 -3
- package/src/front/build/index.html +1 -1
- package/src/front/build/static/js/{main.70ad8e58.js → main.64348568.js} +3 -3
- package/src/front/build/static/js/{main.70ad8e58.js.map → main.64348568.js.map} +1 -1
- package/src/front/src/components/inputs/BetterRichTextInput.js +4 -4
- package/src/front/src/components/inputs/BetterRichTextInput.test.js +32 -0
- package/tests/integration/routes.authorization.integration.test.ts +2 -3
- package/tests/integration/routes.upload.integration.test.ts +114 -25
- /package/src/front/build/static/js/{main.70ad8e58.js.LICENSE.txt → main.64348568.js.LICENSE.txt} +0 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// Run from the repository after building both the backend and frontend.
|
|
2
|
+
const express = require('express');
|
|
3
|
+
const galadmin = require('../../dist').default;
|
|
4
|
+
|
|
5
|
+
const app = express();
|
|
6
|
+
const port = Number(process.env.PORT || 3001);
|
|
7
|
+
const cdnBase = process.env.UPLOAD_CDN_BASE;
|
|
8
|
+
if (!cdnBase) throw new Error('Set UPLOAD_CDN_BASE to the public base URL for your test bucket.');
|
|
9
|
+
const pathTransform = (key) => `${cdnBase.replace(/\/$/, '')}/${key}`;
|
|
10
|
+
const fileUploadProperties = process.env.GCP_BUCKET
|
|
11
|
+
? { gcpConfig: {
|
|
12
|
+
host: 'storage.googleapis.com', bucket: process.env.GCP_BUCKET,
|
|
13
|
+
subfolder: 'galadmin-issue-46', pathTransform,
|
|
14
|
+
} }
|
|
15
|
+
: { s3Config: {
|
|
16
|
+
host: process.env.S3_HOST, bucket: process.env.S3_BUCKET,
|
|
17
|
+
accessKeyId: process.env.S3_ACCESS_KEY_ID,
|
|
18
|
+
secretAccessKey: process.env.S3_SECRET_ACCESS_KEY,
|
|
19
|
+
region: process.env.S3_REGION || 'eu-west-3',
|
|
20
|
+
subfolder: 'galadmin-issue-46', pathTransform,
|
|
21
|
+
} };
|
|
22
|
+
if (!process.env.GCP_BUCKET && ['S3_HOST', 'S3_BUCKET', 'S3_ACCESS_KEY_ID', 'S3_SECRET_ACCESS_KEY'].some((key) => !process.env[key])) {
|
|
23
|
+
throw new Error('Set GCP_BUCKET or all of S3_HOST, S3_BUCKET, S3_ACCESS_KEY_ID, S3_SECRET_ACCESS_KEY.');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
app.use('/admin', galadmin({
|
|
27
|
+
name: 'Rich-text upload test',
|
|
28
|
+
sessionSecret: 'local-issue-46-only',
|
|
29
|
+
auth: { username: 'admin', password: 'admin' },
|
|
30
|
+
postgresql: {
|
|
31
|
+
host: '127.0.0.1', port: Number(process.env.PGPORT || 5546),
|
|
32
|
+
user: 'galadmin', password: 'galadmin', database: 'galadmin_local',
|
|
33
|
+
},
|
|
34
|
+
views: [{
|
|
35
|
+
type: 'table', label: 'Articles', tableName: 'articles', canCreate: true,
|
|
36
|
+
columns: [
|
|
37
|
+
{ label: 'Title', name: 'title' },
|
|
38
|
+
{ label: 'Body', dataType: 'betterRichText', htmlField: 'body', fileUploadProperties },
|
|
39
|
+
],
|
|
40
|
+
}],
|
|
41
|
+
}));
|
|
42
|
+
app.listen(port, '127.0.0.1', () => console.log(`Open http://localhost:${port}/admin/ (admin / admin)`));
|
package/package.json
CHANGED
package/src/api.ts
CHANGED
|
@@ -1511,17 +1511,34 @@ export default (db, config) => {
|
|
|
1511
1511
|
app.post(
|
|
1512
1512
|
"/uploadFileFromBetterRichTextInput",
|
|
1513
1513
|
async function (req, res, next) {
|
|
1514
|
-
//
|
|
1515
|
-
//
|
|
1516
|
-
// to write at least one view (read-only roles are rejected outright).
|
|
1514
|
+
// Resolve settings on the server so function-valued pathTransform survives.
|
|
1515
|
+
// Validate the target before parsing multipart data or contacting storage.
|
|
1517
1516
|
const role = roleOf(req);
|
|
1518
|
-
|
|
1517
|
+
const { viewIndex, columnId } = req.query;
|
|
1518
|
+
if (
|
|
1519
|
+
typeof viewIndex !== "string" ||
|
|
1520
|
+
!/^\d+$/.test(viewIndex) ||
|
|
1521
|
+
typeof columnId !== "string"
|
|
1522
|
+
) {
|
|
1519
1523
|
return res.sendStatus(403);
|
|
1520
1524
|
}
|
|
1521
|
-
const
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
+
const view = req.config.views[viewIndex];
|
|
1526
|
+
if (!view || !canWriteView(view, role)) {
|
|
1527
|
+
return res.sendStatus(403);
|
|
1528
|
+
}
|
|
1529
|
+
const column = [
|
|
1530
|
+
...(view.columns || []),
|
|
1531
|
+
...(view.recordViewPanels?.flatMap(
|
|
1532
|
+
(panel) => panel.createConfig?.columns || [],
|
|
1533
|
+
) || []),
|
|
1534
|
+
].find((column) => column.__id__ === columnId);
|
|
1535
|
+
if (!column || (column.roles && !column.roles.includes(role))) {
|
|
1536
|
+
return res.sendStatus(403);
|
|
1537
|
+
}
|
|
1538
|
+
if (column.dataType !== "betterRichText" || !column.fileUploadProperties) {
|
|
1539
|
+
return res.status(400).send({ error: "Invalid rich-text upload column" });
|
|
1540
|
+
}
|
|
1541
|
+
uploadFile(column.fileUploadProperties, "upload", req, res);
|
|
1525
1542
|
},
|
|
1526
1543
|
);
|
|
1527
1544
|
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"files": {
|
|
3
3
|
"main.css": "/_HOMEPAGE_/static/css/main.eacc50f1.css",
|
|
4
|
-
"main.js": "/_HOMEPAGE_/static/js/main.
|
|
4
|
+
"main.js": "/_HOMEPAGE_/static/js/main.64348568.js",
|
|
5
5
|
"static/media/gt-eesti-medium.woff": "/_HOMEPAGE_/static/media/gt-eesti-medium.a48c02fa57e83ab6ddcd.woff",
|
|
6
6
|
"static/media/gt-eesti-regular.woff": "/_HOMEPAGE_/static/media/gt-eesti-regular.304a7ae06ee4a4d5d04a.woff",
|
|
7
7
|
"static/media/logo.png": "/_HOMEPAGE_/static/media/logo.e407b9ca7e302466a07d.png",
|
|
8
8
|
"static/media/cubano.woff": "/_HOMEPAGE_/static/media/cubano.4eaa47ef94222121a371.woff",
|
|
9
9
|
"index.html": "/_HOMEPAGE_/index.html",
|
|
10
10
|
"main.eacc50f1.css.map": "/_HOMEPAGE_/static/css/main.eacc50f1.css.map",
|
|
11
|
-
"main.
|
|
11
|
+
"main.64348568.js.map": "/_HOMEPAGE_/static/js/main.64348568.js.map"
|
|
12
12
|
},
|
|
13
13
|
"entrypoints": [
|
|
14
14
|
"static/css/main.eacc50f1.css",
|
|
15
|
-
"static/js/main.
|
|
15
|
+
"static/js/main.64348568.js"
|
|
16
16
|
]
|
|
17
17
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<!doctype html><html lang="fr"><head><script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script><script src="https://momentjs.com/downloads/moment-timezone-with-data-10-year-range.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/locale/fr.js"></script><script async="async" defer="defer" src="https://cdnjs.cloudflare.com/ajax/libs/spectrum/1.8.0/spectrum.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/air-datepicker/2.2.3/js/datepicker.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/air-datepicker/2.2.3/js/i18n/datepicker.fr.min.js"></script><script async="async" defer="defer" src="https://cdnjs.cloudflare.com/ajax/libs/downloadjs/1.4.8/download.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.4.0/Chart.min.js"></script><script async="async" defer="defer" src="https://cdn.jsdelivr.net/npm/sweetalert"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/quill/1.3.6/quill.min.js"></script><script src="https://sdk.amazonaws.com/js/aws-sdk-2.606.0.min.js"></script><script src="https://kit.fontawesome.com/75b28933ed.js" crossorigin="anonymous" async="async" defer="defer"></script><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/air-datepicker/2.2.3/css/datepicker.min.css"/><link rel="stylesheet" href="/_HOMEPAGE_/spectrum.css"/><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/quill/1.3.6/quill.snow.min.css"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta charset="utf-8"/><link rel="icon" href="/_HOMEPAGE_/favicon.png"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><link rel="manifest" href="/_HOMEPAGE_/manifest.json"/><title>Back-office</title><script defer="defer" src="/_HOMEPAGE_/static/js/main.
|
|
1
|
+
<!doctype html><html lang="fr"><head><script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script><script src="https://momentjs.com/downloads/moment-timezone-with-data-10-year-range.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/locale/fr.js"></script><script async="async" defer="defer" src="https://cdnjs.cloudflare.com/ajax/libs/spectrum/1.8.0/spectrum.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/air-datepicker/2.2.3/js/datepicker.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/air-datepicker/2.2.3/js/i18n/datepicker.fr.min.js"></script><script async="async" defer="defer" src="https://cdnjs.cloudflare.com/ajax/libs/downloadjs/1.4.8/download.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.4.0/Chart.min.js"></script><script async="async" defer="defer" src="https://cdn.jsdelivr.net/npm/sweetalert"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/quill/1.3.6/quill.min.js"></script><script src="https://sdk.amazonaws.com/js/aws-sdk-2.606.0.min.js"></script><script src="https://kit.fontawesome.com/75b28933ed.js" crossorigin="anonymous" async="async" defer="defer"></script><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/air-datepicker/2.2.3/css/datepicker.min.css"/><link rel="stylesheet" href="/_HOMEPAGE_/spectrum.css"/><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/quill/1.3.6/quill.snow.min.css"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta charset="utf-8"/><link rel="icon" href="/_HOMEPAGE_/favicon.png"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><link rel="manifest" href="/_HOMEPAGE_/manifest.json"/><title>Back-office</title><script defer="defer" src="/_HOMEPAGE_/static/js/main.64348568.js"></script><link href="/_HOMEPAGE_/static/css/main.eacc50f1.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
|