Compare commits

..

2 Commits

38 changed files with 230 additions and 34 deletions

View File

@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.27.1](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.27.0...@standardnotes/analytics@2.27.1) (2023-09-27)
**Note:** Version bump only for package @standardnotes/analytics
# [2.27.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.26.24...@standardnotes/analytics@2.27.0) (2023-09-26)
### Features

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/analytics",
"version": "2.27.0",
"version": "2.27.1",
"engines": {
"node": ">=18.0.0 <21.0.0"
},

View File

@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.75.6](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.75.5...@standardnotes/api-gateway@1.75.6) (2023-09-27)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.75.5](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.75.4...@standardnotes/api-gateway@1.75.5) (2023-09-26)
**Note:** Version bump only for package @standardnotes/api-gateway

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/api-gateway",
"version": "1.75.5",
"version": "1.75.6",
"engines": {
"node": ">=18.0.0 <21.0.0"
},

View File

@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.147.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.147.0...@standardnotes/auth-server@1.147.1) (2023-09-27)
**Note:** Version bump only for package @standardnotes/auth-server
# [1.147.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.146.4...@standardnotes/auth-server@1.147.0) (2023-09-26)
### Features

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/auth-server",
"version": "1.147.0",
"version": "1.147.1",
"engines": {
"node": ">=18.0.0 <21.0.0"
},

View File

@@ -3,6 +3,12 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.34.1](https://github.com/standardnotes/server/compare/@standardnotes/domain-core@1.34.0...@standardnotes/domain-core@1.34.1) (2023-09-27)
### Bug Fixes
* removing items in a vault and notifying about designated survivor ([#855](https://github.com/standardnotes/server/issues/855)) ([1d06ffe](https://github.com/standardnotes/server/commit/1d06ffe9d51722ada7baa040e1d5ed351fc28f39))
# [1.34.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-core@1.33.2...@standardnotes/domain-core@1.34.0) (2023-09-26)
### Features

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/domain-core",
"version": "1.34.0",
"version": "1.34.1",
"engines": {
"node": ">=18.0.0 <21.0.0"
},

View File

@@ -5,6 +5,7 @@ import { NotificationPayloadIdentifierTypeProps } from './NotificationPayloadIde
export class NotificationPayloadIdentifierType extends ValueObject<NotificationPayloadIdentifierTypeProps> {
static readonly TYPES = {
SharedVaultUuid: 'shared_vault_uuid',
UserUuid: 'user_uuid',
SharedVaultInviteUuid: 'shared_vault_invite_uuid',
ItemUuid: 'item_uuid',
}

View File

@@ -7,6 +7,7 @@ export class NotificationType extends ValueObject<NotificationTypeProps> {
SharedVaultItemRemoved: 'shared_vault_item_removed',
SelfRemovedFromSharedVault: 'self_removed_from_shared_vault',
UserRemovedFromSharedVault: 'user_removed_from_shared_vault',
UserDesignatedAsSurvivor: 'user_designated_as_survivor',
UserAddedToSharedVault: 'user_added_to_shared_vault',
SharedVaultInviteCanceled: 'shared_vault_invite_canceled',
SharedVaultFileUploaded: 'shared_vault_file_uploaded',

View File

@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.12.1](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.12.0...@standardnotes/event-store@1.12.1) (2023-09-27)
**Note:** Version bump only for package @standardnotes/event-store
# [1.12.0](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.11.52...@standardnotes/event-store@1.12.0) (2023-09-26)
### Features

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/event-store",
"version": "1.12.0",
"version": "1.12.1",
"description": "Event Store Service",
"private": true,
"main": "dist/src/index.js",

View File

@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.24.1](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.24.0...@standardnotes/files-server@1.24.1) (2023-09-27)
**Note:** Version bump only for package @standardnotes/files-server
# [1.24.0](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.23.2...@standardnotes/files-server@1.24.0) (2023-09-26)
### Features

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/files-server",
"version": "1.24.0",
"version": "1.24.1",
"engines": {
"node": ">=18.0.0 <21.0.0"
},

View File

@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.16.8](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.16.7...@standardnotes/home-server@1.16.8) (2023-09-27)
**Note:** Version bump only for package @standardnotes/home-server
## [1.16.7](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.16.6...@standardnotes/home-server@1.16.7) (2023-09-26)
**Note:** Version bump only for package @standardnotes/home-server

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/home-server",
"version": "1.16.7",
"version": "1.16.8",
"engines": {
"node": ">=18.0.0 <21.0.0"
},

View File

@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.38.1](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.38.0...@standardnotes/revisions-server@1.38.1) (2023-09-27)
**Note:** Version bump only for package @standardnotes/revisions-server
# [1.38.0](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.37.3...@standardnotes/revisions-server@1.38.0) (2023-09-26)
### Features

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/revisions-server",
"version": "1.38.0",
"version": "1.38.1",
"engines": {
"node": ">=18.0.0 <21.0.0"
},

View File

@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.21.1](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.21.0...@standardnotes/scheduler-server@1.21.1) (2023-09-27)
**Note:** Version bump only for package @standardnotes/scheduler-server
# [1.21.0](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.20.56...@standardnotes/scheduler-server@1.21.0) (2023-09-26)
### Features

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/scheduler-server",
"version": "1.21.0",
"version": "1.21.1",
"engines": {
"node": ">=18.0.0 <21.0.0"
},

View File

@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.21.41](https://github.com/standardnotes/server/compare/@standardnotes/settings@1.21.40...@standardnotes/settings@1.21.41) (2023-09-27)
**Note:** Version bump only for package @standardnotes/settings
## [1.21.40](https://github.com/standardnotes/server/compare/@standardnotes/settings@1.21.39...@standardnotes/settings@1.21.40) (2023-09-26)
**Note:** Version bump only for package @standardnotes/settings

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/settings",
"version": "1.21.40",
"version": "1.21.41",
"engines": {
"node": ">=18.0.0 <21.0.0"
},

View File

@@ -3,6 +3,12 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.109.1](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.109.0...@standardnotes/syncing-server@1.109.1) (2023-09-27)
### Bug Fixes
* removing items in a vault and notifying about designated survivor ([#855](https://github.com/standardnotes/syncing-server-js/issues/855)) ([1d06ffe](https://github.com/standardnotes/syncing-server-js/commit/1d06ffe9d51722ada7baa040e1d5ed351fc28f39))
# [1.109.0](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.108.2...@standardnotes/syncing-server@1.109.0) (2023-09-26)
### Features

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/syncing-server",
"version": "1.109.0",
"version": "1.109.1",
"engines": {
"node": ">=18.0.0 <21.0.0"
},

View File

@@ -899,6 +899,7 @@ export class ContainerConfigLoader {
container.get<TimerInterface>(TYPES.Sync_Timer),
container.get<DomainEventFactoryInterface>(TYPES.Sync_DomainEventFactory),
container.get<DomainEventPublisherInterface>(TYPES.Sync_DomainEventPublisher),
container.get<AddNotificationForUser>(TYPES.Sync_AddNotificationForUser),
),
)
container

View File

@@ -1,5 +1,5 @@
import { AccountDeletionRequestedEvent, DomainEventHandlerInterface } from '@standardnotes/domain-events'
import { RoleNameCollection } from '@standardnotes/domain-core'
import { RoleNameCollection, Uuid } from '@standardnotes/domain-core'
import { Logger } from 'winston'
import { ItemRepositoryResolverInterface } from '../Item/ItemRepositoryResolverInterface'
@@ -15,15 +15,25 @@ export class AccountDeletionRequestedEventHandler implements DomainEventHandlerI
) {}
async handle(event: AccountDeletionRequestedEvent): Promise<void> {
const userUuidOrError = Uuid.create(event.payload.userUuid)
if (userUuidOrError.isFailed()) {
this.logger.error(`AccountDeletionRequestedEventHandler failed: ${userUuidOrError.getError()}`)
return
}
const userUuid = userUuidOrError.getValue()
const roleNamesOrError = RoleNameCollection.create(event.payload.roleNames)
if (roleNamesOrError.isFailed()) {
this.logger.error(`AccountDeletionRequestedEventHandler failed: ${roleNamesOrError.getError()}`)
return
}
const roleNames = roleNamesOrError.getValue()
const itemRepository = this.itemRepositoryResolver.resolve(roleNames)
await itemRepository.deleteByUserUuid(event.payload.userUuid)
await itemRepository.deleteByUserUuidAndNotInSharedVault(userUuid)
const deletingVaultsResult = await this.deleteSharedVaults.execute({
ownerUuid: event.payload.userUuid,
@@ -34,6 +44,16 @@ export class AccountDeletionRequestedEventHandler implements DomainEventHandlerI
)
}
const deletedSharedVaultUuids = Array.from(deletingVaultsResult.getValue().keys())
this.logger.debug(
`Deleting items from shared vaults: ${deletedSharedVaultUuids.map((uuid) => uuid.value).join(', ')}`,
)
if (deletedSharedVaultUuids.length !== 0) {
await itemRepository.deleteByUserUuidInSharedVaults(userUuid, deletedSharedVaultUuids)
}
const deletingUserFromOtherVaultsResult = await this.removeUserFromSharedVaults.execute({
userUuid: event.payload.userUuid,
})

View File

@@ -6,7 +6,8 @@ import { ExtendedIntegrityPayload } from './ExtendedIntegrityPayload'
import { ItemContentSizeDescriptor } from './ItemContentSizeDescriptor'
export interface ItemRepositoryInterface {
deleteByUserUuid(userUuid: string): Promise<void>
deleteByUserUuidAndNotInSharedVault(userUuid: Uuid): Promise<void>
deleteByUserUuidInSharedVaults(userUuid: Uuid, sharedVaultUuids: Uuid[]): Promise<void>
findAll(query: ItemQuery): Promise<Item[]>
countAll(query: ItemQuery): Promise<number>
findContentSizeForComputingTransferLimit(query: ItemQuery): Promise<Array<ItemContentSizeDescriptor>>

View File

@@ -10,7 +10,7 @@ import { CancelInviteToSharedVault } from '../CancelInviteToSharedVault/CancelIn
import { DomainEventFactoryInterface } from '../../../Event/DomainEventFactoryInterface'
import { TransferSharedVault } from '../TransferSharedVault/TransferSharedVault'
export class DeleteSharedVault implements UseCaseInterface<void> {
export class DeleteSharedVault implements UseCaseInterface<{ status: 'deleted' | 'transitioned' }> {
constructor(
private sharedVaultRepository: SharedVaultRepositoryInterface,
private sharedVaultUserRepository: SharedVaultUserRepositoryInterface,
@@ -22,7 +22,7 @@ export class DeleteSharedVault implements UseCaseInterface<void> {
private transferSharedVault: TransferSharedVault,
) {}
async execute(dto: DeleteSharedVaultDTO): Promise<Result<void>> {
async execute(dto: DeleteSharedVaultDTO): Promise<Result<{ status: 'deleted' | 'transitioned' }>> {
const originatorUuidOrError = Uuid.create(dto.originatorUuid)
if (originatorUuidOrError.isFailed()) {
return Result.fail(originatorUuidOrError.getError())
@@ -79,7 +79,7 @@ export class DeleteSharedVault implements UseCaseInterface<void> {
return Result.fail(removingOwnerFromSharedVaultResult.getError())
}
return Result.ok()
return Result.ok({ status: 'transitioned' })
}
const sharedVaultUsers = await this.sharedVaultUserRepository.findBySharedVaultUuid(sharedVaultUuid)
@@ -105,6 +105,6 @@ export class DeleteSharedVault implements UseCaseInterface<void> {
}),
)
return Result.ok()
return Result.ok({ status: 'deleted' })
}
}

View File

@@ -24,7 +24,7 @@ describe('DeleteSharedVaults', () => {
sharedVaultRepository.findByUserUuid = jest.fn().mockResolvedValue([sharedVault])
deleteSharedVaultUseCase = {} as jest.Mocked<DeleteSharedVault>
deleteSharedVaultUseCase.execute = jest.fn().mockResolvedValue(Result.ok())
deleteSharedVaultUseCase.execute = jest.fn().mockResolvedValue(Result.ok({ status: 'deleted' }))
})
it('should delete all shared vaults for a user', async () => {

View File

@@ -4,13 +4,13 @@ import { DeleteSharedVaultsDTO } from './DeleteSharedVaultsDTO'
import { DeleteSharedVault } from '../DeleteSharedVault/DeleteSharedVault'
import { SharedVaultRepositoryInterface } from '../../../SharedVault/SharedVaultRepositoryInterface'
export class DeleteSharedVaults implements UseCaseInterface<void> {
export class DeleteSharedVaults implements UseCaseInterface<Map<Uuid, 'deleted' | 'transitioned'>> {
constructor(
private sharedVaultRepository: SharedVaultRepositoryInterface,
private deleteSharedVaultUseCase: DeleteSharedVault,
) {}
async execute(dto: DeleteSharedVaultsDTO): Promise<Result<void>> {
async execute(dto: DeleteSharedVaultsDTO): Promise<Result<Map<Uuid, 'deleted' | 'transitioned'>>> {
const ownerUuidOrError = Uuid.create(dto.ownerUuid)
if (ownerUuidOrError.isFailed()) {
return Result.fail(ownerUuidOrError.getError())
@@ -19,6 +19,7 @@ export class DeleteSharedVaults implements UseCaseInterface<void> {
const sharedVaults = await this.sharedVaultRepository.findByUserUuid(ownerUuid)
const results = new Map<Uuid, 'deleted' | 'transitioned'>()
for (const sharedVault of sharedVaults) {
const result = await this.deleteSharedVaultUseCase.execute({
originatorUuid: ownerUuid.value,
@@ -27,8 +28,10 @@ export class DeleteSharedVaults implements UseCaseInterface<void> {
if (result.isFailed()) {
return Result.fail(result.getError())
}
results.set(sharedVault.uuid, result.getValue().status)
}
return Result.ok()
return Result.ok(results)
}
}

View File

@@ -1,4 +1,11 @@
import { SharedVaultUser, SharedVaultUserPermission, Timestamps, Uuid } from '@standardnotes/domain-core'
import {
NotificationPayload,
Result,
SharedVaultUser,
SharedVaultUserPermission,
Timestamps,
Uuid,
} from '@standardnotes/domain-core'
import { SharedVaultUserRepositoryInterface } from '../../../SharedVault/User/SharedVaultUserRepositoryInterface'
import { DesignateSurvivor } from './DesignateSurvivor'
@@ -7,6 +14,7 @@ import { DomainEventInterface, DomainEventPublisherInterface } from '@standardno
import { DomainEventFactoryInterface } from '../../../Event/DomainEventFactoryInterface'
import { SharedVault } from '../../../SharedVault/SharedVault'
import { SharedVaultRepositoryInterface } from '../../../SharedVault/SharedVaultRepositoryInterface'
import { AddNotificationForUser } from '../../Messaging/AddNotificationForUser/AddNotificationForUser'
describe('DesignateSurvivor', () => {
let sharedVault: SharedVault
@@ -17,6 +25,7 @@ describe('DesignateSurvivor', () => {
let timer: TimerInterface
let domainEventFactory: DomainEventFactoryInterface
let domainEventPublisher: DomainEventPublisherInterface
let addNotificationForUser: AddNotificationForUser
const createUseCase = () =>
new DesignateSurvivor(
@@ -25,6 +34,7 @@ describe('DesignateSurvivor', () => {
timer,
domainEventFactory,
domainEventPublisher,
addNotificationForUser,
)
beforeEach(() => {
@@ -68,6 +78,9 @@ describe('DesignateSurvivor', () => {
domainEventPublisher = {} as jest.Mocked<DomainEventPublisherInterface>
domainEventPublisher.publish = jest.fn()
addNotificationForUser = {} as jest.Mocked<AddNotificationForUser>
addNotificationForUser.execute = jest.fn().mockReturnValue(Result.ok())
})
it('should fail if shared vault uuid is invalid', async () => {
@@ -189,4 +202,39 @@ describe('DesignateSurvivor', () => {
expect(sharedVaultUser.props.isDesignatedSurvivor).toBe(true)
expect(sharedVaultUserRepository.save).toBeCalledTimes(2)
})
it('should fail if it fails to add notification for user', async () => {
sharedVaultUserRepository.findBySharedVaultUuid = jest.fn().mockReturnValue([sharedVaultOwner, sharedVaultUser])
addNotificationForUser.execute = jest.fn().mockReturnValue(Result.fail('Failed to add notification'))
const useCase = createUseCase()
const result = await useCase.execute({
sharedVaultUuid: '00000000-0000-0000-0000-000000000000',
userUuid: '00000000-0000-0000-0000-000000000000',
originatorUuid: '00000000-0000-0000-0000-000000000002',
})
expect(result.isFailed()).toBe(true)
})
it('should fail if it fails to create notification payload', async () => {
sharedVaultUserRepository.findBySharedVaultUuid = jest.fn().mockReturnValue([sharedVaultOwner, sharedVaultUser])
const mock = jest.spyOn(NotificationPayload, 'create')
mock.mockReturnValue(Result.fail('Oops'))
const useCase = createUseCase()
const result = await useCase.execute({
sharedVaultUuid: '00000000-0000-0000-0000-000000000000',
userUuid: '00000000-0000-0000-0000-000000000000',
originatorUuid: '00000000-0000-0000-0000-000000000002',
})
expect(result.isFailed()).toBe(true)
mock.mockRestore()
})
})

View File

@@ -1,6 +1,9 @@
import { TimerInterface } from '@standardnotes/time'
import { DomainEventPublisherInterface } from '@standardnotes/domain-events'
import {
NotificationPayload,
NotificationPayloadIdentifierType,
NotificationType,
Result,
SharedVaultUser,
SharedVaultUserPermission,
@@ -13,6 +16,7 @@ import { SharedVaultUserRepositoryInterface } from '../../../SharedVault/User/Sh
import { DesignateSurvivorDTO } from './DesignateSurvivorDTO'
import { DomainEventFactoryInterface } from '../../../Event/DomainEventFactoryInterface'
import { SharedVaultRepositoryInterface } from '../../../SharedVault/SharedVaultRepositoryInterface'
import { AddNotificationForUser } from '../../Messaging/AddNotificationForUser/AddNotificationForUser'
export class DesignateSurvivor implements UseCaseInterface<void> {
constructor(
@@ -21,6 +25,7 @@ export class DesignateSurvivor implements UseCaseInterface<void> {
private timer: TimerInterface,
private domainEventFactory: DomainEventFactoryInterface,
private domainEventPublisher: DomainEventPublisherInterface,
private addNotificationForUser: AddNotificationForUser,
) {}
async execute(dto: DesignateSurvivorDTO): Promise<Result<void>> {
@@ -91,6 +96,13 @@ export class DesignateSurvivor implements UseCaseInterface<void> {
await this.sharedVaultUserRepository.save(toBeDesignatedAsASurvivor)
sharedVault.props.timestamps = Timestamps.create(
sharedVault.props.timestamps.createdAt,
this.timer.getTimestampInMicroseconds(),
).getValue()
await this.sharedVaultRepository.save(sharedVault)
await this.domainEventPublisher.publish(
this.domainEventFactory.createUserDesignatedAsSurvivorInSharedVaultEvent({
sharedVaultUuid: sharedVaultUuid.value,
@@ -99,12 +111,32 @@ export class DesignateSurvivor implements UseCaseInterface<void> {
}),
)
sharedVault.props.timestamps = Timestamps.create(
sharedVault.props.timestamps.createdAt,
this.timer.getTimestampInMicroseconds(),
).getValue()
const notificationPayloadOrError = NotificationPayload.create({
primaryIdentifier: sharedVault.uuid,
primaryIndentifierType: NotificationPayloadIdentifierType.create(
NotificationPayloadIdentifierType.TYPES.SharedVaultUuid,
).getValue(),
secondaryIdentifier: userUuid,
secondaryIdentifierType: NotificationPayloadIdentifierType.create(
NotificationPayloadIdentifierType.TYPES.UserUuid,
).getValue(),
type: NotificationType.create(NotificationType.TYPES.UserDesignatedAsSurvivor).getValue(),
version: '1.0',
})
if (notificationPayloadOrError.isFailed()) {
return Result.fail(notificationPayloadOrError.getError())
}
const notificationPayload = notificationPayloadOrError.getValue()
await this.sharedVaultRepository.save(sharedVault)
const result = await this.addNotificationForUser.execute({
userUuid: sharedVault.props.userUuid.value,
type: NotificationType.TYPES.UserDesignatedAsSurvivor,
payload: notificationPayload,
version: '1.0',
})
if (result.isFailed()) {
return Result.fail(result.getError())
}
return Result.ok()
}

View File

@@ -153,7 +153,7 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
try {
this.logger.info(`[${userUuid.value}] Cleaning up primary database items`)
await itemRepository.deleteByUserUuid(userUuid.value)
await itemRepository.deleteByUserUuidAndNotInSharedVault(userUuid)
return Result.ok()
} catch (error) {

View File

@@ -17,6 +17,15 @@ export class MongoDBItemRepository implements ItemRepositoryInterface {
private logger: Logger,
) {}
async deleteByUserUuidInSharedVaults(userUuid: Uuid, sharedVaultUuids: Uuid[]): Promise<void> {
await this.mongoRepository.deleteMany({
$and: [
{ userUuid: { $eq: userUuid.value } },
{ sharedVaultUuid: { $in: sharedVaultUuids.map((uuid) => uuid.value) } },
],
})
}
async updateSharedVaultOwner(dto: { sharedVaultUuid: Uuid; fromOwnerUuid: Uuid; toOwnerUuid: Uuid }): Promise<void> {
await this.mongoRepository.updateMany(
{
@@ -37,8 +46,10 @@ export class MongoDBItemRepository implements ItemRepositoryInterface {
await this.mongoRepository.deleteOne({ _id: { $eq: BSON.UUID.createFromHexString(uuid.value) } })
}
async deleteByUserUuid(userUuid: string): Promise<void> {
await this.mongoRepository.deleteMany({ userUuid })
async deleteByUserUuidAndNotInSharedVault(userUuid: Uuid): Promise<void> {
await this.mongoRepository.deleteMany({
$and: [{ userUuid: { $eq: userUuid.value } }, { sharedVaultUuid: { $eq: null } }],
})
}
async findAll(query: ItemQuery): Promise<Item[]> {

View File

@@ -16,6 +16,28 @@ export class SQLItemRepository extends SQLLegacyItemRepository {
super(ormRepository, mapper, logger)
}
override async deleteByUserUuidInSharedVaults(userUuid: Uuid, sharedVaultUuids: Uuid[]): Promise<void> {
await this.ormRepository
.createQueryBuilder('item')
.delete()
.from('items')
.where('user_uuid = :userUuid', { userUuid: userUuid.value })
.andWhere('shared_vault_uuid IN (:...sharedVaultUuids)', {
sharedVaultUuids: sharedVaultUuids.map((uuid) => uuid.value),
})
.execute()
}
override async deleteByUserUuidAndNotInSharedVault(userUuid: Uuid): Promise<void> {
await this.ormRepository
.createQueryBuilder('item')
.delete()
.from('items')
.where('user_uuid = :userUuid', { userUuid: userUuid.value })
.andWhere('shared_vault_uuid IS NULL')
.execute()
}
override async updateSharedVaultOwner(dto: {
sharedVaultUuid: Uuid
fromOwnerUuid: Uuid

View File

@@ -16,6 +16,10 @@ export class SQLLegacyItemRepository implements ItemRepositoryInterface {
protected logger: Logger,
) {}
async deleteByUserUuidInSharedVaults(_userUuid: Uuid, _sharedVaultUuids: Uuid[]): Promise<void> {
this.logger.error('Method deleteByUserUuidInSharedVaults not supported.')
}
async updateSharedVaultOwner(_dto: { sharedVaultUuid: Uuid; fromOwnerUuid: Uuid; toOwnerUuid: Uuid }): Promise<void> {
this.logger.error('Method updateSharedVaultOwner not supported.')
}
@@ -80,12 +84,12 @@ export class SQLLegacyItemRepository implements ItemRepositoryInterface {
return itemContentSizeDescriptors
}
async deleteByUserUuid(userUuid: string): Promise<void> {
async deleteByUserUuidAndNotInSharedVault(userUuid: Uuid): Promise<void> {
await this.ormRepository
.createQueryBuilder('item')
.delete()
.from('items')
.where('user_uuid = :userUuid', { userUuid })
.where('user_uuid = :userUuid', { userUuid: userUuid.value })
.execute()
}

View File

@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.11.1](https://github.com/standardnotes/server/compare/@standardnotes/websockets-server@1.11.0...@standardnotes/websockets-server@1.11.1) (2023-09-27)
**Note:** Version bump only for package @standardnotes/websockets-server
# [1.11.0](https://github.com/standardnotes/server/compare/@standardnotes/websockets-server@1.10.53...@standardnotes/websockets-server@1.11.0) (2023-09-26)
### Features

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/websockets-server",
"version": "1.11.0",
"version": "1.11.1",
"engines": {
"node": ">=18.0.0 <21.0.0"
},