mirror of
https://github.com/standardnotes/server
synced 2026-01-22 02:04:30 -05:00
Compare commits
13 Commits
@standardn
...
@standardn
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1f7989dbed | ||
|
|
0ea88ad202 | ||
|
|
2d41742c34 | ||
|
|
447d600dbe | ||
|
|
3f6db48f83 | ||
|
|
156ab65272 | ||
|
|
a986ee1ccb | ||
|
|
868b7d149a | ||
|
|
b1763b539e | ||
|
|
d21517abe6 | ||
|
|
7ef6765d5b | ||
|
|
11492977c9 | ||
|
|
d133c5aacd |
5
.github/dependabot.yml
vendored
5
.github/dependabot.yml
vendored
@@ -85,6 +85,11 @@ updates:
|
||||
schedule:
|
||||
interval: "daily"
|
||||
|
||||
- package-ecosystem: "npm"
|
||||
directory: "/packages/workspace"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
|
||||
2
.github/workflows/snjs.upgrade.event.yml
vendored
2
.github/workflows/snjs.upgrade.event.yml
vendored
@@ -24,7 +24,7 @@ jobs:
|
||||
git config --global user.name "standardci"
|
||||
git config --global user.email "ci@standardnotes.com"
|
||||
- name: Import GPG key
|
||||
uses: crazy-max/ghaction-import-gpg@v4
|
||||
uses: crazy-max/ghaction-import-gpg@v5
|
||||
with:
|
||||
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
|
||||
passphrase: ${{ secrets.PASSPHRASE }}
|
||||
|
||||
71
.pnp.cjs
generated
71
.pnp.cjs
generated
@@ -2521,6 +2521,20 @@ 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/",\
|
||||
"packageDependencies": [\
|
||||
["@standardnotes/api", "npm:1.11.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/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": [\
|
||||
@@ -2737,6 +2751,19 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||
["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/sncrypto-common", "npm:1.13.0"],\
|
||||
["@standardnotes/utils", "npm:1.9.0"],\
|
||||
["reflect-metadata", "npm:0.1.13"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["@standardnotes/event-store", [\
|
||||
@@ -2790,6 +2817,17 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||
["reflect-metadata", "npm:0.1.13"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}],\
|
||||
["npm:1.52.2", {\
|
||||
"packageLocation": "./.yarn/cache/@standardnotes-features-npm-1.52.2-076ab9f511-ab345f8dc1.zip/node_modules/@standardnotes/features/",\
|
||||
"packageDependencies": [\
|
||||
["@standardnotes/features", "npm:1.52.2"],\
|
||||
["@standardnotes/auth", "npm:3.19.4"],\
|
||||
["@standardnotes/common", "workspace:packages/common"],\
|
||||
["@standardnotes/security", "workspace:packages/security"],\
|
||||
["reflect-metadata", "npm:0.1.13"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["@standardnotes/files-server", [\
|
||||
@@ -2857,6 +2895,19 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||
["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"],\
|
||||
["lodash", "npm:4.17.21"],\
|
||||
["reflect-metadata", "npm:0.1.13"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["@standardnotes/payloads", [\
|
||||
@@ -2899,6 +2950,17 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||
],\
|
||||
"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/security", "workspace:packages/security"],\
|
||||
["reflect-metadata", "npm:0.1.13"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}],\
|
||||
["npm:1.6.39", {\
|
||||
"packageLocation": "./.yarn/cache/@standardnotes-responses-npm-1.6.39-395f4c2d65-0ea1d4d5b8.zip/node_modules/@standardnotes/responses/",\
|
||||
"packageDependencies": [\
|
||||
@@ -3012,6 +3074,14 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||
],\
|
||||
"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": [\
|
||||
["@standardnotes/sncrypto-common", "npm:1.13.0"],\
|
||||
["reflect-metadata", "npm:0.1.13"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}],\
|
||||
["npm:1.9.0", {\
|
||||
"packageLocation": "./.yarn/cache/@standardnotes-sncrypto-common-npm-1.9.0-48773f745a-42252d7198.zip/node_modules/@standardnotes/sncrypto-common/",\
|
||||
"packageDependencies": [\
|
||||
@@ -3143,6 +3213,7 @@ 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/common", "workspace:packages/common"],\
|
||||
["@standardnotes/domain-events", "workspace:packages/domain-events"],\
|
||||
["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\
|
||||
|
||||
BIN
.yarn/cache/@standardnotes-api-npm-1.11.0-ce72fb3e14-f1134efb44.zip
vendored
Normal file
BIN
.yarn/cache/@standardnotes-api-npm-1.11.0-ce72fb3e14-f1134efb44.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@standardnotes-encryption-npm-1.16.0-df46ea19bc-9971b9afcc.zip
vendored
Normal file
BIN
.yarn/cache/@standardnotes-encryption-npm-1.16.0-df46ea19bc-9971b9afcc.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@standardnotes-features-npm-1.52.2-076ab9f511-ab345f8dc1.zip
vendored
Normal file
BIN
.yarn/cache/@standardnotes-features-npm-1.52.2-076ab9f511-ab345f8dc1.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@standardnotes-models-npm-1.24.0-bf039594ac-2acbbbc062.zip
vendored
Normal file
BIN
.yarn/cache/@standardnotes-models-npm-1.24.0-bf039594ac-2acbbbc062.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@standardnotes-responses-npm-1.10.4-3af0d3ab54-41e4971144.zip
vendored
Normal file
BIN
.yarn/cache/@standardnotes-responses-npm-1.10.4-3af0d3ab54-41e4971144.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@standardnotes-sncrypto-common-npm-1.13.0-18cb5f8eb9-e58258f525.zip
vendored
Normal file
BIN
.yarn/cache/@standardnotes-sncrypto-common-npm-1.13.0-18cb5f8eb9-e58258f525.zip
vendored
Normal file
Binary file not shown.
@@ -6,6 +6,7 @@ PORT=3000
|
||||
|
||||
SYNCING_SERVER_JS_URL=http://syncing_server_js:3000
|
||||
AUTH_SERVER_URL=http://auth:3000
|
||||
WORKSPACE_SERVER_URL=http://workspace:3000
|
||||
PAYMENTS_SERVER_URL=http://payments:3000
|
||||
FILES_SERVER_URL=http://files:3000
|
||||
|
||||
|
||||
@@ -3,6 +3,20 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.27.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.27.0...@standardnotes/api-gateway@1.27.1) (2022-10-10)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||
|
||||
# [1.27.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.26.2...@standardnotes/api-gateway@1.27.0) (2022-10-07)
|
||||
|
||||
### Features
|
||||
|
||||
* add workspaces creation ([156ab65](https://github.com/standardnotes/api-gateway/commit/156ab6527265351b13797394cbd34da037ab5a38))
|
||||
|
||||
## [1.26.2](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.26.1...@standardnotes/api-gateway@1.26.2) (2022-10-07)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||
|
||||
## [1.26.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.26.0...@standardnotes/api-gateway@1.26.1) (2022-10-06)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||
|
||||
@@ -19,6 +19,7 @@ import '../src/Controller/v1/TokensController'
|
||||
import '../src/Controller/v1/OfflineController'
|
||||
import '../src/Controller/v1/FilesController'
|
||||
import '../src/Controller/v1/SubscriptionInvitesController'
|
||||
import '../src/Controller/v1/WorkspacesController'
|
||||
|
||||
import '../src/Controller/v2/PaymentsControllerV2'
|
||||
import '../src/Controller/v2/ActionsControllerV2'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/api-gateway",
|
||||
"version": "1.26.1",
|
||||
"version": "1.27.1",
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.0.0"
|
||||
},
|
||||
|
||||
@@ -75,6 +75,7 @@ export class ContainerConfigLoader {
|
||||
container.bind(TYPES.PAYMENTS_SERVER_URL).toConstantValue(env.get('PAYMENTS_SERVER_URL', true))
|
||||
container.bind(TYPES.FILES_SERVER_URL).toConstantValue(env.get('FILES_SERVER_URL', true))
|
||||
container.bind(TYPES.AUTH_JWT_SECRET).toConstantValue(env.get('AUTH_JWT_SECRET'))
|
||||
container.bind(TYPES.WORKSPACE_SERVER_URL).toConstantValue(env.get('WORKSPACE_SERVER_URL'))
|
||||
container
|
||||
.bind(TYPES.HTTP_CALL_TIMEOUT)
|
||||
.toConstantValue(env.get('HTTP_CALL_TIMEOUT', true) ? +env.get('HTTP_CALL_TIMEOUT', true) : 60_000)
|
||||
|
||||
@@ -8,6 +8,7 @@ const TYPES = {
|
||||
AUTH_SERVER_URL: Symbol.for('AUTH_SERVER_URL'),
|
||||
PAYMENTS_SERVER_URL: Symbol.for('PAYMENTS_SERVER_URL'),
|
||||
FILES_SERVER_URL: Symbol.for('FILES_SERVER_URL'),
|
||||
WORKSPACE_SERVER_URL: Symbol.for('WORKSPACE_SERVER_URL'),
|
||||
AUTH_JWT_SECRET: Symbol.for('AUTH_JWT_SECRET'),
|
||||
HTTP_CALL_TIMEOUT: Symbol.for('HTTP_CALL_TIMEOUT'),
|
||||
VERSION: Symbol.for('VERSION'),
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
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/workspaces')
|
||||
export class WorkspacesController extends BaseHttpController {
|
||||
constructor(@inject(TYPES.HTTPService) private httpService: HttpServiceInterface) {
|
||||
super()
|
||||
}
|
||||
|
||||
@httpPost('/', TYPES.AuthMiddleware)
|
||||
async create(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callWorkspaceServer(request, response, 'workspaces', request.body)
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@ export class HttpService implements HttpServiceInterface {
|
||||
@inject(TYPES.SYNCING_SERVER_JS_URL) private syncingServerJsUrl: string,
|
||||
@inject(TYPES.PAYMENTS_SERVER_URL) private paymentsServerUrl: string,
|
||||
@inject(TYPES.FILES_SERVER_URL) private filesServerUrl: string,
|
||||
@inject(TYPES.WORKSPACE_SERVER_URL) private workspaceServerUrl: string,
|
||||
@inject(TYPES.HTTP_CALL_TIMEOUT) private httpCallTimeout: number,
|
||||
@inject(TYPES.CrossServiceTokenCache) private crossServiceTokenCache: CrossServiceTokenCacheInterface,
|
||||
@inject(TYPES.Logger) private logger: Logger,
|
||||
@@ -48,6 +49,15 @@ export class HttpService implements HttpServiceInterface {
|
||||
await this.callServer(this.authServerUrl, request, response, endpoint, payload)
|
||||
}
|
||||
|
||||
async callWorkspaceServer(
|
||||
request: Request,
|
||||
response: Response,
|
||||
endpoint: string,
|
||||
payload?: Record<string, unknown> | string,
|
||||
): Promise<void> {
|
||||
await this.callServer(this.workspaceServerUrl, request, response, endpoint, payload)
|
||||
}
|
||||
|
||||
async callPaymentsServer(
|
||||
request: Request,
|
||||
response: Response,
|
||||
|
||||
@@ -31,4 +31,10 @@ export interface HttpServiceInterface {
|
||||
endpoint: string,
|
||||
payload?: Record<string, unknown> | string,
|
||||
): Promise<void>
|
||||
callWorkspaceServer(
|
||||
request: Request,
|
||||
response: Response,
|
||||
endpoint: string,
|
||||
payload?: Record<string, unknown> | string,
|
||||
): Promise<void>
|
||||
}
|
||||
|
||||
@@ -3,6 +3,22 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.40.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.40.0...@standardnotes/auth-server@1.40.1) (2022-10-10)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/auth-server
|
||||
|
||||
# [1.40.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.39.2...@standardnotes/auth-server@1.40.0) (2022-10-07)
|
||||
|
||||
### Features
|
||||
|
||||
* add user protocol version to the user registration event ([868b7d1](https://github.com/standardnotes/server/commit/868b7d149a572d1991b77daaa37e4c77e10f07d3))
|
||||
|
||||
## [1.39.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.39.1...@standardnotes/auth-server@1.39.2) (2022-10-06)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **auth:** add warning logs for unrecognized payment type ([d21517a](https://github.com/standardnotes/server/commit/d21517abe6a7ed4773e73e83a347bae69495c084))
|
||||
|
||||
## [1.39.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.39.0...@standardnotes/auth-server@1.39.1) (2022-10-06)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/auth-server
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/auth-server",
|
||||
"version": "1.39.1",
|
||||
"version": "1.40.1",
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.0.0"
|
||||
},
|
||||
|
||||
@@ -11,6 +11,7 @@ import TYPES from '../Bootstrap/Types'
|
||||
import { ClearLoginAttempts } from '../Domain/UseCase/ClearLoginAttempts'
|
||||
import { Register } from '../Domain/UseCase/Register'
|
||||
import { DomainEventFactoryInterface } from '../Domain/Event/DomainEventFactoryInterface'
|
||||
import { ProtocolVersion } from '@standardnotes/common'
|
||||
|
||||
@injectable()
|
||||
export class AuthController implements UserServerInterface {
|
||||
@@ -59,10 +60,11 @@ export class AuthController implements UserServerInterface {
|
||||
await this.clearLoginAttempts.execute({ email: registerResult.authResponse.user.email as string })
|
||||
|
||||
await this.domainEventPublisher.publish(
|
||||
this.domainEventFactory.createUserRegisteredEvent(
|
||||
<string>registerResult.authResponse.user.uuid,
|
||||
<string>registerResult.authResponse.user.email,
|
||||
),
|
||||
this.domainEventFactory.createUserRegisteredEvent({
|
||||
userUuid: <string>registerResult.authResponse.user.uuid,
|
||||
email: <string>registerResult.authResponse.user.email,
|
||||
protocolVersion: (<string>registerResult.authResponse.user.protocolVersion) as ProtocolVersion,
|
||||
}),
|
||||
)
|
||||
|
||||
return {
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { Uuid } from '@standardnotes/common'
|
||||
import { ProtocolVersion, Uuid } from '@standardnotes/common'
|
||||
|
||||
export interface AuthResponse {
|
||||
user: {
|
||||
uuid: Uuid
|
||||
email: string
|
||||
protocolVersion: ProtocolVersion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { SessionTokenData, TokenEncoderInterface } from '@standardnotes/security'
|
||||
import { Uuid } from '@standardnotes/common'
|
||||
import { ProtocolVersion, Uuid } from '@standardnotes/common'
|
||||
import * as crypto from 'crypto'
|
||||
|
||||
import { inject, injectable } from 'inversify'
|
||||
@@ -39,7 +39,11 @@ export class AuthResponseFactory20161215 implements AuthResponseFactoryInterface
|
||||
this.logger.debug(`Created JWT token for user ${dto.user.uuid}: ${token}`)
|
||||
|
||||
return {
|
||||
user: this.userProjector.projectSimple(dto.user) as { uuid: Uuid; email: string },
|
||||
user: this.userProjector.projectSimple(dto.user) as {
|
||||
uuid: Uuid
|
||||
email: string
|
||||
protocolVersion: ProtocolVersion
|
||||
},
|
||||
token,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import {
|
||||
SessionTokenData,
|
||||
TokenEncoderInterface,
|
||||
} from '@standardnotes/security'
|
||||
import { Uuid } from '@standardnotes/common'
|
||||
import { ProtocolVersion, Uuid } from '@standardnotes/common'
|
||||
import { SessionBody } from '@standardnotes/responses'
|
||||
import { inject, injectable } from 'inversify'
|
||||
import { Logger } from 'winston'
|
||||
@@ -48,7 +48,11 @@ export class AuthResponseFactory20200115 extends AuthResponseFactory20190520 {
|
||||
return {
|
||||
session: sessionPayload,
|
||||
key_params: this.keyParamsFactory.create(dto.user, true),
|
||||
user: this.userProjector.projectSimple(dto.user) as { uuid: Uuid; email: string },
|
||||
user: this.userProjector.projectSimple(dto.user) as {
|
||||
uuid: Uuid
|
||||
email: string
|
||||
protocolVersion: ProtocolVersion
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import 'reflect-metadata'
|
||||
|
||||
import { EmailMessageIdentifier, RoleName } from '@standardnotes/common'
|
||||
import { EmailMessageIdentifier, ProtocolVersion, RoleName } from '@standardnotes/common'
|
||||
import { PredicateName, PredicateAuthority, PredicateVerificationResult } from '@standardnotes/predicates'
|
||||
import { TimerInterface } from '@standardnotes/time'
|
||||
|
||||
@@ -212,7 +212,13 @@ describe('DomainEventFactory', () => {
|
||||
})
|
||||
|
||||
it('should create a USER_REGISTERED event', () => {
|
||||
expect(createFactory().createUserRegisteredEvent('1-2-3', 'test@test.te')).toEqual({
|
||||
expect(
|
||||
createFactory().createUserRegisteredEvent({
|
||||
userUuid: '1-2-3',
|
||||
email: 'test@test.te',
|
||||
protocolVersion: ProtocolVersion.V004,
|
||||
}),
|
||||
).toEqual({
|
||||
createdAt: expect.any(Date),
|
||||
meta: {
|
||||
correlation: {
|
||||
@@ -224,6 +230,7 @@ describe('DomainEventFactory', () => {
|
||||
payload: {
|
||||
userUuid: '1-2-3',
|
||||
email: 'test@test.te',
|
||||
protocolVersion: '004',
|
||||
},
|
||||
type: 'USER_REGISTERED',
|
||||
})
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { EmailMessageIdentifier, RoleName, Uuid } from '@standardnotes/common'
|
||||
import { EmailMessageIdentifier, ProtocolVersion, RoleName, Uuid } from '@standardnotes/common'
|
||||
import {
|
||||
AccountDeletionRequestedEvent,
|
||||
UserEmailChangedEvent,
|
||||
@@ -253,21 +253,22 @@ export class DomainEventFactory implements DomainEventFactoryInterface {
|
||||
}
|
||||
}
|
||||
|
||||
createUserRegisteredEvent(userUuid: string, email: string): UserRegisteredEvent {
|
||||
createUserRegisteredEvent(dto: {
|
||||
userUuid: string
|
||||
email: string
|
||||
protocolVersion: ProtocolVersion
|
||||
}): UserRegisteredEvent {
|
||||
return {
|
||||
type: 'USER_REGISTERED',
|
||||
createdAt: this.timer.getUTCDate(),
|
||||
meta: {
|
||||
correlation: {
|
||||
userIdentifier: userUuid,
|
||||
userIdentifier: dto.userUuid,
|
||||
userIdentifierType: 'uuid',
|
||||
},
|
||||
origin: DomainEventService.Auth,
|
||||
},
|
||||
payload: {
|
||||
userUuid,
|
||||
email,
|
||||
},
|
||||
payload: dto,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Uuid, RoleName, EmailMessageIdentifier } from '@standardnotes/common'
|
||||
import { Uuid, RoleName, EmailMessageIdentifier, ProtocolVersion } from '@standardnotes/common'
|
||||
import { Predicate, PredicateVerificationResult } from '@standardnotes/predicates'
|
||||
import {
|
||||
AccountDeletionRequestedEvent,
|
||||
@@ -33,7 +33,11 @@ export interface DomainEventFactoryInterface {
|
||||
muteSignInEmailsSettingUuid: Uuid
|
||||
}): UserSignedInEvent
|
||||
createListedAccountRequestedEvent(userUuid: string, userEmail: string): ListedAccountRequestedEvent
|
||||
createUserRegisteredEvent(userUuid: string, email: string): UserRegisteredEvent
|
||||
createUserRegisteredEvent(dto: {
|
||||
userUuid: string
|
||||
email: string
|
||||
protocolVersion: ProtocolVersion
|
||||
}): UserRegisteredEvent
|
||||
createEmailBackupRequestedEvent(
|
||||
userUuid: string,
|
||||
muteEmailsSettingUuid: string,
|
||||
|
||||
@@ -7,6 +7,7 @@ import { PaymentSuccessEventHandler } from './PaymentSuccessEventHandler'
|
||||
import { UserRepositoryInterface } from '../User/UserRepositoryInterface'
|
||||
import { User } from '../User/User'
|
||||
import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId'
|
||||
import { Logger } from 'winston'
|
||||
|
||||
describe('PaymentSuccessEventHandler', () => {
|
||||
let userRepository: UserRepositoryInterface
|
||||
@@ -15,9 +16,10 @@ describe('PaymentSuccessEventHandler', () => {
|
||||
let getUserAnalyticsId: GetUserAnalyticsId
|
||||
let analyticsStore: AnalyticsStoreInterface
|
||||
let statisticsStore: StatisticsStoreInterface
|
||||
let logger: Logger
|
||||
|
||||
const createHandler = () =>
|
||||
new PaymentSuccessEventHandler(userRepository, getUserAnalyticsId, analyticsStore, statisticsStore)
|
||||
new PaymentSuccessEventHandler(userRepository, getUserAnalyticsId, analyticsStore, statisticsStore, logger)
|
||||
|
||||
beforeEach(() => {
|
||||
user = {} as jest.Mocked<User>
|
||||
@@ -42,6 +44,9 @@ describe('PaymentSuccessEventHandler', () => {
|
||||
paymentType: 'initial',
|
||||
subscriptionName: 'PRO_PLAN',
|
||||
}
|
||||
|
||||
logger = {} as jest.Mocked<Logger>
|
||||
logger.warn = jest.fn()
|
||||
})
|
||||
|
||||
it('should mark payment success for analytics', async () => {
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
import { PaymentType, SubscriptionBillingFrequency, SubscriptionName } from '@standardnotes/common'
|
||||
import { DomainEventHandlerInterface, PaymentSuccessEvent } from '@standardnotes/domain-events'
|
||||
import { inject, injectable } from 'inversify'
|
||||
import { Logger } from 'winston'
|
||||
|
||||
import TYPES from '../../Bootstrap/Types'
|
||||
import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId'
|
||||
@@ -61,6 +62,7 @@ export class PaymentSuccessEventHandler implements DomainEventHandlerInterface {
|
||||
@inject(TYPES.GetUserAnalyticsId) private getUserAnalyticsId: GetUserAnalyticsId,
|
||||
@inject(TYPES.AnalyticsStore) private analyticsStore: AnalyticsStoreInterface,
|
||||
@inject(TYPES.StatisticsStore) private statisticsStore: StatisticsStoreInterface,
|
||||
@inject(TYPES.Logger) private logger: Logger,
|
||||
) {}
|
||||
|
||||
async handle(event: PaymentSuccessEvent): Promise<void> {
|
||||
@@ -83,6 +85,10 @@ export class PaymentSuccessEventHandler implements DomainEventHandlerInterface {
|
||||
?.get(event.payload.billingFrequency as SubscriptionBillingFrequency)
|
||||
if (detailedMeasure !== undefined) {
|
||||
statisticMeasures.push(detailedMeasure)
|
||||
} else {
|
||||
this.logger.warn(
|
||||
`Could not find detailed measure for: subscription - ${event.payload.subscriptionName}, payment type - ${event.payload.paymentType}, billing frequency - ${event.payload.billingFrequency}`,
|
||||
)
|
||||
}
|
||||
|
||||
for (const measure of statisticMeasures) {
|
||||
|
||||
@@ -6,6 +6,7 @@ import { UserRegisteredEventHandler } from './UserRegisteredEventHandler'
|
||||
import { AxiosInstance } from 'axios'
|
||||
import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId'
|
||||
import { AnalyticsStoreInterface } from '@standardnotes/analytics'
|
||||
import { ProtocolVersion } from '@standardnotes/common'
|
||||
|
||||
describe('UserRegisteredEventHandler', () => {
|
||||
let httpClient: AxiosInstance
|
||||
@@ -35,6 +36,7 @@ describe('UserRegisteredEventHandler', () => {
|
||||
event.payload = {
|
||||
userUuid: '1-2-3',
|
||||
email: 'test@test.te',
|
||||
protocolVersion: ProtocolVersion.V004,
|
||||
}
|
||||
|
||||
getUserAnalyticsId = {} as jest.Mocked<GetUserAnalyticsId>
|
||||
|
||||
@@ -9,6 +9,7 @@ export class UserProjector implements ProjectorInterface<User> {
|
||||
return {
|
||||
uuid: user.uuid,
|
||||
email: user.email,
|
||||
protocolVersion: user.version,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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.36.1](https://github.com/standardnotes/server/compare/@standardnotes/common@1.36.0...@standardnotes/common@1.36.1) (2022-10-10)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **workspace:** extract workspace type to common types ([0ea88ad](https://github.com/standardnotes/server/commit/0ea88ad202d54de79d1433183c1706823639da93))
|
||||
|
||||
# [1.36.0](https://github.com/standardnotes/server/compare/@standardnotes/common@1.35.1...@standardnotes/common@1.36.0) (2022-10-07)
|
||||
|
||||
### Features
|
||||
|
||||
* add user protocol version to the user registration event ([868b7d1](https://github.com/standardnotes/server/commit/868b7d149a572d1991b77daaa37e4c77e10f07d3))
|
||||
|
||||
## [1.35.1](https://github.com/standardnotes/server/compare/@standardnotes/common@1.35.0...@standardnotes/common@1.35.1) (2022-10-06)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/common
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/common",
|
||||
"version": "1.35.1",
|
||||
"version": "1.36.1",
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,7 @@ export enum ProtocolVersion {
|
||||
V002 = '002',
|
||||
V003 = '003',
|
||||
V004 = '004',
|
||||
V005 = '005',
|
||||
}
|
||||
|
||||
export const ProtocolVersionLatest = ProtocolVersion.V004
|
||||
|
||||
@@ -24,3 +24,4 @@ export * from './Type/Either'
|
||||
export * from './Type/Only'
|
||||
export * from './Validator/UuidValidator'
|
||||
export * from './Validator/ValidatorInterface'
|
||||
export * from './Workspace/WorkspaceType'
|
||||
|
||||
@@ -3,6 +3,14 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.8.20](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.8.19...@standardnotes/domain-events-infra@1.8.20) (2022-10-10)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/domain-events-infra
|
||||
|
||||
## [1.8.19](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.8.18...@standardnotes/domain-events-infra@1.8.19) (2022-10-07)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/domain-events-infra
|
||||
|
||||
## [1.8.18](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.8.17...@standardnotes/domain-events-infra@1.8.18) (2022-10-06)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/domain-events-infra
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/domain-events-infra",
|
||||
"version": "1.8.18",
|
||||
"version": "1.8.20",
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,16 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [2.64.1](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.64.0...@standardnotes/domain-events@2.64.1) (2022-10-10)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/domain-events
|
||||
|
||||
# [2.64.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.63.1...@standardnotes/domain-events@2.64.0) (2022-10-07)
|
||||
|
||||
### Features
|
||||
|
||||
* add user protocol version to the user registration event ([868b7d1](https://github.com/standardnotes/server/commit/868b7d149a572d1991b77daaa37e4c77e10f07d3))
|
||||
|
||||
## [2.63.1](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.63.0...@standardnotes/domain-events@2.63.1) (2022-10-06)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/domain-events
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/domain-events",
|
||||
"version": "2.63.1",
|
||||
"version": "2.64.1",
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.0.0"
|
||||
},
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
export interface UserRegisteredEventPayload {
|
||||
userUuid: string
|
||||
email: string
|
||||
protocolVersion: string
|
||||
}
|
||||
|
||||
@@ -3,6 +3,14 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.3.25](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.3.24...@standardnotes/event-store@1.3.25) (2022-10-10)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/event-store
|
||||
|
||||
## [1.3.24](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.3.23...@standardnotes/event-store@1.3.24) (2022-10-07)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/event-store
|
||||
|
||||
## [1.3.23](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.3.22...@standardnotes/event-store@1.3.23) (2022-10-06)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/event-store
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/event-store",
|
||||
"version": "1.3.23",
|
||||
"version": "1.3.25",
|
||||
"description": "Event Store Service",
|
||||
"private": true,
|
||||
"main": "dist/src/index.js",
|
||||
|
||||
@@ -3,6 +3,14 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.6.11](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.6.10...@standardnotes/files-server@1.6.11) (2022-10-10)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/files-server
|
||||
|
||||
## [1.6.10](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.6.9...@standardnotes/files-server@1.6.10) (2022-10-07)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/files-server
|
||||
|
||||
## [1.6.9](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.6.8...@standardnotes/files-server@1.6.9) (2022-10-06)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/files-server
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/files-server",
|
||||
"version": "1.6.9",
|
||||
"version": "1.6.11",
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,14 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [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.4.6](https://github.com/standardnotes/server/compare/@standardnotes/predicates@1.4.5...@standardnotes/predicates@1.4.6) (2022-10-07)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/predicates
|
||||
|
||||
## [1.4.5](https://github.com/standardnotes/server/compare/@standardnotes/predicates@1.4.4...@standardnotes/predicates@1.4.5) (2022-10-06)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/predicates
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/predicates",
|
||||
"version": "1.4.5",
|
||||
"version": "1.4.7",
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,14 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.10.39](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.10.38...@standardnotes/scheduler-server@1.10.39) (2022-10-10)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/scheduler-server
|
||||
|
||||
## [1.10.38](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.10.37...@standardnotes/scheduler-server@1.10.38) (2022-10-07)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/scheduler-server
|
||||
|
||||
## [1.10.37](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.10.36...@standardnotes/scheduler-server@1.10.37) (2022-10-06)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/scheduler-server
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/scheduler-server",
|
||||
"version": "1.10.37",
|
||||
"version": "1.10.39",
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,14 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [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.4.4](https://github.com/standardnotes/server/compare/@standardnotes/security@1.4.3...@standardnotes/security@1.4.4) (2022-10-07)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/security
|
||||
|
||||
## [1.4.3](https://github.com/standardnotes/server/compare/@standardnotes/security@1.4.2...@standardnotes/security@1.4.3) (2022-10-06)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/security
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/security",
|
||||
"version": "1.4.3",
|
||||
"version": "1.4.5",
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,16 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.9.1](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.9.0...@standardnotes/syncing-server@1.9.1) (2022-10-10)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/syncing-server
|
||||
|
||||
# [1.9.0](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.8.21...@standardnotes/syncing-server@1.9.0) (2022-10-07)
|
||||
|
||||
### Features
|
||||
|
||||
* add user protocol version to the user registration event ([868b7d1](https://github.com/standardnotes/syncing-server-js/commit/868b7d149a572d1991b77daaa37e4c77e10f07d3))
|
||||
|
||||
## [1.8.21](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.8.20...@standardnotes/syncing-server@1.8.21) (2022-10-06)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/syncing-server
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/syncing-server",
|
||||
"version": "1.8.21",
|
||||
"version": "1.9.1",
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.0.0"
|
||||
},
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { TimerInterface } from '@standardnotes/time'
|
||||
import 'reflect-metadata'
|
||||
|
||||
import { TimerInterface } from '@standardnotes/time'
|
||||
|
||||
import { DomainEventFactory } from './DomainEventFactory'
|
||||
|
||||
describe('DomainEventFactory', () => {
|
||||
@@ -13,24 +14,6 @@ describe('DomainEventFactory', () => {
|
||||
timer.getUTCDate = jest.fn().mockReturnValue(new Date(1))
|
||||
})
|
||||
|
||||
it('should create a USER_REGISTERED event', () => {
|
||||
expect(createFactory().createUserRegisteredEvent('1-2-3', 'test@test.te')).toEqual({
|
||||
createdAt: expect.any(Date),
|
||||
meta: {
|
||||
correlation: {
|
||||
userIdentifier: '1-2-3',
|
||||
userIdentifierType: 'uuid',
|
||||
},
|
||||
origin: 'syncing-server',
|
||||
},
|
||||
payload: {
|
||||
userUuid: '1-2-3',
|
||||
email: 'test@test.te',
|
||||
},
|
||||
type: 'USER_REGISTERED',
|
||||
})
|
||||
})
|
||||
|
||||
it('should create a ITEMS_SYNCED event', () => {
|
||||
expect(
|
||||
createFactory().createItemsSyncedEvent({
|
||||
|
||||
@@ -7,7 +7,6 @@ import {
|
||||
GoogleDriveBackupFailedEvent,
|
||||
ItemsSyncedEvent,
|
||||
OneDriveBackupFailedEvent,
|
||||
UserRegisteredEvent,
|
||||
} from '@standardnotes/domain-events'
|
||||
import { TimerInterface } from '@standardnotes/time'
|
||||
import { inject, injectable } from 'inversify'
|
||||
@@ -113,24 +112,6 @@ export class DomainEventFactory implements DomainEventFactoryInterface {
|
||||
}
|
||||
}
|
||||
|
||||
createUserRegisteredEvent(userUuid: string, email: string): UserRegisteredEvent {
|
||||
return {
|
||||
type: 'USER_REGISTERED',
|
||||
createdAt: this.timer.getUTCDate(),
|
||||
meta: {
|
||||
correlation: {
|
||||
userIdentifier: userUuid,
|
||||
userIdentifierType: 'uuid',
|
||||
},
|
||||
origin: DomainEventService.SyncingServer,
|
||||
},
|
||||
payload: {
|
||||
userUuid,
|
||||
email,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
createEmailArchiveExtensionSyncedEvent(userUuid: string, extensionId: string): EmailArchiveExtensionSyncedEvent {
|
||||
return {
|
||||
type: 'EMAIL_ARCHIVE_EXTENSION_SYNCED',
|
||||
|
||||
@@ -6,11 +6,9 @@ import {
|
||||
GoogleDriveBackupFailedEvent,
|
||||
ItemsSyncedEvent,
|
||||
OneDriveBackupFailedEvent,
|
||||
UserRegisteredEvent,
|
||||
} from '@standardnotes/domain-events'
|
||||
|
||||
export interface DomainEventFactoryInterface {
|
||||
createUserRegisteredEvent(userUuid: string, email: string): UserRegisteredEvent
|
||||
createDropboxBackupFailedEvent(muteCloudEmailsSettingUuid: string, email: string): DropboxBackupFailedEvent
|
||||
createGoogleDriveBackupFailedEvent(muteCloudEmailsSettingUuid: string, email: string): GoogleDriveBackupFailedEvent
|
||||
createOneDriveBackupFailedEvent(muteCloudEmailsSettingUuid: string, email: string): OneDriveBackupFailedEvent
|
||||
|
||||
@@ -3,6 +3,28 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.2.2](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.2.1...@standardnotes/workspace-server@1.2.2) (2022-10-10)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **workspace:** extract workspace type to common types ([0ea88ad](https://github.com/standardnotes/server/commit/0ea88ad202d54de79d1433183c1706823639da93))
|
||||
|
||||
## [1.2.1](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.2.0...@standardnotes/workspace-server@1.2.1) (2022-10-10)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **workspace:** rename private key to encrypted private key ([447d600](https://github.com/standardnotes/server/commit/447d600dbe0ee101a7579409adc9da6cd3e309de))
|
||||
|
||||
# [1.2.0](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.1.2...@standardnotes/workspace-server@1.2.0) (2022-10-07)
|
||||
|
||||
### Features
|
||||
|
||||
* add workspaces creation ([156ab65](https://github.com/standardnotes/server/commit/156ab6527265351b13797394cbd34da037ab5a38))
|
||||
|
||||
## [1.1.2](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.1.1...@standardnotes/workspace-server@1.1.2) (2022-10-07)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/workspace-server
|
||||
|
||||
## [1.1.1](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.1.0...@standardnotes/workspace-server@1.1.1) (2022-10-06)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/workspace-server
|
||||
|
||||
@@ -5,6 +5,7 @@ import 'newrelic'
|
||||
import * as Sentry from '@sentry/node'
|
||||
|
||||
import '../src/Infra/InversifyExpressUtils/InversifyExpressHealthCheckController'
|
||||
import '../src/Infra/InversifyExpressUtils/InversifyExpressWorkspacesController'
|
||||
|
||||
import * as cors from 'cors'
|
||||
import { urlencoded, json, Request, Response, NextFunction, RequestHandler, ErrorRequestHandler } from 'express'
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import { MigrationInterface, QueryRunner } from 'typeorm'
|
||||
|
||||
export class renamePrivateKey1665389240189 implements MigrationInterface {
|
||||
name = 'renamePrivateKey1665389240189'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
'ALTER TABLE `workspace_users` CHANGE `private_key` `encrypted_private_key` varchar(255) NOT NULL',
|
||||
)
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
'ALTER TABLE `workspace_users` CHANGE `encrypted_private_key` `private_key` varchar(255) NOT NULL',
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/workspace-server",
|
||||
"version": "1.1.1",
|
||||
"version": "1.2.2",
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.0.0"
|
||||
},
|
||||
@@ -25,6 +25,7 @@
|
||||
"dependencies": {
|
||||
"@newrelic/winston-enricher": "^4.0.0",
|
||||
"@sentry/node": "^7.3.0",
|
||||
"@standardnotes/api": "^1.11.0",
|
||||
"@standardnotes/common": "workspace:*",
|
||||
"@standardnotes/domain-events": "workspace:*",
|
||||
"@standardnotes/domain-events-infra": "workspace:*",
|
||||
|
||||
@@ -21,6 +21,15 @@ import {
|
||||
} from '@standardnotes/domain-events-infra'
|
||||
import { ApiGatewayAuthMiddleware } from '../Controller/ApiGatewayAuthMiddleware'
|
||||
import { CrossServiceTokenData, TokenDecoder, TokenDecoderInterface } from '@standardnotes/security'
|
||||
import { WorkspaceRepositoryInterface } from '../Domain/Workspace/WorkspaceRepositoryInterface'
|
||||
import { MySQLWorkspaceRepository } from '../Infra/MySQL/MySQLWorkspaceRepository'
|
||||
import { WorkspaceUserRepositoryInterface } from '../Domain/Workspace/WorkspaceUserRepositoryInterface'
|
||||
import { MySQLWorkspaceUserRepository } from '../Infra/MySQL/MySQLWorkspaceUserRepository'
|
||||
import { Repository } from 'typeorm'
|
||||
import { Workspace } from '../Domain/Workspace/Workspace'
|
||||
import { WorkspaceUser } from '../Domain/Workspace/WorkspaceUser'
|
||||
import { CreateWorkspace } from '../Domain/UseCase/CreateWorkspace/CreateWorkspace'
|
||||
import { WorkspacesController } from '../Controller/WorkspacesController'
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const newrelicFormatter = require('@newrelic/winston-enricher')
|
||||
@@ -82,8 +91,17 @@ export class ContainerConfigLoader {
|
||||
}
|
||||
|
||||
// Controller
|
||||
container.bind<WorkspacesController>(TYPES.WorkspacesController).to(WorkspacesController)
|
||||
// Repositories
|
||||
container.bind<WorkspaceRepositoryInterface>(TYPES.WorkspaceRepository).to(MySQLWorkspaceRepository)
|
||||
container.bind<WorkspaceUserRepositoryInterface>(TYPES.WorkspaceUserRepository).to(MySQLWorkspaceUserRepository)
|
||||
// ORM
|
||||
container
|
||||
.bind<Repository<Workspace>>(TYPES.ORMWorkspaceRepository)
|
||||
.toConstantValue(AppDataSource.getRepository(Workspace))
|
||||
container
|
||||
.bind<Repository<WorkspaceUser>>(TYPES.ORMWorkspaceUserRepository)
|
||||
.toConstantValue(AppDataSource.getRepository(WorkspaceUser))
|
||||
// Middleware
|
||||
container.bind<ApiGatewayAuthMiddleware>(TYPES.ApiGatewayAuthMiddleware).to(ApiGatewayAuthMiddleware)
|
||||
// env vars
|
||||
@@ -97,6 +115,7 @@ export class ContainerConfigLoader {
|
||||
container.bind(TYPES.VERSION).toConstantValue(env.get('VERSION'))
|
||||
|
||||
// use cases
|
||||
container.bind(TYPES.CreateWorkspace).to(CreateWorkspace)
|
||||
// Handlers
|
||||
// Services
|
||||
container
|
||||
|
||||
@@ -4,8 +4,13 @@ const TYPES = {
|
||||
SNS: Symbol.for('SNS'),
|
||||
SQS: Symbol.for('SQS'),
|
||||
// Controller
|
||||
WorkspacesController: Symbol.for('WorkspacesController'),
|
||||
// Repositories
|
||||
WorkspaceRepository: Symbol.for('WorkspaceRepository'),
|
||||
WorkspaceUserRepository: Symbol.for('WorkspaceUserRepository'),
|
||||
// ORM
|
||||
ORMWorkspaceRepository: Symbol.for('ORMWorkspaceRepository'),
|
||||
ORMWorkspaceUserRepository: Symbol.for('ORMWorkspaceUserRepository'),
|
||||
// Middleware
|
||||
ApiGatewayAuthMiddleware: Symbol.for('ApiGatewayAuthMiddleware'),
|
||||
// env vars
|
||||
@@ -19,6 +24,7 @@ const TYPES = {
|
||||
NEW_RELIC_ENABLED: Symbol.for('NEW_RELIC_ENABLED'),
|
||||
VERSION: Symbol.for('VERSION'),
|
||||
// use cases
|
||||
CreateWorkspace: Symbol.for('CreateWorkspace'),
|
||||
// Handlers
|
||||
// Services
|
||||
CrossServiceTokenDecoder: Symbol.for('CrossServiceTokenDecoder'),
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
import 'reflect-metadata'
|
||||
|
||||
import { CreateWorkspace } from '../Domain/UseCase/CreateWorkspace/CreateWorkspace'
|
||||
|
||||
import { WorkspacesController } from './WorkspacesController'
|
||||
|
||||
describe('WorkspacesController', () => {
|
||||
let doCreateWorkspace: CreateWorkspace
|
||||
|
||||
const createController = () => new WorkspacesController(doCreateWorkspace)
|
||||
|
||||
beforeEach(() => {
|
||||
doCreateWorkspace = {} as jest.Mocked<CreateWorkspace>
|
||||
doCreateWorkspace.execute = jest.fn().mockReturnValue({ workspace: { uuid: 'w-1-2-3' } })
|
||||
})
|
||||
|
||||
it('should create a workspace', async () => {
|
||||
const result = await createController().createWorkspace({
|
||||
encryptedPrivateKey: 'foo',
|
||||
encryptedWorkspaceKey: 'bar',
|
||||
publicKey: 'buzz',
|
||||
workspaceName: 'A Team',
|
||||
ownerUuid: 'u-1-2-3',
|
||||
})
|
||||
|
||||
expect(result).toEqual({
|
||||
data: {
|
||||
uuid: 'w-1-2-3',
|
||||
},
|
||||
status: 200,
|
||||
})
|
||||
})
|
||||
})
|
||||
32
packages/workspace/src/Controller/WorkspacesController.ts
Normal file
32
packages/workspace/src/Controller/WorkspacesController.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import { inject, injectable } from 'inversify'
|
||||
import {
|
||||
HttpStatusCode,
|
||||
WorkspaceCreationRequestParams,
|
||||
WorkspaceCreationResponse,
|
||||
WorkspaceServerInterface,
|
||||
} from '@standardnotes/api'
|
||||
import { WorkspaceType } from '@standardnotes/common'
|
||||
|
||||
import TYPES from '../Bootstrap/Types'
|
||||
import { CreateWorkspace } from '../Domain/UseCase/CreateWorkspace/CreateWorkspace'
|
||||
|
||||
@injectable()
|
||||
export class WorkspacesController implements WorkspaceServerInterface {
|
||||
constructor(@inject(TYPES.CreateWorkspace) private doCreateWorkspace: CreateWorkspace) {}
|
||||
|
||||
async createWorkspace(params: WorkspaceCreationRequestParams): Promise<WorkspaceCreationResponse> {
|
||||
const { workspace } = await this.doCreateWorkspace.execute({
|
||||
encryptedPrivateKey: params.encryptedPrivateKey,
|
||||
encryptedWorkspaceKey: params.encryptedWorkspaceKey,
|
||||
publicKey: params.publicKey,
|
||||
name: params.workspaceName,
|
||||
type: WorkspaceType.Root,
|
||||
ownerUuid: params.ownerUuid as string,
|
||||
})
|
||||
|
||||
return {
|
||||
status: HttpStatusCode.Success,
|
||||
data: { uuid: workspace.uuid },
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
import 'reflect-metadata'
|
||||
|
||||
import { WorkspaceType } from '@standardnotes/common'
|
||||
|
||||
import { WorkspaceRepositoryInterface } from '../../Workspace/WorkspaceRepositoryInterface'
|
||||
import { WorkspaceUserRepositoryInterface } from '../../Workspace/WorkspaceUserRepositoryInterface'
|
||||
|
||||
import { CreateWorkspace } from './CreateWorkspace'
|
||||
|
||||
describe('CreateWorkspace', () => {
|
||||
let workspaceRepository: WorkspaceRepositoryInterface
|
||||
let workspaceUserRepository: WorkspaceUserRepositoryInterface
|
||||
|
||||
const createUseCase = () => new CreateWorkspace(workspaceRepository, workspaceUserRepository)
|
||||
|
||||
beforeEach(() => {
|
||||
workspaceRepository = {} as jest.Mocked<WorkspaceRepositoryInterface>
|
||||
workspaceRepository.save = jest.fn().mockImplementation((workspace) => {
|
||||
return {
|
||||
...workspace,
|
||||
uuid: 'w-1-2-3',
|
||||
}
|
||||
})
|
||||
|
||||
workspaceUserRepository = {} as jest.Mocked<WorkspaceUserRepositoryInterface>
|
||||
workspaceUserRepository.save = jest.fn()
|
||||
})
|
||||
|
||||
it('should create a workspace and owner association with it', async () => {
|
||||
await createUseCase().execute({
|
||||
encryptedPrivateKey: 'foo',
|
||||
encryptedWorkspaceKey: 'bar',
|
||||
publicKey: 'buzz',
|
||||
name: 'A Team',
|
||||
ownerUuid: '1-2-3',
|
||||
type: WorkspaceType.Root,
|
||||
})
|
||||
|
||||
expect(workspaceRepository.save).toHaveBeenCalledWith({
|
||||
name: 'A Team',
|
||||
type: 'root',
|
||||
})
|
||||
expect(workspaceUserRepository.save).toHaveBeenCalledWith({
|
||||
accessLevel: 'owner',
|
||||
encryptedWorkspaceKey: 'bar',
|
||||
encryptedPrivateKey: 'foo',
|
||||
publicKey: 'buzz',
|
||||
status: 'active',
|
||||
userUuid: '1-2-3',
|
||||
workspaceUuid: 'w-1-2-3',
|
||||
})
|
||||
})
|
||||
|
||||
it('should create a workspace without a name and owner association with it', async () => {
|
||||
await createUseCase().execute({
|
||||
encryptedPrivateKey: 'foo',
|
||||
encryptedWorkspaceKey: 'bar',
|
||||
publicKey: 'buzz',
|
||||
ownerUuid: '1-2-3',
|
||||
type: WorkspaceType.Private,
|
||||
})
|
||||
|
||||
expect(workspaceRepository.save).toHaveBeenCalledWith({
|
||||
type: 'private',
|
||||
})
|
||||
expect(workspaceUserRepository.save).toHaveBeenCalledWith({
|
||||
accessLevel: 'owner',
|
||||
encryptedWorkspaceKey: 'bar',
|
||||
encryptedPrivateKey: 'foo',
|
||||
publicKey: 'buzz',
|
||||
status: 'active',
|
||||
userUuid: '1-2-3',
|
||||
workspaceUuid: 'w-1-2-3',
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,44 @@
|
||||
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'
|
||||
import { CreateWorkspaceResponse } from './CreateWorkspaceResponse'
|
||||
|
||||
@injectable()
|
||||
export class CreateWorkspace implements UseCaseInterface {
|
||||
constructor(
|
||||
@inject(TYPES.WorkspaceRepository) private workspaceRepository: WorkspaceRepositoryInterface,
|
||||
@inject(TYPES.WorkspaceUserRepository) private workspaceUserRepository: WorkspaceUserRepositoryInterface,
|
||||
) {}
|
||||
|
||||
async execute(dto: CreateWorkspaceDTO): Promise<CreateWorkspaceResponse> {
|
||||
let workspace = new Workspace()
|
||||
if (dto.name !== undefined) {
|
||||
workspace.name = dto.name
|
||||
}
|
||||
workspace.type = dto.type
|
||||
|
||||
workspace = await this.workspaceRepository.save(workspace)
|
||||
|
||||
const ownerAssociation = new WorkspaceUser()
|
||||
ownerAssociation.accessLevel = WorkspaceAccessLevel.Owner
|
||||
ownerAssociation.encryptedWorkspaceKey = dto.encryptedWorkspaceKey
|
||||
ownerAssociation.encryptedPrivateKey = dto.encryptedPrivateKey
|
||||
ownerAssociation.publicKey = dto.publicKey
|
||||
ownerAssociation.status = WorkspaceUserStatus.Active
|
||||
ownerAssociation.userUuid = dto.ownerUuid
|
||||
ownerAssociation.workspaceUuid = workspace.uuid
|
||||
|
||||
await this.workspaceUserRepository.save(ownerAssociation)
|
||||
|
||||
return { workspace }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import { Uuid, WorkspaceType } from '@standardnotes/common'
|
||||
|
||||
export type CreateWorkspaceDTO = {
|
||||
ownerUuid: Uuid
|
||||
encryptedWorkspaceKey: string
|
||||
encryptedPrivateKey: string
|
||||
publicKey: string
|
||||
type: WorkspaceType
|
||||
name?: string
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import { Workspace } from '../../Workspace/Workspace'
|
||||
|
||||
export type CreateWorkspaceResponse = {
|
||||
workspace: Workspace
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export interface UseCaseInterface {
|
||||
execute(...args: any[]): Promise<Record<string, unknown>>
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import { WorkspaceType } from '@standardnotes/common'
|
||||
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm'
|
||||
import { WorkspaceType } from './WorkspaceType'
|
||||
|
||||
@Entity({ name: 'workspaces' })
|
||||
export class Workspace {
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
import { Workspace } from './Workspace'
|
||||
|
||||
export interface WorkspaceRepositoryInterface {
|
||||
save(workspace: Workspace): Promise<Workspace>
|
||||
}
|
||||
@@ -42,11 +42,11 @@ export class WorkspaceUser {
|
||||
declare publicKey: string
|
||||
|
||||
@Column({
|
||||
name: 'private_key',
|
||||
name: 'encrypted_private_key',
|
||||
length: 255,
|
||||
type: 'varchar',
|
||||
})
|
||||
declare privateKey: string
|
||||
declare encryptedPrivateKey: string
|
||||
|
||||
@Column({
|
||||
name: 'status',
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
import { WorkspaceUser } from './WorkspaceUser'
|
||||
|
||||
export interface WorkspaceUserRepositoryInterface {
|
||||
save(workspace: WorkspaceUser): Promise<WorkspaceUser>
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
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('/workspaces')
|
||||
export class InversifyExpressWorkspacesController extends BaseHttpController {
|
||||
constructor(@inject(TYPES.WorkspacesController) private workspacesController: WorkspacesController) {
|
||||
super()
|
||||
}
|
||||
|
||||
@httpPost('/', TYPES.ApiGatewayAuthMiddleware)
|
||||
async create(request: Request, response: Response): Promise<results.JsonResult> {
|
||||
const result = await this.workspacesController.createWorkspace({
|
||||
...request.body,
|
||||
ownerUuid: response.locals.user.uuid,
|
||||
})
|
||||
|
||||
return this.json(result.data, result.status)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import 'reflect-metadata'
|
||||
|
||||
import { Repository, SelectQueryBuilder } from 'typeorm'
|
||||
|
||||
import { Workspace } from '../../Domain/Workspace/Workspace'
|
||||
|
||||
import { MySQLWorkspaceRepository } from './MySQLWorkspaceRepository'
|
||||
|
||||
describe('MySQLWorkspaceRepository', () => {
|
||||
let ormRepository: Repository<Workspace>
|
||||
let workspace: Workspace
|
||||
let queryBuilder: SelectQueryBuilder<Workspace>
|
||||
|
||||
const createRepository = () => new MySQLWorkspaceRepository(ormRepository)
|
||||
|
||||
beforeEach(() => {
|
||||
workspace = {} as jest.Mocked<Workspace>
|
||||
|
||||
queryBuilder = {} as jest.Mocked<SelectQueryBuilder<Workspace>>
|
||||
|
||||
ormRepository = {} as jest.Mocked<Repository<Workspace>>
|
||||
ormRepository.save = jest.fn()
|
||||
ormRepository.createQueryBuilder = jest.fn().mockImplementation(() => queryBuilder)
|
||||
})
|
||||
|
||||
it('should save', async () => {
|
||||
await createRepository().save(workspace)
|
||||
|
||||
expect(ormRepository.save).toHaveBeenCalledWith(workspace)
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,17 @@
|
||||
import { inject, injectable } from 'inversify'
|
||||
import { Repository } from 'typeorm'
|
||||
import TYPES from '../../Bootstrap/Types'
|
||||
import { Workspace } from '../../Domain/Workspace/Workspace'
|
||||
import { WorkspaceRepositoryInterface } from '../../Domain/Workspace/WorkspaceRepositoryInterface'
|
||||
|
||||
@injectable()
|
||||
export class MySQLWorkspaceRepository implements WorkspaceRepositoryInterface {
|
||||
constructor(
|
||||
@inject(TYPES.ORMWorkspaceRepository)
|
||||
private ormRepository: Repository<Workspace>,
|
||||
) {}
|
||||
|
||||
async save(workspace: Workspace): Promise<Workspace> {
|
||||
return this.ormRepository.save(workspace)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import 'reflect-metadata'
|
||||
|
||||
import { Repository, SelectQueryBuilder } from 'typeorm'
|
||||
|
||||
import { WorkspaceUser } from '../../Domain/Workspace/WorkspaceUser'
|
||||
import { MySQLWorkspaceUserRepository } from './MySQLWorkspaceUserRepository'
|
||||
|
||||
describe('MySQLWorkspaceUserRepository', () => {
|
||||
let ormRepository: Repository<WorkspaceUser>
|
||||
let workspace: WorkspaceUser
|
||||
let queryBuilder: SelectQueryBuilder<WorkspaceUser>
|
||||
|
||||
const createRepository = () => new MySQLWorkspaceUserRepository(ormRepository)
|
||||
|
||||
beforeEach(() => {
|
||||
workspace = {} as jest.Mocked<WorkspaceUser>
|
||||
|
||||
queryBuilder = {} as jest.Mocked<SelectQueryBuilder<WorkspaceUser>>
|
||||
|
||||
ormRepository = {} as jest.Mocked<Repository<WorkspaceUser>>
|
||||
ormRepository.save = jest.fn()
|
||||
ormRepository.createQueryBuilder = jest.fn().mockImplementation(() => queryBuilder)
|
||||
})
|
||||
|
||||
it('should save', async () => {
|
||||
await createRepository().save(workspace)
|
||||
|
||||
expect(ormRepository.save).toHaveBeenCalledWith(workspace)
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,18 @@
|
||||
import { inject, injectable } from 'inversify'
|
||||
import { Repository } from 'typeorm'
|
||||
|
||||
import TYPES from '../../Bootstrap/Types'
|
||||
import { WorkspaceUser } from '../../Domain/Workspace/WorkspaceUser'
|
||||
import { WorkspaceUserRepositoryInterface } from '../../Domain/Workspace/WorkspaceUserRepositoryInterface'
|
||||
|
||||
@injectable()
|
||||
export class MySQLWorkspaceUserRepository implements WorkspaceUserRepositoryInterface {
|
||||
constructor(
|
||||
@inject(TYPES.ORMWorkspaceUserRepository)
|
||||
private ormRepository: Repository<WorkspaceUser>,
|
||||
) {}
|
||||
|
||||
async save(workspaceUser: WorkspaceUser): Promise<WorkspaceUser> {
|
||||
return this.ormRepository.save(workspaceUser)
|
||||
}
|
||||
}
|
||||
77
yarn.lock
77
yarn.lock
@@ -1824,6 +1824,21 @@ __metadata:
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"@standardnotes/api@npm:^1.11.0":
|
||||
version: 1.11.0
|
||||
resolution: "@standardnotes/api@npm:1.11.0"
|
||||
dependencies:
|
||||
"@standardnotes/common": ^1.32.0
|
||||
"@standardnotes/encryption": 1.16.0
|
||||
"@standardnotes/models": 1.24.0
|
||||
"@standardnotes/responses": 1.10.4
|
||||
"@standardnotes/security": ^1.1.0
|
||||
"@standardnotes/utils": 1.9.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"
|
||||
@@ -1986,6 +2001,20 @@ __metadata:
|
||||
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/sncrypto-common": 1.13.0
|
||||
"@standardnotes/utils": 1.9.0
|
||||
reflect-metadata: ^0.1.13
|
||||
checksum: 9971b9afcc8d32c7a6d720b43b7e098659d40212abfe1c4387f6b8aee4f410198a0e28db61bfdfdd8defe8cd336a9823e4cc565bf8f72145da2d349cb4be12a6
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@standardnotes/event-store@workspace:packages/event-store":
|
||||
version: 0.0.0-use.local
|
||||
resolution: "@standardnotes/event-store@workspace:packages/event-store"
|
||||
@@ -2026,6 +2055,18 @@ __metadata:
|
||||
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
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@standardnotes/features@npm:^1.36.3, @standardnotes/features@npm:^1.47.0":
|
||||
version: 1.50.0
|
||||
resolution: "@standardnotes/features@npm:1.50.0"
|
||||
@@ -2101,6 +2142,20 @@ __metadata:
|
||||
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
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@standardnotes/payloads@npm:^1.5.1":
|
||||
version: 1.5.1
|
||||
resolution: "@standardnotes/payloads@npm:1.5.1"
|
||||
@@ -2138,6 +2193,18 @@ __metadata:
|
||||
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
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@standardnotes/responses@npm:^1.6.39":
|
||||
version: 1.6.39
|
||||
resolution: "@standardnotes/responses@npm:1.6.39"
|
||||
@@ -2243,6 +2310,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@standardnotes/sncrypto-common@npm:1.13.0":
|
||||
version: 1.13.0
|
||||
resolution: "@standardnotes/sncrypto-common@npm:1.13.0"
|
||||
dependencies:
|
||||
reflect-metadata: ^0.1.13
|
||||
checksum: e58258f52546a3f0ce2d8f76d4be79a7d23e15dfd81e687ac66cd3fc00dc91e563556da2e600dbd2f270f659b3e1f3e4301dd6e6e7e6eb4faf51c4343fc65c96
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@standardnotes/sncrypto-common@npm:^1.9.0":
|
||||
version: 1.9.0
|
||||
resolution: "@standardnotes/sncrypto-common@npm:1.9.0"
|
||||
@@ -2366,6 +2442,7 @@ __metadata:
|
||||
dependencies:
|
||||
"@newrelic/winston-enricher": ^4.0.0
|
||||
"@sentry/node": ^7.3.0
|
||||
"@standardnotes/api": ^1.11.0
|
||||
"@standardnotes/common": "workspace:*"
|
||||
"@standardnotes/domain-events": "workspace:*"
|
||||
"@standardnotes/domain-events-infra": "workspace:*"
|
||||
|
||||
Reference in New Issue
Block a user