@raclettejs/core 0.1.19 → 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.
Files changed (132) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/bin/cli.js +1 -1
  3. package/dev/README.md +4 -0
  4. package/dist/cli.js +135 -124
  5. package/dist/cli.js.map +4 -4
  6. package/dist/index.js +9 -8
  7. package/dist/index.js.map +4 -4
  8. package/package.json +9 -5
  9. package/services/backend/delay-api-debugger.sh +0 -0
  10. package/services/backend/package.json +1 -0
  11. package/services/backend/src/app.ts +4 -0
  12. package/services/backend/src/core/config/configService.ts +10 -1
  13. package/services/backend/src/core/events/eventEmitter.ts +32 -7
  14. package/services/backend/src/core/http/request-params.plugin.ts +2 -2
  15. package/services/backend/src/core/pluginSystem/pluginFastifyInstance.ts +4 -1
  16. package/services/backend/src/core/pluginSystem/pluginTypes.ts +3 -1
  17. package/services/backend/src/core/sockets/createSystemEventHandlers.ts +7 -0
  18. package/services/backend/src/core/sockets/index.ts +61 -13
  19. package/services/backend/src/core/sockets/socketManager.ts +452 -105
  20. package/services/backend/src/core/sockets/socketTypes.ts +13 -1
  21. package/services/backend/src/core/sockets/workSessionJoinPayload.ts +106 -0
  22. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/account/routes/route.account.get.ts +3 -1
  23. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/account/routes/route.account.getAll.ts +3 -1
  24. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/account/routes/route.account.hardDelete.ts +16 -19
  25. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/account/routes/route.account.patch.ts +3 -1
  26. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/account/routes/route.account.post.ts +3 -1
  27. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/account/routes/route.account.remove.ts +3 -1
  28. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/composition/composition.service.ts +2 -3
  29. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/composition/routes/route.composition.get.ts +3 -1
  30. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/composition/routes/route.composition.getAll.ts +3 -1
  31. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/composition/routes/route.composition.hardDelete.ts +16 -19
  32. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/composition/routes/route.composition.patch.ts +3 -1
  33. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/composition/routes/route.composition.post.bulk.ts +3 -1
  34. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/composition/routes/route.composition.post.ts +3 -1
  35. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/composition/routes/route.composition.remove.ts +3 -1
  36. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/composition/routes/route.composition.restore.ts +12 -15
  37. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/interactionLink/interactionLink.service.ts +2 -3
  38. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/interactionLink/routes/route.interactionLink.get.ts +3 -1
  39. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/interactionLink/routes/route.interactionLink.getAll.ts +4 -2
  40. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/interactionLink/routes/route.interactionLink.hardDelete.ts +12 -17
  41. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/interactionLink/routes/route.interactionLink.patch.ts +3 -1
  42. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/interactionLink/routes/route.interactionLink.post.bulk.ts +3 -1
  43. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/interactionLink/routes/route.interactionLink.post.ts +3 -1
  44. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/interactionLink/routes/route.interactionLink.remove.ts +3 -1
  45. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/interactionLink/routes/route.interactionLink.restore.ts +12 -15
  46. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/project/project.service.ts +1 -0
  47. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/project/routes/route.project.get.ts +3 -1
  48. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/project/routes/route.project.getAll.ts +4 -2
  49. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/project/routes/route.project.hardDelete.ts +3 -1
  50. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/project/routes/route.project.patch.ts +3 -1
  51. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/project/routes/route.project.post.ts +4 -2
  52. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/project/routes/route.project.remove.ts +3 -1
  53. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/tag/routes/route.tag.get.ts +1 -0
  54. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/tag/routes/route.tag.getAll.ts +1 -0
  55. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/tag/routes/route.tag.hardDelete.ts +10 -15
  56. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/tag/routes/route.tag.patch.ts +3 -1
  57. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/tag/routes/route.tag.post.bulk.ts +3 -1
  58. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/tag/routes/route.tag.post.ts +3 -1
  59. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/tag/routes/route.tag.remove.ts +3 -1
  60. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/tag/routes/route.tag.restore.ts +12 -15
  61. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/tag/tag.service.ts +1 -2
  62. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/user/routes/route.user.get.ts +1 -0
  63. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/user/routes/route.user.getAll.ts +1 -0
  64. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/user/routes/route.user.hardDelete.ts +10 -15
  65. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/user/routes/route.user.patch.ts +4 -6
  66. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/user/routes/route.user.patchLastProject.ts +4 -2
  67. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/user/routes/route.user.post.ts +3 -1
  68. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/user/routes/route.user.remove.ts +3 -4
  69. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/user/routes/route.user.restore.ts +12 -15
  70. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/workSession/events/index.ts +45 -0
  71. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/workSession/helpers/crud.ts +12 -0
  72. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/workSession/helpers/payload.ts +21 -0
  73. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/workSession/index.ts +55 -0
  74. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/workSession/routes/index.ts +19 -0
  75. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/workSession/routes/route.workSession.get.ts +53 -0
  76. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/workSession/routes/route.workSession.getAll.ts +39 -0
  77. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/workSession/routes/route.workSession.hardDelete.ts +53 -0
  78. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/workSession/routes/route.workSession.patch.ts +58 -0
  79. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/workSession/routes/route.workSession.post.ts +53 -0
  80. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/workSession/routes/route.workSession.remove.ts +52 -0
  81. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/workSession/workSession.model.ts +65 -0
  82. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/workSession/workSession.schema.ts +125 -0
  83. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/workSession/workSession.service.ts +351 -0
  84. package/services/backend/src/corePlugins/raclette__core/backend/index.ts +2 -0
  85. package/services/backend/src/corePlugins/raclette__core/frontend/generated-config.ts +159 -24
  86. package/services/backend/src/modules/authentication/index.ts +255 -4
  87. package/services/backend/src/modules/hooks/rate-limiter.ts +21 -0
  88. package/services/backend/src/types/custom-fastify.d.ts +17 -0
  89. package/services/backend/src/utils/request.utils.ts +4 -1
  90. package/services/backend/types/index.d.ts +15 -1
  91. package/services/backend/yarn.lock +13 -4
  92. package/services/frontend/index.html +1 -1
  93. package/services/frontend/provision/entrypoint.sh +0 -0
  94. package/services/frontend/src/core/lib/configService.ts +1 -1
  95. package/services/frontend/src/core/lib/dataHelper.ts +1 -1
  96. package/services/frontend/src/core/lib/eggs/snow.ts +49 -20
  97. package/services/frontend/src/core/lib/helpers/index.ts +1 -0
  98. package/services/frontend/src/core/lib/helpers/removeEmpty.ts +69 -0
  99. package/services/frontend/src/core/lib/httpClient.ts +19 -0
  100. package/services/frontend/src/core/main.ts +20 -10
  101. package/services/frontend/src/core/setup/socket.ts +4 -3
  102. package/services/frontend/src/core/setup/socketClient.ts +31 -3
  103. package/services/frontend/src/core/setup/socketEvents.ts +92 -8
  104. package/services/frontend/src/core/store/index.ts +5 -1
  105. package/services/frontend/src/core/store/reducers/compositions/index.ts +2 -2
  106. package/services/frontend/src/core/store/reducers/interactionLinks/index.ts +1 -1
  107. package/services/frontend/src/core/store/reducers/widgets/reducers.ts +1 -2
  108. package/services/frontend/src/core/store/types/index.ts +0 -1
  109. package/services/frontend/src/core/types/PluginRegistrar.ts +8 -6
  110. package/services/frontend/src/core/types/Store.ts +1 -0
  111. package/services/frontend/src/orchestrator/components/composition/WidgetsLayoutLoader.vue +68 -8
  112. package/services/frontend/src/orchestrator/components/menu/UserMenu.vue +17 -5
  113. package/services/frontend/src/orchestrator/components/welcomeScreen/AdminWelcomeScreen.vue +1 -1
  114. package/services/frontend/src/orchestrator/composables/index.ts +1 -0
  115. package/services/frontend/src/orchestrator/composables/usePluginApi.ts +0 -3
  116. package/services/frontend/src/orchestrator/composables/useRouteState.ts +23 -4
  117. package/services/frontend/src/orchestrator/composables/useWidgetLifecycle.ts +166 -0
  118. package/services/frontend/src/orchestrator/helpers/index.ts +1 -0
  119. package/services/frontend/src/orchestrator/i18n/de-DE.json +1 -1
  120. package/services/frontend/src/orchestrator/i18n/en-EU.json +1 -1
  121. package/services/frontend/src/orchestrator/i18n/sk.json +1 -1
  122. package/services/frontend/src/orchestrator/index.ts +34 -4
  123. package/services/frontend/src/orchestrator/router/routeParserHelper.ts +106 -1
  124. package/services/frontend/src/orchestrator/types/Widgets.ts +2 -0
  125. package/services/frontend/types.ts +1 -0
  126. package/src/README.md +404 -0
  127. package/src/types.ts +19 -5
  128. package/templates/README.md +0 -0
  129. package/types/index.ts +18 -4
  130. package/services/backend/.gitignore +0 -17
  131. package/services/frontend/.gitignore +0 -35
  132. package/yarn.lock +0 -2937
