Skip to content

Commit

Permalink
Add pagination cursor interface.
Browse files Browse the repository at this point in the history
  • Loading branch information
wparad committed May 17, 2022
1 parent 3266b56 commit b709227
Show file tree
Hide file tree
Showing 5 changed files with 157 additions and 94 deletions.
2 changes: 1 addition & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,6 @@
"@typescript-eslint/no-var-requires": "off",
"@typescript-eslint/ban-ts-comment": "off",
"no-use-before-define": "off",
"@typescript-eslint/no-shadow": ["error"]
"no-shadow": ["error"]
}
}
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# Change log
This is the changelog for [Authress SDK](readme.md).

## 1.3 ##
* Add new `Pagination` type which pagination `next.cursor` to enable paging through resources.

## 1.2 ##
* Removed legacy support for RS512 service client tokens.
* Add EdDSA support for `tokenVerifier()` class
Expand Down
37 changes: 37 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,43 @@ const temporaryServiceClientAccessToken = await serviceClientTokenProvider.getTo
const response = await client.get(url, { 'Authorization': `Bearer: ${temporaryServiceClientAccessToken}` });
```
#### Paginating through a collection resource
Some of the resources in the API are paginated. These resources contain a `pagination.next.cursor` property when there is a next page. The cursor can be passed to query to fetch the next page. Here's an example usage:
```js
const { AuthressClient } = require('authress-sdk');
const authressClient = new AuthressClient({ baseUrl: 'https://DOMAIN.api-REGION.authress.io' })

