mirror of
https://github.com/standardnotes/server
synced 2026-02-01 05:01:11 -05:00
Compare commits
15 Commits
@standardn
...
@standardn
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3039f58b5a | ||
|
|
e2326190d4 | ||
|
|
095d13f8bb | ||
|
|
1292d1d898 | ||
|
|
8bc92616d2 | ||
|
|
ae45fafaee | ||
|
|
f74227067b | ||
|
|
5f76d25ec3 | ||
|
|
ba9d3bfe46 | ||
|
|
3dc6babfca | ||
|
|
ace2b6936a | ||
|
|
712e874bfe | ||
|
|
266adda45b | ||
|
|
f5ebe4a69e | ||
|
|
15d960d47b |
138
.pnp.cjs
generated
138
.pnp.cjs
generated
@@ -2521,30 +2521,16 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||
}]\
|
||||
]],\
|
||||
["@standardnotes/api", [\
|
||||
["npm:1.11.0", {\
|
||||
"packageLocation": "./.yarn/cache/@standardnotes-api-npm-1.11.0-ce72fb3e14-f1134efb44.zip/node_modules/@standardnotes/api/",\
|
||||
["npm:1.15.0", {\
|
||||
"packageLocation": "./.yarn/cache/@standardnotes-api-npm-1.15.0-12a67ff9b7-88ae0a340e.zip/node_modules/@standardnotes/api/",\
|
||||
"packageDependencies": [\
|
||||
["@standardnotes/api", "npm:1.11.0"],\
|
||||
["@standardnotes/api", "npm:1.15.0"],\
|
||||
["@standardnotes/common", "workspace:packages/common"],\
|
||||
["@standardnotes/encryption", "npm:1.16.0"],\
|
||||
["@standardnotes/models", "npm:1.24.0"],\
|
||||
["@standardnotes/responses", "npm:1.10.4"],\
|
||||
["@standardnotes/encryption", "npm:1.17.0"],\
|
||||
["@standardnotes/models", "npm:1.26.0"],\
|
||||
["@standardnotes/responses", "npm:1.11.0"],\
|
||||
["@standardnotes/security", "workspace:packages/security"],\
|
||||
["@standardnotes/utils", "npm:1.9.0"],\
|
||||
["reflect-metadata", "npm:0.1.13"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}],\
|
||||
["npm:1.9.0", {\
|
||||
"packageLocation": "./.yarn/cache/@standardnotes-api-npm-1.9.0-507434ff00-cc3feac393.zip/node_modules/@standardnotes/api/",\
|
||||
"packageDependencies": [\
|
||||
["@standardnotes/api", "npm:1.9.0"],\
|
||||
["@standardnotes/common", "workspace:packages/common"],\
|
||||
["@standardnotes/encryption", "npm:1.15.9"],\
|
||||
["@standardnotes/models", "npm:1.22.0"],\
|
||||
["@standardnotes/responses", "npm:1.10.3"],\
|
||||
["@standardnotes/security", "workspace:packages/security"],\
|
||||
["@standardnotes/utils", "npm:1.9.0"],\
|
||||
["@standardnotes/utils", "npm:1.10.0"],\
|
||||
["reflect-metadata", "npm:0.1.13"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
@@ -2614,7 +2600,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||
["@newrelic/winston-enricher", "virtual:04783e12400851b8a3d76e71495851cc94959db6e62f04cb0a31190080629440b182d8c8eb4d7f2b04e281912f2783a5fd4d2c3c6ab68d38b7097246c93f4c19#npm:4.0.0"],\
|
||||
["@sentry/node", "npm:7.5.0"],\
|
||||
["@standardnotes/analytics", "workspace:packages/analytics"],\
|
||||
["@standardnotes/api", "npm:1.9.0"],\
|
||||
["@standardnotes/api", "npm:1.15.0"],\
|
||||
["@standardnotes/common", "workspace:packages/common"],\
|
||||
["@standardnotes/domain-events", "workspace:packages/domain-events"],\
|
||||
["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\
|
||||
@@ -2739,28 +2725,15 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||
}]\
|
||||
]],\
|
||||
["@standardnotes/encryption", [\
|
||||
["npm:1.15.9", {\
|
||||
"packageLocation": "./.yarn/cache/@standardnotes-encryption-npm-1.15.9-00c7fac9f6-7595ac08ce.zip/node_modules/@standardnotes/encryption/",\
|
||||
["npm:1.17.0", {\
|
||||
"packageLocation": "./.yarn/cache/@standardnotes-encryption-npm-1.17.0-587d631df2-587516dfed.zip/node_modules/@standardnotes/encryption/",\
|
||||
"packageDependencies": [\
|
||||
["@standardnotes/encryption", "npm:1.15.9"],\
|
||||
["@standardnotes/encryption", "npm:1.17.0"],\
|
||||
["@standardnotes/common", "workspace:packages/common"],\
|
||||
["@standardnotes/models", "npm:1.22.0"],\
|
||||
["@standardnotes/responses", "npm:1.10.3"],\
|
||||
["@standardnotes/sncrypto-common", "npm:1.12.0"],\
|
||||
["@standardnotes/utils", "npm:1.9.0"],\
|
||||
["reflect-metadata", "npm:0.1.13"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}],\
|
||||
["npm:1.16.0", {\
|
||||
"packageLocation": "./.yarn/cache/@standardnotes-encryption-npm-1.16.0-df46ea19bc-9971b9afcc.zip/node_modules/@standardnotes/encryption/",\
|
||||
"packageDependencies": [\
|
||||
["@standardnotes/encryption", "npm:1.16.0"],\
|
||||
["@standardnotes/common", "workspace:packages/common"],\
|
||||
["@standardnotes/models", "npm:1.24.0"],\
|
||||
["@standardnotes/responses", "npm:1.10.4"],\
|
||||
["@standardnotes/models", "npm:1.26.0"],\
|
||||
["@standardnotes/responses", "npm:1.11.0"],\
|
||||
["@standardnotes/sncrypto-common", "npm:1.13.0"],\
|
||||
["@standardnotes/utils", "npm:1.9.0"],\
|
||||
["@standardnotes/utils", "npm:1.10.0"],\
|
||||
["reflect-metadata", "npm:0.1.13"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
@@ -2818,10 +2791,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}],\
|
||||
["npm:1.52.2", {\
|
||||
"packageLocation": "./.yarn/cache/@standardnotes-features-npm-1.52.2-076ab9f511-ab345f8dc1.zip/node_modules/@standardnotes/features/",\
|
||||
["npm:1.53.0", {\
|
||||
"packageLocation": "./.yarn/cache/@standardnotes-features-npm-1.53.0-8ea4a2d559-a856e815a3.zip/node_modules/@standardnotes/features/",\
|
||||
"packageDependencies": [\
|
||||
["@standardnotes/features", "npm:1.52.2"],\
|
||||
["@standardnotes/features", "npm:1.53.0"],\
|
||||
["@standardnotes/auth", "npm:3.19.4"],\
|
||||
["@standardnotes/common", "workspace:packages/common"],\
|
||||
["@standardnotes/security", "workspace:packages/security"],\
|
||||
@@ -2883,27 +2856,14 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||
}]\
|
||||
]],\
|
||||
["@standardnotes/models", [\
|
||||
["npm:1.22.0", {\
|
||||
"packageLocation": "./.yarn/cache/@standardnotes-models-npm-1.22.0-2cc72f987b-9928246368.zip/node_modules/@standardnotes/models/",\
|
||||
["npm:1.26.0", {\
|
||||
"packageLocation": "./.yarn/cache/@standardnotes-models-npm-1.26.0-dade8919ab-f595a3de88.zip/node_modules/@standardnotes/models/",\
|
||||
"packageDependencies": [\
|
||||
["@standardnotes/models", "npm:1.22.0"],\
|
||||
["@standardnotes/models", "npm:1.26.0"],\
|
||||
["@standardnotes/common", "workspace:packages/common"],\
|
||||
["@standardnotes/features", "npm:1.52.1"],\
|
||||
["@standardnotes/responses", "npm:1.10.3"],\
|
||||
["@standardnotes/utils", "npm:1.9.0"],\
|
||||
["lodash", "npm:4.17.21"],\
|
||||
["reflect-metadata", "npm:0.1.13"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}],\
|
||||
["npm:1.24.0", {\
|
||||
"packageLocation": "./.yarn/cache/@standardnotes-models-npm-1.24.0-bf039594ac-2acbbbc062.zip/node_modules/@standardnotes/models/",\
|
||||
"packageDependencies": [\
|
||||
["@standardnotes/models", "npm:1.24.0"],\
|
||||
["@standardnotes/common", "workspace:packages/common"],\
|
||||
["@standardnotes/features", "npm:1.52.2"],\
|
||||
["@standardnotes/responses", "npm:1.10.4"],\
|
||||
["@standardnotes/utils", "npm:1.9.0"],\
|
||||
["@standardnotes/features", "npm:1.53.0"],\
|
||||
["@standardnotes/responses", "npm:1.11.0"],\
|
||||
["@standardnotes/utils", "npm:1.10.0"],\
|
||||
["lodash", "npm:4.17.21"],\
|
||||
["reflect-metadata", "npm:0.1.13"]\
|
||||
],\
|
||||
@@ -2939,23 +2899,12 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||
}]\
|
||||
]],\
|
||||
["@standardnotes/responses", [\
|
||||
["npm:1.10.3", {\
|
||||
"packageLocation": "./.yarn/cache/@standardnotes-responses-npm-1.10.3-7cdb15f83a-4a1e31eb89.zip/node_modules/@standardnotes/responses/",\
|
||||
["npm:1.11.0", {\
|
||||
"packageLocation": "./.yarn/cache/@standardnotes-responses-npm-1.11.0-d066ddbbb6-46d6a47980.zip/node_modules/@standardnotes/responses/",\
|
||||
"packageDependencies": [\
|
||||
["@standardnotes/responses", "npm:1.10.3"],\
|
||||
["@standardnotes/responses", "npm:1.11.0"],\
|
||||
["@standardnotes/common", "workspace:packages/common"],\
|
||||
["@standardnotes/features", "npm:1.52.1"],\
|
||||
["@standardnotes/security", "workspace:packages/security"],\
|
||||
["reflect-metadata", "npm:0.1.13"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}],\
|
||||
["npm:1.10.4", {\
|
||||
"packageLocation": "./.yarn/cache/@standardnotes-responses-npm-1.10.4-3af0d3ab54-41e4971144.zip/node_modules/@standardnotes/responses/",\
|
||||
"packageDependencies": [\
|
||||
["@standardnotes/responses", "npm:1.10.4"],\
|
||||
["@standardnotes/common", "workspace:packages/common"],\
|
||||
["@standardnotes/features", "npm:1.52.2"],\
|
||||
["@standardnotes/features", "npm:1.53.0"],\
|
||||
["@standardnotes/security", "workspace:packages/security"],\
|
||||
["reflect-metadata", "npm:0.1.13"]\
|
||||
],\
|
||||
@@ -3066,14 +3015,6 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||
}]\
|
||||
]],\
|
||||
["@standardnotes/sncrypto-common", [\
|
||||
["npm:1.12.0", {\
|
||||
"packageLocation": "./.yarn/cache/@standardnotes-sncrypto-common-npm-1.12.0-1a093ff006-b89a14bd23.zip/node_modules/@standardnotes/sncrypto-common/",\
|
||||
"packageDependencies": [\
|
||||
["@standardnotes/sncrypto-common", "npm:1.12.0"],\
|
||||
["reflect-metadata", "npm:0.1.13"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}],\
|
||||
["npm:1.13.0", {\
|
||||
"packageLocation": "./.yarn/cache/@standardnotes-sncrypto-common-npm-1.13.0-18cb5f8eb9-e58258f525.zip/node_modules/@standardnotes/sncrypto-common/",\
|
||||
"packageDependencies": [\
|
||||
@@ -3184,6 +3125,17 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||
}]\
|
||||
]],\
|
||||
["@standardnotes/utils", [\
|
||||
["npm:1.10.0", {\
|
||||
"packageLocation": "./.yarn/cache/@standardnotes-utils-npm-1.10.0-0dc2ade40b-c02d54ca8a.zip/node_modules/@standardnotes/utils/",\
|
||||
"packageDependencies": [\
|
||||
["@standardnotes/utils", "npm:1.10.0"],\
|
||||
["@standardnotes/common", "workspace:packages/common"],\
|
||||
["dompurify", "npm:2.4.0"],\
|
||||
["lodash", "npm:4.17.21"],\
|
||||
["reflect-metadata", "npm:0.1.13"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}],\
|
||||
["npm:1.6.12", {\
|
||||
"packageLocation": "./.yarn/cache/@standardnotes-utils-npm-1.6.12-8fa8d7d09b-e177b1fa51.zip/node_modules/@standardnotes/utils/",\
|
||||
"packageDependencies": [\
|
||||
@@ -3193,17 +3145,6 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||
["lodash", "npm:4.17.21"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}],\
|
||||
["npm:1.9.0", {\
|
||||
"packageLocation": "./.yarn/cache/@standardnotes-utils-npm-1.9.0-da939553f6-4591aff48d.zip/node_modules/@standardnotes/utils/",\
|
||||
"packageDependencies": [\
|
||||
["@standardnotes/utils", "npm:1.9.0"],\
|
||||
["@standardnotes/common", "workspace:packages/common"],\
|
||||
["dompurify", "npm:2.4.0"],\
|
||||
["lodash", "npm:4.17.21"],\
|
||||
["reflect-metadata", "npm:0.1.13"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["@standardnotes/workspace-server", [\
|
||||
@@ -3213,10 +3154,11 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||
["@standardnotes/workspace-server", "workspace:packages/workspace"],\
|
||||
["@newrelic/winston-enricher", "virtual:04783e12400851b8a3d76e71495851cc94959db6e62f04cb0a31190080629440b182d8c8eb4d7f2b04e281912f2783a5fd4d2c3c6ab68d38b7097246c93f4c19#npm:4.0.0"],\
|
||||
["@sentry/node", "npm:7.5.0"],\
|
||||
["@standardnotes/api", "npm:1.11.0"],\
|
||||
["@standardnotes/api", "npm:1.15.0"],\
|
||||
["@standardnotes/common", "workspace:packages/common"],\
|
||||
["@standardnotes/domain-events", "workspace:packages/domain-events"],\
|
||||
["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\
|
||||
["@standardnotes/models", "npm:1.26.0"],\
|
||||
["@standardnotes/security", "workspace:packages/security"],\
|
||||
["@standardnotes/time", "workspace:packages/time"],\
|
||||
["@types/cors", "npm:2.8.12"],\
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -3,6 +3,30 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.29.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.28.2...@standardnotes/api-gateway@1.29.0) (2022-10-11)
|
||||
|
||||
### Features
|
||||
|
||||
* add listin worspaces and workspace users ([095d13f](https://github.com/standardnotes/api-gateway/commit/095d13f8bbfe543fcf086840e1a985447a6c51ef))
|
||||
|
||||
## [1.28.2](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.28.1...@standardnotes/api-gateway@1.28.2) (2022-10-11)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||
|
||||
## [1.28.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.28.0...@standardnotes/api-gateway@1.28.1) (2022-10-11)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||
|
||||
# [1.28.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.27.4...@standardnotes/api-gateway@1.28.0) (2022-10-11)
|
||||
|
||||
### Features
|
||||
|
||||
* **workspace:** add invite to workspace endpoints ([266adda](https://github.com/standardnotes/api-gateway/commit/266adda45bd3ad84bc6605824b6be1dd912f3f9a))
|
||||
|
||||
## [1.27.4](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.27.3...@standardnotes/api-gateway@1.27.4) (2022-10-10)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||
|
||||
## [1.27.3](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.27.2...@standardnotes/api-gateway@1.27.3) (2022-10-10)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||
|
||||
@@ -20,6 +20,7 @@ import '../src/Controller/v1/OfflineController'
|
||||
import '../src/Controller/v1/FilesController'
|
||||
import '../src/Controller/v1/SubscriptionInvitesController'
|
||||
import '../src/Controller/v1/WorkspacesController'
|
||||
import '../src/Controller/v1/InvitesController'
|
||||
|
||||
import '../src/Controller/v2/PaymentsControllerV2'
|
||||
import '../src/Controller/v2/ActionsControllerV2'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/api-gateway",
|
||||
"version": "1.27.3",
|
||||
"version": "1.29.0",
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.0.0"
|
||||
},
|
||||
|
||||
23
packages/api-gateway/src/Controller/v1/InvitesController.ts
Normal file
23
packages/api-gateway/src/Controller/v1/InvitesController.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
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,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,43 @@
|
||||
import { inject } from 'inversify'
|
||||
import { Request, Response } from 'express'
|
||||
import { controller, BaseHttpController, httpPost } from 'inversify-express-utils'
|
||||
import { controller, BaseHttpController, httpPost, httpGet } from 'inversify-express-utils'
|
||||
|
||||
import TYPES from '../../Bootstrap/Types'
|
||||
import { HttpServiceInterface } from '../../Service/Http/HttpServiceInterface'
|
||||
|
||||
@controller('/v1/workspaces')
|
||||
@controller('/v1/workspaces', TYPES.AuthMiddleware)
|
||||
export class WorkspacesController extends BaseHttpController {
|
||||
constructor(@inject(TYPES.HTTPService) private httpService: HttpServiceInterface) {
|
||||
super()
|
||||
}
|
||||
|
||||
@httpPost('/', TYPES.AuthMiddleware)
|
||||
@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,
|
||||
)
|
||||
}
|
||||
|
||||
@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,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,30 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.42.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.41.2...@standardnotes/auth-server@1.42.0) (2022-10-11)
|
||||
|
||||
### Features
|
||||
|
||||
* add listin worspaces and workspace users ([095d13f](https://github.com/standardnotes/server/commit/095d13f8bbfe543fcf086840e1a985447a6c51ef))
|
||||
|
||||
## [1.41.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.41.1...@standardnotes/auth-server@1.41.2) (2022-10-11)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/auth-server
|
||||
|
||||
## [1.41.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.41.0...@standardnotes/auth-server@1.41.1) (2022-10-11)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/auth-server
|
||||
|
||||
# [1.41.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.40.4...@standardnotes/auth-server@1.41.0) (2022-10-11)
|
||||
|
||||
### Features
|
||||
|
||||
* **workspace:** add invite to workspace endpoints ([266adda](https://github.com/standardnotes/server/commit/266adda45bd3ad84bc6605824b6be1dd912f3f9a))
|
||||
|
||||
## [1.40.4](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.40.3...@standardnotes/auth-server@1.40.4) (2022-10-10)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/auth-server
|
||||
|
||||
## [1.40.3](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.40.2...@standardnotes/auth-server@1.40.3) (2022-10-10)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/auth-server
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/auth-server",
|
||||
"version": "1.40.3",
|
||||
"version": "1.42.0",
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.0.0"
|
||||
},
|
||||
@@ -34,7 +34,7 @@
|
||||
"@newrelic/winston-enricher": "^4.0.0",
|
||||
"@sentry/node": "^7.3.0",
|
||||
"@standardnotes/analytics": "workspace:*",
|
||||
"@standardnotes/api": "^1.9.0",
|
||||
"@standardnotes/api": "^1.15.0",
|
||||
"@standardnotes/common": "workspace:*",
|
||||
"@standardnotes/domain-events": "workspace:*",
|
||||
"@standardnotes/domain-events-infra": "workspace:*",
|
||||
|
||||
@@ -3,6 +3,24 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.39.0](https://github.com/standardnotes/server/compare/@standardnotes/common@1.38.0...@standardnotes/common@1.39.0) (2022-10-11)
|
||||
|
||||
### Features
|
||||
|
||||
* **workspace:** extract workspace user status to common ([8bc9261](https://github.com/standardnotes/server/commit/8bc92616d2fbeb833c3fcbef6b87538745fc7f3e))
|
||||
|
||||
# [1.38.0](https://github.com/standardnotes/server/compare/@standardnotes/common@1.37.0...@standardnotes/common@1.38.0) (2022-10-11)
|
||||
|
||||
### Features
|
||||
|
||||
* **workspace:** add invite access level ([f742270](https://github.com/standardnotes/server/commit/f74227067b7151cb63a54e815e57f81984467bfe))
|
||||
|
||||
# [1.37.0](https://github.com/standardnotes/server/compare/@standardnotes/common@1.36.1...@standardnotes/common@1.37.0) (2022-10-10)
|
||||
|
||||
### Features
|
||||
|
||||
* **common:** add WORKSPACE_INVITE_CREATED email message identifier ([15d960d](https://github.com/standardnotes/server/commit/15d960d47b0bcf5aeddf869ac939eafb08166db7))
|
||||
|
||||
## [1.36.1](https://github.com/standardnotes/server/compare/@standardnotes/common@1.36.0...@standardnotes/common@1.36.1) (2022-10-10)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/common",
|
||||
"version": "1.36.1",
|
||||
"version": "1.39.0",
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.0.0"
|
||||
},
|
||||
|
||||
@@ -24,4 +24,5 @@ export enum EmailMessageIdentifier {
|
||||
REFUND_NOTICE = 'REFUND_NOTICE',
|
||||
REFUND_REQUESTED = 'REFUND_REQUESTED',
|
||||
RATE_ADJUSTMENT_NOTICE = 'RATE_ADJUSTMENT_NOTICE',
|
||||
WORKSPACE_INVITE_CREATED = 'WORKSPACE_INVITE_CREATED',
|
||||
}
|
||||
|
||||
@@ -24,4 +24,6 @@ export * from './Type/Either'
|
||||
export * from './Type/Only'
|
||||
export * from './Validator/UuidValidator'
|
||||
export * from './Validator/ValidatorInterface'
|
||||
export * from './Workspace/WorkspaceAccessLevel'
|
||||
export * from './Workspace/WorkspaceType'
|
||||
export * from './Workspace/WorkspaceUserStatus'
|
||||
|
||||
@@ -3,6 +3,18 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.8.25](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.8.24...@standardnotes/domain-events-infra@1.8.25) (2022-10-11)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/domain-events-infra
|
||||
|
||||
## [1.8.24](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.8.23...@standardnotes/domain-events-infra@1.8.24) (2022-10-11)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/domain-events-infra
|
||||
|
||||
## [1.8.23](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.8.22...@standardnotes/domain-events-infra@1.8.23) (2022-10-10)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/domain-events-infra
|
||||
|
||||
## [1.8.22](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.8.21...@standardnotes/domain-events-infra@1.8.22) (2022-10-10)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/domain-events-infra
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/domain-events-infra",
|
||||
"version": "1.8.22",
|
||||
"version": "1.8.25",
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,18 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [2.66.3](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.66.2...@standardnotes/domain-events@2.66.3) (2022-10-11)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/domain-events
|
||||
|
||||
## [2.66.2](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.66.1...@standardnotes/domain-events@2.66.2) (2022-10-11)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/domain-events
|
||||
|
||||
## [2.66.1](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.66.0...@standardnotes/domain-events@2.66.1) (2022-10-10)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/domain-events
|
||||
|
||||
# [2.66.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.65.0...@standardnotes/domain-events@2.66.0) (2022-10-10)
|
||||
|
||||
### Features
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/domain-events",
|
||||
"version": "2.66.0",
|
||||
"version": "2.66.3",
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,18 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.4.4](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.4.3...@standardnotes/event-store@1.4.4) (2022-10-11)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/event-store
|
||||
|
||||
## [1.4.3](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.4.2...@standardnotes/event-store@1.4.3) (2022-10-11)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/event-store
|
||||
|
||||
## [1.4.2](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.4.1...@standardnotes/event-store@1.4.2) (2022-10-10)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/event-store
|
||||
|
||||
## [1.4.1](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.4.0...@standardnotes/event-store@1.4.1) (2022-10-10)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/event-store
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/event-store",
|
||||
"version": "1.4.1",
|
||||
"version": "1.4.4",
|
||||
"description": "Event Store Service",
|
||||
"private": true,
|
||||
"main": "dist/src/index.js",
|
||||
|
||||
@@ -3,6 +3,18 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.6.16](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.6.15...@standardnotes/files-server@1.6.16) (2022-10-11)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/files-server
|
||||
|
||||
## [1.6.15](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.6.14...@standardnotes/files-server@1.6.15) (2022-10-11)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/files-server
|
||||
|
||||
## [1.6.14](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.6.13...@standardnotes/files-server@1.6.14) (2022-10-10)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/files-server
|
||||
|
||||
## [1.6.13](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.6.12...@standardnotes/files-server@1.6.13) (2022-10-10)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/files-server
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/files-server",
|
||||
"version": "1.6.13",
|
||||
"version": "1.6.16",
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,18 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.4.10](https://github.com/standardnotes/server/compare/@standardnotes/predicates@1.4.9...@standardnotes/predicates@1.4.10) (2022-10-11)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/predicates
|
||||
|
||||
## [1.4.9](https://github.com/standardnotes/server/compare/@standardnotes/predicates@1.4.8...@standardnotes/predicates@1.4.9) (2022-10-11)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/predicates
|
||||
|
||||
## [1.4.8](https://github.com/standardnotes/server/compare/@standardnotes/predicates@1.4.7...@standardnotes/predicates@1.4.8) (2022-10-10)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/predicates
|
||||
|
||||
## [1.4.7](https://github.com/standardnotes/server/compare/@standardnotes/predicates@1.4.6...@standardnotes/predicates@1.4.7) (2022-10-10)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/predicates
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/predicates",
|
||||
"version": "1.4.7",
|
||||
"version": "1.4.10",
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,18 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.10.44](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.10.43...@standardnotes/scheduler-server@1.10.44) (2022-10-11)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/scheduler-server
|
||||
|
||||
## [1.10.43](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.10.42...@standardnotes/scheduler-server@1.10.43) (2022-10-11)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/scheduler-server
|
||||
|
||||
## [1.10.42](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.10.41...@standardnotes/scheduler-server@1.10.42) (2022-10-10)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/scheduler-server
|
||||
|
||||
## [1.10.41](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.10.40...@standardnotes/scheduler-server@1.10.41) (2022-10-10)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/scheduler-server
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/scheduler-server",
|
||||
"version": "1.10.41",
|
||||
"version": "1.10.44",
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,18 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.4.8](https://github.com/standardnotes/server/compare/@standardnotes/security@1.4.7...@standardnotes/security@1.4.8) (2022-10-11)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/security
|
||||
|
||||
## [1.4.7](https://github.com/standardnotes/server/compare/@standardnotes/security@1.4.6...@standardnotes/security@1.4.7) (2022-10-11)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/security
|
||||
|
||||
## [1.4.6](https://github.com/standardnotes/server/compare/@standardnotes/security@1.4.5...@standardnotes/security@1.4.6) (2022-10-10)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/security
|
||||
|
||||
## [1.4.5](https://github.com/standardnotes/server/compare/@standardnotes/security@1.4.4...@standardnotes/security@1.4.5) (2022-10-10)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/security
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/security",
|
||||
"version": "1.4.5",
|
||||
"version": "1.4.8",
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,18 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.9.6](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.9.5...@standardnotes/syncing-server@1.9.6) (2022-10-11)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/syncing-server
|
||||
|
||||
## [1.9.5](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.9.4...@standardnotes/syncing-server@1.9.5) (2022-10-11)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/syncing-server
|
||||
|
||||
## [1.9.4](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.9.3...@standardnotes/syncing-server@1.9.4) (2022-10-10)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/syncing-server
|
||||
|
||||
## [1.9.3](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.9.2...@standardnotes/syncing-server@1.9.3) (2022-10-10)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/syncing-server
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/syncing-server",
|
||||
"version": "1.9.3",
|
||||
"version": "1.9.6",
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,46 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [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
|
||||
|
||||
@@ -5,6 +5,7 @@ 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'
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
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,0 +1,13 @@
|
||||
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`')
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/workspace-server",
|
||||
"version": "1.5.0",
|
||||
"version": "1.11.0",
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.0.0"
|
||||
},
|
||||
@@ -25,10 +25,11 @@
|
||||
"dependencies": {
|
||||
"@newrelic/winston-enricher": "^4.0.0",
|
||||
"@sentry/node": "^7.3.0",
|
||||
"@standardnotes/api": "^1.11.0",
|
||||
"@standardnotes/api": "^1.15.0",
|
||||
"@standardnotes/common": "workspace:*",
|
||||
"@standardnotes/domain-events": "workspace:^",
|
||||
"@standardnotes/domain-events-infra": "workspace:^",
|
||||
"@standardnotes/models": "^1.26.0",
|
||||
"@standardnotes/security": "workspace:*",
|
||||
"@standardnotes/time": "workspace:^",
|
||||
"aws-sdk": "^2.1159.0",
|
||||
|
||||
@@ -38,6 +38,14 @@ 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'
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const newrelicFormatter = require('@newrelic/winston-enricher')
|
||||
@@ -131,8 +139,16 @@ export class ContainerConfigLoader {
|
||||
// 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)
|
||||
// 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())
|
||||
|
||||
@@ -28,8 +28,14 @@ const TYPES = {
|
||||
// use cases
|
||||
CreateWorkspace: Symbol.for('CreateWorkspace'),
|
||||
InviteToWorkspace: Symbol.for('InviteToWorkspace'),
|
||||
AcceptInvitation: Symbol.for('AcceptInvitation'),
|
||||
ListWorkspaces: Symbol.for('ListWorkspaces'),
|
||||
ListWorkspaceUsers: Symbol.for('ListWorkspaceUsers'),
|
||||
// Handlers
|
||||
UserRegisteredEventHandler: Symbol.for('UserRegisteredEventHandler'),
|
||||
// Projection
|
||||
WorkspaceProjector: Symbol.for('WorkspaceProjector'),
|
||||
WorkspaceUserProjector: Symbol.for('WorkspaceUserProjector'),
|
||||
// Services
|
||||
Timer: Symbol.for('Timer'),
|
||||
CrossServiceTokenDecoder: Symbol.for('CrossServiceTokenDecoder'),
|
||||
|
||||
@@ -1,17 +1,66 @@
|
||||
import { WorkspaceAccessLevel, WorkspaceType } from '@standardnotes/common'
|
||||
import 'reflect-metadata'
|
||||
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 { 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 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)
|
||||
const createController = () =>
|
||||
new WorkspacesController(
|
||||
doCreateWorkspace,
|
||||
doInviteToWorkspace,
|
||||
doListWorkspaces,
|
||||
doListWorkspaceUsers,
|
||||
doAcceptInvitation,
|
||||
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 })
|
||||
|
||||
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 () => {
|
||||
@@ -21,6 +70,7 @@ describe('WorkspacesController', () => {
|
||||
publicKey: 'buzz',
|
||||
workspaceName: 'A Team',
|
||||
ownerUuid: 'u-1-2-3',
|
||||
workspaceType: WorkspaceType.Private,
|
||||
})
|
||||
|
||||
expect(result).toEqual({
|
||||
@@ -30,4 +80,82 @@ describe('WorkspacesController', () => {
|
||||
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,
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -3,16 +3,56 @@ import {
|
||||
HttpStatusCode,
|
||||
WorkspaceCreationRequestParams,
|
||||
WorkspaceCreationResponse,
|
||||
WorkspaceInvitationRequestParams,
|
||||
WorkspaceInvitationResponse,
|
||||
WorkspaceServerInterface,
|
||||
WorkspaceListRequestParams,
|
||||
WorkspaceListResponse,
|
||||
WorkspaceInvitationAcceptingRequestParams,
|
||||
WorkspaceInvitationAcceptingResponse,
|
||||
WorkspaceUserListRequestParams,
|
||||
} from '@standardnotes/api'
|
||||
import { WorkspaceType } from '@standardnotes/common'
|
||||
import { Uuid, WorkspaceAccessLevel, WorkspaceType } 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'
|
||||
|
||||
@injectable()
|
||||
export class WorkspacesController implements WorkspaceServerInterface {
|
||||
constructor(@inject(TYPES.CreateWorkspace) private doCreateWorkspace: CreateWorkspace) {}
|
||||
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.WorkspaceProjector) private workspaceProjector: ProjectorInterface<Workspace, WorkspaceProjection>,
|
||||
@inject(TYPES.WorkspaceUserProjector)
|
||||
private workspaceUserProjector: ProjectorInterface<WorkspaceUser, WorkspaceUserProjection>,
|
||||
) {}
|
||||
|
||||
async inviteToWorkspace(params: WorkspaceInvitationRequestParams): Promise<WorkspaceInvitationResponse> {
|
||||
const { invite } = await this.doInviteToWorkspace.execute({
|
||||
inviteeEmail: params.inviteeEmail,
|
||||
workspaceUuid: params.workspaceUuid,
|
||||
inviterUuid: params.inviterUuid as Uuid,
|
||||
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({
|
||||
@@ -29,4 +69,69 @@ export class WorkspacesController implements WorkspaceServerInterface {
|
||||
data: { uuid: workspace.uuid },
|
||||
}
|
||||
}
|
||||
|
||||
async listWorkspaces(params: WorkspaceListRequestParams): Promise<WorkspaceListResponse> {
|
||||
const { ownedWorkspaces, joinedWorkspaces } = await this.doListWorkspaces.execute({
|
||||
userUuid: params.userUuid as Uuid,
|
||||
})
|
||||
|
||||
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 Uuid,
|
||||
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,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import { WorkspaceAccessLevel } from '@standardnotes/common'
|
||||
import { Column, Entity, JoinColumn, ManyToOne, PrimaryGeneratedColumn } from 'typeorm'
|
||||
|
||||
import { Workspace } from '../Workspace/Workspace'
|
||||
import { WorkspaceInviteStatus } from './WorkspaceInviteStatus'
|
||||
|
||||
@@ -40,6 +42,12 @@ export class WorkspaceInvite {
|
||||
})
|
||||
declare workspaceUuid: string
|
||||
|
||||
@Column({
|
||||
name: 'access_level',
|
||||
length: 64,
|
||||
})
|
||||
declare accessLevel: WorkspaceAccessLevel
|
||||
|
||||
@Column({
|
||||
name: 'created_at',
|
||||
type: 'bigint',
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import { Uuid } from '@standardnotes/common'
|
||||
|
||||
import { WorkspaceInvite } from './WorkspaceInvite'
|
||||
|
||||
export interface WorkspaceInviteRepositoryInterface {
|
||||
findOneByUuid(uuid: Uuid): Promise<WorkspaceInvite | null>
|
||||
save(workspace: WorkspaceInvite): Promise<WorkspaceInvite>
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
export interface ProjectorInterface<T, E> {
|
||||
project(object: T): Promise<E>
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
import { Workspace } from '@standardnotes/models'
|
||||
|
||||
export type WorkspaceProjection = Workspace
|
||||
@@ -0,0 +1,30 @@
|
||||
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,0 +1,19 @@
|
||||
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,0 +1,3 @@
|
||||
import { WorkspaceUser } from '@standardnotes/models'
|
||||
|
||||
export type WorkspaceUserProjection = WorkspaceUser
|
||||
@@ -0,0 +1,42 @@
|
||||
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,0 +1,25 @@
|
||||
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,0 +1,78 @@
|
||||
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'
|
||||
|
||||
describe('AcceptInvitation', () => {
|
||||
let workspaceInviteRepository: WorkspaceInviteRepositoryInterface
|
||||
let workspaceUserRepository: WorkspaceUserRepositoryInterface
|
||||
let timer: TimerInterface
|
||||
let invite: WorkspaceInvite
|
||||
|
||||
const createUseCase = () => new AcceptInvitation(workspaceInviteRepository, workspaceUserRepository, 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)
|
||||
})
|
||||
|
||||
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',
|
||||
})
|
||||
})
|
||||
|
||||
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,0 +1,52 @@
|
||||
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'
|
||||
|
||||
@injectable()
|
||||
export class AcceptInvitation implements UseCaseInterface {
|
||||
constructor(
|
||||
@inject(TYPES.WorkspaceInviteRepository) private workspaceInviteRepository: WorkspaceInviteRepositoryInterface,
|
||||
@inject(TYPES.WorkspaceUserRepository) private workspaceUserRepository: WorkspaceUserRepositoryInterface,
|
||||
@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,
|
||||
}
|
||||
}
|
||||
|
||||
invite.acceptingUserUuid = dto.acceptingUserUuid
|
||||
invite.updatedAt = this.timer.getTimestampInMicroseconds()
|
||||
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
|
||||
|
||||
await this.workspaceUserRepository.save(workspaceUser)
|
||||
|
||||
return {
|
||||
success: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import { Uuid } from '@standardnotes/common'
|
||||
|
||||
export type AcceptInvitationDTO = {
|
||||
invitationUuid: Uuid
|
||||
acceptingUserUuid: Uuid
|
||||
publicKey: string
|
||||
encryptedPrivateKey: string
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export type AcceptInvitationResponse = {
|
||||
success: boolean
|
||||
}
|
||||
@@ -1,13 +1,12 @@
|
||||
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 { WorkspaceAccessLevel } from '../../Workspace/WorkspaceAccessLevel'
|
||||
import { WorkspaceRepositoryInterface } from '../../Workspace/WorkspaceRepositoryInterface'
|
||||
import { WorkspaceUser } from '../../Workspace/WorkspaceUser'
|
||||
import { WorkspaceUserRepositoryInterface } from '../../Workspace/WorkspaceUserRepositoryInterface'
|
||||
import { WorkspaceUserStatus } from '../../Workspace/WorkspaceUserStatus'
|
||||
import { UseCaseInterface } from '../UseCaseInterface'
|
||||
|
||||
import { CreateWorkspaceDTO } from './CreateWorkspaceDTO'
|
||||
|
||||
@@ -6,6 +6,7 @@ import { WorkspaceInviteRepositoryInterface } from '../../Invite/WorkspaceInvite
|
||||
import { InviteToWorkspace } from './InviteToWorkspace'
|
||||
import { DomainEventFactoryInterface } from '../../Event/DomainEventFactoryInterface'
|
||||
import { DomainEventPublisherInterface, WorkspaceInviteCreatedEvent } from '@standardnotes/domain-events'
|
||||
import { WorkspaceAccessLevel } from '@standardnotes/common'
|
||||
|
||||
describe('InviteToWorkspace', () => {
|
||||
let workspaceInviteRepository: WorkspaceInviteRepositoryInterface
|
||||
@@ -42,11 +43,24 @@ describe('InviteToWorkspace', () => {
|
||||
inviteeEmail: 'test@test.te',
|
||||
inviterUuid: 'u-1-2-3',
|
||||
workspaceUuid: 'w-1-2-3',
|
||||
accessLevel: WorkspaceAccessLevel.WriteAndRead,
|
||||
})
|
||||
|
||||
expect(result).toEqual({ uuid: 'i-1-2-3' })
|
||||
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',
|
||||
|
||||
@@ -26,6 +26,7 @@ export class InviteToWorkspace implements UseCaseInterface {
|
||||
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()
|
||||
@@ -44,7 +45,7 @@ export class InviteToWorkspace implements UseCaseInterface {
|
||||
)
|
||||
|
||||
return {
|
||||
uuid: invite.uuid,
|
||||
invite,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { Uuid } from '@standardnotes/common'
|
||||
import { Uuid, WorkspaceAccessLevel } from '@standardnotes/common'
|
||||
|
||||
export type InviteToWorkspaceDTO = {
|
||||
workspaceUuid: Uuid
|
||||
inviterUuid: Uuid
|
||||
inviteeEmail: string
|
||||
accessLevel: WorkspaceAccessLevel
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { WorkspaceInvite } from '../../Invite/WorkspaceInvite'
|
||||
|
||||
export type InviteToWorkspaceResponse = {
|
||||
uuid: string
|
||||
invite: WorkspaceInvite
|
||||
}
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
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,0 +1,50 @@
|
||||
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,0 +1,6 @@
|
||||
import { Uuid } from '@standardnotes/common'
|
||||
|
||||
export type ListWorkspaceUsersDTO = {
|
||||
workspaceUuid: Uuid
|
||||
userUuid: Uuid
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import { WorkspaceUser } from '../../Workspace/WorkspaceUser'
|
||||
|
||||
export type ListWorkspaceUsersResponse = {
|
||||
workspaceUsers: WorkspaceUser[]
|
||||
userIsOwnerOrAdmin: boolean
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
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 { ListWorkspaces } from './ListWorkspaces'
|
||||
|
||||
describe('ListWorkspaces', () => {
|
||||
let workspaceRepository: WorkspaceRepositoryInterface
|
||||
let workspaceUserRepository: WorkspaceUserRepositoryInterface
|
||||
let ownedWorkspace: Workspace
|
||||
let joinedWorkspace: Workspace
|
||||
let workspaceUser1: WorkspaceUser
|
||||
let workspaceUser2: WorkspaceUser
|
||||
|
||||
const createUseCase = () => new ListWorkspaces(workspaceRepository, workspaceUserRepository)
|
||||
|
||||
beforeEach(() => {
|
||||
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],
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,40 @@
|
||||
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 { 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,
|
||||
) {}
|
||||
|
||||
async execute(dto: ListWorkspacesDTO): Promise<ListWorkspacesResponse> {
|
||||
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.uuid)
|
||||
} else {
|
||||
joinedWorkspacesUuids.push(workspaceAssociation.uuid)
|
||||
}
|
||||
}
|
||||
|
||||
const ownedWorkspaces = await this.workspaceRepository.findByUuids(ownedWorkspacesUuids)
|
||||
const joinedWorkspaces = await this.workspaceRepository.findByUuids(joinedWorkspacesUuids)
|
||||
|
||||
return {
|
||||
ownedWorkspaces,
|
||||
joinedWorkspaces,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import { Uuid } from '@standardnotes/common'
|
||||
|
||||
export type ListWorkspacesDTO = {
|
||||
userUuid: Uuid
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import { Workspace } from '../../Workspace/Workspace'
|
||||
|
||||
export type ListWorkspacesResponse = {
|
||||
ownedWorkspaces: Array<Workspace>
|
||||
joinedWorkspaces: Array<Workspace>
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
import { Uuid } from '@standardnotes/common'
|
||||
import { Workspace } from './Workspace'
|
||||
|
||||
export interface WorkspaceRepositoryInterface {
|
||||
save(workspace: Workspace): Promise<Workspace>
|
||||
findByUuids(uuids: Uuid[]): Promise<Workspace[]>
|
||||
findOneByUuid(uuid: Uuid): Promise<Workspace | null>
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { WorkspaceAccessLevel, WorkspaceUserStatus } from '@standardnotes/common'
|
||||
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm'
|
||||
import { WorkspaceAccessLevel } from './WorkspaceAccessLevel'
|
||||
import { WorkspaceUserStatus } from './WorkspaceUserStatus'
|
||||
|
||||
@Entity({ name: 'workspace_users' })
|
||||
@Index('index_workspace_users_on_workspace_and_user', ['userUuid', 'workspaceUuid'], { unique: true })
|
||||
@@ -20,6 +19,14 @@ export class WorkspaceUser {
|
||||
})
|
||||
declare userUuid: string
|
||||
|
||||
@Column({
|
||||
name: 'user_display_name',
|
||||
type: 'varchar',
|
||||
length: 255,
|
||||
nullable: true,
|
||||
})
|
||||
declare userDisplayName: string | null
|
||||
|
||||
@Column({
|
||||
name: 'workspace_uuid',
|
||||
length: 36,
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import { Uuid } from '@standardnotes/common'
|
||||
import { WorkspaceUser } from './WorkspaceUser'
|
||||
|
||||
export interface WorkspaceUserRepositoryInterface {
|
||||
save(workspace: WorkspaceUser): Promise<WorkspaceUser>
|
||||
findByUserUuid(userUuid: Uuid): Promise<WorkspaceUser[]>
|
||||
findByWorkspaceUuid(workspaceUuid: Uuid): Promise<WorkspaceUser[]>
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
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)
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,16 @@
|
||||
import { Request, Response } from 'express'
|
||||
import { inject } from 'inversify'
|
||||
import { BaseHttpController, controller, httpPost, results } from 'inversify-express-utils'
|
||||
import { BaseHttpController, controller, httpGet, httpPost, results } from 'inversify-express-utils'
|
||||
import TYPES from '../../Bootstrap/Types'
|
||||
import { WorkspacesController } from '../../Controller/WorkspacesController'
|
||||
|
||||
@controller('/workspaces')
|
||||
@controller('/workspaces', TYPES.ApiGatewayAuthMiddleware)
|
||||
export class InversifyExpressWorkspacesController extends BaseHttpController {
|
||||
constructor(@inject(TYPES.WorkspacesController) private workspacesController: WorkspacesController) {
|
||||
super()
|
||||
}
|
||||
|
||||
@httpPost('/', TYPES.ApiGatewayAuthMiddleware)
|
||||
@httpPost('/')
|
||||
async create(request: Request, response: Response): Promise<results.JsonResult> {
|
||||
const result = await this.workspacesController.createWorkspace({
|
||||
...request.body,
|
||||
@@ -19,4 +19,44 @@ export class InversifyExpressWorkspacesController extends BaseHttpController {
|
||||
|
||||
return this.json(result.data, result.status)
|
||||
}
|
||||
|
||||
@httpGet('/')
|
||||
async listWorkspaces(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/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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,4 +27,13 @@ describe('MySQLWorkspaceInviteRepository', () => {
|
||||
|
||||
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' })
|
||||
})
|
||||
})
|
||||
|
||||
@@ -12,6 +12,10 @@ export class MySQLWorkspaceInviteRepository implements WorkspaceInviteRepository
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -28,4 +28,22 @@ describe('MySQLWorkspaceRepository', () => {
|
||||
|
||||
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' })
|
||||
})
|
||||
})
|
||||
|
||||
@@ -11,6 +11,14 @@ export class MySQLWorkspaceRepository implements WorkspaceRepositoryInterface {
|
||||
private ormRepository: Repository<Workspace>,
|
||||
) {}
|
||||
|
||||
async findOneByUuid(uuid: string): Promise<Workspace | null> {
|
||||
return this.ormRepository.createQueryBuilder().where('uuid = :uuid', { uuid }).getOne()
|
||||
}
|
||||
|
||||
async findByUuids(uuids: string[]): Promise<Workspace[]> {
|
||||
return this.ormRepository.createQueryBuilder().where('uuid IN (:...uuids)', { uuids }).getMany()
|
||||
}
|
||||
|
||||
async save(workspace: Workspace): Promise<Workspace> {
|
||||
return this.ormRepository.save(workspace)
|
||||
}
|
||||
|
||||
@@ -27,4 +27,22 @@ describe('MySQLWorkspaceUserRepository', () => {
|
||||
|
||||
expect(ormRepository.save).toHaveBeenCalledWith(workspace)
|
||||
})
|
||||
|
||||
it('should find many by user uuid', async () => {
|
||||
queryBuilder.where = jest.fn().mockReturnThis()
|
||||
queryBuilder.getMany = jest.fn().mockReturnValue([])
|
||||
|
||||
await createRepository().findByUserUuid('i-1-2-3')
|
||||
|
||||
expect(queryBuilder.where).toHaveBeenCalledWith('user_uuid = :userUuid', { userUuid: 'i-1-2-3' })
|
||||
})
|
||||
|
||||
it('should find many by workspace uuid', async () => {
|
||||
queryBuilder.where = jest.fn().mockReturnThis()
|
||||
queryBuilder.getMany = jest.fn().mockReturnValue([])
|
||||
|
||||
await createRepository().findByWorkspaceUuid('i-1-2-3')
|
||||
|
||||
expect(queryBuilder.where).toHaveBeenCalledWith('workspace_uuid = :workspaceUuid', { workspaceUuid: 'i-1-2-3' })
|
||||
})
|
||||
})
|
||||
|
||||
@@ -12,6 +12,14 @@ export class MySQLWorkspaceUserRepository implements WorkspaceUserRepositoryInte
|
||||
private ormRepository: Repository<WorkspaceUser>,
|
||||
) {}
|
||||
|
||||
async findByWorkspaceUuid(workspaceUuid: string): Promise<WorkspaceUser[]> {
|
||||
return this.ormRepository.createQueryBuilder().where('workspace_uuid = :workspaceUuid', { workspaceUuid }).getMany()
|
||||
}
|
||||
|
||||
async findByUserUuid(userUuid: string): Promise<WorkspaceUser[]> {
|
||||
return this.ormRepository.createQueryBuilder().where('user_uuid = :userUuid', { userUuid }).getMany()
|
||||
}
|
||||
|
||||
async save(workspaceUser: WorkspaceUser): Promise<WorkspaceUser> {
|
||||
return this.ormRepository.save(workspaceUser)
|
||||
}
|
||||
|
||||
177
yarn.lock
177
yarn.lock
@@ -1824,33 +1824,18 @@ __metadata:
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"@standardnotes/api@npm:^1.11.0":
|
||||
version: 1.11.0
|
||||
resolution: "@standardnotes/api@npm:1.11.0"
|
||||
"@standardnotes/api@npm:^1.15.0":
|
||||
version: 1.15.0
|
||||
resolution: "@standardnotes/api@npm:1.15.0"
|
||||
dependencies:
|
||||
"@standardnotes/common": ^1.32.0
|
||||
"@standardnotes/encryption": 1.16.0
|
||||
"@standardnotes/models": 1.24.0
|
||||
"@standardnotes/responses": 1.10.4
|
||||
"@standardnotes/common": ^1.39.0
|
||||
"@standardnotes/encryption": 1.17.0
|
||||
"@standardnotes/models": 1.26.0
|
||||
"@standardnotes/responses": 1.11.0
|
||||
"@standardnotes/security": ^1.1.0
|
||||
"@standardnotes/utils": 1.9.0
|
||||
"@standardnotes/utils": 1.10.0
|
||||
reflect-metadata: ^0.1.13
|
||||
checksum: f1134efb44a7a2cc8f117bc6a7826d89e11f7780d7ed6f16f654f1a96987cbe6f445ec5f5a91abb11fc79a1e621d9bab30f46fb7a746d44bb5e8b81904d9370f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@standardnotes/api@npm:^1.9.0":
|
||||
version: 1.9.0
|
||||
resolution: "@standardnotes/api@npm:1.9.0"
|
||||
dependencies:
|
||||
"@standardnotes/common": ^1.32.0
|
||||
"@standardnotes/encryption": 1.15.9
|
||||
"@standardnotes/models": 1.22.0
|
||||
"@standardnotes/responses": 1.10.3
|
||||
"@standardnotes/security": ^1.1.0
|
||||
"@standardnotes/utils": 1.9.0
|
||||
reflect-metadata: ^0.1.13
|
||||
checksum: cc3feac3935a382e0ce1fcaf233206a547b6c998cb99ab362d5c7030b3f4e7cbbd3a083eab40bdecbcdc9497dcd283e4513e29dbf200e815ffa46b192ed61b01
|
||||
checksum: 88ae0a340e175b8251e4960f377998a9e21ec5c7967be85c813ff2103d281faea8b13faf787ac51dab4d1737521df136748c9dbd34f0eee2f61d860085bca840
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -1861,7 +1846,7 @@ __metadata:
|
||||
"@newrelic/winston-enricher": ^4.0.0
|
||||
"@sentry/node": ^7.3.0
|
||||
"@standardnotes/analytics": "workspace:*"
|
||||
"@standardnotes/api": ^1.9.0
|
||||
"@standardnotes/api": ^1.15.0
|
||||
"@standardnotes/common": "workspace:*"
|
||||
"@standardnotes/domain-events": "workspace:*"
|
||||
"@standardnotes/domain-events-infra": "workspace:*"
|
||||
@@ -1922,7 +1907,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@standardnotes/common@^1.19.1, @standardnotes/common@^1.23.1, @standardnotes/common@^1.32.0, @standardnotes/common@workspace:*, @standardnotes/common@workspace:^, @standardnotes/common@workspace:packages/common":
|
||||
"@standardnotes/common@^1.19.1, @standardnotes/common@^1.23.1, @standardnotes/common@^1.32.0, @standardnotes/common@^1.39.0, @standardnotes/common@workspace:*, @standardnotes/common@workspace:^, @standardnotes/common@workspace:packages/common":
|
||||
version: 0.0.0-use.local
|
||||
resolution: "@standardnotes/common@workspace:packages/common"
|
||||
dependencies:
|
||||
@@ -1987,31 +1972,17 @@ __metadata:
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"@standardnotes/encryption@npm:1.15.9":
|
||||
version: 1.15.9
|
||||
resolution: "@standardnotes/encryption@npm:1.15.9"
|
||||
"@standardnotes/encryption@npm:1.17.0":
|
||||
version: 1.17.0
|
||||
resolution: "@standardnotes/encryption@npm:1.17.0"
|
||||
dependencies:
|
||||
"@standardnotes/common": ^1.32.0
|
||||
"@standardnotes/models": 1.22.0
|
||||
"@standardnotes/responses": 1.10.3
|
||||
"@standardnotes/sncrypto-common": 1.12.0
|
||||
"@standardnotes/utils": 1.9.0
|
||||
reflect-metadata: ^0.1.13
|
||||
checksum: 7595ac08cea6e54e1456cbff3958969318d90ae237aff166bc4429da5bcf6167c5eb03aa8658a1747486a0639b80b523dae46106ab253c75d24579643cf3e948
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@standardnotes/encryption@npm:1.16.0":
|
||||
version: 1.16.0
|
||||
resolution: "@standardnotes/encryption@npm:1.16.0"
|
||||
dependencies:
|
||||
"@standardnotes/common": ^1.32.0
|
||||
"@standardnotes/models": 1.24.0
|
||||
"@standardnotes/responses": 1.10.4
|
||||
"@standardnotes/common": ^1.39.0
|
||||
"@standardnotes/models": 1.26.0
|
||||
"@standardnotes/responses": 1.11.0
|
||||
"@standardnotes/sncrypto-common": 1.13.0
|
||||
"@standardnotes/utils": 1.9.0
|
||||
"@standardnotes/utils": 1.10.0
|
||||
reflect-metadata: ^0.1.13
|
||||
checksum: 9971b9afcc8d32c7a6d720b43b7e098659d40212abfe1c4387f6b8aee4f410198a0e28db61bfdfdd8defe8cd336a9823e4cc565bf8f72145da2d349cb4be12a6
|
||||
checksum: 587516dfed87ba0bc46fef9ddcc6edb42757c140f852096d6bf6f7911418a7aa1eb0b370c5a0c56eeab3e6b13117ec055374b6e023c64e67cdf2362a584ac06e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -2043,27 +2014,15 @@ __metadata:
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"@standardnotes/features@npm:1.52.1, @standardnotes/features@npm:^1.52.1":
|
||||
version: 1.52.1
|
||||
resolution: "@standardnotes/features@npm:1.52.1"
|
||||
"@standardnotes/features@npm:1.53.0":
|
||||
version: 1.53.0
|
||||
resolution: "@standardnotes/features@npm:1.53.0"
|
||||
dependencies:
|
||||
"@standardnotes/auth": ^3.19.4
|
||||
"@standardnotes/common": ^1.32.0
|
||||
"@standardnotes/common": ^1.39.0
|
||||
"@standardnotes/security": ^1.2.0
|
||||
reflect-metadata: ^0.1.13
|
||||
checksum: ff3684399e0e0c0e799f11e69dddea2e1f65f315e5a5dd3ca5640e24e836ee85faf1f5ee15fc804411bf083004527fcef08411d5c2d0b5894491bf2f28ceca68
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@standardnotes/features@npm:1.52.2":
|
||||
version: 1.52.2
|
||||
resolution: "@standardnotes/features@npm:1.52.2"
|
||||
dependencies:
|
||||
"@standardnotes/auth": ^3.19.4
|
||||
"@standardnotes/common": ^1.32.0
|
||||
"@standardnotes/security": ^1.2.0
|
||||
reflect-metadata: ^0.1.13
|
||||
checksum: ab345f8dc11be32967e439366de0507707a95590b898d6c4332d5d42adbba7bb3fe32bca2ee1fd9948b9106d8186402439916402e8df50cf9e440996420251df
|
||||
checksum: a856e815a313d42706836b1e4c8bbaeb987ee86f2e53bf4b928ed401de483ab11ecd31a8bcb13b23cb7b6a53f72a9f481da2acf68d5e0e970af4ce8c8f2e7c65
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -2078,6 +2037,18 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@standardnotes/features@npm:^1.52.1":
|
||||
version: 1.52.1
|
||||
resolution: "@standardnotes/features@npm:1.52.1"
|
||||
dependencies:
|
||||
"@standardnotes/auth": ^3.19.4
|
||||
"@standardnotes/common": ^1.32.0
|
||||
"@standardnotes/security": ^1.2.0
|
||||
reflect-metadata: ^0.1.13
|
||||
checksum: ff3684399e0e0c0e799f11e69dddea2e1f65f315e5a5dd3ca5640e24e836ee85faf1f5ee15fc804411bf083004527fcef08411d5c2d0b5894491bf2f28ceca68
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@standardnotes/files-server@workspace:packages/files":
|
||||
version: 0.0.0-use.local
|
||||
resolution: "@standardnotes/files-server@workspace:packages/files"
|
||||
@@ -2128,31 +2099,17 @@ __metadata:
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"@standardnotes/models@npm:1.22.0":
|
||||
version: 1.22.0
|
||||
resolution: "@standardnotes/models@npm:1.22.0"
|
||||
"@standardnotes/models@npm:1.26.0, @standardnotes/models@npm:^1.26.0":
|
||||
version: 1.26.0
|
||||
resolution: "@standardnotes/models@npm:1.26.0"
|
||||
dependencies:
|
||||
"@standardnotes/common": ^1.32.0
|
||||
"@standardnotes/features": 1.52.1
|
||||
"@standardnotes/responses": 1.10.3
|
||||
"@standardnotes/utils": 1.9.0
|
||||
"@standardnotes/common": ^1.39.0
|
||||
"@standardnotes/features": 1.53.0
|
||||
"@standardnotes/responses": 1.11.0
|
||||
"@standardnotes/utils": 1.10.0
|
||||
lodash: ^4.17.21
|
||||
reflect-metadata: ^0.1.13
|
||||
checksum: 9928246368b7de7062314374219065507642ed3b6764c27f14ed8d42f0c5a9370fab8731a43a57885a000e461ea60694ba4caa7d9940350839d487cedb7079b5
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@standardnotes/models@npm:1.24.0":
|
||||
version: 1.24.0
|
||||
resolution: "@standardnotes/models@npm:1.24.0"
|
||||
dependencies:
|
||||
"@standardnotes/common": ^1.32.0
|
||||
"@standardnotes/features": 1.52.2
|
||||
"@standardnotes/responses": 1.10.4
|
||||
"@standardnotes/utils": 1.9.0
|
||||
lodash: ^4.17.21
|
||||
reflect-metadata: ^0.1.13
|
||||
checksum: 2acbbbc0629011bc9c901f2e61df936b13f349ff90409072dcfecf4899872f6d0e80d22bd45af9fc0928adc33097fd573983d0f194c4c84e7bf204a28de9943d
|
||||
checksum: f595a3de88ca815d04190ff188c1355ac1848369f94b81f7fc7be3a03918eaaa964eb078bb77622efd1ba7e2db1a47595db94e3ecc90c3544a54838a3980d6b0
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -2181,27 +2138,15 @@ __metadata:
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"@standardnotes/responses@npm:1.10.3":
|
||||
version: 1.10.3
|
||||
resolution: "@standardnotes/responses@npm:1.10.3"
|
||||
"@standardnotes/responses@npm:1.11.0":
|
||||
version: 1.11.0
|
||||
resolution: "@standardnotes/responses@npm:1.11.0"
|
||||
dependencies:
|
||||
"@standardnotes/common": ^1.32.0
|
||||
"@standardnotes/features": 1.52.1
|
||||
"@standardnotes/common": ^1.39.0
|
||||
"@standardnotes/features": 1.53.0
|
||||
"@standardnotes/security": ^1.1.0
|
||||
reflect-metadata: ^0.1.13
|
||||
checksum: 4a1e31eb89342461488f00c65884839d7d935d47d4e217da83967c7cbe181fd0341ee58b744fe607def30d06cd1a8069c3b54f40b3933765303db35ee63f6a0d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@standardnotes/responses@npm:1.10.4":
|
||||
version: 1.10.4
|
||||
resolution: "@standardnotes/responses@npm:1.10.4"
|
||||
dependencies:
|
||||
"@standardnotes/common": ^1.32.0
|
||||
"@standardnotes/features": 1.52.2
|
||||
"@standardnotes/security": ^1.1.0
|
||||
reflect-metadata: ^0.1.13
|
||||
checksum: 41e4971144950e168c0de3d05a2871857d9a416ad8061849b646992f04d6590dce43e8161af0cb05c3faed1856fd4bf93fceea3fcabeebf62b5761e5376ce8c6
|
||||
checksum: 46d6a479806507b15dc6f949e8863915f2cac81964aac715aab0bfc063e7bd7961767fcc6488e08397a0e1a52ccf2808429d8660b98a79415e25f601719125dc
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -2301,15 +2246,6 @@ __metadata:
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"@standardnotes/sncrypto-common@npm:1.12.0":
|
||||
version: 1.12.0
|
||||
resolution: "@standardnotes/sncrypto-common@npm:1.12.0"
|
||||
dependencies:
|
||||
reflect-metadata: ^0.1.13
|
||||
checksum: b89a14bd233cb781213b2e25dd8d7bfe911820d341903f2987647c168745c3afb710ad94fa42e50aaafb644ee4a7b5fd64ec137f622cfc082951fd584af0d230
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@standardnotes/sncrypto-common@npm:1.13.0":
|
||||
version: 1.13.0
|
||||
resolution: "@standardnotes/sncrypto-common@npm:1.13.0"
|
||||
@@ -2413,15 +2349,15 @@ __metadata:
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"@standardnotes/utils@npm:1.9.0":
|
||||
version: 1.9.0
|
||||
resolution: "@standardnotes/utils@npm:1.9.0"
|
||||
"@standardnotes/utils@npm:1.10.0":
|
||||
version: 1.10.0
|
||||
resolution: "@standardnotes/utils@npm:1.10.0"
|
||||
dependencies:
|
||||
"@standardnotes/common": ^1.32.0
|
||||
"@standardnotes/common": ^1.39.0
|
||||
dompurify: ^2.3.8
|
||||
lodash: ^4.17.21
|
||||
reflect-metadata: ^0.1.13
|
||||
checksum: 4591aff48d074b30b911f96c63eaaf521ab49563507672fbd4d7fe460e51f88a45effb002d1c82cca3513d2199c0cdb720556b03ec3e0266f593317c8efa764a
|
||||
checksum: c02d54ca8a4debb62ecf6642825e1c313b3aad11767b1f0e6d36a976ec3058eba8592ab3194544042825296357676bc821e168489b638b0514bd1650dc9d0e0d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -2442,10 +2378,11 @@ __metadata:
|
||||
dependencies:
|
||||
"@newrelic/winston-enricher": ^4.0.0
|
||||
"@sentry/node": ^7.3.0
|
||||
"@standardnotes/api": ^1.11.0
|
||||
"@standardnotes/api": ^1.15.0
|
||||
"@standardnotes/common": "workspace:*"
|
||||
"@standardnotes/domain-events": "workspace:^"
|
||||
"@standardnotes/domain-events-infra": "workspace:^"
|
||||
"@standardnotes/models": ^1.26.0
|
||||
"@standardnotes/security": "workspace:*"
|
||||
"@standardnotes/time": "workspace:^"
|
||||
"@types/cors": ^2.8.9
|
||||
|
||||
Reference in New Issue
Block a user