@@ -0,0 +1,106 @@
1
+ import { v4 as uuidv4 } from "uuid"
2
+
3
+ /**
4
+ * Builds the joinConfirmation payload shape for work-session guests.
5
+ * Keeps virtual composition and simulated interaction-link logic out of socketManager.
6
+ */
7
+
8
+ interface WorkSessionLike {
9
+ _id: string
10
+ userId: string
11
+ createdAt?: Date | string
12
+ updatedAt?: Date | string
13
+ [key: string]: unknown
14
+ }
15
+
16
+ interface CompositionLike {
17
+ title?: string
18
+ description?: string
19
+ tags?: unknown[]
20
+ icon?: string
21
+ slotLayout?: string
22
+ widgetsLayout?: unknown[]
23
+ status?: string
24
+ createdAt?: string
25
+ updatedAt?: string
26
+ [key: string]: unknown
27
+ }
28
+
29
+ /** Virtual composition sent to frontend (pathname.default matches route /:workSession/id=...) */
30
+ function buildVirtualComposition(
31
+ composition: CompositionLike,
32
+ workSession: WorkSessionLike,
33
+ ): Record<string, unknown> {
34
+ const now = new Date()
35
+ return {
36
+ _id: uuidv4(),
37
+ title: composition.title ?? "Shared Session",
38
+ description:
39
+ composition.description ?? "Shared composition for anonymous access",
40
+ tags: composition.tags ?? [],
41
+ icon: composition.icon,
42
+ pathname: { default: "workSession" },
43
+ slotLayout: composition.slotLayout ?? "full",
44
+ widgetsLayout: composition.widgetsLayout ?? [],
45
+ status: composition.status ?? "live",
46
+ author: workSession.userId,
47
+ lastEditor: workSession.userId,
48
+ isDeleted: false,
49
+ createdAt: composition.createdAt ?? now.toISOString(),
50
+ updatedAt: composition.updatedAt ?? now.toISOString(),
51
+ }
52
+ }
53
+
54
+ /** Simulated interaction link so the frontend can resolve the composition like a normal project. */
55
+ function buildSimulatedInteractionLink(
56
+ workSession: WorkSessionLike,
57
+ virtualComposition: { _id: string; [key: string]: unknown },
58
+ ): Record<string, unknown> {
59
+ const created = workSession.createdAt
60
+ ? new Date(workSession.createdAt)
61
+ : new Date()
62
+ const updated = workSession.updatedAt
63
+ ? new Date(workSession.updatedAt)
64
+ : new Date()
65
+ return {
66
+ _id: `session_${workSession._id}_interactionLink`,
67
+ composition: virtualComposition._id,
68
+ slotType: "page",
69
+ triggers: [],
70
+ queryParameters: [],
71
+ description: "Shared session composition",
72
+ tags: [],
73
+ author: workSession.userId,
74
+ lastEditor: workSession.userId,
75
+ isLandingPage: true,
76
+ isDeleted: false,
77
+ createdAt: created,
78
+ updatedAt: updated,
79
+ }
80
+ }
81
+
82
+ export interface WorkSessionJoinPayloadData {
83
+ compositions: unknown[]
84
+ interactionLinks: unknown[]
85
+ projectConfig: Record<string, unknown>
86
+ }
87
+
88
+ /**
89
+ * Build the data part of joinConfirmation for a work session (no token).
90
+ * Socket manager adds token and decoded after creating the JWT.
91
+ */
92
+ export function buildWorkSessionJoinPayload(
93
+ workSession: WorkSessionLike,
94
+ composition: CompositionLike,
95
+ ): WorkSessionJoinPayloadData {
96
+ const virtualComposition = buildVirtualComposition(composition, workSession)
97
+ const simulatedInteractionLink = buildSimulatedInteractionLink(
98
+ workSession,
99
+ virtualComposition as { _id: string; [key: string]: unknown },
100
+ )
101
+ return {
102
+ compositions: [virtualComposition],
103
+ interactionLinks: [simulatedInteractionLink],
104
+ projectConfig: {},
105
+ }
106
+ }
@@ -3,6 +3,8 @@ import type { FastifyReply, FastifyRequest } from "fastify"
3
3
  import { Type } from "@sinclair/typebox"