// on api route
async function (resourceId) {
// Get the user token and pass it to authress
const authorizationToken = request.headers.get('authorization');
authressClient.setToken(authorizationToken);

// Get the users resources
const response = await authressClient.userPermissions.getUserResources(userId, `resources/*`, 10, null, 'READ');
for (const resource of response.data.resources) {
// Iterate on resource
}

// Get the next page:
const nextPageResponse = await authressClient.userPermissions.getUserResources(userId, `resources/*`, 10, response.data.pagination.next.cursor, 'READ');
for (const resource of nextPageResponse.data.resources) {
// Iterate on resource
}

// Get all the next pages:
let cursor = response.data.pagination?.next?.cursor;
while (cursor) {
const response = await authressClient.userPermissions.getUserResources(userId, `resources/*`, 10, cursor, 'READ');
cursor = response.data.pagination?.next?.cursor;
for (const resource of response.data.resources) {
// Iterate on resource
}
}
}
```
## Contributions
### Adding new DTO and methods
Expand Down
103 changes: 10 additions & 93 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
/* eslint-disable @typescript-eslint/no-empty-interface */
/* eslint-disable no-shadow */

import { Response } from './src/response';
import { Response, IPaginated, Links, Cursor } from './src/response';

import { ConnectionsApi } from './src/connections/api';
export * from './src/connections/api';
Expand Down Expand Up @@ -123,19 +123,13 @@ export namespace AccessRecord {
* @export
* @interface AccessRecordCollection
*/
export interface AccessRecordCollection {
export interface AccessRecordCollection extends IPaginated<AccessRecordCollection> {
/**
*
* @type {Array<AccessRecord>}
* @memberof AccessRecordCollection
*/
records: Array<AccessRecord>;
/**
*
* @type {CollectionLinks}
* @memberof AccessRecordCollection
*/
links: CollectionLinks;
}

/**
Expand Down Expand Up @@ -325,7 +319,7 @@ export interface IdentityRequest {
* @export
* @interface UserResources
*/
export interface UserResources {
export interface UserResources extends IPaginated<UserResources> {
/**
*
* @type {AccountLink}
Expand All @@ -350,32 +344,20 @@ export interface UserResources {
* @memberof UserResources
*/
accessToAllSubResources?: boolean;
/**
*
* @type {CollectionLinks}
* @memberof UserResources
*/
links?: CollectionLinks;
}

/**
* The collection of a list of clients
* @export
* @interface ServiceClientCollection
*/
export interface ServiceClientCollection {
export interface ServiceClientCollection extends IPaginated<ServiceClientCollection> {
/**
* A list of clients
* @type {Array<ServiceClient>}
* @memberof ServiceClientCollection
*/
clients: Array<ServiceClientSummary>;
/**
*
* @type {CollectionLinks}
* @memberof ServiceClientCollection
*/
links: CollectionLinks;
}
/**
* A client configuration.
Expand Down Expand Up @@ -554,20 +536,13 @@ export interface ResourcePermissionsCollection {
* @export
* @interface ResourceUsersCollection
*/
export interface ResourceUsersCollection {
export interface ResourceUsersCollection extends IPaginated<ResourceUsersCollection> {
/**
*
* @type {Array<UserRoleCollection>}
* @memberof ResourceUsersCollection
*/
users: Array<UserRoleCollection>;

/**
*
* @type {CollectionLinks}
* @memberof ResourceUsersCollection
*/
links: CollectionLinks;
}

/**
Expand Down Expand Up @@ -616,25 +591,6 @@ export interface Role {
permissions: Array<PermissionObject>;
}

/**
* A url linking object that complies to application/links+json RFC. Either is an IANA approved link relation or has a custom rel specified.
* @export
* @interface Link
*/
export interface Link {
/**
* The absolute url pointing to the reference resource.
* @type {string}
* @memberof Link
*/
href: string;
/**
* Optional property indicating the type of link if it is not a default IANA approved global link relation.
* @type {string}
* @memberof Link
*/
rel?: string;
}
/**
* Metadata and additional properties relevant.
* @export
Expand Down Expand Up @@ -734,38 +690,13 @@ export interface ResourcePermission {
* @export
* @interface ResourcePermissionCollection
*/
export interface ResourcePermissionCollection {
export interface ResourcePermissionCollection extends IPaginated<ResourcePermissionCollection> {
/**
*
* @type {Array<ResourcePermission>}
* @memberof ResourcePermissionCollection
*/
resources: Array<ResourcePermission>;
/**
*
* @type {CollectionLinks}
* @memberof ResourcePermissionCollection
*/
links: CollectionLinks;
}
/**
*
* @export
* @interface CollectionLinks
*/
export interface CollectionLinks {
/**
*
* @type {Link}
* @memberof CollectionLinks
*/
self: Link;
/**
*
* @type {Link}
* @memberof CollectionLinks
*/
next?: Link;
}

/**
Expand Down Expand Up @@ -858,20 +789,6 @@ export interface ServiceClientOptions {
grantMetadataAccess?: boolean;
}

/**
*
* @export
* @interface Links
*/
export interface Links {
/**
*
* @type {Link}
* @memberof Links
*/
self: Link;
}

/**
*
* @export
Expand Down Expand Up @@ -1039,12 +956,12 @@ export interface AccessRecordsApi {
* <i class=\"far fa-money-bill-alt text-primary\"></i> <span class=\"text-primary\">Billable</span> Returns a paginated records list for the account. Only records the user has access to are returned.
* @summary Get all account records.
* @param {number} [limit] Max number of results to return
* @param {string} [cursor] Continuation cursor for paging (will automatically be set)
* @param {Cursor} [cursor] Continuation cursor for paging (will automatically be set)
* @param {string} [filter] Filter to search records by. This is a case insensitive search through every text field.
* @param {string} [status] Filter records by their current status.
* @throws {ArgumentRequiredError}
*/
getRecords(limit?: number, cursor?: string, filter?: string, status?: string): Promise<Response<AccessRecordCollection>>;
getRecords(limit?: number, cursor?: Cursor, filter?: string, status?: string): Promise<Response<AccessRecordCollection>>;
/**
* Updates an access record adding or removing user permissions to resources.
* @summary Update an access record.
Expand Down Expand Up @@ -1291,11 +1208,11 @@ export interface UserPermissionsApi {
* @param {string} [userId] The user to check permissions on
* @param {string} [resourceUri] The top level uri path of a resource to query for. Will only match explicit or collection resource sub-resources. Will not partial match resource names.
* @param {number} [limit] Max number of results to return
* @param {string} [cursor] Continuation cursor for paging (will automatically be set)
* @param {Cursor} [cursor] Continuation cursor for paging (will automatically be set)
* @param {string} [permission] A required ALLOW action to check for. Resources a user does not have this permission will not be returned.
* @throws {ArgumentRequiredError}
*/
getUserResources(userId?: string, resourceUri?: string, limit?: number, cursor?: string, permission?: string): Promise<Response<UserResources>>;
getUserResources(userId?: string, resourceUri?: string, limit?: number, cursor?: Cursor, permission?: string): Promise<Response<UserResources>>;
/**
* <i class=\"far fa-money-bill-alt text-primary\"></i> <span class=\"text-primary\">Billable</span> Get an Authress signed JWT access token using with userId as the sub. Additionally, can be configured to limit the permissions for this particular token and the length of time the token is valid. Token validation is real-time, so deleted tokens are restricted from being used as soon as they are deleted. This gives full control to the user and client creating the token. Client must have access to impersonating the user in order to generate tokens on their behalf.
* @summary Request a user token with additional configuration
Expand Down
106 changes: 106 additions & 0 deletions src/response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,109 @@ export interface Response<ResponseType> {
/** HTTP response status code for success responses */
status: number;
}

/**
*
* @export
* @interface Links
*/
export interface Links {
/**
*
* @type {Link}
* @memberof Links
*/
self: Link;
}

/**
* A url linking object that complies to application/links+json RFC. Either is an IANA approved link relation or has a custom rel specified.
* @export
* @interface Link
*/
export interface Link {
/**
* The absolute url pointing to the reference resource.
* @type {string}
* @memberof Link
*/
href: string;
/**
* Optional property indicating the type of link if it is not a default IANA approved global link relation.
* @type {string}
* @memberof Link
*/
rel?: string;
}

/**
*
* @export
* @interface CollectionLinks
*/
export interface CollectionLinks {
/**
*
* @type {Link}
* @memberof CollectionLinks
*/
self: Link;
/**
*
* @type {Link}
* @memberof CollectionLinks
*/
next?: Link;
}

/**
*
* @export
* @interface IPaginated<CollectionType>
*/
// @ts-ignore
export interface IPaginated<CollectionType> {
/**
*
* @type {CollectionLinks}
* @memberof IPaginated<CollectionType>
*/
links: CollectionLinks;

/**
* @type {Pagination}
* @memberof IPaginated<CollectionType>
* @summary returns the next page of the collection
*/
pagination?: Pagination;
}

/**
*
* @export
* @interface Pagination
*/
export interface Pagination {
/**
*
* @type {PageMetadata}
* @memberof Pagination
*/
next?: PageMetadata;
}

/**
*
* @export
* @interface PageMetadata
*/
export interface PageMetadata {
/**
*
* @type {Cursor}
* @memberof PageMetadata
*/
cursor: Cursor;
}

export type Cursor = string;

0 comments on commit b709227

Please sign in to comment.