underpost 2.8.87 → 2.8.88

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.
Files changed (99) hide show
  1. package/.env.development +35 -3
  2. package/.env.production +39 -4
  3. package/.env.test +35 -3
  4. package/.github/workflows/ghpkg.ci.yml +1 -1
  5. package/.github/workflows/npmpkg.ci.yml +1 -1
  6. package/.github/workflows/pwa-microservices-template-page.cd.yml +6 -5
  7. package/.github/workflows/pwa-microservices-template-test.ci.yml +1 -1
  8. package/.github/workflows/release.cd.yml +3 -3
  9. package/README.md +56 -2
  10. package/bin/build.js +4 -0
  11. package/bin/deploy.js +62 -8
  12. package/bin/file.js +3 -2
  13. package/cli.md +8 -2
  14. package/conf.js +30 -4
  15. package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
  16. package/manifests/deployment/dd-test-development/deployment.yaml +174 -0
  17. package/manifests/deployment/dd-test-development/proxy.yaml +51 -0
  18. package/package.json +6 -5
  19. package/src/api/core/core.router.js +2 -1
  20. package/src/api/default/default.controller.js +6 -1
  21. package/src/api/default/default.router.js +6 -2
  22. package/src/api/default/default.service.js +10 -1
  23. package/src/api/document/document.controller.js +66 -0
  24. package/src/api/document/document.model.js +51 -0
  25. package/src/api/document/document.router.js +24 -0
  26. package/src/api/document/document.service.js +125 -0
  27. package/src/api/file/file.controller.js +15 -1
  28. package/src/api/file/file.router.js +2 -1
  29. package/src/api/test/test.router.js +1 -1
  30. package/src/api/user/postman_collection.json +216 -0
  31. package/src/api/user/user.controller.js +25 -60
  32. package/src/api/user/user.model.js +29 -7
  33. package/src/api/user/user.router.js +9 -3
  34. package/src/api/user/user.service.js +84 -32
  35. package/src/cli/baremetal.js +33 -3
  36. package/src/cli/cloud-init.js +11 -0
  37. package/src/cli/cron.js +0 -1
  38. package/src/cli/deploy.js +46 -23
  39. package/src/cli/index.js +5 -0
  40. package/src/cli/lxd.js +7 -0
  41. package/src/cli/repository.js +42 -6
  42. package/src/cli/run.js +45 -13
  43. package/src/cli/ssh.js +20 -6
  44. package/src/client/Default.index.js +42 -1
  45. package/src/client/components/core/Account.js +10 -2
  46. package/src/client/components/core/AgGrid.js +30 -8
  47. package/src/client/components/core/Auth.js +99 -56
  48. package/src/client/components/core/BtnIcon.js +3 -2
  49. package/src/client/components/core/CalendarCore.js +2 -3
  50. package/src/client/components/core/CommonJs.js +1 -2
  51. package/src/client/components/core/Content.js +15 -12
  52. package/src/client/components/core/Css.js +2 -1
  53. package/src/client/components/core/CssCore.js +6 -1
  54. package/src/client/components/core/Docs.js +5 -5
  55. package/src/client/components/core/FileExplorer.js +3 -3
  56. package/src/client/components/core/Input.js +22 -17
  57. package/src/client/components/core/JoyStick.js +2 -2
  58. package/src/client/components/core/LoadingAnimation.js +2 -2
  59. package/src/client/components/core/LogIn.js +16 -23
  60. package/src/client/components/core/LogOut.js +5 -1
  61. package/src/client/components/core/Logger.js +4 -1
  62. package/src/client/components/core/Modal.js +82 -53
  63. package/src/client/components/core/ObjectLayerEngineModal.js +2 -1
  64. package/src/client/components/core/Pagination.js +207 -0
  65. package/src/client/components/core/Panel.js +10 -10
  66. package/src/client/components/core/PanelForm.js +130 -33
  67. package/src/client/components/core/Recover.js +2 -2
  68. package/src/client/components/core/Router.js +210 -34
  69. package/src/client/components/core/SignUp.js +1 -2
  70. package/src/client/components/core/Stream.js +1 -1
  71. package/src/client/components/core/VanillaJs.js +3 -84
  72. package/src/client/components/core/Worker.js +2 -2
  73. package/src/client/components/default/LogInDefault.js +0 -6
  74. package/src/client/components/default/LogOutDefault.js +0 -16
  75. package/src/client/components/default/MenuDefault.js +97 -44
  76. package/src/client/components/default/RoutesDefault.js +5 -2
  77. package/src/client/services/core/core.service.js +8 -20
  78. package/src/client/services/default/default.management.js +115 -18
  79. package/src/client/services/default/default.service.js +13 -4
  80. package/src/client/services/document/document.service.js +97 -0
  81. package/src/client/services/file/file.service.js +2 -0
  82. package/src/client/services/test/test.service.js +3 -0
  83. package/src/client/services/user/user.management.js +6 -0
  84. package/src/client/services/user/user.service.js +15 -4
  85. package/src/client/ssr/Render.js +1 -1
  86. package/src/client/ssr/head/DefaultScripts.js +3 -0
  87. package/src/client/ssr/head/Seo.js +1 -0
  88. package/src/index.js +24 -2
  89. package/src/runtime/lampp/Lampp.js +89 -2
  90. package/src/runtime/xampp/Xampp.js +48 -1
  91. package/src/server/auth.js +519 -155
  92. package/src/server/backup.js +2 -2
  93. package/src/server/conf.js +66 -8
  94. package/src/server/process.js +2 -1
  95. package/src/server/runtime.js +135 -286
  96. package/src/server/ssl.js +1 -2
  97. package/src/server/ssr.js +85 -0
  98. package/src/server/start.js +2 -2
  99. package/src/server/valkey.js +2 -1
