1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-08 20:22:42 +01:00

remove credentials on account level + remove ApiException + fixes

This commit is contained in:
paulwer 2023-12-13 15:37:19 +01:00
parent dcdd9112d0
commit da6488adac
9 changed files with 64 additions and 103 deletions

View File

@ -69,3 +69,6 @@ MICROSOFT_REDIRECT_URI=
APPLE_CLIENT_ID= APPLE_CLIENT_ID=
APPLE_CLIENT_SECRET= APPLE_CLIENT_SECRET=
APPLE_REDIRECT_URI= APPLE_REDIRECT_URI=
NORDIGEN_SECRET_ID=
NORDIGEN_SECRET_KEY=

View File

@ -1,41 +0,0 @@
<?php
namespace App\Exceptions;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
class NordigenApiException extends Exception
{
/**
* Report the exception.
*
* @return void
*/
public function report()
{
//
}
/**
* Render the exception into an HTTP response.
*
* @param Request $request
* @return Response
*/
public function render($request)
{
// $msg = 'Unable to refund the transaction';
$msg = ctrans('texts.error');
if ($this->getMessage() && strlen($this->getMessage()) >= 1) {
$msg = $this->getMessage();
}
return response()->json([
'message' => $msg,
], 400);
}
}

View File

@ -9,15 +9,18 @@
* @license https://www.elastic.co/licensing/elastic-license * @license https://www.elastic.co/licensing/elastic-license
* *
* Documentation of Api-Usage: https://developer.gocardless.com/bank-account-data/overview * Documentation of Api-Usage: https://developer.gocardless.com/bank-account-data/overview
*
* Institutions: Are Banks or Payment-Providers, which manages bankaccounts.
*
* Accounts: Accounts are existing bank_accounts at a specific institution.
*
* Requisitions: Are registered/active user-flows to authenticate one or many accounts. After completition, the accoundId could be used to fetch data for this account. After the access expires, the user could create a new requisition to connect accounts again.
*/ */
namespace App\Helpers\Bank\Nordigen; namespace App\Helpers\Bank\Nordigen;
use App\Exceptions\NordigenApiException;
use App\Helpers\Bank\Nordigen\Transformer\AccountTransformer; use App\Helpers\Bank\Nordigen\Transformer\AccountTransformer;
use App\Helpers\Bank\Nordigen\Transformer\TransactionTransformer; use App\Helpers\Bank\Nordigen\Transformer\TransactionTransformer;
use Log;
use Nordigen\NordigenPHP\Exceptions\NordigenExceptions\NordigenException;
class Nordigen class Nordigen
{ {
@ -27,11 +30,14 @@ class Nordigen
protected \Nordigen\NordigenPHP\API\NordigenClient $client; protected \Nordigen\NordigenPHP\API\NordigenClient $client;
public function __construct(string $secret_id, string $secret_key) public function __construct()
{ {
$this->test_mode = config('ninja.nordigen.test_mode'); $this->test_mode = config('ninja.nordigen.test_mode');
$this->client = new \Nordigen\NordigenPHP\API\NordigenClient($secret_id, $secret_key); if (!(config('ninja.nordigen.secret_id') && config('ninja.nordigen.secret_key')))
throw new \Exception('missing nordigen credentials');
$this->client = new \Nordigen\NordigenPHP\API\NordigenClient(config('ninja.nordigen.secret_id'), config('ninja.nordigen.secret_key'));
$this->client->createAccessToken(); // access_token is valid 24h -> so we dont have to implement a refresh-cycle $this->client->createAccessToken(); // access_token is valid 24h -> so we dont have to implement a refresh-cycle
} }
@ -51,7 +57,7 @@ class Nordigen
if ($this->test_mode && $initutionId != $this->sandbox_institutionId) if ($this->test_mode && $initutionId != $this->sandbox_institutionId)
throw new \Exception('invalid institutionId while in test-mode'); throw new \Exception('invalid institutionId while in test-mode');
return $this->client->requisition->createRequisition($redirect, $initutionId, null, $reference); // we dont reuse existing requisitions, to prevent double usage of them. see: deleteAccount return $this->client->requisition->createRequisition($redirect, $initutionId, null, $reference);
} }
public function getRequisition(string $requisitionId) public function getRequisition(string $requisitionId)

View File

