mirror of
https://github.com/standardnotes/server
synced 2026-07-14 09:01:33 -04:00
refactor: vault files
This commit is contained in:
@@ -1,4 +1,10 @@
|
||||
import { FileUploadedEvent, FileRemovedEvent, DomainEventService } from '@standardnotes/domain-events'
|
||||
import {
|
||||
UserFileRemovedEvent,
|
||||
UserFileUploadedEvent,
|
||||
DomainEventService,
|
||||
VaultFileUploadedEvent,
|
||||
VaultFileRemovedEvent,
|
||||
} from '@standardnotes/domain-events'
|
||||
import { TimerInterface } from '@standardnotes/time'
|
||||
import { inject, injectable } from 'inversify'
|
||||
|
||||
@@ -9,15 +15,15 @@ import { DomainEventFactoryInterface } from './DomainEventFactoryInterface'
|
||||
export class DomainEventFactory implements DomainEventFactoryInterface {
|
||||
constructor(@inject(TYPES.Timer) private timer: TimerInterface) {}
|
||||
|
||||
createFileRemovedEvent(payload: {
|
||||
createUserFileRemovedEvent(payload: {
|
||||
userUuid: string
|
||||
filePath: string
|
||||
fileName: string
|
||||
fileByteSize: number
|
||||
regularSubscriptionUuid: string
|
||||
}): FileRemovedEvent {
|
||||
}): UserFileRemovedEvent {
|
||||
return {
|
||||
type: 'FILE_REMOVED',
|
||||
type: 'USER_FILE_REMOVED',
|
||||
createdAt: this.timer.getUTCDate(),
|
||||
meta: {
|
||||
correlation: {
|
||||
@@ -30,14 +36,14 @@ export class DomainEventFactory implements DomainEventFactoryInterface {
|
||||
}
|
||||
}
|
||||
|
||||
createFileUploadedEvent(payload: {
|
||||
createUserFileUploadedEvent(payload: {
|
||||
userUuid: string
|
||||
filePath: string
|
||||
fileName: string
|
||||
fileByteSize: number
|
||||
}): FileUploadedEvent {
|
||||
}): UserFileUploadedEvent {
|
||||
return {
|
||||
type: 'FILE_UPLOADED',
|
||||
type: 'USER_FILE_UPLOADED',
|
||||
createdAt: this.timer.getUTCDate(),
|
||||
meta: {
|
||||
correlation: {
|
||||
@@ -49,4 +55,44 @@ export class DomainEventFactory implements DomainEventFactoryInterface {
|
||||
payload,
|
||||
}
|
||||
}
|
||||
|
||||
createVaultFileUploadedEvent(payload: {
|
||||
vaultUuid: string
|
||||
filePath: string
|
||||
fileName: string
|
||||
fileByteSize: number
|
||||
}): VaultFileUploadedEvent {
|
||||
return {
|
||||
type: 'VAULT_FILE_UPLOADED',
|
||||
createdAt: this.timer.getUTCDate(),
|
||||
meta: {
|
||||
correlation: {
|
||||
userIdentifier: payload.vaultUuid,
|
||||
userIdentifierType: 'uuid',
|
||||
},
|
||||
origin: DomainEventService.Files,
|
||||
},
|
||||
payload,
|
||||
}
|
||||
}
|
||||
|
||||
createVaultFileRemovedEvent(payload: {
|
||||
vaultUuid: string
|
||||
filePath: string
|
||||
fileName: string
|
||||
fileByteSize: number
|
||||
}): VaultFileRemovedEvent {
|
||||
return {
|
||||
type: 'VAULT_FILE_REMOVED',
|
||||
createdAt: this.timer.getUTCDate(),
|
||||
meta: {
|
||||
correlation: {
|
||||
userIdentifier: payload.vaultUuid,
|
||||
userIdentifierType: 'uuid',
|
||||
},
|
||||
origin: DomainEventService.Files,
|
||||
},
|
||||
payload,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,35 @@
|
||||
import { FileUploadedEvent, FileRemovedEvent } from '@standardnotes/domain-events'
|
||||
import {
|
||||
UserFileUploadedEvent,
|
||||
UserFileRemovedEvent,
|
||||
VaultFileUploadedEvent,
|
||||
VaultFileRemovedEvent,
|
||||
} from '@standardnotes/domain-events'
|
||||
|
||||
export interface DomainEventFactoryInterface {
|
||||
createFileUploadedEvent(payload: {
|
||||
createUserFileUploadedEvent(payload: {
|
||||
userUuid: string
|
||||
filePath: string
|
||||
fileName: string
|
||||
fileByteSize: number
|
||||
}): FileUploadedEvent
|
||||
createFileRemovedEvent(payload: {
|
||||
}): UserFileUploadedEvent
|
||||
createUserFileRemovedEvent(payload: {
|
||||
userUuid: string
|
||||
filePath: string
|
||||
fileName: string
|
||||
fileByteSize: number
|
||||
regularSubscriptionUuid: string
|
||||
}): FileRemovedEvent
|
||||
}): UserFileRemovedEvent
|
||||
|
||||
createVaultFileUploadedEvent(payload: {
|
||||
vaultUuid: string
|
||||
filePath: string
|
||||
fileName: string
|
||||
fileByteSize: number
|
||||
}): VaultFileUploadedEvent
|
||||
createVaultFileRemovedEvent(payload: {
|
||||
vaultUuid: string
|
||||
filePath: string
|
||||
fileName: string
|
||||
fileByteSize: number
|
||||
}): VaultFileRemovedEvent
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ export class AccountDeletionRequestedEventHandler implements DomainEventHandlerI
|
||||
}
|
||||
|
||||
const response = await this.markFilesToBeRemoved.execute({
|
||||
userUuid: event.payload.userUuid,
|
||||
ownerUuid: event.payload.userUuid,
|
||||
})
|
||||
|
||||
if (!response.success) {
|
||||
@@ -32,7 +32,7 @@ export class AccountDeletionRequestedEventHandler implements DomainEventHandlerI
|
||||
|
||||
for (const fileRemoved of response.filesRemoved) {
|
||||
await this.domainEventPublisher.publish(
|
||||
this.domainEventFactory.createFileRemovedEvent({
|
||||
this.domainEventFactory.createUserFileRemovedEvent({
|
||||
regularSubscriptionUuid: event.payload.regularSubscriptionUuid,
|
||||
...fileRemoved,
|
||||
}),
|
||||
|
||||
+2
-2
@@ -23,7 +23,7 @@ export class SharedSubscriptionInvitationCanceledEventHandler implements DomainE
|
||||
}
|
||||
|
||||
const response = await this.markFilesToBeRemoved.execute({
|
||||
userUuid: event.payload.inviteeIdentifier,
|
||||
ownerUuid: event.payload.inviteeIdentifier,
|
||||
})
|
||||
|
||||
if (!response.success) {
|
||||
@@ -32,7 +32,7 @@ export class SharedSubscriptionInvitationCanceledEventHandler implements DomainE
|
||||
|
||||
for (const fileRemoved of response.filesRemoved) {
|
||||
await this.domainEventPublisher.publish(
|
||||
this.domainEventFactory.createFileRemovedEvent({
|
||||
this.domainEventFactory.createUserFileRemovedEvent({
|
||||
regularSubscriptionUuid: event.payload.inviterSubscriptionUuid,
|
||||
...fileRemoved,
|
||||
}),
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
export interface FileMoverInterface {
|
||||
moveFile(sourcePath: string, destinationPath: string): Promise<void>
|
||||
}
|
||||
@@ -20,7 +20,7 @@ export class CreateUploadSession implements UseCaseInterface {
|
||||
try {
|
||||
this.logger.debug(`Creating upload session for resource: ${dto.resourceRemoteIdentifier}`)
|
||||
|
||||
const filePath = `${dto.userUuid}/${dto.resourceRemoteIdentifier}`
|
||||
const filePath = `${dto.ownerUuid}/${dto.resourceRemoteIdentifier}`
|
||||
|
||||
const uploadId = await this.fileUploader.createUploadSession(filePath)
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export type CreateUploadSessionDTO = {
|
||||
userUuid: string
|
||||
ownerUuid: string
|
||||
resourceRemoteIdentifier: string
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ export class FinishUploadSession implements UseCaseInterface {
|
||||
try {
|
||||
this.logger.debug(`Finishing upload session for resource: ${dto.resourceRemoteIdentifier}`)
|
||||
|
||||
const filePath = `${dto.userUuid}/${dto.resourceRemoteIdentifier}`
|
||||
const filePath = `${dto.ownerUuid}/${dto.resourceRemoteIdentifier}`
|
||||
|
||||
const uploadId = await this.uploadRepository.retrieveUploadSessionId(filePath)
|
||||
if (uploadId === undefined) {
|
||||
@@ -53,14 +53,25 @@ export class FinishUploadSession implements UseCaseInterface {
|
||||
|
||||
await this.fileUploader.finishUploadSession(uploadId, filePath, uploadChunkResults)
|
||||
|
||||
await this.domainEventPublisher.publish(
|
||||
this.domainEventFactory.createFileUploadedEvent({
|
||||
userUuid: dto.userUuid,
|
||||
filePath: `${dto.userUuid}/${dto.resourceRemoteIdentifier}`,
|
||||
fileName: dto.resourceRemoteIdentifier,
|
||||
fileByteSize: totalFileSize,
|
||||
}),
|
||||
)
|
||||
if (dto.ownerType === 'user') {
|
||||
await this.domainEventPublisher.publish(
|
||||
this.domainEventFactory.createUserFileUploadedEvent({
|
||||
userUuid: dto.ownerUuid,
|
||||
filePath: `${dto.ownerUuid}/${dto.resourceRemoteIdentifier}`,
|
||||
fileName: dto.resourceRemoteIdentifier,
|
||||
fileByteSize: totalFileSize,
|
||||
}),
|
||||
)
|
||||
} else {
|
||||
await this.domainEventPublisher.publish(
|
||||
this.domainEventFactory.createVaultFileUploadedEvent({
|
||||
vaultUuid: dto.ownerUuid,
|
||||
filePath: `${dto.ownerUuid}/${dto.resourceRemoteIdentifier}`,
|
||||
fileName: dto.resourceRemoteIdentifier,
|
||||
fileByteSize: totalFileSize,
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
export type FinishUploadSessionDTO = {
|
||||
userUuid: string
|
||||
ownerUuid: string
|
||||
ownerType: 'user' | 'vault'
|
||||
resourceRemoteIdentifier: string
|
||||
uploadBytesUsed: number
|
||||
uploadBytesLimit: number
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Logger } from 'winston'
|
||||
import TYPES from '../../../Bootstrap/Types'
|
||||
import { FileDownloaderInterface } from '../../Services/FileDownloaderInterface'
|
||||
import { UseCaseInterface } from '../UseCaseInterface'
|
||||
import { GetFileMetadataDTO, isGetFileMetadataVaultOwned } from './GetFileMetadataDTO'
|
||||
import { GetFileMetadataDTO } from './GetFileMetadataDTO'
|
||||
import { GetFileMetadataResponse } from './GetFileMetadataResponse'
|
||||
|
||||
@injectable()
|
||||
@@ -14,16 +14,15 @@ export class GetFileMetadata implements UseCaseInterface {
|
||||
) {}
|
||||
|
||||
async execute(dto: GetFileMetadataDTO): Promise<GetFileMetadataResponse> {
|
||||
const ownerUuid = isGetFileMetadataVaultOwned(dto) ? dto.vaultUuid : dto.userUuid
|
||||
try {
|
||||
const size = await this.fileDownloader.getFileSize(`${ownerUuid}/${dto.resourceRemoteIdentifier}`)
|
||||
const size = await this.fileDownloader.getFileSize(`${dto.ownerUuid}/${dto.resourceRemoteIdentifier}`)
|
||||
|
||||
return {
|
||||
success: true,
|
||||
size,
|
||||
}
|
||||
} catch (error) {
|
||||
this.logger.error(`Could not get file metadata for resource: ${ownerUuid}/${dto.resourceRemoteIdentifier}`)
|
||||
this.logger.error(`Could not get file metadata for resource: ${dto.ownerUuid}/${dto.resourceRemoteIdentifier}`)
|
||||
return {
|
||||
success: false,
|
||||
message: 'Could not get file metadata.',
|
||||
|
||||
@@ -1,15 +1,4 @@
|
||||
export type GetFileMetadataDTO = GetVaultFileMetadataDTO | GetUserFileMetadataDTO
|
||||
|
||||
export type GetVaultFileMetadataDTO = {
|
||||
vaultUuid: string
|
||||
export type GetFileMetadataDTO = {
|
||||
ownerUuid: string
|
||||
resourceRemoteIdentifier: string
|
||||
}
|
||||
|
||||
export type GetUserFileMetadataDTO = {
|
||||
userUuid: string
|
||||
resourceRemoteIdentifier: string
|
||||
}
|
||||
|
||||
export function isGetFileMetadataVaultOwned(dto: GetFileMetadataDTO): dto is GetVaultFileMetadataDTO {
|
||||
return (dto as GetVaultFileMetadataDTO).vaultUuid !== undefined
|
||||
}
|
||||
|
||||
@@ -16,16 +16,16 @@ export class MarkFilesToBeRemoved implements UseCaseInterface {
|
||||
|
||||
async execute(dto: MarkFilesToBeRemovedDTO): Promise<MarkFilesToBeRemovedResponse> {
|
||||
try {
|
||||
this.logger.debug(`Marking files for later removal for user: ${dto.userUuid}`)
|
||||
this.logger.debug(`Marking files for later removal for user: ${dto.ownerUuid}`)
|
||||
|
||||
const filesRemoved = await this.fileRemover.markFilesToBeRemoved(dto.userUuid)
|
||||
const filesRemoved = await this.fileRemover.markFilesToBeRemoved(dto.ownerUuid)
|
||||
|
||||
return {
|
||||
success: true,
|
||||
filesRemoved,
|
||||
}
|
||||
} catch (error) {
|
||||
this.logger.error(`Could not mark resources for removal: ${dto.userUuid} - ${(error as Error).message}`)
|
||||
this.logger.error(`Could not mark resources for removal: ${dto.ownerUuid} - ${(error as Error).message}`)
|
||||
|
||||
return {
|
||||
success: false,
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
export type MarkFilesToBeRemovedDTO = {
|
||||
userUuid: string
|
||||
ownerUuid: string
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
import 'reflect-metadata'
|
||||
|
||||
import { Logger } from 'winston'
|
||||
|
||||
import { MoveFile } from './MoveFile'
|
||||
import { FileMoverInterface } from '../../Services/FileMoverInterface'
|
||||
|
||||
describe('MoveFile', () => {
|
||||
let fileRemover: FileMoverInterface
|
||||
|
||||
let logger: Logger
|
||||
|
||||
const createUseCase = () => new MoveFile(fileRemover, logger)
|
||||
|
||||
beforeEach(() => {
|
||||
fileRemover = {} as jest.Mocked<FileMoverInterface>
|
||||
fileRemover.moveFile = jest.fn().mockReturnValue(413)
|
||||
|
||||
logger = {} as jest.Mocked<Logger>
|
||||
logger.debug = jest.fn()
|
||||
logger.error = jest.fn()
|
||||
logger.warn = jest.fn()
|
||||
})
|
||||
|
||||
it('should remove a file', async () => {
|
||||
await createUseCase().execute({
|
||||
resourceRemoteIdentifier: '2-3-4',
|
||||
fromUserUuid: '1-2-3',
|
||||
toVaultUuid: '4-5-6',
|
||||
regularSubscriptionUuid: '3-4-5',
|
||||
})
|
||||
|
||||
expect(fileRemover.moveFile).toHaveBeenCalledWith('1-2-3/2-3-4', '4-5-6/2-3-4')
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,43 @@
|
||||
import { inject, injectable } from 'inversify'
|
||||
import { Logger } from 'winston'
|
||||
|
||||
import TYPES from '../../../Bootstrap/Types'
|
||||
import { FileMoverInterface } from '../../Services/FileMoverInterface'
|
||||
import { UseCaseInterface } from '../UseCaseInterface'
|
||||
import { MoveFileDTO, isMoveFileFromUserToVaultDTO } from './MoveFileDTO'
|
||||
import { MoveFileResponse } from './MoveFileResponse'
|
||||
|
||||
@injectable()
|
||||
export class MoveFile implements UseCaseInterface {
|
||||
constructor(
|
||||
@inject(TYPES.FileMover) private fileMover: FileMoverInterface,
|
||||
@inject(TYPES.Logger) private logger: Logger,
|
||||
) {}
|
||||
|
||||
async execute(dto: MoveFileDTO): Promise<MoveFileResponse> {
|
||||
try {
|
||||
this.logger.debug(`Removing file: ${dto.resourceRemoteIdentifier}`)
|
||||
|
||||
const srcPath = isMoveFileFromUserToVaultDTO(dto)
|
||||
? `${dto.fromUserUuid}/${dto.resourceRemoteIdentifier}`
|
||||
: `${dto.fromVaultUuid}/${dto.resourceRemoteIdentifier}`
|
||||
|
||||
const destPath = isMoveFileFromUserToVaultDTO(dto)
|
||||
? `${dto.toVaultUuid}/${dto.resourceRemoteIdentifier}`
|
||||
: `${dto.toUserUuid}/${dto.resourceRemoteIdentifier}`
|
||||
|
||||
await this.fileMover.moveFile(srcPath, destPath)
|
||||
|
||||
return {
|
||||
success: true,
|
||||
}
|
||||
} catch (error) {
|
||||
this.logger.error(`Could not remove resource: ${dto.resourceRemoteIdentifier} - ${(error as Error).message}`)
|
||||
|
||||
return {
|
||||
success: false,
|
||||
message: 'Could not remove resource',
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
export type MoveFileDTO = MoveFileFromUserToVaultDTO | MoveFileFromVaultToUserDTO
|
||||
|
||||
export type MoveFileFromUserToVaultDTO = {
|
||||
toVaultUuid: string
|
||||
fromUserUuid: string
|
||||
resourceRemoteIdentifier: string
|
||||
regularSubscriptionUuid: string
|
||||
}
|
||||
|
||||
export type MoveFileFromVaultToUserDTO = {
|
||||
fromVaultUuid: string
|
||||
toUserUuid: string
|
||||
resourceRemoteIdentifier: string
|
||||
regularSubscriptionUuid: string
|
||||
}
|
||||
|
||||
export function isMoveFileFromUserToVaultDTO(dto: MoveFileDTO): dto is MoveFileFromUserToVaultDTO {
|
||||
return (dto as MoveFileFromUserToVaultDTO).fromUserUuid !== undefined
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
export type MoveFileResponse =
|
||||
| {
|
||||
success: true
|
||||
}
|
||||
| {
|
||||
success: false
|
||||
message: string
|
||||
}
|
||||
@@ -6,7 +6,7 @@ import TYPES from '../../../Bootstrap/Types'
|
||||
import { DomainEventFactoryInterface } from '../../Event/DomainEventFactoryInterface'
|
||||
import { FileRemoverInterface } from '../../Services/FileRemoverInterface'
|
||||
import { UseCaseInterface } from '../UseCaseInterface'
|
||||
import { RemoveFileDTO } from './RemoveFileDTO'
|
||||
import { RemoveFileDTO, isRemoveUserFileDTO } from './RemoveFileDTO'
|
||||
import { RemoveFileResponse } from './RemoveFileResponse'
|
||||
|
||||
@injectable()
|
||||
@@ -22,19 +22,32 @@ export class RemoveFile implements UseCaseInterface {
|
||||
try {
|
||||
this.logger.debug(`Removing file: ${dto.resourceRemoteIdentifier}`)
|
||||
|
||||
const filePath = `${dto.userUuid}/${dto.resourceRemoteIdentifier}`
|
||||
const ownerUuid = isRemoveUserFileDTO(dto) ? dto.userUuid : dto.vaultUuid
|
||||
|
||||
const filePath = `${ownerUuid}/${dto.resourceRemoteIdentifier}`
|
||||
|
||||
const removedFileSize = await this.fileRemover.remove(filePath)
|
||||
|
||||
await this.domainEventPublisher.publish(
|
||||
this.domainEventFactory.createFileRemovedEvent({
|
||||
userUuid: dto.userUuid,
|
||||
filePath: `${dto.userUuid}/${dto.resourceRemoteIdentifier}`,
|
||||
fileName: dto.resourceRemoteIdentifier,
|
||||
fileByteSize: removedFileSize,
|
||||
regularSubscriptionUuid: dto.regularSubscriptionUuid,
|
||||
}),
|
||||
)
|
||||
if (isRemoveUserFileDTO(dto)) {
|
||||
await this.domainEventPublisher.publish(
|
||||
this.domainEventFactory.createUserFileRemovedEvent({
|
||||
userUuid: dto.userUuid,
|
||||
filePath: `${dto.userUuid}/${dto.resourceRemoteIdentifier}`,
|
||||
fileName: dto.resourceRemoteIdentifier,
|
||||
fileByteSize: removedFileSize,
|
||||
regularSubscriptionUuid: dto.regularSubscriptionUuid,
|
||||
}),
|
||||
)
|
||||
} else {
|
||||
await this.domainEventPublisher.publish(
|
||||
this.domainEventFactory.createVaultFileRemovedEvent({
|
||||
vaultUuid: dto.vaultUuid,
|
||||
filePath: `${dto.vaultUuid}/${dto.resourceRemoteIdentifier}`,
|
||||
fileName: dto.resourceRemoteIdentifier,
|
||||
fileByteSize: removedFileSize,
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
|
||||
@@ -1,5 +1,16 @@
|
||||
export type RemoveFileDTO = {
|
||||
export type RemoveFileDTO = RemoveUserFileDTO | RemoveVaultFileDTO
|
||||
|
||||
export type RemoveUserFileDTO = {
|
||||
userUuid: string
|
||||
resourceRemoteIdentifier: string
|
||||
regularSubscriptionUuid: string
|
||||
}
|
||||
|
||||
export type RemoveVaultFileDTO = {
|
||||
vaultUuid: string
|
||||
resourceRemoteIdentifier: string
|
||||
}
|
||||
|
||||
export function isRemoveUserFileDTO(dto: RemoveFileDTO): dto is RemoveUserFileDTO {
|
||||
return (dto as RemoveUserFileDTO).userUuid !== undefined
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Logger } from 'winston'
|
||||
import TYPES from '../../../Bootstrap/Types'
|
||||
import { FileDownloaderInterface } from '../../Services/FileDownloaderInterface'
|
||||
import { UseCaseInterface } from '../UseCaseInterface'
|
||||
import { StreamDownloadFileDTO, isStreamDownloadFileVaultOwned } from './StreamDownloadFileDTO'
|
||||
import { StreamDownloadFileDTO } from './StreamDownloadFileDTO'
|
||||
import { StreamDownloadFileResponse } from './StreamDownloadFileResponse'
|
||||
|
||||
@injectable()
|
||||
@@ -14,10 +14,9 @@ export class StreamDownloadFile implements UseCaseInterface {
|
||||
) {}
|
||||
|
||||
async execute(dto: StreamDownloadFileDTO): Promise<StreamDownloadFileResponse> {
|
||||
const ownerUuid = isStreamDownloadFileVaultOwned(dto) ? dto.vaultUuid : dto.userUuid
|
||||
try {
|
||||
const readStream = await this.fileDownloader.createDownloadStream(
|
||||
`${ownerUuid}/${dto.resourceRemoteIdentifier}`,
|
||||
`${dto.ownerUuid}/${dto.resourceRemoteIdentifier}`,
|
||||
dto.startRange,
|
||||
dto.endRange,
|
||||
)
|
||||
@@ -27,7 +26,9 @@ export class StreamDownloadFile implements UseCaseInterface {
|
||||
readStream,
|
||||
}
|
||||
} catch (error) {
|
||||
this.logger.error(`Could not create a download stream for resource: ${ownerUuid}/${dto.resourceRemoteIdentifier}`)
|
||||
this.logger.error(
|
||||
`Could not create a download stream for resource: ${dto.ownerUuid}/${dto.resourceRemoteIdentifier}`,
|
||||
)
|
||||
|
||||
return {
|
||||
success: false,
|
||||
|
||||
@@ -1,19 +1,6 @@
|
||||
export type StreamDownloadFileDTO = StreamDownloadVaultFileDTO | StreamDownloadUserFileDTO
|
||||
|
||||
export type StreamDownloadVaultFileDTO = {
|
||||
vaultUuid: string
|
||||
export type StreamDownloadFileDTO = {
|
||||
ownerUuid: string
|
||||
resourceRemoteIdentifier: string
|
||||
startRange: number
|
||||
endRange: number
|
||||
}
|
||||
|
||||
export type StreamDownloadUserFileDTO = {
|
||||
userUuid: string
|
||||
resourceRemoteIdentifier: string
|
||||
startRange: number
|
||||
endRange: number
|
||||
}
|
||||
|
||||
export function isStreamDownloadFileVaultOwned(dto: StreamDownloadFileDTO): dto is StreamDownloadVaultFileDTO {
|
||||
return (dto as StreamDownloadVaultFileDTO).vaultUuid !== undefined
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ export class UploadFileChunk implements UseCaseInterface {
|
||||
`Starting upload file chunk ${dto.chunkId} with ${dto.data.byteLength} bytes for resource: ${dto.resourceRemoteIdentifier}`,
|
||||
)
|
||||
|
||||
const filePath = `${dto.userUuid}/${dto.resourceRemoteIdentifier}`
|
||||
const filePath = `${dto.ownerUuid}/${dto.resourceRemoteIdentifier}`
|
||||
|
||||
const uploadId = await this.uploadRepository.retrieveUploadSessionId(filePath)
|
||||
if (uploadId === undefined) {
|
||||
|
||||
@@ -3,7 +3,7 @@ import { ChunkId } from '../../Upload/ChunkId'
|
||||
export type UploadFileChunkDTO = {
|
||||
data: Uint8Array
|
||||
chunkId: ChunkId
|
||||
userUuid: string
|
||||
ownerUuid: string
|
||||
resourceRemoteIdentifier: string
|
||||
resourceUnencryptedFileSize: number
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user