phpFinTS icon indicating copy to clipboard operation
phpFinTS copied to clipboard

Create Login Action in separate function call

Open thoresuenert opened this issue 9 months ago • 3 comments

Discussion started in https://github.com/nemiah/phpFinTS/pull/474 , because we PRed from the wrong branch we had to open this PR.

The Example: In the Samples/browser.php example the flow is shared between front and backend code and have the assumption that a tan is only required once during login.

If a tan is required the flow of actions is stopped and restarted where we left.

Our Goal here is a flow that fits all actions: We want update a SEPA Account:

  1. Login
  2. GetBalance
  3. GetNewTransaction
  4. Logout/Close Connection

We assume that each step can require a tanRequest flow, so the process can stop on each step and have to restart with a tan (coupled or decoupled). We want to treat every situation the same:

  1. POST Request /account/refresh to start the Process
  2. Handle Exception: tan is needed, show user interaction for all tan requests a like
  3. Continue with POST Request /account/refresh

Our Implementation

// $action is the action from the last call which needed a tan, or the action from the current step:
   $action = session()->pull('fints.action', $bank_connection->fints->createLoginAction());
// if the $action is from the last call and needs a tan and is not from this step:
// skip this step and continue with the next step
    if (! $action instanceof DialogInitialization) {
        return;
    }
// execute the action for the first time or try again with a tan
    $bank_connection->execute($action, $tan = request()->input('tan'));
// if the action needs a tan, fire an expcetion and show the tanRequest to the user
    if ($action->needsTan()) {
        $this->handleTanRequiredException($action);
    }

This is our idea of an implementation of the stop/restart mechanism the tanRequest needs.

thoresuenert avatar Mar 28 '25 14:03 thoresuenert

          Calling
        $this->requireTanMode();
        $this->ensureSynchronized();
        $this->messageNumber = 1;

inside of createLoginAction seems wrong to me.

I am not sure I understand the problem this PR is trying to solve. If you continue after a TAN request, you don't need a login, otherwise you can always login, execute your actions and logout.

Originally posted by @ampaze in https://github.com/nemiah/phpFinTS/issues/474#issuecomment-2758369625

Should every execute of an action call $this->requireTanMode(); and $this->ensureSynchronized(); because in the mean time things can change?

thoresuenert avatar Mar 28 '25 14:03 thoresuenert

I suggest you do this (not literally, but structurally):

function yourUserWantsToLogIn($credentials) {
  $action = $fints->login($credentials);
  commonTanHandling($action);
}

function yourUserWantsTheBalance() {
  $action = createBalanceAction();
  $fints->execute($action);
  commonTanHandling($action);
}

function commonTanHandling($action) {
  // The things you have above, without execute() calls and perhaps restructured a bit.
}

Note how the TAN handling needs to be implemented only in one place, no matter whether it's a login or a GetBalance or something else that requires the TAN.

Philipp91 avatar Mar 28 '25 18:03 Philipp91

Should every execute of an action call $this->requireTanMode(); and $this->ensureSynchronized(); because in the mean time things can change?

No, I meant that these lines of code should be called when you want to login, not when you create the login action.

ampaze avatar Mar 31 '25 09:03 ampaze

@thoresuenert I'm assuming your life has moved on since March. Are you now using something like this createLoginAction() patch in your production application? Or have you found a different (satisfactory?) solution and this can be closed?

Philipp91 avatar Aug 17 '25 09:08 Philipp91