From 758480b85150f3130106769b57b9ee8aae3ba647 Mon Sep 17 00:00:00 2001 From: Vikram Kalta Date: Tue, 29 Oct 2024 22:46:00 +0000 Subject: [PATCH 01/10] fix: added support for arrays in only and except --- src/lib/entry-queryable.ts | 24 ++++++++++++++++++++---- src/lib/internal-types.ts | 2 +- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/lib/entry-queryable.ts b/src/lib/entry-queryable.ts index 9a25de0..c3f4fa8 100644 --- a/src/lib/entry-queryable.ts +++ b/src/lib/entry-queryable.ts @@ -15,8 +15,16 @@ export class EntryQueryable extends BaseQuery { * @param {string} fieldUid - field uid to select * @returns {EntryQueryable} - returns EntryQueryable object for chaining method calls */ - only(fieldUid: string): EntryQueryable { - this._queryParams['only[BASE][]'] = fieldUid; + only(fieldUid: string|string[]): EntryQueryable { + if (Array.isArray(fieldUid)) { + let i = 0; + for (const uid of fieldUid) { + this._queryParams[`only[BASE][${i}]`] = uid; + i++; + } + } else { + this._queryParams["only[BASE][]"] = fieldUid; + } return this; } @@ -34,8 +42,16 @@ export class EntryQueryable extends BaseQuery { * @param {string} fieldUid - field uid to exclude * @returns {EntryQueryable} - returns EntryQueryable object for chaining method calls */ - except(fieldUid: string): EntryQueryable { - this._queryParams['except[BASE][]'] = fieldUid; + except(fieldUid: string|string[]): EntryQueryable { + if (Array.isArray(fieldUid)) { + let i = 0; + for (const uid of fieldUid) { + this._queryParams[`except[BASE][${i}]`] = uid; + i++; + } + } else { + this._queryParams["except[BASE][]"] = fieldUid; + } return this; } diff --git a/src/lib/internal-types.ts b/src/lib/internal-types.ts index 5c998d8..58ed2c1 100644 --- a/src/lib/internal-types.ts +++ b/src/lib/internal-types.ts @@ -3,5 +3,5 @@ export type params = { } export type queryParams = { - [key: string]: string | boolean | number | string[] + [key: string]: string | boolean | number | string[] | any } From 818e13ffeed4bbd0131eda2758a93f13e14b7f96 Mon Sep 17 00:00:00 2001 From: Vikram Kalta Date: Tue, 29 Oct 2024 22:47:47 +0000 Subject: [PATCH 02/10] fix: bumped version --- package.json | 2 +- src/lib/internal-types.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index fc32277..22716f1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@contentstack/delivery-sdk", - "version": "4.4.0", + "version": "4.4.1", "type": "module", "main": "./dist/esm/src/index.js", "types": "./dist/esm/types/src/index.d.ts", diff --git a/src/lib/internal-types.ts b/src/lib/internal-types.ts index 58ed2c1..5c998d8 100644 --- a/src/lib/internal-types.ts +++ b/src/lib/internal-types.ts @@ -3,5 +3,5 @@ export type params = { } export type queryParams = { - [key: string]: string | boolean | number | string[] | any + [key: string]: string | boolean | number | string[] } From 197c6dc4b4301ebb7dd2f2bc20b444c3db03c1b2 Mon Sep 17 00:00:00 2001 From: Vikram Kalta Date: Tue, 12 Nov 2024 23:58:14 +0000 Subject: [PATCH 03/10] fix: added test cases for only and except filters --- package-lock.json | 4 ++-- src/lib/base-query.ts | 3 +-- src/lib/entry-queryable.ts | 1 - test/api/entry-queryables.spec.ts | 22 ++++++++++++++++++++++ 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index b514396..d9b28a7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@contentstack/delivery-sdk", - "version": "4.4.0", + "version": "4.4.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@contentstack/delivery-sdk", - "version": "4.4.0", + "version": "4.4.1", "dependencies": { "@contentstack/core": "^1.1.0", "@contentstack/utils": "^1.3.8", diff --git a/src/lib/base-query.ts b/src/lib/base-query.ts index 91b77ce..3e88255 100644 --- a/src/lib/base-query.ts +++ b/src/lib/base-query.ts @@ -209,7 +209,7 @@ export class BaseQuery extends Pagination { requestParams = { ...this._queryParams, query: { ...this._parameters } }; } - const getRequestOptions: any = { params: requestParams }; + const getRequestOptions: any = requestParams; if (this._variants) { getRequestOptions.headers = { @@ -217,7 +217,6 @@ export class BaseQuery extends Pagination { 'x-cs-variant-uid': this._variants }; } - const response = await getData(this._client, this._urlPath, getRequestOptions); return response as FindResponse; diff --git a/src/lib/entry-queryable.ts b/src/lib/entry-queryable.ts index c3f4fa8..57c1edd 100644 --- a/src/lib/entry-queryable.ts +++ b/src/lib/entry-queryable.ts @@ -25,7 +25,6 @@ export class EntryQueryable extends BaseQuery { } else { this._queryParams["only[BASE][]"] = fieldUid; } - return this; } diff --git a/test/api/entry-queryables.spec.ts b/test/api/entry-queryables.spec.ts index 8763f14..a57c6f1 100644 --- a/test/api/entry-queryables.spec.ts +++ b/test/api/entry-queryables.spec.ts @@ -258,6 +258,28 @@ describe('Query Operators API test cases', () => { } }); + + it('should check for projected fields after only filter is applied', async () => { + const query = makeEntries('contenttype_uid2').only(['title', 'reference']) + const result = await query.find(); + if (result.entries) { + expect(result.entries.length).toBeGreaterThan(0); + expect(result.entries[0].reference).toBeDefined(); + expect(result.entries[0].title).toBeDefined(); + expect(result.entries[0]._version).toBeUndefined(); + } + }); + + it('should ignore fields after except filter is applied', async () => { + const query = makeEntries('contenttype_uid2').except(['title', 'reference']) + const result = await query.find(); + if (result.entries) { + expect(result.entries.length).toBeGreaterThan(0); + expect(result.entries[0].reference).toBeUndefined(); + expect(result.entries[0].title).toBeUndefined(); + expect(result.entries[0]._version).toBeDefined(); + } + }); }); function makeEntries(contentTypeUid = ''): Entries { From 42bc09a2003747aa76c6ef7af0fbb27c902db37d Mon Sep 17 00:00:00 2001 From: Vikram Kalta Date: Sun, 17 Nov 2024 10:32:54 +0000 Subject: [PATCH 04/10] fix: reverted request params --- src/lib/base-query.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/base-query.ts b/src/lib/base-query.ts index 3e88255..cb99594 100644 --- a/src/lib/base-query.ts +++ b/src/lib/base-query.ts @@ -209,7 +209,7 @@ export class BaseQuery extends Pagination { requestParams = { ...this._queryParams, query: { ...this._parameters } }; } - const getRequestOptions: any = requestParams; + const getRequestOptions: any = { params: requestParams }; if (this._variants) { getRequestOptions.headers = { From c9f39620ecd7782d3ad7189710e675f68b37c57d Mon Sep 17 00:00:00 2001 From: Vikram Kalta Date: Tue, 19 Nov 2024 22:05:04 +0000 Subject: [PATCH 05/10] fix: bumped version --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index afd14f9..ac9e0b8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@contentstack/delivery-sdk", - "version": "4.4.2", + "version": "4.4.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@contentstack/delivery-sdk", - "version": "4.4.2", + "version": "4.4.3", "license": "MIT", "dependencies": { "@contentstack/core": "^1.1.3", diff --git a/package.json b/package.json index 6c2a229..bbd0e73 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@contentstack/delivery-sdk", - "version": "4.4.2", + "version": "4.4.3", "type": "module", "license": "MIT", "main": "./dist/legacy/index.cjs", From 92cdf3e6b4c4b7cad80a602dc8e477a428871b48 Mon Sep 17 00:00:00 2001 From: Nadeem Patwekar Date: Wed, 27 Nov 2024 17:03:25 +0530 Subject: [PATCH 06/10] fix: regex method fixed for validation --- CHANGELOG.md | 4 ++++ package.json | 2 +- src/lib/query.ts | 12 +++++------- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 80754d2..4e702b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +### Version: 4.4.3 +#### Date: November-30-2024 +Fix: regex method fixed for validation + ### Version: 4.4.2 #### Date: November-16-2024 Fix: Variants reset issue fix on query call diff --git a/package.json b/package.json index 216971b..883f718 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@contentstack/delivery-sdk", - "version": "4.4.2", + "version": "4.4.3", "type": "module", "license": "MIT", "main": "./dist/legacy/index.cjs", diff --git a/src/lib/query.ts b/src/lib/query.ts index 0139f8a..57de991 100644 --- a/src/lib/query.ts +++ b/src/lib/query.ts @@ -3,10 +3,6 @@ import { BaseQuery } from './base-query'; import { BaseQueryParameters, QueryOperation, QueryOperator, TaxonomyQueryOperation } from './types'; import { params, queryParams } from './internal-types'; -const safePatterns: RegExp[] = [ - /^[a-zA-Z0-9_.-]+$/, // Alphanumeric with underscores, periods, and dashes -]; - export class Query extends BaseQuery { private _contentTypeUid?: string; @@ -34,10 +30,12 @@ export class Query extends BaseQuery { // Validate if input matches any of the safe, pre-approved patterns private isValidRegexPattern(input: string): boolean { - if (!this.isValidAlphanumeric(input)) { - return false; + try { + new RegExp(input); // Try to create a new RegExp object + return true; // No error means it's a valid regex + } catch (e) { + return false; // Error means it's not a valid regex } - return safePatterns.some(pattern => pattern.test(input)); } private isValidValue(value: any[]): boolean { From 9d345657b56e1313da19ca7057cd152e664d6382 Mon Sep 17 00:00:00 2001 From: Nadeem Patwekar Date: Wed, 27 Nov 2024 17:09:17 +0530 Subject: [PATCH 07/10] chore: axios version bump --- .talismanrc | 2 +- package-lock.json | 13 ++++++------- package.json | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/.talismanrc b/.talismanrc index 46d82a6..2c8830b 100644 --- a/.talismanrc +++ b/.talismanrc @@ -1,6 +1,6 @@ fileignoreconfig: - filename: package-lock.json - checksum: d388091773e9515cd3c0a5b881644775aa7b8233a405642e49133f296a4ceeeb + checksum: c27c6a4629a6b1cec5e01b5db15d0e12646a1250e0cf1292ac58c561e9bc4993 - filename: test/unit/image-transform.spec.ts checksum: 7beabdd07bd35d620668fcd97e1a303b9cbc40170bf3008a376d75ce0895de2a - filename: test/utils/mocks.ts diff --git a/package-lock.json b/package-lock.json index d95acbd..5355f11 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,18 +1,18 @@ { "name": "@contentstack/delivery-sdk", - "version": "4.4.2", + "version": "4.4.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@contentstack/delivery-sdk", - "version": "4.4.2", + "version": "4.4.3", "license": "MIT", "dependencies": { "@contentstack/core": "^1.1.3", "@contentstack/utils": "^1.3.14", "@types/humps": "^2.0.6", - "axios": "^1.7.7", + "axios": "^1.7.8", "dotenv": "^16.4.5", "humps": "^2.0.1", "path-browserify": "^1.0.1" @@ -4630,10 +4630,9 @@ "license": "MIT" }, "node_modules/axios": { - "version": "1.7.7", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", - "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", - "license": "MIT", + "version": "1.7.8", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.8.tgz", + "integrity": "sha512-Uu0wb7KNqK2t5K+YQyVCLM76prD5sRFjKHbJYCP1J7JFGEQ6nN7HWn9+04LAeiJ3ji54lgS/gZCH1oxyrf1SPw==", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", diff --git a/package.json b/package.json index 883f718..59503ea 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "@contentstack/core": "^1.1.3", "@contentstack/utils": "^1.3.14", "@types/humps": "^2.0.6", - "axios": "^1.7.7", + "axios": "^1.7.8", "dotenv": "^16.4.5", "humps": "^2.0.1", "path-browserify": "^1.0.1" From 190cb22a304be1b4e1fac20dddf7965d2743a7de Mon Sep 17 00:00:00 2001 From: Nadeem Patwekar Date: Fri, 29 Nov 2024 17:09:06 +0530 Subject: [PATCH 08/10] test: added tests for regex and other query methods --- test/unit/query.spec.ts | 76 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/test/unit/query.spec.ts b/test/unit/query.spec.ts index 4482f7d..301d124 100644 --- a/test/unit/query.spec.ts +++ b/test/unit/query.spec.ts @@ -83,6 +83,82 @@ describe('Query class', () => { expect(mainQuery2._parameters).toHaveProperty('$and', [subQuery1._parameters, subQuery2._parameters]); }); + it('should result in error when regex method is called with invalid regex', async () => { + const regexQuery = getQueryObject(client, 'your-referenced-content-type-uid'); + expect(() => regexQuery.regex("fieldUid", "[a-z")).toThrow("Invalid regexPattern: Must be a valid regular expression"); + }); + + it('should add a regex parameter to _parameters when regex method is called with valid regex', () => { + query.regex('fieldUid', '^ABCXYZ123'); + expect(query._parameters['fieldUid']).toEqual({ $regex: '^ABCXYZ123' }); + }); + + it('should add a containedIn parameter to _parameters', () => { + query.containedIn('fieldUid', ['value1', 'value2']); + expect(query._parameters['fieldUid']).toEqual({ '$in': ['value1', 'value2'] }); + }); + + it('should add a notContainedIn parameter to _parameters', () => { + query.notContainedIn('fieldUid', ['value1', 'value2']); + expect(query._parameters['fieldUid']).toEqual({ '$nin': ['value1', 'value2'] }); + }); + + it('should add an exists parameter to _parameters', () => { + query.exists('fieldUid'); + expect(query._parameters['fieldUid']).toEqual({ '$exists': true }); + }); + + it('should add a notExists parameter to _parameters', () => { + query.notExists('fieldUid'); + expect(query._parameters['fieldUid']).toEqual({ '$exists': false }); + }); + + it('should add an equalTo parameter to _parameters', () => { + query.equalTo('fieldUid', 'value'); + expect(query._parameters['fieldUid']).toEqual('value'); + }); + + it('should add a notEqualTo parameter to _parameters', () => { + query.notEqualTo('fieldUid', 'value'); + expect(query._parameters['fieldUid']).toEqual({ '$ne': 'value' }); + }); + + it('should add a lessThan parameter to _parameters', () => { + query.lessThan('fieldUid', 10); + expect(query._parameters['fieldUid']).toEqual({ '$lt': 10 }); + }); + + it('should add a lessThanOrEqualTo parameter to _parameters', () => { + query.lessThanOrEqualTo('fieldUid', 10); + expect(query._parameters['fieldUid']).toEqual({ '$lte': 10 }); + }); + + it('should add a greaterThan parameter to _parameters', () => { + query.greaterThan('fieldUid', 10); + expect(query._parameters['fieldUid']).toEqual({ '$gt': 10 }); + }); + + it('should add a greaterThanOrEqualTo parameter to _parameters', () => { + query.greaterThanOrEqualTo('fieldUid', 10); + expect(query._parameters['fieldUid']).toEqual({ '$gte': 10 }); + }); + + it('should add a tags parameter to _parameters', () => { + query.tags(['tag1', 'tag2']); + expect(query._parameters['tags']).toEqual(['tag1', 'tag2']); + }); + + it('should add a search parameter to _queryParams', () => { + query.search('searchKey'); + expect(query._queryParams['typeahead']).toEqual('searchKey'); + }); + + it('should provide proper response when find method is called', async () => { + mockClient.onGet(`/content_types/contentTypeUid/entries`).reply(200, entryFindMock); + const returnedValue = await query.find(); + expect(returnedValue).toEqual(entryFindMock); + }); + it('should provide proper response when find method is called', async () => { mockClient.onGet(`/content_types/contentTypeUid/entries`).reply(200, entryFindMock); const returnedValue = await query.find(); From 29b18e4d1d2048d352ffedc253ad73e7da7c3791 Mon Sep 17 00:00:00 2001 From: Vikram Kalta Date: Sun, 1 Dec 2024 11:07:51 +0000 Subject: [PATCH 09/10] fix: updated axios version --- package-lock.json | 9 ++++----- package.json | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 09e0a63..5355f11 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "@contentstack/core": "^1.1.3", "@contentstack/utils": "^1.3.14", "@types/humps": "^2.0.6", - "axios": "^1.7.7", + "axios": "^1.7.8", "dotenv": "^16.4.5", "humps": "^2.0.1", "path-browserify": "^1.0.1" @@ -4630,10 +4630,9 @@ "license": "MIT" }, "node_modules/axios": { - "version": "1.7.7", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", - "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", - "license": "MIT", + "version": "1.7.8", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.8.tgz", + "integrity": "sha512-Uu0wb7KNqK2t5K+YQyVCLM76prD5sRFjKHbJYCP1J7JFGEQ6nN7HWn9+04LAeiJ3ji54lgS/gZCH1oxyrf1SPw==", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", diff --git a/package.json b/package.json index 883f718..59503ea 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "@contentstack/core": "^1.1.3", "@contentstack/utils": "^1.3.14", "@types/humps": "^2.0.6", - "axios": "^1.7.7", + "axios": "^1.7.8", "dotenv": "^16.4.5", "humps": "^2.0.1", "path-browserify": "^1.0.1" From f7594627ab7e2bff7c4ee803750e6eef80e22c76 Mon Sep 17 00:00:00 2001 From: "harshitha.d" Date: Wed, 4 Dec 2024 02:07:17 +0530 Subject: [PATCH 10/10] removed vulnerability --- src/lib/query.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/lib/query.ts b/src/lib/query.ts index 57de991..d2f519e 100644 --- a/src/lib/query.ts +++ b/src/lib/query.ts @@ -30,11 +30,15 @@ export class Query extends BaseQuery { // Validate if input matches any of the safe, pre-approved patterns private isValidRegexPattern(input: string): boolean { + const validRegex = /^[a-zA-Z0-9|^$.*+?()[\]{}\\-]+$/; // Allow only safe regex characters + if (!validRegex.test(input)) { + return false; + } try { - new RegExp(input); // Try to create a new RegExp object - return true; // No error means it's a valid regex + new RegExp(input); + return true; } catch (e) { - return false; // Error means it's not a valid regex + return false; } }