@saltcorn/server 1.0.0-rc.6 → 1.0.0-rc.7
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/locales/en.json +2 -1
- package/package.json +9 -9
- package/routes/api.js +34 -0
- package/tests/api.test.js +29 -0
package/locales/en.json
CHANGED
|
@@ -1476,5 +1476,6 @@
|
|
|
1476
1476
|
"clean node_modules": "clean node_modules",
|
|
1477
1477
|
"After delete": "After delete",
|
|
1478
1478
|
"Search only on exact match, not substring match. Useful for large tables": "Search only on exact match, not substring match. Useful for large tables",
|
|
1479
|
-
"Please select an entry point.": "Please select an entry point."
|
|
1479
|
+
"Please select an entry point.": "Please select an entry point.",
|
|
1480
|
+
"Group by": "Group by"
|
|
1480
1481
|
}
|
package/package.json
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@saltcorn/server",
|
|
3
|
-
"version": "1.0.0-rc.
|
|
3
|
+
"version": "1.0.0-rc.7",
|
|
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": "1.0.0-rc.
|
|
11
|
-
"@saltcorn/builder": "1.0.0-rc.
|
|
12
|
-
"@saltcorn/data": "1.0.0-rc.
|
|
13
|
-
"@saltcorn/admin-models": "1.0.0-rc.
|
|
14
|
-
"@saltcorn/filemanager": "1.0.0-rc.
|
|
15
|
-
"@saltcorn/markup": "1.0.0-rc.
|
|
16
|
-
"@saltcorn/plugins-loader": "1.0.0-rc.
|
|
17
|
-
"@saltcorn/sbadmin2": "1.0.0-rc.
|
|
10
|
+
"@saltcorn/base-plugin": "1.0.0-rc.7",
|
|
11
|
+
"@saltcorn/builder": "1.0.0-rc.7",
|
|
12
|
+
"@saltcorn/data": "1.0.0-rc.7",
|
|
13
|
+
"@saltcorn/admin-models": "1.0.0-rc.7",
|
|
14
|
+
"@saltcorn/filemanager": "1.0.0-rc.7",
|
|
15
|
+
"@saltcorn/markup": "1.0.0-rc.7",
|
|
16
|
+
"@saltcorn/plugins-loader": "1.0.0-rc.7",
|
|
17
|
+
"@saltcorn/sbadmin2": "1.0.0-rc.7",
|
|
18
18
|
"@socket.io/cluster-adapter": "^0.2.1",
|
|
19
19
|
"@socket.io/sticky": "^1.0.1",
|
|
20
20
|
"adm-zip": "0.5.10",
|
package/routes/api.js
CHANGED
|
@@ -27,6 +27,7 @@ const Table = require("@saltcorn/data/models/table");
|
|
|
27
27
|
const View = require("@saltcorn/data/models/view");
|
|
28
28
|
//const Field = require("@saltcorn/data/models/field");
|
|
29
29
|
const Trigger = require("@saltcorn/data/models/trigger");
|
|
30
|
+
const File = require("@saltcorn/data/models/file");
|
|
30
31
|
//const load_plugins = require("../load_plugins");
|
|
31
32
|
const passport = require("passport");
|
|
32
33
|
|
|
@@ -189,6 +190,39 @@ router.post(
|
|
|
189
190
|
)(req, res, next);
|
|
190
191
|
})
|
|
191
192
|
);
|
|
193
|
+
|
|
194
|
+
router.get(
|
|
195
|
+
"/serve-files/*",
|
|
196
|
+
//passport.authenticate("api-bearer", { session: false }),
|
|
197
|
+
error_catcher(async (req, res, next) => {
|
|
198
|
+
await passport.authenticate(
|
|
199
|
+
"api-bearer",
|
|
200
|
+
{ session: false },
|
|
201
|
+
async function (err, user, info) {
|
|
202
|
+
const role = req?.user?.role_id || user?.role_id || 100;
|
|
203
|
+
const user_id = req?.user?.id || user?.id;
|
|
204
|
+
const serve_path = req.params[0];
|
|
205
|
+
const file = await File.findOne(serve_path);
|
|
206
|
+
if (
|
|
207
|
+
file &&
|
|
208
|
+
(role <= file.min_role_read || (user_id && user_id === file.user_id))
|
|
209
|
+
) {
|
|
210
|
+
res.type(file.mimetype);
|
|
211
|
+
const cacheability =
|
|
212
|
+
file.min_role_read === 100 ? "public" : "private";
|
|
213
|
+
const maxAge = getState().getConfig("files_cache_maxage", 86400);
|
|
214
|
+
res.set("Cache-Control", `${cacheability}, max-age=${maxAge}`);
|
|
215
|
+
if (file.s3_store)
|
|
216
|
+
res.status(404).json({ error: req.__("Not found") });
|
|
217
|
+
else res.sendFile(file.location);
|
|
218
|
+
} else {
|
|
219
|
+
res.status(404).json({ error: req.__("Not found") });
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
)(req, res, next);
|
|
223
|
+
})
|
|
224
|
+
);
|
|
225
|
+
|
|
192
226
|
/**
|
|
193
227
|
*
|
|
194
228
|
*/
|
package/tests/api.test.js
CHANGED
|
@@ -2,6 +2,8 @@ const request = require("supertest");
|
|
|
2
2
|
const getApp = require("../app");
|
|
3
3
|
const Table = require("@saltcorn/data/models/table");
|
|
4
4
|
const Trigger = require("@saltcorn/data/models/trigger");
|
|
5
|
+
const File = require("@saltcorn/data/models/file");
|
|
6
|
+
const fs = require("fs").promises;
|
|
5
7
|
|
|
6
8
|
const Field = require("@saltcorn/data/models/field");
|
|
7
9
|
const {
|
|
@@ -19,6 +21,19 @@ const User = require("@saltcorn/data/models/user");
|
|
|
19
21
|
|
|
20
22
|
beforeAll(async () => {
|
|
21
23
|
await resetToFixtures();
|
|
24
|
+
await File.ensure_file_store();
|
|
25
|
+
await File.from_req_files(
|
|
26
|
+
{
|
|
27
|
+
mimetype: "image/png",
|
|
28
|
+
name: "rick1.png",
|
|
29
|
+
mv: async (fnm) => {
|
|
30
|
+
await fs.writeFile(fnm, "nevergonnagiveyouup");
|
|
31
|
+
},
|
|
32
|
+
size: 245752,
|
|
33
|
+
},
|
|
34
|
+
1,
|
|
35
|
+
80
|
|
36
|
+
);
|
|
22
37
|
});
|
|
23
38
|
afterAll(db.close);
|
|
24
39
|
|
|
@@ -352,6 +367,20 @@ describe("API authentication", () => {
|
|
|
352
367
|
|
|
353
368
|
.expect(succeedJsonWith((rows) => rows.length == 2));
|
|
354
369
|
});
|
|
370
|
+
it("should not show file to public", async () => {
|
|
371
|
+
const app = await getApp();
|
|
372
|
+
await request(app)
|
|
373
|
+
.get("/api/serve-files/rick1.png")
|
|
374
|
+
.expect(respondJsonWith(404, (b) => b.error === "Not found"));
|
|
375
|
+
});
|
|
376
|
+
it("should show file to user", async () => {
|
|
377
|
+
const app = await getApp();
|
|
378
|
+
const u = await User.findOne({ id: 1 });
|
|
379
|
+
await request(app)
|
|
380
|
+
.get("/api/serve-files/rick1.png")
|
|
381
|
+
.set("Authorization", "Bearer " + u.api_token)
|
|
382
|
+
.expect(200);
|
|
383
|
+
});
|
|
355
384
|
});
|
|
356
385
|
|
|
357
386
|
describe("API action", () => {
|