refactor: key rotation (#2383)
This commit is contained in:
@@ -1,15 +1,11 @@
|
||||
import { DiscardItemsLocally } from './../UseCase/DiscardItemsLocally'
|
||||
import { InternalEventBusInterface } from './../Internal/InternalEventBusInterface'
|
||||
import { GetOwnedSharedVaults } from './UseCase/GetOwnedSharedVaults'
|
||||
import { IsVaultOwner } from './../VaultUser/UseCase/IsVaultOwner'
|
||||
import { EncryptionProviderInterface } from './../Encryption/EncryptionProviderInterface'
|
||||
import { DeleteSharedVault } from './UseCase/DeleteSharedVault'
|
||||
import { ConvertToSharedVault } from './UseCase/ConvertToSharedVault'
|
||||
import { ShareContactWithVault } from './UseCase/ShareContactWithVault'
|
||||
import { DeleteThirdPartyVault } from './UseCase/DeleteExternalSharedVault'
|
||||
import { FindContact } from './../Contacts/UseCase/FindContact'
|
||||
import { SendVaultDataChangedMessage } from './UseCase/SendVaultDataChangedMessage'
|
||||
import { NotifyVaultUsersOfKeyRotation } from './UseCase/NotifyVaultUsersOfKeyRotation'
|
||||
import { HandleKeyPairChange } from './../Contacts/UseCase/HandleKeyPairChange'
|
||||
import { CreateSharedVault } from './UseCase/CreateSharedVault'
|
||||
import { GetVault } from './../Vault/UseCase/GetVault'
|
||||
@@ -29,20 +25,16 @@ describe('SharedVaultService', () => {
|
||||
const items = {} as jest.Mocked<ItemManagerInterface>
|
||||
items.addObserver = jest.fn()
|
||||
|
||||
const encryption = {} as jest.Mocked<EncryptionProviderInterface>
|
||||
const session = {} as jest.Mocked<SessionsClientInterface>
|
||||
const getVault = {} as jest.Mocked<GetVault>
|
||||
const getOwnedVaults = {} as jest.Mocked<GetOwnedSharedVaults>
|
||||
const createSharedVaultUseCase = {} as jest.Mocked<CreateSharedVault>
|
||||
const handleKeyPairChange = {} as jest.Mocked<HandleKeyPairChange>
|
||||
const notifyVaultUsersOfKeyRotation = {} as jest.Mocked<NotifyVaultUsersOfKeyRotation>
|
||||
const sendVaultDataChangeMessage = {} as jest.Mocked<SendVaultDataChangedMessage>
|
||||
const findContact = {} as jest.Mocked<FindContact>
|
||||
const deleteThirdPartyVault = {} as jest.Mocked<DeleteThirdPartyVault>
|
||||
const shareContactWithVault = {} as jest.Mocked<ShareContactWithVault>
|
||||
const convertToSharedVault = {} as jest.Mocked<ConvertToSharedVault>
|
||||
const deleteSharedVaultUseCase = {} as jest.Mocked<DeleteSharedVault>
|
||||
const isVaultAdmin = {} as jest.Mocked<IsVaultOwner>
|
||||
const discardItemsLocally = {} as jest.Mocked<DiscardItemsLocally>
|
||||
|
||||
const eventBus = {} as jest.Mocked<InternalEventBusInterface>
|
||||
@@ -50,20 +42,16 @@ describe('SharedVaultService', () => {
|
||||
|
||||
service = new SharedVaultService(
|
||||
items,
|
||||
encryption,
|
||||
session,
|
||||
getVault,
|
||||
getOwnedVaults,
|
||||
createSharedVaultUseCase,
|
||||
handleKeyPairChange,
|
||||
notifyVaultUsersOfKeyRotation,
|
||||
sendVaultDataChangeMessage,
|
||||
findContact,
|
||||
deleteThirdPartyVault,
|
||||
shareContactWithVault,
|
||||
convertToSharedVault,
|
||||
deleteSharedVaultUseCase,
|
||||
isVaultAdmin,
|
||||
discardItemsLocally,
|
||||
eventBus,
|
||||
)
|
||||
|
||||
@@ -22,18 +22,13 @@ import { InternalEventInterface } from '../Internal/InternalEventInterface'
|
||||
import { NotificationServiceEvent, NotificationServiceEventPayload } from '../UserEvent/NotificationServiceEvent'
|
||||
import { DeleteThirdPartyVault } from './UseCase/DeleteExternalSharedVault'
|
||||
import { DeleteSharedVault } from './UseCase/DeleteSharedVault'
|
||||
import { VaultServiceEvent, VaultServiceEventPayload } from '../Vault/VaultServiceEvent'
|
||||
import { ShareContactWithVault } from './UseCase/ShareContactWithVault'
|
||||
import { NotifyVaultUsersOfKeyRotation } from './UseCase/NotifyVaultUsersOfKeyRotation'
|
||||
import { CreateSharedVault } from './UseCase/CreateSharedVault'
|
||||
import { SendVaultDataChangedMessage } from './UseCase/SendVaultDataChangedMessage'
|
||||
import { ConvertToSharedVault } from './UseCase/ConvertToSharedVault'
|
||||
import { GetVault } from '../Vault/UseCase/GetVault'
|
||||
import { ContentType, NotificationType, Uuid } from '@standardnotes/domain-core'
|
||||
import { HandleKeyPairChange } from '../Contacts/UseCase/HandleKeyPairChange'
|
||||
import { FindContact } from '../Contacts/UseCase/FindContact'
|
||||
import { EncryptionProviderInterface } from '../Encryption/EncryptionProviderInterface'
|
||||
import { IsVaultOwner } from '../VaultUser/UseCase/IsVaultOwner'
|
||||
import { GetOwnedSharedVaults } from './UseCase/GetOwnedSharedVaults'
|
||||
|
||||
export class SharedVaultService
|
||||
@@ -42,20 +37,16 @@ export class SharedVaultService
|
||||
{
|
||||
constructor(
|
||||
private items: ItemManagerInterface,
|
||||
private encryption: EncryptionProviderInterface,
|
||||
private session: SessionsClientInterface,
|
||||
private _getVault: GetVault,
|
||||
private _getOwnedSharedVaults: GetOwnedSharedVaults,
|
||||
private _createSharedVault: CreateSharedVault,
|
||||
private _handleKeyPairChange: HandleKeyPairChange,
|
||||
private _notifyVaultUsersOfKeyRotation: NotifyVaultUsersOfKeyRotation,
|
||||
private _sendVaultDataChangeMessage: SendVaultDataChangedMessage,
|
||||
private _findContact: FindContact,
|
||||
private _deleteThirdPartyVault: DeleteThirdPartyVault,
|
||||
private _shareContactWithVault: ShareContactWithVault,
|
||||
private _convertToSharedVault: ConvertToSharedVault,
|
||||
private _deleteSharedVault: DeleteSharedVault,
|
||||
private _isVaultAdmin: IsVaultOwner,
|
||||
private _discardItemsLocally: DiscardItemsLocally,
|
||||
eventBus: InternalEventBusInterface,
|
||||
) {
|
||||
@@ -68,32 +59,20 @@ export class SharedVaultService
|
||||
}
|
||||
}),
|
||||
)
|
||||
|
||||
this.eventDisposers.push(
|
||||
items.addObserver<VaultListingInterface>(ContentType.TYPES.VaultListing, ({ changed, source }) => {
|
||||
if (source === PayloadEmitSource.LocalChanged && changed.length > 0) {
|
||||
void this.handleVaultListingsChange(changed)
|
||||
}
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
override deinit(): void {
|
||||
super.deinit()
|
||||
;(this.items as unknown) = undefined
|
||||
;(this.encryption as unknown) = undefined
|
||||
;(this.session as unknown) = undefined
|
||||
;(this._getVault as unknown) = undefined
|
||||
;(this._createSharedVault as unknown) = undefined
|
||||
;(this._handleKeyPairChange as unknown) = undefined
|
||||
;(this._notifyVaultUsersOfKeyRotation as unknown) = undefined
|
||||
;(this._sendVaultDataChangeMessage as unknown) = undefined
|
||||
;(this._findContact as unknown) = undefined
|
||||
;(this._deleteThirdPartyVault as unknown) = undefined
|
||||
;(this._shareContactWithVault as unknown) = undefined
|
||||
;(this._convertToSharedVault as unknown) = undefined
|
||||
;(this._deleteSharedVault as unknown) = undefined
|
||||
;(this._isVaultAdmin as unknown) = undefined
|
||||
}
|
||||
|
||||
async handleEvent(event: InternalEventInterface): Promise<void> {
|
||||
@@ -109,11 +88,6 @@ export class SharedVaultService
|
||||
case NotificationServiceEvent.NotificationReceived:
|
||||
await this.handleUserEvent(event.payload as NotificationServiceEventPayload)
|
||||
break
|
||||
case VaultServiceEvent.VaultRootKeyRotated: {
|
||||
const payload = event.payload as VaultServiceEventPayload[VaultServiceEvent.VaultRootKeyRotated]
|
||||
await this.handleVaultRootKeyRotatedEvent(payload.vault)
|
||||
break
|
||||
}
|
||||
case SyncEvent.ReceivedRemoteSharedVaults:
|
||||
void this.notifyEventSync(SharedVaultServiceEvent.SharedVaultStatusChanged)
|
||||
break
|
||||
@@ -141,33 +115,6 @@ export class SharedVaultService
|
||||
}
|
||||
}
|
||||
|
||||
private isCurrentUserVaultOwner(sharedVault: SharedVaultListingInterface): boolean {
|
||||
if (!sharedVault.sharing.ownerUserUuid) {
|
||||
throw new Error(`Shared vault ${sharedVault.sharing.sharedVaultUuid} does not have an owner user uuid`)
|
||||
}
|
||||
|
||||
return sharedVault.sharing.ownerUserUuid === this.session.userUuid
|
||||
}
|
||||
|
||||
private async handleVaultRootKeyRotatedEvent(vault: VaultListingInterface): Promise<void> {
|
||||
if (!vault.isSharedVaultListing()) {
|
||||
return
|
||||
}
|
||||
|
||||
if (!this.isCurrentUserVaultOwner(vault)) {
|
||||
return
|
||||
}
|
||||
|
||||
await this._notifyVaultUsersOfKeyRotation.execute({
|
||||
sharedVault: vault,
|
||||
senderUuid: this.session.getSureUser().uuid,
|
||||
keys: {
|
||||
encryption: this.encryption.getKeyPair(),
|
||||
signing: this.encryption.getSigningKeyPair(),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
async createSharedVault(dto: {
|
||||
name: string
|
||||
description?: string
|
||||
@@ -198,23 +145,6 @@ export class SharedVaultService
|
||||
}
|
||||
}
|
||||
|
||||
private async handleVaultListingsChange(vaults: VaultListingInterface[]): Promise<void> {
|
||||
for (const vault of vaults) {
|
||||
if (!vault.isSharedVaultListing()) {
|
||||
continue
|
||||
}
|
||||
|
||||
await this._sendVaultDataChangeMessage.execute({
|
||||
vault,
|
||||
senderUuid: this.session.getSureUser().uuid,
|
||||
keys: {
|
||||
encryption: this.encryption.getKeyPair(),
|
||||
signing: this.encryption.getSigningKeyPair(),
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
public async deleteSharedVault(sharedVault: SharedVaultListingInterface): Promise<ClientDisplayableError | void> {
|
||||
return this._deleteSharedVault.execute({ sharedVault })
|
||||
}
|
||||
@@ -224,17 +154,12 @@ export class SharedVaultService
|
||||
throw new Error('Cannot share self contact')
|
||||
}
|
||||
|
||||
const ownedVaults = this._getOwnedSharedVaults.execute({ userUuid: this.session.userUuid }).getValue()
|
||||
const ownedVaults = this._getOwnedSharedVaults.execute().getValue()
|
||||
|
||||
for (const vault of ownedVaults) {
|
||||
await this._shareContactWithVault.execute({
|
||||
keys: {
|
||||
encryption: this.encryption.getKeyPair(),
|
||||
signing: this.encryption.getSigningKeyPair(),
|
||||
},
|
||||
sharedVault: vault,
|
||||
contactToShare: contact,
|
||||
senderUserUuid: this.session.getSureUser().uuid,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,18 +5,17 @@ import { GetSharedVaults } from './GetSharedVaults'
|
||||
|
||||
export class GetOwnedSharedVaults implements SyncUseCaseInterface<SharedVaultListingInterface[]> {
|
||||
constructor(
|
||||
private getSharedVaults: GetSharedVaults,
|
||||
private isVaultOwnwer: IsVaultOwner,
|
||||
private _getSharedVaults: GetSharedVaults,
|
||||
private _isVaultOwnwer: IsVaultOwner,
|
||||
) {}
|
||||
|
||||
execute(dto: { userUuid: string }): Result<SharedVaultListingInterface[]> {
|
||||
const sharedVaults = this.getSharedVaults.execute().getValue()
|
||||
execute(): Result<SharedVaultListingInterface[]> {
|
||||
const sharedVaults = this._getSharedVaults.execute().getValue()
|
||||
|
||||
const ownedVaults = sharedVaults.filter((vault) => {
|
||||
return this.isVaultOwnwer
|
||||
return this._isVaultOwnwer
|
||||
.execute({
|
||||
sharedVault: vault,
|
||||
userUuid: dto.userUuid,
|
||||
})
|
||||
.getValue()
|
||||
})
|
||||
|
||||
@@ -2,30 +2,26 @@ import { SharedVaultInvitesServerInterface } from '@standardnotes/api'
|
||||
import { AsymmetricMessageSharedVaultInvite, SharedVaultListingInterface } from '@standardnotes/models'
|
||||
import { SharedVaultInviteServerHash, isErrorResponse } from '@standardnotes/responses'
|
||||
import { SendVaultKeyChangedMessage } from './SendVaultKeyChangedMessage'
|
||||
import { PkcKeyPair } from '@standardnotes/sncrypto-common'
|
||||
import { Result, UseCaseInterface } from '@standardnotes/domain-core'
|
||||
import { InviteToVault } from '../../VaultInvite/UseCase/InviteToVault'
|
||||
import { GetVaultContacts } from '../../VaultUser/UseCase/GetVaultContacts'
|
||||
import { DecryptOwnMessage } from '../../Encryption/UseCase/Asymmetric/DecryptOwnMessage'
|
||||
import { FindContact } from '../../Contacts/UseCase/FindContact'
|
||||
import { GetKeyPairs } from '../../Encryption/UseCase/GetKeyPairs'
|
||||
|
||||
type Params = {
|
||||
keys: {
|
||||
encryption: PkcKeyPair
|
||||
signing: PkcKeyPair
|
||||
}
|
||||
sharedVault: SharedVaultListingInterface
|
||||
senderUuid: string
|
||||
}
|
||||
|
||||
export class NotifyVaultUsersOfKeyRotation implements UseCaseInterface<void> {
|
||||
constructor(
|
||||
private findContact: FindContact,
|
||||
private sendKeyChangedMessage: SendVaultKeyChangedMessage,
|
||||
private inviteToVault: InviteToVault,
|
||||
private inviteServer: SharedVaultInvitesServerInterface,
|
||||
private getVaultContacts: GetVaultContacts,
|
||||
private decryptOwnMessage: DecryptOwnMessage<AsymmetricMessageSharedVaultInvite>,
|
||||
private _findContact: FindContact,
|
||||
private _sendKeyChangedMessage: SendVaultKeyChangedMessage,
|
||||
private _inviteToVault: InviteToVault,
|
||||
private _inviteServer: SharedVaultInvitesServerInterface,
|
||||
private _getVaultContacts: GetVaultContacts,
|
||||
private _decryptOwnMessage: DecryptOwnMessage<AsymmetricMessageSharedVaultInvite>,
|
||||
private _getKeyPairs: GetKeyPairs,
|
||||
) {}
|
||||
|
||||
async execute(params: Params): Promise<Result<void>> {
|
||||
@@ -44,20 +40,25 @@ export class NotifyVaultUsersOfKeyRotation implements UseCaseInterface<void> {
|
||||
|
||||
await this.deleteAllInvites(params.sharedVault.sharing.sharedVaultUuid)
|
||||
|
||||
const contacts = await this.getVaultContacts.execute({
|
||||
const contacts = await this._getVaultContacts.execute({
|
||||
sharedVaultUuid: params.sharedVault.sharing.sharedVaultUuid,
|
||||
readFromCache: false,
|
||||
})
|
||||
|
||||
const keys = this._getKeyPairs.execute()
|
||||
if (keys.isFailed()) {
|
||||
return Result.fail('Cannot send metadata changed message; keys not found')
|
||||
}
|
||||
|
||||
for (const invite of existingInvites.getValue()) {
|
||||
const recipient = this.findContact.execute({ userUuid: invite.user_uuid })
|
||||
const recipient = this._findContact.execute({ userUuid: invite.user_uuid })
|
||||
if (recipient.isFailed()) {
|
||||
continue
|
||||
}
|
||||
|
||||
const decryptedPreviousInvite = this.decryptOwnMessage.execute({
|
||||
const decryptedPreviousInvite = this._decryptOwnMessage.execute({
|
||||
message: invite.encrypted_message,
|
||||
privateKey: params.keys.encryption.privateKey,
|
||||
privateKey: keys.getValue().encryption.privateKey,
|
||||
recipientPublicKey: recipient.getValue().publicKeySet.encryption,
|
||||
})
|
||||
|
||||
@@ -65,13 +66,11 @@ export class NotifyVaultUsersOfKeyRotation implements UseCaseInterface<void> {
|
||||
return Result.fail(decryptedPreviousInvite.getError())
|
||||
}
|
||||
|
||||
await this.inviteToVault.execute({
|
||||
keys: params.keys,
|
||||
await this._inviteToVault.execute({
|
||||
sharedVault: params.sharedVault,
|
||||
sharedVaultContacts: !contacts.isFailed() ? contacts.getValue() : [],
|
||||
recipient: recipient.getValue(),
|
||||
permission: invite.permission,
|
||||
senderUuid: params.senderUuid,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -79,11 +78,9 @@ export class NotifyVaultUsersOfKeyRotation implements UseCaseInterface<void> {
|
||||
}
|
||||
|
||||
private async performSendKeyChangeMessage(params: Params): Promise<Result<void>> {
|
||||
const result = await this.sendKeyChangedMessage.execute({
|
||||
const result = await this._sendKeyChangedMessage.execute({
|
||||
keySystemIdentifier: params.sharedVault.systemIdentifier,
|
||||
sharedVaultUuid: params.sharedVault.sharing.sharedVaultUuid,
|
||||
senderUuid: params.senderUuid,
|
||||
keys: params.keys,
|
||||
})
|
||||
|
||||
if (result.isFailed()) {
|
||||
@@ -94,7 +91,7 @@ export class NotifyVaultUsersOfKeyRotation implements UseCaseInterface<void> {
|
||||
}
|
||||
|
||||
private async deleteAllInvites(sharedVaultUuid: string): Promise<Result<void>> {
|
||||
const response = await this.inviteServer.deleteAllSharedVaultInvites({
|
||||
const response = await this._inviteServer.deleteAllSharedVaultInvites({
|
||||
sharedVaultUuid: sharedVaultUuid,
|
||||
})
|
||||
|
||||
@@ -106,7 +103,7 @@ export class NotifyVaultUsersOfKeyRotation implements UseCaseInterface<void> {
|
||||
}
|
||||
|
||||
private async getExistingInvites(sharedVaultUuid: string): Promise<Result<SharedVaultInviteServerHash[]>> {
|
||||
const response = await this.inviteServer.getOutboundUserInvites()
|
||||
const response = await this._inviteServer.getOutboundUserInvites()
|
||||
|
||||
if (isErrorResponse(response)) {
|
||||
return Result.fail(`Failed to get outbound user invites ${JSON.stringify(response)}`)
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { UserServiceInterface } from './../../User/UserServiceInterface'
|
||||
import { IsVaultOwner } from './../../VaultUser/UseCase/IsVaultOwner'
|
||||
import {
|
||||
AsymmetricMessagePayloadType,
|
||||
AsymmetricMessageSharedVaultMetadataChanged,
|
||||
@@ -12,24 +14,26 @@ import { EncryptMessage } from '../../Encryption/UseCase/Asymmetric/EncryptMessa
|
||||
import { Result, UseCaseInterface } from '@standardnotes/domain-core'
|
||||
import { GetReplaceabilityIdentifier } from '../../AsymmetricMessage/UseCase/GetReplaceabilityIdentifier'
|
||||
import { FindContact } from '../../Contacts/UseCase/FindContact'
|
||||
import { GetKeyPairs } from '../../Encryption/UseCase/GetKeyPairs'
|
||||
|
||||
export class SendVaultDataChangedMessage implements UseCaseInterface<void> {
|
||||
constructor(
|
||||
private encryptMessage: EncryptMessage,
|
||||
private findContact: FindContact,
|
||||
private getVaultUsers: GetVaultUsers,
|
||||
private sendMessage: SendMessage,
|
||||
private users: UserServiceInterface,
|
||||
private _encryptMessage: EncryptMessage,
|
||||
private _findContact: FindContact,
|
||||
private _getVaultUsers: GetVaultUsers,
|
||||
private _sendMessage: SendMessage,
|
||||
private _isVaultOwner: IsVaultOwner,
|
||||
private _getKeyPairs: GetKeyPairs,
|
||||
) {}
|
||||
|
||||
async execute(params: {
|
||||
vault: SharedVaultListingInterface
|
||||
senderUuid: string
|
||||
keys: {
|
||||
encryption: PkcKeyPair
|
||||
signing: PkcKeyPair
|
||||
async execute(params: { vault: SharedVaultListingInterface }): Promise<Result<void>> {
|
||||
const isOwner = this._isVaultOwner.execute({ sharedVault: params.vault }).getValue()
|
||||
if (!isOwner) {
|
||||
return Result.ok()
|
||||
}
|
||||
}): Promise<Result<void>> {
|
||||
const users = await this.getVaultUsers.execute({
|
||||
|
||||
const users = await this._getVaultUsers.execute({
|
||||
sharedVaultUuid: params.vault.sharing.sharedVaultUuid,
|
||||
readFromCache: false,
|
||||
})
|
||||
@@ -37,20 +41,25 @@ export class SendVaultDataChangedMessage implements UseCaseInterface<void> {
|
||||
return Result.fail('Cannot send metadata changed message; users not found')
|
||||
}
|
||||
|
||||
const keys = this._getKeyPairs.execute()
|
||||
if (keys.isFailed()) {
|
||||
return Result.fail('Cannot send metadata changed message; keys not found')
|
||||
}
|
||||
|
||||
const errors: string[] = []
|
||||
for (const user of users.getValue()) {
|
||||
if (user.user_uuid === params.senderUuid) {
|
||||
if (user.user_uuid === this.users.sureUser.uuid) {
|
||||
continue
|
||||
}
|
||||
|
||||
const trustedContact = this.findContact.execute({ userUuid: user.user_uuid })
|
||||
const trustedContact = this._findContact.execute({ userUuid: user.user_uuid })
|
||||
if (trustedContact.isFailed()) {
|
||||
continue
|
||||
}
|
||||
|
||||
const sendMessageResult = await this.sendToContact({
|
||||
vault: params.vault,
|
||||
keys: params.keys,
|
||||
keys: keys.getValue(),
|
||||
contact: trustedContact.getValue(),
|
||||
})
|
||||
|
||||
@@ -84,7 +93,7 @@ export class SendVaultDataChangedMessage implements UseCaseInterface<void> {
|
||||
},
|
||||
}
|
||||
|
||||
const encryptedMessage = this.encryptMessage.execute({
|
||||
const encryptedMessage = this._encryptMessage.execute({
|
||||
message: message,
|
||||
keys: params.keys,
|
||||
recipientPublicKey: params.contact.publicKeySet.encryption,
|
||||
@@ -100,7 +109,7 @@ export class SendVaultDataChangedMessage implements UseCaseInterface<void> {
|
||||
params.vault.systemIdentifier,
|
||||
)
|
||||
|
||||
const sendMessageResult = await this.sendMessage.execute({
|
||||
const sendMessageResult = await this._sendMessage.execute({
|
||||
recipientUuid: params.contact.contactUuid,
|
||||
encryptedMessage: encryptedMessage.getValue(),
|
||||
replaceabilityIdentifier,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { UserServiceInterface } from './../../User/UserServiceInterface'
|
||||
import {
|
||||
AsymmetricMessagePayloadType,
|
||||
AsymmetricMessageSharedVaultRootKeyChanged,
|
||||
@@ -13,38 +14,38 @@ import { Result, UseCaseInterface } from '@standardnotes/domain-core'
|
||||
import { GetReplaceabilityIdentifier } from '../../AsymmetricMessage/UseCase/GetReplaceabilityIdentifier'
|
||||
import { FindContact } from '../../Contacts/UseCase/FindContact'
|
||||
import { KeySystemKeyManagerInterface } from '../../KeySystem/KeySystemKeyManagerInterface'
|
||||
import { GetKeyPairs } from '../../Encryption/UseCase/GetKeyPairs'
|
||||
|
||||
export class SendVaultKeyChangedMessage implements UseCaseInterface<void> {
|
||||
constructor(
|
||||
private encryptMessage: EncryptMessage,
|
||||
private users: UserServiceInterface,
|
||||
private keyManager: KeySystemKeyManagerInterface,
|
||||
private findContact: FindContact,
|
||||
private sendMessage: SendMessage,
|
||||
private getVaultUsers: GetVaultUsers,
|
||||
private _encryptMessage: EncryptMessage,
|
||||
private _findContact: FindContact,
|
||||
private _sendMessage: SendMessage,
|
||||
private _getVaultUsers: GetVaultUsers,
|
||||
private _getKeyPairs: GetKeyPairs,
|
||||
) {}
|
||||
|
||||
async execute(params: {
|
||||
keySystemIdentifier: KeySystemIdentifier
|
||||
sharedVaultUuid: string
|
||||
senderUuid: string
|
||||
keys: {
|
||||
encryption: PkcKeyPair
|
||||
signing: PkcKeyPair
|
||||
}
|
||||
}): Promise<Result<void>> {
|
||||
const users = await this.getVaultUsers.execute({ sharedVaultUuid: params.sharedVaultUuid, readFromCache: false })
|
||||
async execute(params: { keySystemIdentifier: KeySystemIdentifier; sharedVaultUuid: string }): Promise<Result<void>> {
|
||||
const users = await this._getVaultUsers.execute({ sharedVaultUuid: params.sharedVaultUuid, readFromCache: false })
|
||||
if (users.isFailed()) {
|
||||
return Result.fail('Cannot send root key changed message; users not found')
|
||||
}
|
||||
|
||||
const keys = this._getKeyPairs.execute()
|
||||
if (keys.isFailed()) {
|
||||
return Result.fail('Cannot send root key changed message; keys not found')
|
||||
}
|
||||
|
||||
const errors: string[] = []
|
||||
|
||||
for (const user of users.getValue()) {
|
||||
if (user.user_uuid === params.senderUuid) {
|
||||
if (user.user_uuid === this.users.sureUser.uuid) {
|
||||
continue
|
||||
}
|
||||
|
||||
const trustedContact = this.findContact.execute({ userUuid: user.user_uuid })
|
||||
const trustedContact = this._findContact.execute({ userUuid: user.user_uuid })
|
||||
if (trustedContact.isFailed()) {
|
||||
continue
|
||||
}
|
||||
@@ -52,7 +53,7 @@ export class SendVaultKeyChangedMessage implements UseCaseInterface<void> {
|
||||
const result = await this.sendToContact({
|
||||
keySystemIdentifier: params.keySystemIdentifier,
|
||||
sharedVaultUuid: params.sharedVaultUuid,
|
||||
keys: params.keys,
|
||||
keys: keys.getValue(),
|
||||
contact: trustedContact.getValue(),
|
||||
})
|
||||
|
||||
@@ -87,7 +88,7 @@ export class SendVaultKeyChangedMessage implements UseCaseInterface<void> {
|
||||
data: { recipientUuid: params.contact.contactUuid, rootKey: keySystemRootKey.content },
|
||||
}
|
||||
|
||||
const encryptedMessage = this.encryptMessage.execute({
|
||||
const encryptedMessage = this._encryptMessage.execute({
|
||||
message: message,
|
||||
keys: params.keys,
|
||||
recipientPublicKey: params.contact.publicKeySet.encryption,
|
||||
@@ -103,7 +104,7 @@ export class SendVaultKeyChangedMessage implements UseCaseInterface<void> {
|
||||
params.keySystemIdentifier,
|
||||
)
|
||||
|
||||
const sendMessageResult = await this.sendMessage.execute({
|
||||
const sendMessageResult = await this._sendMessage.execute({
|
||||
recipientUuid: params.contact.contactUuid,
|
||||
encryptedMessage: encryptedMessage.getValue(),
|
||||
replaceabilityIdentifier,
|
||||
|
||||
@@ -1,37 +1,35 @@
|
||||
import { UserServiceInterface } from './../../User/UserServiceInterface'
|
||||
import {
|
||||
TrustedContactInterface,
|
||||
SharedVaultListingInterface,
|
||||
AsymmetricMessagePayloadType,
|
||||
} from '@standardnotes/models'
|
||||
import { PkcKeyPair } from '@standardnotes/sncrypto-common'
|
||||
import { SendMessage } from '../../AsymmetricMessage/UseCase/SendMessage'
|
||||
import { EncryptMessage } from '../../Encryption/UseCase/Asymmetric/EncryptMessage'
|
||||
import { Result, UseCaseInterface } from '@standardnotes/domain-core'
|
||||
import { FindContact } from '../../Contacts/UseCase/FindContact'
|
||||
import { GetVaultUsers } from '../../VaultUser/UseCase/GetVaultUsers'
|
||||
import { GetKeyPairs } from '../../Encryption/UseCase/GetKeyPairs'
|
||||
|
||||
export class ShareContactWithVault implements UseCaseInterface<void> {
|
||||
constructor(
|
||||
private findContact: FindContact,
|
||||
private encryptMessage: EncryptMessage,
|
||||
private sendMessage: SendMessage,
|
||||
private getVaultUsers: GetVaultUsers,
|
||||
private users: UserServiceInterface,
|
||||
private _findContact: FindContact,
|
||||
private _encryptMessage: EncryptMessage,
|
||||
private _sendMessage: SendMessage,
|
||||
private _getVaultUsers: GetVaultUsers,
|
||||
private _getKeyPairs: GetKeyPairs,
|
||||
) {}
|
||||
|
||||
async execute(params: {
|
||||
keys: {
|
||||
encryption: PkcKeyPair
|
||||
signing: PkcKeyPair
|
||||
}
|
||||
senderUserUuid: string
|
||||
sharedVault: SharedVaultListingInterface
|
||||
contactToShare: TrustedContactInterface
|
||||
}): Promise<Result<void>> {
|
||||
if (params.sharedVault.sharing.ownerUserUuid !== params.senderUserUuid) {
|
||||
if (params.sharedVault.sharing.ownerUserUuid !== this.users.sureUser.uuid) {
|
||||
return Result.fail('Cannot share contact; user is not the owner of the shared vault')
|
||||
}
|
||||
|
||||
const users = await this.getVaultUsers.execute({
|
||||
const users = await this._getVaultUsers.execute({
|
||||
sharedVaultUuid: params.sharedVault.sharing.sharedVaultUuid,
|
||||
readFromCache: false,
|
||||
})
|
||||
@@ -44,8 +42,13 @@ export class ShareContactWithVault implements UseCaseInterface<void> {
|
||||
return Result.ok()
|
||||
}
|
||||
|
||||
const keys = this._getKeyPairs.execute()
|
||||
if (keys.isFailed()) {
|
||||
return Result.fail('Cannot share contact; keys not found')
|
||||
}
|
||||
|
||||
for (const vaultUser of users.getValue()) {
|
||||
if (vaultUser.user_uuid === params.senderUserUuid) {
|
||||
if (vaultUser.user_uuid === this.users.sureUser.uuid) {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -53,12 +56,12 @@ export class ShareContactWithVault implements UseCaseInterface<void> {
|
||||
continue
|
||||
}
|
||||
|
||||
const vaultUserAsContact = this.findContact.execute({ userUuid: vaultUser.user_uuid })
|
||||
const vaultUserAsContact = this._findContact.execute({ userUuid: vaultUser.user_uuid })
|
||||
if (vaultUserAsContact.isFailed()) {
|
||||
continue
|
||||
}
|
||||
|
||||
const encryptedMessage = this.encryptMessage.execute({
|
||||
const encryptedMessage = this._encryptMessage.execute({
|
||||
message: {
|
||||
type: AsymmetricMessagePayloadType.ContactShare,
|
||||
data: {
|
||||
@@ -66,7 +69,7 @@ export class ShareContactWithVault implements UseCaseInterface<void> {
|
||||
trustedContact: params.contactToShare.content,
|
||||
},
|
||||
},
|
||||
keys: params.keys,
|
||||
keys: keys.getValue(),
|
||||
recipientPublicKey: vaultUserAsContact.getValue().publicKeySet.encryption,
|
||||
})
|
||||
|
||||
@@ -74,7 +77,7 @@ export class ShareContactWithVault implements UseCaseInterface<void> {
|
||||
continue
|
||||
}
|
||||
|
||||
await this.sendMessage.execute({
|
||||
await this._sendMessage.execute({
|
||||
recipientUuid: vaultUserAsContact.getValue().contactUuid,
|
||||
encryptedMessage: encryptedMessage.getValue(),
|
||||
replaceabilityIdentifier: undefined,
|
||||
|
||||
Reference in New Issue
Block a user