@ossy/workspaces 1.16.7 → 1.17.1

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 (53) hide show
  1. package/README.md +1 -0
  2. package/package.json +5 -4
  3. package/src/AuthenticationGuard.jsx +23 -10
  4. package/src/CreateWorkspacePage.jsx +18 -12
  5. package/src/Definition.js +1 -17
  6. package/src/GeneralSettings.jsx +27 -70
  7. package/src/Invitations.jsx +11 -19
  8. package/src/Invite.jsx +17 -14
  9. package/src/SelectWorkspacePage.jsx +17 -22
  10. package/src/Users.jsx +10 -15
  11. package/src/accept-invitation.action.js +1 -85
  12. package/src/accept-invitation.task.js +84 -0
  13. package/src/create-api-token.action.js +1 -17
  14. package/src/create-api-token.task.js +16 -0
  15. package/src/create.action.js +1 -30
  16. package/src/create.task.js +29 -0
  17. package/src/disable-service.action.js +1 -28
  18. package/src/disable-service.task.js +27 -0
  19. package/src/en.translations.json +72 -0
  20. package/src/enable-service.action.js +1 -28
  21. package/src/enable-service.task.js +27 -0
  22. package/src/get-api-tokens.action.js +1 -11
  23. package/src/get-api-tokens.task.js +10 -0
  24. package/src/get-invitations.action.js +1 -11
  25. package/src/get-invitations.task.js +10 -0
  26. package/src/get-resource-templates.action.js +1 -19
  27. package/src/get-resource-templates.task.js +18 -0
  28. package/src/get-users.action.js +1 -14
  29. package/src/get-users.task.js +13 -0
  30. package/src/get.action.js +1 -14
  31. package/src/get.task.js +13 -0
  32. package/src/import-resource-templates.action.js +1 -27
  33. package/src/import-resource-templates.task.js +26 -0
  34. package/src/index.js +14 -2
  35. package/src/invite-user.action.js +1 -85
  36. package/src/invite-user.task.js +84 -0
  37. package/src/list.action.js +1 -9
  38. package/src/list.task.js +8 -0
  39. package/src/remove-member.action.js +1 -17
  40. package/src/remove-member.task.js +16 -0
  41. package/src/server.js +3 -0
  42. package/src/sv.translations.json +72 -0
  43. package/src/sync-workspace-membership.task.js +4 -3
  44. package/src/workspaces.spec.js +71 -80
  45. package/src/current.api.js +0 -30
  46. package/src/invitations.api.js +0 -46
  47. package/src/item.api.js +0 -32
  48. package/src/list.api.js +0 -35
  49. package/src/members.api.js +0 -42
  50. package/src/resource-templates.api.js +0 -35
  51. package/src/services-disable.api.js +0 -23
  52. package/src/services-enable.api.js +0 -23
  53. package/src/tokens.api.js +0 -35