@ -18,6 +18,7 @@ use App\Http\Requests\Nordigen\ConnectNordigenBankIntegrationRequest;
use App\Jobs\Bank\ProcessBankTransactionsNordigen; use App\Jobs\Bank\ProcessBankTransactionsNordigen;
use App\Models\BankIntegration; use App\Models\BankIntegration;
use App\Models\Company; use App\Models\Company;
use App\Utils\Ninja;
use Cache; use Cache;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Log; use Log;
@ -37,10 +38,13 @@ class NordigenController extends BaseController
$company = $request->getCompany(); $company = $request->getCompany();
$account = $company->account; $account = $company->account;
if (!(($account->bank_integration_nordigen_secret_id && $account->bank_integration_nordigen_secret_key) || (config('ninja.nordigen.secret_id') && config('ninja.nordigen.secret_key')))) if (!(config('ninja.nordigen.secret_id') && config('ninja.nordigen.secret_key')))
return response()->redirectTo($data["redirect"] . "?action=nordigen_connect&status=failed&reason=account-config-invalid"); return response()->redirectTo($data["redirect"] . "?action=nordigen_connect&status=failed&reason=account-config-invalid");
$nordigen = ($account->bank_integration_nordigen_secret_id && $account->bank_integration_nordigen_secret_key) ? new Nordigen($account->bank_integration_nordigen_secret_id, $account->bank_integration_nordigen_secret_key) : new Nordigen(config('ninja.nordigen.secret_id'), config('ninja.nordigen.secret_key')); if (!(Ninja::isSelfHost() || (Ninja::isHosted() && $account->isPaid() && $account->plan == 'enterprise')))
return response()->redirectTo($context["redirect"] . "?action=nordigen_connect&status=failed&reason=not-available");
$nordigen = new Nordigen();
// show bank_selection_screen, when institution_id is not present // show bank_selection_screen, when institution_id is not present
if (!array_key_exists("institution_id", $data)) { if (!array_key_exists("institution_id", $data)) {
@ -157,11 +161,14 @@ class NordigenController extends BaseController
$company = Company::where('company_key', $context["company_key"])->firstOrFail(); $company = Company::where('company_key', $context["company_key"])->firstOrFail();
$account = $company->account; $account = $company->account;
if (!(($account->bank_integration_nordigen_secret_id && $account->bank_integration_nordigen_secret_key) || (config('ninja.nordigen.secret_id') && config('ninja.nordigen.secret_key')))) if (!(config('ninja.nordigen.secret_id') && config('ninja.nordigen.secret_key')))
return response()->redirectTo($context["redirect"] . "?action=nordigen_connect&status=failed&reason=account-config-invalid"); return response()->redirectTo($context["redirect"] . "?action=nordigen_connect&status=failed&reason=account-config-invalid");
if (!(Ninja::isSelfHost() || (Ninja::isHosted() && $account->isPaid() && $account->plan == 'enterprise')))
return response()->redirectTo($context["redirect"] . "?action=nordigen_connect&status=failed&reason=not-available");
// fetch requisition // fetch requisition
$nordigen = ($account->bank_integration_nordigen_secret_id && $account->bank_integration_nordigen_secret_key) ? new Nordigen($account->bank_integration_nordigen_secret_id, $account->bank_integration_nordigen_secret_key) : new Nordigen(config('ninja.nordigen.secret_id'), config('ninja.nordigen.secret_key')); $nordigen = new Nordigen();
$requisition = $nordigen->getRequisition($context["requisitionId"]); $requisition = $nordigen->getRequisition($context["requisitionId"]);
// check validity of requisition // check validity of requisition
@ -222,9 +229,9 @@ class NordigenController extends BaseController
} }
// perform update in background // perform update in background
$company->account->bank_integrations->where("integration_type", BankIntegration::INTEGRATION_TYPE_NORDIGEN)->where('auto_sync', true)->each(function ($bank_integration) use ($company) { $company->account->bank_integrations->where("integration_type", BankIntegration::INTEGRATION_TYPE_NORDIGEN)->where('auto_sync', true)->each(function ($bank_integration) {
ProcessBankTransactionsNordigen::dispatch($company->account, $bank_integration); ProcessBankTransactionsNordigen::dispatch($bank_integration);
}); });
@ -304,10 +311,10 @@ class NordigenController extends BaseController
{ {
$account = auth()->user()->account; $account = auth()->user()->account;
if (!(($account->bank_integration_nordigen_secret_id && $account->bank_integration_nordigen_secret_key) || (config('ninja.nordigen.secret_id') && config('ninja.nordigen.secret_key')))) if (!(config('ninja.nordigen.secret_id') && config('ninja.nordigen.secret_key')))
return response()->json(['message' => 'Not yet authenticated with Nordigen Bank Integration service'], 400); return response()->json(['message' => 'Not yet authenticated with Nordigen Bank Integration service'], 400);
$nordigen = ($account->bank_integration_nordigen_secret_id && $account->bank_integration_nordigen_secret_key) ? new Nordigen($account->bank_integration_nordigen_secret_id, $account->bank_integration_nordigen_secret_key) : new Nordigen(config('ninja.nordigen.secret_id'), config('ninja.nordigen.secret_key')); $nordigen = new Nordigen();
return response()->json($nordigen->getInstitutions()); return response()->json($nordigen->getInstitutions());
} }

