Skip to content

Commit

Permalink
Sending other messages and codes (#1)
Browse files Browse the repository at this point in the history
* Added possibility to send other codes to the user, this will break v1.x + minimal PHP 7.4

* Also make it possible to really send it with the CodeGenerator

* Bugfix: returning confirm code instead of message text
  • Loading branch information
erkens authored Nov 15, 2021
1 parent ad8d16e commit 601bf4f
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 40 deletions.
52 changes: 26 additions & 26 deletions Generator/CodeGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,10 @@

class CodeGenerator implements CodeGeneratorInterface
{
/**
* @var PersisterInterface
*/
private $persister;

/**
* @var AuthCodeTextInterface
*/
private $textSender;

/**
* @var int
*/
private $digits;
/**
* @var string
*/
private $text;
private PersisterInterface $persister;
private AuthCodeTextInterface $textSender;
private int $digits;
private string $text;

public function __construct(
PersisterInterface $persister,
Expand All @@ -43,21 +29,35 @@ public function __construct(

public function generateAndSend(TwoFactorTextInterface $user): void
{
$min = 10 ** ($this->digits - 1);
$max = 10 ** $this->digits - 1;
$code = $this->generateCode($min, $max);
$user->setTextAuthCode((string)$code);
$code = $this->generateCode();
$user->setTextAuthCode($code);
$this->persister->persist($user);
$this->textSender->sendAuthCode($user, $this->text);
$this->send($user);
}

public function returnAndSendWithMessage(TwoFactorTextInterface $user, string $text): string
{
$code = $this->generateCode();
$this->textSender->setMessageFormat($text);
$this->textSender->sendAuthCode($user, $code);
return $code;
}

public function reSend(TwoFactorTextInterface $user): void
{
$this->textSender->sendAuthCode($user, $this->text);
$this->send($user);
}

protected function generateCode(int $min, int $max): int
protected function send(TwoFactorTextInterface $user): void
{
return random_int($min, $max);
$this->textSender->setMessageFormat($this->text);
$this->textSender->sendAuthCode($user, $user->getTextAuthCode());
}

protected function generateCode(): string
{
$min = 10 ** ($this->digits - 1);
$max = 10 ** $this->digits - 1;
return (string) random_int($min, $max);
}
}
7 changes: 6 additions & 1 deletion Generator/CodeGeneratorInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,15 @@
interface CodeGeneratorInterface
{
/**
* Generate a new authentication code an send it to the user.
* Generate a new authentication code, stores it in the user object and send it to the user.
*/
public function generateAndSend(TwoFactorTextInterface $user): void;

/**
* Generate a new authentication code (but will not store it in the user object) and send it to the user with a custom text.
*/
public function returnAndSendWithMessage(TwoFactorTextInterface $user, string $text): string;

/**
* Resend the authentication code to the user
*/
Expand Down
11 changes: 2 additions & 9 deletions Provider/TextTwoFactorProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,8 @@

class TextTwoFactorProvider implements TwoFactorProviderInterface
{
/**
* @var CodeGeneratorInterface
*/
private $codeGenerator;

/**
* @var TwoFactorFormRendererInterface
*/
private $formRenderer;
private CodeGeneratorInterface $codeGenerator;
private TwoFactorFormRendererInterface $formRenderer;

public function __construct(CodeGeneratorInterface $codeGenerator, TwoFactorFormRendererInterface $formRenderer)
{
Expand Down
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,20 @@ two_factor_text:
template: '@SchebTwoFactor/Authentication/form.html.twig'
```

Upgrade to 2.0
--------------
There are two main breaking changes to version 2.0:

- The minimum supported version of PHP is upgraded to 7.4
- In the AuthCodeTextInterface the calling of the method "sendAuthCode" has changed:
old: sendAuthCode(TwoFactorTextInterface $user, string $format): void;
new: sendAuthCode(TwoFactorTextInterface $user, ?string $code): void;
The format/text will be retrieved by the new public method "getMessageFormat" in this way the sender can also be
used for other messages like a confirmation code. If $code is not passed (null) the old way of getting the code via
the user object can be taken.
Note that the default text as specified in the configuration is still used by the default CodeGenerator,
see the ExampleTextSender for an example.

License
-------
This software is available under the [MIT license](LICENSE).
10 changes: 9 additions & 1 deletion TextSender/AuthCodeTextInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,18 @@

interface AuthCodeTextInterface
{
/**
* Sets the message that will be sent to the user (%s will be replaced by the code)
*/
public function setMessageFormat(string $format): void;
public function getMessageFormat(): string;


/**
* Send the auth code to the user via text
*
* @param TwoFactorTextInterface $user
* @param string|null $code
*/
public function sendAuthCode(TwoFactorTextInterface $user, string $format): void;
public function sendAuthCode(TwoFactorTextInterface $user, ?string $code): void;
}
16 changes: 14 additions & 2 deletions TextSender/ExampleTextSender.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@

class ExampleTextSender implements AuthCodeTextInterface
{
public function sendAuthCode(TwoFactorTextInterface $user, string $format): void
private string $format;

public function sendAuthCode(TwoFactorTextInterface $user, ?string $code = null): void
{
// this is just an example, as you can see, this would always generate an error because the host "text-message-api" is invalid
HttpClient::create()->request(
Expand All @@ -18,9 +20,19 @@ public function sendAuthCode(TwoFactorTextInterface $user, string $format): void
[
'body' => [
'recipient' => $user->getTextAuthRecipient(),
'text' => sprintf($format, $user->getTextAuthCode()),
'text' => sprintf($this->getMessageFormat(), $code ?? $user->getTextAuthCode()),
]
]
);
}

public function setMessageFormat(string $format): void
{
$this->format = $format;
}

public function getMessageFormat(): string
{
return $this->format;
}
}
5 changes: 4 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@
}
],
"require": {
"php": ">=7.2.5",
"php": ">=7.4",
"scheb/2fa-bundle": "^5.0"
},
"require-dev": {
"symfony/http-client": "^5.3"
},
"autoload": {
"psr-4": {
"Erkens\\Security\\TwoFactorTextBundle\\": ""
Expand Down

0 comments on commit 601bf4f

Please sign in to comment.