mirror of
https://github.com/standardnotes/server
synced 2026-01-16 20:04:32 -05:00
Compare commits
17 Commits
@standardn
...
@standardn
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4b1fc718a2 | ||
|
|
1708c3f8a0 | ||
|
|
352e02028d | ||
|
|
1bbb639c83 | ||
|
|
c14265f103 | ||
|
|
c030a6b3d8 | ||
|
|
af997ea658 | ||
|
|
efa4d7fc60 | ||
|
|
f714aaa0e9 | ||
|
|
aee6e60583 | ||
|
|
4e602687d5 | ||
|
|
d026152ac8 | ||
|
|
3f21a358d2 | ||
|
|
dc55e47c98 | ||
|
|
3b804e2321 | ||
|
|
b32f851a90 | ||
|
|
479d20e76f |
@@ -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.25.3](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.25.2...@standardnotes/analytics@2.25.3) (2023-07-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.25.2](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.25.1...@standardnotes/analytics@2.25.2) (2023-07-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.25.1](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.25.0...@standardnotes/analytics@2.25.1) (2023-07-19)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
# [2.25.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.24.9...@standardnotes/analytics@2.25.0) (2023-07-17)
|
||||
|
||||
### Features
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/analytics",
|
||||
"version": "2.25.0",
|
||||
"version": "2.25.3",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,32 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.67.2](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.67.1...@standardnotes/api-gateway@1.67.2) (2023-07-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||
|
||||
## [1.67.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.67.0...@standardnotes/api-gateway@1.67.1) (2023-07-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||
|
||||
# [1.67.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.66.1...@standardnotes/api-gateway@1.67.0) (2023-07-20)
|
||||
|
||||
### Features
|
||||
|
||||
* **syncing-server:** add shared vaults, invites, messages and notifications to sync response ([#665](https://github.com/standardnotes/api-gateway/issues/665)) ([efa4d7f](https://github.com/standardnotes/api-gateway/commit/efa4d7fc6007ef668e3de3b04853ac11b2d13c30))
|
||||
|
||||
## [1.66.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.66.0...@standardnotes/api-gateway@1.66.1) (2023-07-19)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* add missing imports and exports for controllers ([#664](https://github.com/standardnotes/api-gateway/issues/664)) ([aee6e60](https://github.com/standardnotes/api-gateway/commit/aee6e6058359e2b5231cc13387656f837699300f))
|
||||
|
||||
# [1.66.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.65.7...@standardnotes/api-gateway@1.66.0) (2023-07-19)
|
||||
|
||||
### Features
|
||||
|
||||
* **syncing-server:** add persistence of shared vaults with users and invites + controllers ([#662](https://github.com/standardnotes/api-gateway/issues/662)) ([3f21a35](https://github.com/standardnotes/api-gateway/commit/3f21a358d24d70daf541aa62dc86cd9e29500e62))
|
||||
|
||||
## [1.65.7](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.65.6...@standardnotes/api-gateway@1.65.7) (2023-07-17)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||
|
||||
@@ -16,8 +16,10 @@ import '../src/Controller/v1/OfflineController'
|
||||
import '../src/Controller/v1/FilesController'
|
||||
import '../src/Controller/v1/SubscriptionInvitesController'
|
||||
import '../src/Controller/v1/AuthenticatorsController'
|
||||
import '../src/Controller/v1/AsymmetricMessagesController'
|
||||
import '../src/Controller/v1/MessagesController'
|
||||
import '../src/Controller/v1/SharedVaultsController'
|
||||
import '../src/Controller/v1/SharedVaultInvitesController'
|
||||
import '../src/Controller/v1/SharedVaultUsersController'
|
||||
|
||||
import '../src/Controller/v2/PaymentsControllerV2'
|
||||
import '../src/Controller/v2/ActionsControllerV2'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/api-gateway",
|
||||
"version": "1.65.7",
|
||||
"version": "1.67.2",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
|
||||
@@ -4,7 +4,7 @@ export * from './SubscriptionTokenAuthMiddleware'
|
||||
export * from './TokenAuthenticationMethod'
|
||||
export * from './WebSocketAuthMiddleware'
|
||||
export * from './v1/ActionsController'
|
||||
export * from './v1/AsymmetricMessagesController'
|
||||
export * from './v1/MessagesController'
|
||||
export * from './v1/AuthenticatorsController'
|
||||
export * from './v1/FilesController'
|
||||
export * from './v1/InvoicesController'
|
||||
@@ -13,6 +13,8 @@ export * from './v1/OfflineController'
|
||||
export * from './v1/PaymentsController'
|
||||
export * from './v1/RevisionsController'
|
||||
export * from './v1/SessionsController'
|
||||
export * from './v1/SharedVaultInvitesController'
|
||||
export * from './v1/SharedVaultUsersController'
|
||||
export * from './v1/SharedVaultsController'
|
||||
export * from './v1/SubscriptionInvitesController'
|
||||
export * from './v1/TokensController'
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
import { Request, Response } from 'express'
|
||||
import { inject } from 'inversify'
|
||||
import { BaseHttpController, controller, all } from 'inversify-express-utils'
|
||||
import { TYPES } from '../../Bootstrap/Types'
|
||||
import { ServiceProxyInterface } from '../../Service/Http/ServiceProxyInterface'
|
||||
|
||||
@controller('/v1/asymmetric-messages')
|
||||
export class AsymmetricMessagesController extends BaseHttpController {
|
||||
constructor(@inject(TYPES.ServiceProxy) private serviceProxy: ServiceProxyInterface) {
|
||||
super()
|
||||
}
|
||||
|
||||
@all('*', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async subscriptions(request: Request, response: Response): Promise<void> {
|
||||
await this.serviceProxy.callSyncingServer(request, response, request.path.replace('/v1/', ''), request.body)
|
||||
}
|
||||
}
|
||||
70
packages/api-gateway/src/Controller/v1/MessagesController.ts
Normal file
70
packages/api-gateway/src/Controller/v1/MessagesController.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
import { Request, Response } from 'express'
|
||||
import { inject } from 'inversify'
|
||||
import { BaseHttpController, controller, httpDelete, httpGet, httpPost } from 'inversify-express-utils'
|
||||
import { TYPES } from '../../Bootstrap/Types'
|
||||
import { ServiceProxyInterface } from '../../Service/Http/ServiceProxyInterface'
|
||||
import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolverInterface'
|
||||
|
||||
@controller('/v1/messages', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
export class MessagesController extends BaseHttpController {
|
||||
constructor(
|
||||
@inject(TYPES.ServiceProxy) private httpService: ServiceProxyInterface,
|
||||
@inject(TYPES.EndpointResolver) private endpointResolver: EndpointResolverInterface,
|
||||
) {
|
||||
super()
|
||||
}
|
||||
|
||||
@httpGet('/')
|
||||
async getMessages(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callSyncingServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier('GET', 'messages/'),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
|
||||
@httpGet('/outbound')
|
||||
async getMessagesSent(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callSyncingServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier('GET', 'messages/outbound'),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
|
||||
@httpPost('/')
|
||||
async sendMessage(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callSyncingServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier('POST', 'messages/'),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
|
||||
@httpDelete('/inbound')
|
||||
async deleteMessagesSentToUser(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callSyncingServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier('DELETE', 'messages/inbound'),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
|
||||
@httpDelete('/:messageUuid')
|
||||
async deleteMessage(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callSyncingServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier(
|
||||
'DELETE',
|
||||
'messages/:messageUuid',
|
||||
request.params.messageUuid,
|
||||
),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
import { Request, Response } from 'express'
|
||||
import { inject } from 'inversify'
|
||||
import { BaseHttpController, controller, httpDelete, httpGet, httpPatch, httpPost } from 'inversify-express-utils'
|
||||
import { TYPES } from '../../Bootstrap/Types'
|
||||
import { ServiceProxyInterface } from '../../Service/Http/ServiceProxyInterface'
|
||||
import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolverInterface'
|
||||
|
||||
@controller('/v1/shared-vaults', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
export class SharedVaultInvitesController extends BaseHttpController {
|
||||
constructor(
|
||||
@inject(TYPES.ServiceProxy) private httpService: ServiceProxyInterface,
|
||||
@inject(TYPES.EndpointResolver) private endpointResolver: EndpointResolverInterface,
|
||||
) {
|
||||
super()
|
||||
}
|
||||
|
||||
@httpPost('/:sharedVaultUuid/invites')
|
||||
async createSharedVaultInvite(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callSyncingServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier(
|
||||
'POST',
|
||||
'shared-vaults/:sharedVaultUuid/invites',
|
||||
request.params.sharedVaultUuid,
|
||||
),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
|
||||
@httpPatch('/:sharedVaultUuid/invites/:inviteUuid')
|
||||
async updateSharedVaultInvite(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callSyncingServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier(
|
||||
'PATCH',
|
||||
'shared-vaults/:sharedVaultUuid/invites/:inviteUuid',
|
||||
request.params.sharedVaultUuid,
|
||||
request.params.inviteUuid,
|
||||
),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
|
||||
@httpPost('/:sharedVaultUuid/invites/:inviteUuid/accept')
|
||||
async acceptSharedVaultInvite(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callSyncingServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier(
|
||||
'POST',
|
||||
'shared-vaults/:sharedVaultUuid/invites/:inviteUuid/accept',
|
||||
request.params.sharedVaultUuid,
|
||||
request.params.inviteUuid,
|
||||
),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
|
||||
@httpPost('/:sharedVaultUuid/invites/:inviteUuid/decline')
|
||||
async declineSharedVaultInvite(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callSyncingServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier(
|
||||
'POST',
|
||||
'shared-vaults/:sharedVaultUuid/invites/:inviteUuid/decline',
|
||||
request.params.sharedVaultUuid,
|
||||
request.params.inviteUuid,
|
||||
),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
|
||||
@httpDelete('/invites/inbound')
|
||||
async deleteInboundUserInvites(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callSyncingServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier('DELETE', 'shared-vaults/invites/inbound'),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
|
||||
@httpGet('/invites/outbound')
|
||||
async getOutboundUserInvites(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callSyncingServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier('GET', 'shared-vaults/invites/outbound'),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
|
||||
@httpGet('/invites')
|
||||
async getUserInvites(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callSyncingServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier('GET', 'shared-vaults/invites'),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
|
||||
@httpGet('/:sharedVaultUuid/invites')
|
||||
async getSharedVaultInvites(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callSyncingServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier(
|
||||
'GET',
|
||||
'shared-vaults/:sharedVaultUuid/invites',
|
||||
request.params.sharedVaultUuid,
|
||||
),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
|
||||
@httpDelete('/:sharedVaultUuid/invites/:inviteUuid')
|
||||
async deleteSharedVaultInvite(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callSyncingServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier(
|
||||
'DELETE',
|
||||
'shared-vaults/:sharedVaultUuid/invites/:inviteUuid',
|
||||
request.params.sharedVaultUuid,
|
||||
request.params.inviteUuid,
|
||||
),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
|
||||
@httpDelete('/:sharedVaultUuid/invites')
|
||||
async deleteAllSharedVaultInvites(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callSyncingServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier(
|
||||
'DELETE',
|
||||
'shared-vaults/:sharedVaultUuid/invites',
|
||||
request.params.sharedVaultUuid,
|
||||
),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
import { Request, Response } from 'express'
|
||||
import { inject } from 'inversify'
|
||||
import { BaseHttpController, controller, httpDelete, httpGet } from 'inversify-express-utils'
|
||||
import { TYPES } from '../../Bootstrap/Types'
|
||||
import { ServiceProxyInterface } from '../../Service/Http/ServiceProxyInterface'
|
||||
import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolverInterface'
|
||||
|
||||
@controller('/v1/shared-vaults/:sharedVaultUuid/users', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
export class SharedVaultUsersController extends BaseHttpController {
|
||||
constructor(
|
||||
@inject(TYPES.ServiceProxy) private httpService: ServiceProxyInterface,
|
||||
@inject(TYPES.EndpointResolver) private endpointResolver: EndpointResolverInterface,
|
||||
) {
|
||||
super()
|
||||
}
|
||||
|
||||
@httpGet('/')
|
||||
async getSharedVaultUsers(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callSyncingServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier(
|
||||
'GET',
|
||||
'shared-vaults/:sharedVaultUuid/users',
|
||||
request.params.sharedVaultUuid,
|
||||
),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
|
||||
@httpDelete('/:userUuid')
|
||||
async removeUserFromSharedVault(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callSyncingServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier(
|
||||
'DELETE',
|
||||
'shared-vaults/:sharedVaultUuid/users/:userUuid',
|
||||
request.params.sharedVaultUuid,
|
||||
request.params.userUuid,
|
||||
),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,64 @@
|
||||
import { Request, Response } from 'express'
|
||||
import { inject } from 'inversify'
|
||||
import { BaseHttpController, controller, all } from 'inversify-express-utils'
|
||||
import { BaseHttpController, controller, httpDelete, httpGet, httpPost } from 'inversify-express-utils'
|
||||
import { TYPES } from '../../Bootstrap/Types'
|
||||
import { ServiceProxyInterface } from '../../Service/Http/ServiceProxyInterface'
|
||||
import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolverInterface'
|
||||
|
||||
@controller('/v1/shared-vaults')
|
||||
@controller('/v1/shared-vaults', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
export class SharedVaultsController extends BaseHttpController {
|
||||
constructor(@inject(TYPES.ServiceProxy) private serviceProxy: ServiceProxyInterface) {
|
||||
constructor(
|
||||
@inject(TYPES.ServiceProxy) private httpService: ServiceProxyInterface,
|
||||
@inject(TYPES.EndpointResolver) private endpointResolver: EndpointResolverInterface,
|
||||
) {
|
||||
super()
|
||||
}
|
||||
|
||||
@all('*', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async subscriptions(request: Request, response: Response): Promise<void> {
|
||||
await this.serviceProxy.callSyncingServer(request, response, request.path.replace('/v1/', ''), request.body)
|
||||
@httpGet('/')
|
||||
async getSharedVaults(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callSyncingServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier('GET', 'shared-vaults/'),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
|
||||
@httpPost('/')
|
||||
async createSharedVault(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callSyncingServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier('POST', 'shared-vaults/'),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
|
||||
@httpDelete('/:sharedVaultUuid')
|
||||
async deleteSharedVault(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callSyncingServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier(
|
||||
'DELETE',
|
||||
'shared-vaults/:sharedVaultUuid',
|
||||
request.params.sharedVaultUuid,
|
||||
),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
|
||||
@httpPost('/:sharedVaultUuid/valet-tokens')
|
||||
async createValetTokenForSharedVaultFile(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callSyncingServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier(
|
||||
'POST',
|
||||
'shared-vaults/:sharedVaultUuid/valet-tokens',
|
||||
request.params.sharedVaultUuid,
|
||||
),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,6 +62,31 @@ export class EndpointResolver implements EndpointResolverInterface {
|
||||
['[GET]:items/:itemUuid/revisions', 'revisions.revisions.getRevisions'],
|
||||
['[GET]:items/:itemUuid/revisions/:id', 'revisions.revisions.getRevision'],
|
||||
['[DELETE]:items/:itemUuid/revisions/:id', 'revisions.revisions.deleteRevision'],
|
||||
// Messages Controller
|
||||
['[GET]:messages/', 'sync.messages.get-received'],
|
||||
['[GET]:messages/outbound', 'sync.messages.get-sent'],
|
||||
['[POST]:messages/', 'sync.messages.send'],
|
||||
['[DELETE]:messages/inbound', 'sync.messages.delete-all'],
|
||||
['[DELETE]:messages/:messageUuid', 'sync.messages.delete'],
|
||||
// Shared Vaults Controller
|
||||
['[GET]:shared-vaults/', 'sync.shared-vaults.get-vaults'],
|
||||
['[POST]:shared-vaults/', 'sync.shared-vaults.create-vault'],
|
||||
['[DELETE]:shared-vaults/:sharedVaultUuid', 'sync.shared-vaults.delete-vault'],
|
||||
['[POST]:shared-vaults/:sharedVaultUuid/valet-tokens', 'sync.shared-vaults.create-file-valet-token'],
|
||||
// Shared Vault Invites Controller
|
||||
['[POST]:shared-vaults/:sharedVaultUuid/invites', 'sync.shared-vault-invites.create'],
|
||||
['[PATCH]:shared-vaults/:sharedVaultUuid/invites/:inviteUuid', 'sync.shared-vault-invites.update'],
|
||||
['[POST]:shared-vaults/:sharedVaultUuid/invites/:inviteUuid/accept', 'sync.shared-vault-invites.accept'],
|
||||
['[POST]:shared-vaults/:sharedVaultUuid/invites/:inviteUuid/decline', 'sync.shared-vault-invites.decline'],
|
||||
['[DELETE]:shared-vaults/invites/inbound', 'sync.shared-vault-invites.delete-inbound'],
|
||||
['[GET]:shared-vaults/invites/outbound', 'sync.shared-vault-invites.get-outbound'],
|
||||
['[GET]:shared-vaults/invites', 'sync.shared-vault-invites.get-user-invites'],
|
||||
['[GET]:shared-vaults/:sharedVaultUuid/invites', 'sync.shared-vault-invites.get-vault-invites'],
|
||||
['[DELETE]:shared-vaults/:sharedVaultUuid/invites/:inviteUuid', 'sync.shared-vault-invites.delete-invite'],
|
||||
['[DELETE]:shared-vaults/:sharedVaultUuid/invites', 'sync.shared-vault-invites.delete-all'],
|
||||
// Shared Vault Users Controller
|
||||
['[GET]:shared-vaults/:sharedVaultUuid/users', 'sync.shared-vault-users.get-users'],
|
||||
['[DELETE]:shared-vaults/:sharedVaultUuid/users/:userUuid', 'sync.shared-vault-users.remove-user'],
|
||||
])
|
||||
|
||||
resolveEndpointOrMethodIdentifier(method: string, endpoint: string, ...params: string[]): string {
|
||||
@@ -75,7 +100,7 @@ export class EndpointResolver implements EndpointResolverInterface {
|
||||
const identifier = this.endpointToIdentifierMap.get(`[${method}]:${endpoint}`)
|
||||
|
||||
if (!identifier) {
|
||||
throw new Error(`Endpoint ${endpoint} not found`)
|
||||
throw new Error(`Endpoint [${method}]:${endpoint} not found`)
|
||||
}
|
||||
|
||||
return identifier
|
||||
|
||||
@@ -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.126.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.126.1...@standardnotes/auth-server@1.126.2) (2023-07-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/auth-server
|
||||
|
||||
## [1.126.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.126.0...@standardnotes/auth-server@1.126.1) (2023-07-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/auth-server
|
||||
|
||||
# [1.126.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.125.1...@standardnotes/auth-server@1.126.0) (2023-07-20)
|
||||
|
||||
### Features
|
||||
|
||||
* **syncing-server:** add shared vaults, invites, messages and notifications to sync response ([#665](https://github.com/standardnotes/server/issues/665)) ([efa4d7f](https://github.com/standardnotes/server/commit/efa4d7fc6007ef668e3de3b04853ac11b2d13c30))
|
||||
|
||||
## [1.125.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.125.0...@standardnotes/auth-server@1.125.1) (2023-07-19)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/auth-server
|
||||
|
||||
# [1.125.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.124.2...@standardnotes/auth-server@1.125.0) (2023-07-17)
|
||||
|
||||
### Features
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
import { MigrationInterface, QueryRunner } from 'typeorm'
|
||||
|
||||
export class AddNotifications1688540448427 implements MigrationInterface {
|
||||
name = 'AddNotifications1688540448427'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
'CREATE TABLE `notifications` (`uuid` varchar(36) NOT NULL, `user_uuid` varchar(36) NOT NULL, `type` varchar(36) NOT NULL, `payload` text NOT NULL, `created_at_timestamp` bigint NOT NULL, `updated_at_timestamp` bigint NOT NULL, INDEX `index_notifications_on_user_uuid` (`user_uuid`), PRIMARY KEY (`uuid`)) ENGINE=InnoDB',
|
||||
)
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query('DROP INDEX `index_notifications_on_user_uuid` ON `notifications`')
|
||||
await queryRunner.query('DROP TABLE `notifications`')
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
import { MigrationInterface, QueryRunner } from 'typeorm'
|
||||
|
||||
export class RemoveNotifications1688540448428 implements MigrationInterface {
|
||||
name = 'RemoveNotifications1688540448428'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query('DROP INDEX `index_notifications_on_user_uuid` ON `notifications`')
|
||||
await queryRunner.query('DROP TABLE `notifications`')
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
'CREATE TABLE `notifications` (`uuid` varchar(36) NOT NULL, `user_uuid` varchar(36) NOT NULL, `type` varchar(36) NOT NULL, `payload` text NOT NULL, `created_at_timestamp` bigint NOT NULL, `updated_at_timestamp` bigint NOT NULL, INDEX `index_notifications_on_user_uuid` (`user_uuid`), PRIMARY KEY (`uuid`)) ENGINE=InnoDB',
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
import { MigrationInterface, QueryRunner } from 'typeorm'
|
||||
|
||||
export class AddNotifications1688540623272 implements MigrationInterface {
|
||||
name = 'AddNotifications1688540623272'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
'CREATE TABLE "notifications" ("uuid" varchar PRIMARY KEY NOT NULL, "user_uuid" varchar(36) NOT NULL, "type" varchar(36) NOT NULL, "payload" text NOT NULL, "created_at_timestamp" bigint NOT NULL, "updated_at_timestamp" bigint NOT NULL)',
|
||||
)
|
||||
await queryRunner.query('CREATE INDEX "index_notifications_on_user_uuid" ON "notifications" ("user_uuid") ')
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query('DROP INDEX "index_notifications_on_user_uuid"')
|
||||
await queryRunner.query('DROP TABLE "notifications"')
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
import { MigrationInterface, QueryRunner } from 'typeorm'
|
||||
|
||||
export class RemoveNotifications1688540623273 implements MigrationInterface {
|
||||
name = 'RemoveNotifications1688540623273'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query('DROP INDEX "index_notifications_on_user_uuid"')
|
||||
await queryRunner.query('DROP TABLE "notifications"')
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
'CREATE TABLE "notifications" ("uuid" varchar PRIMARY KEY NOT NULL, "user_uuid" varchar(36) NOT NULL, "type" varchar(36) NOT NULL, "payload" text NOT NULL, "created_at_timestamp" bigint NOT NULL, "updated_at_timestamp" bigint NOT NULL)',
|
||||
)
|
||||
await queryRunner.query('CREATE INDEX "index_notifications_on_user_uuid" ON "notifications" ("user_uuid") ')
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/auth-server",
|
||||
"version": "1.125.0",
|
||||
"version": "1.126.2",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
|
||||
@@ -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.23.3](https://github.com/standardnotes/server/compare/@standardnotes/domain-core@1.23.2...@standardnotes/domain-core@1.23.3) (2023-07-21)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **domain-core:** notification payload creation from string ([1708c3f](https://github.com/standardnotes/server/commit/1708c3f8a00897369585e1ef8022950a7c3c610e))
|
||||
|
||||
## [1.23.2](https://github.com/standardnotes/server/compare/@standardnotes/domain-core@1.23.1...@standardnotes/domain-core@1.23.2) (2023-07-21)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* user notifications structure ([#667](https://github.com/standardnotes/server/issues/667)) ([1bbb639](https://github.com/standardnotes/server/commit/1bbb639c83922ec09e3778f85419d76669d36ae3))
|
||||
|
||||
## [1.23.1](https://github.com/standardnotes/server/compare/@standardnotes/domain-core@1.23.0...@standardnotes/domain-core@1.23.1) (2023-07-19)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **syncing-server:** add missing messages and key system identifier sql representations ([#663](https://github.com/standardnotes/server/issues/663)) ([d026152](https://github.com/standardnotes/server/commit/d026152ac8cb2ecda2eee8d3f7385d655b210938))
|
||||
|
||||
# [1.23.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-core@1.22.0...@standardnotes/domain-core@1.23.0) (2023-07-17)
|
||||
|
||||
### Features
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/domain-core",
|
||||
"version": "1.23.0",
|
||||
"version": "1.23.3",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
|
||||
@@ -78,4 +78,18 @@ describe('Validator', () => {
|
||||
expect(Validator.isNotEmpty(value).isFailed()).toBeTruthy()
|
||||
}
|
||||
})
|
||||
|
||||
describe('is not empty string', () => {
|
||||
it('should not validate invalid string', () => {
|
||||
expect(Validator.isNotEmptyString(123 as unknown as string).isFailed()).toBeTruthy()
|
||||
})
|
||||
|
||||
it('should not validate an empty string', () => {
|
||||
expect(Validator.isNotEmptyString('').isFailed()).toBeTruthy()
|
||||
})
|
||||
|
||||
it('should validate a string', () => {
|
||||
expect(Validator.isNotEmptyString('foo').isFailed()).toBeFalsy()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -42,4 +42,18 @@ export class Validator {
|
||||
|
||||
return Result.ok()
|
||||
}
|
||||
|
||||
static isNotEmptyString(value: unknown): Result<string> {
|
||||
const isStringResult = Validator.isString(value)
|
||||
if (isStringResult.isFailed()) {
|
||||
return isStringResult
|
||||
}
|
||||
|
||||
const isNotEmptyResult = Validator.isNotEmpty(value)
|
||||
if (isNotEmptyResult.isFailed()) {
|
||||
return isNotEmptyResult
|
||||
}
|
||||
|
||||
return Result.ok()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
import { ValueObject } from '../Core/ValueObject'
|
||||
import { Result } from '../Core/Result'
|
||||
|
||||
import { NotificationPayloadProps } from './NotificationPayloadProps'
|
||||
import { NotificationType } from './NotificationType'
|
||||
import { Uuid } from '../Common/Uuid'
|
||||
|
||||
export class NotificationPayload extends ValueObject<NotificationPayloadProps> {
|
||||
private constructor(props: NotificationPayloadProps) {
|
||||
super(props)
|
||||
}
|
||||
|
||||
override toString(): string {
|
||||
return JSON.stringify({
|
||||
version: this.props.version,
|
||||
type: this.props.type.value,
|
||||
sharedVaultUuid: this.props.sharedVaultUuid.value,
|
||||
itemUuid: this.props.itemUuid ? this.props.itemUuid.value : undefined,
|
||||
})
|
||||
}
|
||||
|
||||
static createFromString(jsonPayload: string): Result<NotificationPayload> {
|
||||
try {
|
||||
const props = JSON.parse(jsonPayload)
|
||||
|
||||
const typeOrError = NotificationType.create(props.type)
|
||||
if (typeOrError.isFailed()) {
|
||||
return Result.fail<NotificationPayload>(typeOrError.getError())
|
||||
}
|
||||
const type = typeOrError.getValue()
|
||||
|
||||
const sharedVaultUuidOrError = Uuid.create(props.sharedVaultUuid)
|
||||
if (sharedVaultUuidOrError.isFailed()) {
|
||||
return Result.fail<NotificationPayload>(sharedVaultUuidOrError.getError())
|
||||
}
|
||||
const sharedVaultUuid = sharedVaultUuidOrError.getValue()
|
||||
|
||||
let itemUuid: Uuid | undefined = undefined
|
||||
if (props.itemUuid) {
|
||||
const itemUuidOrError = Uuid.create(props.itemUuid)
|
||||
if (itemUuidOrError.isFailed()) {
|
||||
return Result.fail<NotificationPayload>(itemUuidOrError.getError())
|
||||
}
|
||||
itemUuid = itemUuidOrError.getValue()
|
||||
}
|
||||
|
||||
return NotificationPayload.create({
|
||||
version: props.version,
|
||||
type,
|
||||
sharedVaultUuid,
|
||||
itemUuid,
|
||||
})
|
||||
} catch (error) {
|
||||
return Result.fail<NotificationPayload>((error as Error).message)
|
||||
}
|
||||
}
|
||||
|
||||
static create(props: NotificationPayloadProps): Result<NotificationPayload> {
|
||||
if (
|
||||
props.itemUuid === undefined &&
|
||||
props.type.equals(NotificationType.create(NotificationType.TYPES.SharedVaultItemRemoved).getValue())
|
||||
) {
|
||||
return Result.fail<NotificationPayload>(
|
||||
`Item uuid is required for ${NotificationType.TYPES.SharedVaultItemRemoved} notification type`,
|
||||
)
|
||||
}
|
||||
|
||||
return Result.ok<NotificationPayload>(new NotificationPayload(props))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import { Uuid } from '../Common/Uuid'
|
||||
import { NotificationType } from './NotificationType'
|
||||
|
||||
export interface NotificationPayloadProps {
|
||||
type: NotificationType
|
||||
sharedVaultUuid: Uuid
|
||||
version: string
|
||||
itemUuid?: Uuid
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import { ValueObject, Result } from '@standardnotes/domain-core'
|
||||
|
||||
import { Result } from '../Core/Result'
|
||||
import { ValueObject } from '../Core/ValueObject'
|
||||
import { NotificationTypeProps } from './NotificationTypeProps'
|
||||
|
||||
export class NotificationType extends ValueObject<NotificationTypeProps> {
|
||||
@@ -17,9 +17,9 @@ export class NotificationType extends ValueObject<NotificationTypeProps> {
|
||||
}
|
||||
|
||||
static create(notificationType: string): Result<NotificationType> {
|
||||
const isValidPermission = Object.values(this.TYPES).includes(notificationType)
|
||||
if (!isValidPermission) {
|
||||
return Result.fail<NotificationType>(`Invalid shared vault user permission ${notificationType}`)
|
||||
const isValidType = Object.values(this.TYPES).includes(notificationType)
|
||||
if (!isValidType) {
|
||||
return Result.fail<NotificationType>(`Invalid notification type: ${notificationType}`)
|
||||
} else {
|
||||
return Result.ok<NotificationType>(new NotificationType({ value: notificationType }))
|
||||
}
|
||||
@@ -45,6 +45,11 @@ export * from './Env/AbstractEnv'
|
||||
|
||||
export * from './Mapping/MapperInterface'
|
||||
|
||||
export * from './Notification/NotificationPayload'
|
||||
export * from './Notification/NotificationPayloadProps'
|
||||
export * from './Notification/NotificationType'
|
||||
export * from './Notification/NotificationTypeProps'
|
||||
|
||||
export * from './Service/ServiceConfiguration'
|
||||
export * from './Service/ServiceContainer'
|
||||
export * from './Service/ServiceContainerInterface'
|
||||
|
||||
@@ -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.11.10](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.11.9...@standardnotes/event-store@1.11.10) (2023-07-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/event-store
|
||||
|
||||
## [1.11.9](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.11.8...@standardnotes/event-store@1.11.9) (2023-07-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/event-store
|
||||
|
||||
## [1.11.8](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.11.7...@standardnotes/event-store@1.11.8) (2023-07-19)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/event-store
|
||||
|
||||
## [1.11.7](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.11.6...@standardnotes/event-store@1.11.7) (2023-07-17)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/event-store
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/event-store",
|
||||
"version": "1.11.7",
|
||||
"version": "1.11.10",
|
||||
"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.19.12](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.19.11...@standardnotes/files-server@1.19.12) (2023-07-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/files-server
|
||||
|
||||
## [1.19.11](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.19.10...@standardnotes/files-server@1.19.11) (2023-07-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/files-server
|
||||
|
||||
## [1.19.10](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.19.9...@standardnotes/files-server@1.19.10) (2023-07-19)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/files-server
|
||||
|
||||
## [1.19.9](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.19.8...@standardnotes/files-server@1.19.9) (2023-07-17)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/files-server
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/files-server",
|
||||
"version": "1.19.9",
|
||||
"version": "1.19.12",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,40 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.13.5](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.13.4...@standardnotes/home-server@1.13.5) (2023-07-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/home-server
|
||||
|
||||
## [1.13.4](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.13.3...@standardnotes/home-server@1.13.4) (2023-07-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/home-server
|
||||
|
||||
## [1.13.3](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.13.2...@standardnotes/home-server@1.13.3) (2023-07-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/home-server
|
||||
|
||||
## [1.13.2](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.13.1...@standardnotes/home-server@1.13.2) (2023-07-20)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/home-server
|
||||
|
||||
## [1.13.1](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.13.0...@standardnotes/home-server@1.13.1) (2023-07-19)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/home-server
|
||||
|
||||
# [1.13.0](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.12.6...@standardnotes/home-server@1.13.0) (2023-07-19)
|
||||
|
||||
### Features
|
||||
|
||||
* **syncing-server:** add persistence of shared vaults with users and invites + controllers ([#662](https://github.com/standardnotes/server/issues/662)) ([3f21a35](https://github.com/standardnotes/server/commit/3f21a358d24d70daf541aa62dc86cd9e29500e62))
|
||||
|
||||
## [1.12.6](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.12.5...@standardnotes/home-server@1.12.6) (2023-07-18)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/home-server
|
||||
|
||||
## [1.12.5](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.12.4...@standardnotes/home-server@1.12.5) (2023-07-18)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/home-server
|
||||
|
||||
## [1.12.4](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.12.3...@standardnotes/home-server@1.12.4) (2023-07-17)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/home-server
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/home-server",
|
||||
"version": "1.12.4",
|
||||
"version": "1.13.5",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
|
||||
@@ -179,6 +179,8 @@ export class HomeServer implements HomeServerInterface {
|
||||
|
||||
return Result.ok('Server started.')
|
||||
} catch (error) {
|
||||
console.error((error as Error).stack)
|
||||
|
||||
return Result.fail((error as Error).message)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.25.3](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.25.2...@standardnotes/revisions-server@1.25.3) (2023-07-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/revisions-server
|
||||
|
||||
## [1.25.2](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.25.1...@standardnotes/revisions-server@1.25.2) (2023-07-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/revisions-server
|
||||
|
||||
## [1.25.1](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.25.0...@standardnotes/revisions-server@1.25.1) (2023-07-19)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/revisions-server
|
||||
|
||||
# [1.25.0](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.24.1...@standardnotes/revisions-server@1.25.0) (2023-07-17)
|
||||
|
||||
### Features
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/revisions-server",
|
||||
"version": "1.25.0",
|
||||
"version": "1.25.3",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.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.20.12](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.20.11...@standardnotes/scheduler-server@1.20.12) (2023-07-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/scheduler-server
|
||||
|
||||
## [1.20.11](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.20.10...@standardnotes/scheduler-server@1.20.11) (2023-07-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/scheduler-server
|
||||
|
||||
## [1.20.10](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.20.9...@standardnotes/scheduler-server@1.20.10) (2023-07-19)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/scheduler-server
|
||||
|
||||
## [1.20.9](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.20.8...@standardnotes/scheduler-server@1.20.9) (2023-07-17)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/scheduler-server
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/scheduler-server",
|
||||
"version": "1.20.9",
|
||||
"version": "1.20.12",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.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.21.17](https://github.com/standardnotes/server/compare/@standardnotes/settings@1.21.16...@standardnotes/settings@1.21.17) (2023-07-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/settings
|
||||
|
||||
## [1.21.16](https://github.com/standardnotes/server/compare/@standardnotes/settings@1.21.15...@standardnotes/settings@1.21.16) (2023-07-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/settings
|
||||
|
||||
## [1.21.15](https://github.com/standardnotes/server/compare/@standardnotes/settings@1.21.14...@standardnotes/settings@1.21.15) (2023-07-19)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/settings
|
||||
|
||||
## [1.21.14](https://github.com/standardnotes/server/compare/@standardnotes/settings@1.21.13...@standardnotes/settings@1.21.14) (2023-07-17)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/settings
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/settings",
|
||||
"version": "1.21.14",
|
||||
"version": "1.21.17",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
|
||||
@@ -49,3 +49,6 @@ NEW_RELIC_LOG_LEVEL=info
|
||||
|
||||
# (Optional) Revision Dumps
|
||||
FILE_UPLOAD_PATH=
|
||||
|
||||
VALET_TOKEN_SECRET=change-me-!
|
||||
VALET_TOKEN_TTL=7200
|
||||
|
||||
@@ -3,6 +3,56 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.68.3](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.68.2...@standardnotes/syncing-server@1.68.3) (2023-07-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/syncing-server
|
||||
|
||||
## [1.68.2](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.68.1...@standardnotes/syncing-server@1.68.2) (2023-07-21)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* user notifications structure ([#667](https://github.com/standardnotes/syncing-server-js/issues/667)) ([1bbb639](https://github.com/standardnotes/syncing-server-js/commit/1bbb639c83922ec09e3778f85419d76669d36ae3))
|
||||
|
||||
## [1.68.1](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.68.0...@standardnotes/syncing-server@1.68.1) (2023-07-21)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **syncing-server:** fetching items associated with shared vaults ([#666](https://github.com/standardnotes/syncing-server-js/issues/666)) ([c030a6b](https://github.com/standardnotes/syncing-server-js/commit/c030a6b3d838b1f09593905d28ace65097a3a940))
|
||||
|
||||
# [1.68.0](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.67.1...@standardnotes/syncing-server@1.68.0) (2023-07-20)
|
||||
|
||||
### Features
|
||||
|
||||
* **syncing-server:** add shared vaults, invites, messages and notifications to sync response ([#665](https://github.com/standardnotes/syncing-server-js/issues/665)) ([efa4d7f](https://github.com/standardnotes/syncing-server-js/commit/efa4d7fc6007ef668e3de3b04853ac11b2d13c30))
|
||||
|
||||
## [1.67.1](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.67.0...@standardnotes/syncing-server@1.67.1) (2023-07-19)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* add missing imports and exports for controllers ([#664](https://github.com/standardnotes/syncing-server-js/issues/664)) ([aee6e60](https://github.com/standardnotes/syncing-server-js/commit/aee6e6058359e2b5231cc13387656f837699300f))
|
||||
|
||||
# [1.67.0](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.66.0...@standardnotes/syncing-server@1.67.0) (2023-07-19)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **syncing-server:** add missing messages and key system identifier sql representations ([#663](https://github.com/standardnotes/syncing-server-js/issues/663)) ([d026152](https://github.com/standardnotes/syncing-server-js/commit/d026152ac8cb2ecda2eee8d3f7385d655b210938))
|
||||
|
||||
### Features
|
||||
|
||||
* **syncing-server:** add persistence of shared vaults with users and invites + controllers ([#662](https://github.com/standardnotes/syncing-server-js/issues/662)) ([3f21a35](https://github.com/standardnotes/syncing-server-js/commit/3f21a358d24d70daf541aa62dc86cd9e29500e62))
|
||||
|
||||
# [1.66.0](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.65.0...@standardnotes/syncing-server@1.66.0) (2023-07-18)
|
||||
|
||||
### Features
|
||||
|
||||
* **syncing-server:** associating existing items with key systems and shared vaults ([#661](https://github.com/standardnotes/syncing-server-js/issues/661)) ([3b804e2](https://github.com/standardnotes/syncing-server-js/commit/3b804e2321f9d8444722f1d336689e12598121ca))
|
||||
|
||||
# [1.65.0](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.64.0...@standardnotes/syncing-server@1.65.0) (2023-07-18)
|
||||
|
||||
### Features
|
||||
|
||||
* **syncing-server:** persisting shared vault and key system associations ([#660](https://github.com/standardnotes/syncing-server-js/issues/660)) ([479d20e](https://github.com/standardnotes/syncing-server-js/commit/479d20e76f7766006dfa34a0d14401b090dec775))
|
||||
|
||||
# [1.64.0](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.63.1...@standardnotes/syncing-server@1.64.0) (2023-07-17)
|
||||
|
||||
### Features
|
||||
|
||||
@@ -2,6 +2,10 @@ import 'reflect-metadata'
|
||||
|
||||
import '../src/Infra/InversifyExpressUtils/InversifyExpressHealthCheckController'
|
||||
import '../src/Infra/InversifyExpressUtils/InversifyExpressItemsController'
|
||||
import '../src/Infra/InversifyExpressUtils/InversifyExpressMessagesController'
|
||||
import '../src/Infra/InversifyExpressUtils/InversifyExpressSharedVaultInvitesController'
|
||||
import '../src/Infra/InversifyExpressUtils/InversifyExpressSharedVaultUsersController'
|
||||
import '../src/Infra/InversifyExpressUtils/InversifyExpressSharedVaultsController'
|
||||
|
||||
import helmet from 'helmet'
|
||||
import * as cors from 'cors'
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
import { MigrationInterface, QueryRunner } from 'typeorm'
|
||||
|
||||
export class AddNotifications1688540448427 implements MigrationInterface {
|
||||
name = 'AddNotifications1688540448427'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
'CREATE TABLE `notifications` (`uuid` varchar(36) NOT NULL, `user_uuid` varchar(36) NOT NULL, `type` varchar(36) NOT NULL, `payload` text NOT NULL, `created_at_timestamp` bigint NOT NULL, `updated_at_timestamp` bigint NOT NULL, INDEX `index_notifications_on_user_uuid` (`user_uuid`), PRIMARY KEY (`uuid`)) ENGINE=InnoDB',
|
||||
)
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query('DROP INDEX `index_notifications_on_user_uuid` ON `notifications`')
|
||||
await queryRunner.query('DROP TABLE `notifications`')
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { MigrationInterface, QueryRunner } from 'typeorm'
|
||||
|
||||
export class AddNotifications1689671563304 implements MigrationInterface {
|
||||
name = 'AddNotifications1689671563304'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
'CREATE TABLE IF NOT EXISTS `notifications` (`uuid` varchar(36) NOT NULL, `user_uuid` varchar(36) NOT NULL, `type` varchar(36) NOT NULL, `payload` text NOT NULL, `created_at_timestamp` bigint NOT NULL, `updated_at_timestamp` bigint NOT NULL, INDEX `index_notifications_on_user_uuid` (`user_uuid`), PRIMARY KEY (`uuid`)) ENGINE=InnoDB',
|
||||
)
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query('DROP INDEX `index_notifications_on_user_uuid` ON `notifications`')
|
||||
await queryRunner.query('DROP TABLE `notifications`')
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { MigrationInterface, QueryRunner } from 'typeorm'
|
||||
|
||||
export class AddSharedVaultAndKeySystemAssociations1689671563305 implements MigrationInterface {
|
||||
name = 'AddSharedVaultAndKeySystemAssociations1689671563305'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
'CREATE TABLE `shared_vault_associations` (`uuid` varchar(36) NOT NULL, `shared_vault_uuid` varchar(36) NOT NULL, `item_uuid` varchar(36) NOT NULL, `last_edited_by` varchar(36) NOT NULL, `created_at_timestamp` bigint NOT NULL, `updated_at_timestamp` bigint NOT NULL, INDEX `shared_vault_uuid_on_shared_vault_associations` (`shared_vault_uuid`), INDEX `item_uuid_on_shared_vault_associations` (`item_uuid`), PRIMARY KEY (`uuid`)) ENGINE=InnoDB',
|
||||
)
|
||||
await queryRunner.query(
|
||||
'CREATE TABLE `key_system_associations` (`uuid` varchar(36) NOT NULL, `key_system_uuid` varchar(36) NOT NULL, `item_uuid` varchar(36) NOT NULL, `created_at_timestamp` bigint NOT NULL, `updated_at_timestamp` bigint NOT NULL, INDEX `key_system_uuid_on_key_system_associations` (`key_system_uuid`), INDEX `item_uuid_on_key_system_associations` (`item_uuid`), PRIMARY KEY (`uuid`)) ENGINE=InnoDB',
|
||||
)
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query('DROP INDEX `item_uuid_on_key_system_associations` ON `key_system_associations`')
|
||||
await queryRunner.query('DROP INDEX `key_system_uuid_on_key_system_associations` ON `key_system_associations`')
|
||||
await queryRunner.query('DROP TABLE `key_system_associations`')
|
||||
await queryRunner.query('DROP INDEX `item_uuid_on_shared_vault_associations` ON `shared_vault_associations`')
|
||||
await queryRunner.query(
|
||||
'DROP INDEX `shared_vault_uuid_on_shared_vault_associations` ON `shared_vault_associations`',
|
||||
)
|
||||
await queryRunner.query('DROP TABLE `shared_vault_associations`')
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import { MigrationInterface, QueryRunner } from 'typeorm'
|
||||
|
||||
export class AddSharedVaultsWithUsersAndInvites1689677728282 implements MigrationInterface {
|
||||
name = 'AddSharedVaultsWithUsersAndInvites1689677728282'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
'CREATE TABLE `shared_vaults` (`uuid` varchar(36) NOT NULL, `user_uuid` varchar(36) NOT NULL, `file_upload_bytes_used` int NOT NULL, `file_upload_bytes_limit` int NOT NULL, `created_at_timestamp` bigint NOT NULL, `updated_at_timestamp` bigint NOT NULL, INDEX `user_uuid_on_shared_vaults` (`user_uuid`), PRIMARY KEY (`uuid`)) ENGINE=InnoDB',
|
||||
)
|
||||
await queryRunner.query(
|
||||
'CREATE TABLE `shared_vault_users` (`uuid` varchar(36) NOT NULL, `shared_vault_uuid` varchar(36) NOT NULL, `user_uuid` varchar(36) NOT NULL, `permission` varchar(24) NOT NULL, `created_at_timestamp` bigint NOT NULL, `updated_at_timestamp` bigint NOT NULL, INDEX `shared_vault_uuid_on_shared_vault_users` (`shared_vault_uuid`), INDEX `user_uuid_on_shared_vault_users` (`user_uuid`), PRIMARY KEY (`uuid`)) ENGINE=InnoDB',
|
||||
)
|
||||
await queryRunner.query(
|
||||
'CREATE TABLE `shared_vault_invites` (`uuid` varchar(36) NOT NULL, `shared_vault_uuid` varchar(36) NOT NULL, `user_uuid` varchar(36) NOT NULL, `sender_uuid` varchar(36) NOT NULL, `encrypted_message` text NOT NULL, `permission` varchar(24) NOT NULL, `created_at_timestamp` bigint NOT NULL, `updated_at_timestamp` bigint NOT NULL, INDEX `shared_vault_uuid_on_shared_vault_invites` (`shared_vault_uuid`), INDEX `user_uuid_on_shared_vault_invites` (`user_uuid`), INDEX `sender_uuid_on_shared_vault_invites` (`sender_uuid`), PRIMARY KEY (`uuid`)) ENGINE=InnoDB',
|
||||
)
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query('DROP INDEX `sender_uuid_on_shared_vault_invites` ON `shared_vault_invites`')
|
||||
await queryRunner.query('DROP INDEX `user_uuid_on_shared_vault_invites` ON `shared_vault_invites`')
|
||||
await queryRunner.query('DROP INDEX `shared_vault_uuid_on_shared_vault_invites` ON `shared_vault_invites`')
|
||||
await queryRunner.query('DROP TABLE `shared_vault_invites`')
|
||||
await queryRunner.query('DROP INDEX `user_uuid_on_shared_vault_users` ON `shared_vault_users`')
|
||||
await queryRunner.query('DROP INDEX `shared_vault_uuid_on_shared_vault_users` ON `shared_vault_users`')
|
||||
await queryRunner.query('DROP TABLE `shared_vault_users`')
|
||||
await queryRunner.query('DROP INDEX `user_uuid_on_shared_vaults` ON `shared_vaults`')
|
||||
await queryRunner.query('DROP TABLE `shared_vaults`')
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import { MigrationInterface, QueryRunner } from 'typeorm'
|
||||
|
||||
export class AddMessages1689745128577 implements MigrationInterface {
|
||||
name = 'AddMessages1689745128577'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
'CREATE TABLE `messages` (`uuid` varchar(36) NOT NULL, `recipient_uuid` varchar(36) NOT NULL, `sender_uuid` varchar(36) NOT NULL, `encrypted_message` text NOT NULL, `replaceability_identifier` varchar(255) NULL, `created_at_timestamp` bigint NOT NULL, `updated_at_timestamp` bigint NOT NULL, INDEX `recipient_uuid_on_messages` (`recipient_uuid`), INDEX `sender_uuid_on_messages` (`sender_uuid`), PRIMARY KEY (`uuid`)) ENGINE=InnoDB',
|
||||
)
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query('DROP INDEX `sender_uuid_on_messages` ON `messages`')
|
||||
await queryRunner.query('DROP INDEX `recipient_uuid_on_messages` ON `messages`')
|
||||
await queryRunner.query('DROP TABLE `messages`')
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import { MigrationInterface, QueryRunner } from 'typeorm'
|
||||
|
||||
export class RenameKeyMessageIdentifier1689746180559 implements MigrationInterface {
|
||||
name = 'RenameKeyMessageIdentifier1689746180559'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query('DROP INDEX `key_system_uuid_on_key_system_associations` ON `key_system_associations`')
|
||||
await queryRunner.query(
|
||||
'ALTER TABLE `key_system_associations` CHANGE `key_system_uuid` `key_system_identifier` varchar(36) NOT NULL',
|
||||
)
|
||||
await queryRunner.query(
|
||||
'CREATE INDEX `key_system_identifier_on_key_system_associations` ON `key_system_associations` (`key_system_identifier`)',
|
||||
)
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
'DROP INDEX `key_system_identifier_on_key_system_associations` ON `key_system_associations`',
|
||||
)
|
||||
await queryRunner.query(
|
||||
'ALTER TABLE `key_system_associations` CHANGE `key_system_identifier` `key_system_uuid` varchar(36) NOT NULL',
|
||||
)
|
||||
await queryRunner.query(
|
||||
'CREATE INDEX `key_system_uuid_on_key_system_associations` ON `key_system_associations` (`key_system_uuid`)',
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
import { MigrationInterface, QueryRunner } from 'typeorm'
|
||||
|
||||
export class AddNotifications1688540623272 implements MigrationInterface {
|
||||
name = 'AddNotifications1688540623272'
|
||||
export class AddNotifications1689672099828 implements MigrationInterface {
|
||||
name = 'AddNotifications1689672099828'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
'CREATE TABLE "notifications" ("uuid" varchar PRIMARY KEY NOT NULL, "user_uuid" varchar(36) NOT NULL, "type" varchar(36) NOT NULL, "payload" text NOT NULL, "created_at_timestamp" bigint NOT NULL, "updated_at_timestamp" bigint NOT NULL)',
|
||||
'CREATE TABLE IF NOT EXISTS "notifications" ("uuid" varchar PRIMARY KEY NOT NULL, "user_uuid" varchar(36) NOT NULL, "type" varchar(36) NOT NULL, "payload" text NOT NULL, "created_at_timestamp" bigint NOT NULL, "updated_at_timestamp" bigint NOT NULL)',
|
||||
)
|
||||
await queryRunner.query('CREATE INDEX "index_notifications_on_user_uuid" ON "notifications" ("user_uuid") ')
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import { MigrationInterface, QueryRunner } from 'typeorm'
|
||||
|
||||
export class AddSharedVaultAndKeySystemAssociations1689672099829 implements MigrationInterface {
|
||||
name = 'AddSharedVaultAndKeySystemAssociations1689672099829'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
'CREATE TABLE "shared_vault_associations" ("uuid" varchar PRIMARY KEY NOT NULL, "shared_vault_uuid" varchar(36) NOT NULL, "item_uuid" varchar(36) NOT NULL, "last_edited_by" varchar(36) NOT NULL, "created_at_timestamp" bigint NOT NULL, "updated_at_timestamp" bigint NOT NULL)',
|
||||
)
|
||||
await queryRunner.query(
|
||||
'CREATE INDEX "shared_vault_uuid_on_shared_vault_associations" ON "shared_vault_associations" ("shared_vault_uuid") ',
|
||||
)
|
||||
await queryRunner.query(
|
||||
'CREATE INDEX "item_uuid_on_shared_vault_associations" ON "shared_vault_associations" ("item_uuid") ',
|
||||
)
|
||||
await queryRunner.query(
|
||||
'CREATE TABLE "key_system_associations" ("uuid" varchar PRIMARY KEY NOT NULL, "key_system_uuid" varchar(36) NOT NULL, "item_uuid" varchar(36) NOT NULL, "created_at_timestamp" bigint NOT NULL, "updated_at_timestamp" bigint NOT NULL)',
|
||||
)
|
||||
await queryRunner.query(
|
||||
'CREATE INDEX "key_system_uuid_on_key_system_associations" ON "key_system_associations" ("key_system_uuid") ',
|
||||
)
|
||||
await queryRunner.query(
|
||||
'CREATE INDEX "item_uuid_on_key_system_associations" ON "key_system_associations" ("item_uuid") ',
|
||||
)
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query('DROP INDEX "item_uuid_on_key_system_associations"')
|
||||
await queryRunner.query('DROP INDEX "key_system_uuid_on_key_system_associations"')
|
||||
await queryRunner.query('DROP TABLE "key_system_associations"')
|
||||
await queryRunner.query('DROP INDEX "item_uuid_on_shared_vault_associations"')
|
||||
await queryRunner.query('DROP INDEX "shared_vault_uuid_on_shared_vault_associations"')
|
||||
await queryRunner.query('DROP TABLE "shared_vault_associations"')
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
import { MigrationInterface, QueryRunner } from 'typeorm'
|
||||
|
||||
export class AddSharedVaultsWithUsersAndInvites1689677867175 implements MigrationInterface {
|
||||
name = 'AddSharedVaultsWithUsersAndInvites1689677867175'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
'CREATE TABLE "shared_vaults" ("uuid" varchar PRIMARY KEY NOT NULL, "user_uuid" varchar(36) NOT NULL, "file_upload_bytes_used" integer NOT NULL, "file_upload_bytes_limit" integer NOT NULL, "created_at_timestamp" bigint NOT NULL, "updated_at_timestamp" bigint NOT NULL)',
|
||||
)
|
||||
await queryRunner.query('CREATE INDEX "user_uuid_on_shared_vaults" ON "shared_vaults" ("user_uuid") ')
|
||||
await queryRunner.query(
|
||||
'CREATE TABLE "shared_vault_users" ("uuid" varchar PRIMARY KEY NOT NULL, "shared_vault_uuid" varchar(36) NOT NULL, "user_uuid" varchar(36) NOT NULL, "permission" varchar(24) NOT NULL, "created_at_timestamp" bigint NOT NULL, "updated_at_timestamp" bigint NOT NULL)',
|
||||
)
|
||||
await queryRunner.query(
|
||||
'CREATE INDEX "shared_vault_uuid_on_shared_vault_users" ON "shared_vault_users" ("shared_vault_uuid") ',
|
||||
)
|
||||
await queryRunner.query('CREATE INDEX "user_uuid_on_shared_vault_users" ON "shared_vault_users" ("user_uuid") ')
|
||||
await queryRunner.query(
|
||||
'CREATE TABLE "shared_vault_invites" ("uuid" varchar PRIMARY KEY NOT NULL, "shared_vault_uuid" varchar(36) NOT NULL, "user_uuid" varchar(36) NOT NULL, "sender_uuid" varchar(36) NOT NULL, "encrypted_message" text NOT NULL, "permission" varchar(24) NOT NULL, "created_at_timestamp" bigint NOT NULL, "updated_at_timestamp" bigint NOT NULL)',
|
||||
)
|
||||
await queryRunner.query(
|
||||
'CREATE INDEX "shared_vault_uuid_on_shared_vault_invites" ON "shared_vault_invites" ("shared_vault_uuid") ',
|
||||
)
|
||||
await queryRunner.query('CREATE INDEX "user_uuid_on_shared_vault_invites" ON "shared_vault_invites" ("user_uuid") ')
|
||||
await queryRunner.query(
|
||||
'CREATE INDEX "sender_uuid_on_shared_vault_invites" ON "shared_vault_invites" ("sender_uuid") ',
|
||||
)
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query('DROP INDEX "sender_uuid_on_shared_vault_invites"')
|
||||
await queryRunner.query('DROP INDEX "user_uuid_on_shared_vault_invites"')
|
||||
await queryRunner.query('DROP INDEX "shared_vault_uuid_on_shared_vault_invites"')
|
||||
await queryRunner.query('DROP TABLE "shared_vault_invites"')
|
||||
await queryRunner.query('DROP INDEX "user_uuid_on_shared_vault_users"')
|
||||
await queryRunner.query('DROP INDEX "shared_vault_uuid_on_shared_vault_users"')
|
||||
await queryRunner.query('DROP TABLE "shared_vault_users"')
|
||||
await queryRunner.query('DROP INDEX "user_uuid_on_shared_vaults"')
|
||||
await queryRunner.query('DROP TABLE "shared_vaults"')
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import { MigrationInterface, QueryRunner } from 'typeorm'
|
||||
|
||||
export class AddMessages1689744778643 implements MigrationInterface {
|
||||
name = 'AddMessages1689744778643'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
'CREATE TABLE "messages" ("uuid" varchar PRIMARY KEY NOT NULL, "recipient_uuid" varchar(36) NOT NULL, "sender_uuid" varchar(36) NOT NULL, "encrypted_message" text NOT NULL, "replaceability_identifier" varchar(255), "created_at_timestamp" bigint NOT NULL, "updated_at_timestamp" bigint NOT NULL)',
|
||||
)
|
||||
await queryRunner.query('CREATE INDEX "recipient_uuid_on_messages" ON "messages" ("recipient_uuid") ')
|
||||
await queryRunner.query('CREATE INDEX "sender_uuid_on_messages" ON "messages" ("sender_uuid") ')
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query('DROP INDEX "sender_uuid_on_messages"')
|
||||
await queryRunner.query('DROP INDEX "recipient_uuid_on_messages"')
|
||||
await queryRunner.query('DROP TABLE "messages"')
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
import { MigrationInterface, QueryRunner } from 'typeorm'
|
||||
|
||||
export class RenameKeyMessageIdentifier1689746527310 implements MigrationInterface {
|
||||
name = 'RenameKeyMessageIdentifier1689746527310'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query('DROP INDEX "key_system_uuid_on_key_system_associations"')
|
||||
await queryRunner.query('DROP INDEX "item_uuid_on_key_system_associations"')
|
||||
await queryRunner.query(
|
||||
'CREATE TABLE "temporary_key_system_associations" ("uuid" varchar PRIMARY KEY NOT NULL, "key_system_identifier" varchar(36) NOT NULL, "item_uuid" varchar(36) NOT NULL, "created_at_timestamp" bigint NOT NULL, "updated_at_timestamp" bigint NOT NULL)',
|
||||
)
|
||||
await queryRunner.query(
|
||||
'INSERT INTO "temporary_key_system_associations"("uuid", "key_system_identifier", "item_uuid", "created_at_timestamp", "updated_at_timestamp") SELECT "uuid", "key_system_uuid", "item_uuid", "created_at_timestamp", "updated_at_timestamp" FROM "key_system_associations"',
|
||||
)
|
||||
await queryRunner.query('DROP TABLE "key_system_associations"')
|
||||
await queryRunner.query('ALTER TABLE "temporary_key_system_associations" RENAME TO "key_system_associations"')
|
||||
await queryRunner.query(
|
||||
'CREATE INDEX "item_uuid_on_key_system_associations" ON "key_system_associations" ("item_uuid") ',
|
||||
)
|
||||
await queryRunner.query(
|
||||
'CREATE INDEX "key_system_identifier_on_key_system_associations" ON "key_system_associations" ("key_system_identifier") ',
|
||||
)
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query('DROP INDEX "key_system_identifier_on_key_system_associations"')
|
||||
await queryRunner.query('DROP INDEX "item_uuid_on_key_system_associations"')
|
||||
await queryRunner.query('ALTER TABLE "key_system_associations" RENAME TO "temporary_key_system_associations"')
|
||||
await queryRunner.query(
|
||||
'CREATE TABLE "key_system_associations" ("uuid" varchar PRIMARY KEY NOT NULL, "key_system_uuid" varchar(36) NOT NULL, "item_uuid" varchar(36) NOT NULL, "created_at_timestamp" bigint NOT NULL, "updated_at_timestamp" bigint NOT NULL)',
|
||||
)
|
||||
await queryRunner.query(
|
||||
'INSERT INTO "key_system_associations"("uuid", "key_system_uuid", "item_uuid", "created_at_timestamp", "updated_at_timestamp") SELECT "uuid", "key_system_identifier", "item_uuid", "created_at_timestamp", "updated_at_timestamp" FROM "temporary_key_system_associations"',
|
||||
)
|
||||
await queryRunner.query('DROP TABLE "temporary_key_system_associations"')
|
||||
await queryRunner.query(
|
||||
'CREATE INDEX "item_uuid_on_key_system_associations" ON "key_system_associations" ("item_uuid") ',
|
||||
)
|
||||
await queryRunner.query(
|
||||
'CREATE INDEX "key_system_uuid_on_key_system_associations" ON "key_system_associations" ("key_system_uuid") ',
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/syncing-server",
|
||||
"version": "1.64.0",
|
||||
"version": "1.68.3",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
|
||||
@@ -78,6 +78,78 @@ import { SaveItems } from '../Domain/UseCase/Syncing/SaveItems/SaveItems'
|
||||
import { ItemHashHttpMapper } from '../Mapping/Http/ItemHashHttpMapper'
|
||||
import { ItemHash } from '../Domain/Item/ItemHash'
|
||||
import { ItemHashHttpRepresentation } from '../Mapping/Http/ItemHashHttpRepresentation'
|
||||
import { TypeORMKeySystemAssociation } from '../Infra/TypeORM/TypeORMKeySystemAssociation'
|
||||
import { SharedVaultAssociation } from '../Domain/SharedVault/SharedVaultAssociation'
|
||||
import { TypeORMSharedVaultAssociation } from '../Infra/TypeORM/TypeORMSharedVaultAssociation'
|
||||
import { SharedVaultAssociationPersistenceMapper } from '../Mapping/Persistence/SharedVaultAssociationPersistenceMapper'
|
||||
import { TypeORMKeySystemAssociationRepository } from '../Infra/TypeORM/TypeORMKeySystemAssociationRepository'
|
||||
import { SharedVaultAssociationRepositoryInterface } from '../Domain/SharedVault/SharedVaultAssociationRepositoryInterface'
|
||||
import { TypeORMSharedVaultAssociationRepository } from '../Infra/TypeORM/TypeORMSharedVaultAssociationRepository'
|
||||
import { KeySystemAssociation } from '../Domain/KeySystem/KeySystemAssociation'
|
||||
import { KeySystemAssociationRepositoryInterface } from '../Domain/KeySystem/KeySystemAssociationRepositoryInterface'
|
||||
import { KeySystemAssociationPersistenceMapper } from '../Mapping/Persistence/KeySystemAssociationPersistenceMapper'
|
||||
import { HomeServerSharedVaultInvitesController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerSharedVaultInvitesController'
|
||||
import { InviteUserToSharedVault } from '../Domain/UseCase/SharedVaults/InviteUserToSharedVault/InviteUserToSharedVault'
|
||||
import { TypeORMSharedVaultRepository } from '../Infra/TypeORM/TypeORMSharedVaultRepository'
|
||||
import { TypeORMSharedVault } from '../Infra/TypeORM/TypeORMSharedVault'
|
||||
import { TypeORMSharedVaultInvite } from '../Infra/TypeORM/TypeORMSharedVaultInvite'
|
||||
import { TypeORMSharedVaultUser } from '../Infra/TypeORM/TypeORMSharedVaultUser'
|
||||
import { SharedVaultRepositoryInterface } from '../Domain/SharedVault/SharedVaultRepositoryInterface'
|
||||
import { SharedVaultPersistenceMapper } from '../Mapping/Persistence/SharedVaultPersistenceMapper'
|
||||
import { SharedVault } from '../Domain/SharedVault/SharedVault'
|
||||
import { SharedVaultUser } from '../Domain/SharedVault/User/SharedVaultUser'
|
||||
import { SharedVaultUserPersistenceMapper } from '../Mapping/Persistence/SharedVaultUserPersistenceMapper'
|
||||
import { SharedVaultInvite } from '../Domain/SharedVault/User/Invite/SharedVaultInvite'
|
||||
import { SharedVaultInvitePersistenceMapper } from '../Mapping/Persistence/SharedVaultInvitePersistenceMapper'
|
||||
import { SharedVaultUserRepositoryInterface } from '../Domain/SharedVault/User/SharedVaultUserRepositoryInterface'
|
||||
import { TypeORMSharedVaultUserRepository } from '../Infra/TypeORM/TypeORMSharedVaultUserRepository'
|
||||
import { SharedVaultInviteRepositoryInterface } from '../Domain/SharedVault/User/Invite/SharedVaultInviteRepositoryInterface'
|
||||
import { TypeORMSharedVaultInviteRepository } from '../Infra/TypeORM/TypeORMSharedVaultInviteRepository'
|
||||
import { UpdateSharedVaultInvite } from '../Domain/UseCase/SharedVaults/UpdateSharedVaultInvite/UpdateSharedVaultInvite'
|
||||
import { AcceptInviteToSharedVault } from '../Domain/UseCase/SharedVaults/AcceptInviteToSharedVault/AcceptInviteToSharedVault'
|
||||
import { AddUserToSharedVault } from '../Domain/UseCase/SharedVaults/AddUserToSharedVault/AddUserToSharedVault'
|
||||
import { DeclineInviteToSharedVault } from '../Domain/UseCase/SharedVaults/DeclineInviteToSharedVault/DeclineInviteToSharedVault'
|
||||
import { DeleteSharedVaultInvitesToUser } from '../Domain/UseCase/SharedVaults/DeleteSharedVaultInvitesToUser/DeleteSharedVaultInvitesToUser'
|
||||
import { DeleteSharedVaultInvitesSentByUser } from '../Domain/UseCase/SharedVaults/DeleteSharedVaultInvitesSentByUser/DeleteSharedVaultInvitesSentByUser'
|
||||
import { GetSharedVaultInvitesSentByUser } from '../Domain/UseCase/SharedVaults/GetSharedVaultInvitesSentByUser/GetSharedVaultInvitesSentByUser'
|
||||
import { GetSharedVaultInvitesSentToUser } from '../Domain/UseCase/SharedVaults/GetSharedVaultInvitesSentToUser/GetSharedVaultInvitesSentToUser'
|
||||
import { HomeServerSharedVaultUsersController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerSharedVaultUsersController'
|
||||
import { GetSharedVaultUsers } from '../Domain/UseCase/SharedVaults/GetSharedVaultUsers/GetSharedVaultUsers'
|
||||
import { RemoveUserFromSharedVault } from '../Domain/UseCase/SharedVaults/RemoveUserFromSharedVault/RemoveUserFromSharedVault'
|
||||
import { AddNotificationForUser } from '../Domain/UseCase/Messaging/AddNotificationForUser/AddNotificationForUser'
|
||||
import { TypeORMNotification } from '../Infra/TypeORM/TypeORMNotification'
|
||||
import { NotificationRepositoryInterface } from '../Domain/Notifications/NotificationRepositoryInterface'
|
||||
import { TypeORMNotificationRepository } from '../Infra/TypeORM/TypeORMNotificationRepository'
|
||||
import { NotificationPersistenceMapper } from '../Mapping/Persistence/NotificationPersistenceMapper'
|
||||
import { Notification } from '../Domain/Notifications/Notification'
|
||||
import { SharedVaultUserHttpRepresentation } from '../Mapping/Http/SharedVaultUserHttpRepresentation'
|
||||
import { SharedVaultUserHttpMapper } from '../Mapping/Http/SharedVaultUserHttpMapper'
|
||||
import { HomeServerSharedVaultsController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerSharedVaultsController'
|
||||
import { GetSharedVaults } from '../Domain/UseCase/SharedVaults/GetSharedVaults/GetSharedVaults'
|
||||
import { CreateSharedVault } from '../Domain/UseCase/SharedVaults/CreateSharedVault/CreateSharedVault'
|
||||
import { DeleteSharedVault } from '../Domain/UseCase/SharedVaults/DeleteSharedVault/DeleteSharedVault'
|
||||
import { CreateSharedVaultFileValetToken } from '../Domain/UseCase/SharedVaults/CreateSharedVaultFileValetToken/CreateSharedVaultFileValetToken'
|
||||
import { SharedVaultValetTokenData, TokenEncoder, TokenEncoderInterface } from '@standardnotes/security'
|
||||
import { SharedVaultHttpRepresentation } from '../Mapping/Http/SharedVaultHttpRepresentation'
|
||||
import { SharedVaultHttpMapper } from '../Mapping/Http/SharedVaultHttpMapper'
|
||||
import { SharedVaultInviteHttpRepresentation } from '../Mapping/Http/SharedVaultInviteHttpRepresentation'
|
||||
import { SharedVaultInviteHttpMapper } from '../Mapping/Http/SharedVaultInviteHttpMapper'
|
||||
import { HomeServerMessagesController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerMessagesController'
|
||||
import { GetMessagesSentToUser } from '../Domain/UseCase/Messaging/GetMessagesSentToUser/GetMessagesSentToUser'
|
||||
import { TypeORMMessage } from '../Infra/TypeORM/TypeORMMessage'
|
||||
import { MessageRepositoryInterface } from '../Domain/Message/MessageRepositoryInterface'
|
||||
import { TypeORMMessageRepository } from '../Infra/TypeORM/TypeORMMessageRepository'
|
||||
import { Message } from '../Domain/Message/Message'
|
||||
import { MessagePersistenceMapper } from '../Mapping/Persistence/MessagePersistenceMapper'
|
||||
import { GetMessagesSentByUser } from '../Domain/UseCase/Messaging/GetMessagesSentByUser/GetMessagesSentByUser'
|
||||
import { SendMessageToUser } from '../Domain/UseCase/Messaging/SendMessageToUser/SendMessageToUser'
|
||||
import { DeleteAllMessagesSentToUser } from '../Domain/UseCase/Messaging/DeleteAllMessagesSentToUser/DeleteAllMessagesSentToUser'
|
||||
import { DeleteMessage } from '../Domain/UseCase/Messaging/DeleteMessage/DeleteMessage'
|
||||
import { MessageHttpRepresentation } from '../Mapping/Http/MessageHttpRepresentation'
|
||||
import { MessageHttpMapper } from '../Mapping/Http/MessageHttpMapper'
|
||||
import { GetUserNotifications } from '../Domain/UseCase/Messaging/GetUserNotifications/GetUserNotifications'
|
||||
import { NotificationHttpMapper } from '../Mapping/Http/NotificationHttpMapper'
|
||||
import { NotificationHttpRepresentation } from '../Mapping/Http/NotificationHttpRepresentation'
|
||||
|
||||
export class ContainerConfigLoader {
|
||||
private readonly DEFAULT_CONTENT_SIZE_TRANSFER_LIMIT = 10_000_000
|
||||
@@ -232,19 +304,140 @@ export class ContainerConfigLoader {
|
||||
container
|
||||
.bind<MapperInterface<Item, ItemBackupRepresentation>>(TYPES.Sync_ItemBackupMapper)
|
||||
.toConstantValue(new ItemBackupMapper(container.get(TYPES.Sync_Timer)))
|
||||
container
|
||||
.bind<MapperInterface<KeySystemAssociation, TypeORMKeySystemAssociation>>(
|
||||
TYPES.Sync_KeySystemAssociationPersistenceMapper,
|
||||
)
|
||||
.toConstantValue(new KeySystemAssociationPersistenceMapper())
|
||||
container
|
||||
.bind<MapperInterface<SharedVaultAssociation, TypeORMSharedVaultAssociation>>(
|
||||
TYPES.Sync_SharedVaultAssociationPersistenceMapper,
|
||||
)
|
||||
.toConstantValue(new SharedVaultAssociationPersistenceMapper())
|
||||
container
|
||||
.bind<MapperInterface<SharedVault, TypeORMSharedVault>>(TYPES.Sync_SharedVaultPersistenceMapper)
|
||||
.toConstantValue(new SharedVaultPersistenceMapper())
|
||||
container
|
||||
.bind<MapperInterface<SharedVaultUser, TypeORMSharedVaultUser>>(TYPES.Sync_SharedVaultUserPersistenceMapper)
|
||||
.toConstantValue(new SharedVaultUserPersistenceMapper())
|
||||
container
|
||||
.bind<MapperInterface<SharedVaultInvite, TypeORMSharedVaultInvite>>(TYPES.Sync_SharedVaultInvitePersistenceMapper)
|
||||
.toConstantValue(new SharedVaultInvitePersistenceMapper())
|
||||
container
|
||||
.bind<MapperInterface<Notification, TypeORMNotification>>(TYPES.Sync_NotificationPersistenceMapper)
|
||||
.toConstantValue(new NotificationPersistenceMapper())
|
||||
container
|
||||
.bind<MapperInterface<SharedVaultUser, SharedVaultUserHttpRepresentation>>(TYPES.Sync_SharedVaultUserHttpMapper)
|
||||
.toConstantValue(new SharedVaultUserHttpMapper())
|
||||
container
|
||||
.bind<MapperInterface<SharedVault, SharedVaultHttpRepresentation>>(TYPES.Sync_SharedVaultHttpMapper)
|
||||
.toConstantValue(new SharedVaultHttpMapper())
|
||||
container
|
||||
.bind<MapperInterface<SharedVaultInvite, SharedVaultInviteHttpRepresentation>>(
|
||||
TYPES.Sync_SharedVaultInviteHttpMapper,
|
||||
)
|
||||
.toConstantValue(new SharedVaultInviteHttpMapper())
|
||||
container
|
||||
.bind<MapperInterface<Message, TypeORMMessage>>(TYPES.Sync_MessagePersistenceMapper)
|
||||
.toConstantValue(new MessagePersistenceMapper())
|
||||
container
|
||||
.bind<MapperInterface<Message, MessageHttpRepresentation>>(TYPES.Sync_MessageHttpMapper)
|
||||
.toConstantValue(new MessageHttpMapper())
|
||||
container
|
||||
.bind<MapperInterface<Notification, NotificationHttpRepresentation>>(TYPES.Sync_NotificationHttpMapper)
|
||||
.toConstantValue(new NotificationHttpMapper())
|
||||
|
||||
// ORM
|
||||
container
|
||||
.bind<Repository<TypeORMItem>>(TYPES.Sync_ORMItemRepository)
|
||||
.toDynamicValue(() => appDataSource.getRepository(TypeORMItem))
|
||||
container
|
||||
.bind<Repository<TypeORMSharedVaultAssociation>>(TYPES.Sync_ORMSharedVaultAssociationRepository)
|
||||
.toConstantValue(appDataSource.getRepository(TypeORMSharedVaultAssociation))
|
||||
container
|
||||
.bind<Repository<TypeORMKeySystemAssociation>>(TYPES.Sync_ORMKeySystemAssociationRepository)
|
||||
.toConstantValue(appDataSource.getRepository(TypeORMKeySystemAssociation))
|
||||
container
|
||||
.bind<Repository<TypeORMSharedVault>>(TYPES.Sync_ORMSharedVaultRepository)
|
||||
.toConstantValue(appDataSource.getRepository(TypeORMSharedVault))
|
||||
container
|
||||
.bind<Repository<TypeORMSharedVaultInvite>>(TYPES.Sync_ORMSharedVaultInviteRepository)
|
||||
.toConstantValue(appDataSource.getRepository(TypeORMSharedVaultInvite))
|
||||
container
|
||||
.bind<Repository<TypeORMSharedVaultUser>>(TYPES.Sync_ORMSharedVaultUserRepository)
|
||||
.toConstantValue(appDataSource.getRepository(TypeORMSharedVaultUser))
|
||||
container
|
||||
.bind<Repository<TypeORMNotification>>(TYPES.Sync_ORMNotificationRepository)
|
||||
.toConstantValue(appDataSource.getRepository(TypeORMNotification))
|
||||
container
|
||||
.bind<Repository<TypeORMMessage>>(TYPES.Sync_ORMMessageRepository)
|
||||
.toConstantValue(appDataSource.getRepository(TypeORMMessage))
|
||||
|
||||
// Repositories
|
||||
container
|
||||
.bind<KeySystemAssociationRepositoryInterface>(TYPES.Sync_KeySystemAssociationRepository)
|
||||
.toConstantValue(
|
||||
new TypeORMKeySystemAssociationRepository(
|
||||
container.get(TYPES.Sync_ORMKeySystemAssociationRepository),
|
||||
container.get(TYPES.Sync_KeySystemAssociationPersistenceMapper),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<SharedVaultAssociationRepositoryInterface>(TYPES.Sync_SharedVaultAssociationRepository)
|
||||
.toConstantValue(
|
||||
new TypeORMSharedVaultAssociationRepository(
|
||||
container.get(TYPES.Sync_ORMSharedVaultAssociationRepository),
|
||||
container.get(TYPES.Sync_SharedVaultAssociationPersistenceMapper),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<ItemRepositoryInterface>(TYPES.Sync_ItemRepository)
|
||||
.toConstantValue(
|
||||
new TypeORMItemRepository(
|
||||
container.get(TYPES.Sync_ORMItemRepository),
|
||||
container.get(TYPES.Sync_ItemPersistenceMapper),
|
||||
container.get(TYPES.Sync_KeySystemAssociationRepository),
|
||||
container.get(TYPES.Sync_SharedVaultAssociationRepository),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<SharedVaultRepositoryInterface>(TYPES.Sync_SharedVaultRepository)
|
||||
.toConstantValue(
|
||||
new TypeORMSharedVaultRepository(
|
||||
container.get(TYPES.Sync_ORMSharedVaultRepository),
|
||||
container.get(TYPES.Sync_SharedVaultPersistenceMapper),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<SharedVaultUserRepositoryInterface>(TYPES.Sync_SharedVaultUserRepository)
|
||||
.toConstantValue(
|
||||
new TypeORMSharedVaultUserRepository(
|
||||
container.get(TYPES.Sync_ORMSharedVaultUserRepository),
|
||||
container.get(TYPES.Sync_SharedVaultUserPersistenceMapper),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<SharedVaultInviteRepositoryInterface>(TYPES.Sync_SharedVaultInviteRepository)
|
||||
.toConstantValue(
|
||||
new TypeORMSharedVaultInviteRepository(
|
||||
container.get(TYPES.Sync_ORMSharedVaultInviteRepository),
|
||||
container.get(TYPES.Sync_SharedVaultInvitePersistenceMapper),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<NotificationRepositoryInterface>(TYPES.Sync_NotificationRepository)
|
||||
.toConstantValue(
|
||||
new TypeORMNotificationRepository(
|
||||
container.get(TYPES.Sync_ORMNotificationRepository),
|
||||
container.get(TYPES.Sync_NotificationPersistenceMapper),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<MessageRepositoryInterface>(TYPES.Sync_MessageRepository)
|
||||
.toConstantValue(
|
||||
new TypeORMMessageRepository(
|
||||
container.get(TYPES.Sync_ORMMessageRepository),
|
||||
container.get(TYPES.Sync_MessagePersistenceMapper),
|
||||
),
|
||||
)
|
||||
|
||||
@@ -292,6 +485,14 @@ export class ContainerConfigLoader {
|
||||
.toConstantValue(
|
||||
env.get('MAX_ITEMS_LIMIT', true) ? +env.get('MAX_ITEMS_LIMIT', true) : this.DEFAULT_MAX_ITEMS_LIMIT,
|
||||
)
|
||||
container.bind(TYPES.Sync_VALET_TOKEN_SECRET).toConstantValue(env.get('VALET_TOKEN_SECRET', true))
|
||||
container
|
||||
.bind(TYPES.Sync_VALET_TOKEN_TTL)
|
||||
.toConstantValue(env.get('VALET_TOKEN_TTL', true) ? +env.get('VALET_TOKEN_TTL', true) : 7200)
|
||||
|
||||
container
|
||||
.bind<TokenEncoderInterface<SharedVaultValetTokenData>>(TYPES.Sync_SharedVaultValetTokenEncoder)
|
||||
.toConstantValue(new TokenEncoder<SharedVaultValetTokenData>(container.get(TYPES.Sync_VALET_TOKEN_SECRET)))
|
||||
|
||||
container.bind<OwnershipFilter>(TYPES.Sync_OwnershipFilter).toConstantValue(new OwnershipFilter())
|
||||
container
|
||||
@@ -316,6 +517,7 @@ export class ContainerConfigLoader {
|
||||
.toConstantValue(
|
||||
new GetItems(
|
||||
container.get(TYPES.Sync_ItemRepository),
|
||||
container.get(TYPES.Sync_SharedVaultUserRepository),
|
||||
container.get(TYPES.Sync_CONTENT_SIZE_TRANSFER_LIMIT),
|
||||
container.get(TYPES.Sync_ItemTransferCalculator),
|
||||
container.get(TYPES.Sync_Timer),
|
||||
@@ -355,6 +557,24 @@ export class ContainerConfigLoader {
|
||||
container.get(TYPES.Sync_Logger),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<GetUserNotifications>(TYPES.Sync_GetUserNotifications)
|
||||
.toConstantValue(new GetUserNotifications(container.get(TYPES.Sync_NotificationRepository)))
|
||||
container
|
||||
.bind<GetSharedVaults>(TYPES.Sync_GetSharedVaults)
|
||||
.toConstantValue(
|
||||
new GetSharedVaults(
|
||||
container.get(TYPES.Sync_SharedVaultUserRepository),
|
||||
container.get(TYPES.Sync_SharedVaultRepository),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<GetSharedVaultInvitesSentToUser>(TYPES.Sync_GetSharedVaultInvitesSentToUser)
|
||||
.toConstantValue(new GetSharedVaultInvitesSentToUser(container.get(TYPES.Sync_SharedVaultInviteRepository)))
|
||||
container
|
||||
.bind<GetMessagesSentToUser>(TYPES.Sync_GetMessagesSentToUser)
|
||||
.toConstantValue(new GetMessagesSentToUser(container.get(TYPES.Sync_MessageRepository)))
|
||||
|
||||
container
|
||||
.bind<SyncItems>(TYPES.Sync_SyncItems)
|
||||
.toConstantValue(
|
||||
@@ -362,6 +582,10 @@ export class ContainerConfigLoader {
|
||||
container.get(TYPES.Sync_ItemRepository),
|
||||
container.get(TYPES.Sync_GetItems),
|
||||
container.get(TYPES.Sync_SaveItems),
|
||||
container.get(TYPES.Sync_GetSharedVaults),
|
||||
container.get(TYPES.Sync_GetSharedVaultInvitesSentToUser),
|
||||
container.get(TYPES.Sync_GetMessagesSentToUser),
|
||||
container.get(TYPES.Sync_GetUserNotifications),
|
||||
),
|
||||
)
|
||||
container.bind<CheckIntegrity>(TYPES.Sync_CheckIntegrity).toDynamicValue((context: interfaces.Context) => {
|
||||
@@ -370,6 +594,132 @@ export class ContainerConfigLoader {
|
||||
container.bind<GetItem>(TYPES.Sync_GetItem).toDynamicValue((context: interfaces.Context) => {
|
||||
return new GetItem(context.container.get(TYPES.Sync_ItemRepository))
|
||||
})
|
||||
container
|
||||
.bind<InviteUserToSharedVault>(TYPES.Sync_InviteUserToSharedVault)
|
||||
.toConstantValue(
|
||||
new InviteUserToSharedVault(
|
||||
container.get(TYPES.Sync_SharedVaultRepository),
|
||||
container.get(TYPES.Sync_SharedVaultInviteRepository),
|
||||
container.get(TYPES.Sync_Timer),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<UpdateSharedVaultInvite>(TYPES.Sync_UpdateSharedVaultInvite)
|
||||
.toConstantValue(
|
||||
new UpdateSharedVaultInvite(
|
||||
container.get(TYPES.Sync_SharedVaultInviteRepository),
|
||||
container.get(TYPES.Sync_Timer),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<AddUserToSharedVault>(TYPES.Sync_AddUserToSharedVault)
|
||||
.toConstantValue(
|
||||
new AddUserToSharedVault(
|
||||
container.get(TYPES.Sync_SharedVaultRepository),
|
||||
container.get(TYPES.Sync_SharedVaultUserRepository),
|
||||
container.get(TYPES.Sync_Timer),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<AcceptInviteToSharedVault>(TYPES.Sync_AcceptInviteToSharedVault)
|
||||
.toConstantValue(
|
||||
new AcceptInviteToSharedVault(
|
||||
container.get(TYPES.Sync_AddUserToSharedVault),
|
||||
container.get(TYPES.Sync_SharedVaultInviteRepository),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<DeclineInviteToSharedVault>(TYPES.Sync_DeclineInviteToSharedVault)
|
||||
.toConstantValue(new DeclineInviteToSharedVault(container.get(TYPES.Sync_SharedVaultInviteRepository)))
|
||||
container
|
||||
.bind<DeleteSharedVaultInvitesToUser>(TYPES.Sync_DeleteSharedVaultInvitesToUser)
|
||||
.toConstantValue(
|
||||
new DeleteSharedVaultInvitesToUser(
|
||||
container.get(TYPES.Sync_SharedVaultInviteRepository),
|
||||
container.get(TYPES.Sync_DeclineInviteToSharedVault),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<DeleteSharedVaultInvitesSentByUser>(TYPES.Sync_DeleteSharedVaultInvitesSentByUser)
|
||||
.toConstantValue(
|
||||
new DeleteSharedVaultInvitesSentByUser(
|
||||
container.get(TYPES.Sync_SharedVaultInviteRepository),
|
||||
container.get(TYPES.Sync_DeclineInviteToSharedVault),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<GetSharedVaultInvitesSentByUser>(TYPES.Sync_GetSharedVaultInvitesSentByUser)
|
||||
.toConstantValue(new GetSharedVaultInvitesSentByUser(container.get(TYPES.Sync_SharedVaultInviteRepository)))
|
||||
container
|
||||
.bind<GetSharedVaultUsers>(TYPES.Sync_GetSharedVaultUsers)
|
||||
.toConstantValue(
|
||||
new GetSharedVaultUsers(
|
||||
container.get(TYPES.Sync_SharedVaultUserRepository),
|
||||
container.get(TYPES.Sync_SharedVaultRepository),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<AddNotificationForUser>(TYPES.Sync_AddNotificationForUser)
|
||||
.toConstantValue(
|
||||
new AddNotificationForUser(container.get(TYPES.Sync_NotificationRepository), container.get(TYPES.Sync_Timer)),
|
||||
)
|
||||
container
|
||||
.bind<RemoveUserFromSharedVault>(TYPES.Sync_RemoveSharedVaultUser)
|
||||
.toConstantValue(
|
||||
new RemoveUserFromSharedVault(
|
||||
container.get(TYPES.Sync_SharedVaultUserRepository),
|
||||
container.get(TYPES.Sync_SharedVaultRepository),
|
||||
container.get(TYPES.Sync_AddNotificationForUser),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<CreateSharedVault>(TYPES.Sync_CreateSharedVault)
|
||||
.toConstantValue(
|
||||
new CreateSharedVault(
|
||||
container.get(TYPES.Sync_AddUserToSharedVault),
|
||||
container.get(TYPES.Sync_SharedVaultRepository),
|
||||
container.get(TYPES.Sync_Timer),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<DeleteSharedVault>(TYPES.Sync_DeleteSharedVault)
|
||||
.toConstantValue(
|
||||
new DeleteSharedVault(
|
||||
container.get(TYPES.Sync_SharedVaultRepository),
|
||||
container.get(TYPES.Sync_SharedVaultUserRepository),
|
||||
container.get(TYPES.Sync_SharedVaultInviteRepository),
|
||||
container.get(TYPES.Sync_RemoveSharedVaultUser),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<CreateSharedVaultFileValetToken>(TYPES.Sync_CreateSharedVaultFileValetToken)
|
||||
.toConstantValue(
|
||||
new CreateSharedVaultFileValetToken(
|
||||
container.get(TYPES.Sync_SharedVaultRepository),
|
||||
container.get(TYPES.Sync_SharedVaultUserRepository),
|
||||
container.get(TYPES.Sync_SharedVaultValetTokenEncoder),
|
||||
container.get(TYPES.Sync_VALET_TOKEN_TTL),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<GetMessagesSentByUser>(TYPES.Sync_GetMessagesSentByUser)
|
||||
.toConstantValue(new GetMessagesSentByUser(container.get(TYPES.Sync_MessageRepository)))
|
||||
container
|
||||
.bind<SendMessageToUser>(TYPES.Sync_SendMessageToUser)
|
||||
.toConstantValue(
|
||||
new SendMessageToUser(container.get(TYPES.Sync_MessageRepository), container.get(TYPES.Sync_Timer)),
|
||||
)
|
||||
container
|
||||
.bind<DeleteMessage>(TYPES.Sync_DeleteMessage)
|
||||
.toConstantValue(new DeleteMessage(container.get(TYPES.Sync_MessageRepository)))
|
||||
container
|
||||
.bind<DeleteAllMessagesSentToUser>(TYPES.Sync_DeleteAllMessagesSentToUser)
|
||||
.toConstantValue(
|
||||
new DeleteAllMessagesSentToUser(
|
||||
container.get(TYPES.Sync_MessageRepository),
|
||||
container.get(TYPES.Sync_DeleteMessage),
|
||||
),
|
||||
)
|
||||
|
||||
// Services
|
||||
container
|
||||
@@ -382,6 +732,10 @@ export class ContainerConfigLoader {
|
||||
container.get(TYPES.Sync_ItemHttpMapper),
|
||||
container.get(TYPES.Sync_ItemConflictHttpMapper),
|
||||
container.get(TYPES.Sync_SavedItemHttpMapper),
|
||||
container.get(TYPES.Sync_SharedVaultHttpMapper),
|
||||
container.get(TYPES.Sync_SharedVaultInviteHttpMapper),
|
||||
container.get(TYPES.Sync_MessageHttpMapper),
|
||||
container.get(TYPES.Sync_NotificationHttpMapper),
|
||||
),
|
||||
)
|
||||
container
|
||||
@@ -557,6 +911,58 @@ export class ContainerConfigLoader {
|
||||
container.get(TYPES.Sync_ControllerContainer),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<HomeServerSharedVaultInvitesController>(TYPES.Sync_HomeServerSharedVaultInvitesController)
|
||||
.toConstantValue(
|
||||
new HomeServerSharedVaultInvitesController(
|
||||
container.get(TYPES.Sync_InviteUserToSharedVault),
|
||||
container.get(TYPES.Sync_UpdateSharedVaultInvite),
|
||||
container.get(TYPES.Sync_AcceptInviteToSharedVault),
|
||||
container.get(TYPES.Sync_DeclineInviteToSharedVault),
|
||||
container.get(TYPES.Sync_DeleteSharedVaultInvitesToUser),
|
||||
container.get(TYPES.Sync_DeleteSharedVaultInvitesSentByUser),
|
||||
container.get(TYPES.Sync_GetSharedVaultInvitesSentByUser),
|
||||
container.get(TYPES.Sync_GetSharedVaultInvitesSentToUser),
|
||||
container.get(TYPES.Sync_SharedVaultInviteHttpMapper),
|
||||
container.get(TYPES.Sync_ControllerContainer),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<HomeServerSharedVaultUsersController>(TYPES.Sync_HomeServerSharedVaultUsersController)
|
||||
.toConstantValue(
|
||||
new HomeServerSharedVaultUsersController(
|
||||
container.get(TYPES.Sync_GetSharedVaultUsers),
|
||||
container.get(TYPES.Sync_RemoveSharedVaultUser),
|
||||
container.get(TYPES.Sync_SharedVaultUserHttpMapper),
|
||||
container.get(TYPES.Sync_ControllerContainer),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<HomeServerSharedVaultsController>(TYPES.Sync_HomeServerSharedVaultsController)
|
||||
.toConstantValue(
|
||||
new HomeServerSharedVaultsController(
|
||||
container.get(TYPES.Sync_GetSharedVaults),
|
||||
container.get(TYPES.Sync_CreateSharedVault),
|
||||
container.get(TYPES.Sync_DeleteSharedVault),
|
||||
container.get(TYPES.Sync_CreateSharedVaultFileValetToken),
|
||||
container.get(TYPES.Sync_SharedVaultHttpMapper),
|
||||
container.get(TYPES.Sync_SharedVaultUserHttpMapper),
|
||||
container.get(TYPES.Sync_ControllerContainer),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<HomeServerMessagesController>(TYPES.Sync_HomeServerMessagesController)
|
||||
.toConstantValue(
|
||||
new HomeServerMessagesController(
|
||||
container.get(TYPES.Sync_GetMessagesSentToUser),
|
||||
container.get(TYPES.Sync_GetMessagesSentByUser),
|
||||
container.get(TYPES.Sync_SendMessageToUser),
|
||||
container.get(TYPES.Sync_DeleteAllMessagesSentToUser),
|
||||
container.get(TYPES.Sync_DeleteMessage),
|
||||
container.get(TYPES.Sync_MessageHttpMapper),
|
||||
container.get(TYPES.Sync_ControllerContainer),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
logger.debug('Configuration complete')
|
||||
|
||||
@@ -4,6 +4,12 @@ import { Env } from './Env'
|
||||
import { SqliteConnectionOptions } from 'typeorm/driver/sqlite/SqliteConnectionOptions'
|
||||
import { TypeORMItem } from '../Infra/TypeORM/TypeORMItem'
|
||||
import { TypeORMNotification } from '../Infra/TypeORM/TypeORMNotification'
|
||||
import { TypeORMSharedVaultAssociation } from '../Infra/TypeORM/TypeORMSharedVaultAssociation'
|
||||
import { TypeORMKeySystemAssociation } from '../Infra/TypeORM/TypeORMKeySystemAssociation'
|
||||
import { TypeORMSharedVault } from '../Infra/TypeORM/TypeORMSharedVault'
|
||||
import { TypeORMSharedVaultUser } from '../Infra/TypeORM/TypeORMSharedVaultUser'
|
||||
import { TypeORMSharedVaultInvite } from '../Infra/TypeORM/TypeORMSharedVaultInvite'
|
||||
import { TypeORMMessage } from '../Infra/TypeORM/TypeORMMessage'
|
||||
|
||||
export class AppDataSource {
|
||||
private _dataSource: DataSource | undefined
|
||||
@@ -33,7 +39,16 @@ export class AppDataSource {
|
||||
|
||||
const commonDataSourceOptions = {
|
||||
maxQueryExecutionTime,
|
||||
entities: [TypeORMItem, TypeORMNotification],
|
||||
entities: [
|
||||
TypeORMItem,
|
||||
TypeORMNotification,
|
||||
TypeORMSharedVaultAssociation,
|
||||
TypeORMKeySystemAssociation,
|
||||
TypeORMSharedVault,
|
||||
TypeORMSharedVaultUser,
|
||||
TypeORMSharedVaultInvite,
|
||||
TypeORMMessage,
|
||||
],
|
||||
migrations: [`${__dirname}/../../migrations/${isConfiguredForMySQL ? 'mysql' : 'sqlite'}/*.js`],
|
||||
migrationsRun: true,
|
||||
logging: <LoggerOptions>this.env.get('DB_DEBUG_LEVEL', true) ?? 'info',
|
||||
|
||||
@@ -8,8 +8,22 @@ const TYPES = {
|
||||
Sync_Env: Symbol.for('Sync_Env'),
|
||||
// Repositories
|
||||
Sync_ItemRepository: Symbol.for('Sync_ItemRepository'),
|
||||
Sync_KeySystemAssociationRepository: Symbol.for('Sync_KeySystemAssociationRepository'),
|
||||
Sync_SharedVaultAssociationRepository: Symbol.for('Sync_SharedVaultAssociationRepository'),
|
||||
Sync_SharedVaultRepository: Symbol.for('Sync_SharedVaultRepository'),
|
||||
Sync_SharedVaultInviteRepository: Symbol.for('Sync_SharedVaultInviteRepository'),
|
||||
Sync_SharedVaultUserRepository: Symbol.for('Sync_SharedVaultUserRepository'),
|
||||
Sync_NotificationRepository: Symbol.for('Sync_NotificationRepository'),
|
||||
Sync_MessageRepository: Symbol.for('Sync_MessageRepository'),
|
||||
// ORM
|
||||
Sync_ORMItemRepository: Symbol.for('Sync_ORMItemRepository'),
|
||||
Sync_ORMSharedVaultAssociationRepository: Symbol.for('Sync_ORMSharedVaultAssociationRepository'),
|
||||
Sync_ORMKeySystemAssociationRepository: Symbol.for('Sync_ORMKeySystemAssociationRepository'),
|
||||
Sync_ORMSharedVaultRepository: Symbol.for('Sync_ORMSharedVaultRepository'),
|
||||
Sync_ORMSharedVaultInviteRepository: Symbol.for('Sync_ORMSharedVaultInviteRepository'),
|
||||
Sync_ORMSharedVaultUserRepository: Symbol.for('Sync_ORMSharedVaultUserRepository'),
|
||||
Sync_ORMNotificationRepository: Symbol.for('Sync_ORMNotificationRepository'),
|
||||
Sync_ORMMessageRepository: Symbol.for('Sync_ORMMessageRepository'),
|
||||
// Middleware
|
||||
Sync_AuthMiddleware: Symbol.for('Sync_AuthMiddleware'),
|
||||
// env vars
|
||||
@@ -30,6 +44,8 @@ const TYPES = {
|
||||
Sync_CONTENT_SIZE_TRANSFER_LIMIT: Symbol.for('Sync_CONTENT_SIZE_TRANSFER_LIMIT'),
|
||||
Sync_MAX_ITEMS_LIMIT: Symbol.for('Sync_MAX_ITEMS_LIMIT'),
|
||||
Sync_FILE_UPLOAD_PATH: Symbol.for('Sync_FILE_UPLOAD_PATH'),
|
||||
Sync_VALET_TOKEN_SECRET: Symbol.for('Sync_VALET_TOKEN_SECRET'),
|
||||
Sync_VALET_TOKEN_TTL: Symbol.for('Sync_VALET_TOKEN_TTL'),
|
||||
// use cases
|
||||
Sync_SyncItems: Symbol.for('Sync_SyncItems'),
|
||||
Sync_CheckIntegrity: Symbol.for('Sync_CheckIntegrity'),
|
||||
@@ -39,6 +55,8 @@ const TYPES = {
|
||||
Sync_DeleteSharedVault: Symbol.for('Sync_DeleteSharedVault'),
|
||||
Sync_CreateSharedVaultFileValetToken: Symbol.for('Sync_CreateSharedVaultFileValetToken'),
|
||||
Sync_GetSharedVaultUsers: Symbol.for('Sync_GetSharedVaultUsers'),
|
||||
Sync_AddUserToSharedVault: Symbol.for('Sync_AddUserToSharedVault'),
|
||||
Sync_AddNotificationForUser: Symbol.for('Sync_AddNotificationForUser'),
|
||||
Sync_RemoveSharedVaultUser: Symbol.for('Sync_RemoveSharedVaultUser'),
|
||||
Sync_InviteUserToSharedVault: Symbol.for('Sync_InviteUserToSharedVault'),
|
||||
Sync_UpdateSharedVaultInvite: Symbol.for('Sync_UpdateSharedVaultInvite'),
|
||||
@@ -57,6 +75,7 @@ const TYPES = {
|
||||
Sync_UpdateExistingItem: Symbol.for('Sync_UpdateExistingItem'),
|
||||
Sync_GetItems: Symbol.for('Sync_GetItems'),
|
||||
Sync_SaveItems: Symbol.for('Sync_SaveItems'),
|
||||
Sync_GetUserNotifications: Symbol.for('Sync_GetUserNotifications'),
|
||||
// Handlers
|
||||
Sync_AccountDeletionRequestedEventHandler: Symbol.for('Sync_AccountDeletionRequestedEventHandler'),
|
||||
Sync_DuplicateItemSyncedEventHandler: Symbol.for('Sync_DuplicateItemSyncedEventHandler'),
|
||||
@@ -70,6 +89,7 @@ const TYPES = {
|
||||
Sync_DomainEventMessageHandler: Symbol.for('Sync_DomainEventMessageHandler'),
|
||||
Sync_HTTPClient: Symbol.for('Sync_HTTPClient'),
|
||||
Sync_Timer: Symbol.for('Sync_Timer'),
|
||||
Sync_SharedVaultValetTokenEncoder: Symbol.for('Sync_SharedVaultValetTokenEncoder'),
|
||||
Sync_SyncResponseFactory20161215: Symbol.for('Sync_SyncResponseFactory20161215'),
|
||||
Sync_SyncResponseFactory20200115: Symbol.for('Sync_SyncResponseFactory20200115'),
|
||||
Sync_SyncResponseFactoryResolver: Symbol.for('Sync_SyncResponseFactoryResolver'),
|
||||
@@ -84,17 +104,29 @@ const TYPES = {
|
||||
Sync_ItemTransferCalculator: Symbol.for('Sync_ItemTransferCalculator'),
|
||||
Sync_ControllerContainer: Symbol.for('Sync_ControllerContainer'),
|
||||
Sync_HomeServerItemsController: Symbol.for('Sync_HomeServerItemsController'),
|
||||
Sync_HomeServerSharedVaultInvitesController: Symbol.for('Sync_HomeServerSharedVaultInvitesController'),
|
||||
Sync_HomeServerSharedVaultUsersController: Symbol.for('Sync_HomeServerSharedVaultUsersController'),
|
||||
Sync_HomeServerSharedVaultsController: Symbol.for('Sync_HomeServerSharedVaultsController'),
|
||||
Sync_HomeServerMessagesController: Symbol.for('Sync_HomeServerMessagesController'),
|
||||
// Mapping
|
||||
Sync_SharedVaultHttpMapper: Symbol.for('Sync_SharedVaultHttpMapper'),
|
||||
Sync_SharedVaultUserHttpMapper: Symbol.for('Sync_SharedVaultUserHttpMapper'),
|
||||
Sync_SharedVaultInviteHttpMapper: Symbol.for('Sync_SharedVaultInviteHttpMapper'),
|
||||
Sync_MessagePersistenceMapper: Symbol.for('Sync_MessagePersistenceMapper'),
|
||||
Sync_MessageHttpMapper: Symbol.for('Sync_MessageHttpMapper'),
|
||||
Sync_NotificationHttpMapper: Symbol.for('Sync_NotificationHttpMapper'),
|
||||
Sync_ItemPersistenceMapper: Symbol.for('Sync_ItemPersistenceMapper'),
|
||||
Sync_ItemHttpMapper: Symbol.for('Sync_ItemHttpMapper'),
|
||||
Sync_ItemHashHttpMapper: Symbol.for('Sync_ItemHashHttpMapper'),
|
||||
Sync_SavedItemHttpMapper: Symbol.for('Sync_SavedItemHttpMapper'),
|
||||
Sync_ItemConflictHttpMapper: Symbol.for('Sync_ItemConflictHttpMapper'),
|
||||
Sync_ItemBackupMapper: Symbol.for('Sync_ItemBackupMapper'),
|
||||
Sync_KeySystemAssociationPersistenceMapper: Symbol.for('Sync_KeySystemAssociationPersistenceMapper'),
|
||||
Sync_SharedVaultAssociationPersistenceMapper: Symbol.for('Sync_SharedVaultAssociationPersistenceMapper'),
|
||||
Sync_SharedVaultPersistenceMapper: Symbol.for('Sync_SharedVaultPersistenceMapper'),
|
||||
Sync_SharedVaultUserPersistenceMapper: Symbol.for('Sync_SharedVaultUserPersistenceMapper'),
|
||||
Sync_SharedVaultInvitePersistenceMapper: Symbol.for('Sync_SharedVaultInvitePersistenceMapper'),
|
||||
Sync_NotificationPersistenceMapper: Symbol.for('Sync_NotificationPersistenceMapper'),
|
||||
}
|
||||
|
||||
export default TYPES
|
||||
|
||||
@@ -53,7 +53,7 @@ describe('ItemRevisionCreationRequestedEventHandler', () => {
|
||||
event = {} as jest.Mocked<ItemRevisionCreationRequestedEvent>
|
||||
event.createdAt = new Date(1)
|
||||
event.payload = {
|
||||
itemUuid: '2-3-4',
|
||||
itemUuid: '00000000-0000-0000-0000-000000000000',
|
||||
}
|
||||
event.meta = {
|
||||
correlation: {
|
||||
@@ -96,4 +96,13 @@ describe('ItemRevisionCreationRequestedEventHandler', () => {
|
||||
expect(domainEventPublisher.publish).not.toHaveBeenCalled()
|
||||
expect(domainEventFactory.createItemDumpedEvent).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should not create a revision if the item uuid is invalid', async () => {
|
||||
event.payload.itemUuid = 'invalid-uuid'
|
||||
|
||||
await createHandler().handle(event)
|
||||
|
||||
expect(domainEventPublisher.publish).not.toHaveBeenCalled()
|
||||
expect(domainEventFactory.createItemDumpedEvent).not.toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
|
||||
@@ -3,6 +3,7 @@ import {
|
||||
DomainEventHandlerInterface,
|
||||
DomainEventPublisherInterface,
|
||||
} from '@standardnotes/domain-events'
|
||||
import { Uuid } from '@standardnotes/domain-core'
|
||||
|
||||
import { DomainEventFactoryInterface } from '../Event/DomainEventFactoryInterface'
|
||||
import { ItemBackupServiceInterface } from '../Item/ItemBackupServiceInterface'
|
||||
@@ -17,7 +18,13 @@ export class ItemRevisionCreationRequestedEventHandler implements DomainEventHan
|
||||
) {}
|
||||
|
||||
async handle(event: ItemRevisionCreationRequestedEvent): Promise<void> {
|
||||
const item = await this.itemRepository.findByUuid(event.payload.itemUuid)
|
||||
const itemUuidOrError = Uuid.create(event.payload.itemUuid)
|
||||
if (itemUuidOrError.isFailed()) {
|
||||
return
|
||||
}
|
||||
const itemUuid = itemUuidOrError.getValue()
|
||||
|
||||
const item = await this.itemRepository.findByUuid(itemUuid)
|
||||
if (item === null) {
|
||||
return
|
||||
}
|
||||
|
||||
47
packages/syncing-server/src/Domain/Item/Item.spec.ts
Normal file
47
packages/syncing-server/src/Domain/Item/Item.spec.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { ContentType, Dates, Timestamps, UniqueEntityId, Uuid } from '@standardnotes/domain-core'
|
||||
|
||||
import { Item } from './Item'
|
||||
|
||||
describe('Item', () => {
|
||||
it('should create an aggregate', () => {
|
||||
const entityOrError = Item.create({
|
||||
duplicateOf: null,
|
||||
itemsKeyId: 'items-key-id',
|
||||
content: 'content',
|
||||
contentType: ContentType.create(ContentType.TYPES.Note).getValue(),
|
||||
encItemKey: 'enc-item-key',
|
||||
authHash: 'auth-hash',
|
||||
userUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
|
||||
deleted: false,
|
||||
updatedWithSession: null,
|
||||
dates: Dates.create(new Date(123), new Date(123)).getValue(),
|
||||
timestamps: Timestamps.create(123, 123).getValue(),
|
||||
})
|
||||
|
||||
expect(entityOrError.isFailed()).toBeFalsy()
|
||||
expect(entityOrError.getValue().id).not.toBeNull()
|
||||
expect(entityOrError.getValue().uuid.value).toEqual(entityOrError.getValue().id.toString())
|
||||
})
|
||||
|
||||
it('should throw an error if id cannot be cast to uuid', () => {
|
||||
const entityOrError = Item.create(
|
||||
{
|
||||
duplicateOf: null,
|
||||
itemsKeyId: 'items-key-id',
|
||||
content: 'content',
|
||||
contentType: ContentType.create(ContentType.TYPES.Note).getValue(),
|
||||
encItemKey: 'enc-item-key',
|
||||
authHash: 'auth-hash',
|
||||
userUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
|
||||
deleted: false,
|
||||
updatedWithSession: null,
|
||||
dates: Dates.create(new Date(123), new Date(123)).getValue(),
|
||||
timestamps: Timestamps.create(123, 123).getValue(),
|
||||
},
|
||||
new UniqueEntityId(1),
|
||||
)
|
||||
|
||||
expect(entityOrError.isFailed()).toBeFalsy()
|
||||
expect(() => entityOrError.getValue().uuid).toThrow()
|
||||
})
|
||||
})
|
||||
@@ -1,8 +1,17 @@
|
||||
import { Entity, Result, UniqueEntityId } from '@standardnotes/domain-core'
|
||||
import { Aggregate, Result, UniqueEntityId, Uuid } from '@standardnotes/domain-core'
|
||||
|
||||
import { ItemProps } from './ItemProps'
|
||||
|
||||
export class Item extends Entity<ItemProps> {
|
||||
export class Item extends Aggregate<ItemProps> {
|
||||
get uuid(): Uuid {
|
||||
const uuidOrError = Uuid.create(this._id.toString())
|
||||
if (uuidOrError.isFailed()) {
|
||||
throw new Error(uuidOrError.getError())
|
||||
}
|
||||
|
||||
return uuidOrError.getValue()
|
||||
}
|
||||
|
||||
private constructor(props: ItemProps, id?: UniqueEntityId) {
|
||||
super(props, id)
|
||||
}
|
||||
|
||||
@@ -10,4 +10,12 @@ export class ItemHash extends ValueObject<ItemHashProps> {
|
||||
static create(props: ItemHashProps): Result<ItemHash> {
|
||||
return Result.ok<ItemHash>(new ItemHash(props))
|
||||
}
|
||||
|
||||
representsASharedVaultItem(): boolean {
|
||||
return this.props.shared_vault_uuid !== null
|
||||
}
|
||||
|
||||
hasDedicatedKeySystemAssociation(): boolean {
|
||||
return this.props.key_system_identifier !== null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import { ContentType, Dates, Timestamps, Uuid } from '@standardnotes/domain-core'
|
||||
|
||||
import { KeySystemAssociation } from '../KeySystem/KeySystemAssociation'
|
||||
import { SharedVaultAssociation } from '../SharedVault/SharedVaultAssociation'
|
||||
|
||||
export interface ItemProps {
|
||||
duplicateOf: Uuid | null
|
||||
itemsKeyId: string | null
|
||||
@@ -13,4 +16,6 @@ export interface ItemProps {
|
||||
dates: Dates
|
||||
timestamps: Timestamps
|
||||
contentSize?: number
|
||||
sharedVaultAssociation?: SharedVaultAssociation
|
||||
keySystemAssociation?: KeySystemAssociation
|
||||
}
|
||||
|
||||
@@ -11,4 +11,6 @@ export type ItemQuery = {
|
||||
limit?: number
|
||||
createdBetween?: Date[]
|
||||
selectString?: string
|
||||
includeSharedVaultUuids?: string[]
|
||||
exclusiveSharedVaultUuids?: string[]
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { Uuid } from '@standardnotes/domain-core'
|
||||
import { ReadStream } from 'fs'
|
||||
|
||||
import { Item } from './Item'
|
||||
import { ItemQuery } from './ItemQuery'
|
||||
import { ReadStream } from 'fs'
|
||||
import { ExtendedIntegrityPayload } from './ExtendedIntegrityPayload'
|
||||
|
||||
export interface ItemRepositoryInterface {
|
||||
@@ -15,7 +17,7 @@ export interface ItemRepositoryInterface {
|
||||
findDatesForComputingIntegrityHash(userUuid: string): Promise<Array<{ updated_at_timestamp: number }>>
|
||||
findItemsForComputingIntegrityPayloads(userUuid: string): Promise<ExtendedIntegrityPayload[]>
|
||||
findByUuidAndUserUuid(uuid: string, userUuid: string): Promise<Item | null>
|
||||
findByUuid(uuid: string): Promise<Item | null>
|
||||
findByUuid(uuid: Uuid): Promise<Item | null>
|
||||
remove(item: Item): Promise<void>
|
||||
save(item: Item): Promise<void>
|
||||
markItemsAsDeleted(itemUuids: Array<string>, updatedAtTimestamp: number): Promise<void>
|
||||
|
||||
@@ -1,11 +1,19 @@
|
||||
import { ItemConflictHttpRepresentation } from '../../../Mapping/Http/ItemConflictHttpRepresentation'
|
||||
import { ItemHttpRepresentation } from '../../../Mapping/Http/ItemHttpRepresentation'
|
||||
import { MessageHttpRepresentation } from '../../../Mapping/Http/MessageHttpRepresentation'
|
||||
import { NotificationHttpRepresentation } from '../../../Mapping/Http/NotificationHttpRepresentation'
|
||||
import { SavedItemHttpRepresentation } from '../../../Mapping/Http/SavedItemHttpRepresentation'
|
||||
import { SharedVaultHttpRepresentation } from '../../../Mapping/Http/SharedVaultHttpRepresentation'
|
||||
import { SharedVaultInviteHttpRepresentation } from '../../../Mapping/Http/SharedVaultInviteHttpRepresentation'
|
||||
|
||||
export type SyncResponse20200115 = {
|
||||
retrieved_items: Array<ItemHttpRepresentation>
|
||||
saved_items: Array<SavedItemHttpRepresentation>
|
||||
conflicts: Array<ItemConflictHttpRepresentation>
|
||||
retrieved_items: ItemHttpRepresentation[]
|
||||
saved_items: SavedItemHttpRepresentation[]
|
||||
conflicts: ItemConflictHttpRepresentation[]
|
||||
sync_token: string
|
||||
cursor_token?: string
|
||||
messages: MessageHttpRepresentation[]
|
||||
shared_vaults: SharedVaultHttpRepresentation[]
|
||||
shared_vault_invites: SharedVaultInviteHttpRepresentation[]
|
||||
notifications: NotificationHttpRepresentation[]
|
||||
}
|
||||
|
||||
@@ -88,6 +88,10 @@ describe('SyncResponseFactory20161215', () => {
|
||||
],
|
||||
syncToken: 'sync-test',
|
||||
cursorToken: 'cursor-test',
|
||||
sharedVaults: [],
|
||||
sharedVaultInvites: [],
|
||||
messages: [],
|
||||
notifications: [],
|
||||
}),
|
||||
).toEqual({
|
||||
retrieved_items: [item1Projection],
|
||||
@@ -133,6 +137,10 @@ describe('SyncResponseFactory20161215', () => {
|
||||
],
|
||||
syncToken: 'sync-test',
|
||||
cursorToken: 'cursor-test',
|
||||
sharedVaults: [],
|
||||
sharedVaultInvites: [],
|
||||
messages: [],
|
||||
notifications: [],
|
||||
}),
|
||||
).toEqual({
|
||||
retrieved_items: [],
|
||||
|
||||
@@ -8,6 +8,14 @@ import { SyncResponseFactory20200115 } from './SyncResponseFactory20200115'
|
||||
import { ItemHttpRepresentation } from '../../../Mapping/Http/ItemHttpRepresentation'
|
||||
import { SavedItemHttpRepresentation } from '../../../Mapping/Http/SavedItemHttpRepresentation'
|
||||
import { ItemConflictHttpRepresentation } from '../../../Mapping/Http/ItemConflictHttpRepresentation'
|
||||
import { MessageHttpRepresentation } from '../../../Mapping/Http/MessageHttpRepresentation'
|
||||
import { NotificationHttpRepresentation } from '../../../Mapping/Http/NotificationHttpRepresentation'
|
||||
import { Notification } from '../../Notifications/Notification'
|
||||
import { SharedVaultHttpRepresentation } from '../../../Mapping/Http/SharedVaultHttpRepresentation'
|
||||
import { SharedVaultInviteHttpRepresentation } from '../../../Mapping/Http/SharedVaultInviteHttpRepresentation'
|
||||
import { Message } from '../../Message/Message'
|
||||
import { SharedVault } from '../../SharedVault/SharedVault'
|
||||
import { SharedVaultInvite } from '../../SharedVault/User/Invite/SharedVaultInvite'
|
||||
|
||||
describe('SyncResponseFactory20200115', () => {
|
||||
let itemMapper: MapperInterface<Item, ItemHttpRepresentation>
|
||||
@@ -19,8 +27,25 @@ describe('SyncResponseFactory20200115', () => {
|
||||
let item1: Item
|
||||
let item2: Item
|
||||
let itemConflict: ItemConflict
|
||||
let sharedVault: SharedVault
|
||||
let sharedVaultInvite: SharedVaultInvite
|
||||
let message: Message
|
||||
let notification: Notification
|
||||
let sharedVaultMapper: MapperInterface<SharedVault, SharedVaultHttpRepresentation>
|
||||
let sharedVaultInvitesMapper: MapperInterface<SharedVaultInvite, SharedVaultInviteHttpRepresentation>
|
||||
let messageMapper: MapperInterface<Message, MessageHttpRepresentation>
|
||||
let notificationMapper: MapperInterface<Notification, NotificationHttpRepresentation>
|
||||
|
||||
const createFactory = () => new SyncResponseFactory20200115(itemMapper, itemConflictMapper, savedItemMapper)
|
||||
const createFactory = () =>
|
||||
new SyncResponseFactory20200115(
|
||||
itemMapper,
|
||||
itemConflictMapper,
|
||||
savedItemMapper,
|
||||
sharedVaultMapper,
|
||||
sharedVaultInvitesMapper,
|
||||
messageMapper,
|
||||
notificationMapper,
|
||||
)
|
||||
|
||||
beforeEach(() => {
|
||||
itemProjection = {
|
||||
@@ -45,6 +70,27 @@ describe('SyncResponseFactory20200115', () => {
|
||||
item2 = {} as jest.Mocked<Item>
|
||||
|
||||
itemConflict = {} as jest.Mocked<ItemConflict>
|
||||
|
||||
sharedVaultMapper = {} as jest.Mocked<MapperInterface<SharedVault, SharedVaultHttpRepresentation>>
|
||||
sharedVaultMapper.toProjection = jest.fn().mockReturnValue({} as jest.Mocked<SharedVaultHttpRepresentation>)
|
||||
|
||||
sharedVaultInvitesMapper = {} as jest.Mocked<
|
||||
MapperInterface<SharedVaultInvite, SharedVaultInviteHttpRepresentation>
|
||||
>
|
||||
sharedVaultInvitesMapper.toProjection = jest
|
||||
.fn()
|
||||
.mockReturnValue({} as jest.Mocked<SharedVaultInviteHttpRepresentation>)
|
||||
|
||||
messageMapper = {} as jest.Mocked<MapperInterface<Message, MessageHttpRepresentation>>
|
||||
messageMapper.toProjection = jest.fn().mockReturnValue({} as jest.Mocked<MessageHttpRepresentation>)
|
||||
|
||||
notificationMapper = {} as jest.Mocked<MapperInterface<Notification, NotificationHttpRepresentation>>
|
||||
notificationMapper.toProjection = jest.fn().mockReturnValue({} as jest.Mocked<NotificationHttpRepresentation>)
|
||||
|
||||
sharedVault = {} as jest.Mocked<SharedVault>
|
||||
sharedVaultInvite = {} as jest.Mocked<SharedVaultInvite>
|
||||
message = {} as jest.Mocked<Message>
|
||||
notification = {} as jest.Mocked<Notification>
|
||||
})
|
||||
|
||||
it('should turn sync items response into a sync response for API Version 20200115', async () => {
|
||||
@@ -55,6 +101,10 @@ describe('SyncResponseFactory20200115', () => {
|
||||
conflicts: [itemConflict],
|
||||
syncToken: 'sync-test',
|
||||
cursorToken: 'cursor-test',
|
||||
sharedVaults: [sharedVault],
|
||||
sharedVaultInvites: [sharedVaultInvite],
|
||||
messages: [message],
|
||||
notifications: [notification],
|
||||
}),
|
||||
).toEqual({
|
||||
retrieved_items: [itemProjection],
|
||||
@@ -62,6 +112,10 @@ describe('SyncResponseFactory20200115', () => {
|
||||
conflicts: [itemConflictProjection],
|
||||
sync_token: 'sync-test',
|
||||
cursor_token: 'cursor-test',
|
||||
shared_vaults: [{} as jest.Mocked<SharedVaultHttpRepresentation>],
|
||||
shared_vault_invites: [{} as jest.Mocked<SharedVaultInviteHttpRepresentation>],
|
||||
messages: [{} as jest.Mocked<MessageHttpRepresentation>],
|
||||
notifications: [{} as jest.Mocked<NotificationHttpRepresentation>],
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -8,12 +8,24 @@ import { SyncItemsResponse } from '../../UseCase/Syncing/SyncItems/SyncItemsResp
|
||||
import { ItemHttpRepresentation } from '../../../Mapping/Http/ItemHttpRepresentation'
|
||||
import { ItemConflictHttpRepresentation } from '../../../Mapping/Http/ItemConflictHttpRepresentation'
|
||||
import { SavedItemHttpRepresentation } from '../../../Mapping/Http/SavedItemHttpRepresentation'
|
||||
import { SharedVault } from '../../SharedVault/SharedVault'
|
||||
import { SharedVaultHttpRepresentation } from '../../../Mapping/Http/SharedVaultHttpRepresentation'
|
||||
import { SharedVaultInvite } from '../../SharedVault/User/Invite/SharedVaultInvite'
|
||||
import { SharedVaultInviteHttpRepresentation } from '../../../Mapping/Http/SharedVaultInviteHttpRepresentation'
|
||||
import { Message } from '../../Message/Message'
|
||||
import { MessageHttpRepresentation } from '../../../Mapping/Http/MessageHttpRepresentation'
|
||||
import { Notification } from '../../Notifications/Notification'
|
||||
import { NotificationHttpRepresentation } from '../../../Mapping/Http/NotificationHttpRepresentation'
|
||||
|
||||
export class SyncResponseFactory20200115 implements SyncResponseFactoryInterface {
|
||||
constructor(
|
||||
private httpMapper: MapperInterface<Item, ItemHttpRepresentation>,
|
||||
private itemConflictMapper: MapperInterface<ItemConflict, ItemConflictHttpRepresentation>,
|
||||
private savedItemMapper: MapperInterface<Item, SavedItemHttpRepresentation>,
|
||||
private sharedVaultMapper: MapperInterface<SharedVault, SharedVaultHttpRepresentation>,
|
||||
private sharedVaultInvitesMapper: MapperInterface<SharedVaultInvite, SharedVaultInviteHttpRepresentation>,
|
||||
private messageMapper: MapperInterface<Message, MessageHttpRepresentation>,
|
||||
private notificationMapper: MapperInterface<Notification, NotificationHttpRepresentation>,
|
||||
) {}
|
||||
|
||||
async createResponse(syncItemsResponse: SyncItemsResponse): Promise<SyncResponse20200115> {
|
||||
@@ -32,12 +44,36 @@ export class SyncResponseFactory20200115 implements SyncResponseFactoryInterface
|
||||
conflicts.push(this.itemConflictMapper.toProjection(itemConflict))
|
||||
}
|
||||
|
||||
const sharedVaults = []
|
||||
for (const sharedVault of syncItemsResponse.sharedVaults) {
|
||||
sharedVaults.push(this.sharedVaultMapper.toProjection(sharedVault))
|
||||
}
|
||||
|
||||
const sharedVaultInvites = []
|
||||
for (const sharedVaultInvite of syncItemsResponse.sharedVaultInvites) {
|
||||
sharedVaultInvites.push(this.sharedVaultInvitesMapper.toProjection(sharedVaultInvite))
|
||||
}
|
||||
|
||||
const messages = []
|
||||
for (const contact of syncItemsResponse.messages) {
|
||||
messages.push(this.messageMapper.toProjection(contact))
|
||||
}
|
||||
|
||||
const notifications = []
|
||||
for (const notification of syncItemsResponse.notifications) {
|
||||
notifications.push(this.notificationMapper.toProjection(notification))
|
||||
}
|
||||
|
||||
return {
|
||||
retrieved_items: retrievedItems,
|
||||
saved_items: savedItems,
|
||||
conflicts,
|
||||
sync_token: syncItemsResponse.syncToken,
|
||||
cursor_token: syncItemsResponse.cursorToken,
|
||||
messages,
|
||||
shared_vaults: sharedVaults,
|
||||
shared_vault_invites: sharedVaultInvites,
|
||||
notifications,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import { Timestamps, Uuid } from '@standardnotes/domain-core'
|
||||
|
||||
export interface KeySystemAssociationProps {
|
||||
itemUuid: Uuid
|
||||
keySystemIdentifier: string
|
||||
timestamps: Timestamps
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { Timestamps, Uuid } from '@standardnotes/domain-core'
|
||||
|
||||
import { KeySystemAssociation } from './KeySystemAssociation'
|
||||
|
||||
describe('KeySystemAssociation', () => {
|
||||
it('should create an entity', () => {
|
||||
const entityOrError = KeySystemAssociation.create({
|
||||
timestamps: Timestamps.create(123456789, 123456789).getValue(),
|
||||
itemUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
|
||||
keySystemIdentifier: '00000000-0000-0000-0000-000000000000',
|
||||
})
|
||||
|
||||
expect(entityOrError.isFailed()).toBeFalsy()
|
||||
expect(entityOrError.getValue().id).not.toBeNull()
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,13 @@
|
||||
import { Entity, Result, UniqueEntityId } from '@standardnotes/domain-core'
|
||||
|
||||
import { KeySystemAssociationProps } from './KeySystemAssocationProps'
|
||||
|
||||
export class KeySystemAssociation extends Entity<KeySystemAssociationProps> {
|
||||
private constructor(props: KeySystemAssociationProps, id?: UniqueEntityId) {
|
||||
super(props, id)
|
||||
}
|
||||
|
||||
static create(props: KeySystemAssociationProps, id?: UniqueEntityId): Result<KeySystemAssociation> {
|
||||
return Result.ok<KeySystemAssociation>(new KeySystemAssociation(props, id))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import { Uuid } from '@standardnotes/domain-core'
|
||||
|
||||
import { KeySystemAssociation } from './KeySystemAssociation'
|
||||
|
||||
export interface KeySystemAssociationRepositoryInterface {
|
||||
save(keySystem: KeySystemAssociation): Promise<void>
|
||||
remove(keySystem: KeySystemAssociation): Promise<void>
|
||||
findByItemUuid(itemUuid: Uuid): Promise<KeySystemAssociation | null>
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import { Message } from './Message'
|
||||
export interface MessageRepositoryInterface {
|
||||
findByUuid: (uuid: Uuid) => Promise<Message | null>
|
||||
findByRecipientUuid: (uuid: Uuid) => Promise<Message[]>
|
||||
findByRecipientUuidUpdatedAfter: (uuid: Uuid, updatedAtTimestamp: number) => Promise<Message[]>
|
||||
findBySenderUuid: (uuid: Uuid) => Promise<Message[]>
|
||||
findByRecipientUuidAndReplaceabilityIdentifier: (dto: {
|
||||
recipientUuid: Uuid
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
import { Timestamps, Uuid } from '@standardnotes/domain-core'
|
||||
import { NotificationPayload, NotificationType, Timestamps, Uuid } from '@standardnotes/domain-core'
|
||||
|
||||
import { Notification } from './Notification'
|
||||
import { NotificationType } from './NotificationType'
|
||||
|
||||
describe('Notification', () => {
|
||||
it('should create an entity', () => {
|
||||
const payload = NotificationPayload.create({
|
||||
sharedVaultUuid: Uuid.create('0e8c3c7e-3f1a-4f7a-9b5a-5b2b0a7d4b1e').getValue(),
|
||||
type: NotificationType.create(NotificationType.TYPES.RemovedFromSharedVault).getValue(),
|
||||
version: '1.0',
|
||||
}).getValue()
|
||||
|
||||
const entityOrError = Notification.create({
|
||||
timestamps: Timestamps.create(123456789, 123456789).getValue(),
|
||||
userUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
|
||||
payload: 'payload',
|
||||
payload,
|
||||
type: NotificationType.create(NotificationType.TYPES.SharedVaultItemRemoved).getValue(),
|
||||
})
|
||||
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
import { Timestamps, Uuid } from '@standardnotes/domain-core'
|
||||
|
||||
import { NotificationType } from './NotificationType'
|
||||
import { NotificationPayload, NotificationType, Timestamps, Uuid } from '@standardnotes/domain-core'
|
||||
|
||||
export interface NotificationProps {
|
||||
userUuid: Uuid
|
||||
type: NotificationType
|
||||
payload: string
|
||||
payload: NotificationPayload
|
||||
timestamps: Timestamps
|
||||
}
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import { Uuid } from '@standardnotes/domain-core'
|
||||
|
||||
import { Notification } from './Notification'
|
||||
|
||||
export interface NotificationRepositoryInterface {
|
||||
save(notification: Notification): Promise<void>
|
||||
findByUserUuidUpdatedAfter(userUuid: Uuid, lastSyncTime: number): Promise<Notification[]>
|
||||
findByUserUuid(userUuid: Uuid): Promise<Notification[]>
|
||||
}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
import { Timestamps, UniqueEntityId, Uuid } from '@standardnotes/domain-core'
|
||||
|
||||
import { SharedVaultItem } from './SharedVaultItem'
|
||||
|
||||
describe('SharedVaultItem', () => {
|
||||
it('should create an entity', () => {
|
||||
const entityOrError = SharedVaultItem.create({
|
||||
itemId: new UniqueEntityId('00000000-0000-0000-0000-000000000000'),
|
||||
sharedVaultId: new UniqueEntityId('00000000-0000-0000-0000-000000000000'),
|
||||
keySystemIdentifier: 'key-system-identifier',
|
||||
lastEditedBy: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
|
||||
timestamps: Timestamps.create(123456789, 123456789).getValue(),
|
||||
})
|
||||
|
||||
expect(entityOrError.isFailed()).toBeFalsy()
|
||||
expect(entityOrError.getValue().id).not.toBeNull()
|
||||
})
|
||||
})
|
||||
@@ -1,13 +0,0 @@
|
||||
import { Entity, Result, UniqueEntityId } from '@standardnotes/domain-core'
|
||||
|
||||
import { SharedVaultItemProps } from './SharedVaultItemProps'
|
||||
|
||||
export class SharedVaultItem extends Entity<SharedVaultItemProps> {
|
||||
private constructor(props: SharedVaultItemProps, id?: UniqueEntityId) {
|
||||
super(props, id)
|
||||
}
|
||||
|
||||
static create(props: SharedVaultItemProps, id?: UniqueEntityId): Result<SharedVaultItem> {
|
||||
return Result.ok<SharedVaultItem>(new SharedVaultItem(props, id))
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
import { Timestamps, UniqueEntityId, Uuid } from '@standardnotes/domain-core'
|
||||
|
||||
export interface SharedVaultItemProps {
|
||||
sharedVaultId: UniqueEntityId
|
||||
itemId: UniqueEntityId
|
||||
keySystemIdentifier: string
|
||||
lastEditedBy: Uuid
|
||||
timestamps: Timestamps
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
import { UniqueEntityId } from '@standardnotes/domain-core'
|
||||
|
||||
import { SharedVaultItem } from './SharedVaultItem'
|
||||
|
||||
export interface SharedVaultItemRepositoryInterface {
|
||||
save(sharedVaultItem: SharedVaultItem): Promise<void>
|
||||
findBySharedVaultId(sharedVaultId: UniqueEntityId): Promise<SharedVaultItem[]>
|
||||
}
|
||||
@@ -1,18 +1,33 @@
|
||||
import { Timestamps, Uuid } from '@standardnotes/domain-core'
|
||||
import { Timestamps, UniqueEntityId, Uuid } from '@standardnotes/domain-core'
|
||||
|
||||
import { SharedVault } from './SharedVault'
|
||||
|
||||
describe('SharedVault', () => {
|
||||
it('should create an aggregate', () => {
|
||||
it('should create an entity', () => {
|
||||
const entityOrError = SharedVault.create({
|
||||
fileUploadBytesLimit: 1_000_000,
|
||||
fileUploadBytesUsed: 0,
|
||||
timestamps: Timestamps.create(123456789, 123456789).getValue(),
|
||||
userUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
|
||||
sharedVaultItems: [],
|
||||
})
|
||||
|
||||
expect(entityOrError.isFailed()).toBeFalsy()
|
||||
expect(entityOrError.getValue().id).not.toBeNull()
|
||||
expect(entityOrError.getValue().uuid.value).toEqual(entityOrError.getValue().id.toString())
|
||||
})
|
||||
|
||||
it('should throw an error if id cannot be cast to uuid', () => {
|
||||
const entityOrError = SharedVault.create(
|
||||
{
|
||||
fileUploadBytesLimit: 1_000_000,
|
||||
fileUploadBytesUsed: 0,
|
||||
timestamps: Timestamps.create(123456789, 123456789).getValue(),
|
||||
userUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
|
||||
},
|
||||
new UniqueEntityId(1),
|
||||
)
|
||||
|
||||
expect(entityOrError.isFailed()).toBeFalsy()
|
||||
expect(() => entityOrError.getValue().uuid).toThrow()
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,12 +1,21 @@
|
||||
import { Aggregate, Result, UniqueEntityId } from '@standardnotes/domain-core'
|
||||
import { Entity, Result, UniqueEntityId, Uuid } from '@standardnotes/domain-core'
|
||||
|
||||
import { SharedVaultProps } from './SharedVaultProps'
|
||||
|
||||
export class SharedVault extends Aggregate<SharedVaultProps> {
|
||||
export class SharedVault extends Entity<SharedVaultProps> {
|
||||
private constructor(props: SharedVaultProps, id?: UniqueEntityId) {
|
||||
super(props, id)
|
||||
}
|
||||
|
||||
get uuid(): Uuid {
|
||||
const uuidOrError = Uuid.create(this._id.toString())
|
||||
if (uuidOrError.isFailed()) {
|
||||
throw new Error(uuidOrError.getError())
|
||||
}
|
||||
|
||||
return uuidOrError.getValue()
|
||||
}
|
||||
|
||||
static create(props: SharedVaultProps, id?: UniqueEntityId): Result<SharedVault> {
|
||||
return Result.ok<SharedVault>(new SharedVault(props, id))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import { Timestamps, Uuid } from '@standardnotes/domain-core'
|
||||
|
||||
import { SharedVaultAssociation } from './SharedVaultAssociation'
|
||||
|
||||
describe('SharedVaultAssociation', () => {
|
||||
it('should create an entity', () => {
|
||||
const entityOrError = SharedVaultAssociation.create({
|
||||
timestamps: Timestamps.create(123456789, 123456789).getValue(),
|
||||
itemUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
|
||||
lastEditedBy: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
|
||||
sharedVaultUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
|
||||
})
|
||||
|
||||
expect(entityOrError.isFailed()).toBeFalsy()
|
||||
expect(entityOrError.getValue().id).not.toBeNull()
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,13 @@
|
||||
import { Aggregate, Result, UniqueEntityId } from '@standardnotes/domain-core'
|
||||
|
||||
import { SharedVaultAssociationProps } from './SharedVaultAssociationProps'
|
||||
|
||||
export class SharedVaultAssociation extends Aggregate<SharedVaultAssociationProps> {
|
||||
private constructor(props: SharedVaultAssociationProps, id?: UniqueEntityId) {
|
||||
super(props, id)
|
||||
}
|
||||
|
||||
static create(props: SharedVaultAssociationProps, id?: UniqueEntityId): Result<SharedVaultAssociation> {
|
||||
return Result.ok<SharedVaultAssociation>(new SharedVaultAssociation(props, id))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import { Timestamps, Uuid } from '@standardnotes/domain-core'
|
||||
|
||||
export interface SharedVaultAssociationProps {
|
||||
lastEditedBy: Uuid
|
||||
sharedVaultUuid: Uuid
|
||||
itemUuid: Uuid
|
||||
timestamps: Timestamps
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import { Uuid } from '@standardnotes/domain-core'
|
||||
|
||||
import { SharedVaultAssociation } from './SharedVaultAssociation'
|
||||
|
||||
export interface SharedVaultAssociationRepositoryInterface {
|
||||
save(sharedVaultAssociation: SharedVaultAssociation): Promise<void>
|
||||
remove(sharedVaultAssociation: SharedVaultAssociation): Promise<void>
|
||||
findByItemUuid(itemUuid: Uuid): Promise<SharedVaultAssociation | null>
|
||||
}
|
||||
@@ -1,11 +1,8 @@
|
||||
import { Uuid, Timestamps } from '@standardnotes/domain-core'
|
||||
|
||||
import { SharedVaultItem } from './Item/SharedVaultItem'
|
||||
|
||||
export interface SharedVaultProps {
|
||||
userUuid: Uuid
|
||||
fileUploadBytesUsed: number
|
||||
fileUploadBytesLimit: number
|
||||
timestamps: Timestamps
|
||||
sharedVaultItems: SharedVaultItem[]
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ export interface SharedVaultInviteRepositoryInterface {
|
||||
remove(sharedVaultInvite: SharedVaultInvite): Promise<void>
|
||||
removeBySharedVaultUuid(sharedVaultUuid: Uuid): Promise<void>
|
||||
findByUserUuid(userUuid: Uuid): Promise<SharedVaultInvite[]>
|
||||
findByUserUuidUpdatedAfter(userUuid: Uuid, updatedAtTimestamp: number): Promise<SharedVaultInvite[]>
|
||||
findBySenderUuid(senderUuid: Uuid): Promise<SharedVaultInvite[]>
|
||||
findByUserUuidAndSharedVaultUuid(dto: { userUuid: Uuid; sharedVaultUuid: Uuid }): Promise<SharedVaultInvite | null>
|
||||
findBySenderUuidAndSharedVaultUuid(dto: { senderUuid: Uuid; sharedVaultUuid: Uuid }): Promise<SharedVaultInvite[]>
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import { TimerInterface } from '@standardnotes/time'
|
||||
import { Result } from '@standardnotes/domain-core'
|
||||
import { NotificationPayload, NotificationType, Result, Uuid } from '@standardnotes/domain-core'
|
||||
|
||||
import { NotificationRepositoryInterface } from '../../../Notifications/NotificationRepositoryInterface'
|
||||
import { Notification } from '../../../Notifications/Notification'
|
||||
import { AddNotificationForUser } from './AddNotificationForUser'
|
||||
import { NotificationType } from '../../../Notifications/NotificationType'
|
||||
|
||||
describe('AddNotificationForUser', () => {
|
||||
let notificationRepository: NotificationRepositoryInterface
|
||||
let timer: TimerInterface
|
||||
let payload: NotificationPayload
|
||||
|
||||
const createUseCase = () => new AddNotificationForUser(notificationRepository, timer)
|
||||
|
||||
@@ -18,6 +18,12 @@ describe('AddNotificationForUser', () => {
|
||||
|
||||
timer = {} as jest.Mocked<TimerInterface>
|
||||
timer.getTimestampInMicroseconds = jest.fn().mockReturnValue(123456789)
|
||||
|
||||
payload = NotificationPayload.create({
|
||||
sharedVaultUuid: Uuid.create('0e8c3c7e-3f1a-4f7a-9b5a-5b2b0a7d4b1e').getValue(),
|
||||
type: NotificationType.create(NotificationType.TYPES.RemovedFromSharedVault).getValue(),
|
||||
version: '1.0',
|
||||
}).getValue()
|
||||
})
|
||||
|
||||
it('should save notification', async () => {
|
||||
@@ -26,7 +32,7 @@ describe('AddNotificationForUser', () => {
|
||||
const result = await useCase.execute({
|
||||
userUuid: '0e8c3c7e-3f1a-4f7a-9b5a-5b2b0a7d4b1e',
|
||||
type: NotificationType.TYPES.RemovedFromSharedVault,
|
||||
payload: 'payload',
|
||||
payload,
|
||||
version: '1.0',
|
||||
})
|
||||
|
||||
@@ -39,7 +45,7 @@ describe('AddNotificationForUser', () => {
|
||||
const result = await useCase.execute({
|
||||
userUuid: 'invalid',
|
||||
type: NotificationType.TYPES.RemovedFromSharedVault,
|
||||
payload: 'payload',
|
||||
payload,
|
||||
version: '1.0',
|
||||
})
|
||||
|
||||
@@ -52,20 +58,7 @@ describe('AddNotificationForUser', () => {
|
||||
const result = await useCase.execute({
|
||||
userUuid: '0e8c3c7e-3f1a-4f7a-9b5a-5b2b0a7d4b1e',
|
||||
type: 'invalid',
|
||||
payload: 'payload',
|
||||
version: '1.0',
|
||||
})
|
||||
|
||||
expect(result.isFailed()).toBeTruthy()
|
||||
})
|
||||
|
||||
it('should return error if notification payload is invalid', async () => {
|
||||
const useCase = createUseCase()
|
||||
|
||||
const result = await useCase.execute({
|
||||
userUuid: '0e8c3c7e-3f1a-4f7a-9b5a-5b2b0a7d4b1e',
|
||||
type: NotificationType.TYPES.RemovedFromSharedVault,
|
||||
payload: '',
|
||||
payload,
|
||||
version: '1.0',
|
||||
})
|
||||
|
||||
@@ -83,7 +76,7 @@ describe('AddNotificationForUser', () => {
|
||||
const result = await useCase.execute({
|
||||
userUuid: '0e8c3c7e-3f1a-4f7a-9b5a-5b2b0a7d4b1e',
|
||||
type: NotificationType.TYPES.RemovedFromSharedVault,
|
||||
payload: 'payload',
|
||||
payload,
|
||||
version: '1.0',
|
||||
})
|
||||
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import { Result, Timestamps, UseCaseInterface, Uuid, Validator } from '@standardnotes/domain-core'
|
||||
import { NotificationType, Result, Timestamps, UseCaseInterface, Uuid } from '@standardnotes/domain-core'
|
||||
import { TimerInterface } from '@standardnotes/time'
|
||||
|
||||
import { AddNotificationForUserDTO } from './AddNotificationForUserDTO'
|
||||
import { NotificationRepositoryInterface } from '../../../Notifications/NotificationRepositoryInterface'
|
||||
import { Notification } from '../../../Notifications/Notification'
|
||||
import { NotificationType } from '../../../Notifications/NotificationType'
|
||||
|
||||
export class AddNotificationForUser implements UseCaseInterface<Notification> {
|
||||
constructor(private notificationRepository: NotificationRepositoryInterface, private timer: TimerInterface) {}
|
||||
@@ -22,11 +21,6 @@ export class AddNotificationForUser implements UseCaseInterface<Notification> {
|
||||
}
|
||||
const type = typeOrError.getValue()
|
||||
|
||||
const paylodNotEmptyValidationResult = Validator.isNotEmpty(dto.payload)
|
||||
if (paylodNotEmptyValidationResult.isFailed()) {
|
||||
return Result.fail(paylodNotEmptyValidationResult.getError())
|
||||
}
|
||||
|
||||
const notificationOrError = Notification.create({
|
||||
userUuid,
|
||||
type,
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { NotificationPayload } from '@standardnotes/domain-core'
|
||||
|
||||
export interface AddNotificationForUserDTO {
|
||||
version: string
|
||||
type: string
|
||||
userUuid: string
|
||||
payload: string
|
||||
payload: NotificationPayload
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ describe('GetMessagesSentToUser', () => {
|
||||
beforeEach(() => {
|
||||
messageRepository = {} as jest.Mocked<MessageRepositoryInterface>
|
||||
messageRepository.findByRecipientUuid = jest.fn().mockReturnValue([])
|
||||
messageRepository.findByRecipientUuidUpdatedAfter = jest.fn().mockReturnValue([])
|
||||
})
|
||||
|
||||
it('should return messages sent to user', async () => {
|
||||
@@ -20,6 +21,16 @@ describe('GetMessagesSentToUser', () => {
|
||||
expect(result.getValue()).toEqual([])
|
||||
})
|
||||
|
||||
it('should return messages sent to user updated after given time', async () => {
|
||||
const useCase = createUseCase()
|
||||
const result = await useCase.execute({
|
||||
recipientUuid: '00000000-0000-0000-0000-000000000000',
|
||||
lastSyncTime: 123,
|
||||
})
|
||||
|
||||
expect(result.getValue()).toEqual([])
|
||||
})
|
||||
|
||||
it('should return error when recipient uuid is invalid', async () => {
|
||||
const useCase = createUseCase()
|
||||
const result = await useCase.execute({
|
||||
|
||||
@@ -14,8 +14,10 @@ export class GetMessagesSentToUser implements UseCaseInterface<Message[]> {
|
||||
}
|
||||
const recipientUuid = recipientUuidOrError.getValue()
|
||||
|
||||
const messages = await this.messageRepository.findByRecipientUuid(recipientUuid)
|
||||
if (dto.lastSyncTime) {
|
||||
return Result.ok(await this.messageRepository.findByRecipientUuidUpdatedAfter(recipientUuid, dto.lastSyncTime))
|
||||
}
|
||||
|
||||
return Result.ok(messages)
|
||||
return Result.ok(await this.messageRepository.findByRecipientUuid(recipientUuid))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
export interface GetMessagesSentToUserDTO {
|
||||
recipientUuid: string
|
||||
lastSyncTime?: number
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
import { NotificationRepositoryInterface } from '../../../Notifications/NotificationRepositoryInterface'
|
||||
import { GetUserNotifications } from './GetUserNotifications'
|
||||
|
||||
describe('GetUserNotifications', () => {
|
||||
let notificationRepository: NotificationRepositoryInterface
|
||||
|
||||
const createUseCase = () => new GetUserNotifications(notificationRepository)
|
||||
|
||||
beforeEach(() => {
|
||||
notificationRepository = {} as jest.Mocked<NotificationRepositoryInterface>
|
||||
notificationRepository.findByUserUuid = jest.fn().mockReturnValue([])
|
||||
notificationRepository.findByUserUuidUpdatedAfter = jest.fn().mockReturnValue([])
|
||||
})
|
||||
|
||||
it('should return notification for user', async () => {
|
||||
const useCase = createUseCase()
|
||||
const result = await useCase.execute({
|
||||
userUuid: '00000000-0000-0000-0000-000000000000',
|
||||
})
|
||||
|
||||
expect(result.getValue()).toEqual([])
|
||||
})
|
||||
|
||||
it('should return notifications for user updated after given time', async () => {
|
||||
const useCase = createUseCase()
|
||||
const result = await useCase.execute({
|
||||
userUuid: '00000000-0000-0000-0000-000000000000',
|
||||
lastSyncTime: 123,
|
||||
})
|
||||
|
||||
expect(result.getValue()).toEqual([])
|
||||
})
|
||||
|
||||
it('should return error when user uuid is invalid', async () => {
|
||||
const useCase = createUseCase()
|
||||
const result = await useCase.execute({
|
||||
userUuid: 'invalid',
|
||||
})
|
||||
|
||||
expect(result.isFailed()).toBe(true)
|
||||
expect(result.getError()).toBe('Given value is not a valid uuid: invalid')
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,22 @@
|
||||
import { Result, UseCaseInterface, Uuid } from '@standardnotes/domain-core'
|
||||
import { Notification } from '../../../Notifications/Notification'
|
||||
import { GetUserNotificationsDTO } from './GetUserNotificationsDTO'
|
||||
import { NotificationRepositoryInterface } from '../../../Notifications/NotificationRepositoryInterface'
|
||||
|
||||
export class GetUserNotifications implements UseCaseInterface<Notification[]> {
|
||||
constructor(private notificationRepository: NotificationRepositoryInterface) {}
|
||||
|
||||
async execute(dto: GetUserNotificationsDTO): Promise<Result<Notification[]>> {
|
||||
const userUuidOrError = Uuid.create(dto.userUuid)
|
||||
if (userUuidOrError.isFailed()) {
|
||||
return Result.fail(userUuidOrError.getError())
|
||||
}
|
||||
const userUuid = userUuidOrError.getValue()
|
||||
|
||||
if (dto.lastSyncTime) {
|
||||
return Result.ok(await this.notificationRepository.findByUserUuidUpdatedAfter(userUuid, dto.lastSyncTime))
|
||||
}
|
||||
|
||||
return Result.ok(await this.notificationRepository.findByUserUuid(userUuid))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export interface GetUserNotificationsDTO {
|
||||
userUuid: string
|
||||
lastSyncTime?: number
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user