@raclettejs/core 0.1.18 → 0.1.20
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/CHANGELOG.md +23 -0
- package/bin/cli.js +1 -1
- package/dev/README.md +4 -0
- package/dist/cli.js +135 -124
- package/dist/cli.js.map +4 -4
- package/dist/index.js +9 -8
- package/dist/index.js.map +4 -4
- package/package.json +9 -5
- package/services/backend/delay-api-debugger.sh +0 -0
- package/services/backend/package.json +1 -0
- package/services/backend/src/app.ts +4 -0
- package/services/backend/src/core/config/configService.ts +10 -1
- package/services/backend/src/core/events/eventEmitter.ts +32 -7
- package/services/backend/src/core/http/request-params.plugin.ts +2 -2
- package/services/backend/src/core/pluginSystem/pluginFastifyInstance.ts +4 -1
- package/services/backend/src/core/pluginSystem/pluginTypes.ts +3 -1
- package/services/backend/src/core/sockets/createSystemEventHandlers.ts +7 -0
- package/services/backend/src/core/sockets/index.ts +61 -13
- package/services/backend/src/core/sockets/socketManager.ts +452 -105
- package/services/backend/src/core/sockets/socketTypes.ts +13 -1
- package/services/backend/src/core/sockets/workSessionJoinPayload.ts +106 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/account/routes/route.account.get.ts +3 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/account/routes/route.account.getAll.ts +3 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/account/routes/route.account.hardDelete.ts +16 -19
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/account/routes/route.account.patch.ts +3 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/account/routes/route.account.post.ts +3 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/account/routes/route.account.remove.ts +3 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/composition/composition.service.ts +86 -3
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/composition/routes/index.ts +2 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/composition/routes/route.composition.get.ts +3 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/composition/routes/route.composition.getAll.ts +3 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/composition/routes/route.composition.hardDelete.ts +16 -19
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/composition/routes/route.composition.patch.ts +3 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/composition/routes/route.composition.post.bulk.ts +60 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/composition/routes/route.composition.post.ts +3 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/composition/routes/route.composition.remove.ts +3 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/composition/routes/route.composition.restore.ts +12 -15
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/interactionLink/interactionLink.service.ts +96 -12
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/interactionLink/routes/index.ts +2 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/interactionLink/routes/route.interactionLink.get.ts +3 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/interactionLink/routes/route.interactionLink.getAll.ts +4 -2
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/interactionLink/routes/route.interactionLink.hardDelete.ts +12 -17
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/interactionLink/routes/route.interactionLink.patch.ts +3 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/interactionLink/routes/route.interactionLink.post.bulk.ts +62 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/interactionLink/routes/route.interactionLink.post.ts +3 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/interactionLink/routes/route.interactionLink.remove.ts +3 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/interactionLink/routes/route.interactionLink.restore.ts +12 -15
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/project/project.service.ts +1 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/project/routes/route.project.get.ts +3 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/project/routes/route.project.getAll.ts +4 -2
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/project/routes/route.project.hardDelete.ts +3 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/project/routes/route.project.patch.ts +3 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/project/routes/route.project.post.ts +4 -2
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/project/routes/route.project.remove.ts +3 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/tag/routes/index.ts +2 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/tag/routes/route.tag.get.ts +1 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/tag/routes/route.tag.getAll.ts +1 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/tag/routes/route.tag.hardDelete.ts +10 -15
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/tag/routes/route.tag.patch.ts +3 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/tag/routes/route.tag.post.bulk.ts +60 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/tag/routes/route.tag.post.ts +3 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/tag/routes/route.tag.remove.ts +3 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/tag/routes/route.tag.restore.ts +12 -15
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/tag/tag.service.ts +73 -3
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/user/routes/route.user.get.ts +1 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/user/routes/route.user.getAll.ts +1 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/user/routes/route.user.hardDelete.ts +10 -15
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/user/routes/route.user.patch.ts +4 -6
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/user/routes/route.user.patchLastProject.ts +4 -2
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/user/routes/route.user.post.ts +3 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/user/routes/route.user.remove.ts +3 -4
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/user/routes/route.user.restore.ts +12 -15
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/workSession/events/index.ts +45 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/workSession/helpers/crud.ts +12 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/workSession/helpers/payload.ts +21 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/workSession/index.ts +55 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/workSession/routes/index.ts +19 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/workSession/routes/route.workSession.get.ts +53 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/workSession/routes/route.workSession.getAll.ts +39 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/workSession/routes/route.workSession.hardDelete.ts +53 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/workSession/routes/route.workSession.patch.ts +58 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/workSession/routes/route.workSession.post.ts +53 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/workSession/routes/route.workSession.remove.ts +52 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/workSession/workSession.model.ts +65 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/workSession/workSession.schema.ts +125 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/workSession/workSession.service.ts +351 -0
- package/services/backend/src/corePlugins/raclette__core/backend/index.ts +2 -0
- package/services/backend/src/corePlugins/raclette__core/frontend/generated-config.ts +159 -24
- package/services/backend/src/modules/authentication/index.ts +255 -4
- package/services/backend/src/modules/hooks/rate-limiter.ts +21 -0
- package/services/backend/src/types/custom-fastify.d.ts +17 -0
- package/services/backend/src/utils/request.utils.ts +4 -1
- package/services/backend/types/index.d.ts +15 -1
- package/services/backend/yarn.lock +13 -4
- package/services/frontend/index.html +1 -1
- package/services/frontend/provision/entrypoint.sh +0 -0
- package/services/frontend/src/core/lib/configService.ts +1 -1
- package/services/frontend/src/core/lib/data/dataApi.ts +10 -1
- package/services/frontend/src/core/lib/dataHelper.ts +1 -1
- package/services/frontend/src/core/lib/eggs/snow.ts +66 -48
- package/services/frontend/src/core/lib/helpers/index.ts +1 -0
- package/services/frontend/src/core/lib/helpers/removeEmpty.ts +69 -0
- package/services/frontend/src/core/lib/httpClient.ts +19 -0
- package/services/frontend/src/core/main.ts +20 -10
- package/services/frontend/src/core/setup/socket.ts +4 -3
- package/services/frontend/src/core/setup/socketClient.ts +31 -3
- package/services/frontend/src/core/setup/socketEvents.ts +92 -8
- package/services/frontend/src/core/store/index.ts +5 -1
- package/services/frontend/src/core/store/reducers/compositions/index.ts +2 -2
- package/services/frontend/src/core/store/reducers/interactionLinks/index.ts +1 -1
- package/services/frontend/src/core/store/reducers/widgets/reducers.ts +1 -2
- package/services/frontend/src/core/store/types/index.ts +0 -1
- package/services/frontend/src/core/types/PluginRegistrar.ts +8 -6
- package/services/frontend/src/core/types/Store.ts +1 -0
- package/services/frontend/src/orchestrator/components/composition/WidgetsLayoutLoader.vue +68 -8
- package/services/frontend/src/orchestrator/components/menu/UserMenu.vue +17 -5
- package/services/frontend/src/orchestrator/components/welcomeScreen/AdminWelcomeScreen.vue +1 -1
- package/services/frontend/src/orchestrator/composables/index.ts +1 -0
- package/services/frontend/src/orchestrator/composables/usePluginApi.ts +0 -3
- package/services/frontend/src/orchestrator/composables/useRouteState.ts +23 -4
- package/services/frontend/src/orchestrator/composables/useWidgetLifecycle.ts +166 -0
- package/services/frontend/src/orchestrator/helpers/index.ts +1 -0
- package/services/frontend/src/orchestrator/i18n/de-DE.json +15 -1
- package/services/frontend/src/orchestrator/i18n/en-EU.json +15 -1
- package/services/frontend/src/orchestrator/i18n/sk.json +15 -1
- package/services/frontend/src/orchestrator/index.ts +34 -4
- package/services/frontend/src/orchestrator/router/routeParserHelper.ts +106 -1
- package/services/frontend/src/orchestrator/types/Widgets.ts +2 -0
- package/services/frontend/types.ts +1 -0
- package/src/README.md +404 -0
- package/src/types.ts +19 -5
- package/templates/README.md +0 -0
- package/types/index.ts +18 -4
- package/services/backend/.gitignore +0 -17
- package/services/frontend/.gitignore +0 -35
- package/yarn.lock +0 -2937
|
@@ -97,11 +97,10 @@ export class InteractionLinkService {
|
|
|
97
97
|
*/
|
|
98
98
|
async _readAllInteractionLinks(
|
|
99
99
|
fastify: PluginFastifyInstance,
|
|
100
|
-
filters: Record<string, any> = {},
|
|
100
|
+
filters: Record<string, any> = { isDeleted: false },
|
|
101
101
|
): Promise<InteractionLinkType[]> {
|
|
102
102
|
try {
|
|
103
|
-
|
|
104
|
-
filters.isDeleted = false
|
|
103
|
+
filters = { isDeleted: false, ...filters }
|
|
105
104
|
return await this.interactionLinkModel
|
|
106
105
|
.find({
|
|
107
106
|
...filters,
|
|
@@ -130,16 +129,16 @@ export class InteractionLinkService {
|
|
|
130
129
|
}
|
|
131
130
|
|
|
132
131
|
/**
|
|
133
|
-
* Core function to get interaction links by
|
|
132
|
+
* Core function to get interaction links by interactionLink ID (returns raw data)
|
|
134
133
|
*/
|
|
135
|
-
async
|
|
134
|
+
async _readInteractionLinksByInteractionLink(
|
|
136
135
|
fastify: PluginFastifyInstance,
|
|
137
|
-
|
|
136
|
+
interactionLinkId: string,
|
|
138
137
|
): Promise<InteractionLinkType[]> {
|
|
139
138
|
try {
|
|
140
139
|
return await this.interactionLinkModel
|
|
141
140
|
.find({
|
|
142
|
-
|
|
141
|
+
interactionLink: interactionLinkId,
|
|
143
142
|
isDeleted: false,
|
|
144
143
|
})
|
|
145
144
|
.lean()
|
|
@@ -150,16 +149,16 @@ export class InteractionLinkService {
|
|
|
150
149
|
}
|
|
151
150
|
|
|
152
151
|
/**
|
|
153
|
-
* Get interaction links by
|
|
152
|
+
* Get interaction links by interactionLink ID with payload wrapping
|
|
154
153
|
*/
|
|
155
|
-
async
|
|
154
|
+
async readInteractionLinksByInteractionLink(
|
|
156
155
|
fastify: PluginFastifyInstance,
|
|
157
156
|
requestData: FrontendPayloadRequestData,
|
|
158
|
-
|
|
157
|
+
interactionLinkId: string,
|
|
159
158
|
): Promise<FrontendPayload<InteractionLinkType[]>> {
|
|
160
|
-
const interactionLinks = await this.
|
|
159
|
+
const interactionLinks = await this._readInteractionLinksByInteractionLink(
|
|
161
160
|
fastify,
|
|
162
|
-
|
|
161
|
+
interactionLinkId,
|
|
163
162
|
)
|
|
164
163
|
|
|
165
164
|
return createInteractionLinkPayload(fastify, interactionLinks, requestData)
|
|
@@ -439,6 +438,91 @@ export class InteractionLinkService {
|
|
|
439
438
|
|
|
440
439
|
return createInteractionLinkPayload(fastify, interactionLinks, requestData)
|
|
441
440
|
}
|
|
441
|
+
/**
|
|
442
|
+
* Core function to create multiple interactionLinks (returns raw data)
|
|
443
|
+
*/
|
|
444
|
+
async _createInteractionLinks(
|
|
445
|
+
fastify: PluginFastifyInstance,
|
|
446
|
+
interactionLinkBodies: InteractionLinkBody[],
|
|
447
|
+
userId: string,
|
|
448
|
+
): Promise<InteractionLinkType[]> {
|
|
449
|
+
try {
|
|
450
|
+
const interactionLinksToCreate: InteractionLinkBody[] = []
|
|
451
|
+
|
|
452
|
+
// Validate and prepare all interactionLinks
|
|
453
|
+
for (const interactionLinkBody of interactionLinkBodies) {
|
|
454
|
+
if (interactionLinkBody._id) {
|
|
455
|
+
const uuidValid = validate(interactionLinkBody._id)
|
|
456
|
+
|
|
457
|
+
if (!uuidValid) {
|
|
458
|
+
throw new Error(
|
|
459
|
+
`Invalid ID - not a valid uuid v4: ${interactionLinkBody._id}`,
|
|
460
|
+
)
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
const duplicate = await this.interactionLinkModel.findOne({
|
|
464
|
+
_id: interactionLinkBody._id,
|
|
465
|
+
})
|
|
466
|
+
|
|
467
|
+
if (duplicate) {
|
|
468
|
+
throw new Error(
|
|
469
|
+
`An entry with this id already exists: ${interactionLinkBody._id}`,
|
|
470
|
+
)
|
|
471
|
+
}
|
|
472
|
+
} else {
|
|
473
|
+
interactionLinkBody._id = uuidv4()
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
interactionLinksToCreate.push({
|
|
477
|
+
...interactionLinkBody,
|
|
478
|
+
author: userId,
|
|
479
|
+
lastEditor: userId,
|
|
480
|
+
})
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
// Bulk insert
|
|
484
|
+
const interactionLinks = await this.interactionLinkModel.insertMany(
|
|
485
|
+
interactionLinksToCreate,
|
|
486
|
+
)
|
|
487
|
+
|
|
488
|
+
fastify.log.info(
|
|
489
|
+
`[API] Created ${interactionLinks.length} interactionLinks in bulk`,
|
|
490
|
+
)
|
|
491
|
+
|
|
492
|
+
return interactionLinks.map((comp) =>
|
|
493
|
+
comp.toObject ? comp.toObject() : comp,
|
|
494
|
+
)
|
|
495
|
+
} catch (error: any) {
|
|
496
|
+
fastify.log.error(error.message)
|
|
497
|
+
throw error
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
/**
|
|
502
|
+
* Create multiple interactionLinks with payload wrapping and event emission
|
|
503
|
+
*/
|
|
504
|
+
async createInteractionLinks(
|
|
505
|
+
fastify: PluginFastifyInstance,
|
|
506
|
+
requestData: FrontendPayloadRequestData,
|
|
507
|
+
interactionLinkBodies: InteractionLinkBody[],
|
|
508
|
+
userId: string,
|
|
509
|
+
): Promise<FrontendPayload<InteractionLinkType[]>> {
|
|
510
|
+
const interactionLinks = await this._createInteractionLinks(
|
|
511
|
+
fastify,
|
|
512
|
+
interactionLinkBodies,
|
|
513
|
+
userId,
|
|
514
|
+
)
|
|
515
|
+
|
|
516
|
+
const payload = await createInteractionLinkPayload(
|
|
517
|
+
fastify,
|
|
518
|
+
interactionLinks,
|
|
519
|
+
requestData,
|
|
520
|
+
)
|
|
521
|
+
|
|
522
|
+
fastify.emit("interactionLinksCreated", payload)
|
|
523
|
+
|
|
524
|
+
return payload
|
|
525
|
+
}
|
|
442
526
|
}
|
|
443
527
|
|
|
444
528
|
export const createInteractionLinkService = (
|
|
@@ -4,6 +4,7 @@ import getAll from "./route.interactionLink.getAll"
|
|
|
4
4
|
import hardDelete from "./route.interactionLink.hardDelete"
|
|
5
5
|
import patch from "./route.interactionLink.patch"
|
|
6
6
|
import post from "./route.interactionLink.post"
|
|
7
|
+
import postBulk from "./route.interactionLink.post.bulk"
|
|
7
8
|
import remove from "./route.interactionLink.remove"
|
|
8
9
|
import restore from "./route.interactionLink.restore"
|
|
9
10
|
|
|
@@ -13,6 +14,7 @@ const registerRoutes = async (fastify: PluginFastifyInstance) => {
|
|
|
13
14
|
await fastify.patch("/interactionLink/:_id", patch(fastify))
|
|
14
15
|
await fastify.patch("/interactionLink/:_id/restore", restore(fastify))
|
|
15
16
|
await fastify.post("/interactionLink", post(fastify))
|
|
17
|
+
await fastify.post("/interactionLink/bulk", postBulk(fastify))
|
|
16
18
|
await fastify.delete("/interactionLink/:_id", remove(fastify))
|
|
17
19
|
await fastify.delete("/interactionLink/:_id/hard", hardDelete(fastify))
|
|
18
20
|
}
|
|
@@ -3,6 +3,8 @@ import type { FastifyReply, FastifyRequest } from "fastify"
|
|
|
3
3
|
import { PluginFastifyInstance } from "types"
|
|
4
4
|
import { Type } from "@sinclair/typebox"
|
|
5
5
|
|
|
6
|
+
const permissions = ["user.isAdmin"]
|
|
7
|
+
|
|
6
8
|
const ParamsSchema = Type.Object({
|
|
7
9
|
_id: Type.String(),
|
|
8
10
|
})
|
|
@@ -39,7 +41,7 @@ export default (fastify: PluginFastifyInstance) => {
|
|
|
39
41
|
|
|
40
42
|
return {
|
|
41
43
|
handler,
|
|
42
|
-
onRequest: [fastify.authenticate],
|
|
44
|
+
onRequest: [fastify.authenticate, fastify.checkPermissions(permissions)],
|
|
43
45
|
config: {
|
|
44
46
|
type: "dataRead",
|
|
45
47
|
},
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { FastifyReply, FastifyRequest } from "fastify"
|
|
2
|
-
import { PluginFastifyInstance } from "types"
|
|
2
|
+
import type { PluginFastifyInstance } from "types"
|
|
3
|
+
|
|
4
|
+
const permissions = ["user.isAdmin"]
|
|
3
5
|
|
|
4
6
|
export default (fastify: PluginFastifyInstance) => {
|
|
5
7
|
const interactionLinkService = fastify.custom.interactionLinkService
|
|
@@ -21,7 +23,7 @@ export default (fastify: PluginFastifyInstance) => {
|
|
|
21
23
|
|
|
22
24
|
return {
|
|
23
25
|
handler,
|
|
24
|
-
onRequest: [fastify.authenticate],
|
|
26
|
+
onRequest: [fastify.authenticate, fastify.checkPermissions(permissions)],
|
|
25
27
|
config: {
|
|
26
28
|
type: "dataRead",
|
|
27
29
|
},
|
|
@@ -2,7 +2,8 @@ import type { Static } from "@sinclair/typebox"
|
|
|
2
2
|
import type { FastifyReply, FastifyRequest } from "fastify"
|
|
3
3
|
import { PluginFastifyInstance } from "types"
|
|
4
4
|
import { Type } from "@sinclair/typebox"
|
|
5
|
-
|
|
5
|
+
|
|
6
|
+
const permissions = ["user.isAdmin"]
|
|
6
7
|
|
|
7
8
|
const ParamsSchema = Type.Object({
|
|
8
9
|
_id: Type.String(),
|
|
@@ -19,21 +20,15 @@ export default (fastify: PluginFastifyInstance) => {
|
|
|
19
20
|
reply: FastifyReply,
|
|
20
21
|
) => {
|
|
21
22
|
try {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
return payload
|
|
32
|
-
} else {
|
|
33
|
-
throw new ForbiddenError(
|
|
34
|
-
"Only admins can hard delete this core datatype",
|
|
35
|
-
)
|
|
36
|
-
}
|
|
23
|
+
const { _id } = req.params
|
|
24
|
+
|
|
25
|
+
const payload = await interactionLinkService.hardDeleteInteractionLink(
|
|
26
|
+
fastify,
|
|
27
|
+
req.requestParams,
|
|
28
|
+
_id,
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
return payload
|
|
37
32
|
} catch (error: any) {
|
|
38
33
|
fastify.log.error(error.message)
|
|
39
34
|
return reply.internalServerError(error.message)
|
|
@@ -42,7 +37,7 @@ export default (fastify: PluginFastifyInstance) => {
|
|
|
42
37
|
|
|
43
38
|
return {
|
|
44
39
|
handler,
|
|
45
|
-
onRequest: [fastify.authenticate],
|
|
40
|
+
onRequest: [fastify.authenticate, fastify.checkPermissions(permissions)],
|
|
46
41
|
config: {
|
|
47
42
|
type: "dataHardDelete",
|
|
48
43
|
broadcastChannels: ["interactionLinkHardDeleted"],
|
|
@@ -5,6 +5,8 @@ import { PluginFastifyInstance } from "types"
|
|
|
5
5
|
import { Type } from "@sinclair/typebox"
|
|
6
6
|
import { interactionLinkUpdateSchema } from "../interactionLink.schema"
|
|
7
7
|
|
|
8
|
+
const permissions = ["user.isAdmin"]
|
|
9
|
+
|
|
8
10
|
const ParamsSchema = Type.Object({
|
|
9
11
|
_id: Type.String(),
|
|
10
12
|
})
|
|
@@ -39,7 +41,7 @@ export default (fastify: PluginFastifyInstance) => {
|
|
|
39
41
|
|
|
40
42
|
return {
|
|
41
43
|
handler,
|
|
42
|
-
onRequest: [fastify.authenticate],
|
|
44
|
+
onRequest: [fastify.authenticate, fastify.checkPermissions(permissions)],
|
|
43
45
|
config: {
|
|
44
46
|
type: "dataUpdate",
|
|
45
47
|
broadcastChannels: ["interactionLinkUpdated"],
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { InteractionLinkBody } from "../interactionLink.service"
|
|
2
|
+
import type { FastifyReply, FastifyRequest } from "fastify"
|
|
3
|
+
import type { PluginFastifyInstance } from "types"
|
|
4
|
+
import { interactionLinkCreateSchema } from "../interactionLink.schema"
|
|
5
|
+
|
|
6
|
+
const permissions = ["user.isAdmin"]
|
|
7
|
+
|
|
8
|
+
export default (fastify: PluginFastifyInstance) => {
|
|
9
|
+
const interactionLinkService = fastify.custom.interactionLinkService
|
|
10
|
+
|
|
11
|
+
const handler = async (
|
|
12
|
+
req: FastifyRequest<{
|
|
13
|
+
Body: InteractionLinkBody[]
|
|
14
|
+
}>,
|
|
15
|
+
reply: FastifyReply,
|
|
16
|
+
) => {
|
|
17
|
+
try {
|
|
18
|
+
// Validate that body is an array
|
|
19
|
+
if (!Array.isArray(req.body)) {
|
|
20
|
+
return reply.badRequest(
|
|
21
|
+
"Request body must be an array of interactionLinks",
|
|
22
|
+
)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Validate that array is not empty
|
|
26
|
+
if (req.body.length === 0) {
|
|
27
|
+
return reply.badRequest("Request body cannot be an empty array")
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const payload = await interactionLinkService.createInteractionLinks(
|
|
31
|
+
fastify,
|
|
32
|
+
req.requestParams,
|
|
33
|
+
req.body,
|
|
34
|
+
req.user._id,
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
return payload
|
|
38
|
+
} catch (error: any) {
|
|
39
|
+
fastify.log.error(error.message)
|
|
40
|
+
|
|
41
|
+
return reply.internalServerError(error.message)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return {
|
|
46
|
+
handler,
|
|
47
|
+
onRequest: [fastify.authenticate, fastify.checkPermissions(permissions)],
|
|
48
|
+
config: {
|
|
49
|
+
type: "dataCreate",
|
|
50
|
+
broadcastChannels: ["interactionLinksCreated"],
|
|
51
|
+
},
|
|
52
|
+
schema: {
|
|
53
|
+
summary: "Create multiple interactionLinks in bulk",
|
|
54
|
+
tags: ["core/interactionLink"],
|
|
55
|
+
body: {
|
|
56
|
+
type: "array",
|
|
57
|
+
items: interactionLinkCreateSchema,
|
|
58
|
+
minItems: 1,
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -3,6 +3,8 @@ import type { FastifyReply, FastifyRequest } from "fastify"
|
|
|
3
3
|
import { PluginFastifyInstance } from "types"
|
|
4
4
|
import { interactionLinkCreateSchema } from "../interactionLink.schema"
|
|
5
5
|
|
|
6
|
+
const permissions = ["user.isAdmin"]
|
|
7
|
+
|
|
6
8
|
export default (fastify: PluginFastifyInstance) => {
|
|
7
9
|
const interactionLinkService = fastify.custom.interactionLinkService
|
|
8
10
|
|
|
@@ -30,7 +32,7 @@ export default (fastify: PluginFastifyInstance) => {
|
|
|
30
32
|
|
|
31
33
|
return {
|
|
32
34
|
handler,
|
|
33
|
-
onRequest: [fastify.authenticate],
|
|
35
|
+
onRequest: [fastify.authenticate, fastify.checkPermissions(permissions)],
|
|
34
36
|
config: {
|
|
35
37
|
type: "dataCreate",
|
|
36
38
|
broadcastChannels: ["interactionLinkCreated"],
|
|
@@ -3,6 +3,8 @@ import type { FastifyReply, FastifyRequest } from "fastify"
|
|
|
3
3
|
import { PluginFastifyInstance } from "types"
|
|
4
4
|
import { Type } from "@sinclair/typebox"
|
|
5
5
|
|
|
6
|
+
const permissions = ["user.isAdmin"]
|
|
7
|
+
|
|
6
8
|
const ParamsSchema = Type.Object({
|
|
7
9
|
_id: Type.String(),
|
|
8
10
|
})
|
|
@@ -35,7 +37,7 @@ export default (fastify: PluginFastifyInstance) => {
|
|
|
35
37
|
|
|
36
38
|
return {
|
|
37
39
|
handler,
|
|
38
|
-
onRequest: [fastify.authenticate],
|
|
40
|
+
onRequest: [fastify.authenticate, fastify.checkPermissions(permissions)],
|
|
39
41
|
config: {
|
|
40
42
|
type: "dataDelete",
|
|
41
43
|
broadcastChannels: ["interactionLinkDeleted"],
|
|
@@ -2,7 +2,8 @@ import type { Static } from "@sinclair/typebox"
|
|
|
2
2
|
import type { FastifyReply, FastifyRequest } from "fastify"
|
|
3
3
|
import { PluginFastifyInstance } from "types"
|
|
4
4
|
import { Type } from "@sinclair/typebox"
|
|
5
|
-
|
|
5
|
+
|
|
6
|
+
const permissions = ["user.isAdmin"]
|
|
6
7
|
|
|
7
8
|
const ParamsSchema = Type.Object({
|
|
8
9
|
_id: Type.String(),
|
|
@@ -17,21 +18,17 @@ export default (fastify: PluginFastifyInstance) => {
|
|
|
17
18
|
reply: FastifyReply,
|
|
18
19
|
) => {
|
|
19
20
|
try {
|
|
20
|
-
|
|
21
|
-
const { _id } = req.params
|
|
21
|
+
const { _id } = req.params
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
23
|
+
const payload = await interactionLinkService.updateInteractionLink(
|
|
24
|
+
fastify,
|
|
25
|
+
req.requestParams,
|
|
26
|
+
_id,
|
|
27
|
+
{ isDeleted: false },
|
|
28
|
+
req.user._id,
|
|
29
|
+
)
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
} else {
|
|
33
|
-
throw new ForbiddenError("Only admins can restore this core datatype")
|
|
34
|
-
}
|
|
31
|
+
return payload
|
|
35
32
|
} catch (error: any) {
|
|
36
33
|
fastify.log.error(error.message)
|
|
37
34
|
return reply.internalServerError(error.message)
|
|
@@ -40,7 +37,7 @@ export default (fastify: PluginFastifyInstance) => {
|
|
|
40
37
|
|
|
41
38
|
return {
|
|
42
39
|
handler,
|
|
43
|
-
onRequest: [fastify.authenticate],
|
|
40
|
+
onRequest: [fastify.authenticate, fastify.checkPermissions(permissions)],
|
|
44
41
|
config: {
|
|
45
42
|
type: "dataRestore",
|
|
46
43
|
broadcastChannels: ["interactionLinkRestored"],
|
|
@@ -3,6 +3,8 @@ import type { FastifyReply, FastifyRequest } from "fastify"
|
|
|
3
3
|
import { PluginFastifyInstance } from "types"
|
|
4
4
|
import { Type } from "@sinclair/typebox"
|
|
5
5
|
|
|
6
|
+
const permissions = ["user.isAdmin"]
|
|
7
|
+
|
|
6
8
|
const ParamsSchema = Type.Object({
|
|
7
9
|
_id: Type.String(),
|
|
8
10
|
})
|
|
@@ -39,7 +41,7 @@ export default (fastify: PluginFastifyInstance) => {
|
|
|
39
41
|
|
|
40
42
|
return {
|
|
41
43
|
handler,
|
|
42
|
-
onRequest: [fastify.authenticate],
|
|
44
|
+
onRequest: [fastify.authenticate, fastify.checkPermissions(permissions)],
|
|
43
45
|
config: {
|
|
44
46
|
type: "dataRead",
|
|
45
47
|
},
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { FastifyReply, FastifyRequest } from "fastify"
|
|
2
|
-
import { PluginFastifyInstance } from "types"
|
|
2
|
+
import type { PluginFastifyInstance } from "types"
|
|
3
|
+
|
|
4
|
+
const permissions = ["user.isAdmin"]
|
|
3
5
|
|
|
4
6
|
export default (fastify: PluginFastifyInstance) => {
|
|
5
7
|
const projectService = fastify.custom.projectService
|
|
@@ -24,7 +26,7 @@ export default (fastify: PluginFastifyInstance) => {
|
|
|
24
26
|
|
|
25
27
|
return {
|
|
26
28
|
handler,
|
|
27
|
-
onRequest: [fastify.authenticate],
|
|
29
|
+
onRequest: [fastify.authenticate, fastify.checkPermissions(permissions)],
|
|
28
30
|
config: {
|
|
29
31
|
type: "dataRead",
|
|
30
32
|
},
|
|
@@ -3,6 +3,8 @@ import type { FastifyReply, FastifyRequest } from "fastify"
|
|
|
3
3
|
import { PluginFastifyInstance } from "types"
|
|
4
4
|
import { Type } from "@sinclair/typebox"
|
|
5
5
|
|
|
6
|
+
const permissions = ["user.isAdmin"]
|
|
7
|
+
|
|
6
8
|
const ParamsSchema = Type.Object({
|
|
7
9
|
_id: Type.String(),
|
|
8
10
|
})
|
|
@@ -35,7 +37,7 @@ export default (fastify: PluginFastifyInstance) => {
|
|
|
35
37
|
|
|
36
38
|
return {
|
|
37
39
|
handler,
|
|
38
|
-
onRequest: [fastify.authenticate],
|
|
40
|
+
onRequest: [fastify.authenticate, fastify.checkPermissions(permissions)],
|
|
39
41
|
config: {
|
|
40
42
|
type: "dataHardDeleted",
|
|
41
43
|
broadcastChannels: ["projectHardDeleted"],
|
|
@@ -5,6 +5,8 @@ import { PluginFastifyInstance } from "types"
|
|
|
5
5
|
import { Type } from "@sinclair/typebox"
|
|
6
6
|
import { projectSchema } from "../project.schema"
|
|
7
7
|
|
|
8
|
+
const permissions = ["user.isAdmin"]
|
|
9
|
+
|
|
8
10
|
const ParamsSchema = Type.Object({
|
|
9
11
|
_id: Type.String(),
|
|
10
12
|
})
|
|
@@ -40,7 +42,7 @@ export default (fastify: PluginFastifyInstance) => {
|
|
|
40
42
|
|
|
41
43
|
return {
|
|
42
44
|
handler,
|
|
43
|
-
onRequest: [fastify.authenticate],
|
|
45
|
+
onRequest: [fastify.authenticate, fastify.checkPermissions(permissions)],
|
|
44
46
|
config: {
|
|
45
47
|
type: "dataUpdate",
|
|
46
48
|
broadcastChannels: ["projectUpdated"],
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type { FastifyReply, FastifyRequest } from "fastify"
|
|
2
|
-
import { PluginFastifyInstance } from "types"
|
|
2
|
+
import type { PluginFastifyInstance } from "types"
|
|
3
3
|
import { projectCreateSchema, type ProjectCreate } from "../project.schema"
|
|
4
4
|
|
|
5
|
+
const permissions = ["user.isAdmin"]
|
|
6
|
+
|
|
5
7
|
export default (fastify: PluginFastifyInstance) => {
|
|
6
8
|
const projectService = fastify.custom.projectService
|
|
7
9
|
|
|
@@ -27,7 +29,7 @@ export default (fastify: PluginFastifyInstance) => {
|
|
|
27
29
|
|
|
28
30
|
return {
|
|
29
31
|
handler,
|
|
30
|
-
|
|
32
|
+
onRequest: [fastify.authenticate, fastify.checkPermissions(permissions)],
|
|
31
33
|
config: {
|
|
32
34
|
type: "dataCreate",
|
|
33
35
|
broadcastChannels: ["projectCreated"],
|
|
@@ -3,6 +3,8 @@ import type { FastifyReply, FastifyRequest } from "fastify"
|
|
|
3
3
|
import { PluginFastifyInstance } from "types"
|
|
4
4
|
import { Type } from "@sinclair/typebox"
|
|
5
5
|
|
|
6
|
+
const permissions = ["user.isAdmin"]
|
|
7
|
+
|
|
6
8
|
const ParamsSchema = Type.Object({
|
|
7
9
|
_id: Type.String(),
|
|
8
10
|
})
|
|
@@ -35,7 +37,7 @@ export default (fastify: PluginFastifyInstance) => {
|
|
|
35
37
|
|
|
36
38
|
return {
|
|
37
39
|
handler,
|
|
38
|
-
onRequest: [fastify.authenticate],
|
|
40
|
+
onRequest: [fastify.authenticate, fastify.checkPermissions(permissions)],
|
|
39
41
|
config: {
|
|
40
42
|
type: "dataUpdate",
|
|
41
43
|
broadcastChannels: ["projectDeleted"],
|
package/services/backend/src/corePlugins/raclette__core/backend/datatypes/tag/routes/index.ts
CHANGED
|
@@ -4,6 +4,7 @@ import getAll from "./route.tag.getAll"
|
|
|
4
4
|
import hardDelete from "./route.tag.hardDelete"
|
|
5
5
|
import patch from "./route.tag.patch"
|
|
6
6
|
import post from "./route.tag.post"
|
|
7
|
+
import postBulk from "./route.tag.post.bulk"
|
|
7
8
|
import remove from "./route.tag.remove"
|
|
8
9
|
import restore from "./route.tag.restore"
|
|
9
10
|
|
|
@@ -13,6 +14,7 @@ const registerRoutes = async (fastify: PluginFastifyInstance) => {
|
|
|
13
14
|
await fastify.patch("/tag/:_id", patch(fastify))
|
|
14
15
|
await fastify.patch("/tag/:_id/restore", restore(fastify))
|
|
15
16
|
await fastify.post("/tag/:project/:_id", post(fastify))
|
|
17
|
+
await fastify.post("/tag/bulk", postBulk(fastify))
|
|
16
18
|
await fastify.delete("/tag/:_id", remove(fastify))
|
|
17
19
|
await fastify.delete("/tag/:_id/hard", hardDelete(fastify))
|
|
18
20
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { FastifyReply, FastifyRequest } from "fastify"
|
|
2
2
|
import { PluginFastifyInstance } from "types"
|
|
3
3
|
import { Type, type Static } from "@sinclair/typebox"
|
|
4
|
+
import { ForbiddenError } from "@/utils/errors"
|
|
4
5
|
|
|
5
6
|
const ParamsSchema = Type.Object({
|
|
6
7
|
_id: Type.Optional(Type.String()),
|
|
@@ -2,7 +2,8 @@ import type { Static } from "@sinclair/typebox"
|
|
|
2
2
|
import type { FastifyReply, FastifyRequest } from "fastify"
|
|
3
3
|
import { PluginFastifyInstance } from "types"
|
|
4
4
|
import { Type } from "@sinclair/typebox"
|
|
5
|
-
|
|
5
|
+
|
|
6
|
+
const permissions = ["user.isAdmin"]
|
|
6
7
|
|
|
7
8
|
const ParamsSchema = Type.Object({
|
|
8
9
|
_id: Type.String(),
|
|
@@ -17,21 +18,15 @@ export default (fastify: PluginFastifyInstance) => {
|
|
|
17
18
|
reply: FastifyReply,
|
|
18
19
|
) => {
|
|
19
20
|
try {
|
|
20
|
-
|
|
21
|
-
const { _id } = req.params
|
|
21
|
+
const { _id } = req.params
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
const payloadWithTag = await tagService.hardDeleteTag(
|
|
24
|
+
fastify,
|
|
25
|
+
req.requestParams,
|
|
26
|
+
_id,
|
|
27
|
+
)
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
} else {
|
|
31
|
-
throw new ForbiddenError(
|
|
32
|
-
"Only admins can hard delete this core datatype",
|
|
33
|
-
)
|
|
34
|
-
}
|
|
29
|
+
return payloadWithTag
|
|
35
30
|
} catch (error: any) {
|
|
36
31
|
fastify.log.error(error.message)
|
|
37
32
|
return reply.internalServerError(error.message)
|
|
@@ -40,7 +35,7 @@ export default (fastify: PluginFastifyInstance) => {
|
|
|
40
35
|
|
|
41
36
|
return {
|
|
42
37
|
handler,
|
|
43
|
-
onRequest: [fastify.authenticate],
|
|
38
|
+
onRequest: [fastify.authenticate, fastify.checkPermissions(permissions)],
|
|
44
39
|
config: {
|
|
45
40
|
type: "dataHardDeleted",
|
|
46
41
|
broadcastChannels: ["tagHardDeleted"],
|
|
@@ -4,6 +4,8 @@ import { PluginFastifyInstance } from "types"
|
|
|
4
4
|
import { Type } from "@sinclair/typebox"
|
|
5
5
|
import { tagUpdateSchema } from "../tag.schema"
|
|
6
6
|
|
|
7
|
+
const permissions = ["user.isAdmin"]
|
|
8
|
+
|
|
7
9
|
const ParamsSchema = Type.Object({
|
|
8
10
|
_id: Type.String(),
|
|
9
11
|
})
|
|
@@ -40,7 +42,7 @@ export default (fastify: PluginFastifyInstance) => {
|
|
|
40
42
|
|
|
41
43
|
return {
|
|
42
44
|
handler,
|
|
43
|
-
onRequest: [fastify.authenticate],
|
|
45
|
+
onRequest: [fastify.authenticate, fastify.checkPermissions(permissions)],
|
|
44
46
|
config: {
|
|
45
47
|
type: "dataUpdate",
|
|
46
48
|
broadcastChannels: ["tagUpdated"],
|