From d5fddcfd045dea046f8a690a6b543d4929edb829 Mon Sep 17 00:00:00 2001 From: Austin Kregel Date: Sun, 20 Sep 2020 13:15:46 -0400 Subject: [PATCH] Update plaid to use link key (#40) * Update the env example * Add a method to create a link token * Add new create link token controller * Add the configs for the new plaid options * Update the link feature to work with link tokens! * Add bin commands for linux * Clean up the controoller --- .env.example | 3 +- .../Services/PlaidServiceContract.php | 3 +- .../Plaid/CreateLinkTokenController.php | 14 ++++++ app/Services/Banking/PlaidService.php | 18 ++++++++ bin/artisan | 3 ++ bin/composer | 3 ++ config/services.php | 8 +++- resources/js/settings/Plaid/LinkAccount.vue | 46 +++++++++++-------- routes/web.php | 4 +- 9 files changed, 77 insertions(+), 25 deletions(-) create mode 100644 app/Http/Controllers/Plaid/CreateLinkTokenController.php create mode 100755 bin/artisan create mode 100755 bin/composer diff --git a/.env.example b/.env.example index 817218e3..28f35e8a 100644 --- a/.env.example +++ b/.env.example @@ -36,9 +36,10 @@ AWS_DEFAULT_REGION=us-east-1 AWS_BUCKET= PLAID_ENV=sandbox -PLAID_PUBLIC_KEY= PLAID_SECRET= PLAID_CLIENT_ID= +PLAID_LANGUAGE=en +PLAID_COUNTRY_CODES=US MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}" MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" diff --git a/app/Contracts/Services/PlaidServiceContract.php b/app/Contracts/Services/PlaidServiceContract.php index f40c7395..39bf1f3e 100644 --- a/app/Contracts/Services/PlaidServiceContract.php +++ b/app/Contracts/Services/PlaidServiceContract.php @@ -71,4 +71,5 @@ public function getCategories(): array; * @return LengthAwarePaginatorContract */ public function getInstitutions(int $count = 500, int $page = 1): LengthAwarePaginatorContract; -} \ No newline at end of file + public function createLinkToken(string $userId): array; +} diff --git a/app/Http/Controllers/Plaid/CreateLinkTokenController.php b/app/Http/Controllers/Plaid/CreateLinkTokenController.php new file mode 100644 index 00000000..0dc7d724 --- /dev/null +++ b/app/Http/Controllers/Plaid/CreateLinkTokenController.php @@ -0,0 +1,14 @@ +createLinkToken($request->user()->id); + } +} diff --git a/app/Services/Banking/PlaidService.php b/app/Services/Banking/PlaidService.php index cf74271c..02ccadde 100644 --- a/app/Services/Banking/PlaidService.php +++ b/app/Services/Banking/PlaidService.php @@ -231,4 +231,22 @@ public function getInstitutions(int $count = 500, int $page = 1): LengthAwarePag return new LengthAwarePaginator($items['institutions'], $items['total'], $count, $page); } + + public function createLinkToken(string $userId): array + { + return $this->http + ->{config('services.plaid.env')}() + ->post('/link/token/create', [ + 'client_id' => config('services.plaid.client_id'), + 'secret' => config('services.plaid.secret_key'), + 'client_name' => config('services.plaid.client_name'), + 'user' => [ + 'client_user_id' => $userId + ], + 'products' => config('services.plaid.products'), + 'country_codes' => config('services.plaid.country_codes'), + 'language' => config('services.plaid.language'), + ]) + ->toArray(); + } } diff --git a/bin/artisan b/bin/artisan new file mode 100755 index 00000000..a5062562 --- /dev/null +++ b/bin/artisan @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +docker exec -it finance-php php artisan "$@" diff --git a/bin/composer b/bin/composer new file mode 100755 index 00000000..fc671062 --- /dev/null +++ b/bin/composer @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +docker exec -it finance-php composer "$@" diff --git a/config/services.php b/config/services.php index 69f28d93..6411b3ac 100644 --- a/config/services.php +++ b/config/services.php @@ -46,9 +46,13 @@ 'plaid' => [ 'env' => env('PLAID_ENV', 'sandbox'), - 'public_key' => env('PLAID_PUBLIC_KEY', ''), 'secret_key' => env('PLAID_SECRET', ''), - 'client_id' => env('PLAID_CLIENT_ID', '') + 'client_id' => env('PLAID_CLIENT_ID', ''), + 'client_name' => env('APP_NAME'), + 'language' => env('PLAID_LANGUAGE', 'en'), + 'country_codes' => explode(',', env('PLAID_COUNTRY_CODES', 'US')), + 'products' => ['transactions'], + ], 'slack_webhook_url' => env('SLACK_WEBHOOK_URL'), diff --git a/resources/js/settings/Plaid/LinkAccount.vue b/resources/js/settings/Plaid/LinkAccount.vue index e204d3a9..fb13e216 100644 --- a/resources/js/settings/Plaid/LinkAccount.vue +++ b/resources/js/settings/Plaid/LinkAccount.vue @@ -41,30 +41,36 @@ return dayjs(date); }, }, - mounted() { - const that = this; - var handler = Plaid.create({ - clientName: 'Kregel API', - env: process.env.MIX_PLAID_ENV, - key: process.env.MIX_PLAID_KEY, - product: ['transactions'], - // webhook: this.url, - selectAccount: false, - onSuccess: (public_token, metadata) => { - axios.post('/api/plaid/exchange_token', { - public_token: public_token, - institution: metadata.institution.institution_id - }) - .then((res) => { - Bus.$emit('fetchAccounts') - }) - } - }); + async mounted() { + const fetchLinkToken = async () => { + const { data } = await axios.post('/api/plaid/create-link-token'); + return data.link_token; + }; + + const configs = { + token: await fetchLinkToken(), + onSuccess: async function(public_token, { institution: { institution_id } }) { + await axios.post('/api/plaid/exchange-token', { public_token: public_token, institution: institution_id }); + }, + onExit: async function(err, metadata) { + if (err != null && err.error_code === 'INVALID_LINK_TOKEN') { + handler.destroy(); + handler = Plaid.create({ + ...configs, + token: await fetchLinkToken(), + }); + } + if (err != null) { + this.$toasted.error(err.message || err.error_code); + return; + } + }, + }; + var handler = Plaid.create(configs) Bus.$on('fetchAccounts', () => this.getAccounts()); Bus.$emit('fetchAccounts') - $('#link-button').on('click', function(e) { handler.open(); }); diff --git a/routes/web.php b/routes/web.php index b541ca2a..e60583d9 100644 --- a/routes/web.php +++ b/routes/web.php @@ -5,6 +5,7 @@ use App\Http\Controllers\Api\SubscriptionsController; use App\Http\Controllers\DynamicViewController; use App\Http\Controllers\HomeController; +use App\Http\Controllers\Plaid\CreateLinkTokenController; use App\Http\Controllers\Plaid\TokenController; /* @@ -49,7 +50,8 @@ }); Route::post('actions/{action}', ActionController::class); - Route::post('plaid/exchange_token', TokenController::class); + Route::post('plaid/create-link-token', CreateLinkTokenController::class); + Route::post('plaid/exchange-token', TokenController::class); Route::post('cache-clear', App\Http\Controllers\Api\CacheController::class); Route::apiResource('alerts', App\Http\Controllers\Api\AlertController::class);