@@ -0,0 +1,174 @@
1
+ ---
2
+ apiVersion: apps/v1
3
+ kind: Deployment
4
+ metadata:
5
+ name: dd-test-development-blue
6
+ labels:
7
+ app: dd-test-development-blue
8
+ spec:
9
+ replicas: 1
10
+ selector:
11
+ matchLabels:
12
+ app: dd-test-development-blue
13
+ template:
14
+ metadata:
15
+ labels:
16
+ app: dd-test-development-blue
17
+ spec:
18
+ containers:
19
+ - name: dd-test-development-blue
20
+ image: localhost/rockylinux9-underpost:v2.8.88
21
+ # resources:
22
+ # requests:
23
+ # memory: "94Ki"
24
+ # cpu: "75m"
25
+ # limits:
26
+ # memory: "1504Ki"
27
+ # cpu: "1200m"
28
+ command:
29
+ - /bin/sh
30
+ - -c
31
+ - >
32
+ npm install -g npm@11.2.0 &&
33
+ npm install -g underpost &&
34
+ underpost secret underpost --create-from-file /etc/config/.env.development &&
35
+ underpost start --build --run dd-test development
36
+ volumeMounts:
37
+ - name: config-volume
38
+ mountPath: /etc/config
39
+ volumes:
40
+ - name: config-volume
41
+ configMap:
42
+ name: underpost-config
43
+ ---
44
+ apiVersion: v1
45
+ kind: Service
46
+ metadata:
47
+ name: dd-test-development-blue-service
48
+ spec:
49
+ selector:
50
+ app: dd-test-development-blue
51
+ ports:
52
+ - name: 'tcp-4021'
53
+ protocol: TCP
54
+ port: 4021
55
+ targetPort: 4021
56
+ - name: 'udp-4021'
57
+ protocol: UDP
58
+ port: 4021
59
+ targetPort: 4021
60
+
61
+ - name: 'tcp-4022'
62
+ protocol: TCP
63
+ port: 4022
64
+ targetPort: 4022
65
+ - name: 'udp-4022'
66
+ protocol: UDP
67
+ port: 4022
68
+ targetPort: 4022
69
+
70
+ - name: 'tcp-4023'
71
+ protocol: TCP
72
+ port: 4023
73
+ targetPort: 4023
74
+ - name: 'udp-4023'
75
+ protocol: UDP
76
+ port: 4023
77
+ targetPort: 4023
78
+
79
+ - name: 'tcp-4024'
80
+ protocol: TCP
81
+ port: 4024
82
+ targetPort: 4024
83
+ - name: 'udp-4024'
84
+ protocol: UDP
85
+ port: 4024
86
+ targetPort: 4024
87
+ type: LoadBalancer
88
+ ---
89
+ apiVersion: apps/v1
90
+ kind: Deployment
91
+ metadata:
92
+ name: dd-test-development-green
93
+ labels:
94
+ app: dd-test-development-green
95
+ spec:
96
+ replicas: 1
97
+ selector:
98
+ matchLabels:
99
+ app: dd-test-development-green
100
+ template:
101
+ metadata:
102
+ labels:
103
+ app: dd-test-development-green
104
+ spec:
105
+ containers:
106
+ - name: dd-test-development-green
107
+ image: localhost/rockylinux9-underpost:v2.8.88
108
+ # resources:
109
+ # requests:
110
+ # memory: "94Ki"
111
+ # cpu: "75m"
112
+ # limits:
113
+ # memory: "1504Ki"
114
+ # cpu: "1200m"
115
+ command:
116
+ - /bin/sh
117
+ - -c
118
+ - >
119
+ npm install -g npm@11.2.0 &&
120
+ npm install -g underpost &&
121
+ underpost secret underpost --create-from-file /etc/config/.env.development &&
122
+ underpost start --build --run dd-test development
123
+ volumeMounts:
124
+ - name: config-volume
125
+ mountPath: /etc/config
126
+ volumes:
127
+ - name: config-volume
128
+ configMap:
129
+ name: underpost-config
130
+ ---
131
+ apiVersion: v1
132
+ kind: Service
133
+ metadata:
134
+ name: dd-test-development-green-service
135
+ spec:
136
+ selector:
137
+ app: dd-test-development-green
138
+ ports:
139
+ - name: 'tcp-4021'
140
+ protocol: TCP
141
+ port: 4021
142
+ targetPort: 4021
143
+ - name: 'udp-4021'
144
+ protocol: UDP
145
+ port: 4021
146
+ targetPort: 4021
147
+
148
+ - name: 'tcp-4022'
149
+ protocol: TCP
150
+ port: 4022
151
+ targetPort: 4022
152
+ - name: 'udp-4022'
153
+ protocol: UDP
154
+ port: 4022
155
+ targetPort: 4022
156
+
157
+ - name: 'tcp-4023'
158
+ protocol: TCP
159
+ port: 4023
160
+ targetPort: 4023
161
+ - name: 'udp-4023'
162
+ protocol: UDP
163
+ port: 4023
164
+ targetPort: 4023
165
+
166
+ - name: 'tcp-4024'
167
+ protocol: TCP
168
+ port: 4024
169
+ targetPort: 4024
170
+ - name: 'udp-4024'
171
+ protocol: UDP
172
+ port: 4024
173
+ targetPort: 4024
174
+ type: LoadBalancer
@@ -0,0 +1,51 @@
1
+
2
+ ---
3
+ apiVersion: projectcontour.io/v1
4
+ kind: HTTPProxy
5
+ metadata:
6
+ name: test.nexodev.org
7
+ spec:
8
+ virtualhost:
9
+ fqdn: test.nexodev.org
10
+ routes:
11
+ - conditions:
12
+ - prefix: /
13
+ enableWebsockets: true
14
+ services:
15
+ - name: dd-test-development-blue-service
16
+ port: 4021
17
+ weight: 100
18
+
19
+ - conditions:
20
+ - prefix: /peer
21
+ enableWebsockets: true
22
+ services:
23
+ - name: dd-test-development-blue-service
24
+ port: 4022
25
+ weight: 100
26
+
27
+ ---
28
+ apiVersion: projectcontour.io/v1
29
+ kind: HTTPProxy
30
+ metadata:
31
+ name: stagging.nexodev.org
32
+ spec:
33
+ virtualhost:
34
+ fqdn: stagging.nexodev.org
35
+ routes:
36
+ - conditions:
37
+ - prefix: /
38
+ enableWebsockets: true
39
+ services:
40
+ - name: dd-test-development-blue-service
41
+ port: 4023
42
+ weight: 100
43
+
44
+ - conditions:
45
+ - prefix: /peer
46
+ enableWebsockets: true
47
+ services:
48
+ - name: dd-test-development-blue-service
49
+ port: 4024
50
+ weight: 100
51
+
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "type": "module",
3
3
  "main": "src/index.js",