4
4
  import type { PluginFastifyInstance } from "types"
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,6 +1,8 @@
1
1
  import type { FastifyReply, FastifyRequest } from "fastify"
2
2
  import type { PluginFastifyInstance } from "types"
3
3
 
4
+ const permissions = ["user.isAdmin"]
5
+
4
6
  export default (fastify: PluginFastifyInstance) => {
5
7
  const accountService = fastify.custom.accountService
6
8
 
@@ -20,7 +22,7 @@ export default (fastify: PluginFastifyInstance) => {
20
22
 
21
23
  return {
22
24
  handler,
23
- onRequest: [fastify.authenticate],
25
+ onRequest: [fastify.authenticate, fastify.checkPermissions(permissions)],
24
26
  config: {
25
27
  type: "dataRead",
26
28
  },
@@ -2,7 +2,8 @@ import type { Static } from "@sinclair/typebox"
2
2
  import type { FastifyReply, FastifyRequest } from "fastify"
3
3
  import type { PluginFastifyInstance } from "types"
4
4
  import { Type } from "@sinclair/typebox"
5
- import { ForbiddenError } from "@/utils/errors"
5
+
6
+ const permissions = ["user.isAdmin"]
6
7
 
7
8
  const ParamsSchema = Type.Object({
8
9
  _id: Type.String(),
@@ -18,29 +19,25 @@ export default (fastify: PluginFastifyInstance) => {
18
19
  }>,
19
20
  reply: FastifyReply,
20
21
  ) => {
21
- if (req.user.isAdmin) {
22
- try {
23
- const { _id } = req.params
24
-
25
- const payload = await accountService.hardDeleteAccount(
26
- fastify,
27
- req.requestParams,
28
- _id,
29
- )
30
-
31
- return payload
32
- } catch (error: any) {
33
- fastify.log.error(error.message)
34
- return reply.internalServerError(error.message)
35
- }
36
- } else {
37
- throw new ForbiddenError("Only admins can hard delete this core datatype")
22
+ try {
23
+ const { _id } = req.params
24
+
25
+ const payload = await accountService.hardDeleteAccount(
26
+ fastify,
27
+ req.requestParams,
28
+ _id,
29
+ )
30
+
31
+ return payload
32
+ } catch (error: any) {
33
+ fastify.log.error(error.message)
34
+ return reply.internalServerError(error.message)
38
35
  }
39
36
  }
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: "dataHardDeleted",
46
43
  broadcastChannels: ["accountHardDeleted"],
@@ -5,6 +5,8 @@ import type { PluginFastifyInstance } from "types"
5
5
  import { Type } from "@sinclair/typebox"
6
6
  import { accountSchema } from "../account.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: ["accountUpdated", "broadcastDataUpdated"],
@@ -3,6 +3,8 @@ import type { FastifyReply, FastifyRequest } from "fastify"
3
3
  import type { PluginFastifyInstance } from "types"
4
4
  import { accountSchema } from "../account.schema"
5
5
 
6
+ const permissions = ["user.isAdmin"]
7
+
6
8
  export default (fastify: PluginFastifyInstance) => {
7
9
  const accountService = fastify.custom.accountService
8
10
 
@@ -29,7 +31,7 @@ export default (fastify: PluginFastifyInstance) => {
29
31
 
30
32
  return {
31
33
  handler,
32
- onRequest: [fastify.authenticate],
34
+ onRequest: [fastify.authenticate, fastify.checkPermissions(permissions)],
33
35
  config: {
34
36
  type: "dataCreate",
35
37
  broadcastChannels: ["accountCreated"],
@@ -3,6 +3,8 @@ import type { FastifyReply, FastifyRequest } from "fastify"
3
3
  import type { 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: ["accountDeleted"],
@@ -94,11 +94,10 @@ export class CompositionService {
94
94
  */
95
95
  async _readAllCompositions(
96
96
  fastify: PluginFastifyInstance,
97
- filters: Record<string, any> = {},
97
+ filters: Record<string, any> = { isDeleted: false },
98
98
  ): Promise<CompositionType[]> {
99
99
  try {
100
- if (filters.isDeleted !== true && filters.isDeleted !== "true")
101
- filters.isDeleted = false
100
+ filters = { isDeleted: false, ...filters }
102
101
  return await this.compositionModel
103
102
  .find({
104
103
  ...filters,
@@ -3,6 +3,8 @@ import type { FastifyReply, FastifyRequest } from "fastify"
3
3
  import type { 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,6 +1,8 @@
1
1
  import type { FastifyReply, FastifyRequest } from "fastify"
2
2
  import type { PluginFastifyInstance } from "types"
3
3
 
4
+ const permissions = ["user.isAdmin"]
5
+
4
6
  export default (fastify: PluginFastifyInstance) => {
5
7
  const compositionService = fastify.custom.compositionService
6
8
 
@@ -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 type { PluginFastifyInstance } from "types"
4
4
  import { Type } from "@sinclair/typebox"
5
- import { ForbiddenError } from "@/utils/errors"
5
+
6
+ const permissions = ["user.isAdmin"]
6
7
 
7
8
  const ParamsSchema = Type.Object({
8
9
  _id: Type.String(),
@@ -18,29 +19,25 @@ export default (fastify: PluginFastifyInstance) => {
18
19
  }>,
19
20
  reply: FastifyReply,
20
21
  ) => {
21
- if (req.user.isAdmin) {
22
- try {
23
- const { _id } = req.params
24
-
25
- const payload = await compositionService.hardDeleteComposition(
26
- fastify,
27
- req.requestParams,
28
- _id,
29
- )
30
-
31
- return payload
32
- } catch (error: any) {
33
- fastify.log.error(error.message)
34
- return reply.internalServerError(error.message)
35
- }
36
- } else {
37
- throw new ForbiddenError("Only admins can hard delete this core datatype")
22
+ try {
23
+ const { _id } = req.params
24
+
25
+ const payload = await compositionService.hardDeleteComposition(
26
+ fastify,
27
+ req.requestParams,
28
+ _id,
29
+ )
30
+
31
+ return payload
32
+ } catch (error: any) {
33
+ fastify.log.error(error.message)
34
+ return reply.internalServerError(error.message)
38
35
  }
39
36
  }
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: "dataHardDelete",
46
43
  broadcastChannels: ["compositionHardDeleted"],
@@ -5,6 +5,8 @@ import type { PluginFastifyInstance } from "types"
5
5
  import { Type } from "@sinclair/typebox"
6
6
  import { compositionUpdateSchema } from "../composition.schema"
7
7
 
8
+ const permissions = ["user.isAdmin"]
9
+
8
10
  const ParamsSchema = Type.Object({
9
11
  _id: Type.String(),
10
12
  })
@@ -42,7 +44,7 @@ export default (fastify: PluginFastifyInstance) => {
42
44
 
43
45
  return {
44
46
  handler,
45
- onRequest: [fastify.authenticate],
47
+ onRequest: [fastify.authenticate, fastify.checkPermissions(permissions)],
46
48
  config: {
47
49
  type: "dataUpdate",
48
50
  broadcastChannels: ["compositionUpdated"],
@@ -3,6 +3,8 @@ import type { FastifyReply, FastifyRequest } from "fastify"
3
3
  import type { PluginFastifyInstance } from "types"
4
4
  import { compositionCreateSchema } from "../composition.schema"
5
5
 
6
+ const permissions = ["user.isAdmin"]
7
+
6
8
  export default (fastify: PluginFastifyInstance) => {
7
9
  const compositionService = fastify.custom.compositionService
8
10
 
@@ -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: "dataCreate",
46
48
  broadcastChannels: ["compositionsCreated"],
@@ -3,6 +3,8 @@ import type { FastifyReply, FastifyRequest } from "fastify"
3
3
  import type { PluginFastifyInstance } from "types"
4
4
  import { compositionCreateSchema } from "../composition.schema"
5
5
 
6
+ const permissions = ["user.isAdmin"]
7
+
6
8
  export default (fastify: PluginFastifyInstance) => {
7
9
  const compositionService = fastify.custom.compositionService
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: ["compositionCreated"],
@@ -3,6 +3,8 @@ import type { FastifyReply, FastifyRequest } from "fastify"
3
3
  import type { 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: ["compositionDeleted"],
@@ -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
- import { ForbiddenError } from "@/utils/errors"
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
- if (req.user.isAdmin) {
21
- const { _id } = req.params
21
+ const { _id } = req.params
22
22
 
23
- const payload = await compositionService.updateComposition(
24
- fastify,
25
- req.requestParams,
26
- _id,
27
- { isDeleted: false },
28
- req.user._id,
29
- )
23
+ const payload = await compositionService.updateComposition(
24
+ fastify,
25
+ req.requestParams,
26
+ _id,
27
+ { isDeleted: false },
28
+ req.user._id,
29
+ )
30
30
 
31
- return payload
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: ["compositionRestored"],
@@ -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
- if (filters.isDeleted !== true && filters.isDeleted !== "true")
104
- filters.isDeleted = false
103
+ filters = { isDeleted: false, ...filters }
105
104
  return await this.interactionLinkModel
106
105
  .find({
107
106
  ...filters,
@@ -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
- import { ForbiddenError } from "@/utils/errors"
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
- if (req.user.isAdmin) {
23
- const { _id } = req.params
24
-
25
- const payload = await interactionLinkService.hardDeleteInteractionLink(
26
- fastify,
27
- req.requestParams,
28
- _id,
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"],
@@ -3,6 +3,8 @@ import type { FastifyReply, FastifyRequest } from "fastify"
3
3
  import type { 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
 
@@ -42,7 +44,7 @@ export default (fastify: PluginFastifyInstance) => {
42
44
 
43
45
  return {
44
46
  handler,
45
- onRequest: [fastify.authenticate],
47
+ onRequest: [fastify.authenticate, fastify.checkPermissions(permissions)],
46
48
  config: {
47
49
  type: "dataCreate",
48
50
  broadcastChannels: ["interactionLinksCreated"],
@@ -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"],