From 90cf7a3bf5f50dd2bd11f9ed09a826c4e0637571 Mon Sep 17 00:00:00 2001 From: James Cole Date: Tue, 10 Apr 2018 21:18:38 +0200 Subject: [PATCH] Fix several issues with bunq import #1330 --- .../Prerequisites/BunqPrerequisites.php | 76 +++++++++++++++---- app/Import/Routine/BunqRoutine.php | 64 ++++++++-------- app/Models/Preference.php | 2 +- app/Providers/FireflyServiceProvider.php | 5 ++ app/Services/Bunq/Id/BunqId.php | 1 + app/Services/Bunq/Object/Avatar.php | 6 +- app/Services/Bunq/Object/DeviceServer.php | 4 +- app/Services/Bunq/Object/Image.php | 8 +- .../Bunq/Object/LabelMonetaryAccount.php | 4 +- app/Services/Bunq/Object/LabelUser.php | 4 +- .../Bunq/Object/MonetaryAccountBank.php | 4 +- app/Services/Bunq/Object/Payment.php | 4 +- app/Services/Bunq/Object/ServerPublicKey.php | 4 +- app/Services/Bunq/Object/UserLight.php | 4 +- .../Bunq/Request/InstallationTokenRequest.php | 2 - app/Services/Bunq/Token/BunqToken.php | 2 - app/Services/IP/IPRetrievalInterface.php | 40 ++++++++++ app/Services/IP/IpifyOrg.php | 60 +++++++++++++++ app/Support/Preferences.php | 2 +- resources/lang/en_US/form.php | 1 + resources/lang/en_US/import.php | 1 + .../views/import/bunq/prerequisites.twig | 14 ++++ 22 files changed, 243 insertions(+), 69 deletions(-) create mode 100644 app/Services/IP/IPRetrievalInterface.php create mode 100644 app/Services/IP/IpifyOrg.php diff --git a/app/Import/Prerequisites/BunqPrerequisites.php b/app/Import/Prerequisites/BunqPrerequisites.php index 05246d701d..286268b919 100644 --- a/app/Import/Prerequisites/BunqPrerequisites.php +++ b/app/Import/Prerequisites/BunqPrerequisites.php @@ -22,6 +22,7 @@ declare(strict_types=1); namespace FireflyIII\Import\Prerequisites; +use FireflyIII\Services\IP\IPRetrievalInterface; use FireflyIII\User; use Illuminate\Http\Request; use Illuminate\Support\MessageBag; @@ -56,13 +57,23 @@ class BunqPrerequisites implements PrerequisitesInterface public function getViewParameters(): array { Log::debug('Now in BunqPrerequisites::getViewParameters()'); - $apiKey = Preferences::getForUser($this->user, 'bunq_api_key', null); - $string = ''; - if (null !== $apiKey) { - $string = $apiKey->data; + $key = ''; + $serverIP = ''; + if ($this->hasApiKey()) { + $key = Preferences::getForUser($this->user, 'bunq_api_key', null)->data; + } + if ($this->hasServerIP()) { + $serverIP = Preferences::getForUser($this->user, 'external_ip', null)->data; + } + if (!$this->hasServerIP()) { + /** @var IPRetrievalInterface $service */ + $service = app(IPRetrievalInterface::class); + $serverIP = (string)$service->getIP(); } - return ['key' => $string]; + + // get IP address + return ['key' => $key, 'ip' => $serverIP]; } /** @@ -74,15 +85,10 @@ class BunqPrerequisites implements PrerequisitesInterface */ public function hasPrerequisites(): bool { - Log::debug('Now in BunqPrerequisites::hasPrerequisites()'); - $apiKey = Preferences::getForUser($this->user, 'bunq_api_key', false); - $result = (false === $apiKey->data || null === $apiKey->data); + $hasApiKey = $this->hasApiKey(); + $hasServerIP = $this->hasServerIP(); - Log::debug(sprintf('Is apiKey->data false? %s', var_export(false === $apiKey->data, true))); - Log::debug(sprintf('Is apiKey->data NULL? %s', var_export(null === $apiKey->data, true))); - Log::debug(sprintf('Result is: %s', var_export($result, true))); - - return $result; + return !$hasApiKey || !$hasServerIP; } /** @@ -94,8 +100,6 @@ class BunqPrerequisites implements PrerequisitesInterface { Log::debug(sprintf('Now in setUser(#%d)', $user->id)); $this->user = $user; - - return; } /** @@ -108,10 +112,50 @@ class BunqPrerequisites implements PrerequisitesInterface */ public function storePrerequisites(Request $request): MessageBag { - $apiKey = $request->get('api_key'); + $apiKey = $request->get('api_key'); + $serverIP = $request->get('external_ip'); Log::debug('Storing bunq API key'); Preferences::setForUser($this->user, 'bunq_api_key', $apiKey); + Preferences::setForUser($this->user, 'external_ip', $serverIP); return new MessageBag; } + + /** + * @return bool + */ + private function hasApiKey(): bool + { + $apiKey = Preferences::getForUser($this->user, 'bunq_api_key', false); + if (null === $apiKey) { + return false; + } + if (null === $apiKey->data) { + return false; + } + if (\strlen((string)$apiKey->data) === 64) { + return true; + } + + return false; + } + + /** + * @return bool + */ + private function hasServerIP(): bool + { + $serverIP = Preferences::getForUser($this->user, 'external_ip', false); + if (null === $serverIP) { + return false; + } + if (null === $serverIP->data) { + return false; + } + if (\strlen((string)$serverIP->data) > 6) { + return true; + } + + return false; + } } diff --git a/app/Import/Routine/BunqRoutine.php b/app/Import/Routine/BunqRoutine.php index bff5cbfb6e..160eb4459e 100644 --- a/app/Import/Routine/BunqRoutine.php +++ b/app/Import/Routine/BunqRoutine.php @@ -25,7 +25,6 @@ namespace FireflyIII\Import\Routine; use Carbon\Carbon; use DB; -use Exception; use FireflyIII\Exceptions\FireflyException; use FireflyIII\Factory\AccountFactory; use FireflyIII\Factory\TransactionJournalFactory; @@ -53,10 +52,10 @@ use FireflyIII\Services\Bunq\Request\ListMonetaryAccountRequest; use FireflyIII\Services\Bunq\Request\ListPaymentRequest; use FireflyIII\Services\Bunq\Token\InstallationToken; use FireflyIII\Services\Bunq\Token\SessionToken; +use FireflyIII\Services\IP\IPRetrievalInterface; use Illuminate\Support\Collection; use Log; use Preferences; -use Requests; /** * Class BunqRoutine @@ -212,7 +211,7 @@ class BunqRoutine implements RoutineInterface /** * @throws FireflyException */ - protected function runStageInitial() + protected function runStageInitial(): void { $this->addStep(); Log::debug('In runStageInitial()'); @@ -237,8 +236,8 @@ class BunqRoutine implements RoutineInterface { $this->addStep(); Log::debug('Now in runStageRegistered()'); - $apiKey = Preferences::getForUser($this->job->user, 'bunq_api_key')->data; - $serverPublicKey = Preferences::getForUser($this->job->user, 'bunq_server_public_key')->data; + $apiKey = (string)Preferences::getForUser($this->job->user, 'bunq_api_key')->data; + $serverPublicKey = new ServerPublicKey(Preferences::getForUser($this->job->user, 'bunq_server_public_key', [])->data); $installationToken = $this->getInstallationToken(); $request = new DeviceSessionRequest; $request->setInstallationToken($installationToken); @@ -265,14 +264,12 @@ class BunqRoutine implements RoutineInterface $this->addStep(); Log::debug('Session stored in job.'); - - return; } /** * Shorthand method. */ - private function addStep() + private function addStep(): void { $this->addSteps(1); } @@ -282,17 +279,17 @@ class BunqRoutine implements RoutineInterface * * @param int $count */ - private function addSteps(int $count) + private function addSteps(int $count): void { $this->repository->addStepsDone($this->job, $count); } /** - * Shorthand + * Shorthand method * * @param int $steps */ - private function addTotalSteps(int $steps) + private function addTotalSteps(int $steps): void { $this->repository->addTotalSteps($this->job, $steps); } @@ -334,7 +331,7 @@ class BunqRoutine implements RoutineInterface // try to find asset account just in case: if ($expectedType !== AccountType::ASSET) { $result = $this->accountRepository->findByIbanNull($party->getIban(), [AccountType::ASSET]); - if (nul !== $result) { + if (null !== $result) { Log::debug(sprintf('Search for Asset "%s" resulted in account %s (#%d)', $party->getIban(), $result->name, $result->id)); return $result; @@ -403,6 +400,8 @@ class BunqRoutine implements RoutineInterface } /** + * Shorthand method. + * * @return array */ private function getConfig(): array @@ -466,7 +465,7 @@ class BunqRoutine implements RoutineInterface if (null !== $token) { Log::debug('Have installation token, return it.'); - return $token->data; + return new InstallationToken($token->data); } Log::debug('Have no installation token, request one.'); @@ -481,9 +480,12 @@ class BunqRoutine implements RoutineInterface $installationId = $request->getInstallationId(); $serverPublicKey = $request->getServerPublicKey(); - Preferences::setForUser($this->job->user, 'bunq_installation_token', $installationToken); - Preferences::setForUser($this->job->user, 'bunq_installation_id', $installationId); - Preferences::setForUser($this->job->user, 'bunq_server_public_key', $serverPublicKey); + Log::debug('Have all values from InstallationTokenRequest'); + + + Preferences::setForUser($this->job->user, 'bunq_installation_token', $installationToken->toArray()); + Preferences::setForUser($this->job->user, 'bunq_installation_id', $installationId->toArray()); + Preferences::setForUser($this->job->user, 'bunq_server_public_key', $serverPublicKey->toArray()); Log::debug('Stored token, ID and pub key.'); @@ -507,7 +509,7 @@ class BunqRoutine implements RoutineInterface $preference = Preferences::getForUser($this->job->user, 'bunq_private_key', null); Log::debug('Return private key for user'); - return $preference->data; + return (string)$preference->data; } /** @@ -527,7 +529,7 @@ class BunqRoutine implements RoutineInterface $preference = Preferences::getForUser($this->job->user, 'bunq_public_key', null); Log::debug('Return public key for user'); - return $preference->data; + return (string)$preference->data; } /** @@ -537,20 +539,18 @@ class BunqRoutine implements RoutineInterface * * @throws FireflyException */ - private function getRemoteIp(): string + private function getRemoteIp(): ?string { + $preference = Preferences::getForUser($this->job->user, 'external_ip', null); if (null === $preference) { - try { - $response = Requests::get('https://api.ipify.org'); - } catch (Exception $e) { - throw new FireflyException(sprintf('Could not retrieve external IP: %s', $e->getMessage())); + + /** @var IPRetrievalInterface $service */ + $service = app(IPRetrievalInterface::class); + $serverIp = $service->getIP(); + if (null !== $serverIp) { + Preferences::setForUser($this->job->user, 'external_ip', $serverIp); } - if (200 !== $response->status_code) { - throw new FireflyException(sprintf('Could not retrieve external IP: %d %s', $response->status_code, $response->body)); - } - $serverIp = $response->body; - Preferences::setForUser($this->job->user, 'external_ip', $serverIp); return $serverIp; } @@ -572,7 +572,7 @@ class BunqRoutine implements RoutineInterface throw new FireflyException('Cannot determine bunq server public key, but should have it at this point.'); } - return $pref; + return new ServerPublicKey($pref); } /** @@ -738,7 +738,7 @@ class BunqRoutine implements RoutineInterface if (null !== $deviceServerId) { Log::debug('Already have device server ID.'); - return $deviceServerId->data; + return new DeviceServerId($deviceServerId->data); } Log::debug('Device server ID is null, we have to find an existing one or register a new one.'); @@ -778,8 +778,8 @@ class BunqRoutine implements RoutineInterface throw new FireflyException('Was not able to register server with bunq. Please see the log files.'); } - Preferences::setForUser($this->job->user, 'bunq_device_server_id', $deviceServerId); - Log::debug(sprintf('Server ID: %s', serialize($deviceServerId))); + Preferences::setForUser($this->job->user, 'bunq_device_server_id', $deviceServerId->toArray()); + Log::debug(sprintf('Server ID: %s', json_encode($deviceServerId))); return $deviceServerId; } diff --git a/app/Models/Preference.php b/app/Models/Preference.php index 7c3cae0da9..38f86409ed 100644 --- a/app/Models/Preference.php +++ b/app/Models/Preference.php @@ -73,7 +73,7 @@ class Preference extends Model unserialize($data, ['allowed_classes' => false]); } catch (Exception $e) { $serialized = false; - Log::debug(sprintf('Could not unserialise preference #%d. This is good. %s', $this->id, $e->getMessage())); + Log::debug(sprintf('Could not unserialise preference #%d ("%s"). This is good. %s', $this->id, $this->name, $e->getMessage())); } if (!$serialized) { $result = json_decode($data, true); diff --git a/app/Providers/FireflyServiceProvider.php b/app/Providers/FireflyServiceProvider.php index 5a9c83b109..6bea0cca5b 100644 --- a/app/Providers/FireflyServiceProvider.php +++ b/app/Providers/FireflyServiceProvider.php @@ -48,6 +48,8 @@ use FireflyIII\Repositories\User\UserRepository; use FireflyIII\Repositories\User\UserRepositoryInterface; use FireflyIII\Services\Currency\ExchangeRateInterface; use FireflyIII\Services\Currency\FixerIOv2; +use FireflyIII\Services\IP\IpifyOrg; +use FireflyIII\Services\IP\IPRetrievalInterface; use FireflyIII\Services\Password\PwndVerifierV2; use FireflyIII\Services\Password\Verifier; use FireflyIII\Support\Amount; @@ -180,5 +182,8 @@ class FireflyServiceProvider extends ServiceProvider // password verifier thing $this->app->bind(Verifier::class, PwndVerifierV2::class); + + // IP thing: + $this->app->bind(IPRetrievalInterface::class, IpifyOrg::class); } } diff --git a/app/Services/Bunq/Id/BunqId.php b/app/Services/Bunq/Id/BunqId.php index 8c62a3d29a..1b657519f0 100644 --- a/app/Services/Bunq/Id/BunqId.php +++ b/app/Services/Bunq/Id/BunqId.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace FireflyIII\Services\Bunq\Id; +use Log; /** * Class BunqId. */ diff --git a/app/Services/Bunq/Object/Avatar.php b/app/Services/Bunq/Object/Avatar.php index 7231c763b3..91c7847527 100644 --- a/app/Services/Bunq/Object/Avatar.php +++ b/app/Services/Bunq/Object/Avatar.php @@ -51,6 +51,10 @@ class Avatar extends BunqObject */ public function toArray(): array { - die(sprintf('Cannot convert %s to array.', get_class($this))); + return [ + 'uuid' => $this->uuid, + 'anchor_uuid' => $this->anchorUuid, + 'image' => $this->image->toArray(), + ]; } } diff --git a/app/Services/Bunq/Object/DeviceServer.php b/app/Services/Bunq/Object/DeviceServer.php index 77dd6a02ef..486c2e74de 100644 --- a/app/Services/Bunq/Object/DeviceServer.php +++ b/app/Services/Bunq/Object/DeviceServer.php @@ -25,6 +25,8 @@ namespace FireflyIII\Services\Bunq\Object; use Carbon\Carbon; use FireflyIII\Services\Bunq\Id\DeviceServerId; +use FireflyIII\Exceptions\FireflyException; + /** * Class DeviceServer */ @@ -82,6 +84,6 @@ class DeviceServer extends BunqObject */ public function toArray(): array { - die(sprintf('Cannot convert %s to array.', get_class($this))); + throw new FireflyException(sprintf('Cannot convert %s to array.', \get_class($this))); } } diff --git a/app/Services/Bunq/Object/Image.php b/app/Services/Bunq/Object/Image.php index 11d83f9e5b..bfc36cdff4 100644 --- a/app/Services/Bunq/Object/Image.php +++ b/app/Services/Bunq/Object/Image.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace FireflyIII\Services\Bunq\Object; - /** * Class Image */ @@ -56,7 +55,12 @@ class Image extends BunqObject */ public function toArray(): array { - die(sprintf('Cannot convert %s to array.', get_class($this))); + return [ + 'attachment_public_uuid' => $this->attachmentPublicUuid, + 'height' => $this->height, + 'width' => $this->width, + 'content_type' => $this->contentType, + ]; } } diff --git a/app/Services/Bunq/Object/LabelMonetaryAccount.php b/app/Services/Bunq/Object/LabelMonetaryAccount.php index c652f959df..2e6198530c 100644 --- a/app/Services/Bunq/Object/LabelMonetaryAccount.php +++ b/app/Services/Bunq/Object/LabelMonetaryAccount.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace FireflyIII\Services\Bunq\Object; - +use FireflyIII\Exceptions\FireflyException; /** * Class LabelMonetaryAccount */ @@ -75,7 +75,7 @@ class LabelMonetaryAccount extends BunqObject */ public function toArray(): array { - die(sprintf('Cannot convert %s to array.', get_class($this))); + throw new FireflyException(sprintf('Cannot convert %s to array.', \get_class($this))); } } diff --git a/app/Services/Bunq/Object/LabelUser.php b/app/Services/Bunq/Object/LabelUser.php index 2d940851c7..d7820f9eb5 100644 --- a/app/Services/Bunq/Object/LabelUser.php +++ b/app/Services/Bunq/Object/LabelUser.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace FireflyIII\Services\Bunq\Object; - +use FireflyIII\Exceptions\FireflyException; /** * Class LabelUser */ @@ -83,6 +83,6 @@ class LabelUser extends BunqObject */ public function toArray(): array { - die(sprintf('Cannot convert %s to array.', get_class($this))); + throw new FireflyException(sprintf('Cannot convert %s to array.', \get_class($this))); } } diff --git a/app/Services/Bunq/Object/MonetaryAccountBank.php b/app/Services/Bunq/Object/MonetaryAccountBank.php index f38e88a53f..18264af185 100644 --- a/app/Services/Bunq/Object/MonetaryAccountBank.php +++ b/app/Services/Bunq/Object/MonetaryAccountBank.php @@ -94,8 +94,8 @@ class MonetaryAccountBank extends BunqObject $this->setting = new MonetaryAccountSetting($data['setting']); $this->overdraftLimit = new Amount($data['overdraft_limit']); $this->avatar = new Avatar($data['avatar']); - $this->reason = $data['reason']; - $this->reasonDescription = $data['reason_description']; + $this->reason = $data['reason'] ?? ''; + $this->reasonDescription = $data['reason_description'] ?? ''; // create aliases: foreach ($data['alias'] as $alias) { diff --git a/app/Services/Bunq/Object/Payment.php b/app/Services/Bunq/Object/Payment.php index 2e063897d0..98b91bcdb8 100644 --- a/app/Services/Bunq/Object/Payment.php +++ b/app/Services/Bunq/Object/Payment.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace FireflyIII\Services\Bunq\Object; use Carbon\Carbon; - +use FireflyIII\Exceptions\FireflyException; /** * Class Payment @@ -138,7 +138,7 @@ class Payment extends BunqObject */ public function toArray(): array { - die(sprintf('Cannot convert %s to array.', get_class($this))); + throw new FireflyException(sprintf('Cannot convert %s to array.', \get_class($this))); } } diff --git a/app/Services/Bunq/Object/ServerPublicKey.php b/app/Services/Bunq/Object/ServerPublicKey.php index a5fa808392..4a665fda99 100644 --- a/app/Services/Bunq/Object/ServerPublicKey.php +++ b/app/Services/Bunq/Object/ServerPublicKey.php @@ -61,6 +61,8 @@ class ServerPublicKey extends BunqObject */ public function toArray(): array { - die(sprintf('Cannot convert %s to array.', get_class($this))); + return [ + 'server_public_key' => $this->publicKey, + ]; } } diff --git a/app/Services/Bunq/Object/UserLight.php b/app/Services/Bunq/Object/UserLight.php index 3576c94d31..0de5bee797 100644 --- a/app/Services/Bunq/Object/UserLight.php +++ b/app/Services/Bunq/Object/UserLight.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace FireflyIII\Services\Bunq\Object; use Carbon\Carbon; - +use FireflyIII\Exceptions\FireflyException; /** * Class UserLight. */ @@ -81,6 +81,6 @@ class UserLight extends BunqObject */ public function toArray(): array { - die(sprintf('Cannot convert %s to array.', get_class($this))); + throw new FireflyException(sprintf('Cannot convert %s to array.', \get_class($this))); } } diff --git a/app/Services/Bunq/Request/InstallationTokenRequest.php b/app/Services/Bunq/Request/InstallationTokenRequest.php index 0558738218..b612a9aed2 100644 --- a/app/Services/Bunq/Request/InstallationTokenRequest.php +++ b/app/Services/Bunq/Request/InstallationTokenRequest.php @@ -58,8 +58,6 @@ class InstallationTokenRequest extends BunqRequest Log::debug(sprintf('Installation ID: %s', $this->installationId->getId())); Log::debug(sprintf('Installation token: %s', $this->installationToken->getToken())); Log::debug('Server public key: (not included)'); - - return; } /** diff --git a/app/Services/Bunq/Token/BunqToken.php b/app/Services/Bunq/Token/BunqToken.php index 161448a364..a83716408d 100644 --- a/app/Services/Bunq/Token/BunqToken.php +++ b/app/Services/Bunq/Token/BunqToken.php @@ -103,7 +103,5 @@ class BunqToken $this->created = Carbon::createFromFormat('Y-m-d H:i:s.u', $response['created']); $this->updated = Carbon::createFromFormat('Y-m-d H:i:s.u', $response['updated']); $this->token = $response['token']; - - return; } } diff --git a/app/Services/IP/IPRetrievalInterface.php b/app/Services/IP/IPRetrievalInterface.php new file mode 100644 index 0000000000..69ca1132a9 --- /dev/null +++ b/app/Services/IP/IPRetrievalInterface.php @@ -0,0 +1,40 @@ +. + */ + +declare(strict_types=1); + +namespace FireflyIII\Services\IP; + +/** + * Interface IPRetrievalInterface + * + * @package FireflyIII\Services\IP + */ +interface IPRetrievalInterface +{ + + /** + * Returns the user's IP address. + * + * @return null|string + */ + public function getIP(): ?string; +} \ No newline at end of file diff --git a/app/Services/IP/IpifyOrg.php b/app/Services/IP/IpifyOrg.php new file mode 100644 index 0000000000..89256e9024 --- /dev/null +++ b/app/Services/IP/IpifyOrg.php @@ -0,0 +1,60 @@ +. + */ + +declare(strict_types=1); + +namespace FireflyIII\Services\IP; + +use Exception; +use Log; +use Requests; + +/** + * Class IpifyOrg + */ +class IpifyOrg implements IPRetrievalInterface +{ + /** + * Returns the user's IP address. + * + * @noinspection MultipleReturnStatementsInspection + * @return null|string + */ + public function getIP(): ?string + { + $result = null; + try { + $response = Requests::get('https://api.ipify.org'); + } catch (Exception $e) { + Log::warning(sprintf('The ipify.org service could not retrieve external IP: %s', $e->getMessage())); + Log::warning($e->getTraceAsString()); + + return null; + } + if (200 !== $response->status_code) { + Log::warning(sprintf('Could not retrieve external IP: %d %s', $response->status_code, $response->body)); + + return null; + } + + return (string)$response->body; + } +} \ No newline at end of file diff --git a/app/Support/Preferences.php b/app/Support/Preferences.php index 9acd6163fc..932b534c6e 100644 --- a/app/Support/Preferences.php +++ b/app/Support/Preferences.php @@ -208,7 +208,7 @@ class Preferences /** * @param \FireflyIII\User $user * @param $name - * @param string $value + * @param mixed $value * * @return Preference */ diff --git a/resources/lang/en_US/form.php b/resources/lang/en_US/form.php index 23b88d81d6..af213d8bbc 100644 --- a/resources/lang/en_US/form.php +++ b/resources/lang/en_US/form.php @@ -38,6 +38,7 @@ return [ 'journal_currency_id' => 'Currency', 'currency_id' => 'Currency', 'transaction_currency_id' => 'Currency', + 'external_ip' => 'Your server\'s external IP', 'attachments' => 'Attachments', 'journal_amount' => 'Amount', 'journal_source_account_name' => 'Revenue account (source)', diff --git a/resources/lang/en_US/import.php b/resources/lang/en_US/import.php index 3130034c8b..716665edd7 100644 --- a/resources/lang/en_US/import.php +++ b/resources/lang/en_US/import.php @@ -164,6 +164,7 @@ return [ // bunq 'bunq_prerequisites_title' => 'Prerequisites for an import from bunq', 'bunq_prerequisites_text' => 'In order to import from bunq, you need to obtain an API key. You can do this through the app. Please note that the import function for bunq is in BETA. It has only been tested against the sandbox API.', + 'bunq_prerequisites_text_ip' => 'Bunq requires your externally facing IP address. Firefly III has tried to fill this in using the ipify service. Make sure this IP address is correct, or the import will fail.', 'bunq_do_import' => 'Yes, import from this account', 'bunq_accounts_title' => 'Bunq accounts', 'bunq_accounts_text' => 'These are the accounts associated with your bunq account. Please select the accounts from which you want to import, and in which account the transactions must be imported.', diff --git a/resources/views/import/bunq/prerequisites.twig b/resources/views/import/bunq/prerequisites.twig index 5ff2448bb7..0e45d3223f 100644 --- a/resources/views/import/bunq/prerequisites.twig +++ b/resources/views/import/bunq/prerequisites.twig @@ -26,6 +26,20 @@ {{ ExpandedForm.text('api_key', key) }} + +
+
+

+ {{ trans('import.bunq_prerequisites_text_ip')|raw }} +

+
+
+ +
+
+ {{ ExpandedForm.text('external_ip', ip) }} +
+