mirror of
https://github.com/standardnotes/server
synced 2026-10-13 00:13:41 -04:00
feat: add creating shared vault file valet tokens. (#635)
Co-authored-by: Mo <[email protected]>
This commit is contained in:
+363
@@ -0,0 +1,363 @@
|
||||
import { SharedVaultValetTokenData, TokenEncoderInterface, ValetTokenOperation } from '@standardnotes/security'
|
||||
import { SharedVaultRepositoryInterface } from '../../SharedVault/SharedVaultRepositoryInterface'
|
||||
import { SharedVaultUserRepositoryInterface } from '../../SharedVault/User/SharedVaultUserRepositoryInterface'
|
||||
import { CreateSharedVaultFileValetToken } from './CreateSharedVaultFileValetToken'
|
||||
import { SharedVault } from '../../SharedVault/SharedVault'
|
||||
import { SharedVaultUser } from '../../SharedVault/User/SharedVaultUser'
|
||||
import { SharedVaultUserPermission } from '../../SharedVault/User/SharedVaultUserPermission'
|
||||
import { Timestamps, Uuid } from '@standardnotes/domain-core'
|
||||
|
||||
describe('CreateSharedVaultFileValetToken', () => {
|
||||
let sharedVaultRepository: SharedVaultRepositoryInterface
|
||||
let sharedVaultUserRepository: SharedVaultUserRepositoryInterface
|
||||
let tokenEncoder: TokenEncoderInterface<SharedVaultValetTokenData>
|
||||
const valetTokenTTL = 3600
|
||||
let sharedVault: SharedVault
|
||||
let sharedVaultUser: SharedVaultUser
|
||||
|
||||
const createUseCase = () =>
|
||||
new CreateSharedVaultFileValetToken(sharedVaultRepository, sharedVaultUserRepository, tokenEncoder, valetTokenTTL)
|
||||
|
||||
beforeEach(() => {
|
||||
sharedVault = SharedVault.create({
|
||||
fileUploadBytesLimit: 100,
|
||||
fileUploadBytesUsed: 2,
|
||||
userUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
|
||||
timestamps: Timestamps.create(123, 123).getValue(),
|
||||
}).getValue()
|
||||
|
||||
sharedVaultRepository = {} as jest.Mocked<SharedVaultRepositoryInterface>
|
||||
sharedVaultRepository.findByUuid = jest.fn().mockResolvedValue(sharedVault)
|
||||
|
||||
sharedVaultUser = SharedVaultUser.create({
|
||||
permission: SharedVaultUserPermission.create(SharedVaultUserPermission.PERMISSIONS.Read).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(),
|
||||
}).getValue()
|
||||
|
||||
sharedVaultUserRepository = {} as jest.Mocked<SharedVaultUserRepositoryInterface>
|
||||
sharedVaultUserRepository.findByUserUuidAndSharedVaultUuid = jest.fn().mockResolvedValue(sharedVaultUser)
|
||||
|
||||
tokenEncoder = {} as jest.Mocked<TokenEncoderInterface<SharedVaultValetTokenData>>
|
||||
tokenEncoder.encodeExpirableToken = jest.fn().mockReturnValue('encoded-token')
|
||||
})
|
||||
|
||||
it('should return error when shared vault uuid is invalid', async () => {
|
||||
const useCase = createUseCase()
|
||||
const result = await useCase.execute({
|
||||
userUuid: '00000000-0000-0000-0000-000000000000',
|
||||
sharedVaultUuid: 'invalid-uuid',
|
||||
remoteIdentifier: 'remote-identifier',
|
||||
operation: ValetTokenOperation.Read,
|
||||
})
|
||||
|
||||
expect(result.isFailed()).toBe(true)
|
||||
expect(result.getError()).toBe('Given value is not a valid uuid: invalid-uuid')
|
||||
})
|
||||
|
||||
it('should return error when user uuid is invalid', async () => {
|
||||
const useCase = createUseCase()
|
||||
const result = await useCase.execute({
|
||||
userUuid: 'invalid-uuid',
|
||||
sharedVaultUuid: '00000000-0000-0000-0000-000000000000',
|
||||
remoteIdentifier: 'remote-identifier',
|
||||
operation: ValetTokenOperation.Read,
|
||||
})
|
||||
|
||||
expect(result.isFailed()).toBe(true)
|
||||
expect(result.getError()).toBe('Given value is not a valid uuid: invalid-uuid')
|
||||
})
|
||||
|
||||
it('should return error when shared vault is not found', async () => {
|
||||
sharedVaultRepository.findByUuid = jest.fn().mockResolvedValue(null)
|
||||
|
||||
const useCase = createUseCase()
|
||||
const result = await useCase.execute({
|
||||
userUuid: '00000000-0000-0000-0000-000000000000',
|
||||
sharedVaultUuid: '00000000-0000-0000-0000-000000000000',
|
||||
remoteIdentifier: 'remote-identifier',
|
||||
operation: ValetTokenOperation.Read,
|
||||
})
|
||||
|
||||
expect(result.isFailed()).toBe(true)
|
||||
expect(result.getError()).toBe('Shared vault not found')
|
||||
})
|
||||
|
||||
it('should return error when shared vault user is not found', async () => {
|
||||
sharedVaultUserRepository.findByUserUuidAndSharedVaultUuid = jest.fn().mockResolvedValue(null)
|
||||
|
||||
const useCase = createUseCase()
|
||||
const result = await useCase.execute({
|
||||
userUuid: '00000000-0000-0000-0000-000000000000',
|
||||
sharedVaultUuid: '00000000-0000-0000-0000-000000000000',
|
||||
remoteIdentifier: 'remote-identifier',
|
||||
operation: ValetTokenOperation.Read,
|
||||
})
|
||||
|
||||
expect(result.isFailed()).toBe(true)
|
||||
expect(result.getError()).toBe('Shared vault user not found')
|
||||
})
|
||||
|
||||
it('should return error when shared vault user does not have permission', async () => {
|
||||
const useCase = createUseCase()
|
||||
const result = await useCase.execute({
|
||||
userUuid: '00000000-0000-0000-0000-000000000000',
|
||||
sharedVaultUuid: '00000000-0000-0000-0000-000000000000',
|
||||
remoteIdentifier: 'remote-identifier',
|
||||
operation: ValetTokenOperation.Write,
|
||||
})
|
||||
|
||||
expect(result.isFailed()).toBe(true)
|
||||
expect(result.getError()).toBe('User does not have permission to perform this operation')
|
||||
})
|
||||
|
||||
it('should create a shared vault file valet token', async () => {
|
||||
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(),
|
||||
}).getValue()
|
||||
sharedVaultUserRepository.findByUserUuidAndSharedVaultUuid = jest.fn().mockResolvedValue(sharedVaultUser)
|
||||
|
||||
const useCase = createUseCase()
|
||||
const result = await useCase.execute({
|
||||
userUuid: '00000000-0000-0000-0000-000000000000',
|
||||
sharedVaultUuid: '00000000-0000-0000-0000-000000000000',
|
||||
remoteIdentifier: 'remote-identifier',
|
||||
operation: ValetTokenOperation.Write,
|
||||
})
|
||||
|
||||
expect(result.isFailed()).toBe(false)
|
||||
expect(result.getValue()).toBe('encoded-token')
|
||||
})
|
||||
|
||||
describe('move operation', () => {
|
||||
beforeEach(() => {
|
||||
sharedVaultUserRepository.findByUserUuidAndSharedVaultUuid = jest
|
||||
.fn()
|
||||
.mockReturnValueOnce(
|
||||
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(),
|
||||
}).getValue(),
|
||||
)
|
||||
.mockReturnValueOnce(
|
||||
SharedVaultUser.create({
|
||||
permission: SharedVaultUserPermission.create(SharedVaultUserPermission.PERMISSIONS.Read).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(),
|
||||
}).getValue(),
|
||||
)
|
||||
})
|
||||
|
||||
it('should return error when move operation type is not specified', async () => {
|
||||
const useCase = createUseCase()
|
||||
const result = await useCase.execute({
|
||||
userUuid: '00000000-0000-0000-0000-000000000000',
|
||||
sharedVaultUuid: '00000000-0000-0000-0000-000000000000',
|
||||
remoteIdentifier: 'remote-identifier',
|
||||
operation: ValetTokenOperation.Move,
|
||||
})
|
||||
|
||||
expect(result.isFailed()).toBe(true)
|
||||
expect(result.getError()).toBe('Move operation type is required')
|
||||
})
|
||||
|
||||
it('should return error when target uuid is missing on a shared-vault-to-shared-vault move operation', async () => {
|
||||
const useCase = createUseCase()
|
||||
const result = await useCase.execute({
|
||||
userUuid: '00000000-0000-0000-0000-000000000000',
|
||||
sharedVaultUuid: '00000000-0000-0000-0000-000000000000',
|
||||
remoteIdentifier: 'remote-identifier',
|
||||
operation: ValetTokenOperation.Move,
|
||||
moveOperationType: 'shared-vault-to-shared-vault',
|
||||
})
|
||||
|
||||
expect(result.isFailed()).toBe(true)
|
||||
expect(result.getError()).toBe('Shared vault to shared vault move target uuid is required')
|
||||
})
|
||||
|
||||
it('should return error when target uuid is invalid on a shared-vault-to-shared-vault move operation', async () => {
|
||||
const useCase = createUseCase()
|
||||
const result = await useCase.execute({
|
||||
userUuid: '00000000-0000-0000-0000-000000000000',
|
||||
sharedVaultUuid: '00000000-0000-0000-0000-000000000000',
|
||||
remoteIdentifier: 'remote-identifier',
|
||||
operation: ValetTokenOperation.Move,
|
||||
moveOperationType: 'shared-vault-to-shared-vault',
|
||||
sharedVaultToSharedVaultMoveTargetUuid: 'invalid-uuid',
|
||||
})
|
||||
|
||||
expect(result.isFailed()).toBe(true)
|
||||
expect(result.getError()).toBe('Given value is not a valid uuid: invalid-uuid')
|
||||
})
|
||||
|
||||
it('should return error when target shared vault user is not found on a shared-vault-to-shared-vault move operation', async () => {
|
||||
sharedVaultUserRepository.findByUserUuidAndSharedVaultUuid = jest
|
||||
.fn()
|
||||
.mockReturnValueOnce(
|
||||
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(),
|
||||
}).getValue(),
|
||||
)
|
||||
.mockReturnValueOnce(null)
|
||||
|
||||
const useCase = createUseCase()
|
||||
const result = await useCase.execute({
|
||||
userUuid: '00000000-0000-0000-0000-000000000000',
|
||||
sharedVaultUuid: '00000000-0000-0000-0000-000000000000',
|
||||
remoteIdentifier: 'remote-identifier',
|
||||
operation: ValetTokenOperation.Move,
|
||||
moveOperationType: 'shared-vault-to-shared-vault',
|
||||
sharedVaultToSharedVaultMoveTargetUuid: '00000000-0000-0000-0000-000000000000',
|
||||
})
|
||||
|
||||
expect(result.isFailed()).toBe(true)
|
||||
expect(result.getError()).toBe('Shared vault target user not found')
|
||||
})
|
||||
|
||||
it('should return error when target shared vault user does not have permission on a shared-vault-to-shared-vault move operation', async () => {
|
||||
sharedVaultUserRepository.findByUserUuidAndSharedVaultUuid = jest
|
||||
.fn()
|
||||
.mockReturnValueOnce(
|
||||
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(),
|
||||
}).getValue(),
|
||||
)
|
||||
.mockReturnValueOnce(
|
||||
SharedVaultUser.create({
|
||||
permission: SharedVaultUserPermission.create(SharedVaultUserPermission.PERMISSIONS.Read).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(),
|
||||
}).getValue(),
|
||||
)
|
||||
|
||||
const useCase = createUseCase()
|
||||
const result = await useCase.execute({
|
||||
userUuid: '00000000-0000-0000-0000-000000000000',
|
||||
sharedVaultUuid: '00000000-0000-0000-0000-000000000000',
|
||||
remoteIdentifier: 'remote-identifier',
|
||||
operation: ValetTokenOperation.Move,
|
||||
moveOperationType: 'shared-vault-to-shared-vault',
|
||||
sharedVaultToSharedVaultMoveTargetUuid: '00000000-0000-0000-0000-000000000000',
|
||||
})
|
||||
|
||||
expect(result.isFailed()).toBe(true)
|
||||
expect(result.getError()).toBe('User does not have permission to perform this operation')
|
||||
})
|
||||
|
||||
it('should create move valet token for shared-vault-to-shared-vault operation', async () => {
|
||||
sharedVaultUserRepository.findByUserUuidAndSharedVaultUuid = jest
|
||||
.fn()
|
||||
.mockReturnValueOnce(
|
||||
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(),
|
||||
}).getValue(),
|
||||
)
|
||||
.mockReturnValueOnce(
|
||||
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(),
|
||||
}).getValue(),
|
||||
)
|
||||
|
||||
const useCase = createUseCase()
|
||||
const result = await useCase.execute({
|
||||
userUuid: '00000000-0000-0000-0000-000000000000',
|
||||
sharedVaultUuid: '00000000-0000-0000-0000-000000000000',
|
||||
remoteIdentifier: 'remote-identifier',
|
||||
operation: ValetTokenOperation.Move,
|
||||
moveOperationType: 'shared-vault-to-shared-vault',
|
||||
sharedVaultToSharedVaultMoveTargetUuid: '00000000-0000-0000-0000-000000000000',
|
||||
})
|
||||
|
||||
expect(result.isFailed()).toBe(false)
|
||||
expect(result.getValue()).toBe('encoded-token')
|
||||
})
|
||||
|
||||
it('should create move valet token for shared-vault-to-user operation', async () => {
|
||||
sharedVaultUserRepository.findByUserUuidAndSharedVaultUuid = jest
|
||||
.fn()
|
||||
.mockReturnValueOnce(
|
||||
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(),
|
||||
}).getValue(),
|
||||
)
|
||||
.mockReturnValueOnce(
|
||||
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(),
|
||||
}).getValue(),
|
||||
)
|
||||
|
||||
const useCase = createUseCase()
|
||||
const result = await useCase.execute({
|
||||
userUuid: '00000000-0000-0000-0000-000000000000',
|
||||
sharedVaultUuid: '00000000-0000-0000-0000-000000000000',
|
||||
remoteIdentifier: 'remote-identifier',
|
||||
operation: ValetTokenOperation.Move,
|
||||
moveOperationType: 'shared-vault-to-user',
|
||||
sharedVaultToSharedVaultMoveTargetUuid: '00000000-0000-0000-0000-000000000000',
|
||||
})
|
||||
|
||||
expect(result.isFailed()).toBe(false)
|
||||
expect(result.getValue()).toBe('encoded-token')
|
||||
})
|
||||
|
||||
it('should create move valet token for user-to-shared-vault operation', async () => {
|
||||
sharedVaultUserRepository.findByUserUuidAndSharedVaultUuid = jest
|
||||
.fn()
|
||||
.mockReturnValueOnce(
|
||||
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(),
|
||||
}).getValue(),
|
||||
)
|
||||
.mockReturnValueOnce(
|
||||
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(),
|
||||
}).getValue(),
|
||||
)
|
||||
|
||||
const useCase = createUseCase()
|
||||
const result = await useCase.execute({
|
||||
userUuid: '00000000-0000-0000-0000-000000000000',
|
||||
sharedVaultUuid: '00000000-0000-0000-0000-000000000000',
|
||||
remoteIdentifier: 'remote-identifier',
|
||||
operation: ValetTokenOperation.Move,
|
||||
moveOperationType: 'user-to-shared-vault',
|
||||
sharedVaultToSharedVaultMoveTargetUuid: '00000000-0000-0000-0000-000000000000',
|
||||
})
|
||||
|
||||
expect(result.isFailed()).toBe(false)
|
||||
expect(result.getValue()).toBe('encoded-token')
|
||||
})
|
||||
})
|
||||
})
|
||||
+124
@@ -0,0 +1,124 @@
|
||||
import { SharedVaultValetTokenData, TokenEncoderInterface, ValetTokenOperation } from '@standardnotes/security'
|
||||
|
||||
import { SharedVaultRepositoryInterface } from '../../SharedVault/SharedVaultRepositoryInterface'
|
||||
import { Result, UseCaseInterface, Uuid } from '@standardnotes/domain-core'
|
||||
import { SharedVaultUserRepositoryInterface } from '../../SharedVault/User/SharedVaultUserRepositoryInterface'
|
||||
import { CreateSharedVaultFileValetTokenDTO } from './CreateSharedVaultFileValetTokenDTO'
|
||||
import { SharedVaultUserPermission } from '../../SharedVault/User/SharedVaultUserPermission'
|
||||
|
||||
export class CreateSharedVaultFileValetToken implements UseCaseInterface<string> {
|
||||
constructor(
|
||||
private sharedVaultRepository: SharedVaultRepositoryInterface,
|
||||
private sharedVaultUserRepository: SharedVaultUserRepositoryInterface,
|
||||
private tokenEncoder: TokenEncoderInterface<SharedVaultValetTokenData>,
|
||||
private valetTokenTTL: number,
|
||||
) {}
|
||||
|
||||
async execute(dto: CreateSharedVaultFileValetTokenDTO): Promise<Result<string>> {
|
||||
const sharedVaultUuidOrError = Uuid.create(dto.sharedVaultUuid)
|
||||
if (sharedVaultUuidOrError.isFailed()) {
|
||||
return Result.fail(sharedVaultUuidOrError.getError())
|
||||
}
|
||||
const sharedVaultUuid = sharedVaultUuidOrError.getValue()
|
||||
|
||||
const userUuidOrError = Uuid.create(dto.userUuid)
|
||||
if (userUuidOrError.isFailed()) {
|
||||
return Result.fail(userUuidOrError.getError())
|
||||
}
|
||||
const userUuid = userUuidOrError.getValue()
|
||||
|
||||
const sharedVault = await this.sharedVaultRepository.findByUuid(sharedVaultUuid)
|
||||
if (!sharedVault) {
|
||||
return Result.fail('Shared vault not found')
|
||||
}
|
||||
|
||||
const sharedVaultUser = await this.sharedVaultUserRepository.findByUserUuidAndSharedVaultUuid({
|
||||
userUuid: userUuid,
|
||||
sharedVaultUuid: sharedVaultUuid,
|
||||
})
|
||||
if (!sharedVaultUser) {
|
||||
return Result.fail('Shared vault user not found')
|
||||
}
|
||||
|
||||
if (
|
||||
sharedVaultUser.props.permission.value === SharedVaultUserPermission.PERMISSIONS.Read &&
|
||||
dto.operation !== ValetTokenOperation.Read
|
||||
) {
|
||||
return Result.fail('User does not have permission to perform this operation')
|
||||
}
|
||||
|
||||
if (dto.operation === ValetTokenOperation.Move) {
|
||||
if (!dto.moveOperationType) {
|
||||
return Result.fail('Move operation type is required')
|
||||
}
|
||||
|
||||
if (dto.moveOperationType === 'shared-vault-to-shared-vault') {
|
||||
if (!dto.sharedVaultToSharedVaultMoveTargetUuid) {
|
||||
return Result.fail('Shared vault to shared vault move target uuid is required')
|
||||
}
|
||||
|
||||
const sharedVaultTargetUuidOrError = Uuid.create(dto.sharedVaultToSharedVaultMoveTargetUuid)
|
||||
if (sharedVaultTargetUuidOrError.isFailed()) {
|
||||
return Result.fail(sharedVaultTargetUuidOrError.getError())
|
||||
}
|
||||
const sharedVaultTargetUuid = sharedVaultTargetUuidOrError.getValue()
|
||||
|
||||
const toSharedVaultUser = await this.sharedVaultUserRepository.findByUserUuidAndSharedVaultUuid({
|
||||
userUuid: userUuid,
|
||||
sharedVaultUuid: sharedVaultTargetUuid,
|
||||
})
|
||||
|
||||
if (!toSharedVaultUser) {
|
||||
return Result.fail('Shared vault target user not found')
|
||||
}
|
||||
|
||||
if (toSharedVaultUser.props.permission.value === SharedVaultUserPermission.PERMISSIONS.Read) {
|
||||
return Result.fail('User does not have permission to perform this operation')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const tokenData: SharedVaultValetTokenData = {
|
||||
sharedVaultUuid: dto.sharedVaultUuid,
|
||||
permittedOperation: dto.operation,
|
||||
remoteIdentifier: dto.remoteIdentifier,
|
||||
uploadBytesUsed: sharedVault.props.fileUploadBytesUsed,
|
||||
uploadBytesLimit: sharedVault.props.fileUploadBytesLimit,
|
||||
unencryptedFileSize: dto.unencryptedFileSize,
|
||||
moveOperation: this.createMoveOperationData(dto),
|
||||
}
|
||||
|
||||
const valetToken = this.tokenEncoder.encodeExpirableToken(tokenData, this.valetTokenTTL)
|
||||
|
||||
return Result.ok(valetToken)
|
||||
}
|
||||
|
||||
private createMoveOperationData(dto: CreateSharedVaultFileValetTokenDTO): SharedVaultValetTokenData['moveOperation'] {
|
||||
if (!dto.moveOperationType) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
let fromUuid: string
|
||||
let toUuid: string
|
||||
switch (dto.moveOperationType) {
|
||||
case 'shared-vault-to-user':
|
||||
fromUuid = dto.sharedVaultUuid
|
||||
toUuid = dto.userUuid
|
||||
break
|
||||
case 'user-to-shared-vault':
|
||||
fromUuid = dto.userUuid
|
||||
toUuid = dto.sharedVaultUuid
|
||||
break
|
||||
case 'shared-vault-to-shared-vault':
|
||||
fromUuid = dto.sharedVaultUuid
|
||||
toUuid = dto.sharedVaultToSharedVaultMoveTargetUuid as string
|
||||
break
|
||||
}
|
||||
|
||||
return {
|
||||
type: dto.moveOperationType,
|
||||
fromUuid,
|
||||
toUuid,
|
||||
}
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
import { SharedVaultMoveType, ValetTokenOperation } from '@standardnotes/security'
|
||||
|
||||
export interface CreateSharedVaultFileValetTokenDTO {
|
||||
userUuid: string
|
||||
sharedVaultUuid: string
|
||||
fileUuid?: string
|
||||
remoteIdentifier: string
|
||||
operation: ValetTokenOperation
|
||||
unencryptedFileSize?: number
|
||||
moveOperationType?: SharedVaultMoveType
|
||||
sharedVaultToSharedVaultMoveTargetUuid?: string
|
||||
}
|
||||
Reference in New Issue
Block a user