4
4
  "name": "underpost",
5
- "version": "2.8.87",
5
+ "version": "2.8.88",
6
6
  "description": "pwa api rest template",
7
7
  "scripts": {
8
8
  "start": "env-cmd -f .env.production node --max-old-space-size=8192 src/server",
@@ -51,10 +51,9 @@
51
51
  "dependencies": {
52
52
  "@fortawesome/fontawesome-free": "^6.4.2",
53
53
  "@fullcalendar/rrule": "^6.1.15",
54
- "@loadingio/css-spinner": "^2.0.2",
55
54
  "@neodrag/vanilla": "^2.0.3",
56
55
  "adm-zip": "^0.5.10",
57
- "ag-grid-community": "31.0.0",
56
+ "ag-grid-community": "^31.3.4",
58
57
  "axios": "^1.5.1",
59
58
  "chai": "^5.1.0",
60
59
  "clean-jsdoc-theme": "^4.3.0",
@@ -63,6 +62,7 @@
63
62
  "colors": "^1.4.0",
64
63
  "commander": "^12.1.0",
65
64
  "compression": "^1.7.4",
65
+ "cookie-parser": "^1.4.7",
66
66
  "cors": "^2.8.5",
67
67
  "d3": "^7.9.0",
68
68
  "dotenv": "^16.3.1",
@@ -70,9 +70,12 @@
70
70
  "env-cmd": "^10.1.0",
71
71
  "express": "^4.18.2",
72
72
  "express-fileupload": "^1.4.3",
73
+ "express-rate-limit": "^8.1.0",
74
+ "express-slow-down": "^3.0.0",
73
75
  "favicons": "^7.2.0",
74
76
  "fs-extra": "^11.1.1",
75
77
  "fullcalendar": "^6.1.15",
78
+ "helmet": "^8.1.0",
76
79
  "html-minifier-terser": "^7.2.0",
77
80
  "http-proxy-middleware": "^2.0.6",
78
81
  "ignore-walk": "^6.0.4",
@@ -80,7 +83,6 @@
80
83
  "jimp": "^0.22.12",
81
84
  "json-colorizer": "^2.2.2",
82
85
  "jsonwebtoken": "^9.0.2",
83
- "keyword-extractor": "^0.0.28",
84
86
  "mariadb": "^3.2.2",
85
87
  "marked": "^12.0.2",
86
88
  "mocha": "^10.8.2",
@@ -88,7 +90,6 @@
88
90
  "morgan": "^1.10.0",
89
91
  "nodemailer": "^6.9.9",
90
92
  "nodemon": "^3.0.1",
91
- "pathfinding": "^0.4.18",
92
93
  "peer": "^1.0.2",
93
94
  "peerjs": "^1.5.2",
94
95
  "prom-client": "^15.1.2",
@@ -1,4 +1,4 @@
1
- import { adminGuard, authMiddleware } from '../../server/auth.js';
1
+ import { adminGuard } from '../../server/auth.js';
2
2
  import { loggerFactory } from '../../server/logger.js';
3
3
  import { CoreController } from './core.controller.js';
4
4
  import express from 'express';
@@ -7,6 +7,7 @@ const logger = loggerFactory(import.meta);
7
7
 
8
8
  const CoreRouter = (options) => {
9
9
  const router = express.Router();
10
+ const authMiddleware = options.authMiddleware;
10
11
  router.post(`/:id`, authMiddleware, adminGuard, async (req, res) => await CoreController.post(req, res, options));
11
12
  router.post(`/`, authMiddleware, adminGuard, async (req, res) => await CoreController.post(req, res, options));
12
13
  router.get(`/:id`, authMiddleware, adminGuard, async (req, res) => await CoreController.get(req, res, options));
@@ -21,7 +21,12 @@ const DefaultController = {
21
21
  },
22
22
  get: async (req, res, options) => {
23
23
  try {
24
- const result = await DefaultService.get(req, res, options);
24
+ const { page, limit } = req.query;
25
+ const result = await DefaultService.get(
26
+ { ...req, query: { ...req.query, page: parseInt(page), limit: parseInt(limit) } },
27
+ res,
28
+ options,
29
+ );
25
30
  return res.status(200).json({
26
31
  status: 'success',
27
32
  data: result,
@@ -1,4 +1,3 @@
1
- import { authMiddleware } from '../../server/auth.js';
2
1
  import { loggerFactory } from '../../server/logger.js';
3
2
  import { DefaultController } from './default.controller.js';
4
3
  import express from 'express';
@@ -7,9 +6,14 @@ const logger = loggerFactory(import.meta);
7
6
 
8
7
  const DefaultRouter = (options) => {
9
8
  const router = express.Router();
9
+ const authMiddleware = options.authMiddleware;
10
10
  router.post(`/:id`, async (req, res) => await DefaultController.post(req, res, options));
11
11
  router.post(`/`, async (req, res) => await DefaultController.post(req, res, options));
12
- router.get(`/:id`, async (req, res) => await DefaultController.get(req, res, options));
12
+ router.get(
13
+ `/:id`,
14
+ // authMiddleware,
15
+ async (req, res) => await DefaultController.get(req, res, options),
16
+ );
13
17
  router.get(`/`, async (req, res) => await DefaultController.get(req, res, options));
14
18
  router.put(`/:id`, async (req, res) => await DefaultController.put(req, res, options));
15
19
  router.put(`/`, async (req, res) => await DefaultController.put(req, res, options));
@@ -13,7 +13,16 @@ const DefaultService = {
13
13
  /** @type {import('./default.model.js').DefaultModel} */
14
14
  const Default = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.Default;
15
15
  if (req.params.id) return await Default.findById(req.params.id);
16
- return await Default.find();
16
+ const { query, page = 1, limit = 10, sort = { updatedAt: -1 } } = req.query;
17
+ const queryPayload = query ? JSON.parse(query) : {};
18
+ const skip = (page - 1) * limit;
19
+ const [data, total] = await Promise.all([
20
+ Default.find(queryPayload).sort(sort).limit(limit).skip(skip),
21
+ Default.countDocuments(queryPayload),
22
+ ]);
23
+
24
+ const totalPages = Math.ceil(total / limit);
25
+ return { data, total, page, totalPages };
17
26
  },
18
27
  put: async (req, res, options) => {
19
28
  /** @type {import('./default.model.js').DefaultModel} */
@@ -0,0 +1,66 @@
1
+ import { loggerFactory } from '../../server/logger.js';
2
+ import { DocumentService } from './document.service.js';
3
+ const logger = loggerFactory(import.meta);
4
+
5
+ const DocumentController = {
6
+ post: async (req, res, options) => {
7
+ try {
8
+ return res.status(200).json({
9
+ status: 'success',
10
+ data: await DocumentService.post(req, res, options),
11
+ });
12
+ } catch (error) {
13
+ logger.error(error, error.stack);
14
+ return res.status(400).json({
15
+ status: 'error',
16
+ message: error.message,
17
+ });
18
+ }
19
+ },
20
+ get: async (req, res, options) => {
21
+ try {
22
+ return res.status(200).json({
23
+ status: 'success',
24
+ data: await DocumentService.get(req, res, options),
25
+ });
26
+ } catch (error) {
27
+ logger.error(error, error.stack);
28
+ return res.status(400).json({
29
+ status: 'error',
30
+ message: error.message,
31
+ });
32
+ }
33
+ },
34
+ delete: async (req, res, options) => {
35
+ try {
36
+ const result = await DocumentService.delete(req, res, options);
37
+ return res.status(200).json({
38
+ status: 'success',
39
+ data: result,
40
+ });
41
+ } catch (error) {
42
+ logger.error(error, error.stack);
43
+ return res.status(400).json({
44
+ status: 'error',
45
+ message: error.message,
46
+ });
47
+ }
48
+ },
49
+ put: async (req, res, options) => {
50
+ try {
51
+ const result = await DocumentService.put(req, res, options);
52
+ return res.status(200).json({
53
+ status: 'success',
54
+ data: result,
55
+ });
56
+ } catch (error) {
57
+ logger.error(error, error.stack);
58
+ return res.status(400).json({
59
+ status: 'error',
60
+ message: error.message,
61
+ });
62
+ }
63
+ },
64
+ };
65
+
66
+ export { DocumentController };
@@ -0,0 +1,51 @@
1
+ import { Schema, model, Types } from 'mongoose';
2
+
3
+ // https://mongoosejs.com/docs/2.7.x/docs/schematypes.html
4
+
5
+ const DocumentSchema = new Schema(
6
+ {
7
+ userId: {
8
+ type: Schema.Types.ObjectId,
9
+ ref: 'User',
10
+ },
11
+ location: { type: String },
12
+ title: { type: String },
13
+ tags: [{ type: String }],
14
+ fileId: {
15
+ type: Schema.Types.ObjectId,
16
+ ref: 'File',
17
+ },
18
+ mdFileId: {
19
+ type: Schema.Types.ObjectId,
20
+ ref: 'File',
21
+ },
22
+ },
23
+ {
24
+ timestamps: true,
25
+ },
26
+ );
27
+
28
+ const DocumentModel = model('Document', DocumentSchema);
29
+
30
+ const ProviderSchema = DocumentSchema;
31
+
32
+ const DocumentDto = {
33
+ populate: {
34
+ file: () => {
35
+ return {
36
+ path: 'fileId',
37
+ model: 'File',
38
+ select: '_id name mimetype',
39
+ };
40
+ },
41
+ user: () => {
42
+ return {
43
+ path: 'userId',
44
+ model: 'User',
45
+ select: '_id email username',
46
+ };
47
+ },
48
+ },
49
+ };
50
+
51
+ export { DocumentSchema, DocumentModel, ProviderSchema, DocumentDto };
@@ -0,0 +1,24 @@
1
+ import { loggerFactory } from '../../server/logger.js';
2
+ import { DocumentController } from './document.controller.js';
3
+ import express from 'express';
4
+ import fs from 'fs-extra';
5
+ const logger = loggerFactory(import.meta);
6
+
7
+ const DocumentRouter = (options) => {
8
+ const router = express.Router();
9
+ const authMiddleware = options.authMiddleware;
10
+ router.post(`/:id`, authMiddleware, async (req, res) => await DocumentController.post(req, res, options));
11
+ router.post(`/`, authMiddleware, async (req, res) => await DocumentController.post(req, res, options));
12
+ router.get(`/public`, async (req, res) => await DocumentController.get(req, res, options));
13
+ router.get(`/:id`, authMiddleware, async (req, res) => await DocumentController.get(req, res, options));
14
+ router.get(`/`, authMiddleware, async (req, res) => await DocumentController.get(req, res, options));
15
+ router.put(`/:id`, authMiddleware, async (req, res) => await DocumentController.put(req, res, options));
16
+ router.put(`/`, authMiddleware, async (req, res) => await DocumentController.put(req, res, options));
17
+ router.delete(`/:id`, authMiddleware, async (req, res) => await DocumentController.delete(req, res, options));
18
+ router.delete(`/`, authMiddleware, async (req, res) => await DocumentController.delete(req, res, options));
19
+ return router;
20
+ };
21
+
22
+ const ApiRouter = DocumentRouter;
23
+
24
+ export { ApiRouter, DocumentRouter };
@@ -0,0 +1,125 @@
1
+ import { loggerFactory } from '../../server/logger.js';
2
+ import { DataBaseProvider } from '../../db/DataBaseProvider.js';
3
+ import { DocumentDto } from './document.model.js';
4
+ import { uniqueArray } from '../../client/components/core/CommonJs.js';
5
+ import { getBearerToken, verifyJWT } from '../../server/auth.js';
6
+ import { isValidObjectId } from 'mongoose';
7
+
8
+ const logger = loggerFactory(import.meta);
9
+
10
+ const DocumentService = {
11
+ post: async (req, res, options) => {
12
+ /** @type {import('./document.model.js').DocumentModel} */
13
+ const Document = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.Document;
14
+
15
+ switch (req.params.id) {
16
+ default:
17
+ req.body.userId = req.auth.user._id;
18
+ return await new Document(req.body).save();
19
+ }
20
+ },
21
+ get: async (req, res, options) => {
22
+ /** @type {import('./document.model.js').DocumentModel} */
23
+ const Document = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.Document;
24
+ /** @type {import('../user/user.model.js').UserModel} */
25
+ const User = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.User;
26
+
27
+ if (req.path.startsWith('/public') && req.query['tags']) {
28
+ const publisherUsers = await User.find({ $or: [{ role: 'admin' }, { role: 'moderator' }] });
29
+
30
+ const token = getBearerToken(req);
31
+ let user;
32
+ if (token) user = verifyJWT(token, options);
33
+
34
+ const queryPayload = {
35
+ userId: {
36
+ $in: publisherUsers.map((p) => p._id).concat(user?.role && user.role !== 'guest' ? [user._id] : []),
37
+ },
38
+ tags: {
39
+ // $in: uniqueArray(['public'].concat(req.query['tags'].split(','))),
40
+ $all: uniqueArray(['public'].concat(req.query['tags'].split(','))),
41
+ },
42
+ ...(req.query.cid
43
+ ? {
44
+ _id: {
45
+ $in: req.query.cid.split(',').filter((cid) => isValidObjectId(cid)),
46
+ },
47
+ }
48
+ : undefined),
49
+ };
50
+ logger.info('queryPayload', queryPayload);
51
+ // sort in descending (-1) order by length
52
+ const sort = { createdAt: -1 };
53
+ const limit = req.query.limit ? parseInt(req.query.limit, 10) : 6;
54
+ const skip = req.query.skip ? parseInt(req.query.skip, 10) : 0;
55
+
56
+ return await Document.find(queryPayload)
57
+ .sort(sort)
58
+ .limit(limit)
59
+ .skip(skip)
60
+ .populate(DocumentDto.populate.file())
61
+ .populate(user && user.role !== 'guest' ? DocumentDto.populate.user() : null);
62
+ }
63
+
64
+ switch (req.params.id) {
65
+ default:
66
+ return await Document.find({
67
+ userId: req.auth.user._id,
68
+ ...(req.params.id ? { _id: req.params.id } : undefined),
69
+ }).populate(DocumentDto.populate.file());
70
+ }
71
+ },
72
+ delete: async (req, res, options) => {
73
+ /** @type {import('./document.model.js').DocumentModel} */
74
+ const Document = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.Document;
75
+ /** @type {import('../file/file.model.js').FileModel} */
76
+ const File = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.File;
77
+
78
+ switch (req.params.id) {
79
+ default: {
80
+ const document = await Document.findOne({ _id: req.params.id });
81
+ if (!document) throw new Error('document not found');
82
+
83
+ if (document.userId.toString() !== req.auth.user._id) throw new Error('invalid user');
84
+
85
+ if (document.mdFileId) {
86
+ const file = await File.findOne({ _id: document.mdFileId });
87
+ if (file) await File.findByIdAndDelete(document.mdFileId);
88
+ }
89
+
90
+ if (document.fileId) {
91
+ const file = await File.findOne({ _id: document.fileId });
92
+ if (file) await File.findByIdAndDelete(document.fileId);
93
+ }
94
+
95
+ return await Document.findByIdAndDelete(req.params.id);
96
+ }
97
+ }
98
+ },
99
+ put: async (req, res, options) => {
100
+ /** @type {import('./document.model.js').DocumentModel} */
101
+ const Document = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.Document;
102
+ /** @type {import('../file/file.model.js').FileModel} */
103
+ const File = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.File;
104
+
105
+ switch (req.params.id) {
106
+ default: {
107
+ const document = await Document.findOne({ _id: req.params.id });
108
+ if (!document) throw new Error(`Document not found`);
109
+
110
+ if (document.mdFileId) {
111
+ const file = await File.findOne({ _id: document.mdFileId });
112
+ if (file) await File.findByIdAndDelete(document.mdFileId);
113
+ }
114
+
115
+ if (document.fileId) {
116
+ const file = await File.findOne({ _id: document.fileId });
117
+ if (file) await File.findByIdAndDelete(document.fileId);
118
+ }
119
+ return await Document.findByIdAndUpdate(req.params.id, req.body);
120
+ }
121
+ }
122
+ },
123
+ };
124
+
125
+ export { DocumentService };
@@ -20,7 +20,21 @@ const FileController = {
20
20
  get: async (req, res, options) => {
21
21
  try {
22
22
  const result = await FileService.get(req, res, options);
23
- if (result instanceof Buffer) return res.status(200).end(result);
23
+ if (result instanceof Buffer) {
24
+ if (
25
+ process.env.NODE_ENV === 'development' ||
26
+ req.hostname === options.host ||
27
+ (options.origins && options.origins.find((o) => o.match(req.hostname)))
28
+ ) {
29
+ res.set('Cross-Origin-Resource-Policy', 'cross-origin');
30
+ return res.status(200).end(result);
31
+ }
32
+ return res.status(403).json({
33
+ status: 'error',
34
+ message: 'Forbidden',
35
+ });
36
+ }
37
+
24
38
  return res.status(200).json({
25
39
  status: 'success',
26
40
  data: result,
@@ -1,4 +1,4 @@
1
- import { adminGuard, authMiddleware } from '../../server/auth.js';
1
+ import { adminGuard } from '../../server/auth.js';
2
2
  import { loggerFactory } from '../../server/logger.js';
3
3
  import { FileController } from './file.controller.js';
4
4
  import express from 'express';
@@ -6,6 +6,7 @@ const logger = loggerFactory(import.meta);
6
6
 
7
7
  const FileRouter = (options) => {
8
8
  const router = express.Router();
9
+ const authMiddleware = options.authMiddleware;
9
10
  router.post(`/:id`, authMiddleware, async (req, res) => await FileController.post(req, res, options));
10
11
  router.post(`/`, authMiddleware, async (req, res) => await FileController.post(req, res, options));
11
12
  router.get(`/blob/:id`, async (req, res) => await FileController.get(req, res, options));
@@ -1,4 +1,3 @@
1
- import { authMiddleware } from '../../server/auth.js';
2
1
  import { loggerFactory } from '../../server/logger.js';
3
2
  import { TestController } from './test.controller.js';
4
3
  import express from 'express';
@@ -7,6 +6,7 @@ const logger = loggerFactory(import.meta);
7
6
 
8
7
  const TestRouter = (options) => {
9
8
  const router = express.Router();
9
+ const authMiddleware = options.authMiddleware;
10
10
  router.post(`/:id`, async (req, res) => await TestController.post(req, res, options));
11
11
  router.post(`/`, authMiddleware, async (req, res) => await TestController.post(req, res, options));
12
12
  router.get(`/:id`, async (req, res) => await TestController.get(req, res, options));