Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
405c099
move decrypt mnemonic to a new file
TamaraFinogina Aug 14, 2026
917f3a2
add new files
TamaraFinogina Aug 14, 2026
5a920bc
use encryptMnemonic
TamaraFinogina Aug 14, 2026
8c11481
use v2 for creating private sharing
TamaraFinogina Aug 17, 2026
439c97b
switch download to file key
TamaraFinogina Aug 19, 2026
010fd95
pass key in download shared files
TamaraFinogina Aug 19, 2026
c5b038e
remove logs, fix getSharedFileKeyParams
TamaraFinogina Aug 19, 2026
e3f719e
fix file preview
TamaraFinogina Aug 19, 2026
8dc8500
fix sonar complains
TamaraFinogina Aug 19, 2026
9680050
use master hybrid encryption
TamaraFinogina Aug 19, 2026
d86844d
merge master
TamaraFinogina Aug 19, 2026
a58db07
up the version
TamaraFinogina Aug 20, 2026
fd0fa68
bring files from master
TamaraFinogina Aug 20, 2026
718e8dc
bring master
TamaraFinogina Aug 20, 2026
7a6f94b
Merge branch 'master' into update_private_sharings
TamaraFinogina Aug 20, 2026
b9959c8
reduce code duplication
TamaraFinogina Aug 21, 2026
f0cd8bd
remove log, add test
TamaraFinogina Aug 21, 2026
4339497
add more tests
TamaraFinogina Aug 21, 2026
d82f289
add createNetworkFacade
TamaraFinogina Aug 21, 2026
fe2995a
add multipart download
TamaraFinogina Aug 21, 2026
375deed
add multipart tests
TamaraFinogina Aug 21, 2026
8cbf76d
switch to decryptSharingKey in shared view
TamaraFinogina Aug 21, 2026
a60c38f
fix sonar erorr and video streaming
TamaraFinogina Aug 21, 2026
164f054
remove code duplicate in download
TamaraFinogina Aug 21, 2026
ce9c608
Merge branch 'master' into update_private_sharings
TamaraFinogina Aug 24, 2026
95a8bb2
Merge branch 'master' into update_private_sharings
TamaraFinogina Aug 24, 2026
92a8e9c
user arrow function style in v2.ts
TamaraFinogina Aug 25, 2026
fc2c736
Merge branch 'master' into update_private_sharings
TamaraFinogina Aug 28, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ const FileViewerWrapper = ({
abortController,
},
currentFile.credentials,
currentFile.mnemonic,
currentFile.key,
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ const FileVideoViewer = ({
bucketId: file.bucket,
fileSize: file.size,
fileType: file.type,
mnemonic: file.mnemonic ?? mnemonic,
key: file.key ?? { mnemonic },
credentials: file.credentials
? { user: file.credentials?.user, pass: file.credentials?.pass }
: { user: bridgeUser, pass: userId },
Expand Down
8 changes: 3 additions & 5 deletions src/app/drive/services/download.service/fetchFileBlob.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { binaryStreamToBlob } from 'services/stream.service';
import { Downloadable, downloadFile } from 'app/network/download';
import { getEnvironmentConfig } from '../network.service';
import { NetworkCredentials } from 'app/network/types/helper-types';
import { FileKey, NetworkCredentials } from 'app/network/types/helper-types';

type FetchFileBlobOptions = {
updateProgressCallback: (progress: number) => void;
Expand All @@ -14,7 +14,7 @@ export default async function fetchFileBlob(
item: Downloadable,
options: FetchFileBlobOptions,
credentials?: NetworkCredentials,
mnemonic?: string,
key?: FileKey,
): Promise<Blob> {
const { bridgeUser, bridgePass, encryptionKey } = await getEnvironmentConfig(!!options.isWorkspace);

Expand All @@ -24,9 +24,7 @@ export default async function fetchFileBlob(
bucketId: item.bucketId,
fileId: item.fileId,
creds,
key: {
mnemonic: mnemonic ? mnemonic : encryptionKey,
},
key: key ?? { mnemonic: encryptionKey },
options: {
notifyProgress: (totalBytes, downloadedBytes) => {
options.updateProgressCallback(downloadedBytes / totalBytes);
Expand Down
14 changes: 8 additions & 6 deletions src/app/drive/services/downloadManager.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,12 @@ export class DownloadManagerService {
const failedItems: DownloadItemType[] = [];
let downloadedProgress = 0;

const resolveItemKey = (driveItem: DownloadItemType): FileKey => {
const shareCredentials = (driveItem as AdvancedSharedItem).credentials;
if (shareCredentials?.bucketKey) return { bucketKey: shareCredentials.bucketKey };
return { mnemonic: shareCredentials?.mnemonic ?? credentials.key.mnemonic };
Comment on lines +342 to +343

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand that this is because v3 uses a bucketKey, and if there is no bucketKey, does that mean v2? Is that right?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, hybrid works with mnemonic, and hybrid-v2 works with bucketKey. If not set properly, the download will fail

P.S. v3 is for public sharing because it has v2 already

};

items.forEach((_, index) => {
downloadProgress[index] = 0;
lastReportedBytes[index] = 0;
Expand Down Expand Up @@ -391,9 +397,7 @@ export class DownloadManagerService {
user: (driveItem as AdvancedSharedItem).credentials?.networkUser ?? credentials.credentials.user,
pass: (driveItem as AdvancedSharedItem).credentials?.networkPass ?? credentials.credentials.pass,
},
key: {
mnemonic: (driveItem as AdvancedSharedItem).credentials?.mnemonic ?? credentials.key.mnemonic,
},
key: resolveItemKey(driveItem),
options: {
abortController,
notifyProgress: notifyProgressCallback,
Expand Down Expand Up @@ -431,9 +435,7 @@ export class DownloadManagerService {
user: (driveItem as AdvancedSharedItem).credentials?.networkUser ?? credentials.credentials.user,
pass: (driveItem as AdvancedSharedItem).credentials?.networkPass ?? credentials.credentials.pass,
},
key: {
mnemonic: (driveItem as AdvancedSharedItem).credentials?.mnemonic ?? credentials.key.mnemonic,
},
key: resolveItemKey(driveItem),
workspaceId: credentials.workspaceId,
},
abortController,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const createConfig = (): VideoStreamingSessionConfig => ({
bucketId: 'bucket-456',
fileSize: 1000000,
fileType: 'video/mp4',
mnemonic: 'test mnemonic',
key: { mnemonic: 'test mnemonic' },
credentials: { user: 'user', pass: 'pass' },
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { NetworkCredentials } from 'app/network/types/helper-types';
import { FileKey, NetworkCredentials } from 'app/network/types/helper-types';
import { VideoSessionDestroyedError } from '../errors/video-streaming.errors';
import { VideoStreamingService } from './index';

Expand All @@ -7,7 +7,7 @@ export interface VideoStreamingSessionConfig {
bucketId: string;
fileSize: number;
fileType: string;
mnemonic: string;
key: FileKey;
credentials: NetworkCredentials;
}

Expand Down
2 changes: 1 addition & 1 deletion src/app/drive/services/video-streaming.service/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export class VideoStreamingService {
const stream = await downloadChunkFile({
bucketId: this.config.bucketId,
fileId: this.config.fileId,
key: { mnemonic: this.config.mnemonic },
key: this.config.key,
creds: this.config.credentials,
chunkStart: start,
chunkEnd: end,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const createConfig = (): VideoStreamingSessionConfig => ({
bucketId: 'bucket-456',
fileSize: 1024000,
fileType: 'video/mp4',
mnemonic: 'test mnemonic',
key: { mnemonic: 'test mnemonic' },
credentials: { user: 'user', pass: 'pass' },
});

Expand All @@ -45,7 +45,7 @@ describe('Video Streaming Service', () => {
expect.objectContaining({
bucketId: config.bucketId,
fileId: config.fileId,
key: { mnemonic: config.mnemonic },
key: config.key,
chunkStart: 0,
chunkEnd: 1024,
}),
Expand Down
56 changes: 31 additions & 25 deletions src/app/network/NetworkFacade.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ describe('NetworkFacade', () => {
mockDownloadFile();
vi.mocked(getFileHmacFromShardHashes).mockResolvedValue('any-hmac');

const result = await networkFacade.download(bucketId, fileId, mnemonic);
const result = await networkFacade.download(bucketId, fileId, { mnemonic });

expect(result).toBeDefined();
expect(buildProgressStream).toHaveBeenCalledOnce();
Expand All @@ -115,7 +115,7 @@ describe('NetworkFacade', () => {
return new ReadableStream({ start: (c) => c.close() });
});

await networkFacade.download(bucketId, fileId, mnemonic);
await networkFacade.download(bucketId, fileId, { mnemonic });

await expect(capturedOnFinished?.()).resolves.toBeUndefined();
});
Expand All @@ -130,7 +130,7 @@ describe('NetworkFacade', () => {
return new ReadableStream({ start: (c) => c.close() });
});

await networkFacade.download(bucketId, fileId, mnemonic);
await networkFacade.download(bucketId, fileId, { mnemonic });

await expect(capturedOnFinished?.()).rejects.toThrow('File integrity check failed');
});
Expand All @@ -139,7 +139,7 @@ describe('NetworkFacade', () => {
mockDownloadFile();
vi.mocked(getFileHmacFromShardHashes).mockResolvedValue('any-hmac');

await networkFacade.download(bucketId, fileId, mnemonic);
await networkFacade.download(bucketId, fileId, { mnemonic });

expect(createSha256HashingStream).toHaveBeenCalledOnce();
});
Expand All @@ -154,7 +154,7 @@ describe('NetworkFacade', () => {
return new ReadableStream({ start: (c) => c.close() });
});

await networkFacade.download(bucketId, fileId, mnemonic);
await networkFacade.download(bucketId, fileId, { mnemonic });
await capturedOnFinished?.();

expect(getFileHmacFromShardHashes).toHaveBeenCalledWith(fakeKey, [fakeRipemd160Hash]);
Expand Down Expand Up @@ -186,7 +186,7 @@ describe('NetworkFacade', () => {
);
vi.mocked(decryptStream).mockReturnValue(mockDecryptedStream);

const result = await networkFacade.downloadChunk({ bucketId, fileId, mnemonic, chunkStart, chunkEnd });
const result = await networkFacade.downloadChunk({ bucketId, fileId, key: { mnemonic }, chunkStart, chunkEnd });

expect(result).toStrictEqual(mockDecryptedStream);

Expand Down Expand Up @@ -215,9 +215,9 @@ describe('NetworkFacade', () => {
},
);

await expect(networkFacade.downloadChunk({ bucketId, fileId, mnemonic, chunkStart, chunkEnd })).rejects.toThrow(
new DownloadFailedWithUnknownError(mockResponse.status),
);
await expect(
networkFacade.downloadChunk({ bucketId, fileId, key: { mnemonic }, chunkStart, chunkEnd }),
).rejects.toThrow(new DownloadFailedWithUnknownError(mockResponse.status));
});

test('When there is no body in the response, then an error indicating so is thrown', async () => {
Expand All @@ -233,9 +233,9 @@ describe('NetworkFacade', () => {
},
);

await expect(networkFacade.downloadChunk({ bucketId, fileId, mnemonic, chunkStart, chunkEnd })).rejects.toThrow(
NoContentReceivedError,
);
await expect(
networkFacade.downloadChunk({ bucketId, fileId, key: { mnemonic }, chunkStart, chunkEnd }),
).rejects.toThrow(NoContentReceivedError);
});

it('When the download is aborted, then an DownloadAbortedByUserError error is thrown', async () => {
Expand All @@ -251,7 +251,7 @@ describe('NetworkFacade', () => {
networkFacade.downloadChunk({
bucketId,
fileId,
mnemonic,
key: { mnemonic },
chunkStart,
chunkEnd,
options: {
Expand Down Expand Up @@ -338,7 +338,7 @@ describe('NetworkFacade', () => {
mockDownloadFileWithBucketKey();
vi.mocked(getFileHmacFromShardHashes).mockResolvedValue('any-hmac');

const result = await networkFacade.downloadWithBucketKey(bucketId, fileId, bucketKey);
const result = await networkFacade.download(bucketId, fileId, { bucketKey });

expect(result).toBeDefined();
expect(downloadFileWithBucketKey).toHaveBeenCalledWith(
Expand All @@ -362,7 +362,7 @@ describe('NetworkFacade', () => {
mockDownloadFileWithBucketKey();
vi.mocked(getFileHmacFromShardHashes).mockResolvedValue('any-hmac');

const result = await networkFacade.downloadWithBucketKey(bucketId, fileId, bucketKey);
const result = await networkFacade.download(bucketId, fileId, { bucketKey });

expect(result).toBeDefined();
expect(buildProgressStream).toHaveBeenCalledOnce();
Expand All @@ -379,7 +379,7 @@ describe('NetworkFacade', () => {
return new ReadableStream({ start: (c) => c.close() });
});

await networkFacade.downloadWithBucketKey(bucketId, fileId, bucketKey);
await networkFacade.download(bucketId, fileId, { bucketKey });

await expect(capturedOnFinished?.()).resolves.toBeUndefined();
});
Expand All @@ -394,7 +394,7 @@ describe('NetworkFacade', () => {
return new ReadableStream({ start: (c) => c.close() });
});

await networkFacade.downloadWithBucketKey(bucketId, fileId, bucketKey);
await networkFacade.download(bucketId, fileId, { bucketKey });

await expect(capturedOnFinished?.()).rejects.toThrow('File integrity check failed');
});
Expand All @@ -403,7 +403,7 @@ describe('NetworkFacade', () => {
mockDownloadFileWithBucketKey();
vi.mocked(getFileHmacFromShardHashes).mockResolvedValue('any-hmac');

await networkFacade.downloadWithBucketKey(bucketId, fileId, bucketKey);
await networkFacade.download(bucketId, fileId, { bucketKey });

expect(createSha256HashingStream).toHaveBeenCalledOnce();
});
Expand All @@ -418,7 +418,7 @@ describe('NetworkFacade', () => {
return new ReadableStream({ start: (c) => c.close() });
});

await networkFacade.downloadWithBucketKey(bucketId, fileId, bucketKey);
await networkFacade.download(bucketId, fileId, { bucketKey });
await capturedOnFinished?.();

expect(getFileHmacFromShardHashes).toHaveBeenCalledWith(fakeKey, [fakeRipemd160Hash]);
Expand All @@ -435,7 +435,7 @@ describe('NetworkFacade', () => {
return new ReadableStream({ start: (c) => c.close() });
});

await networkFacade.downloadWithBucketKey(bucketId, fileId, bucketKey, { key: overrideKey });
await networkFacade.download(bucketId, fileId, { bucketKey }, { key: overrideKey });
await capturedOnFinished?.();

expect(getFileHmacFromShardHashes).toHaveBeenCalledWith(overrideKey, [fakeRipemd160Hash]);
Expand All @@ -445,7 +445,7 @@ describe('NetworkFacade', () => {
mockDownloadFileWithBucketKey();
vi.mocked(getFileHmacFromShardHashes).mockResolvedValue('any-hmac');

await networkFacade.downloadWithBucketKey(bucketId, fileId, bucketKey, { token: 'test-token' });
await networkFacade.download(bucketId, fileId, { bucketKey }, { token: 'test-token' });

expect(downloadFileWithBucketKey).toHaveBeenCalledWith(
fileId,
Expand All @@ -464,7 +464,7 @@ describe('NetworkFacade', () => {
mockDownloadFileWithBucketKey();
vi.mocked(getFileHmacFromShardHashes).mockResolvedValue('any-hmac');

await networkFacade.downloadWithBucketKey(bucketId, fileId, bucketKey);
await networkFacade.download(bucketId, fileId, { bucketKey });

expect(downloadFileWithBucketKey).toHaveBeenCalledWith(
fileId,
Expand Down Expand Up @@ -497,9 +497,15 @@ describe('NetworkFacade', () => {
return { body: new ReadableStream() };
});

await expect(
networkFacade.downloadWithBucketKey(bucketId, fileId, bucketKey, { abortController }),
).rejects.toThrow('Download aborted');
await expect(networkFacade.download(bucketId, fileId, { bucketKey }, { abortController })).rejects.toThrow(
'Download aborted',
);
});
});

test('When neither mnemonic nor bucketKey is provided, throws', async () => {
await expect(
networkFacade.downloadChunk({ bucketId, fileId, key: {}, chunkStart: 2, chunkEnd: 5 } as any),
).rejects.toThrow('No bucket key or mnemonic is given');
});
});
Loading
Loading