Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
19 changes: 19 additions & 0 deletions lib/core/buckets/helpers/uploadValidation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import semver from "semver";
import { getContext } from "../../../requestContext";

const EXEMPT_CLIENTS: Record<string, string> = {
"internxt-cli": "1.6.3",
"drive-desktop-windows": "2.6.6",
// All versions
"drive-desktop-linux": '*',
Copy link
Author

Choose a reason for hiding this comment

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

It seems linux has some issues with the node version so I am skipping it for the time being @sg-gs

};

export function shouldEnforceUploadValidation(): boolean {
const { clientId, version } = getContext();
if (!clientId || !version) return true;
if (!(clientId in EXEMPT_CLIENTS)) return true;

const maxExemptVersion = EXEMPT_CLIENTS[clientId];
const coerced = semver.coerce(version) ?? version;
return !semver.satisfies(coerced, `<=${maxExemptVersion}`);
}
17 changes: 9 additions & 8 deletions lib/core/buckets/usecase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { ContactsRepository } from '../contacts/Repository';
import { StorageGateway } from '../storage/StorageGateway';
import { Contact } from '../contacts/Contact';
import { Upload } from '../uploads/Upload';
import { shouldEnforceUploadValidation } from './helpers/uploadValidation';

export class BucketEntryNotFoundError extends Error {
constructor(bucketEntryId?: string) {
Expand Down Expand Up @@ -679,19 +680,19 @@ export class BucketsUsecase {
if (contact.objectCheckNotRequired) {
contactsThatStoreTheShard.push(contact);
} else {
await this.validateObjectInStorage(contact, uuid, data_size).catch((error) => {
try {
await this.validateObjectInStorage(contact, uuid, data_size);
} catch (error) {
if (error instanceof UploadSizeDoesNotMatchError) {
log.error(`[finishUpload][SizeDoesNotMatchError] ${JSON.stringify({ uuid, expectedSize: data_size, contactId: contact.id, message: error.message, isMultipartUpload })}`);
throw error;
}

if (error instanceof UploadNotFoundInStorageError) {
} else if (error instanceof UploadNotFoundInStorageError) {
log.error(`[finishUpload][UploadNotFoundInStorageError] ${JSON.stringify({ uuid, contactId: contact.id, error: error.message, stack: error.stack, isMultipartUpload, size: data_size })}`);
return;
} else {
log.error(`[finishUpload][unexpectedError] Error getting bucket meta ${JSON.stringify({ uuid, contactId: contact.id, error: (error as Error).message, stack: (error as Error).stack })}`);
}

log.error(`[finishUpload][unexpectedError] Error getting bucket meta ${JSON.stringify({ uuid, contactId: contact.id, error: error.message, stack: error.stack })}`);
});
if (shouldEnforceUploadValidation()) throw error;
}
contactsThatStoreTheShard.push(contact);
}
}
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
"@types/node": "^17.0.23",
"@types/node-mongodb-fixtures": "^3.2.3",
"@types/secp256k1": "^4.0.6",
"@types/semver": "^7.7.1",
"@types/sinon": "^10.0.11",
"@types/supertest": "^2.0.12",
"@types/uuid": "^8.3.4",
Expand Down Expand Up @@ -118,6 +119,7 @@
"rc": "^1.2.8",
"redis": "^3.1.0",
"secp256k1": "^4.0.2",
"semver": "^7.7.4",
"storj-lib": "github:internxt/core#v8.7.3-beta",
"storj-mongodb-adapter": "github:internxt/mongodb-adapter#10.1.0-beta",
"storj-service-error-types": "github:internxt/service-error-types",
Expand Down
92 changes: 92 additions & 0 deletions tests/lib/core/buckets/helpers/uploadValidation.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import * as requestContext from '../../../../../lib/requestContext';
import { shouldEnforceUploadValidation } from '../../../../../lib/core/buckets/helpers/uploadValidation';

describe('shouldEnforceUploadValidation()', () => {
beforeEach(() => {
jest.restoreAllMocks();
});

const mockContext = (clientId: string | undefined, version: string | undefined) => {
jest.spyOn(requestContext, 'getContext').mockReturnValue({ clientId, version });
};

describe('When there are no client headers', () => {
it('When clientId is missing, then it should enforce', () => {
mockContext(undefined, '1.0.0');
expect(shouldEnforceUploadValidation()).toBe(true);
});

it('When version is missing, then it should enforce', () => {
mockContext('internxt-cli', undefined);
expect(shouldEnforceUploadValidation()).toBe(true);
});

it('When both are missing, then it should enforce', () => {
mockContext(undefined, undefined);
expect(shouldEnforceUploadValidation()).toBe(true);
});
});

describe('When the client is not in the exempt list', () => {
it('When called with an unknown client, then it should enforce', () => {
mockContext('some-unknown-client', '9.9.9');
expect(shouldEnforceUploadValidation()).toBe(true);
});
});

describe('When the client is drive-desktop-linux (all versions exempt)', () => {
it('When called with any version, then it should not enforce', () => {
mockContext('drive-desktop-linux', '0.0.1');
expect(shouldEnforceUploadValidation()).toBe(false);
});

it('When called with a high version, then it should not enforce', () => {
mockContext('drive-desktop-linux', '99.99.99');
expect(shouldEnforceUploadValidation()).toBe(false);
});
});

describe('When the client is internxt-cli (exempt up to 1.6.3)', () => {
it('When version is below the exempt threshold, then it should not enforce', () => {
mockContext('internxt-cli', '1.6.2');
expect(shouldEnforceUploadValidation()).toBe(false);
});

it('When version equals the exempt threshold, then it should not enforce', () => {
mockContext('internxt-cli', '1.6.3');
expect(shouldEnforceUploadValidation()).toBe(false);
});

it('When version is above the exempt threshold, then it should enforce', () => {
mockContext('internxt-cli', '1.6.4');
expect(shouldEnforceUploadValidation()).toBe(true);
});

it('When minor version is above the exempt threshold, then it should enforce', () => {
mockContext('internxt-cli', '1.7.0');
expect(shouldEnforceUploadValidation()).toBe(true);
});

it('When major version is above the exempt threshold, then it should enforce', () => {
mockContext('internxt-cli', '2.0.0');
expect(shouldEnforceUploadValidation()).toBe(true);
});
});

describe('When the client is drive-desktop-windows (exempt up to 2.6.6)', () => {
it('When version is below the exempt threshold, then it should not enforce', () => {
mockContext('drive-desktop-windows', '2.6.5');
expect(shouldEnforceUploadValidation()).toBe(false);
});

it('When version equals the exempt threshold, then it should not enforce', () => {
mockContext('drive-desktop-windows', '2.6.6');
expect(shouldEnforceUploadValidation()).toBe(false);
});

it('When version is above the exempt threshold, then it should enforce', () => {
mockContext('drive-desktop-windows', '2.6.7');
expect(shouldEnforceUploadValidation()).toBe(true);
});
});
});
7 changes: 6 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1808,6 +1808,11 @@
dependencies:
"@types/node" "*"

"@types/semver@^7.7.1":
version "7.7.1"
resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.7.1.tgz#3ce3af1a5524ef327d2da9e4fd8b6d95c8d70528"
integrity sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==

"@types/send@*":
version "1.2.1"
resolved "https://registry.yarnpkg.com/@types/send/-/send-1.2.1.tgz#6a784e45543c18c774c049bff6d3dbaf045c9c74"
Expand Down Expand Up @@ -8149,7 +8154,7 @@ semver-store@^0.3.0:
resolved "https://registry.yarnpkg.com/semver-store/-/semver-store-0.3.0.tgz#ce602ff07df37080ec9f4fb40b29576547befbe9"
integrity sha512-TcZvGMMy9vodEFSse30lWinkj+JgOBvPn8wRItpQRSayhc+4ssDs335uklkfvQQJgL/WvmHLVj4Ycv2s7QCQMg==

semver@7.7.4, semver@^7.2.1, semver@^7.3.5, semver@^7.3.8, semver@^7.5.3, semver@^7.5.4, semver@^7.7.3:
semver@7.7.4, semver@^7.2.1, semver@^7.3.5, semver@^7.3.8, semver@^7.5.3, semver@^7.5.4, semver@^7.7.3, semver@^7.7.4:
version "7.7.4"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.4.tgz#28464e36060e991fa7a11d0279d2d3f3b57a7e8a"
integrity sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==
Expand Down
Loading