From ee923a6e402c59084628c6defaad0f63738be62a Mon Sep 17 00:00:00 2001 From: Tia Esguerra Date: Fri, 21 Nov 2025 04:44:39 -0800 Subject: [PATCH 1/3] feat: add last login filtering support to Users API --- lib/provisioning/account.js | 12 +++++++--- .../api/provisioning/account_spec.js | 23 +++++++++++++++++++ types/index.d.ts | 2 +- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/lib/provisioning/account.js b/lib/provisioning/account.js index f2c8566c..1b33342d 100644 --- a/lib/provisioning/account.js +++ b/lib/provisioning/account.js @@ -122,18 +122,24 @@ function user(user_id, options = {}, callback) { * @param [prefix] {string} - Returns users where the name or email address begins with the specified case-insensitive * string. * @param [sub_account_id[ {string} - Only returns users who have access to the specified account. + * @param [last_login] {boolean} - Returns users based on their last login within a specified date range. true for users who logged in, false for users who haven't logged in, undefined for all users. + * @param [from_date] {Date|string} - Last login start date. + * @param [to_date] {Date|string} - Last login end date. * @param [options] {object} - See {@link https://cloudinary.com/documentation/cloudinary_sdks#configuration_parameters|Configuration parameters} in the SDK documentation. * @param [callback] {function} */ -function users(pending, user_ids, prefix, sub_account_id, options = {}, callback) { +function users(pending, user_ids, prefix, sub_account_id, last_login, from_date, to_date, options = {}, callback) { let uri = ['users']; let params = { ids: user_ids, pending, prefix, - sub_account_id + sub_account_id, + last_login, + from: from_date, + to: to_date }; - return call_account_api('GET', uri, pickOnlyExistingValues(params, "ids", "pending", "prefix", "sub_account_id"), callback, options); + return call_account_api('GET', uri, pickOnlyExistingValues(params, "ids", "pending", "prefix", "sub_account_id", "last_login", "from", "to"), callback, options); } /** diff --git a/test/integration/api/provisioning/account_spec.js b/test/integration/api/provisioning/account_spec.js index cd0f9bd4..455c94fa 100644 --- a/test/integration/api/provisioning/account_spec.js +++ b/test/integration/api/provisioning/account_spec.js @@ -199,6 +199,29 @@ runOnlyForInternalPRs('account API - Provisioning', function () { expect(result.users.length).to.eql(1); }); + it("Gets users by last login", async () => { + const today = new Date(); + const result1 = await cloudinary.provisioning.account.users( + null, + [USER_ID_1], + null, + null, + true, + today, + today + ); + expect(result1.users.length).to.eql(0); + + const result2 = await cloudinary.provisioning.account.users( + null, + [USER_ID_1], + null, + null, + false + ); + expect(result2.users.length).to.eql(1); + }); + it('Should throw an error when attempting to get users by a nonexistent sub_account_id', async () => { const random_id = Math.floor(Math.random() * 100000); try { diff --git a/types/index.d.ts b/types/index.d.ts index 601be7cd..f6ad0aed 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -1495,7 +1495,7 @@ declare module 'cloudinary' { function user(userId: string, options?: ProvisioningApiOptions, callback?: ResponseCallback): Promise; - function users(pending: boolean, userIds?: string[], prefix?: string, subAccountId?: string, options?: ProvisioningApiOptions, callback?: ResponseCallback): Promise; + function users(pending: boolean, userIds?: string[], prefix?: string, subAccountId?: string, lastLogin?: boolean, fromDate?: Date | string, toDate?: Date | string, options?: ProvisioningApiOptions, callback?: ResponseCallback): Promise; function create_user(name: string, email: string, role: string, subAccountIds?: string[], options?: ProvisioningApiOptions, callback?: ResponseCallback): Promise; From a3efb79d620b5023a22e212d2bdacd412606a3b7 Mon Sep 17 00:00:00 2001 From: Tia Esguerra Date: Sun, 4 Jan 2026 11:16:04 -0800 Subject: [PATCH 2/3] refactor: move last login, from date, and to date into the options object --- lib/provisioning/account.js | 25 ++++++++++++++++--------- types/index.d.ts | 2 +- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/lib/provisioning/account.js b/lib/provisioning/account.js index 1b33342d..cc5bf723 100644 --- a/lib/provisioning/account.js +++ b/lib/provisioning/account.js @@ -121,23 +121,30 @@ function user(user_id, options = {}, callback) { * @param [user_ids] {string[]} - A list of up to 100 user IDs. When provided, other parameters are ignored. * @param [prefix] {string} - Returns users where the name or email address begins with the specified case-insensitive * string. - * @param [sub_account_id[ {string} - Only returns users who have access to the specified account. - * @param [last_login] {boolean} - Returns users based on their last login within a specified date range. true for users who logged in, false for users who haven't logged in, undefined for all users. - * @param [from_date] {Date|string} - Last login start date. - * @param [to_date] {Date|string} - Last login end date. - * @param [options] {object} - See {@link https://cloudinary.com/documentation/cloudinary_sdks#configuration_parameters|Configuration parameters} in the SDK documentation. + * @param [sub_account_id] {string} - Only returns users who have access to the specified account. + * @param [options] {object} - Configuration options. Can include: + * - lastLogin {boolean} - Returns users based on their last login within a specified date range. true for users who logged in, false for users who haven't logged in, undefined for all users. + * - fromDate {Date|string} - Last login start date. + * - toDate {Date|string} - Last login end date. + * See {@link https://cloudinary.com/documentation/cloudinary_sdks#configuration_parameters|Configuration parameters} in the SDK documentation. * @param [callback] {function} */ -function users(pending, user_ids, prefix, sub_account_id, last_login, from_date, to_date, options = {}, callback) { +function users(pending, user_ids, prefix, sub_account_id, options = {}, callback) { + // Handle optional callback argument + if (typeof options === 'function') { + callback = options; + options = {}; + } + let uri = ['users']; let params = { ids: user_ids, pending, prefix, sub_account_id, - last_login, - from: from_date, - to: to_date + last_login: options.lastLogin, + from: options.fromDate, + to: options.toDate }; return call_account_api('GET', uri, pickOnlyExistingValues(params, "ids", "pending", "prefix", "sub_account_id", "last_login", "from", "to"), callback, options); } diff --git a/types/index.d.ts b/types/index.d.ts index f6ad0aed..3e5db75e 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -1495,7 +1495,7 @@ declare module 'cloudinary' { function user(userId: string, options?: ProvisioningApiOptions, callback?: ResponseCallback): Promise; - function users(pending: boolean, userIds?: string[], prefix?: string, subAccountId?: string, lastLogin?: boolean, fromDate?: Date | string, toDate?: Date | string, options?: ProvisioningApiOptions, callback?: ResponseCallback): Promise; + function users(pending: boolean, userIds?: string[], prefix?: string, subAccountId?: string, options?: ProvisioningApiOptions | { lastLogin?: boolean; fromDate?: Date | string; toDate?: Date | string }, callback?: ResponseCallback): Promise; function create_user(name: string, email: string, role: string, subAccountIds?: string[], options?: ProvisioningApiOptions, callback?: ResponseCallback): Promise; From 18882401a37669881343c579a5aceef04e681ad8 Mon Sep 17 00:00:00 2001 From: Tia Esguerra Date: Sun, 4 Jan 2026 11:50:08 -0800 Subject: [PATCH 3/3] test: update the users test to include the new options in the refactored users function --- test/integration/api/provisioning/account_spec.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/test/integration/api/provisioning/account_spec.js b/test/integration/api/provisioning/account_spec.js index 455c94fa..4d949c64 100644 --- a/test/integration/api/provisioning/account_spec.js +++ b/test/integration/api/provisioning/account_spec.js @@ -206,9 +206,11 @@ runOnlyForInternalPRs('account API - Provisioning', function () { [USER_ID_1], null, null, - true, - today, - today + { + lastLogin: true, + fromDate: today, + toDate: today + } ); expect(result1.users.length).to.eql(0); @@ -217,7 +219,9 @@ runOnlyForInternalPRs('account API - Provisioning', function () { [USER_ID_1], null, null, - false + { + lastLogin: false + } ); expect(result2.users.length).to.eql(1); });