diff --git a/packages/api-gateway/bin/server.ts b/packages/api-gateway/bin/server.ts index 831cf6d99..934dd4e26 100644 --- a/packages/api-gateway/bin/server.ts +++ b/packages/api-gateway/bin/server.ts @@ -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' diff --git a/packages/api-gateway/src/Controller/index.ts b/packages/api-gateway/src/Controller/index.ts index 052de10df..a82e514f2 100644 --- a/packages/api-gateway/src/Controller/index.ts +++ b/packages/api-gateway/src/Controller/index.ts @@ -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' diff --git a/packages/api-gateway/src/Controller/v1/AsymmetricMessagesController.ts b/packages/api-gateway/src/Controller/v1/AsymmetricMessagesController.ts deleted file mode 100644 index 27747355d..000000000 --- a/packages/api-gateway/src/Controller/v1/AsymmetricMessagesController.ts +++ /dev/null @@ -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 { - await this.serviceProxy.callSyncingServer(request, response, request.path.replace('/v1/', ''), request.body) - } -} diff --git a/packages/api-gateway/src/Controller/v1/MessagesController.ts b/packages/api-gateway/src/Controller/v1/MessagesController.ts new file mode 100644 index 000000000..292d23887 --- /dev/null +++ b/packages/api-gateway/src/Controller/v1/MessagesController.ts @@ -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 { + await this.httpService.callSyncingServer( + request, + response, + this.endpointResolver.resolveEndpointOrMethodIdentifier('GET', 'messages/'), + request.body, + ) + } + + @httpGet('/outbound') + async getMessagesSent(request: Request, response: Response): Promise { + await this.httpService.callSyncingServer( + request, + response, + this.endpointResolver.resolveEndpointOrMethodIdentifier('GET', 'messages/outbound'), + request.body, + ) + } + + @httpPost('/') + async sendMessage(request: Request, response: Response): Promise { + await this.httpService.callSyncingServer( + request, + response, + this.endpointResolver.resolveEndpointOrMethodIdentifier('POST', 'messages/'), + request.body, + ) + } + + @httpDelete('/inbound') + async deleteMessagesSentToUser(request: Request, response: Response): Promise { + await this.httpService.callSyncingServer( + request, + response, + this.endpointResolver.resolveEndpointOrMethodIdentifier('DELETE', 'messages/inbound'), + request.body, + ) + } + + @httpDelete('/:messageUuid') + async deleteMessage(request: Request, response: Response): Promise { + await this.httpService.callSyncingServer( + request, + response, + this.endpointResolver.resolveEndpointOrMethodIdentifier( + 'DELETE', + 'messages/:messageUuid', + request.params.messageUuid, + ), + request.body, + ) + } +} diff --git a/packages/api-gateway/src/Controller/v1/SharedVaultInvitesController.ts b/packages/api-gateway/src/Controller/v1/SharedVaultInvitesController.ts new file mode 100644 index 000000000..393797bd1 --- /dev/null +++ b/packages/api-gateway/src/Controller/v1/SharedVaultInvitesController.ts @@ -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 { + 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 { + 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 { + 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 { + 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 { + 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 { + 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 { + 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 { + 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 { + 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 { + await this.httpService.callSyncingServer( + request, + response, + this.endpointResolver.resolveEndpointOrMethodIdentifier( + 'DELETE', + 'shared-vaults/:sharedVaultUuid/invites', + request.params.sharedVaultUuid, + ), + request.body, + ) + } +} diff --git a/packages/api-gateway/src/Controller/v1/SharedVaultUsersController.ts b/packages/api-gateway/src/Controller/v1/SharedVaultUsersController.ts new file mode 100644 index 000000000..6b554c54b --- /dev/null +++ b/packages/api-gateway/src/Controller/v1/SharedVaultUsersController.ts @@ -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 { + 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 { + await this.httpService.callSyncingServer( + request, + response, + this.endpointResolver.resolveEndpointOrMethodIdentifier( + 'DELETE', + '/shared-vaults/:sharedVaultUuid/users/:userUuid', + request.params.sharedVaultUuid, + request.params.userUuid, + ), + request.body, + ) + } +} diff --git a/packages/api-gateway/src/Controller/v1/SharedVaultsController.ts b/packages/api-gateway/src/Controller/v1/SharedVaultsController.ts index ed414a0e2..5e458721a 100644 --- a/packages/api-gateway/src/Controller/v1/SharedVaultsController.ts +++ b/packages/api-gateway/src/Controller/v1/SharedVaultsController.ts @@ -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 { - await this.serviceProxy.callSyncingServer(request, response, request.path.replace('/v1/', ''), request.body) + @httpGet('/') + async getSharedVaults(request: Request, response: Response): Promise { + await this.httpService.callSyncingServer( + request, + response, + this.endpointResolver.resolveEndpointOrMethodIdentifier('GET', 'shared-vaults/'), + request.body, + ) + } + + @httpPost('/') + async createSharedVault(request: Request, response: Response): Promise { + await this.httpService.callSyncingServer( + request, + response, + this.endpointResolver.resolveEndpointOrMethodIdentifier('POST', 'shared-vaults/'), + request.body, + ) + } + + @httpDelete('/:sharedVaultUuid') + async deleteSharedVault(request: Request, response: Response): Promise { + 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 { + await this.httpService.callSyncingServer( + request, + response, + this.endpointResolver.resolveEndpointOrMethodIdentifier( + 'POST', + 'shared-vaults/:sharedVaultUuid/valet-tokens', + request.params.sharedVaultUuid, + ), + request.body, + ) } } diff --git a/packages/api-gateway/src/Service/Resolver/EndpointResolver.ts b/packages/api-gateway/src/Service/Resolver/EndpointResolver.ts index d558970d8..c73c28048 100644 --- a/packages/api-gateway/src/Service/Resolver/EndpointResolver.ts +++ b/packages/api-gateway/src/Service/Resolver/EndpointResolver.ts @@ -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 { diff --git a/packages/home-server/src/Server/HomeServer.ts b/packages/home-server/src/Server/HomeServer.ts index e39c8b91e..04e29f2f1 100644 --- a/packages/home-server/src/Server/HomeServer.ts +++ b/packages/home-server/src/Server/HomeServer.ts @@ -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) } } diff --git a/packages/syncing-server/.env.sample b/packages/syncing-server/.env.sample index c64656c44..64b1545d5 100644 --- a/packages/syncing-server/.env.sample +++ b/packages/syncing-server/.env.sample @@ -49,3 +49,6 @@ NEW_RELIC_LOG_LEVEL=info # (Optional) Revision Dumps FILE_UPLOAD_PATH= + +VALET_TOKEN_SECRET=change-me-! +VALET_TOKEN_TTL=7200 diff --git a/packages/syncing-server/src/Bootstrap/Container.ts b/packages/syncing-server/src/Bootstrap/Container.ts index b25165262..b8d7b3c88 100644 --- a/packages/syncing-server/src/Bootstrap/Container.ts +++ b/packages/syncing-server/src/Bootstrap/Container.ts @@ -88,6 +88,65 @@ import { TypeORMSharedVaultAssociationRepository } from '../Infra/TypeORM/TypeOR 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' export class ContainerConfigLoader { private readonly DEFAULT_CONTENT_SIZE_TRANSFER_LIMIT = 10_000_000 @@ -252,6 +311,35 @@ export class ContainerConfigLoader { TYPES.Sync_SharedVaultAssociationPersistenceMapper, ) .toConstantValue(new SharedVaultAssociationPersistenceMapper()) + container + .bind>(TYPES.Sync_SharedVaultPersistenceMapper) + .toConstantValue(new SharedVaultPersistenceMapper()) + container + .bind>(TYPES.Sync_SharedVaultUserPersistenceMapper) + .toConstantValue(new SharedVaultUserPersistenceMapper()) + container + .bind>(TYPES.Sync_SharedVaultInvitePersistenceMapper) + .toConstantValue(new SharedVaultInvitePersistenceMapper()) + container + .bind>(TYPES.Sync_NotificationPersistenceMapper) + .toConstantValue(new NotificationPersistenceMapper()) + container + .bind>(TYPES.Sync_SharedVaultUserHttpMapper) + .toConstantValue(new SharedVaultUserHttpMapper()) + container + .bind>(TYPES.Sync_SharedVaultHttpMapper) + .toConstantValue(new SharedVaultHttpMapper()) + container + .bind>( + TYPES.Sync_SharedVaultInviteHttpMapper, + ) + .toConstantValue(new SharedVaultInviteHttpMapper()) + container + .bind>(TYPES.Sync_MessagePersistenceMapper) + .toConstantValue(new MessagePersistenceMapper()) + container + .bind>(TYPES.Sync_MessageHttpMapper) + .toConstantValue(new MessageHttpMapper()) // ORM container @@ -263,6 +351,21 @@ export class ContainerConfigLoader { container .bind>(TYPES.Sync_ORMKeySystemAssociationRepository) .toConstantValue(appDataSource.getRepository(TypeORMKeySystemAssociation)) + container + .bind>(TYPES.Sync_ORMSharedVaultRepository) + .toConstantValue(appDataSource.getRepository(TypeORMSharedVault)) + container + .bind>(TYPES.Sync_ORMSharedVaultInviteRepository) + .toConstantValue(appDataSource.getRepository(TypeORMSharedVaultInvite)) + container + .bind>(TYPES.Sync_ORMSharedVaultUserRepository) + .toConstantValue(appDataSource.getRepository(TypeORMSharedVaultUser)) + container + .bind>(TYPES.Sync_ORMNotificationRepository) + .toConstantValue(appDataSource.getRepository(TypeORMNotification)) + container + .bind>(TYPES.Sync_ORMMessageRepository) + .toConstantValue(appDataSource.getRepository(TypeORMMessage)) // Repositories container @@ -281,7 +384,6 @@ export class ContainerConfigLoader { container.get(TYPES.Sync_SharedVaultAssociationPersistenceMapper), ), ) - container .bind(TYPES.Sync_ItemRepository) .toConstantValue( @@ -292,6 +394,46 @@ export class ContainerConfigLoader { container.get(TYPES.Sync_SharedVaultAssociationRepository), ), ) + container + .bind(TYPES.Sync_SharedVaultRepository) + .toConstantValue( + new TypeORMSharedVaultRepository( + container.get(TYPES.Sync_ORMSharedVaultRepository), + container.get(TYPES.Sync_SharedVaultPersistenceMapper), + ), + ) + container + .bind(TYPES.Sync_SharedVaultUserRepository) + .toConstantValue( + new TypeORMSharedVaultUserRepository( + container.get(TYPES.Sync_ORMSharedVaultUserRepository), + container.get(TYPES.Sync_SharedVaultUserPersistenceMapper), + ), + ) + container + .bind(TYPES.Sync_SharedVaultInviteRepository) + .toConstantValue( + new TypeORMSharedVaultInviteRepository( + container.get(TYPES.Sync_ORMSharedVaultInviteRepository), + container.get(TYPES.Sync_SharedVaultInvitePersistenceMapper), + ), + ) + container + .bind(TYPES.Sync_NotificationRepository) + .toConstantValue( + new TypeORMNotificationRepository( + container.get(TYPES.Sync_ORMNotificationRepository), + container.get(TYPES.Sync_NotificationPersistenceMapper), + ), + ) + container + .bind(TYPES.Sync_MessageRepository) + .toConstantValue( + new TypeORMMessageRepository( + container.get(TYPES.Sync_ORMMessageRepository), + container.get(TYPES.Sync_MessagePersistenceMapper), + ), + ) container .bind(TYPES.Sync_DomainEventFactory) @@ -337,6 +479,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>(TYPES.Sync_SharedVaultValetTokenEncoder) + .toConstantValue(new TokenEncoder(container.get(TYPES.Sync_VALET_TOKEN_SECRET))) container.bind(TYPES.Sync_OwnershipFilter).toConstantValue(new OwnershipFilter()) container @@ -415,6 +565,146 @@ export class ContainerConfigLoader { container.bind(TYPES.Sync_GetItem).toDynamicValue((context: interfaces.Context) => { return new GetItem(context.container.get(TYPES.Sync_ItemRepository)) }) + container + .bind(TYPES.Sync_InviteUserToSharedVault) + .toConstantValue( + new InviteUserToSharedVault( + container.get(TYPES.Sync_SharedVaultRepository), + container.get(TYPES.Sync_SharedVaultInviteRepository), + container.get(TYPES.Sync_Timer), + ), + ) + container + .bind(TYPES.Sync_UpdateSharedVaultInvite) + .toConstantValue( + new UpdateSharedVaultInvite( + container.get(TYPES.Sync_SharedVaultInviteRepository), + container.get(TYPES.Sync_Timer), + ), + ) + container + .bind(TYPES.Sync_AddUserToSharedVault) + .toConstantValue( + new AddUserToSharedVault( + container.get(TYPES.Sync_SharedVaultRepository), + container.get(TYPES.Sync_SharedVaultUserRepository), + container.get(TYPES.Sync_Timer), + ), + ) + container + .bind(TYPES.Sync_AcceptInviteToSharedVault) + .toConstantValue( + new AcceptInviteToSharedVault( + container.get(TYPES.Sync_AddUserToSharedVault), + container.get(TYPES.Sync_SharedVaultInviteRepository), + ), + ) + container + .bind(TYPES.Sync_DeclineInviteToSharedVault) + .toConstantValue(new DeclineInviteToSharedVault(container.get(TYPES.Sync_SharedVaultInviteRepository))) + container + .bind(TYPES.Sync_DeleteSharedVaultInvitesToUser) + .toConstantValue( + new DeleteSharedVaultInvitesToUser( + container.get(TYPES.Sync_SharedVaultInviteRepository), + container.get(TYPES.Sync_DeclineInviteToSharedVault), + ), + ) + container + .bind(TYPES.Sync_DeleteSharedVaultInvitesSentByUser) + .toConstantValue( + new DeleteSharedVaultInvitesSentByUser( + container.get(TYPES.Sync_SharedVaultInviteRepository), + container.get(TYPES.Sync_DeclineInviteToSharedVault), + ), + ) + container + .bind(TYPES.Sync_GetSharedVaultInvitesSentByUser) + .toConstantValue(new GetSharedVaultInvitesSentByUser(container.get(TYPES.Sync_SharedVaultInviteRepository))) + container + .bind(TYPES.Sync_GetSharedVaultInvitesSentToUser) + .toConstantValue(new GetSharedVaultInvitesSentToUser(container.get(TYPES.Sync_SharedVaultInviteRepository))) + container + .bind(TYPES.Sync_GetSharedVaultUsers) + .toConstantValue( + new GetSharedVaultUsers( + container.get(TYPES.Sync_SharedVaultUserRepository), + container.get(TYPES.Sync_SharedVaultRepository), + ), + ) + container + .bind(TYPES.Sync_AddNotificationForUser) + .toConstantValue( + new AddNotificationForUser(container.get(TYPES.Sync_NotificationRepository), container.get(TYPES.Sync_Timer)), + ) + container + .bind(TYPES.Sync_RemoveSharedVaultUser) + .toConstantValue( + new RemoveUserFromSharedVault( + container.get(TYPES.Sync_SharedVaultUserRepository), + container.get(TYPES.Sync_SharedVaultRepository), + container.get(TYPES.Sync_AddNotificationForUser), + ), + ) + container + .bind(TYPES.Sync_GetSharedVaults) + .toConstantValue( + new GetSharedVaults( + container.get(TYPES.Sync_SharedVaultUserRepository), + container.get(TYPES.Sync_SharedVaultRepository), + ), + ) + container + .bind(TYPES.Sync_CreateSharedVault) + .toConstantValue( + new CreateSharedVault( + container.get(TYPES.Sync_AddUserToSharedVault), + container.get(TYPES.Sync_SharedVaultRepository), + container.get(TYPES.Sync_Timer), + ), + ) + container + .bind(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(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(TYPES.Sync_GetMessagesSentToUser) + .toConstantValue(new GetMessagesSentToUser(container.get(TYPES.Sync_MessageRepository))) + container + .bind(TYPES.Sync_GetMessagesSentByUser) + .toConstantValue(new GetMessagesSentByUser(container.get(TYPES.Sync_MessageRepository))) + container + .bind(TYPES.Sync_SendMessageToUser) + .toConstantValue( + new SendMessageToUser(container.get(TYPES.Sync_MessageRepository), container.get(TYPES.Sync_Timer)), + ) + container + .bind(TYPES.Sync_DeleteMessage) + .toConstantValue(new DeleteMessage(container.get(TYPES.Sync_MessageRepository))) + container + .bind(TYPES.Sync_DeleteAllMessagesSentToUser) + .toConstantValue( + new DeleteAllMessagesSentToUser( + container.get(TYPES.Sync_MessageRepository), + container.get(TYPES.Sync_DeleteMessage), + ), + ) // Services container @@ -602,6 +892,58 @@ export class ContainerConfigLoader { container.get(TYPES.Sync_ControllerContainer), ), ) + container + .bind(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(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(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(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') diff --git a/packages/syncing-server/src/Bootstrap/Types.ts b/packages/syncing-server/src/Bootstrap/Types.ts index 545ec9fe6..c2a859e26 100644 --- a/packages/syncing-server/src/Bootstrap/Types.ts +++ b/packages/syncing-server/src/Bootstrap/Types.ts @@ -10,10 +10,20 @@ const TYPES = { 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 @@ -34,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'), @@ -43,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'), @@ -74,6 +88,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'), @@ -88,10 +103,15 @@ 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_ItemPersistenceMapper: Symbol.for('Sync_ItemPersistenceMapper'), Sync_ItemHttpMapper: Symbol.for('Sync_ItemHttpMapper'), @@ -101,6 +121,10 @@ const TYPES = { 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 diff --git a/packages/syncing-server/src/Infra/InversifyExpressUtils/HomeServer/HomeServerSharedVaultInvitesController.ts b/packages/syncing-server/src/Infra/InversifyExpressUtils/HomeServer/HomeServerSharedVaultInvitesController.ts index 85b6452c6..3d6e47da6 100644 --- a/packages/syncing-server/src/Infra/InversifyExpressUtils/HomeServer/HomeServerSharedVaultInvitesController.ts +++ b/packages/syncing-server/src/Infra/InversifyExpressUtils/HomeServer/HomeServerSharedVaultInvitesController.ts @@ -43,6 +43,10 @@ export class HomeServerSharedVaultInvitesController extends BaseHttpController { this.getOutboundUserInvites.bind(this), ) this.controllerContainer.register('sync.shared-vault-invites.get-user-invites', this.getUserInvites.bind(this)) + this.controllerContainer.register( + 'sync.shared-vault-invites.get-vault-invites', + this.getSharedVaultInvites.bind(this), + ) this.controllerContainer.register( 'sync.shared-vault-invites.delete-invite', this.deleteSharedVaultInvite.bind(this), diff --git a/packages/syncing-server/src/Mapping/Http/SavedItemHttpMapper.ts b/packages/syncing-server/src/Mapping/Http/SavedItemHttpMapper.ts index a54ff20e1..f499a892e 100644 --- a/packages/syncing-server/src/Mapping/Http/SavedItemHttpMapper.ts +++ b/packages/syncing-server/src/Mapping/Http/SavedItemHttpMapper.ts @@ -22,6 +22,16 @@ export class SavedItemHttpMapper implements MapperInterface