@@ -1,85 +1 @@
1
- import jwt from 'jsonwebtoken'
2
- import { Aggregate } from '@ossy/event-store'
3
- import { Workspace, WorkspacesEvents } from '@ossy/workspaces'
4
- import { User, UsersEvents } from '@ossy/users'
5
- import { Token, TokenEvents } from '@ossy/tokens'
6
- import { ConfigService } from '@ossy/platform'
7
- import { createLogger } from '@ossy/observability'
8
-
9
- const log = createLogger('workspaces/accept-invitation')
10
-
11
- function verifyToken(token) {
12
- return new Promise((resolve, reject) => {
13
- if (!token) return reject(new Error('No token'))
14
- jwt.verify(token, ConfigService.TokenSecret, { algorithms: ['HS256'] }, (err, payload) => {
15
- if (err) return reject(err)
16
- resolve(payload)
17
- })
18
- })
19
- }
20
-
21
- export const id = 'workspaces/accept-invitation'
22
- export const access = 'public'
23
-
24
- export async function run({ payload, req }) {
25
- const workspaceId = payload?.workspaceId ?? req?.workspaceId
26
- const verificationToken = payload?.token ?? req?.query?.token
27
-
28
- const { aud: tokenWorkspaceId, sub: email } = await verifyToken(verificationToken)
29
- .catch(() => { throw Object.assign(new Error('Invalid token'), { status: 401 }) })
30
-
31
- const resolvedWorkspaceId = tokenWorkspaceId ?? workspaceId
32
- const workspace = await Aggregate.Of(Workspace, resolvedWorkspaceId).then(Aggregate.View())
33
-
34
- if (!email) throw Object.assign(new Error('No email found in token payload'), { status: 401 })
35
-
36
- const existingUser = await Aggregate.Collection.findOne({ type: 'User', 'state.email': email }).then(agg => agg?.state)
37
-
38
- if (existingUser && workspace.users.includes(existingUser.id)) {
39
- throw Object.assign(new Error('User already in workspace'), { status: 400 })
40
- }
41
-
42
- let userId
43
- let signInToken
44
- let signInExpiresAt
45
-
46
- if (existingUser) {
47
- userId = existingUser.id
48
- const signInExpiresIn = ConfigService.TokenValidity
49
- signInExpiresAt = Date.now() + signInExpiresIn * 1000
50
- signInToken = jwt.sign({ sub: userId, type: 'WebAuth' }, ConfigService.TokenSecret, { expiresIn: signInExpiresIn })
51
- const signInEvent = TokenEvents.Created({
52
- type: 'WebAuth',
53
- subject: userId,
54
- createdBy: userId,
55
- token: signInToken,
56
- expiresAt: signInExpiresAt,
57
- })
58
- const userInvitationAccepted = WorkspacesEvents.UserInvitationAccepted({ email, createdBy: userId })
59
- await Promise.all([
60
- Aggregate.Of(Token, signInEvent),
61
- Aggregate.Of(Workspace, resolvedWorkspaceId).then(Aggregate.Add(userInvitationAccepted)),
62
- ])
63
- } else {
64
- const signUpEvent = UsersEvents.SignedUp({ email })
65
- userId = signUpEvent.createdBy
66
- const signInExpiresIn = ConfigService.TokenValidity
67
- signInExpiresAt = Date.now() + signInExpiresIn * 1000
68
- signInToken = jwt.sign({ sub: userId, type: 'WebAuth' }, ConfigService.TokenSecret, { expiresIn: signInExpiresIn })
69
- const signInEvent = TokenEvents.Created({
70
- type: 'WebAuth',
71
- subject: userId,
72
- createdBy: userId,
73
- token: signInToken,
74
- expiresAt: signInExpiresAt,
75
- })
76
- const userInvitationAccepted = WorkspacesEvents.UserInvitationAccepted({ email, createdBy: userId })
77
- await Promise.all([
78
- Aggregate.Of(User, signUpEvent),
79
- Aggregate.Of(Token, signInEvent),
80
- Aggregate.Of(Workspace, resolvedWorkspaceId).then(Aggregate.Add(userInvitationAccepted)),
81
- ])
82
- }
83
-
84
- return { authToken: signInToken, authExpiresAt: signInExpiresAt }
85
- }
1
+ export const metadata = { id: 'workspaces/accept-invitation', access: 'public' }
@@ -0,0 +1,84 @@
1
+ import jwt from 'jsonwebtoken'
2
+ import { Aggregate } from '@ossy/event-store'
3
+ import { Workspace, WorkspacesEvents } from '@ossy/workspaces/server'
4
+ import { User, UsersEvents } from '@ossy/users/server'
5
+ import { Token, TokenEvents } from '@ossy/tokens/server'
6
+ import { ConfigService } from '@ossy/platform'
7
+ import { createLogger } from '@ossy/observability'
8
+
9
+ export const metadata = { id: 'workspaces/accept-invitation' }
10
+
11
+ const log = createLogger('workspaces/accept-invitation')
12
+
13
+ function verifyToken(token) {
14
+ return new Promise((resolve, reject) => {
15
+ if (!token) return reject(new Error('No token'))
16
+ jwt.verify(token, ConfigService.TokenSecret, { algorithms: ['HS256'] }, (err, payload) => {
17
+ if (err) return reject(err)
18
+ resolve(payload)
19
+ })
20
+ })
21
+ }
22
+
23
+ export async function run({ payload, req }) {
24
+ const workspaceId = payload?.workspaceId ?? req?.workspaceId
25
+ const verificationToken = payload?.token ?? req?.query?.token
26
+
27
+ const { aud: tokenWorkspaceId, sub: email } = await verifyToken(verificationToken)
28
+ .catch(() => { throw Object.assign(new Error('Invalid token'), { status: 401 }) })
29
+
30
+ const resolvedWorkspaceId = tokenWorkspaceId ?? workspaceId
31
+ const workspace = await Aggregate.Of(Workspace, resolvedWorkspaceId).then(Aggregate.View())
32
+
33
+ if (!email) throw Object.assign(new Error('No email found in token payload'), { status: 401 })
34
+
35
+ const existingUser = await Aggregate.Collection.findOne({ type: 'User', 'state.email': email }).then(agg => agg?.state)
36
+
37
+ if (existingUser && workspace.users.includes(existingUser.id)) {
38
+ throw Object.assign(new Error('User already in workspace'), { status: 400 })
39
+ }
40
+
41
+ let userId
42
+ let signInToken
43
+ let signInExpiresAt
44
+
45
+ if (existingUser) {
46
+ userId = existingUser.id
47
+ const signInExpiresIn = ConfigService.TokenValidity
48
+ signInExpiresAt = Date.now() + signInExpiresIn * 1000
49
+ signInToken = jwt.sign({ sub: userId, type: 'WebAuth' }, ConfigService.TokenSecret, { expiresIn: signInExpiresIn })
50
+ const signInEvent = TokenEvents.Created({
51
+ type: 'WebAuth',
52
+ subject: userId,
53
+ createdBy: userId,
54
+ token: signInToken,
55
+ expiresAt: signInExpiresAt,
56
+ })
57
+ const userInvitationAccepted = WorkspacesEvents.UserInvitationAccepted({ email, createdBy: userId })
58
+ await Promise.all([
59
+ Aggregate.Of(Token, signInEvent),
60
+ Aggregate.Of(Workspace, resolvedWorkspaceId).then(Aggregate.Add(userInvitationAccepted)),
61
+ ])
62
+ } else {
63
+ const signUpEvent = UsersEvents.SignedUp({ email })
64
+ userId = signUpEvent.createdBy
65
+ const signInExpiresIn = ConfigService.TokenValidity
66
+ signInExpiresAt = Date.now() + signInExpiresIn * 1000
67
+ signInToken = jwt.sign({ sub: userId, type: 'WebAuth' }, ConfigService.TokenSecret, { expiresIn: signInExpiresIn })
68
+ const signInEvent = TokenEvents.Created({
69
+ type: 'WebAuth',
70
+ subject: userId,
71
+ createdBy: userId,
72
+ token: signInToken,
73
+ expiresAt: signInExpiresAt,
74
+ })
75
+ const userInvitationAccepted = WorkspacesEvents.UserInvitationAccepted({ email, createdBy: userId })
76
+ await Promise.all([
77
+ Aggregate.Of(User, signUpEvent),
78
+ Aggregate.Of(Token, signInEvent),
79
+ Aggregate.Of(Workspace, resolvedWorkspaceId).then(Aggregate.Add(userInvitationAccepted)),
80
+ ])
81
+ }
82
+
83
+ return { authToken: signInToken, authExpiresAt: signInExpiresAt }
84
+ }
@@ -1,17 +1 @@
1
- import { Aggregate } from '@ossy/event-store'
2
- import { Workspace, WorkspacesEvents } from '@ossy/workspaces'
3
-
4
- export const id = 'workspaces/create-api-token'
5
- export const access = 'workspace'
6
-
7
- export async function run({ payload, req }) {
8
- const createdBy = payload?.userId ?? req?.userId
9
- const workspaceId = payload?.workspaceId ?? req?.workspaceId
10
- const description = payload?.description
11
-
12
- const event = WorkspacesEvents.ApiTokenCreated({ createdBy, workspaceId, description })
13
-
14
- const aggregate = await Aggregate.Of(Workspace, workspaceId).then(Aggregate.Add(event))
15
- const last = aggregate.events[aggregate.events.length - 1]
16
- return { id: last.id, token: event.payload.token }
17
- }
1
+ export const metadata = { id: 'workspaces/create-api-token', access: 'workspace' }
@@ -0,0 +1,16 @@
1
+ import { Aggregate } from '@ossy/event-store'
2
+ import { Workspace, WorkspacesEvents } from '@ossy/workspaces/server'
3
+
4
+ export const metadata = { id: 'workspaces/create-api-token' }
5
+
6
+ export async function run({ payload, req }) {
7
+ const createdBy = payload?.userId ?? req?.userId
8
+ const workspaceId = payload?.workspaceId ?? req?.workspaceId
9
+ const description = payload?.description
10
+
11
+ const event = WorkspacesEvents.ApiTokenCreated({ createdBy, workspaceId, description })
12
+
13
+ const aggregate = await Aggregate.Of(Workspace, workspaceId).then(Aggregate.Add(event))
14
+ const last = aggregate.events[aggregate.events.length - 1]
15
+ return { id: last.id, token: event.payload.token }
16
+ }
@@ -1,30 +1 @@
1
- import { Aggregate } from '@ossy/event-store'
2
- import { Workspace, WorkspacesEvents } from '@ossy/workspaces'
3
- import { ConfigService } from '@ossy/platform'
4
-
5
- export const id = 'workspaces/create'
6
- export const access = 'authenticated'
7
-
8
- export async function run({ payload, req }) {
9
- const createdBy = payload?.userId ?? req?.userId
10
- const name = (payload?.name ?? req?.body?.name)?.trim?.()
11
-
12
- if (!name || typeof name !== 'string') {
13
- throw Object.assign(new Error('Invalid name'), { status: 400 })
14
- }
15
-
16
- const createdEvent = WorkspacesEvents.Created({ createdBy, name })
17
- const botUserInvitedEvent = WorkspacesEvents.UserInvited({
18
- createdBy: ConfigService.BotUserId,
19
- email: ConfigService.BotUserEmail,
20
- })
21
- const botUserAcceptedEvent = WorkspacesEvents.UserInvitationAccepted({
22
- createdBy: ConfigService.BotUserId,
23
- email: ConfigService.BotUserEmail,
24
- })
25
-
26
- return Aggregate.Of(Workspace, createdEvent)
27
- .then(Aggregate.Add(botUserInvitedEvent))
28
- .then(Aggregate.Add(botUserAcceptedEvent))
29
- .then(Aggregate.View())
30
- }
1
+ export const metadata = { id: 'workspaces/create', access: 'authenticated' }
@@ -0,0 +1,29 @@
1
+ import { Aggregate } from '@ossy/event-store'
2
+ import { Workspace, WorkspacesEvents } from '@ossy/workspaces/server'
3
+ import { ConfigService } from '@ossy/platform'
4
+
5
+ export const metadata = { id: 'workspaces/create' }
6
+
7
+ export async function run({ payload, req }) {
8
+ const createdBy = payload?.userId ?? req?.userId
9
+ const name = (payload?.name ?? req?.body?.name)?.trim?.()
10
+
11
+ if (!name || typeof name !== 'string') {
12
+ throw Object.assign(new Error('Invalid name'), { status: 400 })
13
+ }
14
+
15
+ const createdEvent = WorkspacesEvents.Created({ createdBy, name })
16
+ const botUserInvitedEvent = WorkspacesEvents.UserInvited({
17
+ createdBy: ConfigService.BotUserId,
18
+ email: ConfigService.BotUserEmail,
19
+ })
20
+ const botUserAcceptedEvent = WorkspacesEvents.UserInvitationAccepted({
21
+ createdBy: ConfigService.BotUserId,
22
+ email: ConfigService.BotUserEmail,
23
+ })
24
+
25
+ return Aggregate.Of(Workspace, createdEvent)
26
+ .then(Aggregate.Add(botUserInvitedEvent))
27
+ .then(Aggregate.Add(botUserAcceptedEvent))
28
+ .then(Aggregate.View())
29
+ }
@@ -1,28 +1 @@
1
- import { Aggregate } from '@ossy/event-store'
2
- import { Workspace, WorkspacesEvents } from '@ossy/workspaces'
3
-
4
- export const id = 'workspaces/disable-service'
5
- export const access = 'workspace'
6
-
7
- const AVAILABLE_SERVICES = [
8
- '@ossy/tasks/visual-content-descriptors',
9
- '@ossy/tasks/resize-common-web',
10
- '@ossy/resumes',
11
- '@ossy/consultancy',
12
- '@ossy/apps',
13
- '@ossy/domains',
14
- ]
15
-
16
- export async function run({ payload, req }) {
17
- const createdBy = payload?.userId ?? req?.userId
18
- const workspaceId = payload?.workspaceId ?? req?.workspaceId
19
- const service = payload?.service
20
-
21
- if (!AVAILABLE_SERVICES.includes(service)) {
22
- throw Object.assign(new Error(`Service ${service} is not available`), { status: 400 })
23
- }
24
-
25
- const event = WorkspacesEvents.ServiceDisabled({ createdBy, service })
26
- await Aggregate.Of(Workspace, workspaceId).then(Aggregate.Add(event))
27
- return null
28
- }
1
+ export const metadata = { id: 'workspaces/disable-service', access: 'workspace' }
@@ -0,0 +1,27 @@
1
+ import { Aggregate } from '@ossy/event-store'
2
+ import { Workspace, WorkspacesEvents } from '@ossy/workspaces/server'
3
+
4
+ export const metadata = { id: 'workspaces/disable-service' }
5
+
6
+ const AVAILABLE_SERVICES = [
7
+ '@ossy/tasks/visual-content-descriptors',
8
+ '@ossy/tasks/resize-common-web',
9
+ '@ossy/resumes',
10
+ '@ossy/consultancy',
11
+ '@ossy/apps',
12
+ '@ossy/domains',
13
+ ]
14
+
15
+ export async function run({ payload, req }) {
16
+ const createdBy = payload?.userId ?? req?.userId
17
+ const workspaceId = payload?.workspaceId ?? req?.workspaceId
18
+ const service = payload?.service
19
+
20
+ if (!AVAILABLE_SERVICES.includes(service)) {
21
+ throw Object.assign(new Error(`Service ${service} is not available`), { status: 400 })
22
+ }
23
+
24
+ const event = WorkspacesEvents.ServiceDisabled({ createdBy, service })
25
+ await Aggregate.Of(Workspace, workspaceId).then(Aggregate.Add(event))
26
+ return null
27
+ }
@@ -0,0 +1,72 @@
1
+ {
2
+ "profile/workspaces/create.documentTitle": "Create workspace",
3
+ "workspaces.create.title": "Create a new workspace",
4
+ "workspaces.create.namePlaceholder": "Workspace name",
5
+ "workspaces.create.cancel": "Cancel",
6
+ "workspaces.create.submit": "Create",
7
+ "profile/workspaces.documentTitle": "Select workspace",
8
+ "workspaces.select.title": "My workspaces",
9
+ "workspaces.select.newWorkspace": "New workspace",
10
+ "workspaces.select.loading": "Loading...",
11
+ "workspaces.select.description": "Workspaces are separate environments where you can manage resources, templates, services and billing.",
12
+ "workspaces.select.errorTitle": "We could not load your workspaces",
13
+ "workspaces.select.errorText": "Something went wrong when loading your workspaces. Maybe your session has expired, or we messed up somehow. Try starting over from our home page.",
14
+ "workspaces.select.errorAction": "Go to our home page",
15
+ "workspaces.select.emptyTitle": "Let's get the party started",
16
+ "workspaces.select.emptyText": "To get started we need to create a workspace. A workspace is an encapsulation of resources, resource templates, billing information, and what users have access to these things.",
17
+ "workspaces.select.emptyAction": "Create a workspace",
18
+ "workspaces/create.label": "Create workspace",
19
+ "workspaces/create.description": "Create a new workspace for the authenticated user",
20
+ "workspaces/accept-invitation.label": "Accept invitation",
21
+ "workspaces/accept-invitation.description": "Accept a workspace invitation",
22
+ "workspaces/create-api-token.label": "Create workspace API token",
23
+ "workspaces/create-api-token.description": "Create an API token scoped to the workspace",
24
+ "workspaces/disable-service.label": "Disable service",
25
+ "workspaces/disable-service.description": "Disable a service for the workspace",
26
+ "workspaces/enable-service.label": "Enable service",
27
+ "workspaces/enable-service.description": "Enable a service for the workspace",
28
+ "workspaces/get-api-tokens.label": "Get workspace API tokens",
29
+ "workspaces/get-api-tokens.description": "List API tokens for the workspace",
30
+ "workspaces/get-invitations.label": "Get invitations",
31
+ "workspaces/get-invitations.description": "List pending workspace invitations",
32
+ "workspaces/get-resource-templates.label": "Get resource templates",
33
+ "workspaces/get-resource-templates.description": "List resource templates available to the workspace",
34
+ "workspaces/get-users.label": "Get workspace users",
35
+ "workspaces/get-users.description": "List members of the workspace",
36
+ "workspaces/get.label": "Get workspace",
37
+ "workspaces/get.description": "Load a workspace by id",
38
+ "workspaces/import-resource-templates.label": "Import resource templates",
39
+ "workspaces/import-resource-templates.description": "Import resource templates into the workspace",
40
+ "workspaces/invite-user.label": "Invite user",
41
+ "workspaces/invite-user.description": "Send a workspace invitation to a user",
42
+ "workspaces/remove-member.label": "Remove member",
43
+ "workspaces/remove-member.description": "Remove a user from the workspace",
44
+ "workspaces/list.label": "List workspaces",
45
+ "workspaces/list.description": "List workspaces for the authenticated user",
46
+ "workspace/settings.documentTitle": "Workspace settings",
47
+ "workspace.settings.title": "Workspace settings",
48
+ "workspace/users.documentTitle": "Users",
49
+ "workspace.users.title": "Users",
50
+ "workspace.users.description": "Manage users in your workspace.",
51
+ "workspace.users.invite": "Invite user",
52
+ "workspace.users.loading": "Loading",
53
+ "workspace/invitations.documentTitle": "Invitations",
54
+ "workspace/invitations/add.documentTitle": "Invite user",
55
+ "workspace.invitations.title": "Invitations",
56
+ "workspace.settings.detailsTitle": "Workspace details",
57
+ "workspace.settings.edit": "Edit",
58
+ "workspace.settings.name": "Name",
59
+ "workspace.settings.created": "Created",
60
+ "workspace.settings.services": "Services",
61
+ "workspace.settings.loading": "Loading...",
62
+ "workspace.invitations.description": "Invite users to your workspace to collaborate.",
63
+ "workspace.invitations.invite": "Invite user",
64
+ "workspace.invitations.empty": "No invitations",
65
+ "workspace.invite.title": "Invite user",
66
+ "workspace.invite.description": "Invite a user to manage and contribute content to this workspace",
67
+ "workspace.invite.emailPlaceholder": "Email address",
68
+ "workspace.invite.submit": "Send invite",
69
+ "workspace.invite.successTitle": "Success",
70
+ "workspace.invite.successBody": "We sent them an invitation over email. When they have accepted they will show up in the list of users.",
71
+ "workspace.invite.error": "Something went wrong, try again in a couple of minutes"
72
+ }
@@ -1,28 +1 @@
1
- import { Aggregate } from '@ossy/event-store'
2
- import { Workspace, WorkspacesEvents } from '@ossy/workspaces'
3
-
4
- export const id = 'workspaces/enable-service'
5
- export const access = 'workspace'
6
-
7
- const AVAILABLE_SERVICES = [
8
- '@ossy/tasks/visual-content-descriptors',
9
- '@ossy/tasks/resize-common-web',
10
- '@ossy/resumes',
11
- '@ossy/consultancy',
12
- '@ossy/apps',
13
- '@ossy/domains',
14
- ]
15
-
16
- export async function run({ payload, req }) {
17
- const createdBy = payload?.userId ?? req?.userId
18
- const workspaceId = payload?.workspaceId ?? req?.workspaceId
19
- const service = payload?.service ?? payload
20
-
21
- if (!AVAILABLE_SERVICES.includes(service)) {
22
- throw Object.assign(new Error(`Service ${service} is not available`), { status: 400 })
23
- }
24
-
25
- const event = WorkspacesEvents.ServiceEnabled({ createdBy, service })
26
- await Aggregate.Of(Workspace, workspaceId).then(Aggregate.Add(event))
27
- return null
28
- }
1
+ export const metadata = { id: 'workspaces/enable-service', access: 'workspace' }
@@ -0,0 +1,27 @@
1
+ import { Aggregate } from '@ossy/event-store'
2
+ import { Workspace, WorkspacesEvents } from '@ossy/workspaces/server'
3
+
4
+ export const metadata = { id: 'workspaces/enable-service' }
5
+
6
+ const AVAILABLE_SERVICES = [
7
+ '@ossy/tasks/visual-content-descriptors',
8
+ '@ossy/tasks/resize-common-web',
9
+ '@ossy/resumes',
10
+ '@ossy/consultancy',
11
+ '@ossy/apps',
12
+ '@ossy/domains',
13
+ ]
14
+
15
+ export async function run({ payload, req }) {
16
+ const createdBy = payload?.userId ?? req?.userId
17
+ const workspaceId = payload?.workspaceId ?? req?.workspaceId
18
+ const service = payload?.service ?? payload
19
+
20
+ if (!AVAILABLE_SERVICES.includes(service)) {
21
+ throw Object.assign(new Error(`Service ${service} is not available`), { status: 400 })
22
+ }
23
+
24
+ const event = WorkspacesEvents.ServiceEnabled({ createdBy, service })
25
+ await Aggregate.Of(Workspace, workspaceId).then(Aggregate.Add(event))
26
+ return null
27
+ }
@@ -1,11 +1 @@
1
- import { Aggregate } from '@ossy/event-store'
2
- import { Workspace } from '@ossy/workspaces'
3
-
4
- export const id = 'workspaces/get-api-tokens'
5
- export const access = 'workspace'
6
-
7
- export async function run({ payload, req }) {
8
- const workspaceId = payload?.workspaceId ?? req?.workspaceId
9
- const workspace = await Aggregate.Of(Workspace, workspaceId).then(Aggregate.View())
10
- return workspace.apiTokens
11
- }
1
+ export const metadata = { id: 'workspaces/get-api-tokens', access: 'workspace' }
@@ -0,0 +1,10 @@
1
+ import { Aggregate } from '@ossy/event-store'
2
+ import { Workspace } from '@ossy/workspaces/server'
3
+
4
+ export const metadata = { id: 'workspaces/get-api-tokens' }
5
+
6
+ export async function run({ payload, req }) {
7
+ const workspaceId = payload?.workspaceId ?? req?.workspaceId
8
+ const workspace = await Aggregate.Of(Workspace, workspaceId).then(Aggregate.View())
9
+ return workspace.apiTokens
10
+ }
@@ -1,11 +1 @@
1
- import { Aggregate } from '@ossy/event-store'
2
- import { Workspace } from '@ossy/workspaces'
3
-
4
- export const id = 'workspaces/get-invitations'
5
- export const access = 'workspace'
6
-
7
- export async function run({ payload, req }) {
8
- const workspaceId = payload?.workspaceId ?? req?.workspaceId
9
- const workspace = await Aggregate.Of(Workspace, workspaceId).then(Aggregate.View())
10
- return workspace.invitations
11
- }
1
+ export const metadata = { id: 'workspaces/get-invitations', access: 'workspace' }
@@ -0,0 +1,10 @@
1
+ import { Aggregate } from '@ossy/event-store'
2
+ import { Workspace } from '@ossy/workspaces/server'
3
+
4
+ export const metadata = { id: 'workspaces/get-invitations' }
5
+
6
+ export async function run({ payload, req }) {
7
+ const workspaceId = payload?.workspaceId ?? req?.workspaceId
8
+ const workspace = await Aggregate.Of(Workspace, workspaceId).then(Aggregate.View())
9
+ return workspace.invitations
10
+ }
@@ -1,19 +1 @@
1
- import { Aggregate } from '@ossy/event-store'
2
- import { Workspace } from '@ossy/workspaces'
3
- import { getSystemResourceTemplates } from '@ossy/platform'
4
-
5
- export const id = 'workspaces/get-resource-templates'
6
- export const access = 'workspace'
7
-
8
- export async function run({ payload, req }) {
9
- const workspaceId = payload?.workspaceId ?? req?.workspaceId
10
-
11
- const workspace = await Aggregate.Of(Workspace, workspaceId).then(Aggregate.View())
12
- const systemTemplates = getSystemResourceTemplates()
13
- const workspaceTemplates = workspace.resourceTemplates || []
14
- const workspaceIds = new Set(workspaceTemplates.map(t => t.id))
15
- return [
16
- ...systemTemplates.filter(t => !workspaceIds.has(t.id)),
17
- ...workspaceTemplates,
18
- ]
19
- }
1
+ export const metadata = { id: 'workspaces/get-resource-templates', access: 'workspace' }
@@ -0,0 +1,18 @@
1
+ import { Aggregate } from '@ossy/event-store'
2
+ import { Workspace } from '@ossy/workspaces/server'
3
+ import { getSystemResourceTemplates } from '@ossy/platform'
4
+
5
+ export const metadata = { id: 'workspaces/get-resource-templates' }
6
+
7
+ export async function run({ payload, req }) {
8
+ const workspaceId = payload?.workspaceId ?? req?.workspaceId
9
+
10
+ const workspace = await Aggregate.Of(Workspace, workspaceId).then(Aggregate.View())
11
+ const systemTemplates = getSystemResourceTemplates()
12
+ const workspaceTemplates = workspace.resourceTemplates || []
13
+ const workspaceIds = new Set(workspaceTemplates.map(t => t.id))
14
+ return [
15
+ ...systemTemplates.filter(t => !workspaceIds.has(t.id)),
16
+ ...workspaceTemplates,
17
+ ]
18
+ }
@@ -1,14 +1 @@
1
- import { Aggregate } from '@ossy/event-store'
2
- import { Workspace } from '@ossy/workspaces'
3
- import { User } from '@ossy/users'
4
-
5
- export const id = 'workspaces/get-users'
6
- export const access = 'workspace'
7
-
8
- export async function run({ payload, req }) {
9
- const workspaceId = payload?.workspaceId ?? req?.workspaceId
10
- const workspace = await Aggregate.Of(Workspace, workspaceId).then(Aggregate.View())
11
- return Promise.all(
12
- workspace.users.map(userId => Aggregate.Of(User, userId).then(Aggregate.View(User.UserForWorkspace)))
13
- )
14
- }
1
+ export const metadata = { id: 'workspaces/get-users', access: 'workspace' }
@@ -0,0 +1,13 @@
1
+ import { Aggregate } from '@ossy/event-store'
2
+ import { Workspace } from '@ossy/workspaces/server'
3
+ import { User } from '@ossy/users/server'
4
+
5
+ export const metadata = { id: 'workspaces/get-users' }
6
+
7
+ export async function run({ payload, req }) {
8
+ const workspaceId = payload?.workspaceId ?? req?.workspaceId
9
+ const workspace = await Aggregate.Of(Workspace, workspaceId).then(Aggregate.View())
10
+ return Promise.all(
11
+ workspace.users.map(userId => Aggregate.Of(User, userId).then(Aggregate.View(User.UserForWorkspace)))
12
+ )
13
+ }
package/src/get.action.js CHANGED
@@ -1,14 +1 @@
1
- import { Aggregate } from '@ossy/event-store'
2
- import { Workspace } from '@ossy/workspaces'
3
-
4
- export const id = 'workspaces/get'
5
- export const access = 'workspace'
6
-
7
- export async function run({ payload, req }) {
8
- const workspaceId = payload?.workspaceId ?? req?.workspaceId
9
- if (!workspaceId) throw Object.assign(new Error('workspaceId is required'), { status: 404 })
10
-
11
- const workspace = await Aggregate.Of(Workspace, workspaceId).then(Aggregate.View())
12
- if (!workspace?.id) throw Object.assign(new Error('Workspace not found'), { status: 404 })
13
- return workspace
14
- }
1
+ export const metadata = { id: 'workspaces/get', access: 'workspace' }
@@ -0,0 +1,13 @@
1
+ import { Aggregate } from '@ossy/event-store'
2
+ import { Workspace } from '@ossy/workspaces/server'
3
+
4
+ export const metadata = { id: 'workspaces/get' }
5
+
6
+ export async function run({ payload, req }) {
7
+ const workspaceId = payload?.workspaceId ?? req?.workspaceId
8
+ if (!workspaceId) throw Object.assign(new Error('workspaceId is required'), { status: 404 })
9
+
10
+ const workspace = await Aggregate.Of(Workspace, workspaceId).then(Aggregate.View())
11
+ if (!workspace?.id) throw Object.assign(new Error('Workspace not found'), { status: 404 })
12
+ return workspace
13
+ }
@@ -1,27 +1 @@
1
- import { Aggregate } from '@ossy/event-store'
2
- import { Workspace, WorkspacesEvents } from '@ossy/workspaces'
3
- import { validateResourceTemplatesForImport } from '@ossy/platform'
4
-
5
- export const id = 'workspaces/import-resource-templates'
6
- export const access = 'workspace'
7
-
8
- export async function run({ payload, req }) {
9
- const userId = payload?.userId ?? req?.userId
10
- const workspaceId = payload?.workspaceId ?? req?.workspaceId
11
- const templates = payload?.templates ?? payload
12
-
13
- if (!Array.isArray(templates)) {
14
- throw Object.assign(new Error('templates must be an array'), { status: 400 })
15
- }
16
-
17
- const reservedIds = new Set([])
18
- const validation = validateResourceTemplatesForImport(templates, reservedIds)
19
- if (!validation.ok) {
20
- throw Object.assign(new Error(validation.message), { status: 400, type: validation.code })
21
- }
22
-
23
- const event = WorkspacesEvents.ResourceTemplatesImported({ createdBy: userId, templates })
24
-
25
- await Aggregate.Of(Workspace, workspaceId).then(Aggregate.Add(event))
26
- return event.payload.templates
27
- }
1
+ export const metadata = { id: 'workspaces/import-resource-templates', access: 'workspace' }