Skip to content

Commit

Permalink
Remove the public key (#310)
Browse files Browse the repository at this point in the history
  • Loading branch information
otherchen authored Jul 9, 2020
1 parent c2893cd commit 02bcdee
Show file tree
Hide file tree
Showing 9 changed files with 137 additions and 79 deletions.
4 changes: 1 addition & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Instructions for contributing to [plaid-node][1]. A node.js client library for t
cp .env.example .env
```

2. Go to the [Plaid Dashboard](https://dashboard.plaid.com/) and copy and paste your `client_id`, `public_key`, and sandbox `secret`
2. Go to the [Plaid Dashboard](https://dashboard.plaid.com/) and copy and paste your `client_id` and sandbox `secret`
into `.env` using a text editor of your choice.

3. Install the necessary dependencies.
Expand All @@ -24,14 +24,12 @@ Instructions for contributing to [plaid-node][1]. A node.js client library for t
```console
$ SECRET=$PLAID_SECRET \
CLIENT_ID=$PLAID_CLIENT_ID \
PUBLIC_KEY=$PLAID_PUBLIC_KEY \
make test

# Running specific tests
$ GREP='constructor|item|assets' \
SECRET=$PLAID_SECRET \
CLIENT_ID=$PLAID_CLIENT_ID \
PUBLIC_KEY=$PLAID_PUBLIC_KEY \
make test

```
Expand Down
60 changes: 39 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,14 @@ $ npm install plaid
You can specify the Plaid API version you wish to use when initializing `plaid-node`. Releases prior to `2.6.x` do not support versioning.

```javascript
const plaidClient = new plaid.Client(
process.env.PLAID_CLIENT_ID,
process.env.PLAID_SECRET,
process.env.PUBLIC_KEY,
plaid.environments.sandbox,
{version: '2019-05-29'} // '2019-05-29' | '2018-05-22' | '2017-03-08'
);
const plaidClient = new plaid.Client({
clientID: process.env.PLAID_CLIENT_ID,
secret: process.env.PLAID_SECRET,
env: plaid.environments.sandbox,
options: {
version: '2019-05-29', // '2019-05-29' | '2018-05-22' | '2017-03-08'
},
});
```

For information about what has changed between versions and how to update your integration, head to the [API upgrade guide][api-upgrades].
Expand All @@ -45,26 +46,35 @@ For information about what has changed between versions and how to update your i
The module supports all Plaid API endpoints. For complete information about the API, head
to the [docs][2].

All endpoints require a valid `client_id`, `secret`, and `public_key` to
All endpoints require a valid `client_id` and `secret` to
access and are accessible from a valid instance of a Plaid `Client`:

```javascript
const plaid = require('plaid');

const plaidClient = new plaid.Client(client_id, secret, public_key, plaid_env, {version: '2019-05-29'});
const plaidClient = new plaid.Client({
clientID: client_id,
secret: secret,
env: plaid_env,
});
```

The `plaid_env` parameter dictates which Plaid API environment you will access. Values are:
- `plaid.environments.production` - production use, creates `Item`s on https://production.plaid.com
- `plaid.environments.development` - use for integration development and testing, creates `Item`s on https://development.plaid.com
- `plaid.environments.sandbox` - quickly build out your integration with stateful test data, creates `Item`s on https://sandbox.plaid.com

The `options` parameter is optional and allows for clients to override the default options used to make requests. e.g.
The `options` field is optional and allows for clients to override the default options used to make requests. e.g.

```javascript
const patientClient = new plaid.Client(client_id, secret, public_key, plaid_env, {
timeout: 30 * 60 * 1000, // 30 minutes
agent: 'Patient Agent'
const patientClient = new plaid.Client({
clientID: client_id,
secret: secret,
env: plaid_env,
options: {
timeout: 30 * 60 * 1000, // 30 minutes
version: '2019-05-29',
}
});
```

Expand All @@ -78,7 +88,14 @@ Once an instance of the client has been created you use the following methods:
const plaid = require('plaid');

// Initialize client
const plaidClient = new plaid.Client(client_id, secret, public_key, plaid_env, {version: '2018-05-22'});
const plaidClient = new plaid.Client({
clientID: client_id,
secret: secret,
env: plaid_env,
options: {
version: '2019-05-29',
},
});

// createPublicToken(String, Function)
plaidClient.createPublicToken(access_token, cb);
Expand Down Expand Up @@ -264,13 +281,14 @@ const bodyParser = require('body-parser');
const express = require('express');
const plaid = require('plaid');

const plaidClient = new plaid.Client(
process.env.PLAID_CLIENT_ID,
process.env.PLAID_SECRET,
process.env.PUBLIC_KEY,
plaid.environments.sandbox,
{version: '2018-05-22'}
);
const plaidClient = new plaid.Client({
clientID: process.env.PLAID_CLIENT_ID,
secret: process.env.PLAID_SECRET,
env: plaid.environments.sandbox,
options: {
version: '2018-05-22',
},
});

const app = express();
const port = process.env.PORT || 3000;
Expand Down
18 changes: 10 additions & 8 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -717,9 +717,17 @@ declare module 'plaid' {

interface SandboxItemSetVerificationStatusResponse extends BaseResponse {}

interface ClientOptions extends AxiosRequestConfig {
interface ClientOptions {
version?: '2019-05-29' | '2018-05-22' | '2017-03-08';
clientApp?: string;
timeout?: number;
}

interface ClientConfigs extends AxiosRequestConfig {
clientID: string;
secret: string;
env: string,
options: ClientOptions,
}

type IdentityFieldBase = {
Expand Down Expand Up @@ -749,13 +757,7 @@ declare module 'plaid' {
}

class Client {
constructor(
clientId: string,
secret: string,
publicKey: string,
env: string,
options?: ClientOptions,
);
constructor(configs: ClientConfigs);

exchangePublicToken(publicToken: string): Promise<TokenResponse>;
exchangePublicToken(
Expand Down
54 changes: 29 additions & 25 deletions lib/PlaidClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,35 +12,42 @@ var helpers = require('./_helpers');
const DEFAULT_VERSION = '2019-05-29';

// Client(String, String, String, String, Object?)
function Client(client_id, secret, public_key, env, options) {
if (R.isNil(client_id)) {
function Client(configs) {
if (!R.is(Object, configs)) {
throw new Error('Unexpected parameter type. ' +
'Refer to https://github.com/plaid/plaid-node ' +
'for how to create a Plaid client.');
}

if (R.isNil(configs.clientID)) {
throw new Error('Missing Plaid "client_id"');
}

if (R.isNil(secret)) {
if (R.isNil(configs.secret)) {
throw new Error('Missing Plaid "secret"');
}

if (R.isNil(public_key)) {
throw new Error('Missing Plaid "public_key"');
if (!R.any(R.equals(configs.env), R.values(plaidEnvironments))) {
throw new Error('Invalid Plaid environment');
}

if (!R.any(R.equals(env), R.values(plaidEnvironments))) {
throw new Error('Invalid Plaid environment');
if (arguments.length > 1) {
throw new Error('Too many arguments to constructor');
}

this.client_id = client_id;
this.secret = secret;
this.env = env;
this.public_key = public_key;
this.client_id = configs.clientID;
this.secret = configs.secret;
this.env = configs.env;

if (options == null) {
options = {};
if (configs.options == null) {
configs.options = {};
}
if (options.version == null) {
options.version = DEFAULT_VERSION;

if (configs.options.version == null) {
configs.options.version = DEFAULT_VERSION;
}
this.client_request_opts = options;

this.client_request_opts = configs.options;
}

// Private
Expand All @@ -56,7 +63,7 @@ var requestWithAccessToken = function(path) {
};

Client.prototype._authenticatedRequest =
function _authenticatedRequest(requestSpec, options, cb, withPublicKey) {
function _authenticatedRequest(requestSpec, options, cb) {
// juggle arguments
if (typeof options === 'function') {
cb = options;
Expand All @@ -65,13 +72,10 @@ Client.prototype._authenticatedRequest =
requestSpec.body.options = options;
}

var context = R.merge({env: this.env}, withPublicKey ? {
public_key: this.public_key,
} : {
var context = R.merge({env: this.env}, {
client_id: this.client_id,
secret: this.secret,
}
);
});

return plaidRequest(context, requestSpec, this.client_request_opts, cb);
};
Expand Down Expand Up @@ -514,7 +518,7 @@ Client.prototype.getInstitutionById =
body: {
institution_id: institution_id,
}
}, options, cb, true);
}, options, cb);
};

// searchInstitutionsByName(String, [String], Object?, Function)
Expand All @@ -526,7 +530,7 @@ Client.prototype.searchInstitutionsByName =
query: query,
products: products,
}
}, options, cb, true);
}, options, cb);
};

// getCategories(Function)
Expand Down Expand Up @@ -563,7 +567,7 @@ function(institution_id, initial_products, options, cb) {
institution_id: institution_id,
initial_products: initial_products,
},
}, options, cb, true);
}, options, cb);
};

// sandboxItemFireWebhook(String, String, Function) - sandbox only
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

68 changes: 51 additions & 17 deletions test/PlaidClientTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,42 @@ const plaid = require('../');
const testConstants = require('./testConstants.js');

dotenv.config();
const {SECRET, PUBLIC_KEY, CLIENT_ID} = process.env;
const {SECRET, CLIENT_ID} = process.env;

describe('plaid.Client', () => {
const configs = {
clientID: CLIENT_ID,
secret: SECRET,
env: plaid.environments.sandbox,
options: {
version: '2019-05-29',
},
};

let pCl;
beforeEach(() => {
pCl = new plaid.Client(
CLIENT_ID,
SECRET,
PUBLIC_KEY,
plaid.environments.sandbox,
{version: '2019-05-29'}
);
pCl = new plaid.Client(configs);
});

describe('constructor', () => {
it('throws for invalid parameter', () => {
expect(() => {
plaid.Client('client_id');
}).to.throwException(e => {
expect(e).to.be.ok();
expect(e.message).to.equal(
'Unexpected parameter type. Refer to ' +
'https://github.com/plaid/plaid-node ' +
'for how to create a Plaid client.'
);
});
});

it('throws for missing client_id', () => {
expect(() => {
plaid.Client(null, SECRET, PUBLIC_KEY, plaid.environments.sandbox);
plaid.Client(R.merge(configs, {
clientID: null,
}));
}).to.throwException(e => {
expect(e).to.be.ok();
expect(e.message).to.equal('Missing Plaid "client_id"');
Expand All @@ -41,35 +58,52 @@ describe('plaid.Client', () => {

it('throws for missing secret', () => {
expect(() => {
plaid.Client(CLIENT_ID, null, PUBLIC_KEY, plaid.environments.sandbox);
plaid.Client(R.merge(configs, {
secret: null,
}));
}).to.throwException(e => {
expect(e).to.be.ok();
expect(e.message).to.equal('Missing Plaid "secret"');
});
});

it('throws for missing public_key', () => {
it('throws for invalid environment', () => {
expect(() => {
plaid.Client(CLIENT_ID, SECRET, null, plaid.environments.sandbox);
plaid.Client(R.merge(configs, {
env: 'gingham',
}));
}).to.throwException(e => {
expect(e).to.be.ok();
expect(e.message).to.equal('Missing Plaid "public_key"');
expect(e.message).to.equal('Invalid Plaid environment');
});
});

it('throws for invalid environment', () => {
it('throws for too many arguments', () => {
expect(() => {
plaid.Client(CLIENT_ID, SECRET, PUBLIC_KEY, 'gingham');
plaid.Client(configs, 'extra arg');
}).to.throwException(e => {
expect(e).to.be.ok();
expect(e.message).to.equal('Invalid Plaid environment');
expect(e.message).to.equal('Too many arguments to constructor');
});
});

it('succeeds with all arguments', () => {
expect(() => {
R.forEachObjIndexed(env => {
plaid.Client(CLIENT_ID, SECRET, PUBLIC_KEY, env);
plaid.Client(R.merge(configs, {
env: env,
}));
}, plaid.environments);
}).not.to.throwException();
});

it('succeeds without any options', () => {
expect(() => {
R.forEachObjIndexed(env => {
plaid.Client(R.merge(configs, {
options: null,
env: env,
}));
}, plaid.environments);
}).not.to.throwException();
});
Expand Down
2 changes: 1 addition & 1 deletion test/mocks/api-invalid-json.nb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
>> POST /institutions/get_by_id
>> ={"public_key":"xxx","institution_id":"ins_3"}
>> ={"client_id":"xxx","secret":"yyy","institution_id":"ins_3"}
<< 400
<< content-type: application/json; charset=utf-8
<< =<html>invalidJsonIsTheWorst</html>
Loading

0 comments on commit 02bcdee

Please sign in to comment.