chore: add handling shared vault invites via websockets (#2475)
This commit is contained in:
Binary file not shown.
@@ -1,6 +1,4 @@
|
|||||||
import { AsymmetricMessageServerHash } from '../AsymmetricMessage/AsymmetricMessageServerHash'
|
export interface SharedVaultInviteServerHash {
|
||||||
|
|
||||||
export interface SharedVaultInviteServerHash extends AsymmetricMessageServerHash {
|
|
||||||
uuid: string
|
uuid: string
|
||||||
shared_vault_uuid: string
|
shared_vault_uuid: string
|
||||||
user_uuid: string
|
user_uuid: string
|
||||||
|
|||||||
@@ -67,3 +67,7 @@ export * from './User/SettingData'
|
|||||||
export * from './User/UpdateSettingResponse'
|
export * from './User/UpdateSettingResponse'
|
||||||
|
|
||||||
export * from './Notification/NotificationServerHash'
|
export * from './Notification/NotificationServerHash'
|
||||||
|
|
||||||
|
export * from './SharedVaults/SharedVaultInviteServerHash'
|
||||||
|
export * from './SharedVaults/SharedVaultServerHash'
|
||||||
|
export * from './SharedVaults/SharedVaultUserServerHash'
|
||||||
|
|||||||
@@ -2,4 +2,5 @@ export enum WebSocketsServiceEvent {
|
|||||||
UserRoleMessageReceived = 'WebSocketMessageReceived',
|
UserRoleMessageReceived = 'WebSocketMessageReceived',
|
||||||
NotificationAddedForUser = 'NotificationAddedForUser',
|
NotificationAddedForUser = 'NotificationAddedForUser',
|
||||||
MessageSentToUser = 'MessageSentToUser',
|
MessageSentToUser = 'MessageSentToUser',
|
||||||
|
UserInvitedToSharedVault = 'UserInvitedToSharedVault',
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,6 +71,9 @@ export class WebSocketsService extends AbstractService<WebSocketsServiceEvent, D
|
|||||||
case 'MESSAGE_SENT_TO_USER':
|
case 'MESSAGE_SENT_TO_USER':
|
||||||
void this.notifyEvent(WebSocketsServiceEvent.MessageSentToUser, eventData)
|
void this.notifyEvent(WebSocketsServiceEvent.MessageSentToUser, eventData)
|
||||||
break
|
break
|
||||||
|
case 'USER_INVITED_TO_SHARED_VAULT':
|
||||||
|
void this.notifyEvent(WebSocketsServiceEvent.UserInvitedToSharedVault, eventData)
|
||||||
|
break
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -211,7 +211,7 @@ export class AsymmetricMessageService
|
|||||||
|
|
||||||
const result = this._getUntrustedPayload.execute({
|
const result = this._getUntrustedPayload.execute({
|
||||||
privateKey: keys.getValue().encryption.privateKey,
|
privateKey: keys.getValue().encryption.privateKey,
|
||||||
message,
|
payload: message,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (result.isFailed()) {
|
if (result.isFailed()) {
|
||||||
@@ -236,7 +236,7 @@ export class AsymmetricMessageService
|
|||||||
privateKey: keys.getValue().encryption.privateKey,
|
privateKey: keys.getValue().encryption.privateKey,
|
||||||
sender: contact.getValue(),
|
sender: contact.getValue(),
|
||||||
ownUserUuid: this.sessions.userUuid,
|
ownUserUuid: this.sessions.userUuid,
|
||||||
message,
|
payload: message,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (result.isFailed()) {
|
if (result.isFailed()) {
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ describe('GetTrustedPayload', () => {
|
|||||||
describe('execute', () => {
|
describe('execute', () => {
|
||||||
const mockDto = {
|
const mockDto = {
|
||||||
privateKey: 'test-private-key',
|
privateKey: 'test-private-key',
|
||||||
message: {} as AsymmetricMessageServerHash,
|
payload: {} as AsymmetricMessageServerHash,
|
||||||
sender: {} as TrustedContactInterface,
|
sender: {} as TrustedContactInterface,
|
||||||
ownUserUuid: 'test-user-uuid',
|
ownUserUuid: 'test-user-uuid',
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { AsymmetricMessageServerHash } from '@standardnotes/responses'
|
import { AsymmetricMessageServerHash, SharedVaultInviteServerHash } from '@standardnotes/responses'
|
||||||
import { AsymmetricMessagePayload, TrustedContactInterface } from '@standardnotes/models'
|
import { AsymmetricMessagePayload, TrustedContactInterface } from '@standardnotes/models'
|
||||||
import { DecryptMessage } from '../../Encryption/UseCase/Asymmetric/DecryptMessage'
|
import { DecryptMessage } from '../../Encryption/UseCase/Asymmetric/DecryptMessage'
|
||||||
import { Result, SyncUseCaseInterface } from '@standardnotes/domain-core'
|
import { Result, SyncUseCaseInterface } from '@standardnotes/domain-core'
|
||||||
@@ -8,12 +8,12 @@ export class GetTrustedPayload implements SyncUseCaseInterface<AsymmetricMessage
|
|||||||
|
|
||||||
execute<M extends AsymmetricMessagePayload>(dto: {
|
execute<M extends AsymmetricMessagePayload>(dto: {
|
||||||
privateKey: string
|
privateKey: string
|
||||||
message: AsymmetricMessageServerHash
|
payload: AsymmetricMessageServerHash | SharedVaultInviteServerHash
|
||||||
sender: TrustedContactInterface
|
sender: TrustedContactInterface
|
||||||
ownUserUuid: string
|
ownUserUuid: string
|
||||||
}): Result<M> {
|
}): Result<M> {
|
||||||
const result = this.decryptMessage.execute<M>({
|
const result = this.decryptMessage.execute<M>({
|
||||||
message: dto.message.encrypted_message,
|
message: dto.payload.encrypted_message,
|
||||||
sender: dto.sender,
|
sender: dto.sender,
|
||||||
privateKey: dto.privateKey,
|
privateKey: dto.privateKey,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { AsymmetricMessageServerHash } from '@standardnotes/responses'
|
import { AsymmetricMessageServerHash, SharedVaultInviteServerHash } from '@standardnotes/responses'
|
||||||
import { AsymmetricMessagePayload } from '@standardnotes/models'
|
import { AsymmetricMessagePayload } from '@standardnotes/models'
|
||||||
import { DecryptMessage } from '../../Encryption/UseCase/Asymmetric/DecryptMessage'
|
import { DecryptMessage } from '../../Encryption/UseCase/Asymmetric/DecryptMessage'
|
||||||
import { Result, SyncUseCaseInterface } from '@standardnotes/domain-core'
|
import { Result, SyncUseCaseInterface } from '@standardnotes/domain-core'
|
||||||
@@ -8,10 +8,10 @@ export class GetUntrustedPayload implements SyncUseCaseInterface<AsymmetricMessa
|
|||||||
|
|
||||||
execute<M extends AsymmetricMessagePayload>(dto: {
|
execute<M extends AsymmetricMessagePayload>(dto: {
|
||||||
privateKey: string
|
privateKey: string
|
||||||
message: AsymmetricMessageServerHash
|
payload: AsymmetricMessageServerHash | SharedVaultInviteServerHash
|
||||||
}): Result<M> {
|
}): Result<M> {
|
||||||
const result = this.decryptMessage.execute<M>({
|
const result = this.decryptMessage.execute<M>({
|
||||||
message: dto.message.encrypted_message,
|
message: dto.payload.encrypted_message,
|
||||||
sender: undefined,
|
sender: undefined,
|
||||||
privateKey: dto.privateKey,
|
privateKey: dto.privateKey,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,3 +1,20 @@
|
|||||||
|
import { UserInvitedToSharedVaultEvent } from '@standardnotes/domain-events'
|
||||||
|
import {
|
||||||
|
ClientDisplayableError,
|
||||||
|
SharedVaultInviteServerHash,
|
||||||
|
SharedVaultUserServerHash,
|
||||||
|
isClientDisplayableError,
|
||||||
|
isErrorResponse,
|
||||||
|
} from '@standardnotes/responses'
|
||||||
|
import { ContentType, Result } from '@standardnotes/domain-core'
|
||||||
|
import { SharedVaultInvitesServer } from '@standardnotes/api'
|
||||||
|
import {
|
||||||
|
AsymmetricMessageSharedVaultInvite,
|
||||||
|
PayloadEmitSource,
|
||||||
|
SharedVaultListingInterface,
|
||||||
|
TrustedContactInterface,
|
||||||
|
} from '@standardnotes/models'
|
||||||
|
|
||||||
import { AcceptVaultInvite } from './UseCase/AcceptVaultInvite'
|
import { AcceptVaultInvite } from './UseCase/AcceptVaultInvite'
|
||||||
import { SyncEvent, SyncEventReceivedSharedVaultInvitesData } from './../Event/SyncEvent'
|
import { SyncEvent, SyncEventReceivedSharedVaultInvitesData } from './../Event/SyncEvent'
|
||||||
import { InternalEventInterface } from './../Internal/InternalEventInterface'
|
import { InternalEventInterface } from './../Internal/InternalEventInterface'
|
||||||
@@ -15,26 +32,12 @@ import { SyncServiceInterface } from './../Sync/SyncServiceInterface'
|
|||||||
import { InternalEventBusInterface } from './../Internal/InternalEventBusInterface'
|
import { InternalEventBusInterface } from './../Internal/InternalEventBusInterface'
|
||||||
import { SessionsClientInterface } from './../Session/SessionsClientInterface'
|
import { SessionsClientInterface } from './../Session/SessionsClientInterface'
|
||||||
import { GetAllContacts } from './../Contacts/UseCase/GetAllContacts'
|
import { GetAllContacts } from './../Contacts/UseCase/GetAllContacts'
|
||||||
import {
|
|
||||||
AsymmetricMessageSharedVaultInvite,
|
|
||||||
PayloadEmitSource,
|
|
||||||
SharedVaultListingInterface,
|
|
||||||
TrustedContactInterface,
|
|
||||||
} from '@standardnotes/models'
|
|
||||||
import { VaultInviteServiceInterface } from './VaultInviteServiceInterface'
|
import { VaultInviteServiceInterface } from './VaultInviteServiceInterface'
|
||||||
import {
|
|
||||||
ClientDisplayableError,
|
|
||||||
SharedVaultInviteServerHash,
|
|
||||||
SharedVaultUserServerHash,
|
|
||||||
isClientDisplayableError,
|
|
||||||
isErrorResponse,
|
|
||||||
} from '@standardnotes/responses'
|
|
||||||
import { AbstractService } from './../Service/AbstractService'
|
import { AbstractService } from './../Service/AbstractService'
|
||||||
import { VaultInviteServiceEvent } from './VaultInviteServiceEvent'
|
import { VaultInviteServiceEvent } from './VaultInviteServiceEvent'
|
||||||
import { ContentType, Result } from '@standardnotes/domain-core'
|
|
||||||
import { SharedVaultInvitesServer } from '@standardnotes/api'
|
|
||||||
import { GetKeyPairs } from '../Encryption/UseCase/GetKeyPairs'
|
import { GetKeyPairs } from '../Encryption/UseCase/GetKeyPairs'
|
||||||
import { DecryptErroredPayloads } from '../Encryption/UseCase/DecryptErroredPayloads'
|
import { DecryptErroredPayloads } from '../Encryption/UseCase/DecryptErroredPayloads'
|
||||||
|
import { WebSocketsServiceEvent } from '../Api/WebSocketsServiceEvent'
|
||||||
|
|
||||||
export class VaultInviteService
|
export class VaultInviteService
|
||||||
extends AbstractService<VaultInviteServiceEvent>
|
extends AbstractService<VaultInviteServiceEvent>
|
||||||
@@ -98,6 +101,9 @@ export class VaultInviteService
|
|||||||
case SyncEvent.ReceivedSharedVaultInvites:
|
case SyncEvent.ReceivedSharedVaultInvites:
|
||||||
await this.processInboundInvites(event.payload as SyncEventReceivedSharedVaultInvitesData)
|
await this.processInboundInvites(event.payload as SyncEventReceivedSharedVaultInvitesData)
|
||||||
break
|
break
|
||||||
|
case WebSocketsServiceEvent.UserInvitedToSharedVault:
|
||||||
|
await this.processInboundInvites([(event as UserInvitedToSharedVaultEvent).payload.invite])
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -261,7 +267,7 @@ export class VaultInviteService
|
|||||||
const sender = this._findContact.execute({ userUuid: invite.sender_uuid })
|
const sender = this._findContact.execute({ userUuid: invite.sender_uuid })
|
||||||
if (!sender.isFailed()) {
|
if (!sender.isFailed()) {
|
||||||
const trustedMessage = this._getTrustedPayload.execute<AsymmetricMessageSharedVaultInvite>({
|
const trustedMessage = this._getTrustedPayload.execute<AsymmetricMessageSharedVaultInvite>({
|
||||||
message: invite,
|
payload: invite,
|
||||||
privateKey: keys.getValue().encryption.privateKey,
|
privateKey: keys.getValue().encryption.privateKey,
|
||||||
ownUserUuid: this.session.userUuid,
|
ownUserUuid: this.session.userUuid,
|
||||||
sender: sender.getValue(),
|
sender: sender.getValue(),
|
||||||
@@ -279,7 +285,7 @@ export class VaultInviteService
|
|||||||
}
|
}
|
||||||
|
|
||||||
const untrustedMessage = this._getUntrustedPayload.execute<AsymmetricMessageSharedVaultInvite>({
|
const untrustedMessage = this._getUntrustedPayload.execute<AsymmetricMessageSharedVaultInvite>({
|
||||||
message: invite,
|
payload: invite,
|
||||||
privateKey: keys.getValue().encryption.privateKey,
|
privateKey: keys.getValue().encryption.privateKey,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,7 @@
|
|||||||
"@standardnotes/api": "workspace:*",
|
"@standardnotes/api": "workspace:*",
|
||||||
"@standardnotes/common": "^1.50.0",
|
"@standardnotes/common": "^1.50.0",
|
||||||
"@standardnotes/domain-core": "^1.25.0",
|
"@standardnotes/domain-core": "^1.25.0",
|
||||||
"@standardnotes/domain-events": "^2.121.0",
|
"@standardnotes/domain-events": "^2.122.0",
|
||||||
"@standardnotes/encryption": "workspace:*",
|
"@standardnotes/encryption": "workspace:*",
|
||||||
"@standardnotes/features": "workspace:*",
|
"@standardnotes/features": "workspace:*",
|
||||||
"@standardnotes/files": "workspace:*",
|
"@standardnotes/files": "workspace:*",
|
||||||
|
|||||||
10
yarn.lock
10
yarn.lock
@@ -4349,13 +4349,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@standardnotes/domain-events@npm:^2.121.0":
|
"@standardnotes/domain-events@npm:^2.122.0":
|
||||||
version: 2.121.0
|
version: 2.122.0
|
||||||
resolution: "@standardnotes/domain-events@npm:2.121.0"
|
resolution: "@standardnotes/domain-events@npm:2.122.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@standardnotes/predicates": 1.6.9
|
"@standardnotes/predicates": 1.6.9
|
||||||
"@standardnotes/security": 1.12.0
|
"@standardnotes/security": 1.12.0
|
||||||
checksum: 49d4a834212f24b4469487ce6126d554e50145dee665326e2fc0536a1890febbca4e8c07e37666bfced9d5bfd36d175edfeb1483876326a4c964805993dba7ec
|
checksum: 9dd2f02f1c9c91b3380d0db88dba3e504aaa14b7e58dcb519611dd8b15edb27c111805eb0e34f1612751fb59428296a216e39b5711892f6c8f1fc1f057e61c50
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@@ -4829,7 +4829,7 @@ __metadata:
|
|||||||
"@standardnotes/api": "workspace:*"
|
"@standardnotes/api": "workspace:*"
|
||||||
"@standardnotes/common": ^1.50.0
|
"@standardnotes/common": ^1.50.0
|
||||||
"@standardnotes/domain-core": ^1.25.0
|
"@standardnotes/domain-core": ^1.25.0
|
||||||
"@standardnotes/domain-events": ^2.121.0
|
"@standardnotes/domain-events": ^2.122.0
|
||||||
"@standardnotes/encryption": "workspace:*"
|
"@standardnotes/encryption": "workspace:*"
|
||||||
"@standardnotes/features": "workspace:*"
|
"@standardnotes/features": "workspace:*"
|
||||||
"@standardnotes/files": "workspace:*"
|
"@standardnotes/files": "workspace:*"
|
||||||
|
|||||||
Reference in New Issue
Block a user