Skip to content
Merged
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
21 changes: 13 additions & 8 deletions src/tools/auth0/handlers/connections.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,17 +162,22 @@ export const getConnectionEnabledClients = async (

let enabledClients = await auth0Client.connections.clients.get(connectionId);

do {
if (enabledClients && enabledClients.data?.length > 0) {
enabledClients.data.forEach((client) => {
if (client?.client_id) {
enabledClientsFormatted.push(client.client_id);
}
});
// Process first page
enabledClients.data?.forEach((client) => {
if (client?.client_id) {
enabledClientsFormatted.push(client.client_id);
}
});

// Fetch remaining pages
while (enabledClients.hasNextPage()) {
enabledClients = await enabledClients.getNextPage();
} while (enabledClients.hasNextPage());
enabledClients.data?.forEach((client) => {
if (client?.client_id) {
enabledClientsFormatted.push(client.client_id);
}
});
}

return enabledClientsFormatted;
} catch (error) {
Expand Down
11 changes: 8 additions & 3 deletions src/tools/auth0/handlers/flowVaultConnections.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,15 @@ export const getAllFlowConnections = async (
const allFlowConnections: Management.FlowsVaultConnectionSummary[] = [];

let vaultConnections = await auth0Client.flows.vault.connections.list();
do {
allFlowConnections.push(...vaultConnections.data);

// Process first page
allFlowConnections.push(...vaultConnections.data);

// Fetch remaining pages
while (vaultConnections.hasNextPage()) {
vaultConnections = await vaultConnections.getNextPage();
} while (vaultConnections.hasNextPage());
allFlowConnections.push(...vaultConnections.data);
}

return allFlowConnections;
};
Expand Down
33 changes: 24 additions & 9 deletions src/tools/auth0/handlers/organizations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -560,10 +560,15 @@ export default class OrganizationsHandler extends DefaultHandler {
let organizationConnections = await this.client.organizations.enabledConnections.list(
organizationId
);
do {
allOrganizationConnections.push(...organizationConnections.data);

// Process first page
allOrganizationConnections.push(...organizationConnections.data);

// Fetch remaining pages
while (organizationConnections.hasNextPage()) {
organizationConnections = await organizationConnections.getNextPage();
} while (organizationConnections.hasNextPage());
allOrganizationConnections.push(...organizationConnections.data);
}

return allOrganizationConnections;
}
Expand All @@ -576,10 +581,15 @@ export default class OrganizationsHandler extends DefaultHandler {
let organizationClientGrants = await this.client.organizations.clientGrants.list(
organizationId
);
do {
allOrganizationClientGrants.push(...organizationClientGrants.data);

// Process first page
allOrganizationClientGrants.push(...organizationClientGrants.data);

// Fetch remaining pages
while (organizationClientGrants.hasNextPage()) {
organizationClientGrants = await organizationClientGrants.getNextPage();
} while (organizationClientGrants.hasNextPage());
allOrganizationClientGrants.push(...organizationClientGrants.data);
}

return allOrganizationClientGrants;
}
Expand Down Expand Up @@ -614,10 +624,15 @@ export default class OrganizationsHandler extends DefaultHandler {
let orgDiscoveryDomain = await this.client.organizations.discoveryDomains.list(
organizationId
);
do {
allDiscoveryDomains.push(...orgDiscoveryDomain.data);

// Process first page
allDiscoveryDomains.push(...orgDiscoveryDomain.data);

// Fetch remaining pages
while (orgDiscoveryDomain.hasNextPage()) {
orgDiscoveryDomain = await orgDiscoveryDomain.getNextPage();
} while (orgDiscoveryDomain.hasNextPage());
allDiscoveryDomains.push(...orgDiscoveryDomain.data);
}

return allDiscoveryDomains;
} catch (err) {
Expand Down
11 changes: 8 additions & 3 deletions src/tools/auth0/handlers/roles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,10 +181,15 @@ export default class RolesHandler extends DefaultHandler {

const rolesId = roles[index].id as string;
let permissions = await this.client.roles.permissions.list(rolesId, { per_page: 100 });
do {
allPermission.push(...permissions.data);

// Process first page
allPermission.push(...permissions.data);

// Fetch remaining pages
while (permissions.hasNextPage()) {
permissions = await permissions.getNextPage();
} while (permissions.hasNextPage());
allPermission.push(...permissions.data);
}

const strippedPerms = await Promise.all(
allPermission.map(async (permission) => {
Expand Down
34 changes: 34 additions & 0 deletions test/tools/auth0/handlers/connections.tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -924,6 +924,40 @@ describe('#connections enabled clients functionality', () => {

expect(result).to.deep.equal([]);
});

it('should handle multi-page pagination correctly', async () => {
const connectionId = 'con_123';

// Simulate 3 pages of results
const page3 = {
data: [{ client_id: 'client_7' }, { client_id: 'client_8' }],
hasNextPage: () => false,
getNextPage: async () => ({ data: [], hasNextPage: () => false }),
};

const page2 = {
data: [{ client_id: 'client_4' }, { client_id: 'client_5' }, { client_id: 'client_6' }],
hasNextPage: () => true,
getNextPage: async () => page3,
};

const page1 = {
data: [{ client_id: 'client_1' }, { client_id: 'client_2' }, { client_id: 'client_3' }],
hasNextPage: () => true,
getNextPage: async () => page2,
};

mockAuth0Client.connections.clients.get.resolves(page1);

const result = await getConnectionEnabledClients(mockAuth0Client, connectionId);

// Should include ALL clients from ALL 3 pages
expect(result).to.deep.equal([
'client_1', 'client_2', 'client_3', // Page 1
'client_4', 'client_5', 'client_6', // Page 2
'client_7', 'client_8', // Page 3
]);
});
});

describe('#updateConnectionEnabledClients', () => {
Expand Down
33 changes: 33 additions & 0 deletions test/tools/auth0/handlers/flowVaultConnections.tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,39 @@ describe('#flowVaultConnections handler', () => {
expect(data).to.deep.equal([sampleFlowVaultConnections]);
});

it('should handle multi-page pagination for flowVaultConnections', async () => {
// Simulate 3 pages of flow vault connections
const page1 = [
{ id: 'ac_1', name: 'Connection 1', app_id: 'HTTP' },
{ id: 'ac_2', name: 'Connection 2', app_id: 'HTTP' },
];
const page2 = [
{ id: 'ac_3', name: 'Connection 3', app_id: 'HTTP' },
];
const page3 = [
{ id: 'ac_4', name: 'Connection 4', app_id: 'HTTP' },
{ id: 'ac_5', name: 'Connection 5', app_id: 'HTTP' },
];

const auth0 = {
flows: {
vault: {
connections: {
list: (params) => mockPagedData(params, 'connections', page1, [page2, page3]),
},
},
},
pool,
};

const handler = new flowVaultConnections.default({ client: pageClient(auth0), config });
const data = await handler.getType();

// Should include connections from ALL 3 pages
expect(data).to.have.length(5);
expect(data.map((c) => c.id)).to.deep.equal(['ac_1', 'ac_2', 'ac_3', 'ac_4', 'ac_5']);
});

it('should update flowVaultConnections', async () => {
const auth0 = {
flows: {
Expand Down
53 changes: 53 additions & 0 deletions test/tools/auth0/handlers/organizations.tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,59 @@ describe('#organizations handler', () => {
]);
});

it('should handle multi-page pagination for enabled connections', async () => {
// Simulate 3 pages of enabled connections
const connectionsPage1 = [
{ connection_id: 'con_1', connection: { name: 'conn1' } },
{ connection_id: 'con_2', connection: { name: 'conn2' } },
];
const connectionsPage2 = [
{ connection_id: 'con_3', connection: { name: 'conn3' } },
];
const connectionsPage3 = [
{ connection_id: 'con_4', connection: { name: 'conn4' } },
{ connection_id: 'con_5', connection: { name: 'conn5' } },
];

const auth0 = {
organizations: {
list: (params) => Promise.resolve(mockPagedData(params, 'organizations', [sampleOrg])),
enabledConnections: {
list: () =>
mockPagedData(
{},
'enabled_connections',
connectionsPage1,
[connectionsPage2, connectionsPage3]
),
},
clientGrants: {
list: () => mockPagedData({}, 'client_grants', []),
},
discoveryDomains: {
list: () => mockPagedData({}, 'discovery_domains', []),
},
},
clients: {
list: (params) => mockPagedData(params, 'clients', sampleClients),
},
pool,
};

const handler = new organizations.default({ client: pageClient(auth0), config });
const data = await handler.getType();

// Should include connections from ALL 3 pages
expect(data[0].connections).to.have.length(5);
expect(data[0].connections.map((c) => c.connection_id)).to.deep.equal([
'con_1',
'con_2',
'con_3',
'con_4',
'con_5',
]);
});

it('should get all organizations', async function () {
const organizationsPage1 = Array.from({ length: 3 }, (v, i) => ({
id: 'org_' + i,
Expand Down
50 changes: 50 additions & 0 deletions test/tools/auth0/handlers/roles.tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,56 @@ describe('#roles handler', () => {
]);
});

it('should handle multi-page pagination for role permissions', async () => {
// Simulate 3 pages of permissions
const page1Permissions = [
{ permission_name: 'read:users', resource_server_identifier: 'api1' },
{ permission_name: 'write:users', resource_server_identifier: 'api1' },
];
const page2Permissions = [
{ permission_name: 'read:orders', resource_server_identifier: 'api2' },
{ permission_name: 'write:orders', resource_server_identifier: 'api2' },
];
const page3Permissions = [
{ permission_name: 'delete:all', resource_server_identifier: 'api3' },
];

const auth0 = {
roles: {
list: (params) =>
mockPagedData({ ...params, include_totals: true }, 'roles', [
{
name: 'adminRole',
id: 'role_123',
description: 'Admin role with multi-page permissions',
},
]),
permissions: {
list: (roleId, params) =>
mockPagedData(
{ ...params, include_totals: true },
'permissions',
page1Permissions,
[page2Permissions, page3Permissions]
),
},
},
pool,
};

const handler = new roles.default({ client: pageClient(auth0), config });
const data = await handler.getType();

// Should include permissions from ALL 3 pages
expect(data[0].permissions).to.deep.equal([
{ permission_name: 'read:users', resource_server_identifier: 'api1' },
{ permission_name: 'write:users', resource_server_identifier: 'api1' },
{ permission_name: 'read:orders', resource_server_identifier: 'api2' },
{ permission_name: 'write:orders', resource_server_identifier: 'api2' },
{ permission_name: 'delete:all', resource_server_identifier: 'api3' },
]);
});

it('should return an empty array for 501 status code', async () => {
const auth0 = {
roles: {
Expand Down