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
40 changes: 40 additions & 0 deletions src/management/__generated/managers/users-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import type {
GetUserOrganizations200Response,
GetUsers200Response,
GetUsers200ResponseOneOfInner,
ListUserConnectedAccountsResponseContent,
PatchAuthenticationMethodsByAuthenticationMethodIdRequest,
PostAuthenticationMethods201Response,
PostAuthenticationMethodsRequest,
Expand Down Expand Up @@ -52,6 +53,7 @@ import type {
DeleteUsersByIdRequest,
GetAuthenticationMethodsRequest,
GetAuthenticationMethodsByAuthenticationMethodIdRequest,
GetConnectedAccountsRequest,
GetEnrollmentsRequest,
GetFederatedConnectionsTokensetsRequest,
GetLogsByUserRequest,
Expand Down Expand Up @@ -447,6 +449,44 @@ export class UsersManager extends BaseAPI {
return runtime.JSONApiResponse.fromResponse(response);
}

/**
* Retrieve all connected accounts associated with the user.
* Get a User's Connected Accounts
*
* @throws {RequiredError}
*/
async getConnectedAccounts(
requestParameters: GetConnectedAccountsRequest,
initOverrides?: InitOverride
): Promise<ApiResponse<ListUserConnectedAccountsResponseContent>> {
runtime.validateRequiredRequestParams(requestParameters, ['id']);

const queryParameters = runtime.applyQueryParams(requestParameters, [
{
key: 'from',
config: {},
},
{
key: 'take',
config: {},
},
]);

const response = await this.request(
{
path: `/users/{id}/connected-accounts`.replace(
'{id}',
encodeURIComponent(String(requestParameters.id))
),
method: 'GET',
query: queryParameters,
},
initOverrides
);

return runtime.JSONApiResponse.fromResponse(response);
}

/**
* Retrieve the first confirmed <a href="https://auth0.com/docs/multifactor-authentication/guardian">Guardian</a> enrollment for a user.
* Get the First Confirmed Multi-factor Authentication Enrollment
Expand Down
86 changes: 86 additions & 0 deletions src/management/__generated/models/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3217,6 +3217,59 @@ export interface ClientUpdateSignedRequestObject {
*/
credentials?: Array<ClientClientAuthenticationMethodsPrivateKeyJwtCredentialsInner>;
}
/**
*
*/
export interface ConnectedAccount {
/**
* The unique identifier for the connected account.
*
*/
id: string;
/**
* The name of the connection associated with the account.
*
*/
connection: string;
/**
* The unique identifier of the connection associated with the account.
*
*/
connection_id: string;
/**
* The authentication strategy used by the connection.
*
*/
strategy: string;
/**
*/
access_type: ConnectedAccountAccessTypeEnum;
/**
* The scopes granted for this connected account.
*
*/
scopes?: Array<string>;
/**
* ISO 8601 timestamp when the connected account was created.
*
*/
created_at: string;
/**
* ISO 8601 timestamp when the connected account expires.
*
*/
expires_at?: string;
}

/**
* The access type for the connected account.
*/
export const ConnectedAccountAccessTypeEnum = {
offline: 'offline',
} as const;
export type ConnectedAccountAccessTypeEnum =
(typeof ConnectedAccountAccessTypeEnum)[keyof typeof ConnectedAccountAccessTypeEnum];

/**
*
*/
Expand Down Expand Up @@ -10016,6 +10069,19 @@ export interface ListUserAttributeProfilesPaginatedResponseContent {
*/
user_attribute_profiles?: Array<UserAttributeProfile>;
}
/**
*
*/
export interface ListUserConnectedAccountsResponseContent {
/**
*/
connected_accounts: Array<ConnectedAccount>;
/**
* The token to retrieve the next page of connected accounts (if there is one)
*
*/
next?: string;
}
/**
*
*/
Expand Down Expand Up @@ -23736,6 +23802,26 @@ export interface GetAuthenticationMethodsByAuthenticationMethodIdRequest {
*/
authentication_method_id: string;
}
/**
*
*/
export interface GetConnectedAccountsRequest {
/**
* ID of the user to list connected accounts for.
*
*/
id: string;
/**
* Optional Id from which to start selection.
*
*/
from?: string;
/**
* Number of results to return. Defaults to 10 with a maximum of 20
*
*/
take?: number;
}
/**
*
*/
Expand Down
99 changes: 99 additions & 0 deletions test/management/users.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1727,4 +1727,103 @@ describe('UsersManager', () => {
expect(request.isDone()).toBe(true);
});
});

describe('#getConnectedAccounts', () => {
const data = {
id: 'user_id',
};

let scope: nock.Scope;

beforeEach(() => {
scope = nock(API_URL).get(`/users/${data.id}/connected-accounts`).reply(200, []);
});

it('should return a promise when no callback is given', (done) => {
expect(usersManager.getConnectedAccounts(data).then(() => done())).toBeInstanceOf(Promise);
});

it('should perform a GET request to /api/v2/users/user_id/connected-accounts', async () => {
await usersManager.getConnectedAccounts(data);
expect(scope.isDone()).toBe(true);
});

it('should pass any errors to the promise catch handler', async () => {
nock.cleanAll();

nock(API_URL).get(`/users/${data.id}/connected-accounts`).reply(500, {});

try {
await usersManager.getConnectedAccounts(data);
} catch (err) {
expect(err).toBeDefined();
}
});

it('should include the token in the authorization header', async () => {
nock.cleanAll();

const request = nock(API_URL)
.get(`/users/${data.id}/connected-accounts`)
.matchHeader('authorization', `Bearer ${token}`)
.reply(200, []);

await usersManager.getConnectedAccounts(data);
expect(request.isDone()).toBe(true);
});

it('should pass the body of the response to the "then" handler', async () => {
nock.cleanAll();

const connectedAccountsData = [
{
id: 'conn_123',
connection: 'google-oauth2',
connection_id: 'con_abc123',
strategy: 'google-oauth2',
access_type: 'offline',
scopes: ['profile', 'email'],
created_at: '2023-01-01T00:00:00.000Z',
expires_at: '2024-01-01T00:00:00.000Z',
},
];

const response = {
connected_accounts: connectedAccountsData,
next: null,
};

nock(API_URL).get(`/users/${data.id}/connected-accounts`).reply(200, response);

const connectedAccounts = await usersManager.getConnectedAccounts(data);
expect(connectedAccounts.data.connected_accounts).toBeInstanceOf(Array);
expect(connectedAccounts.data.connected_accounts.length).toBe(connectedAccountsData.length);
expect(connectedAccounts.data.connected_accounts[0].id).toBe(connectedAccountsData[0].id);
expect(connectedAccounts.data.connected_accounts[0].connection).toBe(connectedAccountsData[0].connection);
expect(connectedAccounts.data.connected_accounts[0].strategy).toBe(connectedAccountsData[0].strategy);
});

it('should pass the parameters in the query-string', async () => {
nock.cleanAll();

const params = {
from: 'conn_123',
take: 10,
};
const request = nock(API_URL)
.get(`/users/${data.id}/connected-accounts`)
.query(params)
.reply(200, []);

await usersManager.getConnectedAccounts({
id: data.id,
...params,
});
expect(request.isDone()).toBe(true);
});

it('should validate empty id', async () => {
await expect(usersManager.getConnectedAccounts({} as any)).rejects.toThrowError();
});
});
});