Quellcode durchsuchen

chore: remove workspaces from code base

Karol Sójko vor 2 Jahren
Ursprung
Commit
deec29c1b4
100 geänderte Dateien mit 0 neuen und 3706 gelöschten Zeilen
  1. 0 5
      .github/dependabot.yml
  2. 0 47
      .github/workflows/workspace.yml
  3. 0 1
      docker/docker-entrypoint.sh
  4. 0 14
      docker/localstack_bootstrap.sh
  5. 0 1
      packages/api-gateway/.env.sample
  6. 0 1
      packages/api-gateway/bin/server.ts
  7. 0 1
      packages/api-gateway/src/Bootstrap/Container.ts
  8. 0 1
      packages/api-gateway/src/Bootstrap/Types.ts
  9. 0 23
      packages/api-gateway/src/Controller/v1/InvitesController.ts
  10. 0 53
      packages/api-gateway/src/Controller/v1/WorkspacesController.ts
  11. 0 16
      packages/api-gateway/src/Service/Http/HttpService.ts
  12. 0 6
      packages/api-gateway/src/Service/Http/HttpServiceInterface.ts
  13. 0 1
      packages/common/src/Domain/Email/EmailMessageIdentifier.ts
  14. 0 6
      packages/common/src/Domain/Workspace/WorkspaceAccessLevel.ts
  15. 0 5
      packages/common/src/Domain/Workspace/WorkspaceType.ts
  16. 0 4
      packages/common/src/Domain/Workspace/WorkspaceUserStatus.ts
  17. 0 3
      packages/common/src/Domain/index.ts
  18. 0 1
      packages/domain-events/src/Domain/Event/DomainEventService.ts
  19. 0 7
      packages/domain-events/src/Domain/Event/WorkspaceInviteAcceptedEvent.ts
  20. 0 5
      packages/domain-events/src/Domain/Event/WorkspaceInviteAcceptedEventPayload.ts
  21. 0 2
      packages/domain-events/src/Domain/index.ts
  22. 0 32
      packages/workspace/.env.sample
  23. 0 3
      packages/workspace/.eslintignore
  24. 0 6
      packages/workspace/.eslintrc
  25. 0 558
      packages/workspace/CHANGELOG.md
  26. 0 17
      packages/workspace/Dockerfile
  27. 0 71
      packages/workspace/bin/server.ts
  28. 0 25
      packages/workspace/bin/worker.ts
  29. 0 11
      packages/workspace/docker/entrypoint-server.js
  30. 0 11
      packages/workspace/docker/entrypoint-worker.js
  31. 0 22
      packages/workspace/docker/entrypoint.sh
  32. 0 12
      packages/workspace/jest.config.js
  33. 0 4
      packages/workspace/linter.tsconfig.json
  34. 0 20
      packages/workspace/migrations/1665049971623-initial.ts
  35. 0 17
      packages/workspace/migrations/1665389240189-rename-private-key.ts
  36. 0 19
      packages/workspace/migrations/1665390489236-optional-keys.ts
  37. 0 27
      packages/workspace/migrations/1665394559520-add-invites.ts
  38. 0 13
      packages/workspace/migrations/1665480537103-add-user-display-name.ts
  39. 0 13
      packages/workspace/migrations/1665481699781-add-invite-access-level.ts
  40. 0 15
      packages/workspace/migrations/1665580464598-add-workspace-user-foreign-key.ts
  41. 0 62
      packages/workspace/package.json
  42. 0 195
      packages/workspace/src/Bootstrap/Container.ts
  43. 0 53
      packages/workspace/src/Bootstrap/DataSource.ts
  44. 0 24
      packages/workspace/src/Bootstrap/Env.ts
  45. 0 48
      packages/workspace/src/Bootstrap/Types.ts
  46. 0 99
      packages/workspace/src/Controller/ApiGatewayAuthMiddleware.spec.ts
  47. 0 59
      packages/workspace/src/Controller/ApiGatewayAuthMiddleware.ts
  48. 0 204
      packages/workspace/src/Controller/WorkspacesController.spec.ts
  49. 0 170
      packages/workspace/src/Controller/WorkspacesController.ts
  50. 0 9
      packages/workspace/src/Domain/Email/WorkspaceInviteCreated.ts
  51. 0 11
      packages/workspace/src/Domain/Email/workspace-invite-created.html.ts
  52. 0 72
      packages/workspace/src/Domain/Event/DomainEventFactory.ts
  53. 0 22
      packages/workspace/src/Domain/Event/DomainEventFactoryInterface.ts
  54. 0 44
      packages/workspace/src/Domain/Handler/UserRegisteredEventHandler.spec.ts
  55. 0 22
      packages/workspace/src/Domain/Handler/UserRegisteredEventHandler.ts
  56. 0 76
      packages/workspace/src/Domain/Invite/WorkspaceInvite.ts
  57. 0 6
      packages/workspace/src/Domain/Invite/WorkspaceInviteRepositoryInterface.ts
  58. 0 4
      packages/workspace/src/Domain/Invite/WorkspaceInviteStatus.ts
  59. 0 3
      packages/workspace/src/Domain/Projection/ProjectorInterface.ts
  60. 0 3
      packages/workspace/src/Domain/Projection/WorkspaceProjection.ts
  61. 0 30
      packages/workspace/src/Domain/Projection/WorkspaceProjector.spec.ts
  62. 0 19
      packages/workspace/src/Domain/Projection/WorkspaceProjector.ts
  63. 0 3
      packages/workspace/src/Domain/Projection/WorkspaceUserProjection.ts
  64. 0 42
      packages/workspace/src/Domain/Projection/WorkspaceUserProjector.spec.ts
  65. 0 25
      packages/workspace/src/Domain/Projection/WorkspaceUserProjector.ts
  66. 0 106
      packages/workspace/src/Domain/UseCase/AcceptInvitation/AcceptInvitation.spec.ts
  67. 0 72
      packages/workspace/src/Domain/UseCase/AcceptInvitation/AcceptInvitation.ts
  68. 0 6
      packages/workspace/src/Domain/UseCase/AcceptInvitation/AcceptInvitationDTO.ts
  69. 0 3
      packages/workspace/src/Domain/UseCase/AcceptInvitation/AcceptInvitationResponse.ts
  70. 0 83
      packages/workspace/src/Domain/UseCase/CreateWorkspace/CreateWorkspace.spec.ts
  71. 0 56
      packages/workspace/src/Domain/UseCase/CreateWorkspace/CreateWorkspace.ts
  72. 0 10
      packages/workspace/src/Domain/UseCase/CreateWorkspace/CreateWorkspaceDTO.ts
  73. 0 5
      packages/workspace/src/Domain/UseCase/CreateWorkspace/CreateWorkspaceResponse.ts
  74. 0 100
      packages/workspace/src/Domain/UseCase/InitiateKeyShare/InitiateKeyShare.spec.ts
  75. 0 52
      packages/workspace/src/Domain/UseCase/InitiateKeyShare/InitiateKeyShare.ts
  76. 0 6
      packages/workspace/src/Domain/UseCase/InitiateKeyShare/InitiateKeyShareDTO.ts
  77. 0 3
      packages/workspace/src/Domain/UseCase/InitiateKeyShare/InitiateKeyShareResponse.ts
  78. 0 72
      packages/workspace/src/Domain/UseCase/InviteToWorkspace/InviteToWorkspace.spec.ts
  79. 0 54
      packages/workspace/src/Domain/UseCase/InviteToWorkspace/InviteToWorkspace.ts
  80. 0 8
      packages/workspace/src/Domain/UseCase/InviteToWorkspace/InviteToWorkspaceDTO.ts
  81. 0 5
      packages/workspace/src/Domain/UseCase/InviteToWorkspace/InviteToWorkspaceResponse.ts
  82. 0 84
      packages/workspace/src/Domain/UseCase/ListWorkspaceUsers/ListWorkspaceUsers.spec.ts
  83. 0 50
      packages/workspace/src/Domain/UseCase/ListWorkspaceUsers/ListWorkspaceUsers.ts
  84. 0 4
      packages/workspace/src/Domain/UseCase/ListWorkspaceUsers/ListWorkspaceUsersDTO.ts
  85. 0 6
      packages/workspace/src/Domain/UseCase/ListWorkspaceUsers/ListWorkspaceUsersResponse.ts
  86. 0 66
      packages/workspace/src/Domain/UseCase/ListWorkspaces/ListWorkspaces.spec.ts
  87. 0 54
      packages/workspace/src/Domain/UseCase/ListWorkspaces/ListWorkspaces.ts
  88. 0 3
      packages/workspace/src/Domain/UseCase/ListWorkspaces/ListWorkspacesDTO.ts
  89. 0 6
      packages/workspace/src/Domain/UseCase/ListWorkspaces/ListWorkspacesResponse.ts
  90. 0 3
      packages/workspace/src/Domain/UseCase/UseCaseInterface.ts
  91. 0 56
      packages/workspace/src/Domain/Workspace/Workspace.ts
  92. 0 7
      packages/workspace/src/Domain/Workspace/WorkspaceRepositoryInterface.ts
  93. 0 98
      packages/workspace/src/Domain/Workspace/WorkspaceUser.ts
  94. 0 8
      packages/workspace/src/Domain/Workspace/WorkspaceUserRepositoryInterface.ts
  95. 0 9
      packages/workspace/src/Infra/InversifyExpressUtils/InversifyExpressHealthCheckController.ts
  96. 0 23
      packages/workspace/src/Infra/InversifyExpressUtils/InversifyExpressInvitesController.ts
  97. 0 74
      packages/workspace/src/Infra/InversifyExpressUtils/InversifyExpressWorkspacesController.ts
  98. 0 39
      packages/workspace/src/Infra/MySQL/MySQLWorkspaceInviteRepository.spec.ts
  99. 0 22
      packages/workspace/src/Infra/MySQL/MySQLWorkspaceInviteRepository.ts
  100. 0 49
      packages/workspace/src/Infra/MySQL/MySQLWorkspaceRepository.spec.ts

+ 0 - 5
.github/dependabot.yml

@@ -95,11 +95,6 @@ updates:
     schedule:
     schedule:
       interval: "daily"
       interval: "daily"
 
 
-  - package-ecosystem: "npm"
-    directory: "/packages/workspace"
-    schedule:
-      interval: "daily"
-
   - package-ecosystem: "github-actions"
   - package-ecosystem: "github-actions"
     directory: "/"
     directory: "/"
     schedule:
     schedule:

+ 0 - 47
.github/workflows/workspace.yml

@@ -1,47 +0,0 @@
-name: Workspace Server
-
-concurrency:
-  group: workspace
-  cancel-in-progress: true
-
-on:
-  push:
-    tags:
-      - '*standardnotes/workspace-server*'
-  workflow_dispatch:
-
-jobs:
-  call_server_application_workflow:
-    name: Server Application
-    uses: standardnotes/server/.github/workflows/common-server-application.yml@main
-    with:
-      service_name: workspace
-      workspace_name: "@standardnotes/workspace-server"
-      package_path: packages/workspace
-    secrets: inherit
-
-  newrelic:
-    needs: call_server_application_workflow
-
-    runs-on: ubuntu-latest
-    steps:
-
-      - name: Create New Relic deployment marker for Web
-        uses: newrelic/deployment-marker-action@v1
-        with:
-          accountId: ${{ secrets.NEW_RELIC_ACCOUNT_ID }}
-          apiKey: ${{ secrets.NEW_RELIC_API_KEY }}
-          applicationId: ${{ secrets.NEW_RELIC_APPLICATION_ID_WORKSPACE_WEB_PROD }}
-          revision: "${{ github.sha }}"
-          description: "Automated Deployment via Github Actions"
-          user: "${{ github.actor }}"
-
-      - name: Create New Relic deployment marker for Worker
-        uses: newrelic/deployment-marker-action@v1
-        with:
-          accountId: ${{ secrets.NEW_RELIC_ACCOUNT_ID }}
-          apiKey: ${{ secrets.NEW_RELIC_API_KEY }}
-          applicationId: ${{ secrets.NEW_RELIC_APPLICATION_ID_WORKSPACE_WORKER_PROD }}
-          revision: "${{ github.sha }}"
-          description: "Automated Deployment via Github Actions"
-          user: "${{ github.actor }}"

+ 0 - 1
docker/docker-entrypoint.sh

@@ -349,7 +349,6 @@ export API_GATEWAY_NEW_RELIC_NO_CONFIG_FILE=true
 
 
 export API_GATEWAY_SYNCING_SERVER_JS_URL=http://localhost:$SYNCING_SERVER_PORT
 export API_GATEWAY_SYNCING_SERVER_JS_URL=http://localhost:$SYNCING_SERVER_PORT
 export API_GATEWAY_AUTH_SERVER_URL=http://localhost:$AUTH_SERVER_PORT
 export API_GATEWAY_AUTH_SERVER_URL=http://localhost:$AUTH_SERVER_PORT
-export API_GATEWAY_WORKSPACE_SERVER_URL=http://localhost:3004
 export API_GATEWAY_REVISIONS_SERVER_URL=http://localhost:3005
 export API_GATEWAY_REVISIONS_SERVER_URL=http://localhost:3005
 if [ -z "$PUBLIC_FILES_SERVER_URL" ]; then
 if [ -z "$PUBLIC_FILES_SERVER_URL" ]; then
   export PUBLIC_FILES_SERVER_URL=http://localhost:3125
   export PUBLIC_FILES_SERVER_URL=http://localhost:3125

+ 0 - 14
docker/localstack_bootstrap.sh

@@ -91,13 +91,6 @@ TOPIC_CREATED_RESULT=$(create_topic ${SCHEDULER_TOPIC_NAME})
 echo "created topic: $TOPIC_CREATED_RESULT"
 echo "created topic: $TOPIC_CREATED_RESULT"
 SCHEDULER_TOPIC_ARN=$(get_topic_arn_from_name $SCHEDULER_TOPIC_NAME)
 SCHEDULER_TOPIC_ARN=$(get_topic_arn_from_name $SCHEDULER_TOPIC_NAME)
 
 
-WORKSPACE_TOPIC_NAME="workspace-local-topic"
-
-echo "creating topic $WORKSPACE_TOPIC_NAME"
-TOPIC_CREATED_RESULT=$(create_topic ${WORKSPACE_TOPIC_NAME})
-echo "created topic: $TOPIC_CREATED_RESULT"
-WORKSPACE_TOPIC_ARN=$(get_topic_arn_from_name $WORKSPACE_TOPIC_NAME)
-
 QUEUE_NAME="analytics-local-queue"
 QUEUE_NAME="analytics-local-queue"
 
 
 echo "creating queue $QUEUE_NAME"
 echo "creating queue $QUEUE_NAME"
@@ -182,13 +175,6 @@ QUEUE_URL=$(create_queue ${QUEUE_NAME})
 echo "created queue: $QUEUE_URL"
 echo "created queue: $QUEUE_URL"
 SCHEDULER_QUEUE_ARN=$(get_queue_arn_from_name $QUEUE_NAME)
 SCHEDULER_QUEUE_ARN=$(get_queue_arn_from_name $QUEUE_NAME)
 
 
-QUEUE_NAME="workspace-local-queue"
-
-echo "creating queue $QUEUE_NAME"
-QUEUE_URL=$(create_queue ${QUEUE_NAME})
-echo "created queue: $QUEUE_URL"
-WORKSPACE_QUEUE_ARN=$(get_queue_arn_from_name $QUEUE_NAME)
-
 echo "all topics are:"
 echo "all topics are:"
 echo "$(get_all_topics)"
 echo "$(get_all_topics)"
 
 

+ 0 - 1
packages/api-gateway/.env.sample

@@ -6,7 +6,6 @@ PORT=3000
 
 
 SYNCING_SERVER_JS_URL=http://syncing_server_js:3000
 SYNCING_SERVER_JS_URL=http://syncing_server_js:3000
 AUTH_SERVER_URL=http://auth:3000
 AUTH_SERVER_URL=http://auth:3000
-WORKSPACE_SERVER_URL=http://workspace:3000
 WEB_SOCKET_SERVER_URL=http://websockets:3000
 WEB_SOCKET_SERVER_URL=http://websockets:3000
 PAYMENTS_SERVER_URL=http://payments:3000
 PAYMENTS_SERVER_URL=http://payments:3000
 FILES_SERVER_URL=http://files:3000
 FILES_SERVER_URL=http://files:3000

+ 0 - 1
packages/api-gateway/bin/server.ts

@@ -19,7 +19,6 @@ import '../src/Controller/v1/TokensController'
 import '../src/Controller/v1/OfflineController'
 import '../src/Controller/v1/OfflineController'
 import '../src/Controller/v1/FilesController'
 import '../src/Controller/v1/FilesController'
 import '../src/Controller/v1/SubscriptionInvitesController'
 import '../src/Controller/v1/SubscriptionInvitesController'
-import '../src/Controller/v1/WorkspacesController'
 import '../src/Controller/v1/InvitesController'
 import '../src/Controller/v1/InvitesController'
 import '../src/Controller/v1/AuthenticatorsController'
 import '../src/Controller/v1/AuthenticatorsController'
 import '../src/Controller/v1/ProxyController'
 import '../src/Controller/v1/ProxyController'

+ 0 - 1
packages/api-gateway/src/Bootstrap/Container.ts

