Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move Grants to NylasClient and custom authentication to Auth #522

Merged
merged 6 commits into from
Dec 22, 2023
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
@@ -1,6 +1,8 @@
# Changelog

### 7.0.0-beta.4 / TBD
* **BREAKING CHANGE**: Moved grants API out of `Auth` to `NylasClient`
* **BREAKING CHANGE**: Moved `Grants.create()` to `Auth.customAuthentication()`
* Fix issue with form-data not importing correctly for ESM projects

### 7.0.0-beta.3 / 2023-10-23
Expand Down
6 changes: 6 additions & 0 deletions src/nylas.ts
Expand Up @@ -10,6 +10,7 @@ import { Drafts } from './resources/drafts.js';
import { Threads } from './resources/threads.js';
import { Connectors } from './resources/connectors.js';
import { Folders } from './resources/folders.js';
import { Grants } from './resources/grants.js';
import { Contacts } from './resources/contacts.js';
import { Attachments } from './resources/attachments.js';

Expand Down Expand Up @@ -52,6 +53,10 @@ export default class Nylas {
* Access the Events API
*/
public events: Events;
/**
* Access the Grants API
*/
public grants: Grants;
/**
* Access the Messages API
*/
Expand Down Expand Up @@ -91,6 +96,7 @@ export default class Nylas {
this.connectors = new Connectors(this.apiClient);
this.drafts = new Drafts(this.apiClient);
this.events = new Events(this.apiClient);
this.grants = new Grants(this.apiClient);
this.messages = new Messages(this.apiClient);
this.threads = new Threads(this.apiClient);
this.webhooks = new Webhooks(this.apiClient);
Expand Down
44 changes: 26 additions & 18 deletions src/resources/auth.ts
@@ -1,8 +1,6 @@
import { v4 as uuid } from 'uuid';
import { createHash } from 'node:crypto';
import APIClient from '../apiClient.js';
import { Resource } from './resource.js';
import { Grants } from './grants.js';
import {
URLForAdminConsentConfig,
URLForAuthenticationConfig,
Expand All @@ -13,6 +11,16 @@ import {
ProviderDetectParams,
ProviderDetectResponse,
} from '../models/auth.js';
import { Overrides } from '../config.js';
import { NylasResponse } from '../models/response.js';
import { CreateGrantRequest, Grant } from '../models/grants.js';

/**
* @property requestBody The values to create the Grant with.
*/
interface CreateGrantParams {
requestBody: CreateGrantRequest;
}

/**
* A collection of authentication related API endpoints
Expand All @@ -21,22 +29,6 @@ import {
* Also contains the Grants API and collection of provider API endpoints.
*/
export class Auth extends Resource {
/**
* Access the Grants API
*/
public grants: Grants;

apiClient: APIClient;

/**
* @param apiClient The configured Nylas API client
*/
constructor(apiClient: APIClient) {
super(apiClient);
this.apiClient = apiClient;
this.grants = new Grants(apiClient);
}

/**
* Build the URL for authenticating users to your application with OAuth 2.0
* @param config The configuration for building the URL
Expand Down Expand Up @@ -117,6 +109,22 @@ export class Auth extends Resource {
return url.toString();
}

/**
* Create a grant via Custom Authentication
* @return The created grant
*/
public customAuthentication({
requestBody,
overrides,
}: CreateGrantParams & Overrides): Promise<NylasResponse<Grant>> {
return this.apiClient.request<NylasResponse<Grant>>({
method: 'POST',
path: `/v3/connect/custom`,
body: requestBody,
overrides,
});
}

/**
* Revoke a token (and the grant attached to the token)
* @param token The token to revoke
Expand Down
4 changes: 2 additions & 2 deletions src/resources/contacts.ts
Expand Up @@ -10,7 +10,7 @@ import {
import {
NylasResponse,
NylasListResponse,
NylasDeleteResponse,
NylasBaseResponse,
} from '../models/response.js';
import { AsyncListResponse, Resource } from './resource.js';

Expand Down Expand Up @@ -152,7 +152,7 @@ export class Contacts extends Resource {
identifier,
contactId,
overrides,
}: DestroyContactParams & Overrides): Promise<NylasDeleteResponse> {
}: DestroyContactParams & Overrides): Promise<NylasBaseResponse> {
return super._destroy({
path: `/v3/grants/${identifier}/contacts/${contactId}`,
overrides,
Expand Down
23 changes: 0 additions & 23 deletions src/resources/grants.ts
Expand Up @@ -6,7 +6,6 @@ import {
NylasListResponse,
} from '../models/response.js';
import {
CreateGrantRequest,
Grant,
ListGrantsQueryParams,
UpdateGrantRequest,
Expand All @@ -19,13 +18,6 @@ interface FindGrantParams {
grantId: string;
}

/**
* @property requestBody The values to create the Grant with.
*/
interface CreateGrantParams {
requestBody: CreateGrantRequest;
}

/**
* @property grantId The id of the Grant to update.
* @property requestBody The values to update the Grant with.
Expand Down Expand Up @@ -77,21 +69,6 @@ export class Grants extends Resource {
});
}

/**
* Create a Grant via Custom Authentication
* @return The created Grant
*/
public create({
requestBody,
overrides,
}: CreateGrantParams & Overrides): Promise<NylasResponse<Grant>> {
return super._create({
path: `/v3/connect/custom`,
requestBody,
overrides,
});
}

/**
* Update a Grant
* @return The updated Grant
Expand Down
24 changes: 0 additions & 24 deletions tests/apiClient.spec.ts
Expand Up @@ -216,30 +216,6 @@ describe('APIClient', () => {
).rejects.toThrow(new NylasOAuthError(payload));
});

// it('should throw a TokenValidationError if the error comes from connect/tokeninfo', async () => {
// const payload = {
// success: false,
// error: {
// httpCode: 400,
// eventCode: 10020,
// message: 'Invalid access token',
// type: 'AuthenticationError',
// requestId: 'abc123',
// },
// };
// mockedFetch.mockImplementation(() => new Response('', { status: 400 }));
// jest
// .spyOn(Response.prototype, 'text')
// .mockImplementation(() => Promise.resolve(JSON.stringify(payload)));
//
// await expect(
// client.request({
// path: '/connect/tokeninfo',
// method: 'POST',
// })
// ).rejects.toThrow(new NylasTokenValidationError(payload));
// });

it('should throw a NylasApiError if the error comes from the other non-auth endpoints', async () => {
const payload = {
requestId: 'abc123',
Expand Down
62 changes: 33 additions & 29 deletions tests/resources/auth.spec.ts
Expand Up @@ -94,35 +94,39 @@ describe('Auth', () => {
});
});
});
// describe('Validating token', () => {
// describe('validateIDToken', () => {
// it('should call apiClient.request with the correct params', async () => {
// await auth.validateIDToken('id123');
//
// expect(apiClient.request).toHaveBeenCalledWith({
// method: 'GET',
// path: '/v3/connect/tokeninfo',
// queryParams: {
// idToken: 'id123',
// },
// });
// });
// });
//
// describe('validateAccessToken', () => {
// it('should call apiClient.request with the correct params', async () => {
// await auth.validateAccessToken('accessToken123');
//
// expect(apiClient.request).toHaveBeenCalledWith({
// method: 'GET',
// path: '/v3/connect/tokeninfo',
// queryParams: {
// accessToken: 'accessToken123',
// },
// });
// });
// });
// });
describe('customAuthentication', () => {
it('should call apiClient.request with the correct params', async () => {
await auth.customAuthentication({
requestBody: {
provider: 'google',
settings: {
test_setting: 'abc123',
},
scope: ['calendar'],
state: 'state123',
},
overrides: {
apiUri: 'https://test.api.nylas.com',
},
});

expect(apiClient.request).toHaveBeenCalledWith({
method: 'POST',
path: '/v3/connect/custom',
body: {
provider: 'google',
settings: {
test_setting: 'abc123',
},
scope: ['calendar'],
state: 'state123',
},
overrides: {
apiUri: 'https://test.api.nylas.com',
},
});
});
});
describe('URL building', () => {
describe('urlForAuthentication', () => {
it('should build the correct url', () => {
Expand Down
34 changes: 0 additions & 34 deletions tests/resources/grants.spec.ts
Expand Up @@ -63,40 +63,6 @@ describe('Grants', () => {
});
});

describe('create', () => {
it('should call apiClient.request with the correct params', async () => {
await grants.create({
requestBody: {
provider: 'google',
settings: {
test_setting: 'abc123',
},
scope: ['calendar'],
state: 'state123',
},
overrides: {
apiUri: 'https://test.api.nylas.com',
},
});

expect(apiClient.request).toHaveBeenCalledWith({
method: 'POST',
path: '/v3/connect/custom',
body: {
provider: 'google',
settings: {
test_setting: 'abc123',
},
scope: ['calendar'],
state: 'state123',
},
overrides: {
apiUri: 'https://test.api.nylas.com',
},
});
});
});

describe('update', () => {
it('should call apiClient.request with the correct params', async () => {
await grants.update({
Expand Down