View File

@ -30,6 +30,7 @@ use App\Models\BankIntegration;
use App\Models\User; use App\Models\User;
use App\Repositories\BankIntegrationRepository; use App\Repositories\BankIntegrationRepository;
use App\Transformers\BankIntegrationTransformer; use App\Transformers\BankIntegrationTransformer;
use App\Utils\Ninja;
use App\Utils\Traits\MakesHash; use App\Utils\Traits\MakesHash;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
use Illuminate\Http\Response; use Illuminate\Http\Response;
@ -206,17 +207,17 @@ class BankIntegrationController extends BaseController
return response()->json(BankIntegration::query()->company(), 200); return response()->json(BankIntegration::query()->company(), 200);
// Processing transactions for each bank account // Processing transactions for each bank account
if ($user->account->bank_integration_yodlee_account_id) if (Ninja::isHosted() && $user->account->bank_integration_yodlee_account_id)
$user_account->bank_integrations->where("integration_type", BankIntegration::INTEGRATION_TYPE_YODLEE)->where('auto_sync', true)->each(function ($bank_integration) use ($user_account) { $user_account->bank_integrations->where("integration_type", BankIntegration::INTEGRATION_TYPE_YODLEE)->where('auto_sync', true)->each(function ($bank_integration) use ($user_account) {
ProcessBankTransactionsYodlee::dispatch($user_account, $bank_integration); ProcessBankTransactionsYodlee::dispatch($user_account, $bank_integration);
}); });
if (($user->account->bank_integration_nordigen_secret_id && $user->account->bank_integration_nordigen_secret_key) || (config('ninja.nordigen.secret_id') && config('ninja.nordigen.secret_key'))) if (config('ninja.nordigen.secret_id') && config('ninja.nordigen.secret_key') && (Ninja::isSelfHost() || (Ninja::isHosted() && $user_account->isPaid() && $user_account->plan == 'enterprise')))
$user_account->bank_integrations->where("integration_type", BankIntegration::INTEGRATION_TYPE_NORDIGEN)->where('auto_sync', true)->each(function ($bank_integration) use ($user_account) { $user_account->bank_integrations->where("integration_type", BankIntegration::INTEGRATION_TYPE_NORDIGEN)->where('auto_sync', true)->each(function ($bank_integration) {
ProcessBankTransactionsNordigen::dispatch($user_account, $bank_integration); ProcessBankTransactionsNordigen::dispatch($bank_integration);
}); });
@ -265,10 +266,10 @@ class BankIntegrationController extends BaseController
{ {
$account = $user->account; $account = $user->account;
if (!(($account->bank_integration_nordigen_secret_id && $account->bank_integration_nordigen_secret_key) || (config('ninja.nordigen.secret_id') && config('ninja.nordigen.secret_key')))) if (!(config('ninja.nordigen.secret_id') && config('ninja.nordigen.secret_key')))
return; return;
$nordigen = ($account->bank_integration_nordigen_secret_id && $account->bank_integration_nordigen_secret_key) ? new Nordigen($account->bank_integration_nordigen_secret_id, $account->bank_integration_nordigen_secret_key) : new Nordigen(config('ninja.nordigen.secret_id'), config('ninja.nordigen.secret_key')); $nordigen = new Nordigen();
BankIntegration::withTrashed()->where("integration_type", BankIntegration::INTEGRATION_TYPE_NORDIGEN)->whereNotNull('nordigen_account_id')->each(function (BankIntegration $bank_integration) use ($nordigen) { BankIntegration::withTrashed()->where("integration_type", BankIntegration::INTEGRATION_TYPE_NORDIGEN)->whereNotNull('nordigen_account_id')->each(function (BankIntegration $bank_integration) use ($nordigen) {
$account = $nordigen->getAccount($bank_integration->nordigen_account_id); $account = $nordigen->getAccount($bank_integration->nordigen_account_id);
@ -334,18 +335,20 @@ class BankIntegrationController extends BaseController
*/ */
public function getTransactions(AdminBankIntegrationRequest $request) public function getTransactions(AdminBankIntegrationRequest $request)
{ {
/** @var \App\Models\User $user */ /** @var \App\Models\Account $account */
$user = auth()->user(); $account = auth()->user()->account();
// Yodlee if (Ninja::isHosted() && $account->isPaid() && $account->plan == 'enterprise') {
$user->account->bank_integrations->where("integration_type", BankIntegration::INTEGRATION_TYPE_YODLEE)->each(function ($bank_integration) use ($user) { $account->bank_integrations()->where('integration_type', BankIntegration::INTEGRATION_TYPE_YODLEE)->where('auto_sync', true)->cursor()->each(function ($bank_integration) use ($account) {
(new ProcessBankTransactionsYodlee($user->account, $bank_integration))->handle(); (new ProcessBankTransactionsYodlee($account, $bank_integration))->handle();
}); });
}
// Nordigen if (config("ninja.nortigen.secret_id") && config("ninja.nortigen.secret_key") && (Ninja::isSelfHost() || (Ninja::isHosted() && $account->isPaid() && $account->plan == 'enterprise'))) {
$user->account->bank_integrations->where("integration_type", BankIntegration::INTEGRATION_TYPE_NORDIGEN)->each(function ($bank_integration) use ($user) { $account->bank_integrations()->where('integration_type', BankIntegration::INTEGRATION_TYPE_NORDIGEN)->where('auto_sync', true)->cursor()->each(function ($bank_integration) {
(new ProcessBankTransactionsYodlee($user->account, $bank_integration))->handle(); (new ProcessBankTransactionsNordigen($bank_integration))->handle();
}); });
}
return response()->json(['message' => 'Fetching transactions....'], 200); return response()->json(['message' => 'Fetching transactions....'], 200);
} }

View File

@ -30,7 +30,6 @@ class ProcessBankTransactionsNordigen implements ShouldQueue
{ {
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
private Account $account;
private BankIntegration $bank_integration; private BankIntegration $bank_integration;
private string $secret_id; private string $secret_id;
private string $secret_key; private string $secret_key;
@ -48,9 +47,8 @@ class ProcessBankTransactionsNordigen implements ShouldQueue
/** /**
* Create a new job instance. * Create a new job instance.
*/ */
public function __construct(Account $account, BankIntegration $bank_integration) public function __construct(BankIntegration $bank_integration)
{ {
$this->account = $account;
$this->bank_integration = $bank_integration; $this->bank_integration = $bank_integration;
$this->from_date = $bank_integration->from_date; $this->from_date = $bank_integration->from_date;
$this->company = $this->bank_integration->company; $this->company = $this->bank_integration->company;
@ -68,18 +66,10 @@ class ProcessBankTransactionsNordigen implements ShouldQueue
if ($this->bank_integration->integration_type != BankIntegration::INTEGRATION_TYPE_NORDIGEN) if ($this->bank_integration->integration_type != BankIntegration::INTEGRATION_TYPE_NORDIGEN)
throw new \Exception("Invalid BankIntegration Type"); throw new \Exception("Invalid BankIntegration Type");
if (!(($this->account->bank_integration_nordigen_secret_id && $this->account->bank_integration_nordigen_secret_key) || (config('ninja.nordigen.secret_id') && config('ninja.nordigen.secret_key')))) if (!(config('ninja.nordigen.secret_id') && config('ninja.nordigen.secret_key')))
throw new \Exception("Missing credentials for bank_integration service nortigen"); throw new \Exception("Missing credentials for bank_integration service nortigen");
if ($this->account->bank_integration_nordigen_secret_id && $this->account->bank_integration_nordigen_secret_key) { $this->nordigen = new Nordigen();
$this->secret_id = $this->account->bank_integration_nordigen_secret_id;
$this->secret_key = $this->account->bank_integration_nordigen_secret_key;
} else {
$this->secret_id = config('ninja.nordigen.secret_id');
$this->secret_key = config('ninja.nordigen.secret_key');
}
$this->nordigen = new Nordigen($this->secret_id, $this->secret_key);
set_time_limit(0); set_time_limit(0);

View File

@ -53,30 +53,29 @@ class BankTransactionSync implements ShouldQueue
nlog("syncing transactions - yodlee"); nlog("syncing transactions - yodlee");
Account::with('bank_integrations')->whereNotNull('bank_integration_yodlee_account_id')->cursor()->each(function ($account) { Account::with('bank_integrations')->whereNotNull('bank_integration_yodlee_account_id')->cursor()->each(function ($account) {
// $queue = Ninja::isHosted() ? 'bank' : 'default';
if ($account->isPaid() && $account->plan == 'enterprise') { if ($account->isPaid() && $account->plan == 'enterprise') {
$account->bank_integrations()->where('integration_type', BankIntegration::INTEGRATION_TYPE_YODLEE)->where('auto_sync', true)->cursor()->each(function ($bank_integration) use ($account) { $account->bank_integrations()->where('integration_type', BankIntegration::INTEGRATION_TYPE_YODLEE)->where('auto_sync', true)->cursor()->each(function ($bank_integration) use ($account) {
(new ProcessBankTransactionsYodlee($account, $bank_integration))->handle(); (new ProcessBankTransactionsYodlee($account, $bank_integration))->handle();
}); });
} }
}); });
} }
if (config("ninja.nortigen.secret_id") && config("ninja.nortigen.secret_key")) { // @turbo124 check condition, when to execute this should be placed here (isSelfHosted || isPro/isEnterprise)
nlog("syncing transactions - nordigen"); nlog("syncing transactions - nordigen");
if (config("ninja.nortigen.secret_id") && config("ninja.nortigen.secret_key"))
Account::with('bank_integrations')->cursor()->each(function ($account) { Account::with('bank_integrations')->cursor()->each(function ($account) {
$account->bank_integrations()->where('integration_type', BankIntegration::INTEGRATION_TYPE_NORDIGEN)->where('auto_sync', true)->cursor()->each(function ($bank_integration) use ($account) {
(new ProcessBankTransactionsNordigen($account, $bank_integration))->handle(); if ((Ninja::isSelfHost() || (Ninja::isHosted() && $account->isPaid() && $account->plan == 'enterprise'))) {
}); $account->bank_integrations()->where('integration_type', BankIntegration::INTEGRATION_TYPE_NORDIGEN)->where('auto_sync', true)->cursor()->each(function ($bank_integration) {
}); (new ProcessBankTransactionsNordigen($bank_integration))->handle();
else
Account::with('bank_integrations')->whereNotNull('bank_integration_nordigen_secret_id')->whereNotNull('bank_integration_nordigen_secret_key')->cursor()->each(function ($account) {
$account->bank_integrations()->where('integration_type', BankIntegration::INTEGRATION_TYPE_NORDIGEN)->where('auto_sync', true)->cursor()->each(function ($bank_integration) use ($account) {
(new ProcessBankTransactionsNordigen($account, $bank_integration))->handle();
}); });
}
}); });
}
nlog("syncing transactions - done"); nlog("syncing transactions - done");
} }

View File

@ -70,8 +70,6 @@ use Laracasts\Presenter\PresentableTrait;
* @property string|null $account_sms_verification_number * @property string|null $account_sms_verification_number
* @property bool $account_sms_verified * @property bool $account_sms_verified
* @property string|null $bank_integration_yodlee_account_id * @property string|null $bank_integration_yodlee_account_id
* @property string|null $bank_integration_nordigen_secret_id
* @property string|null $bank_integration_nordigen_secret_key
* @property int $is_trial * @property int $is_trial
* @property-read int|null $bank_integrations_count * @property-read int|null $bank_integrations_count
* @property-read int|null $companies_count * @property-read int|null $companies_count
@ -128,8 +126,6 @@ class Account extends BaseModel
'platform', 'platform',
'set_react_as_default_ap', 'set_react_as_default_ap',
'inapp_transaction_id', 'inapp_transaction_id',
'bank_integration_nordigen_secret_id',
'bank_integration_nordigen_secret_key',
]; ];
protected $casts = [ protected $casts = [

View File

@ -29,8 +29,6 @@ return new class extends Migration {
// MAYBE migration of account->bank_account_id etc // MAYBE migration of account->bank_account_id etc
Schema::table('accounts', function (Blueprint $table) { Schema::table('accounts', function (Blueprint $table) {
$table->renameColumn('bank_integration_account_id', 'bank_integration_yodlee_account_id'); $table->renameColumn('bank_integration_account_id', 'bank_integration_yodlee_account_id');
$table->string('bank_integration_nordigen_secret_id')->nullable();
$table->string('bank_integration_nordigen_secret_key')->nullable();
}); });
} }