@@ -59,7 +59,6 @@ export class ContainerConfigLoader {
     container.bind(TYPES.PAYMENTS_SERVER_URL).toConstantValue(env.get('PAYMENTS_SERVER_URL', true))
     container.bind(TYPES.PAYMENTS_SERVER_URL).toConstantValue(env.get('PAYMENTS_SERVER_URL', true))
     container.bind(TYPES.FILES_SERVER_URL).toConstantValue(env.get('FILES_SERVER_URL', true))
     container.bind(TYPES.FILES_SERVER_URL).toConstantValue(env.get('FILES_SERVER_URL', true))
     container.bind(TYPES.AUTH_JWT_SECRET).toConstantValue(env.get('AUTH_JWT_SECRET'))
     container.bind(TYPES.AUTH_JWT_SECRET).toConstantValue(env.get('AUTH_JWT_SECRET'))
-    container.bind(TYPES.WORKSPACE_SERVER_URL).toConstantValue(env.get('WORKSPACE_SERVER_URL', true))
     container.bind(TYPES.WEB_SOCKET_SERVER_URL).toConstantValue(env.get('WEB_SOCKET_SERVER_URL', true))
     container.bind(TYPES.WEB_SOCKET_SERVER_URL).toConstantValue(env.get('WEB_SOCKET_SERVER_URL', true))
     container.bind(TYPES.PROXY_SERVER_URL).toConstantValue(env.get('PROXY_SERVER_URL', true))
     container.bind(TYPES.PROXY_SERVER_URL).toConstantValue(env.get('PROXY_SERVER_URL', true))
     container
     container

+ 0 - 1
packages/api-gateway/src/Bootstrap/Types.ts

@@ -9,7 +9,6 @@ const TYPES = {
   FILES_SERVER_URL: Symbol.for('FILES_SERVER_URL'),
   FILES_SERVER_URL: Symbol.for('FILES_SERVER_URL'),
   REVISIONS_SERVER_URL: Symbol.for('REVISIONS_SERVER_URL'),
   REVISIONS_SERVER_URL: Symbol.for('REVISIONS_SERVER_URL'),
   EMAIL_SERVER_URL: Symbol.for('EMAIL_SERVER_URL'),
   EMAIL_SERVER_URL: Symbol.for('EMAIL_SERVER_URL'),
-  WORKSPACE_SERVER_URL: Symbol.for('WORKSPACE_SERVER_URL'),
   WEB_SOCKET_SERVER_URL: Symbol.for('WEB_SOCKET_SERVER_URL'),
   WEB_SOCKET_SERVER_URL: Symbol.for('WEB_SOCKET_SERVER_URL'),
   PROXY_SERVER_URL: Symbol.for('PROXY_SERVER_URL'),
   PROXY_SERVER_URL: Symbol.for('PROXY_SERVER_URL'),
   AUTH_JWT_SECRET: Symbol.for('AUTH_JWT_SECRET'),
   AUTH_JWT_SECRET: Symbol.for('AUTH_JWT_SECRET'),

+ 0 - 23
packages/api-gateway/src/Controller/v1/InvitesController.ts

@@ -1,23 +0,0 @@
-import { inject } from 'inversify'
-import { Request, Response } from 'express'
-import { controller, BaseHttpController, httpPost } from 'inversify-express-utils'
-
-import TYPES from '../../Bootstrap/Types'
-import { HttpServiceInterface } from '../../Service/Http/HttpServiceInterface'
-
-@controller('/v1/invites', TYPES.AuthMiddleware)
-export class InvitesController extends BaseHttpController {
-  constructor(@inject(TYPES.HTTPService) private httpService: HttpServiceInterface) {
-    super()
-  }
-
-  @httpPost('/:inviteUuid/accept')
-  async accept(request: Request, response: Response): Promise<void> {
-    await this.httpService.callWorkspaceServer(
-      request,
-      response,
-      `invites/${request.params.inviteUuid}/accept`,
-      request.body,
-    )
-  }
-}

+ 0 - 53
packages/api-gateway/src/Controller/v1/WorkspacesController.ts

@@ -1,53 +0,0 @@
-import { inject } from 'inversify'
-import { Request, Response } from 'express'
-import { controller, BaseHttpController, httpPost, httpGet } from 'inversify-express-utils'
-
-import TYPES from '../../Bootstrap/Types'
-import { HttpServiceInterface } from '../../Service/Http/HttpServiceInterface'
-
-@controller('/v1/workspaces', TYPES.AuthMiddleware)
-export class WorkspacesController extends BaseHttpController {
-  constructor(@inject(TYPES.HTTPService) private httpService: HttpServiceInterface) {
-    super()
-  }
-
-  @httpPost('/')
-  async create(request: Request, response: Response): Promise<void> {
-    await this.httpService.callWorkspaceServer(request, response, 'workspaces', request.body)
-  }
-
-  @httpGet('/:workspaceUuid/users')
-  async listWorkspaceUsers(request: Request, response: Response): Promise<void> {
-    await this.httpService.callWorkspaceServer(
-      request,
-      response,
-      `workspaces/${request.params.workspaceUuid}/users`,
-      request.body,
-    )
-  }
-
-  @httpPost('/:workspaceUuid/users/:userUuid/keyshare')
-  async initiateKeyshare(request: Request, response: Response): Promise<void> {
-    await this.httpService.callWorkspaceServer(
-      request,
-      response,
-      `workspaces/${request.params.workspaceUuid}/users/${request.params.userUuid}/keyshare`,
-      request.body,
-    )
-  }
-
-  @httpGet('/')
-  async listWorkspaces(request: Request, response: Response): Promise<void> {
-    await this.httpService.callWorkspaceServer(request, response, 'workspaces', request.body)
-  }
-
-  @httpPost('/:workspaceUuid/invites')
-  async invite(request: Request, response: Response): Promise<void> {
-    await this.httpService.callWorkspaceServer(
-      request,
-      response,
-      `workspaces/${request.params.workspaceUuid}/invites`,
-      request.body,
-    )
-  }
-}

+ 0 - 16
packages/api-gateway/src/Service/Http/HttpService.ts

@@ -16,7 +16,6 @@ export class HttpService implements HttpServiceInterface {
     @inject(TYPES.SYNCING_SERVER_JS_URL) private syncingServerJsUrl: string,
     @inject(TYPES.SYNCING_SERVER_JS_URL) private syncingServerJsUrl: string,
     @inject(TYPES.PAYMENTS_SERVER_URL) private paymentsServerUrl: string,
     @inject(TYPES.PAYMENTS_SERVER_URL) private paymentsServerUrl: string,
     @inject(TYPES.FILES_SERVER_URL) private filesServerUrl: string,
     @inject(TYPES.FILES_SERVER_URL) private filesServerUrl: string,
-    @inject(TYPES.WORKSPACE_SERVER_URL) private workspaceServerUrl: string,
     @inject(TYPES.WEB_SOCKET_SERVER_URL) private webSocketServerUrl: string,
     @inject(TYPES.WEB_SOCKET_SERVER_URL) private webSocketServerUrl: string,
     @inject(TYPES.REVISIONS_SERVER_URL) private revisionsServerUrl: string,
     @inject(TYPES.REVISIONS_SERVER_URL) private revisionsServerUrl: string,
     @inject(TYPES.EMAIL_SERVER_URL) private emailServerUrl: string,
     @inject(TYPES.EMAIL_SERVER_URL) private emailServerUrl: string,
@@ -82,21 +81,6 @@ export class HttpService implements HttpServiceInterface {
     await this.callServer(this.emailServerUrl, request, response, endpoint, payload)
     await this.callServer(this.emailServerUrl, request, response, endpoint, payload)
   }
   }
 
 
-  async callWorkspaceServer(
-    request: Request,
-    response: Response,
-    endpoint: string,
-    payload?: Record<string, unknown> | string,
-  ): Promise<void> {
-    if (!this.workspaceServerUrl) {
-      response.status(400).send({ message: 'Workspace Server not configured' })
-
-      return
-    }
-
-    await this.callServer(this.workspaceServerUrl, request, response, endpoint, payload)
-  }
-
   async callWebSocketServer(
   async callWebSocketServer(
     request: Request,
     request: Request,
     response: Response,
     response: Response,

+ 0 - 6
packages/api-gateway/src/Service/Http/HttpServiceInterface.ts

@@ -43,12 +43,6 @@ export interface HttpServiceInterface {
     endpoint: string,
     endpoint: string,
     payload?: Record<string, unknown> | string,
     payload?: Record<string, unknown> | string,
   ): Promise<void>
   ): Promise<void>
-  callWorkspaceServer(
-    request: Request,
-    response: Response,
-    endpoint: string,
-    payload?: Record<string, unknown> | string,
-  ): Promise<void>
   callWebSocketServer(
   callWebSocketServer(
     request: Request,
     request: Request,
     response: Response,
     response: Response,

+ 0 - 1
packages/common/src/Domain/Email/EmailMessageIdentifier.ts

@@ -26,7 +26,6 @@ export enum EmailMessageIdentifier {
   REFUND_NOTICE = 'REFUND_NOTICE',
   REFUND_NOTICE = 'REFUND_NOTICE',
   REFUND_REQUESTED = 'REFUND_REQUESTED',
   REFUND_REQUESTED = 'REFUND_REQUESTED',
   RATE_ADJUSTMENT_NOTICE = 'RATE_ADJUSTMENT_NOTICE',
   RATE_ADJUSTMENT_NOTICE = 'RATE_ADJUSTMENT_NOTICE',
-  WORKSPACE_INVITE_CREATED = 'WORKSPACE_INVITE_CREATED',
   EXIT_DISCOUNT = 'EXIT_DISCOUNT',
   EXIT_DISCOUNT = 'EXIT_DISCOUNT',
   SUBSCRIPTION_CANCELLED = 'SUBSCRIPTION_CANCELLED',
   SUBSCRIPTION_CANCELLED = 'SUBSCRIPTION_CANCELLED',
 }
 }

+ 0 - 6
packages/common/src/Domain/Workspace/WorkspaceAccessLevel.ts

@@ -1,6 +0,0 @@
-export enum WorkspaceAccessLevel {
-  Owner = 'owner',
-  Admin = 'admin',
-  ReadOnly = 'read-only',
-  WriteAndRead = 'write-and-read',
-}

+ 0 - 5
packages/common/src/Domain/Workspace/WorkspaceType.ts

@@ -1,5 +0,0 @@
-export enum WorkspaceType {
-  Root = 'root',
-  Team = 'team',
-  Private = 'private',
-}

+ 0 - 4
packages/common/src/Domain/Workspace/WorkspaceUserStatus.ts

@@ -1,4 +0,0 @@
-export enum WorkspaceUserStatus {
-  Active = 'active',
-  PendingKeyshare = 'pending-keyshare',
-}

+ 0 - 3
packages/common/src/Domain/index.ts

@@ -20,6 +20,3 @@ export * from './Subscription/SubscriptionName'
 export * from './Type/Either'
 export * from './Type/Either'
 export * from './Type/Only'
 export * from './Type/Only'
 export * from './User/UserRequestType'
 export * from './User/UserRequestType'
-export * from './Workspace/WorkspaceAccessLevel'
-export * from './Workspace/WorkspaceType'
-export * from './Workspace/WorkspaceUserStatus'

+ 0 - 1
packages/domain-events/src/Domain/Event/DomainEventService.ts

@@ -8,7 +8,6 @@ export enum DomainEventService {
   ApiGateway = 'api-gateway',
   ApiGateway = 'api-gateway',
   Files = 'files',
   Files = 'files',
   Scheduler = 'scheduler',
   Scheduler = 'scheduler',
-  Workspace = 'workspace',
   Analytics = 'analytics',
   Analytics = 'analytics',
   Revisions = 'revisions',
   Revisions = 'revisions',
   Email = 'email',
   Email = 'email',

+ 0 - 7
packages/domain-events/src/Domain/Event/WorkspaceInviteAcceptedEvent.ts

@@ -1,7 +0,0 @@
-import { DomainEventInterface } from './DomainEventInterface'
-import { WorkspaceInviteAcceptedEventPayload } from './WorkspaceInviteAcceptedEventPayload'
-
-export interface WorkspaceInviteAcceptedEvent extends DomainEventInterface {
-  type: 'WORKSPACE_INVITE_ACCEPTED'
-  payload: WorkspaceInviteAcceptedEventPayload
-}

+ 0 - 5
packages/domain-events/src/Domain/Event/WorkspaceInviteAcceptedEventPayload.ts

@@ -1,5 +0,0 @@
-export interface WorkspaceInviteAcceptedEventPayload {
-  inviterUuid: string
-  inviteeUuid: string
-  workspaceUuid: string
-}

+ 0 - 2
packages/domain-events/src/Domain/index.ts

@@ -92,8 +92,6 @@ export * from './Event/UserRolesChangedEvent'
 export * from './Event/UserRolesChangedEventPayload'
 export * from './Event/UserRolesChangedEventPayload'
 export * from './Event/WebSocketMessageRequestedEvent'
 export * from './Event/WebSocketMessageRequestedEvent'
 export * from './Event/WebSocketMessageRequestedEventPayload'
 export * from './Event/WebSocketMessageRequestedEventPayload'
-export * from './Event/WorkspaceInviteAcceptedEvent'
-export * from './Event/WorkspaceInviteAcceptedEventPayload'
 
 
 export * from './Handler/DomainEventHandlerInterface'
 export * from './Handler/DomainEventHandlerInterface'
 export * from './Handler/DomainEventMessageHandlerInterface'
 export * from './Handler/DomainEventMessageHandlerInterface'

+ 0 - 32
packages/workspace/.env.sample

@@ -1,32 +0,0 @@
-LOG_LEVEL=debug
-NODE_ENV=development
-VERSION=development
-
-AUTH_JWT_SECRET=auth_jwt_secret
-
-PORT=3000
-
-DB_HOST=127.0.0.1
-DB_REPLICA_HOST=127.0.0.1
-DB_PORT=3306
-DB_USERNAME=workspace
-DB_PASSWORD=changeme123
-DB_DATABASE=workspace
-DB_DEBUG_LEVEL=all # "all" | "query" | "schema" | "error" | "warn" | "info" | "log" | "migration"
-DB_MIGRATIONS_PATH=dist/migrations/*.js
-
-REDIS_URL=redis://cache
-
-SNS_TOPIC_ARN=
-SNS_AWS_REGION=
-SQS_QUEUE_URL=
-SQS_AWS_REGION=
-
-# (Optional) New Relic Setup
-NEW_RELIC_ENABLED=false
-NEW_RELIC_APP_NAME=Workspace
-NEW_RELIC_LICENSE_KEY=
-NEW_RELIC_NO_CONFIG_FILE=true
-NEW_RELIC_DISTRIBUTED_TRACING_ENABLED=false
-NEW_RELIC_LOG_ENABLED=false
-NEW_RELIC_LOG_LEVEL=info

+ 0 - 3
packages/workspace/.eslintignore

@@ -1,3 +0,0 @@
-dist
-test-setup.ts
-data

+ 0 - 6
packages/workspace/.eslintrc

@@ -1,6 +0,0 @@
-{
-  "extends": "../../.eslintrc",
-  "parserOptions": {
-    "project": "./linter.tsconfig.json"
-  }
-}

+ 0 - 558
packages/workspace/CHANGELOG.md

@@ -1,558 +0,0 @@
-# Change Log
-
-All notable changes to this project will be documented in this file.
-See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
-
-## [1.20.4](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.20.3...@standardnotes/workspace-server@1.20.4) (2023-02-23)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.20.3](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.20.2...@standardnotes/workspace-server@1.20.3) (2023-02-21)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.20.2](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.20.1...@standardnotes/workspace-server@1.20.2) (2023-02-20)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.20.1](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.20.0...@standardnotes/workspace-server@1.20.1) (2023-02-15)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-# [1.20.0](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.19.23...@standardnotes/workspace-server@1.20.0) (2023-02-15)
-
-### Features
-
-* optimize memory on server utilities ([881a696](https://github.com/standardnotes/server/commit/881a6967aca57d68795af0792114f848ddddf120))
-
-## [1.19.23](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.19.22...@standardnotes/workspace-server@1.19.23) (2023-02-06)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.19.22](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.19.21...@standardnotes/workspace-server@1.19.22) (2023-01-30)
-
-### Bug Fixes
-
-* sqs configuration for aws sdk v3 ([b54c331](https://github.com/standardnotes/server/commit/b54c331bef0d4ad1ba1111700dc9f1bf64c1ea51))
-
-## [1.19.21](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.19.20...@standardnotes/workspace-server@1.19.21) (2023-01-25)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.19.20](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.19.19...@standardnotes/workspace-server@1.19.20) (2023-01-24)
-
-### Bug Fixes
-
-* **auth:** add pseudo u2f params on non existing accounts ([e4c65ca](https://github.com/standardnotes/server/commit/e4c65ca631938d8b1d635a40e463d5544051e4a1))
-
-## [1.19.19](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.19.18...@standardnotes/workspace-server@1.19.19) (2023-01-24)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.19.18](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.19.17...@standardnotes/workspace-server@1.19.18) (2023-01-23)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.19.17](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.19.16...@standardnotes/workspace-server@1.19.17) (2023-01-20)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.19.16](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.19.15...@standardnotes/workspace-server@1.19.16) (2023-01-20)
-
-### Bug Fixes
-
-* dependency issues ([589f8e6](https://github.com/standardnotes/server/commit/589f8e62f4753b9c6fab21bd675114d373d89f2d))
-
-## [1.19.15](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.19.14...@standardnotes/workspace-server@1.19.15) (2023-01-20)
-
-### Reverts
-
-* Revert "chore: upgrade @standardnotes/* dependencies" ([5bf3ecd](https://github.com/standardnotes/server/commit/5bf3ecdf42e1e5b9cb538cad08a18fb6e4054129))
-
-## [1.19.14](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.19.13...@standardnotes/workspace-server@1.19.14) (2023-01-20)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.19.13](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.19.12...@standardnotes/workspace-server@1.19.13) (2023-01-19)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.19.12](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.19.11...@standardnotes/workspace-server@1.19.12) (2023-01-19)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.19.11](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.19.10...@standardnotes/workspace-server@1.19.11) (2023-01-19)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.19.10](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.19.9...@standardnotes/workspace-server@1.19.10) (2023-01-19)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.19.9](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.19.8...@standardnotes/workspace-server@1.19.9) (2023-01-18)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.19.8](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.19.7...@standardnotes/workspace-server@1.19.8) (2023-01-17)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.19.7](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.19.6...@standardnotes/workspace-server@1.19.7) (2023-01-17)
-
-### Bug Fixes
-
-* allow to run typeorm in non-replica mode ([f73129c](https://github.com/standardnotes/server/commit/f73129cd7e7d6a9b8a63e5c80284467597557982))
-
-## [1.19.6](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.19.5...@standardnotes/workspace-server@1.19.6) (2023-01-16)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.19.5](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.19.4...@standardnotes/workspace-server@1.19.5) (2023-01-13)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.19.4](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.19.3...@standardnotes/workspace-server@1.19.4) (2022-12-28)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.19.3](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.19.2...@standardnotes/workspace-server@1.19.3) (2022-12-20)
-
-### Bug Fixes
-
-* **workspace:** specs ([c8203cf](https://github.com/standardnotes/server/commit/c8203cf04cb93cc65d30b69f10fb275f5e6be449))
-
-## [1.19.2](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.19.1...@standardnotes/workspace-server@1.19.2) (2022-12-20)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.19.1](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.19.0...@standardnotes/workspace-server@1.19.1) (2022-12-19)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-# [1.19.0](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.18.6...@standardnotes/workspace-server@1.19.0) (2022-12-19)
-
-### Features
-
-* **auth:** add session traces ([8bcb552](https://github.com/standardnotes/server/commit/8bcb552783b2d12f3296b3195752168482790bc8))
-
-## [1.18.6](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.18.5...@standardnotes/workspace-server@1.18.6) (2022-12-15)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.18.5](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.18.4...@standardnotes/workspace-server@1.18.5) (2022-12-15)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.18.4](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.18.3...@standardnotes/workspace-server@1.18.4) (2022-12-12)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.18.3](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.18.2...@standardnotes/workspace-server@1.18.3) (2022-12-12)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.18.2](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.18.1...@standardnotes/workspace-server@1.18.2) (2022-12-09)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.18.1](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.18.0...@standardnotes/workspace-server@1.18.1) (2022-12-09)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-# [1.18.0](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.47...@standardnotes/workspace-server@1.18.0) (2022-12-09)
-
-### Features
-
-* **workspace:** replace workspace invite created event with email requested ([61c1cff](https://github.com/standardnotes/server/commit/61c1cfff4bcee09e1f933cb3e085412b6f07cc42))
-
-## [1.17.47](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.46...@standardnotes/workspace-server@1.17.47) (2022-12-09)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.17.46](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.45...@standardnotes/workspace-server@1.17.46) (2022-12-09)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.17.45](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.44...@standardnotes/workspace-server@1.17.45) (2022-12-09)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.17.44](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.43...@standardnotes/workspace-server@1.17.44) (2022-12-09)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.17.43](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.42...@standardnotes/workspace-server@1.17.43) (2022-12-09)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.17.42](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.41...@standardnotes/workspace-server@1.17.42) (2022-12-08)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.17.41](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.40...@standardnotes/workspace-server@1.17.41) (2022-12-08)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.17.40](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.39...@standardnotes/workspace-server@1.17.40) (2022-12-08)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.17.39](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.38...@standardnotes/workspace-server@1.17.39) (2022-12-08)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.17.38](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.37...@standardnotes/workspace-server@1.17.38) (2022-12-08)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.17.37](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.36...@standardnotes/workspace-server@1.17.37) (2022-12-07)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.17.36](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.35...@standardnotes/workspace-server@1.17.36) (2022-12-07)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.17.35](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.34...@standardnotes/workspace-server@1.17.35) (2022-12-07)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.17.34](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.33...@standardnotes/workspace-server@1.17.34) (2022-12-06)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.17.33](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.32...@standardnotes/workspace-server@1.17.33) (2022-12-05)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.17.32](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.31...@standardnotes/workspace-server@1.17.32) (2022-11-30)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.17.31](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.30...@standardnotes/workspace-server@1.17.31) (2022-11-28)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.17.30](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.29...@standardnotes/workspace-server@1.17.30) (2022-11-25)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.17.29](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.28...@standardnotes/workspace-server@1.17.29) (2022-11-24)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.17.28](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.27...@standardnotes/workspace-server@1.17.28) (2022-11-23)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.17.27](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.26...@standardnotes/workspace-server@1.17.27) (2022-11-23)
-
-### Bug Fixes
-
-* binding of sns and sqs with additional config ([74bc791](https://github.com/standardnotes/server/commit/74bc79116bc50d9a5af1a558db1b7108dcda6d0e))
-
-## [1.17.26](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.25...@standardnotes/workspace-server@1.17.26) (2022-11-22)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.17.25](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.24...@standardnotes/workspace-server@1.17.25) (2022-11-21)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.17.24](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.23...@standardnotes/workspace-server@1.17.24) (2022-11-18)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.17.23](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.22...@standardnotes/workspace-server@1.17.23) (2022-11-16)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.17.22](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.21...@standardnotes/workspace-server@1.17.22) (2022-11-14)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.17.21](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.18...@standardnotes/workspace-server@1.17.21) (2022-11-14)
-
-### Bug Fixes
-
-* versioning issue ([7ca377f](https://github.com/standardnotes/server/commit/7ca377f1b889379e6a43a66c0134bf266763516d))
-
-## [1.17.18](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.17...@standardnotes/workspace-server@1.17.18) (2022-11-14)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.17.17](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.16...@standardnotes/workspace-server@1.17.17) (2022-11-11)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.17.16](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.15...@standardnotes/workspace-server@1.17.16) (2022-11-11)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.17.15](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.14...@standardnotes/workspace-server@1.17.15) (2022-11-10)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.17.14](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.13...@standardnotes/workspace-server@1.17.14) (2022-11-10)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.17.13](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.12...@standardnotes/workspace-server@1.17.13) (2022-11-09)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.17.12](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.11...@standardnotes/workspace-server@1.17.12) (2022-11-09)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.17.11](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.10...@standardnotes/workspace-server@1.17.11) (2022-11-09)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.17.10](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.9...@standardnotes/workspace-server@1.17.10) (2022-11-09)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.17.9](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.8...@standardnotes/workspace-server@1.17.9) (2022-11-09)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.17.8](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.7...@standardnotes/workspace-server@1.17.8) (2022-11-07)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.17.7](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.6...@standardnotes/workspace-server@1.17.7) (2022-11-07)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.17.6](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.5...@standardnotes/workspace-server@1.17.6) (2022-11-07)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.17.5](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.4...@standardnotes/workspace-server@1.17.5) (2022-11-07)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.17.4](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.3...@standardnotes/workspace-server@1.17.4) (2022-11-04)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.17.3](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.2...@standardnotes/workspace-server@1.17.3) (2022-11-04)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.17.2](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.1...@standardnotes/workspace-server@1.17.2) (2022-11-04)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.17.1](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.0...@standardnotes/workspace-server@1.17.1) (2022-11-03)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-# [1.17.0](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.16.6...@standardnotes/workspace-server@1.17.0) (2022-11-02)
-
-### Features
-
-* **auth:** add processing user requests ([2255f85](https://github.com/standardnotes/server/commit/2255f856f928e855ac94f8aca4e1fb81047f58f7))
-
-## [1.16.6](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.16.5...@standardnotes/workspace-server@1.16.6) (2022-11-02)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.16.5](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.16.4...@standardnotes/workspace-server@1.16.5) (2022-11-01)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.16.4](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.16.3...@standardnotes/workspace-server@1.16.4) (2022-11-01)
-
-### Bug Fixes
-
-* force utf8mb4 charset on typeorm ([5160cc3](https://github.com/standardnotes/server/commit/5160cc36ddc9e30551d5ad40a9e210d87091eec3))
-
-## [1.16.3](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.16.2...@standardnotes/workspace-server@1.16.3) (2022-10-31)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.16.2](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.16.1...@standardnotes/workspace-server@1.16.2) (2022-10-31)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.16.1](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.16.0...@standardnotes/workspace-server@1.16.1) (2022-10-26)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-# [1.16.0](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.15.0...@standardnotes/workspace-server@1.16.0) (2022-10-24)
-
-### Features
-
-* **auth:** change accepting invitations to be an authorized endpoint ([771a555](https://github.com/standardnotes/server/commit/771a555b4f33452311cd5bf0b8cfcbc4f2f1c4dd))
-
-# [1.15.0](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.14.6...@standardnotes/workspace-server@1.15.0) (2022-10-19)
-
-### Features
-
-* building server applications in ARM64 architecture for Docker ([fd92866](https://github.com/standardnotes/server/commit/fd92866ba1a86b22769b23cc4c8387a83f87979a))
-
-## [1.14.6](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.14.5...@standardnotes/workspace-server@1.14.6) (2022-10-17)
-
-### Bug Fixes
-
-* **workspaces:** accepting invitations ([b6f3954](https://github.com/standardnotes/server/commit/b6f3954e24794d6ab97ab61f39c4d91c39e5f558))
-
-## [1.14.5](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.14.4...@standardnotes/workspace-server@1.14.5) (2022-10-17)
-
-### Bug Fixes
-
-* **workspaces:** allow type of workspace to come from parameters ([6af8ff7](https://github.com/standardnotes/server/commit/6af8ff700ea795252d5f8d3a955f27eef9240ae2))
-
-## [1.14.4](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.14.3...@standardnotes/workspace-server@1.14.4) (2022-10-17)
-
-### Bug Fixes
-
-* **workspaces:** listing workspace uuids ([365d316](https://github.com/standardnotes/server/commit/365d316878d8d76256efc102e53ff9868789cbc8))
-
-## [1.14.3](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.14.2...@standardnotes/workspace-server@1.14.3) (2022-10-17)
-
-### Bug Fixes
-
-* **workspaces:** add debug logs for listing workspaces ([d232e71](https://github.com/standardnotes/server/commit/d232e71683d553ddaa41dd2f75716cdf8e62a19f))
-
-## [1.14.2](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.14.1...@standardnotes/workspace-server@1.14.2) (2022-10-14)
-
-### Bug Fixes
-
-* **workspace:** fetching users workspaces list ([0cacc8e](https://github.com/standardnotes/server/commit/0cacc8efa06d6dde0e8cc4486c303082a5ee4211))
-
-## [1.14.1](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.14.0...@standardnotes/workspace-server@1.14.1) (2022-10-14)
-
-### Bug Fixes
-
-* **workspaces:** reading response locals when listing workspaces ([d2fcc76](https://github.com/standardnotes/server/commit/d2fcc761ad30786c7245f379ded996da383c5cfe))
-
-# [1.14.0](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.13.2...@standardnotes/workspace-server@1.14.0) (2022-10-13)
-
-### Features
-
-* publish workspace invite accepted event for websockets ([86379eb](https://github.com/standardnotes/server/commit/86379eb96d7231d6a76ee91350accef2d44a941d))
-
-## [1.13.2](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.13.1...@standardnotes/workspace-server@1.13.2) (2022-10-13)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.13.1](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.13.0...@standardnotes/workspace-server@1.13.1) (2022-10-12)
-
-### Bug Fixes
-
-* **workspace:** add workspace to workspace user foreign keys ([4f6a2a8](https://github.com/standardnotes/server/commit/4f6a2a83d3d7b57d176e169f33780730eeae6919))
-
-# [1.13.0](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.12.0...@standardnotes/workspace-server@1.13.0) (2022-10-12)
-
-### Features
-
-* **workspace:** add endpoints for initiating keyshare in a workspace ([0c1a779](https://github.com/standardnotes/server/commit/0c1a779ef03819928e7e791a6843d90eb9fed964))
-
-# [1.12.0](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.11.0...@standardnotes/workspace-server@1.12.0) (2022-10-12)
-
-### Features
-
-* **workspace:** add initiating key share ([cea9021](https://github.com/standardnotes/server/commit/cea9021c164588969890370a2332f11749ac820e))
-
-# [1.11.0](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.10.0...@standardnotes/workspace-server@1.11.0) (2022-10-11)
-
-### Features
-
-* add listin worspaces and workspace users ([095d13f](https://github.com/standardnotes/server/commit/095d13f8bbfe543fcf086840e1a985447a6c51ef))
-
-# [1.10.0](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.9.0...@standardnotes/workspace-server@1.10.0) (2022-10-11)
-
-### Features
-
-* **workspace:** extract workspace user status to common ([8bc9261](https://github.com/standardnotes/server/commit/8bc92616d2fbeb833c3fcbef6b87538745fc7f3e))
-
-# [1.9.0](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.8.0...@standardnotes/workspace-server@1.9.0) (2022-10-11)
-
-### Features
-
-* **workspace:** add invite access level ([f742270](https://github.com/standardnotes/server/commit/f74227067b7151cb63a54e815e57f81984467bfe))
-
-# [1.8.0](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.7.0...@standardnotes/workspace-server@1.8.0) (2022-10-11)
-
-### Features
-
-* **workspace:** add workspace user display name ([ba9d3bf](https://github.com/standardnotes/server/commit/ba9d3bfe4632d5001b8c967860df086f103e2e35))
-
-# [1.7.0](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.6.0...@standardnotes/workspace-server@1.7.0) (2022-10-11)
-
-### Features
-
-* **workspace:** accepting invitation ([ace2b69](https://github.com/standardnotes/server/commit/ace2b6936a104f3cfcad8f15d846e845917aa678))
-
-# [1.6.0](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.5.1...@standardnotes/workspace-server@1.6.0) (2022-10-11)
-
-### Features
-
-* **workspace:** add invite to workspace endpoints ([266adda](https://github.com/standardnotes/server/commit/266adda45bd3ad84bc6605824b6be1dd912f3f9a))
-
-## [1.5.1](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.5.0...@standardnotes/workspace-server@1.5.1) (2022-10-10)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-# [1.5.0](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.4.1...@standardnotes/workspace-server@1.5.0) (2022-10-10)
-
-### Features
-
-* **workspace:** add publishing workspace invite created ([6f9683c](https://github.com/standardnotes/server/commit/6f9683c41a1135489832d9a854a114c82825a647))
-
-## [1.4.1](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.4.0...@standardnotes/workspace-server@1.4.1) (2022-10-10)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-# [1.4.0](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.3.0...@standardnotes/workspace-server@1.4.0) (2022-10-10)
-
-### Features
-
-* **workspace:** add inviting to workspace ([e06cc3b](https://github.com/standardnotes/server/commit/e06cc3ba80fd3bbf8a5fb0e176bc76b4318a36e9))
-
-# [1.3.0](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.2.3...@standardnotes/workspace-server@1.3.0) (2022-10-10)
-
-### Features
-
-* **workspace:** add creating root workspace upon user registration ([3f61d31](https://github.com/standardnotes/server/commit/3f61d3163ef91b3b94056208a41bb4858c0df259))
-
-## [1.2.3](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.2.2...@standardnotes/workspace-server@1.2.3) (2022-10-10)
-
-### Bug Fixes
-
-* **workspace:** add optional parameters to creating workspace ([0ce4185](https://github.com/standardnotes/server/commit/0ce4185379d921cf69eb27c94d63933b8cabc2e7))
-
-## [1.2.2](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.2.1...@standardnotes/workspace-server@1.2.2) (2022-10-10)
-
-### Bug Fixes
-
-* **workspace:** extract workspace type to common types ([0ea88ad](https://github.com/standardnotes/server/commit/0ea88ad202d54de79d1433183c1706823639da93))
-
-## [1.2.1](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.2.0...@standardnotes/workspace-server@1.2.1) (2022-10-10)
-
-### Bug Fixes
-
-* **workspace:** rename private key to encrypted private key ([447d600](https://github.com/standardnotes/server/commit/447d600dbe0ee101a7579409adc9da6cd3e309de))
-
-# [1.2.0](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.1.2...@standardnotes/workspace-server@1.2.0) (2022-10-07)
-
-### Features
-
-* add workspaces creation ([156ab65](https://github.com/standardnotes/server/commit/156ab6527265351b13797394cbd34da037ab5a38))
-
-## [1.1.2](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.1.1...@standardnotes/workspace-server@1.1.2) (2022-10-07)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-## [1.1.1](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.1.0...@standardnotes/workspace-server@1.1.1) (2022-10-06)
-
-**Note:** Version bump only for package @standardnotes/workspace-server
-
-# 1.1.0 (2022-10-06)
-
-### Features
-
-* add workspace microservice ([44a9ade](https://github.com/standardnotes/server/commit/44a9ade3fc0935d24733327c6b2de05b52496b1c))

+ 0 - 17
packages/workspace/Dockerfile

@@ -1,17 +0,0 @@
-FROM node:18.13.0-alpine
-
-RUN apk add --update \
-  curl \
-  && rm -rf /var/cache/apk/*
-
-ENV NODE_ENV production
-
-RUN corepack enable
-
-COPY ./ /workspace
-
-WORKDIR /workspace/packages/workspace
-
-ENTRYPOINT [ "/workspace/packages/workspace/docker/entrypoint.sh" ]
-
-CMD [ "start-web" ]

+ 0 - 71
packages/workspace/bin/server.ts

@@ -1,71 +0,0 @@
-import 'reflect-metadata'
-
-import 'newrelic'
-
-import * as Sentry from '@sentry/node'
-
-import '../src/Infra/InversifyExpressUtils/InversifyExpressHealthCheckController'
-import '../src/Infra/InversifyExpressUtils/InversifyExpressInvitesController'
-import '../src/Infra/InversifyExpressUtils/InversifyExpressWorkspacesController'
-
-import * as cors from 'cors'
-import { urlencoded, json, Request, Response, NextFunction, RequestHandler, ErrorRequestHandler } from 'express'
-import * as winston from 'winston'
-
-import { InversifyExpressServer } from 'inversify-express-utils'
-import { ContainerConfigLoader } from '../src/Bootstrap/Container'
-import TYPES from '../src/Bootstrap/Types'
-import { Env } from '../src/Bootstrap/Env'
-
-const container = new ContainerConfigLoader()
-void container.load().then((container) => {
-  const env: Env = new Env()
-  env.load()
-
-  const server = new InversifyExpressServer(container)
-
-  server.setConfig((app) => {
-    app.use((_request: Request, response: Response, next: NextFunction) => {
-      response.setHeader('X-Auth-Version', container.get(TYPES.VERSION))
-      next()
-    })
-    app.use(json())
-    app.use(urlencoded({ extended: true }))
-    app.use(cors())
-
-    if (env.get('SENTRY_DSN', true)) {
-      Sentry.init({
-        dsn: env.get('SENTRY_DSN'),
-        integrations: [new Sentry.Integrations.Http({ tracing: false, breadcrumbs: true })],
-        tracesSampleRate: 0,
-      })
-
-      app.use(Sentry.Handlers.requestHandler() as RequestHandler)
-    }
-  })
-
-  const logger: winston.Logger = container.get(TYPES.Logger)
-
-  server.setErrorConfig((app) => {
-    if (env.get('SENTRY_DSN', true)) {
-      app.use(Sentry.Handlers.errorHandler() as ErrorRequestHandler)
-    }
-
-    app.use((error: Record<string, unknown>, _request: Request, response: Response, _next: NextFunction) => {
-      logger.error(error.stack)
-
-      response.status(500).send({
-        error: {
-          message:
-            "Unfortunately, we couldn't handle your request. Please try again or contact our support if the error persists.",
-        },
-      })
-    })
-  })
-
-  const serverInstance = server.build()
-
-  serverInstance.listen(env.get('PORT'))
-
-  logger.info(`Server started on port ${process.env.PORT}`)
-})

+ 0 - 25
packages/workspace/bin/worker.ts

@@ -1,25 +0,0 @@
-import 'reflect-metadata'
-
-import 'newrelic'
-
-import { Logger } from 'winston'
-
-import { ContainerConfigLoader } from '../src/Bootstrap/Container'
-import TYPES from '../src/Bootstrap/Types'
-import { Env } from '../src/Bootstrap/Env'
-import { DomainEventSubscriberFactoryInterface } from '@standardnotes/domain-events'
-
-const container = new ContainerConfigLoader()
-void container.load().then((container) => {
-  const env: Env = new Env()
-  env.load()
-
-  const logger: Logger = container.get(TYPES.Logger)
-
-  logger.info('Starting worker...')
-
-  const subscriberFactory: DomainEventSubscriberFactoryInterface = container.get(TYPES.DomainEventSubscriberFactory)
-  subscriberFactory.create().start()
-
-  setInterval(() => logger.info('Alive and kicking!'), 20 * 60 * 1000)
-})

+ 0 - 11
packages/workspace/docker/entrypoint-server.js

@@ -1,11 +0,0 @@
-'use strict'
-
-const path = require('path')
-
-const pnp = require(path.normalize(path.resolve(__dirname, '../../..', '.pnp.cjs'))).setup()
-
-const index = require(path.normalize(path.resolve(__dirname, '../dist/bin/server.js')))
-
-Object.defineProperty(exports, '__esModule', { value: true })
-
-exports.default = index

+ 0 - 11
packages/workspace/docker/entrypoint-worker.js

@@ -1,11 +0,0 @@
-'use strict'
-
-const path = require('path')
-
-const pnp = require(path.normalize(path.resolve(__dirname, '../../..', '.pnp.cjs'))).setup()
-
-const index = require(path.normalize(path.resolve(__dirname, '../dist/bin/worker.js')))
-
-Object.defineProperty(exports, '__esModule', { value: true })
-
-exports.default = index

+ 0 - 22
packages/workspace/docker/entrypoint.sh

@@ -1,22 +0,0 @@
-#!/bin/sh
-set -e
-
-COMMAND=$1 && shift 1
-
-case "$COMMAND" in
-  'start-web' )
-    echo "Starting Web..."
-    node docker/entrypoint-server.js
-    ;;
-
-  'start-worker' )
-    echo "Starting Worker..."
-    node docker/entrypoint-worker.js
-    ;;
-
-   * )
-    echo "Unknown command"
-    ;;
-esac
-
-exec "$@"

+ 0 - 12
packages/workspace/jest.config.js

@@ -1,12 +0,0 @@
-// eslint-disable-next-line @typescript-eslint/no-var-requires
-const base = require('../../jest.config')
-const { defaults: tsjPreset } = require('ts-jest/presets')
-
-module.exports = {
-  ...base,
-  transform: {
-    ...tsjPreset.transform,
-  },
-  coveragePathIgnorePatterns: ['/Bootstrap/', '/InversifyExpressUtils/', '/Domain/Email/', '/Domain/Event'],
-  setupFilesAfterEnv: ['./test-setup.ts'],
-}

+ 0 - 4
packages/workspace/linter.tsconfig.json

@@ -1,4 +0,0 @@
-{
-  "extends": "./tsconfig.json",
-  "exclude": ["dist", "test-setup.ts"]
-}

+ 0 - 20
packages/workspace/migrations/1665049971623-initial.ts

@@ -1,20 +0,0 @@
-import { MigrationInterface, QueryRunner } from 'typeorm'
-
-export class initial1665049971623 implements MigrationInterface {
-  name = 'initial1665049971623'
-
-  public async up(queryRunner: QueryRunner): Promise<void> {
-    await queryRunner.query(
-      'CREATE TABLE `workspaces` (`uuid` varchar(36) NOT NULL, `type` varchar(64) NOT NULL, `name` varchar(255) NULL, `key_rotation_index` int NOT NULL DEFAULT 0, PRIMARY KEY (`uuid`)) ENGINE=InnoDB',
-    )
-    await queryRunner.query(
-      'CREATE TABLE `workspace_users` (`uuid` varchar(36) NOT NULL, `access_level` varchar(64) NOT NULL, `user_uuid` varchar(36) NOT NULL, `workspace_uuid` varchar(36) NOT NULL, `encrypted_workspace_key` varchar(255) NULL, `public_key` varchar(255) NOT NULL, `private_key` varchar(255) NOT NULL, `status` varchar(64) NOT NULL, `key_rotation_index` int NOT NULL DEFAULT 0, UNIQUE INDEX `index_workspace_users_on_workspace_and_user` (`user_uuid`, `workspace_uuid`), PRIMARY KEY (`uuid`)) ENGINE=InnoDB',
-    )
-  }
-
-  public async down(queryRunner: QueryRunner): Promise<void> {
-    await queryRunner.query('DROP INDEX `index_workspace_users_on_workspace_and_user` ON `workspace_users`')
-    await queryRunner.query('DROP TABLE `workspace_users`')
-    await queryRunner.query('DROP TABLE `workspaces`')
-  }
-}

+ 0 - 17
packages/workspace/migrations/1665389240189-rename-private-key.ts

@@ -1,17 +0,0 @@
-import { MigrationInterface, QueryRunner } from 'typeorm'
-
-export class renamePrivateKey1665389240189 implements MigrationInterface {
-  name = 'renamePrivateKey1665389240189'
-
-  public async up(queryRunner: QueryRunner): Promise<void> {
-    await queryRunner.query(
-      'ALTER TABLE `workspace_users` CHANGE `private_key` `encrypted_private_key` varchar(255) NOT NULL',
-    )
-  }
-
-  public async down(queryRunner: QueryRunner): Promise<void> {
-    await queryRunner.query(
-      'ALTER TABLE `workspace_users` CHANGE `encrypted_private_key` `private_key` varchar(255) NOT NULL',
-    )
-  }
-}

+ 0 - 19
packages/workspace/migrations/1665390489236-optional-keys.ts

@@ -1,19 +0,0 @@
-import { MigrationInterface, QueryRunner } from 'typeorm'
-
-export class optionalKeys1665390489236 implements MigrationInterface {
-  name = 'optionalKeys1665390489236'
-
-  public async up(queryRunner: QueryRunner): Promise<void> {
-    await queryRunner.query('ALTER TABLE `workspace_users` CHANGE `public_key` `public_key` varchar(255) NULL')
-    await queryRunner.query(
-      'ALTER TABLE `workspace_users` CHANGE `encrypted_private_key` `encrypted_private_key` varchar(255) NULL',
-    )
-  }
-
-  public async down(queryRunner: QueryRunner): Promise<void> {
-    await queryRunner.query(
-      'ALTER TABLE `workspace_users` CHANGE `encrypted_private_key` `encrypted_private_key` varchar(255) NOT NULL',
-    )
-    await queryRunner.query('ALTER TABLE `workspace_users` CHANGE `public_key` `public_key` varchar(255) NOT NULL')
-  }
-}

+ 0 - 27
packages/workspace/migrations/1665394559520-add-invites.ts

@@ -1,27 +0,0 @@
-import { MigrationInterface, QueryRunner } from 'typeorm'
-
-export class addInvites1665394559520 implements MigrationInterface {
-  name = 'addInvites1665394559520'
-
-  public async up(queryRunner: QueryRunner): Promise<void> {
-    await queryRunner.query(
-      'CREATE TABLE `workspace_invites` (`uuid` varchar(36) NOT NULL, `inviter_uuid` varchar(36) NOT NULL, `invitee_email` varchar(255) NOT NULL, `status` varchar(64) NOT NULL, `accepting_user_uuid` varchar(36) NULL, `workspace_uuid` varchar(36) NOT NULL, `created_at` bigint NOT NULL, `updated_at` bigint NOT NULL, PRIMARY KEY (`uuid`)) ENGINE=InnoDB',
-    )
-    await queryRunner.query('ALTER TABLE `workspaces` ADD `created_at` bigint NOT NULL')
-    await queryRunner.query('ALTER TABLE `workspaces` ADD `updated_at` bigint NOT NULL')
-    await queryRunner.query('ALTER TABLE `workspace_users` ADD `created_at` bigint NOT NULL')
-    await queryRunner.query('ALTER TABLE `workspace_users` ADD `updated_at` bigint NOT NULL')
-    await queryRunner.query(
-      'ALTER TABLE `workspace_invites` ADD CONSTRAINT `FK_782df40d03151dd3998acd0a6ba` FOREIGN KEY (`workspace_uuid`) REFERENCES `workspaces`(`uuid`) ON DELETE CASCADE ON UPDATE NO ACTION',
-    )
-  }
-
-  public async down(queryRunner: QueryRunner): Promise<void> {
-    await queryRunner.query('ALTER TABLE `workspace_invites` DROP FOREIGN KEY `FK_782df40d03151dd3998acd0a6ba`')
-    await queryRunner.query('ALTER TABLE `workspace_users` DROP COLUMN `updated_at`')
-    await queryRunner.query('ALTER TABLE `workspace_users` DROP COLUMN `created_at`')
-    await queryRunner.query('ALTER TABLE `workspaces` DROP COLUMN `updated_at`')
-    await queryRunner.query('ALTER TABLE `workspaces` DROP COLUMN `created_at`')
-    await queryRunner.query('DROP TABLE `workspace_invites`')
-  }
-}

+ 0 - 13
packages/workspace/migrations/1665480537103-add-user-display-name.ts

@@ -1,13 +0,0 @@
-import { MigrationInterface, QueryRunner } from 'typeorm'
-
-export class addUserDisplayName1665480537103 implements MigrationInterface {
-  name = 'addUserDisplayName1665480537103'
-
-  public async up(queryRunner: QueryRunner): Promise<void> {
-    await queryRunner.query('ALTER TABLE `workspace_users` ADD `user_display_name` varchar(255) NULL')
-  }
-
-  public async down(queryRunner: QueryRunner): Promise<void> {
-    await queryRunner.query('ALTER TABLE `workspace_users` DROP COLUMN `user_display_name`')
-  }
-}

+ 0 - 13
packages/workspace/migrations/1665481699781-add-invite-access-level.ts

@@ -1,13 +0,0 @@
-import { MigrationInterface, QueryRunner } from 'typeorm'
-
-export class addInviteAccessLevel1665481699781 implements MigrationInterface {
-  name = 'addInviteAccessLevel1665481699781'
-
-  public async up(queryRunner: QueryRunner): Promise<void> {
-    await queryRunner.query('ALTER TABLE `workspace_invites` ADD `access_level` varchar(64) NOT NULL')
-  }
-
-  public async down(queryRunner: QueryRunner): Promise<void> {
-    await queryRunner.query('ALTER TABLE `workspace_invites` DROP COLUMN `access_level`')
-  }
-}

+ 0 - 15
packages/workspace/migrations/1665580464598-add-workspace-user-foreign-key.ts

@@ -1,15 +0,0 @@
-import { MigrationInterface, QueryRunner } from 'typeorm'
-
-export class addWorkspaceUserForeignKey1665580464598 implements MigrationInterface {
-  name = 'addWorkspaceUserForeignKey1665580464598'
-
-  public async up(queryRunner: QueryRunner): Promise<void> {
-    await queryRunner.query(
-      'ALTER TABLE `workspace_users` ADD CONSTRAINT `FK_cd407e5f2c4f3156ad2015aed41` FOREIGN KEY (`workspace_uuid`) REFERENCES `workspaces`(`uuid`) ON DELETE CASCADE ON UPDATE NO ACTION',
-    )
-  }
-
-  public async down(queryRunner: QueryRunner): Promise<void> {
-    await queryRunner.query('ALTER TABLE `workspace_users` DROP FOREIGN KEY `FK_cd407e5f2c4f3156ad2015aed41`')
-  }
-}

+ 0 - 62
packages/workspace/package.json

@@ -1,62 +0,0 @@
-{
-  "name": "@standardnotes/workspace-server",
-  "version": "1.20.4",
-  "engines": {
-    "node": ">=18.0.0 <19.0.0"
-  },
-  "private": true,
-  "description": "Workspace Server",
-  "main": "dist/src/index.js",
-  "typings": "dist/src/index.d.ts",
-  "author": "Karol Sójko <karol@standardnotes.com>",
-  "license": "AGPL-3.0-or-later",
-  "scripts": {
-    "clean": "rm -fr dist",
-    "setup:env": "cp .env.sample .env",
-    "build": "tsc --build",
-    "lint": "eslint . --ext .ts",
-    "pretest": "yarn lint && yarn build",
-    "test": "jest --coverage --config=./jest.config.js --maxWorkers=50%",
-    "start": "yarn node dist/bin/server.js",
-    "worker": "yarn node dist/bin/worker.js",
-    "typeorm": "typeorm-ts-node-commonjs"
-  },
-  "dependencies": {
-    "@aws-sdk/client-sns": "^3.259.0",
-    "@aws-sdk/client-sqs": "^3.259.0",
-    "@newrelic/winston-enricher": "^4.0.0",
-    "@sentry/node": "^7.28.1",
-    "@standardnotes/api": "^1.24.10",
-    "@standardnotes/common": "workspace:*",
-    "@standardnotes/domain-core": "workspace:^",
-    "@standardnotes/domain-events": "workspace:^",
-    "@standardnotes/domain-events-infra": "workspace:^",
-    "@standardnotes/models": "^1.42.11",
-    "@standardnotes/security": "workspace:*",
-    "@standardnotes/time": "workspace:^",
-    "cors": "2.8.5",
-    "dotenv": "^16.0.1",
-    "express": "^4.18.2",
-    "inversify": "^6.0.1",
-    "inversify-express-utils": "^6.4.3",
-    "ioredis": "^5.2.4",
-    "mysql2": "^3.0.1",
-    "newrelic": "^9.8.0",
-    "reflect-metadata": "0.1.13",
-    "typeorm": "^0.3.10",
-    "winston": "^3.8.1"
-  },
-  "devDependencies": {
-    "@types/cors": "^2.8.9",
-    "@types/express": "^4.17.14",
-    "@types/ioredis": "^5.0.0",
-    "@types/jest": "^29.1.1",
-    "@types/newrelic": "^9.4.0",
-    "@typescript-eslint/eslint-plugin": "^5.48.2",
-    "eslint": "^8.32.0",
-    "eslint-plugin-prettier": "^4.0.0",
-    "jest": "^29.1.2",
-    "ts-jest": "^29.0.3",
-    "typescript": "^4.8.4"
-  }
-}

+ 0 - 195
packages/workspace/src/Bootstrap/Container.ts

@@ -1,195 +0,0 @@
-import * as winston from 'winston'
-import Redis from 'ioredis'
-import { SNSClient, SNSClientConfig } from '@aws-sdk/client-sns'
-import { SQSClient, SQSClientConfig } from '@aws-sdk/client-sqs'
-import { Container } from 'inversify'
-import {
-  DomainEventHandlerInterface,
-  DomainEventMessageHandlerInterface,
-  DomainEventSubscriberFactoryInterface,
-} from '@standardnotes/domain-events'
-import { TimerInterface, Timer } from '@standardnotes/time'
-import { Env } from './Env'
-import TYPES from './Types'
-import { AppDataSource } from './DataSource'
-import {
-  SNSDomainEventPublisher,
-  SQSDomainEventSubscriberFactory,
-  SQSEventMessageHandler,
-  SQSNewRelicEventMessageHandler,
-} from '@standardnotes/domain-events-infra'
-import { ApiGatewayAuthMiddleware } from '../Controller/ApiGatewayAuthMiddleware'
-import { CrossServiceTokenData, TokenDecoder, TokenDecoderInterface } from '@standardnotes/security'
-import { WorkspaceRepositoryInterface } from '../Domain/Workspace/WorkspaceRepositoryInterface'
-import { MySQLWorkspaceRepository } from '../Infra/MySQL/MySQLWorkspaceRepository'
-import { WorkspaceUserRepositoryInterface } from '../Domain/Workspace/WorkspaceUserRepositoryInterface'
-import { MySQLWorkspaceUserRepository } from '../Infra/MySQL/MySQLWorkspaceUserRepository'
-import { Repository } from 'typeorm'
-import { Workspace } from '../Domain/Workspace/Workspace'
-import { WorkspaceUser } from '../Domain/Workspace/WorkspaceUser'
-import { CreateWorkspace } from '../Domain/UseCase/CreateWorkspace/CreateWorkspace'
-import { WorkspacesController } from '../Controller/WorkspacesController'
-import { UserRegisteredEventHandler } from '../Domain/Handler/UserRegisteredEventHandler'
-import { WorkspaceInviteRepositoryInterface } from '../Domain/Invite/WorkspaceInviteRepositoryInterface'
-import { MySQLWorkspaceInviteRepository } from '../Infra/MySQL/MySQLWorkspaceInviteRepository'
-import { WorkspaceInvite } from '../Domain/Invite/WorkspaceInvite'
-import { InviteToWorkspace } from '../Domain/UseCase/InviteToWorkspace/InviteToWorkspace'
-import { DomainEventFactory } from '../Domain/Event/DomainEventFactory'
-import { DomainEventFactoryInterface } from '../Domain/Event/DomainEventFactoryInterface'
-import { WorkspaceProjection } from '../Domain/Projection/WorkspaceProjection'
-import { WorkspaceProjector } from '../Domain/Projection/WorkspaceProjector'
-import { ProjectorInterface } from '../Domain/Projection/ProjectorInterface'
-import { WorkspaceUserProjection } from '../Domain/Projection/WorkspaceUserProjection'
-import { WorkspaceUserProjector } from '../Domain/Projection/WorkspaceUserProjector'
-import { AcceptInvitation } from '../Domain/UseCase/AcceptInvitation/AcceptInvitation'
-import { ListWorkspaces } from '../Domain/UseCase/ListWorkspaces/ListWorkspaces'
-import { ListWorkspaceUsers } from '../Domain/UseCase/ListWorkspaceUsers/ListWorkspaceUsers'
-import { InitiateKeyShare } from '../Domain/UseCase/InitiateKeyShare/InitiateKeyShare'
-
-// eslint-disable-next-line @typescript-eslint/no-var-requires
-const newrelicFormatter = require('@newrelic/winston-enricher')
-
-export class ContainerConfigLoader {
-  async load(): Promise<Container> {
-    const env: Env = new Env()
-    env.load()
-
-    const container = new Container()
-
-    await AppDataSource.initialize()
-
-    const redisUrl = env.get('REDIS_URL')
-    const isRedisInClusterMode = redisUrl.indexOf(',') > 0
-    let redis
-    if (isRedisInClusterMode) {
-      redis = new Redis.Cluster(redisUrl.split(','))
-    } else {
-      redis = new Redis(redisUrl)
-    }
-
-    container.bind(TYPES.Redis).toConstantValue(redis)
-
-    const newrelicWinstonFormatter = newrelicFormatter(winston)
-    const winstonFormatters = [winston.format.splat(), winston.format.json()]
-    if (env.get('NEW_RELIC_ENABLED', true) === 'true') {
-      winstonFormatters.push(newrelicWinstonFormatter())
-    }
-
-    const logger = winston.createLogger({
-      level: env.get('LOG_LEVEL') || 'info',
-      format: winston.format.combine(...winstonFormatters),
-      transports: [new winston.transports.Console({ level: env.get('LOG_LEVEL') || 'info' })],
-    })
-    container.bind<winston.Logger>(TYPES.Logger).toConstantValue(logger)
-
-    if (env.get('SNS_TOPIC_ARN', true)) {
-      const snsConfig: SNSClientConfig = {
-        apiVersion: 'latest',
-        region: env.get('SNS_AWS_REGION', true),
-      }
-      if (env.get('SNS_ENDPOINT', true)) {
-        snsConfig.endpoint = env.get('SNS_ENDPOINT', true)
-      }
-      if (env.get('SNS_ACCESS_KEY_ID', true) && env.get('SNS_SECRET_ACCESS_KEY', true)) {
-        snsConfig.credentials = {
-          accessKeyId: env.get('SNS_ACCESS_KEY_ID', true),
-          secretAccessKey: env.get('SNS_SECRET_ACCESS_KEY', true),
-        }
-      }
-      container.bind<SNSClient>(TYPES.SNS).toConstantValue(new SNSClient(snsConfig))
-    }
-
-    if (env.get('SQS_QUEUE_URL', true)) {
-      const sqsConfig: SQSClientConfig = {
-        region: env.get('SQS_AWS_REGION', true),
-      }
-      if (env.get('SQS_ENDPOINT', true)) {
-        sqsConfig.endpoint = env.get('SQS_ENDPOINT', true)
-      }
-      if (env.get('SQS_ACCESS_KEY_ID', true) && env.get('SQS_SECRET_ACCESS_KEY', true)) {
-        sqsConfig.credentials = {
-          accessKeyId: env.get('SQS_ACCESS_KEY_ID', true),
-          secretAccessKey: env.get('SQS_SECRET_ACCESS_KEY', true),
-        }
-      }
-      container.bind<SQSClient>(TYPES.SQS).toConstantValue(new SQSClient(sqsConfig))
-    }
-
-    // Controller
-    container.bind<WorkspacesController>(TYPES.WorkspacesController).to(WorkspacesController)
-    // Repositories
-    container.bind<WorkspaceRepositoryInterface>(TYPES.WorkspaceRepository).to(MySQLWorkspaceRepository)
-    container.bind<WorkspaceUserRepositoryInterface>(TYPES.WorkspaceUserRepository).to(MySQLWorkspaceUserRepository)
-    container
-      .bind<WorkspaceInviteRepositoryInterface>(TYPES.WorkspaceInviteRepository)
-      .to(MySQLWorkspaceInviteRepository)
-    // ORM
-    container
-      .bind<Repository<Workspace>>(TYPES.ORMWorkspaceRepository)
-      .toConstantValue(AppDataSource.getRepository(Workspace))
-    container
-      .bind<Repository<WorkspaceUser>>(TYPES.ORMWorkspaceUserRepository)
-      .toConstantValue(AppDataSource.getRepository(WorkspaceUser))
-    container
-      .bind<Repository<WorkspaceInvite>>(TYPES.ORMWorkspaceInviteRepository)
-      .toConstantValue(AppDataSource.getRepository(WorkspaceInvite))
-    // Middleware
-    container.bind<ApiGatewayAuthMiddleware>(TYPES.ApiGatewayAuthMiddleware).to(ApiGatewayAuthMiddleware)
-    // env vars
-    container.bind(TYPES.AUTH_JWT_SECRET).toConstantValue(env.get('AUTH_JWT_SECRET'))
-    container.bind(TYPES.REDIS_URL).toConstantValue(env.get('REDIS_URL'))
-    container.bind(TYPES.SNS_TOPIC_ARN).toConstantValue(env.get('SNS_TOPIC_ARN'))
-    container.bind(TYPES.SNS_AWS_REGION).toConstantValue(env.get('SNS_AWS_REGION', true))
-    container.bind(TYPES.SQS_QUEUE_URL).toConstantValue(env.get('SQS_QUEUE_URL'))
-    container.bind(TYPES.NEW_RELIC_ENABLED).toConstantValue(env.get('NEW_RELIC_ENABLED', true))
-    container.bind(TYPES.VERSION).toConstantValue(env.get('VERSION'))
-
-    // use cases
-    container.bind<CreateWorkspace>(TYPES.CreateWorkspace).to(CreateWorkspace)
-    container.bind<InviteToWorkspace>(TYPES.InviteToWorkspace).to(InviteToWorkspace)
-    container.bind<AcceptInvitation>(TYPES.AcceptInvitation).to(AcceptInvitation)
-    container.bind<ListWorkspaces>(TYPES.ListWorkspaces).to(ListWorkspaces)
-    container.bind<ListWorkspaceUsers>(TYPES.ListWorkspaceUsers).to(ListWorkspaceUsers)
-    container.bind<InitiateKeyShare>(TYPES.InitiateKeyShare).to(InitiateKeyShare)
-    // Handlers
-    container.bind<UserRegisteredEventHandler>(TYPES.UserRegisteredEventHandler).to(UserRegisteredEventHandler)
-    // Projection
-    container.bind<ProjectorInterface<Workspace, WorkspaceProjection>>(TYPES.WorkspaceProjector).to(WorkspaceProjector)
-    container
-      .bind<ProjectorInterface<WorkspaceUser, WorkspaceUserProjection>>(TYPES.WorkspaceUserProjector)
-      .to(WorkspaceUserProjector)
-    // Services
-    container.bind<DomainEventFactoryInterface>(TYPES.DomainEventFactory).to(DomainEventFactory)
-    container.bind<TimerInterface>(TYPES.Timer).toConstantValue(new Timer())
-    container
-      .bind<TokenDecoderInterface<CrossServiceTokenData>>(TYPES.CrossServiceTokenDecoder)
-      .toConstantValue(new TokenDecoder<CrossServiceTokenData>(container.get(TYPES.AUTH_JWT_SECRET)))
-
-    container
-      .bind<SNSDomainEventPublisher>(TYPES.DomainEventPublisher)
-      .toConstantValue(new SNSDomainEventPublisher(container.get(TYPES.SNS), container.get(TYPES.SNS_TOPIC_ARN)))
-
-    const eventHandlers: Map<string, DomainEventHandlerInterface> = new Map([
-      ['USER_REGISTERED', container.get(TYPES.UserRegisteredEventHandler)],
-    ])
-
-    container
-      .bind<DomainEventMessageHandlerInterface>(TYPES.DomainEventMessageHandler)
-      .toConstantValue(
-        env.get('NEW_RELIC_ENABLED', true) === 'true'
-          ? new SQSNewRelicEventMessageHandler(eventHandlers, container.get(TYPES.Logger))
-          : new SQSEventMessageHandler(eventHandlers, container.get(TYPES.Logger)),
-      )
-    container
-      .bind<DomainEventSubscriberFactoryInterface>(TYPES.DomainEventSubscriberFactory)
-      .toConstantValue(
-        new SQSDomainEventSubscriberFactory(
-          container.get(TYPES.SQS),
-          container.get(TYPES.SQS_QUEUE_URL),
-          container.get(TYPES.DomainEventMessageHandler),
-        ),
-      )
-
-    return container
-  }
-}

+ 0 - 53
packages/workspace/src/Bootstrap/DataSource.ts

@@ -1,53 +0,0 @@
-import { DataSource, LoggerOptions } from 'typeorm'
-import { WorkspaceInvite } from '../Domain/Invite/WorkspaceInvite'
-import { Workspace } from '../Domain/Workspace/Workspace'
-import { WorkspaceUser } from '../Domain/Workspace/WorkspaceUser'
-import { Env } from './Env'
-
-const env: Env = new Env()
-env.load()
-
-const maxQueryExecutionTime = env.get('DB_MAX_QUERY_EXECUTION_TIME', true)
-  ? +env.get('DB_MAX_QUERY_EXECUTION_TIME', true)
-  : 45_000
-
-const inReplicaMode = env.get('DB_REPLICA_HOST', true) ? true : false
-
-const replicationConfig = {
-  master: {
-    host: env.get('DB_HOST'),
-    port: parseInt(env.get('DB_PORT')),
-    username: env.get('DB_USERNAME'),
-    password: env.get('DB_PASSWORD'),
-    database: env.get('DB_DATABASE'),
-  },
-  slaves: [
-    {
-      host: env.get('DB_REPLICA_HOST', true),
-      port: parseInt(env.get('DB_PORT')),
-      username: env.get('DB_USERNAME'),
-      password: env.get('DB_PASSWORD'),
-      database: env.get('DB_DATABASE'),
-    },
-  ],
-  removeNodeErrorCount: 10,
-  restoreNodeTimeout: 5,
-}
-
-export const AppDataSource = new DataSource({
-  type: 'mysql',
-  charset: 'utf8mb4',
-  supportBigNumbers: true,
-  bigNumberStrings: false,
-  maxQueryExecutionTime,
-  replication: inReplicaMode ? replicationConfig : undefined,
-  host: inReplicaMode ? undefined : env.get('DB_HOST'),
-  port: inReplicaMode ? undefined : parseInt(env.get('DB_PORT')),
-  username: inReplicaMode ? undefined : env.get('DB_USERNAME'),
-  password: inReplicaMode ? undefined : env.get('DB_PASSWORD'),
-  database: inReplicaMode ? undefined : env.get('DB_DATABASE'),
-  entities: [Workspace, WorkspaceUser, WorkspaceInvite],
-  migrations: [env.get('DB_MIGRATIONS_PATH', true) ?? 'dist/migrations/*.js'],
-  migrationsRun: true,
-  logging: <LoggerOptions>env.get('DB_DEBUG_LEVEL'),
-})

+ 0 - 24
packages/workspace/src/Bootstrap/Env.ts

@@ -1,24 +0,0 @@
-import { config, DotenvParseOutput } from 'dotenv'
-import { injectable } from 'inversify'
-
-@injectable()
-export class Env {
-  private env?: DotenvParseOutput
-
-  public load(): void {
-    const output = config()
-    this.env = <DotenvParseOutput>output.parsed
-  }
-
-  public get(key: string, optional = false): string {
-    if (!this.env) {
-      this.load()
-    }
-
-    if (!process.env[key] && !optional) {
-      throw new Error(`Environment variable ${key} not set`)
-    }
-
-    return <string>process.env[key]
-  }
-}

+ 0 - 48
packages/workspace/src/Bootstrap/Types.ts

@@ -1,48 +0,0 @@
-const TYPES = {
-  Logger: Symbol.for('Logger'),
-  Redis: Symbol.for('Redis'),
-  SNS: Symbol.for('SNS'),
-  SQS: Symbol.for('SQS'),
-  // Controller
-  WorkspacesController: Symbol.for('WorkspacesController'),
-  // Repositories
-  WorkspaceRepository: Symbol.for('WorkspaceRepository'),
-  WorkspaceUserRepository: Symbol.for('WorkspaceUserRepository'),
-  WorkspaceInviteRepository: Symbol.for('WorkspaceInviteRepository'),
-  // ORM
-  ORMWorkspaceRepository: Symbol.for('ORMWorkspaceRepository'),
-  ORMWorkspaceUserRepository: Symbol.for('ORMWorkspaceUserRepository'),
-  ORMWorkspaceInviteRepository: Symbol.for('ORMWorkspaceInviteRepository'),
-  // Middleware
-  ApiGatewayAuthMiddleware: Symbol.for('ApiGatewayAuthMiddleware'),
-  // env vars
-  AUTH_JWT_SECRET: Symbol.for('AUTH_JWT_SECRET'),
-  REDIS_URL: Symbol.for('REDIS_URL'),
-  SNS_TOPIC_ARN: Symbol.for('SNS_TOPIC_ARN'),
-  SNS_AWS_REGION: Symbol.for('SNS_AWS_REGION'),
-  SQS_QUEUE_URL: Symbol.for('SQS_QUEUE_URL'),
-  SQS_AWS_REGION: Symbol.for('SQS_AWS_REGION'),
-  NEW_RELIC_ENABLED: Symbol.for('NEW_RELIC_ENABLED'),
-  VERSION: Symbol.for('VERSION'),
-  // use cases
-  CreateWorkspace: Symbol.for('CreateWorkspace'),
-  InviteToWorkspace: Symbol.for('InviteToWorkspace'),
-  AcceptInvitation: Symbol.for('AcceptInvitation'),
-  ListWorkspaces: Symbol.for('ListWorkspaces'),
-  ListWorkspaceUsers: Symbol.for('ListWorkspaceUsers'),
-  InitiateKeyShare: Symbol.for('InitiateKeyShare'),
-  // Handlers
-  UserRegisteredEventHandler: Symbol.for('UserRegisteredEventHandler'),
-  // Projection
-  WorkspaceProjector: Symbol.for('WorkspaceProjector'),
-  WorkspaceUserProjector: Symbol.for('WorkspaceUserProjector'),
-  // Services
-  Timer: Symbol.for('Timer'),
-  CrossServiceTokenDecoder: Symbol.for('CrossServiceTokenDecoder'),
-  DomainEventPublisher: Symbol.for('DomainEventPublisher'),
-  DomainEventSubscriberFactory: Symbol.for('DomainEventSubscriberFactory'),
-  DomainEventMessageHandler: Symbol.for('DomainEventMessageHandler'),
-  DomainEventFactory: Symbol.for('DomainEventFactory'),
-}
-
-export default TYPES

+ 0 - 99
packages/workspace/src/Controller/ApiGatewayAuthMiddleware.spec.ts

@@ -1,99 +0,0 @@
-import 'reflect-metadata'
-
-import { ApiGatewayAuthMiddleware } from './ApiGatewayAuthMiddleware'
-import { NextFunction, Request, Response } from 'express'
-import { Logger } from 'winston'
-import { CrossServiceTokenData, TokenDecoderInterface } from '@standardnotes/security'
-import { RoleName } from '@standardnotes/domain-core'
-
-describe('ApiGatewayAuthMiddleware', () => {
-  let tokenDecoder: TokenDecoderInterface<CrossServiceTokenData>
-  let request: Request
-  let response: Response
-  let next: NextFunction
-
-  const logger = {
-    debug: jest.fn(),
-  } as unknown as jest.Mocked<Logger>
-
-  const createMiddleware = () => new ApiGatewayAuthMiddleware(tokenDecoder, logger)
-
-  beforeEach(() => {
-    tokenDecoder = {} as jest.Mocked<TokenDecoderInterface<CrossServiceTokenData>>
-    tokenDecoder.decodeToken = jest.fn().mockReturnValue({
-      user: {
-        uuid: '1-2-3',
-        email: 'test@test.te',
-      },
-      roles: [
-        {
-          uuid: 'a-b-c',
-          name: RoleName.NAMES.CoreUser,
-        },
-      ],
-    })
-
-    request = {
-      headers: {},
-    } as jest.Mocked<Request>
-    response = {
-      locals: {},
-    } as jest.Mocked<Response>
-    response.status = jest.fn().mockReturnThis()
-    response.send = jest.fn()
-    next = jest.fn()
-  })
-
-  it('should authorize user', async () => {
-    request.headers['x-auth-token'] = 'auth-jwt-token'
-
-    await createMiddleware().handler(request, response, next)
-
-    expect(response.locals.user).toEqual({
-      uuid: '1-2-3',
-      email: 'test@test.te',
-    })
-    expect(response.locals.roles).toEqual([
-      {
-        uuid: 'a-b-c',
-        name: RoleName.NAMES.CoreUser,
-      },
-    ])
-
-    expect(next).toHaveBeenCalled()
-  })
-
-  it('should not authorize if request is missing auth jwt token in headers', async () => {
-    await createMiddleware().handler(request, response, next)
-
-    expect(response.status).toHaveBeenCalledWith(401)
-    expect(next).not.toHaveBeenCalled()
-  })
-
-  it('should not authorize if auth jwt token is malformed', async () => {
-    request.headers['x-auth-token'] = 'auth-jwt-token'
-
-    tokenDecoder.decodeToken = jest.fn().mockReturnValue(undefined)
-
-    await createMiddleware().handler(request, response, next)
-
-    expect(response.status).toHaveBeenCalledWith(401)
-    expect(next).not.toHaveBeenCalled()
-  })
-
-  it('should pass the error to next middleware if one occurres', async () => {
-    request.headers['x-auth-token'] = 'auth-jwt-token'
-
-    const error = new Error('Ooops')
-
-    tokenDecoder.decodeToken = jest.fn().mockImplementation(() => {
-      throw error
-    })
-
-    await createMiddleware().handler(request, response, next)
-
-    expect(response.status).not.toHaveBeenCalled()
-
-    expect(next).toHaveBeenCalledWith(error)
-  })
-})

+ 0 - 59
packages/workspace/src/Controller/ApiGatewayAuthMiddleware.ts

@@ -1,59 +0,0 @@
-import { CrossServiceTokenData, TokenDecoderInterface } from '@standardnotes/security'
-import { NextFunction, Request, Response } from 'express'
-import { inject, injectable } from 'inversify'
-import { BaseMiddleware } from 'inversify-express-utils'
-import { Logger } from 'winston'
-import TYPES from '../Bootstrap/Types'
-
-@injectable()
-export class ApiGatewayAuthMiddleware extends BaseMiddleware {
-  constructor(
-    @inject(TYPES.CrossServiceTokenDecoder) private tokenDecoder: TokenDecoderInterface<CrossServiceTokenData>,
-    @inject(TYPES.Logger) private logger: Logger,
-  ) {
-    super()
-  }
-
-  async handler(request: Request, response: Response, next: NextFunction): Promise<void> {
-    try {
-      if (!request.headers['x-auth-token']) {
-        this.logger.debug('ApiGatewayAuthMiddleware missing x-auth-token header.')
-
-        response.status(401).send({
-          error: {
-            tag: 'invalid-auth',
-            message: 'Invalid login credentials.',
-          },
-        })
-
-        return
-      }
-
-      const token: CrossServiceTokenData | undefined = this.tokenDecoder.decodeToken(
-        request.headers['x-auth-token'] as string,
-      )
-
-      if (token === undefined) {
-        this.logger.debug('ApiGatewayAuthMiddleware authentication failure.')
-
-        response.status(401).send({
-          error: {
-            tag: 'invalid-auth',
-            message: 'Invalid login credentials.',
-          },
-        })
-
-        return
-      }
-
-      response.locals.user = token.user
-      response.locals.roles = token.roles
-      response.locals.session = token.session
-      response.locals.readOnlyAccess = token.session?.readonly_access ?? false
-
-      return next()
-    } catch (error) {
-      return next(error)
-    }
-  }
-}

+ 0 - 204
packages/workspace/src/Controller/WorkspacesController.spec.ts

@@ -1,204 +0,0 @@
-import 'reflect-metadata'
-import { WorkspaceAccessLevel, WorkspaceType } from '@standardnotes/common'
-
-import { ProjectorInterface } from '../Domain/Projection/ProjectorInterface'
-import { WorkspaceProjection } from '../Domain/Projection/WorkspaceProjection'
-import { WorkspaceUserProjection } from '../Domain/Projection/WorkspaceUserProjection'
-import { AcceptInvitation } from '../Domain/UseCase/AcceptInvitation/AcceptInvitation'
-
-import { CreateWorkspace } from '../Domain/UseCase/CreateWorkspace/CreateWorkspace'
-import { InitiateKeyShare } from '../Domain/UseCase/InitiateKeyShare/InitiateKeyShare'
-import { InviteToWorkspace } from '../Domain/UseCase/InviteToWorkspace/InviteToWorkspace'
-import { ListWorkspaces } from '../Domain/UseCase/ListWorkspaces/ListWorkspaces'
-import { ListWorkspaceUsers } from '../Domain/UseCase/ListWorkspaceUsers/ListWorkspaceUsers'
-import { Workspace } from '../Domain/Workspace/Workspace'
-import { WorkspaceUser } from '../Domain/Workspace/WorkspaceUser'
-
-import { WorkspacesController } from './WorkspacesController'
-
-describe('WorkspacesController', () => {
-  let doCreateWorkspace: CreateWorkspace
-  let doInviteToWorkspace: InviteToWorkspace
-  let doAcceptInvitation: AcceptInvitation
-  let doListWorkspaces: ListWorkspaces
-  let doListWorkspaceUsers: ListWorkspaceUsers
-  let doInitiateKeyshare: InitiateKeyShare
-  let workspacesProject: ProjectorInterface<Workspace, WorkspaceProjection>
-  let workspaceUsersProjector: ProjectorInterface<WorkspaceUser, WorkspaceUserProjection>
-  let workspace1: Workspace
-  let workspace2: Workspace
-  let workspaceUser1: WorkspaceUser
-  let workspaceUser2: WorkspaceUser
-
-  const createController = () =>
-    new WorkspacesController(
-      doCreateWorkspace,
-      doInviteToWorkspace,
-      doListWorkspaces,
-      doListWorkspaceUsers,
-      doAcceptInvitation,
-      doInitiateKeyshare,
-      workspacesProject,
-      workspaceUsersProjector,
-    )
-
-  beforeEach(() => {
-    doCreateWorkspace = {} as jest.Mocked<CreateWorkspace>
-    doCreateWorkspace.execute = jest.fn().mockReturnValue({ workspace: { uuid: 'w-1-2-3' } })
-
-    doInviteToWorkspace = {} as jest.Mocked<InviteToWorkspace>
-    doInviteToWorkspace.execute = jest.fn().mockReturnValue({ invite: { uuid: 'i-1-2-3' } })
-
-    doListWorkspaces = {} as jest.Mocked<ListWorkspaces>
-    doListWorkspaces.execute = jest
-      .fn()
-      .mockReturnValue({ ownedWorkspaces: [workspace1], joinedWorkspaces: [workspace2] })
-
-    doListWorkspaceUsers = {} as jest.Mocked<ListWorkspaceUsers>
-    doListWorkspaceUsers.execute = jest.fn().mockReturnValue({ workspaceUsers: [workspaceUser1, workspaceUser2] })
-
-    doAcceptInvitation = {} as jest.Mocked<AcceptInvitation>
-    doAcceptInvitation.execute = jest.fn().mockReturnValue({ success: true })
-
-    doInitiateKeyshare = {} as jest.Mocked<InitiateKeyShare>
-    doInitiateKeyshare.execute = jest.fn().mockReturnValue({ success: true })
-
-    workspacesProject = {} as jest.Mocked<ProjectorInterface<Workspace, WorkspaceProjection>>
-    workspacesProject.project = jest.fn().mockReturnValue({ foo: 'bar' })
-
-    workspaceUsersProjector = {} as jest.Mocked<ProjectorInterface<WorkspaceUser, WorkspaceUserProjection>>
-    workspaceUsersProjector.project = jest.fn().mockReturnValue({ bar: 'buzz' })
-  })
-
-  it('should create a workspace', async () => {
-    const result = await createController().createWorkspace({
-      encryptedPrivateKey: 'foo',
-      encryptedWorkspaceKey: 'bar',
-      publicKey: 'buzz',
-      workspaceName: 'A Team',
-      ownerUuid: 'u-1-2-3',
-      workspaceType: WorkspaceType.Private,
-    })
-
-    expect(result).toEqual({
-      data: {
-        uuid: 'w-1-2-3',
-      },
-      status: 200,
-    })
-  })
-
-  it('should invite to a workspace', async () => {
-    const result = await createController().inviteToWorkspace({
-      inviteeEmail: 'test@test.te',
-      workspaceUuid: 'w-1-2-3',
-      accessLevel: WorkspaceAccessLevel.ReadOnly,
-    })
-
-    expect(result).toEqual({
-      data: {
-        uuid: 'i-1-2-3',
-      },
-      status: 200,
-    })
-  })
-
-  it('should accept an invite', async () => {
-    const result = await createController().acceptInvite({
-      userUuid: '1-2-3',
-      encryptedPrivateKey: 'foo',
-      inviteUuid: 'i-1-2-3',
-      publicKey: 'bar',
-    })
-
-    expect(result).toEqual({
-      data: {
-        success: true,
-      },
-      status: 200,
-    })
-  })
-
-  it('should not accept an invite if it fails', async () => {
-    doAcceptInvitation.execute = jest.fn().mockReturnValue({ success: false })
-    const result = await createController().acceptInvite({
-      userUuid: '1-2-3',
-      encryptedPrivateKey: 'foo',
-      inviteUuid: 'i-1-2-3',
-      publicKey: 'bar',
-    })
-
-    expect(result).toEqual({
-      data: {
-        error: {
-          message: 'Could not accept invite',
-        },
-      },
-      status: 400,
-    })
-  })
-
-  it('should list workspaces', async () => {
-    const result = await createController().listWorkspaces({
-      userUuid: '1-2-3',
-    })
-
-    expect(result).toEqual({
-      data: {
-        ownedWorkspaces: [{ foo: 'bar' }],
-        joinedWorkspaces: [{ foo: 'bar' }],
-      },
-      status: 200,
-    })
-  })
-
-  it('should list workspace users', async () => {
-    const result = await createController().listWorkspaceUsers({
-      userUuid: '1-2-3',
-      workspaceUuid: 'w-1-2-3',
-    })
-
-    expect(result).toEqual({
-      data: {
-        users: [{ bar: 'buzz' }, { bar: 'buzz' }],
-      },
-      status: 200,
-    })
-  })
-
-  it('should initiate keyshare', async () => {
-    const result = await createController().initiateKeyshare({
-      userUuid: 'u-1-2-3',
-      encryptedWorkspaceKey: 'foo',
-      workspaceUuid: 'w-1-2-3',
-      performingUserUuid: 'p-1-2-3',
-    })
-
-    expect(result).toEqual({
-      data: {
-        success: true,
-      },
-      status: 200,
-    })
-  })
-
-  it('should not initiate keyshare if it fails', async () => {
-    doInitiateKeyshare.execute = jest.fn().mockReturnValue({ success: false })
-
-    const result = await createController().initiateKeyshare({
-      userUuid: 'u-1-2-3',
-      encryptedWorkspaceKey: 'foo',
-      workspaceUuid: 'w-1-2-3',
-      performingUserUuid: 'p-1-2-3',
-    })
-
-    expect(result).toEqual({
-      data: {
-        error: {
-          message: 'Could not initiate keyshare.',
-        },
-      },
-      status: 400,
-    })
-  })
-})

+ 0 - 170
packages/workspace/src/Controller/WorkspacesController.ts

@@ -1,170 +0,0 @@
-import { inject, injectable } from 'inversify'
-import {
-  HttpStatusCode,
-  WorkspaceCreationRequestParams,
-  WorkspaceCreationResponse,
-  WorkspaceInvitationRequestParams,
-  WorkspaceInvitationResponse,
-  WorkspaceServerInterface,
-  WorkspaceListRequestParams,
-  WorkspaceListResponse,
-  WorkspaceInvitationAcceptingRequestParams,
-  WorkspaceInvitationAcceptingResponse,
-  WorkspaceUserListRequestParams,
-  WorkspaceKeyshareInitiatingRequestParams,
-  WorkspaceKeyshareInitiatingResponse,
-} from '@standardnotes/api'
-import { WorkspaceAccessLevel } from '@standardnotes/common'
-
-import TYPES from '../Bootstrap/Types'
-import { CreateWorkspace } from '../Domain/UseCase/CreateWorkspace/CreateWorkspace'
-import { InviteToWorkspace } from '../Domain/UseCase/InviteToWorkspace/InviteToWorkspace'
-import { ProjectorInterface } from '../Domain/Projection/ProjectorInterface'
-import { WorkspaceProjection } from '../Domain/Projection/WorkspaceProjection'
-import { Workspace } from '../Domain/Workspace/Workspace'
-import { ListWorkspaces } from '../Domain/UseCase/ListWorkspaces/ListWorkspaces'
-import { WorkspaceUserListResponse } from '@standardnotes/api/dist/Domain/Response/Workspace/WorkspaceUserListResponse'
-import { AcceptInvitation } from '../Domain/UseCase/AcceptInvitation/AcceptInvitation'
-import { WorkspaceUser } from '../Domain/Workspace/WorkspaceUser'
-import { WorkspaceUserProjection } from '../Domain/Projection/WorkspaceUserProjection'
-import { ListWorkspaceUsers } from '../Domain/UseCase/ListWorkspaceUsers/ListWorkspaceUsers'
-import { InitiateKeyShare } from '../Domain/UseCase/InitiateKeyShare/InitiateKeyShare'
-
-@injectable()
-export class WorkspacesController implements WorkspaceServerInterface {
-  constructor(
-    @inject(TYPES.CreateWorkspace) private doCreateWorkspace: CreateWorkspace,
-    @inject(TYPES.InviteToWorkspace) private doInviteToWorkspace: InviteToWorkspace,
-    @inject(TYPES.ListWorkspaces) private doListWorkspaces: ListWorkspaces,
-    @inject(TYPES.ListWorkspaceUsers) private doListWorkspaceUsers: ListWorkspaceUsers,
-    @inject(TYPES.AcceptInvitation) private doAcceptInvite: AcceptInvitation,
-    @inject(TYPES.InitiateKeyShare) private doInitiateKeyshare: InitiateKeyShare,
-    @inject(TYPES.WorkspaceProjector) private workspaceProjector: ProjectorInterface<Workspace, WorkspaceProjection>,
-    @inject(TYPES.WorkspaceUserProjector)
-    private workspaceUserProjector: ProjectorInterface<WorkspaceUser, WorkspaceUserProjection>,
-  ) {}
-
-  async initiateKeyshare(
-    params: WorkspaceKeyshareInitiatingRequestParams,
-  ): Promise<WorkspaceKeyshareInitiatingResponse> {
-    const result = await this.doInitiateKeyshare.execute({
-      userUuid: params.userUuid,
-      workspaceUuid: params.workspaceUuid,
-      encryptedWorkspaceKey: params.encryptedWorkspaceKey,
-      performingUserUuid: params.performingUserUuid as string,
-    })
-
-    if (!result.success) {
-      return {
-        status: HttpStatusCode.BadRequest,
-        data: {
-          error: {
-            message: 'Could not initiate keyshare.',
-          },
-        },
-      }
-    }
-
-    return {
-      status: HttpStatusCode.Success,
-      data: {
-        success: true,
-      },
-    }
-  }
-
-  async inviteToWorkspace(params: WorkspaceInvitationRequestParams): Promise<WorkspaceInvitationResponse> {
-    const { invite } = await this.doInviteToWorkspace.execute({
-      inviteeEmail: params.inviteeEmail,
-      workspaceUuid: params.workspaceUuid,
-      inviterUuid: params.inviterUuid as string,
-      accessLevel: params.accessLevel as WorkspaceAccessLevel,
-    })
-
-    return {
-      status: HttpStatusCode.Success,
-      data: { uuid: invite.uuid },
-    }
-  }
-
-  async createWorkspace(params: WorkspaceCreationRequestParams): Promise<WorkspaceCreationResponse> {
-    const { workspace } = await this.doCreateWorkspace.execute({
-      encryptedPrivateKey: params.encryptedPrivateKey,
-      encryptedWorkspaceKey: params.encryptedWorkspaceKey,
-      publicKey: params.publicKey,
-      name: params.workspaceName,
-      type: params.workspaceType,
-      ownerUuid: params.ownerUuid as string,
-    })
-
-    return {
-      status: HttpStatusCode.Success,
-      data: { uuid: workspace.uuid },
-    }
-  }
-
-  async listWorkspaces(params: WorkspaceListRequestParams): Promise<WorkspaceListResponse> {
-    const { ownedWorkspaces, joinedWorkspaces } = await this.doListWorkspaces.execute({
-      userUuid: params.userUuid as string,
-    })
-
-    const ownedWorkspacesProjections = []
-    for (const ownedWorkspace of ownedWorkspaces) {
-      ownedWorkspacesProjections.push(await this.workspaceProjector.project(ownedWorkspace))
-    }
-
-    const joinedWorkspacesProjections = []
-    for (const joinedWorkspace of joinedWorkspaces) {
-      joinedWorkspacesProjections.push(await this.workspaceProjector.project(joinedWorkspace))
-    }
-
-    return {
-      status: HttpStatusCode.Success,
-      data: { ownedWorkspaces: ownedWorkspacesProjections, joinedWorkspaces: joinedWorkspacesProjections },
-    }
-  }
-
-  async listWorkspaceUsers(params: WorkspaceUserListRequestParams): Promise<WorkspaceUserListResponse> {
-    const { workspaceUsers } = await this.doListWorkspaceUsers.execute({
-      userUuid: params.userUuid as string,
-      workspaceUuid: params.workspaceUuid,
-    })
-
-    const workspaceUserProjections = []
-    for (const workspaceUser of workspaceUsers) {
-      workspaceUserProjections.push(await this.workspaceUserProjector.project(workspaceUser))
-    }
-
-    return {
-      status: HttpStatusCode.Success,
-      data: { users: workspaceUserProjections },
-    }
-  }
-
-  async acceptInvite(params: WorkspaceInvitationAcceptingRequestParams): Promise<WorkspaceInvitationAcceptingResponse> {
-    const result = await this.doAcceptInvite.execute({
-      acceptingUserUuid: params.userUuid,
-      encryptedPrivateKey: params.encryptedPrivateKey,
-      invitationUuid: params.inviteUuid,
-      publicKey: params.publicKey,
-    })
-
-    if (!result.success) {
-      return {
-        status: HttpStatusCode.BadRequest,
-        data: {
-          error: {
-            message: 'Could not accept invite',
-          },
-        },
-      }
-    }
-
-    return {
-      status: HttpStatusCode.Success,
-      data: {
-        success: true,
-      },
-    }
-  }
-}

+ 0 - 9
packages/workspace/src/Domain/Email/WorkspaceInviteCreated.ts

@@ -1,9 +0,0 @@
-import { html } from './workspace-invite-created.html'
-
-export function getSubject(): string {
-  return 'You have been invited to a Standard Notes workspace'
-}
-
-export function getBody(inviteUuid: string): string {
-  return html(inviteUuid)
-}

+ 0 - 11
packages/workspace/src/Domain/Email/workspace-invite-created.html.ts

@@ -1,11 +0,0 @@
-export const html = (inviteUuid: string) => `<p>Hello,</p>
-<p>We are happy to inform that you have been invited to a shared workspace in Standard Notes.</p>
-<p>
-  Please
-  <a href='https://app.standardnotes.com/?accept_workspace_invite=${inviteUuid}'>accept the invitation</a>
-  to see the shared content.
-</p>
-<p>
-  Thanks,
-  <br>SN</br>
-</p>`

+ 0 - 72
packages/workspace/src/Domain/Event/DomainEventFactory.ts

@@ -1,72 +0,0 @@
-import {
-  DomainEventService,
-  EmailRequestedEvent,
-  WebSocketMessageRequestedEvent,
-  WorkspaceInviteAcceptedEvent,
-} from '@standardnotes/domain-events'
-import { TimerInterface } from '@standardnotes/time'
-import { inject, injectable } from 'inversify'
-
-import TYPES from '../../Bootstrap/Types'
-
-import { DomainEventFactoryInterface } from './DomainEventFactoryInterface'
-
-@injectable()
-export class DomainEventFactory implements DomainEventFactoryInterface {
-  constructor(@inject(TYPES.Timer) private timer: TimerInterface) {}
-
-  createWorkspaceInviteAcceptedEvent(dto: {
-    inviterUuid: string
-    inviteeUuid: string
-    workspaceUuid: string
-  }): WorkspaceInviteAcceptedEvent {
-    return {
-      type: 'WORKSPACE_INVITE_ACCEPTED',
-      createdAt: this.timer.getUTCDate(),
-      meta: {
-        correlation: {
-          userIdentifier: dto.inviteeUuid,
-          userIdentifierType: 'uuid',
-        },
-        origin: DomainEventService.Workspace,
-      },
-      payload: dto,
-    }
-  }
-
-  createWebSocketMessageRequestedEvent(dto: { userUuid: string; message: string }): WebSocketMessageRequestedEvent {
-    return {
-      type: 'WEB_SOCKET_MESSAGE_REQUESTED',
-      createdAt: this.timer.getUTCDate(),
-      meta: {
-        correlation: {
-          userIdentifier: dto.userUuid,
-          userIdentifierType: 'uuid',
-        },
-        origin: DomainEventService.Workspace,
-      },
-      payload: dto,
-    }
-  }
-
-  createEmailRequestedEvent(dto: {
-    userEmail: string
-    messageIdentifier: string
-    level: string
-    body: string
-    subject: string
-  }): EmailRequestedEvent {
-    return {
-      type: 'EMAIL_REQUESTED',
-      createdAt: this.timer.getUTCDate(),
-      meta: {
-        correlation: {
-          userIdentifier: dto.userEmail,
-          userIdentifierType: 'email',
-        },
-        origin: DomainEventService.Auth,
-      },
-      payload: dto,
-    }
-  }
-}

+ 0 - 22
packages/workspace/src/Domain/Event/DomainEventFactoryInterface.ts

@@ -1,22 +0,0 @@
-import { JSONString } from '@standardnotes/common'
-import {
-  EmailRequestedEvent,
-  WebSocketMessageRequestedEvent,
-  WorkspaceInviteAcceptedEvent,
-} from '@standardnotes/domain-events'
-
-export interface DomainEventFactoryInterface {
-  createEmailRequestedEvent(dto: {
-    userEmail: string
-    messageIdentifier: string
-    level: string
-    body: string
-    subject: string
-  }): EmailRequestedEvent
-  createWorkspaceInviteAcceptedEvent(dto: {
-    inviterUuid: string
-    inviteeUuid: string
-    workspaceUuid: string
-  }): WorkspaceInviteAcceptedEvent
-  createWebSocketMessageRequestedEvent(dto: { userUuid: string; message: JSONString }): WebSocketMessageRequestedEvent
-}

+ 0 - 44
packages/workspace/src/Domain/Handler/UserRegisteredEventHandler.spec.ts

@@ -1,44 +0,0 @@
-import 'reflect-metadata'
-
-import { UserRegisteredEvent } from '@standardnotes/domain-events'
-
-import { UserRegisteredEventHandler } from './UserRegisteredEventHandler'
-import { CreateWorkspace } from '../UseCase/CreateWorkspace/CreateWorkspace'
-import { ProtocolVersion } from '@standardnotes/common'
-
-describe('UserRegisteredEventHandler', () => {
-  let createWorkspace: CreateWorkspace
-  let event: UserRegisteredEvent
-
-  const createHandler = () => new UserRegisteredEventHandler(createWorkspace)
-
-  beforeEach(() => {
-    createWorkspace = {} as jest.Mocked<CreateWorkspace>
-    createWorkspace.execute = jest.fn()
-
-    event = {} as jest.Mocked<UserRegisteredEvent>
-    event.createdAt = new Date(1)
-    event.payload = {
-      userUuid: '1-2-3',
-      email: 'test@test.te',
-      protocolVersion: ProtocolVersion.V005,
-    }
-  })
-
-  it('should create a root workspace for newly registered user', async () => {
-    await createHandler().handle(event)
-
-    expect(createWorkspace.execute).toHaveBeenCalledWith({
-      ownerUuid: '1-2-3',
-      type: 'root',
-    })
-  })
-
-  it('should not create a root workspace for newly registered user on legacy protocols', async () => {
-    event.payload.protocolVersion = ProtocolVersion.V004
-
-    await createHandler().handle(event)
-
-    expect(createWorkspace.execute).not.toHaveBeenCalled()
-  })
-})

+ 0 - 22
packages/workspace/src/Domain/Handler/UserRegisteredEventHandler.ts

@@ -1,22 +0,0 @@
-import { ProtocolVersion, WorkspaceType } from '@standardnotes/common'
-import { DomainEventHandlerInterface, UserRegisteredEvent } from '@standardnotes/domain-events'
-import { inject, injectable } from 'inversify'
-
-import TYPES from '../../Bootstrap/Types'
-import { CreateWorkspace } from '../UseCase/CreateWorkspace/CreateWorkspace'
-
-@injectable()
-export class UserRegisteredEventHandler implements DomainEventHandlerInterface {
-  constructor(@inject(TYPES.CreateWorkspace) private createWorkspace: CreateWorkspace) {}
-
-  async handle(event: UserRegisteredEvent): Promise<void> {
-    if (event.payload.protocolVersion !== ProtocolVersion.V005) {
-      return
-    }
-
-    await this.createWorkspace.execute({
-      ownerUuid: event.payload.userUuid,
-      type: WorkspaceType.Root,
-    })
-  }
-}

+ 0 - 76
packages/workspace/src/Domain/Invite/WorkspaceInvite.ts

@@ -1,76 +0,0 @@
-import { WorkspaceAccessLevel } from '@standardnotes/common'
-import { Column, Entity, JoinColumn, ManyToOne, PrimaryGeneratedColumn } from 'typeorm'
-
-import { Workspace } from '../Workspace/Workspace'
-import { WorkspaceInviteStatus } from './WorkspaceInviteStatus'
-
-@Entity({ name: 'workspace_invites' })
-export class WorkspaceInvite {
-  @PrimaryGeneratedColumn('uuid')
-  declare uuid: string
-
-  @Column({
-    name: 'inviter_uuid',
-    length: 36,
-  })
-  declare inviterUuid: string
-
-  @Column({
-    name: 'invitee_email',
-    length: 255,
-  })
-  declare inviteeEmail: string
-
-  @Column({
-    name: 'status',
-    type: 'varchar',
-    length: 64,
-  })
-  declare status: WorkspaceInviteStatus
-
-  @Column({
-    name: 'accepting_user_uuid',
-    type: 'varchar',
-    length: 36,
-    nullable: true,
-  })
-  declare acceptingUserUuid: string | null
-
-  @Column({
-    name: 'workspace_uuid',
-    length: 36,
-  })
-  declare workspaceUuid: string
-
-  @Column({
-    name: 'access_level',
-    length: 64,
-  })
-  declare accessLevel: WorkspaceAccessLevel
-
-  @Column({
-    name: 'created_at',
-    type: 'bigint',
-  })
-  declare createdAt: number
-
-  @Column({
-    name: 'updated_at',
-    type: 'bigint',
-  })
-  declare updatedAt: number
-
-  @ManyToOne(
-    /* istanbul ignore next */
-    () => Workspace,
-    /* istanbul ignore next */
-    (workspace) => workspace.invites,
-    /* istanbul ignore next */
-    { onDelete: 'CASCADE' },
-  )
-  @JoinColumn(
-    /* istanbul ignore next */
-    { name: 'workspace_uuid' },
-  )
-  declare workspace: Promise<Workspace>
-}

+ 0 - 6
packages/workspace/src/Domain/Invite/WorkspaceInviteRepositoryInterface.ts

@@ -1,6 +0,0 @@
-import { WorkspaceInvite } from './WorkspaceInvite'
-
-export interface WorkspaceInviteRepositoryInterface {
-  findOneByUuid(uuid: string): Promise<WorkspaceInvite | null>
-  save(workspace: WorkspaceInvite): Promise<WorkspaceInvite>
-}

+ 0 - 4
packages/workspace/src/Domain/Invite/WorkspaceInviteStatus.ts

@@ -1,4 +0,0 @@
-export enum WorkspaceInviteStatus {
-  Created = 'created',
-  Accepted = 'accepted',
-}

+ 0 - 3
packages/workspace/src/Domain/Projection/ProjectorInterface.ts

@@ -1,3 +0,0 @@
-export interface ProjectorInterface<T, E> {
-  project(object: T): Promise<E>
-}

+ 0 - 3
packages/workspace/src/Domain/Projection/WorkspaceProjection.ts

@@ -1,3 +0,0 @@
-import { Workspace } from '@standardnotes/api'
-
-export type WorkspaceProjection = Workspace

+ 0 - 30
packages/workspace/src/Domain/Projection/WorkspaceProjector.spec.ts

@@ -1,30 +0,0 @@
-import 'reflect-metadata'
-
-import { WorkspaceType } from '@standardnotes/common'
-import { Workspace } from '../Workspace/Workspace'
-
-import { WorkspaceProjector } from './WorkspaceProjector'
-
-describe('WorkspaceProjector', () => {
-  const createProjector = () => new WorkspaceProjector()
-
-  it('should project a workspace', async () => {
-    expect(
-      await createProjector().project({
-        uuid: 'w-1-2-3',
-        type: WorkspaceType.Private,
-        name: 'test',
-        keyRotationIndex: 0,
-        createdAt: 1,
-        updatedAt: 2,
-      } as jest.Mocked<Workspace>),
-    ).toEqual({
-      uuid: 'w-1-2-3',
-      type: 'private',
-      name: 'test',
-      keyRotationIndex: 0,
-      createdAt: 1,
-      updatedAt: 2,
-    })
-  })
-})

+ 0 - 19
packages/workspace/src/Domain/Projection/WorkspaceProjector.ts

@@ -1,19 +0,0 @@
-import { injectable } from 'inversify'
-import { ProjectorInterface } from './ProjectorInterface'
-
-import { WorkspaceProjection } from './WorkspaceProjection'
-import { Workspace } from '../Workspace/Workspace'
-
-@injectable()
-export class WorkspaceProjector implements ProjectorInterface<Workspace, WorkspaceProjection> {
-  async project(workspace: Workspace): Promise<WorkspaceProjection> {
-    return {
-      uuid: workspace.uuid,
-      type: workspace.type,
-      name: workspace.name,
-      keyRotationIndex: workspace.keyRotationIndex,
-      createdAt: workspace.createdAt,
-      updatedAt: workspace.updatedAt,
-    }
-  }
-}

+ 0 - 3
packages/workspace/src/Domain/Projection/WorkspaceUserProjection.ts

@@ -1,3 +0,0 @@
-import { WorkspaceUser } from '@standardnotes/api'
-
-export type WorkspaceUserProjection = WorkspaceUser

+ 0 - 42
packages/workspace/src/Domain/Projection/WorkspaceUserProjector.spec.ts

@@ -1,42 +0,0 @@
-import 'reflect-metadata'
-
-import { WorkspaceAccessLevel, WorkspaceUserStatus } from '@standardnotes/common'
-import { WorkspaceUser } from '../Workspace/WorkspaceUser'
-
-import { WorkspaceUserProjector } from './WorkspaceUserProjector'
-
-describe('WorkspaceUserProjector', () => {
-  const createProjector = () => new WorkspaceUserProjector()
-
-  it('should project a workspace user', async () => {
-    expect(
-      await createProjector().project({
-        uuid: '1-2-3',
-        accessLevel: WorkspaceAccessLevel.Owner,
-        userUuid: 'u-1-2-3',
-        userDisplayName: 'foobar',
-        workspaceUuid: 'w-1-2-3',
-        encryptedWorkspaceKey: 'foo',
-        publicKey: 'bar',
-        encryptedPrivateKey: 'buzz',
-        status: WorkspaceUserStatus.PendingKeyshare,
-        keyRotationIndex: 0,
-        createdAt: 1,
-        updatedAt: 2,
-      } as jest.Mocked<WorkspaceUser>),
-    ).toEqual({
-      uuid: '1-2-3',
-      accessLevel: 'owner',
-      userUuid: 'u-1-2-3',
-      userDisplayName: 'foobar',
-      workspaceUuid: 'w-1-2-3',
-      encryptedWorkspaceKey: 'foo',
-      publicKey: 'bar',
-      encryptedPrivateKey: 'buzz',
-      status: 'pending-keyshare',
-      keyRotationIndex: 0,
-      createdAt: 1,
-      updatedAt: 2,
-    })
-  })
-})

+ 0 - 25
packages/workspace/src/Domain/Projection/WorkspaceUserProjector.ts

@@ -1,25 +0,0 @@
-import { injectable } from 'inversify'
-import { ProjectorInterface } from './ProjectorInterface'
-
-import { WorkspaceUserProjection } from './WorkspaceUserProjection'
-import { WorkspaceUser } from '../Workspace/WorkspaceUser'
-
-@injectable()
-export class WorkspaceUserProjector implements ProjectorInterface<WorkspaceUser, WorkspaceUserProjection> {
-  async project(workspaceUser: WorkspaceUser): Promise<WorkspaceUserProjection> {
-    return {
-      uuid: workspaceUser.uuid,
-      accessLevel: workspaceUser.accessLevel,
-      userUuid: workspaceUser.userUuid,
-      userDisplayName: workspaceUser.userDisplayName,
-      workspaceUuid: workspaceUser.workspaceUuid,
-      encryptedWorkspaceKey: workspaceUser.encryptedWorkspaceKey,
-      publicKey: workspaceUser.publicKey,
-      encryptedPrivateKey: workspaceUser.encryptedPrivateKey,
-      status: workspaceUser.status,
-      keyRotationIndex: workspaceUser.keyRotationIndex,
-      createdAt: workspaceUser.createdAt,
-      updatedAt: workspaceUser.updatedAt,
-    }
-  }
-}

+ 0 - 106
packages/workspace/src/Domain/UseCase/AcceptInvitation/AcceptInvitation.spec.ts

@@ -1,106 +0,0 @@
-import 'reflect-metadata'
-import { TimerInterface } from '@standardnotes/time'
-
-import { WorkspaceInvite } from '../../Invite/WorkspaceInvite'
-import { WorkspaceInviteRepositoryInterface } from '../../Invite/WorkspaceInviteRepositoryInterface'
-import { WorkspaceUserRepositoryInterface } from '../../Workspace/WorkspaceUserRepositoryInterface'
-
-import { AcceptInvitation } from './AcceptInvitation'
-import { WorkspaceAccessLevel } from '@standardnotes/common'
-import { DomainEventFactoryInterface } from '../../Event/DomainEventFactoryInterface'
-import {
-  DomainEventPublisherInterface,
-  WebSocketMessageRequestedEvent,
-  WorkspaceInviteAcceptedEvent,
-} from '@standardnotes/domain-events'
-
-describe('AcceptInvitation', () => {
-  let workspaceInviteRepository: WorkspaceInviteRepositoryInterface
-  let workspaceUserRepository: WorkspaceUserRepositoryInterface
-  let domainEventFactory: DomainEventFactoryInterface
-  let domainEventPublisher: DomainEventPublisherInterface
-  let timer: TimerInterface
-  let invite: WorkspaceInvite
-
-  const createUseCase = () =>
-    new AcceptInvitation(
-      workspaceInviteRepository,
-      workspaceUserRepository,
-      domainEventFactory,
-      domainEventPublisher,
-      timer,
-    )
-
-  beforeEach(() => {
-    invite = {
-      uuid: 'i-1-2-3',
-      workspaceUuid: 'w-1-2-3',
-      inviteeEmail: 'test@test.te',
-      accessLevel: WorkspaceAccessLevel.WriteAndRead,
-    } as jest.Mocked<WorkspaceInvite>
-    workspaceInviteRepository = {} as jest.Mocked<WorkspaceInviteRepositoryInterface>
-    workspaceInviteRepository.findOneByUuid = jest.fn().mockReturnValue(invite)
-    workspaceInviteRepository.save = jest.fn()
-
-    workspaceUserRepository = {} as jest.Mocked<WorkspaceUserRepositoryInterface>
-    workspaceUserRepository.save = jest.fn()
-
-    timer = {} as jest.Mocked<TimerInterface>
-    timer.getTimestampInMicroseconds = jest.fn().mockReturnValue(1)
-
-    domainEventFactory = {} as jest.Mocked<DomainEventFactoryInterface>
-    domainEventFactory.createWebSocketMessageRequestedEvent = jest
-      .fn()
-      .mockReturnValue({} as jest.Mocked<WebSocketMessageRequestedEvent>)
-    domainEventFactory.createWorkspaceInviteAcceptedEvent = jest
-      .fn()
-      .mockReturnValue({} as jest.Mocked<WorkspaceInviteAcceptedEvent>)
-
-    domainEventPublisher = {} as jest.Mocked<DomainEventPublisherInterface>
-    domainEventPublisher.publish = jest.fn()
-  })
-
-  it('should accept an invite and assign user to workspace', async () => {
-    await createUseCase().execute({
-      acceptingUserUuid: 'u-1-2-3',
-      encryptedPrivateKey: 'foo',
-      publicKey: 'bar',
-      invitationUuid: 'i-1-2-3',
-    })
-
-    expect(workspaceInviteRepository.save).toHaveBeenCalledWith({
-      acceptingUserUuid: 'u-1-2-3',
-      status: 'accepted',
-      updatedAt: 1,
-      uuid: 'i-1-2-3',
-      workspaceUuid: 'w-1-2-3',
-      inviteeEmail: 'test@test.te',
-      accessLevel: 'write-and-read',
-    })
-    expect(workspaceUserRepository.save).toHaveBeenCalledWith({
-      encryptedPrivateKey: 'foo',
-      publicKey: 'bar',
-      status: 'pending-keyshare',
-      userUuid: 'u-1-2-3',
-      workspaceUuid: 'w-1-2-3',
-      accessLevel: 'write-and-read',
-      userDisplayName: 'test@test.te',
-      createdAt: 1,
-      updatedAt: 1,
-    })
-  })
-
-  it('should not accept an invite if it does not exist', async () => {
-    workspaceInviteRepository.findOneByUuid = jest.fn().mockReturnValue(null)
-
-    await createUseCase().execute({
-      acceptingUserUuid: 'u-1-2-3',
-      encryptedPrivateKey: 'foo',
-      publicKey: 'bar',
-      invitationUuid: 'i-1-2-3',
-    })
-
-    expect(workspaceInviteRepository.save).not.toHaveBeenCalled()
-    expect(workspaceUserRepository.save).not.toHaveBeenCalled()
-  })
-})

+ 0 - 72
packages/workspace/src/Domain/UseCase/AcceptInvitation/AcceptInvitation.ts

@@ -1,72 +0,0 @@
-import { TimerInterface } from '@standardnotes/time'
-import { WorkspaceUserStatus } from '@standardnotes/common'
-import { inject, injectable } from 'inversify'
-
-import TYPES from '../../../Bootstrap/Types'
-import { WorkspaceInviteRepositoryInterface } from '../../Invite/WorkspaceInviteRepositoryInterface'
-import { WorkspaceInviteStatus } from '../../Invite/WorkspaceInviteStatus'
-import { WorkspaceUser } from '../../Workspace/WorkspaceUser'
-import { WorkspaceUserRepositoryInterface } from '../../Workspace/WorkspaceUserRepositoryInterface'
-import { UseCaseInterface } from '../UseCaseInterface'
-
-import { AcceptInvitationDTO } from './AcceptInvitationDTO'
-import { AcceptInvitationResponse } from './AcceptInvitationResponse'
-import { DomainEventFactoryInterface } from '../../Event/DomainEventFactoryInterface'
-import { DomainEventPublisherInterface } from '@standardnotes/domain-events'
-
-@injectable()
-export class AcceptInvitation implements UseCaseInterface {
-  constructor(
-    @inject(TYPES.WorkspaceInviteRepository) private workspaceInviteRepository: WorkspaceInviteRepositoryInterface,
-    @inject(TYPES.WorkspaceUserRepository) private workspaceUserRepository: WorkspaceUserRepositoryInterface,
-    @inject(TYPES.DomainEventFactory) private domainEventFactory: DomainEventFactoryInterface,
-    @inject(TYPES.DomainEventPublisher) private domainEventPublisher: DomainEventPublisherInterface,
-    @inject(TYPES.Timer) private timer: TimerInterface,
-  ) {}
-
-  async execute(dto: AcceptInvitationDTO): Promise<AcceptInvitationResponse> {
-    const invite = await this.workspaceInviteRepository.findOneByUuid(dto.invitationUuid)
-    if (invite === null) {
-      return {
-        success: false,
-      }
-    }
-
-    const timestamp = this.timer.getTimestampInMicroseconds()
-    invite.acceptingUserUuid = dto.acceptingUserUuid
-    invite.updatedAt = timestamp
-    invite.status = WorkspaceInviteStatus.Accepted
-
-    await this.workspaceInviteRepository.save(invite)
-
-    const workspaceUser = new WorkspaceUser()
-    workspaceUser.userUuid = dto.acceptingUserUuid
-    workspaceUser.userDisplayName = invite.inviteeEmail
-    workspaceUser.workspaceUuid = invite.workspaceUuid
-    workspaceUser.publicKey = dto.publicKey
-    workspaceUser.encryptedPrivateKey = dto.encryptedPrivateKey
-    workspaceUser.accessLevel = invite.accessLevel
-    workspaceUser.status = WorkspaceUserStatus.PendingKeyshare
-    workspaceUser.createdAt = timestamp
-    workspaceUser.updatedAt = timestamp
-
-    await this.workspaceUserRepository.save(workspaceUser)
-
-    const event = this.domainEventFactory.createWorkspaceInviteAcceptedEvent({
-      inviteeUuid: invite.acceptingUserUuid,
-      inviterUuid: invite.inviterUuid,
-      workspaceUuid: invite.workspaceUuid,
-    })
-
-    await this.domainEventPublisher.publish(
-      this.domainEventFactory.createWebSocketMessageRequestedEvent({
-        userUuid: invite.inviterUuid,
-        message: JSON.stringify(event),
-      }),
-    )
-
-    return {
-      success: true,
-    }
-  }
-}

+ 0 - 6
packages/workspace/src/Domain/UseCase/AcceptInvitation/AcceptInvitationDTO.ts

@@ -1,6 +0,0 @@
-export type AcceptInvitationDTO = {
-  invitationUuid: string
-  acceptingUserUuid: string
-  publicKey: string
-  encryptedPrivateKey: string
-}

+ 0 - 3
packages/workspace/src/Domain/UseCase/AcceptInvitation/AcceptInvitationResponse.ts

@@ -1,3 +0,0 @@
-export type AcceptInvitationResponse = {
-  success: boolean
-}

+ 0 - 83
packages/workspace/src/Domain/UseCase/CreateWorkspace/CreateWorkspace.spec.ts

@@ -1,83 +0,0 @@
-import 'reflect-metadata'
-
-import { WorkspaceType } from '@standardnotes/common'
-
-import { WorkspaceRepositoryInterface } from '../../Workspace/WorkspaceRepositoryInterface'
-import { WorkspaceUserRepositoryInterface } from '../../Workspace/WorkspaceUserRepositoryInterface'
-
-import { CreateWorkspace } from './CreateWorkspace'
-import { TimerInterface } from '@standardnotes/time'
-
-describe('CreateWorkspace', () => {
-  let workspaceRepository: WorkspaceRepositoryInterface
-  let workspaceUserRepository: WorkspaceUserRepositoryInterface
-  let timer: TimerInterface
-
-  const createUseCase = () => new CreateWorkspace(workspaceRepository, workspaceUserRepository, timer)
-
-  beforeEach(() => {
-    timer = {} as jest.Mocked<TimerInterface>
-    timer.getTimestampInMicroseconds = jest.fn().mockReturnValue(1)
-
-    workspaceRepository = {} as jest.Mocked<WorkspaceRepositoryInterface>
-    workspaceRepository.save = jest.fn().mockImplementation((workspace) => {
-      return {
-        ...workspace,
-        uuid: 'w-1-2-3',
-      }
-    })
-
-    workspaceUserRepository = {} as jest.Mocked<WorkspaceUserRepositoryInterface>
-    workspaceUserRepository.save = jest.fn()
-  })
-
-  it('should create a workspace and owner association with it', async () => {
-    await createUseCase().execute({
-      encryptedPrivateKey: 'foo',
-      encryptedWorkspaceKey: 'bar',
-      publicKey: 'buzz',
-      name: 'A Team',
-      ownerUuid: '1-2-3',
-      type: WorkspaceType.Root,
-    })
-
-    expect(workspaceRepository.save).toHaveBeenCalledWith({
-      name: 'A Team',
-      type: 'root',
-      createdAt: 1,
-      updatedAt: 1,
-    })
-    expect(workspaceUserRepository.save).toHaveBeenCalledWith({
-      accessLevel: 'owner',
-      encryptedWorkspaceKey: 'bar',
-      encryptedPrivateKey: 'foo',
-      publicKey: 'buzz',
-      status: 'active',
-      userUuid: '1-2-3',
-      workspaceUuid: 'w-1-2-3',
-      createdAt: 1,
-      updatedAt: 1,
-    })
-  })
-
-  it('should create a workspace without optional parameters', async () => {
-    await createUseCase().execute({
-      ownerUuid: '1-2-3',
-      type: WorkspaceType.Private,
-    })
-
-    expect(workspaceRepository.save).toHaveBeenCalledWith({
-      type: 'private',
-      createdAt: 1,
-      updatedAt: 1,
-    })
-    expect(workspaceUserRepository.save).toHaveBeenCalledWith({
-      accessLevel: 'owner',
-      status: 'active',
-      userUuid: '1-2-3',
-      workspaceUuid: 'w-1-2-3',
-      createdAt: 1,
-      updatedAt: 1,
-    })
-  })
-})

+ 0 - 56
packages/workspace/src/Domain/UseCase/CreateWorkspace/CreateWorkspace.ts

@@ -1,56 +0,0 @@
-import { TimerInterface } from '@standardnotes/time'
-import { WorkspaceAccessLevel, WorkspaceUserStatus } from '@standardnotes/common'
-import { inject, injectable } from 'inversify'
-
-import TYPES from '../../../Bootstrap/Types'
-import { Workspace } from '../../Workspace/Workspace'
-import { WorkspaceRepositoryInterface } from '../../Workspace/WorkspaceRepositoryInterface'
-import { WorkspaceUser } from '../../Workspace/WorkspaceUser'
-import { WorkspaceUserRepositoryInterface } from '../../Workspace/WorkspaceUserRepositoryInterface'
-import { UseCaseInterface } from '../UseCaseInterface'
-
-import { CreateWorkspaceDTO } from './CreateWorkspaceDTO'
-import { CreateWorkspaceResponse } from './CreateWorkspaceResponse'
-
-@injectable()
-export class CreateWorkspace implements UseCaseInterface {
-  constructor(
-    @inject(TYPES.WorkspaceRepository) private workspaceRepository: WorkspaceRepositoryInterface,
-    @inject(TYPES.WorkspaceUserRepository) private workspaceUserRepository: WorkspaceUserRepositoryInterface,
-    @inject(TYPES.Timer) private timer: TimerInterface,
-  ) {}
-
-  async execute(dto: CreateWorkspaceDTO): Promise<CreateWorkspaceResponse> {
-    let workspace = new Workspace()
-    if (dto.name !== undefined) {
-      workspace.name = dto.name
-    }
-    workspace.type = dto.type
-    const timestamp = this.timer.getTimestampInMicroseconds()
-    workspace.createdAt = timestamp
-    workspace.updatedAt = timestamp
-
-    workspace = await this.workspaceRepository.save(workspace)
-
-    const ownerAssociation = new WorkspaceUser()
-    ownerAssociation.accessLevel = WorkspaceAccessLevel.Owner
-    if (dto.encryptedWorkspaceKey !== undefined) {
-      ownerAssociation.encryptedWorkspaceKey = dto.encryptedWorkspaceKey
-    }
-    if (dto.encryptedPrivateKey !== undefined) {
-      ownerAssociation.encryptedPrivateKey = dto.encryptedPrivateKey
-    }
-    if (dto.publicKey !== undefined) {
-      ownerAssociation.publicKey = dto.publicKey
-    }
-    ownerAssociation.status = WorkspaceUserStatus.Active
-    ownerAssociation.userUuid = dto.ownerUuid
-    ownerAssociation.workspaceUuid = workspace.uuid
-    ownerAssociation.createdAt = timestamp
-    ownerAssociation.updatedAt = timestamp
-
-    await this.workspaceUserRepository.save(ownerAssociation)
-
-    return { workspace }
-  }
-}

+ 0 - 10
packages/workspace/src/Domain/UseCase/CreateWorkspace/CreateWorkspaceDTO.ts

@@ -1,10 +0,0 @@
-import { WorkspaceType } from '@standardnotes/common'
-
-export type CreateWorkspaceDTO = {
-  ownerUuid: string
-  type: WorkspaceType
-  encryptedWorkspaceKey?: string
-  encryptedPrivateKey?: string
-  publicKey?: string
-  name?: string
-}

+ 0 - 5
packages/workspace/src/Domain/UseCase/CreateWorkspace/CreateWorkspaceResponse.ts

@@ -1,5 +0,0 @@
-import { Workspace } from '../../Workspace/Workspace'
-
-export type CreateWorkspaceResponse = {
-  workspace: Workspace
-}

+ 0 - 100
packages/workspace/src/Domain/UseCase/InitiateKeyShare/InitiateKeyShare.spec.ts

@@ -1,100 +0,0 @@
-import 'reflect-metadata'
-
-import { TimerInterface } from '@standardnotes/time'
-
-import { WorkspaceUser } from '../../Workspace/WorkspaceUser'
-import { WorkspaceUserRepositoryInterface } from '../../Workspace/WorkspaceUserRepositoryInterface'
-
-import { InitiateKeyShare } from './InitiateKeyShare'
-import { WorkspaceAccessLevel } from '@standardnotes/common'
-
-describe('InitiateKeyShare', () => {
-  let workspaceUserRepository: WorkspaceUserRepositoryInterface
-  let timer: TimerInterface
-  let workspaceUser: WorkspaceUser
-  let workspaceOwner: WorkspaceUser
-
-  const createUseCase = () => new InitiateKeyShare(workspaceUserRepository, timer)
-
-  beforeEach(() => {
-    workspaceOwner = {
-      accessLevel: WorkspaceAccessLevel.Owner,
-    } as jest.Mocked<WorkspaceUser>
-    workspaceUser = {} as jest.Mocked<WorkspaceUser>
-
-    workspaceUserRepository = {} as jest.Mocked<WorkspaceUserRepositoryInterface>
-    workspaceUserRepository.findOneByUserUuidAndWorkspaceUuid = jest
-      .fn()
-      .mockReturnValueOnce(workspaceOwner)
-      .mockReturnValueOnce(workspaceUser)
-    workspaceUserRepository.save = jest.fn().mockImplementation((user: WorkspaceUser) => user)
-
-    timer = {} as jest.Mocked<TimerInterface>
-    timer.getTimestampInMicroseconds = jest.fn().mockReturnValue(1)
-  })
-
-  it('should update the workspace user with a workspace key and mark as active', async () => {
-    await createUseCase().execute({
-      workspaceUuid: 'w-1-2-3',
-      userUuid: 'u-1-2-3',
-      encryptedWorkspaceKey: 'foobar',
-      performingUserUuid: 'o-1-2-3',
-    })
-
-    expect(workspaceUserRepository.save).toHaveBeenCalledWith({
-      encryptedWorkspaceKey: 'foobar',
-      status: 'active',
-      updatedAt: 1,
-    })
-  })
-
-  it('should not initiate key share if workspace is not found', async () => {
-    workspaceUserRepository.findOneByUserUuidAndWorkspaceUuid = jest
-      .fn()
-      .mockReturnValueOnce(workspaceOwner)
-      .mockReturnValueOnce(null)
-
-    await createUseCase().execute({
-      workspaceUuid: 'w-1-2-3',
-      userUuid: 'u-1-2-3',
-      encryptedWorkspaceKey: 'foobar',
-      performingUserUuid: 'o-1-2-3',
-    })
-
-    expect(workspaceUserRepository.save).not.toHaveBeenCalled()
-  })
-
-  it('should not initiate key share if workspace performing user is not the owner or admin', async () => {
-    workspaceOwner.accessLevel = WorkspaceAccessLevel.ReadOnly
-    workspaceUserRepository.findOneByUserUuidAndWorkspaceUuid = jest
-      .fn()
-      .mockReturnValueOnce(workspaceOwner)
-      .mockReturnValueOnce(workspaceUser)
-
-    await createUseCase().execute({
-      workspaceUuid: 'w-1-2-3',
-      userUuid: 'u-1-2-3',
-      encryptedWorkspaceKey: 'foobar',
-      performingUserUuid: 'o-1-2-3',
-    })
-
-    expect(workspaceUserRepository.save).not.toHaveBeenCalled()
-  })
-
-  it('should not initiate key share if workspace performing user is found in workspace', async () => {
-    workspaceOwner.accessLevel = WorkspaceAccessLevel.ReadOnly
-    workspaceUserRepository.findOneByUserUuidAndWorkspaceUuid = jest
-      .fn()
-      .mockReturnValueOnce(null)
-      .mockReturnValueOnce(workspaceUser)
-
-    await createUseCase().execute({
-      workspaceUuid: 'w-1-2-3',
-      userUuid: 'u-1-2-3',
-      encryptedWorkspaceKey: 'foobar',
-      performingUserUuid: 'o-1-2-3',
-    })
-
-    expect(workspaceUserRepository.save).not.toHaveBeenCalled()
-  })
-})

+ 0 - 52
packages/workspace/src/Domain/UseCase/InitiateKeyShare/InitiateKeyShare.ts

@@ -1,52 +0,0 @@
-import { WorkspaceAccessLevel, WorkspaceUserStatus } from '@standardnotes/common'
-import { TimerInterface } from '@standardnotes/time'
-import { inject, injectable } from 'inversify'
-import TYPES from '../../../Bootstrap/Types'
-import { WorkspaceUserRepositoryInterface } from '../../Workspace/WorkspaceUserRepositoryInterface'
-import { UseCaseInterface } from '../UseCaseInterface'
-import { InitiateKeyShareDTO } from './InitiateKeyShareDTO'
-import { InitiateKeyShareResponse } from './InitiateKeyShareResponse'
-
-@injectable()
-export class InitiateKeyShare implements UseCaseInterface {
-  constructor(
-    @inject(TYPES.WorkspaceUserRepository) private workspaceUserRepository: WorkspaceUserRepositoryInterface,
-    @inject(TYPES.Timer) private timer: TimerInterface,
-  ) {}
-
-  async execute(dto: InitiateKeyShareDTO): Promise<InitiateKeyShareResponse> {
-    const workspaceOwner = await this.workspaceUserRepository.findOneByUserUuidAndWorkspaceUuid({
-      workspaceUuid: dto.workspaceUuid,
-      userUuid: dto.performingUserUuid,
-    })
-    if (
-      workspaceOwner === null ||
-      ![WorkspaceAccessLevel.Admin, WorkspaceAccessLevel.Owner].includes(workspaceOwner.accessLevel)
-    ) {
-      return {
-        success: false,
-      }
-    }
-
-    const workspaceUser = await this.workspaceUserRepository.findOneByUserUuidAndWorkspaceUuid({
-      workspaceUuid: dto.workspaceUuid,
-      userUuid: dto.userUuid,
-    })
-
-    if (workspaceUser === null) {
-      return {
-        success: false,
-      }
-    }
-
-    workspaceUser.encryptedWorkspaceKey = dto.encryptedWorkspaceKey
-    workspaceUser.status = WorkspaceUserStatus.Active
-    workspaceUser.updatedAt = this.timer.getTimestampInMicroseconds()
-
-    await this.workspaceUserRepository.save(workspaceUser)
-
-    return {
-      success: true,
-    }
-  }
-}

+ 0 - 6
packages/workspace/src/Domain/UseCase/InitiateKeyShare/InitiateKeyShareDTO.ts

@@ -1,6 +0,0 @@
-export type InitiateKeyShareDTO = {
-  workspaceUuid: string
-  userUuid: string
-  performingUserUuid: string
-  encryptedWorkspaceKey: string
-}

+ 0 - 3
packages/workspace/src/Domain/UseCase/InitiateKeyShare/InitiateKeyShareResponse.ts

@@ -1,3 +0,0 @@
-export type InitiateKeyShareResponse = {
-  success: boolean
-}

+ 0 - 72
packages/workspace/src/Domain/UseCase/InviteToWorkspace/InviteToWorkspace.spec.ts

@@ -1,72 +0,0 @@
-import 'reflect-metadata'
-import { TimerInterface } from '@standardnotes/time'
-
-import { WorkspaceInviteRepositoryInterface } from '../../Invite/WorkspaceInviteRepositoryInterface'
-
-import { InviteToWorkspace } from './InviteToWorkspace'
-import { DomainEventFactoryInterface } from '../../Event/DomainEventFactoryInterface'
-import { DomainEventPublisherInterface, EmailRequestedEvent } from '@standardnotes/domain-events'
-import { WorkspaceAccessLevel } from '@standardnotes/common'
-
-describe('InviteToWorkspace', () => {
-  let workspaceInviteRepository: WorkspaceInviteRepositoryInterface
-  let timer: TimerInterface
-  let domainEventFactory: DomainEventFactoryInterface
-  let domainEventPublisher: DomainEventPublisherInterface
-
-  const createUseCase = () =>
-    new InviteToWorkspace(workspaceInviteRepository, timer, domainEventFactory, domainEventPublisher)
-
-  beforeEach(() => {
-    workspaceInviteRepository = {} as jest.Mocked<WorkspaceInviteRepositoryInterface>
-    workspaceInviteRepository.save = jest.fn().mockImplementation((invite) => {
-      return {
-        ...invite,
-        uuid: 'i-1-2-3',
-      }
-    })
-
-    timer = {} as jest.Mocked<TimerInterface>
-    timer.getTimestampInMicroseconds = jest.fn().mockReturnValue(1)
-
-    domainEventPublisher = {} as jest.Mocked<DomainEventPublisherInterface>
-    domainEventPublisher.publish = jest.fn()
-
-    domainEventFactory = {} as jest.Mocked<DomainEventFactoryInterface>
-    domainEventFactory.createEmailRequestedEvent = jest.fn().mockReturnValue({} as jest.Mocked<EmailRequestedEvent>)
-  })
-
-  it('should create an invite', async () => {
-    const result = await createUseCase().execute({
-      inviteeEmail: 'test@test.te',
-      inviterUuid: 'u-1-2-3',
-      workspaceUuid: 'w-1-2-3',
-      accessLevel: WorkspaceAccessLevel.WriteAndRead,
-    })
-
-    expect(result).toEqual({
-      invite: {
-        uuid: 'i-1-2-3',
-        inviterUuid: 'u-1-2-3',
-        inviteeEmail: 'test@test.te',
-        workspaceUuid: 'w-1-2-3',
-        status: 'created',
-        accessLevel: 'write-and-read',
-        createdAt: 1,
-        updatedAt: 1,
-      },
-    })
-
-    expect(workspaceInviteRepository.save).toHaveBeenCalledWith({
-      accessLevel: 'write-and-read',
-      inviterUuid: 'u-1-2-3',
-      inviteeEmail: 'test@test.te',
-      workspaceUuid: 'w-1-2-3',
-      status: 'created',
-      createdAt: 1,
-      updatedAt: 1,
-    })
-
-    expect(domainEventPublisher.publish).toHaveBeenCalled()
-  })
-})

+ 0 - 54
packages/workspace/src/Domain/UseCase/InviteToWorkspace/InviteToWorkspace.ts

@@ -1,54 +0,0 @@
-import { DomainEventPublisherInterface } from '@standardnotes/domain-events'
-import { TimerInterface } from '@standardnotes/time'
-import { EmailLevel } from '@standardnotes/domain-core'
-import { inject, injectable } from 'inversify'
-
-import TYPES from '../../../Bootstrap/Types'
-import { getBody, getSubject } from '../../Email/WorkspaceInviteCreated'
-import { DomainEventFactoryInterface } from '../../Event/DomainEventFactoryInterface'
-import { WorkspaceInvite } from '../../Invite/WorkspaceInvite'
-import { WorkspaceInviteRepositoryInterface } from '../../Invite/WorkspaceInviteRepositoryInterface'
-import { WorkspaceInviteStatus } from '../../Invite/WorkspaceInviteStatus'
-
-import { UseCaseInterface } from '../UseCaseInterface'
-import { InviteToWorkspaceDTO } from './InviteToWorkspaceDTO'
-import { InviteToWorkspaceResponse } from './InviteToWorkspaceResponse'
-
-@injectable()
-export class InviteToWorkspace implements UseCaseInterface {
-  constructor(
-    @inject(TYPES.WorkspaceInviteRepository) private workspaceInviteRepository: WorkspaceInviteRepositoryInterface,
-    @inject(TYPES.Timer) private timer: TimerInterface,
-    @inject(TYPES.DomainEventFactory) private domainEventFactory: DomainEventFactoryInterface,
-    @inject(TYPES.DomainEventPublisher) private domainEventPublisher: DomainEventPublisherInterface,
-  ) {}
-
-  async execute(dto: InviteToWorkspaceDTO): Promise<InviteToWorkspaceResponse> {
-    let invite = new WorkspaceInvite()
-    invite.inviterUuid = dto.inviterUuid
-    invite.inviteeEmail = dto.inviteeEmail
-    invite.workspaceUuid = dto.workspaceUuid
-    invite.accessLevel = dto.accessLevel
-    invite.status = WorkspaceInviteStatus.Created
-
-    const timestamp = this.timer.getTimestampInMicroseconds()
-    invite.createdAt = timestamp
-    invite.updatedAt = timestamp
-
-    invite = await this.workspaceInviteRepository.save(invite)
-
-    await this.domainEventPublisher.publish(
-      this.domainEventFactory.createEmailRequestedEvent({
-        body: getBody(invite.uuid),
-        subject: getSubject(),
-        level: EmailLevel.LEVELS.System,
-        messageIdentifier: 'WORKSPACE_INVITE_CREATED',
-        userEmail: dto.inviteeEmail,
-      }),
-    )
-
-    return {
-      invite,
-    }
-  }
-}

+ 0 - 8
packages/workspace/src/Domain/UseCase/InviteToWorkspace/InviteToWorkspaceDTO.ts

@@ -1,8 +0,0 @@
-import { WorkspaceAccessLevel } from '@standardnotes/common'
-
-export type InviteToWorkspaceDTO = {
-  workspaceUuid: string
-  inviterUuid: string
-  inviteeEmail: string
-  accessLevel: WorkspaceAccessLevel
-}

+ 0 - 5
packages/workspace/src/Domain/UseCase/InviteToWorkspace/InviteToWorkspaceResponse.ts

@@ -1,5 +0,0 @@
-import { WorkspaceInvite } from '../../Invite/WorkspaceInvite'
-
-export type InviteToWorkspaceResponse = {
-  invite: WorkspaceInvite
-}

+ 0 - 84
packages/workspace/src/Domain/UseCase/ListWorkspaceUsers/ListWorkspaceUsers.spec.ts

@@ -1,84 +0,0 @@
-import { WorkspaceAccessLevel } from '@standardnotes/common'
-import 'reflect-metadata'
-import { Workspace } from '../../Workspace/Workspace'
-import { WorkspaceRepositoryInterface } from '../../Workspace/WorkspaceRepositoryInterface'
-import { WorkspaceUser } from '../../Workspace/WorkspaceUser'
-import { WorkspaceUserRepositoryInterface } from '../../Workspace/WorkspaceUserRepositoryInterface'
-
-import { ListWorkspaceUsers } from './ListWorkspaceUsers'
-
-describe('ListWorkspaceUsers', () => {
-  let workspaceRepository: WorkspaceRepositoryInterface
-  let workspaceUserRepository: WorkspaceUserRepositoryInterface
-  let workspace: Workspace
-  let workspaceUser1: WorkspaceUser
-  let workspaceUser2: WorkspaceUser
-
-  const createUseCase = () => new ListWorkspaceUsers(workspaceRepository, workspaceUserRepository)
-
-  beforeEach(() => {
-    workspace = { uuid: 'j-1-2-3' } as jest.Mocked<Workspace>
-
-    workspaceUser1 = { userUuid: 'u-1-2-3', accessLevel: WorkspaceAccessLevel.Owner } as jest.Mocked<WorkspaceUser>
-    workspaceUser2 = {
-      userUuid: 'u-2-3-4',
-      accessLevel: WorkspaceAccessLevel.WriteAndRead,
-    } as jest.Mocked<WorkspaceUser>
-
-    workspaceRepository = {} as jest.Mocked<WorkspaceRepositoryInterface>
-    workspaceRepository.findOneByUuid = jest.fn().mockReturnValue(workspace)
-
-    workspaceUserRepository = {} as jest.Mocked<WorkspaceUserRepositoryInterface>
-    workspaceUserRepository.findByWorkspaceUuid = jest.fn().mockReturnValue([workspaceUser1, workspaceUser2])
-  })
-
-  it('should list users in a workspace where the user is owner or admin', async () => {
-    const result = await createUseCase().execute({
-      userUuid: 'u-1-2-3',
-      workspaceUuid: 'j-1-2-3',
-    })
-
-    expect(result).toEqual({
-      workspaceUsers: [workspaceUser1, workspaceUser2],
-      userIsOwnerOrAdmin: true,
-    })
-  })
-
-  it('should list users in a workspace where the user is not the owner or admin with indiciation', async () => {
-    const result = await createUseCase().execute({
-      userUuid: 'u-2-3-4',
-      workspaceUuid: 'j-1-2-3',
-    })
-
-    expect(result).toEqual({
-      workspaceUsers: [workspaceUser1, workspaceUser2],
-      userIsOwnerOrAdmin: false,
-    })
-  })
-
-  it('should not list users in a workspace where the user does not belong', async () => {
-    const result = await createUseCase().execute({
-      userUuid: 'z-1-2-3',
-      workspaceUuid: 'j-1-2-3',
-    })
-
-    expect(result).toEqual({
-      workspaceUsers: [],
-      userIsOwnerOrAdmin: false,
-    })
-  })
-
-  it('should not list users in a workspace that does not exist', async () => {
-    workspaceRepository.findOneByUuid = jest.fn().mockReturnValue(null)
-
-    const result = await createUseCase().execute({
-      userUuid: 'u-1-2-3',
-      workspaceUuid: 'j-1-2-3',
-    })
-
-    expect(result).toEqual({
-      workspaceUsers: [],
-      userIsOwnerOrAdmin: false,
-    })
-  })
-})

+ 0 - 50
packages/workspace/src/Domain/UseCase/ListWorkspaceUsers/ListWorkspaceUsers.ts

@@ -1,50 +0,0 @@
-import { WorkspaceAccessLevel } from '@standardnotes/common'
-import { inject, injectable } from 'inversify'
-import TYPES from '../../../Bootstrap/Types'
-import { WorkspaceRepositoryInterface } from '../../Workspace/WorkspaceRepositoryInterface'
-import { WorkspaceUserRepositoryInterface } from '../../Workspace/WorkspaceUserRepositoryInterface'
-import { UseCaseInterface } from '../UseCaseInterface'
-import { ListWorkspaceUsersDTO } from './ListWorkspaceUsersDTO'
-import { ListWorkspaceUsersResponse } from './ListWorkspaceUsersResponse'
-
-@injectable()
-export class ListWorkspaceUsers implements UseCaseInterface {
-  constructor(
-    @inject(TYPES.WorkspaceRepository) private workspaceRepository: WorkspaceRepositoryInterface,
-    @inject(TYPES.WorkspaceUserRepository) private workspaceUserRepository: WorkspaceUserRepositoryInterface,
-  ) {}
-
-  async execute(dto: ListWorkspaceUsersDTO): Promise<ListWorkspaceUsersResponse> {
-    const workspace = await this.workspaceRepository.findOneByUuid(dto.workspaceUuid)
-    if (workspace === null) {
-      return {
-        workspaceUsers: [],
-        userIsOwnerOrAdmin: false,
-      }
-    }
-
-    const workspaceUsers = await this.workspaceUserRepository.findByWorkspaceUuid(dto.workspaceUuid)
-    let userIsOwnerOrAdmin = false
-    let userIsInWorkspace = false
-    for (const workspaceUser of workspaceUsers) {
-      if (workspaceUser.userUuid === dto.userUuid) {
-        userIsInWorkspace = true
-        if ([WorkspaceAccessLevel.Admin, WorkspaceAccessLevel.Owner].includes(workspaceUser.accessLevel)) {
-          userIsOwnerOrAdmin = true
-        }
-      }
-    }
-
-    if (!userIsInWorkspace) {
-      return {
-        workspaceUsers: [],
-        userIsOwnerOrAdmin: false,
-      }
-    }
-
-    return {
-      workspaceUsers,
-      userIsOwnerOrAdmin,
-    }
-  }
-}

+ 0 - 4
packages/workspace/src/Domain/UseCase/ListWorkspaceUsers/ListWorkspaceUsersDTO.ts

@@ -1,4 +0,0 @@
-export type ListWorkspaceUsersDTO = {
-  workspaceUuid: string
-  userUuid: string
-}

+ 0 - 6
packages/workspace/src/Domain/UseCase/ListWorkspaceUsers/ListWorkspaceUsersResponse.ts

@@ -1,6 +0,0 @@
-import { WorkspaceUser } from '../../Workspace/WorkspaceUser'
-
-export type ListWorkspaceUsersResponse = {
-  workspaceUsers: WorkspaceUser[]
-  userIsOwnerOrAdmin: boolean
-}

+ 0 - 66
packages/workspace/src/Domain/UseCase/ListWorkspaces/ListWorkspaces.spec.ts

@@ -1,66 +0,0 @@
-import 'reflect-metadata'
-import { WorkspaceAccessLevel } from '@standardnotes/common'
-import { Logger } from 'winston'
-
-import { Workspace } from '../../Workspace/Workspace'
-import { WorkspaceRepositoryInterface } from '../../Workspace/WorkspaceRepositoryInterface'
-import { WorkspaceUser } from '../../Workspace/WorkspaceUser'
-import { WorkspaceUserRepositoryInterface } from '../../Workspace/WorkspaceUserRepositoryInterface'
-
-import { ListWorkspaces } from './ListWorkspaces'
-
-describe('ListWorkspaces', () => {
-  let workspaceRepository: WorkspaceRepositoryInterface
-  let workspaceUserRepository: WorkspaceUserRepositoryInterface
-  let ownedWorkspace: Workspace
-  let joinedWorkspace: Workspace
-  let workspaceUser1: WorkspaceUser
-  let workspaceUser2: WorkspaceUser
-  let logger: Logger
-
-  const createUseCase = () => new ListWorkspaces(workspaceRepository, workspaceUserRepository, logger)
-
-  beforeEach(() => {
-    logger = {} as jest.Mocked<Logger>
-    logger.debug = jest.fn()
-
-    ownedWorkspace = { uuid: 'o-1-2-3' } as jest.Mocked<Workspace>
-    joinedWorkspace = { uuid: 'j-1-2-3' } as jest.Mocked<Workspace>
-
-    workspaceUser1 = { accessLevel: WorkspaceAccessLevel.Owner } as jest.Mocked<WorkspaceUser>
-    workspaceUser2 = { accessLevel: WorkspaceAccessLevel.WriteAndRead } as jest.Mocked<WorkspaceUser>
-
-    workspaceRepository = {} as jest.Mocked<WorkspaceRepositoryInterface>
-    workspaceRepository.findByUuids = jest
-      .fn()
-      .mockReturnValueOnce([ownedWorkspace])
-      .mockReturnValueOnce([joinedWorkspace])
-
-    workspaceUserRepository = {} as jest.Mocked<WorkspaceUserRepositoryInterface>
-    workspaceUserRepository.findByUserUuid = jest.fn().mockReturnValue([workspaceUser1, workspaceUser2])
-  })
-
-  it('should list owned and joined workspaces for a user', async () => {
-    const result = await createUseCase().execute({
-      userUuid: 'u-1-2-3',
-    })
-
-    expect(result).toEqual({
-      ownedWorkspaces: [ownedWorkspace],
-      joinedWorkspaces: [joinedWorkspace],
-    })
-  })
-
-  it('should list empty owned and joined workspaces for a user that does not have any', async () => {
-    workspaceUserRepository.findByUserUuid = jest.fn().mockReturnValue([])
-
-    const result = await createUseCase().execute({
-      userUuid: 'u-1-2-3',
-    })
-
-    expect(result).toEqual({
-      ownedWorkspaces: [],
-      joinedWorkspaces: [],
-    })
-  })
-})

+ 0 - 54
packages/workspace/src/Domain/UseCase/ListWorkspaces/ListWorkspaces.ts

@@ -1,54 +0,0 @@
-import { WorkspaceAccessLevel } from '@standardnotes/common'
-import { inject, injectable } from 'inversify'
-import { Logger } from 'winston'
-
-import TYPES from '../../../Bootstrap/Types'
-import { Workspace } from '../../Workspace/Workspace'
-import { WorkspaceRepositoryInterface } from '../../Workspace/WorkspaceRepositoryInterface'
-import { WorkspaceUserRepositoryInterface } from '../../Workspace/WorkspaceUserRepositoryInterface'
-import { UseCaseInterface } from '../UseCaseInterface'
-
-import { ListWorkspacesDTO } from './ListWorkspacesDTO'
-import { ListWorkspacesResponse } from './ListWorkspacesResponse'
-
-@injectable()
-export class ListWorkspaces implements UseCaseInterface {
-  constructor(
-    @inject(TYPES.WorkspaceRepository) private workspaceRepository: WorkspaceRepositoryInterface,
-    @inject(TYPES.WorkspaceUserRepository) private workspaceUserRepository: WorkspaceUserRepositoryInterface,
-    @inject(TYPES.Logger) private logger: Logger,
-  ) {}
-
-  async execute(dto: ListWorkspacesDTO): Promise<ListWorkspacesResponse> {
-    this.logger.debug(`Listing workspaces for user ${dto.userUuid}`)
-
-    const workspaceAssociations = await this.workspaceUserRepository.findByUserUuid(dto.userUuid)
-
-    const ownedWorkspacesUuids = []
-    const joinedWorkspacesUuids = []
-    for (const workspaceAssociation of workspaceAssociations) {
-      if ([WorkspaceAccessLevel.Admin, WorkspaceAccessLevel.Owner].includes(workspaceAssociation.accessLevel)) {
-        ownedWorkspacesUuids.push(workspaceAssociation.workspaceUuid)
-      } else {
-        joinedWorkspacesUuids.push(workspaceAssociation.workspaceUuid)
-      }
-    }
-
-    this.logger.debug(`Owned workspaces uuids: ${JSON.stringify(ownedWorkspacesUuids)}`)
-    this.logger.debug(`Joined workspaces uuids: ${JSON.stringify(joinedWorkspacesUuids)}`)
-
-    let ownedWorkspaces: Array<Workspace> = []
-    if (ownedWorkspacesUuids.length > 0) {
-      ownedWorkspaces = await this.workspaceRepository.findByUuids(ownedWorkspacesUuids)
-    }
-    let joinedWorkspaces: Array<Workspace> = []
-    if (joinedWorkspacesUuids.length > 0) {
-      joinedWorkspaces = await this.workspaceRepository.findByUuids(joinedWorkspacesUuids)
-    }
-
-    return {
-      ownedWorkspaces,
-      joinedWorkspaces,
-    }
-  }
-}

+ 0 - 3
packages/workspace/src/Domain/UseCase/ListWorkspaces/ListWorkspacesDTO.ts

@@ -1,3 +0,0 @@
-export type ListWorkspacesDTO = {
-  userUuid: string
-}

+ 0 - 6
packages/workspace/src/Domain/UseCase/ListWorkspaces/ListWorkspacesResponse.ts

@@ -1,6 +0,0 @@
-import { Workspace } from '../../Workspace/Workspace'
-
-export type ListWorkspacesResponse = {
-  ownedWorkspaces: Array<Workspace>
-  joinedWorkspaces: Array<Workspace>
-}

+ 0 - 3
packages/workspace/src/Domain/UseCase/UseCaseInterface.ts

@@ -1,3 +0,0 @@
-export interface UseCaseInterface {
-  execute(...args: any[]): Promise<Record<string, unknown>>
-}

+ 0 - 56
packages/workspace/src/Domain/Workspace/Workspace.ts

@@ -1,56 +0,0 @@
-import { WorkspaceType } from '@standardnotes/common'
-import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from 'typeorm'
-import { WorkspaceInvite } from '../Invite/WorkspaceInvite'
-import { WorkspaceUser } from './WorkspaceUser'
-
-@Entity({ name: 'workspaces' })
-export class Workspace {
-  @PrimaryGeneratedColumn('uuid')
-  declare uuid: string
-
-  @Column({
-    length: 64,
-  })
-  declare type: WorkspaceType
-
-  @Column({
-    length: 255,
-    nullable: true,
-    type: 'varchar',
-  })
-  declare name: string | null
-
-  @Column({
-    name: 'key_rotation_index',
-    default: 0,
-  })
-  declare keyRotationIndex: number
-
-  @Column({
-    name: 'created_at',
-    type: 'bigint',
-  })
-  declare createdAt: number
-
-  @Column({
-    name: 'updated_at',
-    type: 'bigint',
-  })
-  declare updatedAt: number
-
-  @OneToMany(
-    /* istanbul ignore next */
-    () => WorkspaceInvite,
-    /* istanbul ignore next */
-    (workspaceInvite) => workspaceInvite.workspace,
-  )
-  declare invites: Promise<WorkspaceInvite[]>
-
-  @OneToMany(
-    /* istanbul ignore next */
-    () => WorkspaceUser,
-    /* istanbul ignore next */
-    (workspaceUser) => workspaceUser.workspace,
-  )
-  declare users: Promise<WorkspaceUser[]>
-}

+ 0 - 7
packages/workspace/src/Domain/Workspace/WorkspaceRepositoryInterface.ts

@@ -1,7 +0,0 @@
-import { Workspace } from './Workspace'
-
-export interface WorkspaceRepositoryInterface {
-  save(workspace: Workspace): Promise<Workspace>
-  findByUuids(uuids: string[]): Promise<Workspace[]>
-  findOneByUuid(uuid: string): Promise<Workspace | null>
-}

+ 0 - 98
packages/workspace/src/Domain/Workspace/WorkspaceUser.ts

@@ -1,98 +0,0 @@
-import { WorkspaceAccessLevel, WorkspaceUserStatus } from '@standardnotes/common'
-import { Column, Entity, Index, JoinColumn, ManyToOne, PrimaryGeneratedColumn } from 'typeorm'
-import { Workspace } from './Workspace'
-
-@Entity({ name: 'workspace_users' })
-@Index('index_workspace_users_on_workspace_and_user', ['userUuid', 'workspaceUuid'], { unique: true })
-export class WorkspaceUser {
-  @PrimaryGeneratedColumn('uuid')
-  declare uuid: string
-
-  @Column({
-    name: 'access_level',
-    length: 64,
-  })
-  declare accessLevel: WorkspaceAccessLevel
-
-  @Column({
-    name: 'user_uuid',
-    length: 36,
-  })
-  declare userUuid: string
-
-  @Column({
-    name: 'user_display_name',
-    type: 'varchar',
-    length: 255,
-    nullable: true,
-  })
-  declare userDisplayName: string | null
-
-  @Column({
-    name: 'workspace_uuid',
-    length: 36,
-  })
-  declare workspaceUuid: string
-
-  @Column({
-    name: 'encrypted_workspace_key',
-    length: 255,
-    type: 'varchar',
-    nullable: true,
-  })
-  declare encryptedWorkspaceKey: string | null
-
-  @Column({
-    name: 'public_key',
-    length: 255,
-    type: 'varchar',
-    nullable: true,
-  })
-  declare publicKey: string | null
-
-  @Column({
-    name: 'encrypted_private_key',
-    length: 255,
-    type: 'varchar',
-    nullable: true,
-  })
-  declare encryptedPrivateKey: string | null
-
-  @Column({
-    name: 'status',
-    length: 64,
-  })
-  declare status: WorkspaceUserStatus
-
-  @Column({
-    name: 'key_rotation_index',
-    default: 0,
-  })
-  declare keyRotationIndex: number
-
-  @Column({
-    name: 'created_at',
-    type: 'bigint',
-  })
-  declare createdAt: number
-
-  @Column({
-    name: 'updated_at',
-    type: 'bigint',
-  })
-  declare updatedAt: number
-
-  @ManyToOne(
-    /* istanbul ignore next */
-    () => Workspace,
-    /* istanbul ignore next */
-    (workspace) => workspace.users,
-    /* istanbul ignore next */
-    { onDelete: 'CASCADE' },
-  )
-  @JoinColumn(
-    /* istanbul ignore next */
-    { name: 'workspace_uuid' },
-  )
-  declare workspace: Promise<Workspace>
-}

+ 0 - 8
packages/workspace/src/Domain/Workspace/WorkspaceUserRepositoryInterface.ts

@@ -1,8 +0,0 @@
-import { WorkspaceUser } from './WorkspaceUser'
-
-export interface WorkspaceUserRepositoryInterface {
-  save(workspace: WorkspaceUser): Promise<WorkspaceUser>
-  findByUserUuid(userUuid: string): Promise<WorkspaceUser[]>
-  findByWorkspaceUuid(workspaceUuid: string): Promise<WorkspaceUser[]>
-  findOneByUserUuidAndWorkspaceUuid(dto: { workspaceUuid: string; userUuid: string }): Promise<WorkspaceUser | null>
-}

+ 0 - 9
packages/workspace/src/Infra/InversifyExpressUtils/InversifyExpressHealthCheckController.ts

@@ -1,9 +0,0 @@
-import { controller, httpGet } from 'inversify-express-utils'
-
-@controller('/healthcheck')
-export class InversifyExpressHealthCheckController {
-  @httpGet('/')
-  public async get(): Promise<string> {
-    return 'OK'
-  }
-}

+ 0 - 23
packages/workspace/src/Infra/InversifyExpressUtils/InversifyExpressInvitesController.ts

@@ -1,23 +0,0 @@
-import { Request, Response } from 'express'
-import { inject } from 'inversify'
-import { BaseHttpController, controller, httpPost, results } from 'inversify-express-utils'
-import TYPES from '../../Bootstrap/Types'
-import { WorkspacesController } from '../../Controller/WorkspacesController'
-
-@controller('/invites', TYPES.ApiGatewayAuthMiddleware)
-export class InversifyExpressInvitesController extends BaseHttpController {
-  constructor(@inject(TYPES.WorkspacesController) private workspacesController: WorkspacesController) {
-    super()
-  }
-
-  @httpPost('/:inviteUuid/accept')
-  async acceptInvite(request: Request, response: Response): Promise<results.JsonResult> {
-    const result = await this.workspacesController.acceptInvite({
-      ...request.body,
-      inviteUuid: request.params.inviteUuid,
-      userUuid: response.locals.user.uuid,
-    })
-
-    return this.json(result.data, result.status)
-  }
-}

+ 0 - 74
packages/workspace/src/Infra/InversifyExpressUtils/InversifyExpressWorkspacesController.ts

@@ -1,74 +0,0 @@
-import { Request, Response } from 'express'
-import { inject } from 'inversify'
-import { BaseHttpController, controller, httpGet, httpPost, results } from 'inversify-express-utils'
-import TYPES from '../../Bootstrap/Types'
-import { WorkspacesController } from '../../Controller/WorkspacesController'
-
-@controller('/workspaces', TYPES.ApiGatewayAuthMiddleware)
-export class InversifyExpressWorkspacesController extends BaseHttpController {
-  constructor(@inject(TYPES.WorkspacesController) private workspacesController: WorkspacesController) {
-    super()
-  }
-
-  @httpPost('/')
-  async create(request: Request, response: Response): Promise<results.JsonResult> {
-    const result = await this.workspacesController.createWorkspace({
-      ...request.body,
-      ownerUuid: response.locals.user.uuid,
-    })
-
-    return this.json(result.data, result.status)
-  }
-
-  @httpGet('/')
-  async listWorkspaces(_request: Request, response: Response): Promise<results.JsonResult> {
-    const result = await this.workspacesController.listWorkspaces({
-      userUuid: response.locals.user.uuid,
-    })
-
-    return this.json(result.data, result.status)
-  }
-
-  @httpGet('/:workspaceUuid/users')
-  async listWorkspaceUsers(request: Request, response: Response): Promise<results.JsonResult> {
-    const result = await this.workspacesController.listWorkspaceUsers({
-      userUuid: response.locals.user.uuid,
-      workspaceUuid: request.params.workspaceUuid,
-    })
-
-    return this.json(result.data, result.status)
-  }
-
-  @httpPost('/:workspaceUuid/users/:userUuid/keyshare')
-  async initiateKeyshare(request: Request, response: Response): Promise<results.JsonResult> {
-    const result = await this.workspacesController.initiateKeyshare({
-      userUuid: request.params.userUuid,
-      workspaceUuid: request.params.workspaceUuid,
-      encryptedWorkspaceKey: request.body.encryptedWorkspaceKey,
-      performingUserUuid: response.locals.user.uuid,
-    })
-
-    return this.json(result.data, result.status)
-  }
-
-  @httpPost('/:workspaceUuid/invites')
-  async inviteToWorkspace(request: Request, response: Response): Promise<results.JsonResult> {
-    if (request.params.workspaceUuid !== request.body.workspaceUuid) {
-      return this.json(
-        {
-          error: {
-            message: 'Invalid workspace uuid.',
-          },
-        },
-        400,
-      )
-    }
-
-    const result = await this.workspacesController.inviteToWorkspace({
-      ...request.body,
-      inviterUuid: response.locals.user.uuid,
-    })
-
-    return this.json(result.data, result.status)
-  }
-}

+ 0 - 39
packages/workspace/src/Infra/MySQL/MySQLWorkspaceInviteRepository.spec.ts

@@ -1,39 +0,0 @@
-import 'reflect-metadata'
-
-import { Repository, SelectQueryBuilder } from 'typeorm'
-
-import { WorkspaceInvite } from '../../Domain/Invite/WorkspaceInvite'
-import { MySQLWorkspaceInviteRepository } from './MySQLWorkspaceInviteRepository'
-
-describe('MySQLWorkspaceInviteRepository', () => {
-  let ormRepository: Repository<WorkspaceInvite>
-  let invite: WorkspaceInvite
-  let queryBuilder: SelectQueryBuilder<WorkspaceInvite>
-
-  const createRepository = () => new MySQLWorkspaceInviteRepository(ormRepository)
-
-  beforeEach(() => {
-    invite = {} as jest.Mocked<WorkspaceInvite>
-
-    queryBuilder = {} as jest.Mocked<SelectQueryBuilder<WorkspaceInvite>>
-
-    ormRepository = {} as jest.Mocked<Repository<WorkspaceInvite>>
-    ormRepository.save = jest.fn()
-    ormRepository.createQueryBuilder = jest.fn().mockImplementation(() => queryBuilder)
-  })
-
-  it('should save', async () => {
-    await createRepository().save(invite)
-
-    expect(ormRepository.save).toHaveBeenCalledWith(invite)
-  })
-
-  it('should find one by uuid', async () => {
-    queryBuilder.where = jest.fn().mockReturnThis()
-    queryBuilder.getOne = jest.fn().mockReturnValue(null)
-
-    await createRepository().findOneByUuid('i-1-2-3')
-
-    expect(queryBuilder.where).toHaveBeenCalledWith('uuid = :uuid', { uuid: 'i-1-2-3' })
-  })
-})

+ 0 - 22
packages/workspace/src/Infra/MySQL/MySQLWorkspaceInviteRepository.ts

@@ -1,22 +0,0 @@
-import { inject, injectable } from 'inversify'
-import { Repository } from 'typeorm'
-
-import TYPES from '../../Bootstrap/Types'
-import { WorkspaceInvite } from '../../Domain/Invite/WorkspaceInvite'
-import { WorkspaceInviteRepositoryInterface } from '../../Domain/Invite/WorkspaceInviteRepositoryInterface'
-
-@injectable()
-export class MySQLWorkspaceInviteRepository implements WorkspaceInviteRepositoryInterface {
-  constructor(
-    @inject(TYPES.ORMWorkspaceInviteRepository)
-    private ormRepository: Repository<WorkspaceInvite>,
-  ) {}
-
-  async findOneByUuid(uuid: string): Promise<WorkspaceInvite | null> {
-    return this.ormRepository.createQueryBuilder().where('uuid = :uuid', { uuid }).getOne()
-  }
-
-  async save(workspaceInvite: WorkspaceInvite): Promise<WorkspaceInvite> {
-    return this.ormRepository.save(workspaceInvite)
-  }
-}

+ 0 - 49
packages/workspace/src/Infra/MySQL/MySQLWorkspaceRepository.spec.ts

@@ -1,49 +0,0 @@
-import 'reflect-metadata'
-
-import { Repository, SelectQueryBuilder } from 'typeorm'
-
-import { Workspace } from '../../Domain/Workspace/Workspace'
-
-import { MySQLWorkspaceRepository } from './MySQLWorkspaceRepository'
-
-describe('MySQLWorkspaceRepository', () => {
-  let ormRepository: Repository<Workspace>
-  let workspace: Workspace
-  let queryBuilder: SelectQueryBuilder<Workspace>
-
-  const createRepository = () => new MySQLWorkspaceRepository(ormRepository)
-
-  beforeEach(() => {
-    workspace = {} as jest.Mocked<Workspace>
-
-    queryBuilder = {} as jest.Mocked<SelectQueryBuilder<Workspace>>
-
-    ormRepository = {} as jest.Mocked<Repository<Workspace>>
-    ormRepository.save = jest.fn()
-    ormRepository.createQueryBuilder = jest.fn().mockImplementation(() => queryBuilder)
-  })
-
-  it('should save', async () => {
-    await createRepository().save(workspace)
-
-    expect(ormRepository.save).toHaveBeenCalledWith(workspace)
-  })
-
-  it('should find many by uuids', async () => {
-    queryBuilder.where = jest.fn().mockReturnThis()
-    queryBuilder.getMany = jest.fn().mockReturnValue([])
-
-    await createRepository().findByUuids(['i-1-2-3'])
-
-    expect(queryBuilder.where).toHaveBeenCalledWith('uuid IN (:...uuids)', { uuids: ['i-1-2-3'] })
-  })
-
-  it('should find one by uuid', async () => {
-    queryBuilder.where = jest.fn().mockReturnThis()
-    queryBuilder.getOne = jest.fn().mockReturnValue(null)
-
-    await createRepository().findOneByUuid('i-1-2-3')
-
-    expect(queryBuilder.where).toHaveBeenCalledWith('uuid = :uuid', { uuid: 'i-1-2-3' })
-  })
-})

Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden.