feat: remove user from all shared vaults upon account deletion (#843)

This commit is contained in:
Karol Sójko
2023-09-22 10:49:53 +02:00
committed by GitHub
parent 6515dcf487
commit dc77ff3e45
14 changed files with 220 additions and 143 deletions
@@ -0,0 +1,79 @@
import { Result, SharedVaultUser, SharedVaultUserPermission, Timestamps, Uuid } from '@standardnotes/domain-core'
import { Logger } from 'winston'
import { SharedVaultUserRepositoryInterface } from '../../../SharedVault/User/SharedVaultUserRepositoryInterface'
import { RemoveUserFromSharedVault } from '../RemoveUserFromSharedVault/RemoveUserFromSharedVault'
import { RemoveUserFromSharedVaults } from './RemoveUserFromSharedVaults'
describe('RemoveUserFromSharedVaults', () => {
let sharedVaultUserRepository: SharedVaultUserRepositoryInterface
let sharedVaultUser: SharedVaultUser
let removeUserFromSharedVault: RemoveUserFromSharedVault
let logger: Logger
const createUseCase = () =>
new RemoveUserFromSharedVaults(sharedVaultUserRepository, removeUserFromSharedVault, logger)
beforeEach(() => {
sharedVaultUser = SharedVaultUser.create({
permission: SharedVaultUserPermission.create(SharedVaultUserPermission.PERMISSIONS.Write).getValue(),
sharedVaultUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
userUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
timestamps: Timestamps.create(123, 123).getValue(),
isDesignatedSurvivor: false,
}).getValue()
sharedVaultUserRepository = {} as jest.Mocked<SharedVaultUserRepositoryInterface>
sharedVaultUserRepository.findByUserUuid = jest.fn().mockResolvedValue([sharedVaultUser])
removeUserFromSharedVault = {} as jest.Mocked<RemoveUserFromSharedVault>
removeUserFromSharedVault.execute = jest.fn().mockResolvedValue(Result.ok())
logger = {} as jest.Mocked<Logger>
logger.error = jest.fn()
})
it('should remove user from shared vaults', async () => {
const useCase = createUseCase()
const result = await useCase.execute({
userUuid: '00000000-0000-0000-0000-000000000000',
})
expect(result.isFailed()).toBeFalsy()
expect(removeUserFromSharedVault.execute).toHaveBeenCalledTimes(1)
expect(removeUserFromSharedVault.execute).toHaveBeenCalledWith({
sharedVaultUuid: '00000000-0000-0000-0000-000000000000',
originatorUuid: '00000000-0000-0000-0000-000000000000',
userUuid: '00000000-0000-0000-0000-000000000000',
forceRemoveOwner: true,
})
})
it('should log error if removing user from shared vault fails', async () => {
removeUserFromSharedVault.execute = jest.fn().mockResolvedValue(Result.fail('error'))
const useCase = createUseCase()
const result = await useCase.execute({
userUuid: '00000000-0000-0000-0000-000000000000',
})
expect(result.isFailed()).toBeFalsy()
expect(logger.error).toHaveBeenCalledTimes(1)
expect(logger.error).toHaveBeenCalledWith(
'Failed to remove user: 00000000-0000-0000-0000-000000000000 from shared vault: 00000000-0000-0000-0000-000000000000: error',
)
})
it('should fail if the user uuid is invalid', async () => {
const useCase = createUseCase()
const result = await useCase.execute({
userUuid: 'invalid',
})
expect(result.isFailed()).toBeTruthy()
expect(removeUserFromSharedVault.execute).not.toHaveBeenCalled()
})
})
@@ -0,0 +1,41 @@
import { Result, UseCaseInterface, Uuid } from '@standardnotes/domain-core'
import { SharedVaultUserRepositoryInterface } from '../../../SharedVault/User/SharedVaultUserRepositoryInterface'
import { RemoveUserFromSharedVault } from '../RemoveUserFromSharedVault/RemoveUserFromSharedVault'
import { Logger } from 'winston'
import { RemoveUserFromSharedVaultsDTO } from './RemoveUserFromSharedVaultsDTO'
export class RemoveUserFromSharedVaults implements UseCaseInterface<void> {
constructor(
private sharedVaultUserRepository: SharedVaultUserRepositoryInterface,
private removeUserFromSharedVault: RemoveUserFromSharedVault,
private logger: Logger,
) {}
async execute(dto: RemoveUserFromSharedVaultsDTO): Promise<Result<void>> {
const userUuidOrError = Uuid.create(dto.userUuid)
if (userUuidOrError.isFailed()) {
return Result.fail(userUuidOrError.getError())
}
const userUuid = userUuidOrError.getValue()
const sharedVaultUsers = await this.sharedVaultUserRepository.findByUserUuid(userUuid)
for (const sharedVaultUser of sharedVaultUsers) {
const result = await this.removeUserFromSharedVault.execute({
sharedVaultUuid: sharedVaultUser.props.sharedVaultUuid.value,
originatorUuid: userUuid.value,
userUuid: userUuid.value,
forceRemoveOwner: true,
})
if (result.isFailed()) {
this.logger.error(
`Failed to remove user: ${userUuid.value} from shared vault: ${
sharedVaultUser.props.sharedVaultUuid.value
}: ${result.getError()}`,
)
}
}
return Result.ok()
}
}
@@ -0,0 +1,3 @@
export interface RemoveUserFromSharedVaultsDTO {
userUuid: string
}