diff --git a/Classes/Domain/Model/SecondFactor.php b/Classes/Domain/Model/SecondFactor.php index 036cf86..569d9d4 100644 --- a/Classes/Domain/Model/SecondFactor.php +++ b/Classes/Domain/Model/SecondFactor.php @@ -2,6 +2,7 @@ namespace Sandstorm\NeosTwoFactorAuthentication\Domain\Model; +use DateTime; use Neos\Flow\Http\InvalidArgumentException; use Neos\Flow\Security\Account; use Doctrine\ORM\Mapping as ORM; @@ -38,6 +39,15 @@ class SecondFactor */ protected string $secret; + /** + * Introduced with version 1.4.0 + * Nullable for backwards compatibility. Null values will be shown as '-' in backend module. + * + * @var DateTime|null + * @ORM\Column(type="datetime", nullable=true) + */ + protected DateTime|null $creationDate; + /** * @return Account */ @@ -94,6 +104,16 @@ public function setSecret(string $secret): void $this->secret = $secret; } + public function getCreationDate(): DateTime|null + { + return $this->creationDate; + } + + public function setCreationDate(DateTime $creationDate): void + { + $this->creationDate = $creationDate; + } + public function __toString(): string { return $this->account->getAccountIdentifier() . " with " . self::typeToString($this->type); diff --git a/Classes/Domain/Repository/SecondFactorRepository.php b/Classes/Domain/Repository/SecondFactorRepository.php index b166d21..08aa1fe 100644 --- a/Classes/Domain/Repository/SecondFactorRepository.php +++ b/Classes/Domain/Repository/SecondFactorRepository.php @@ -16,6 +16,11 @@ */ class SecondFactorRepository extends Repository { + protected $defaultOrderings = [ + 'account' => 'ASC', + 'creationDate' => 'DESC' + ]; + /** * @throws IllegalObjectTypeException */ @@ -25,6 +30,7 @@ public function createSecondFactorForAccount(string $secret, Account $account): $secondFactor->setAccount($account); $secondFactor->setSecret($secret); $secondFactor->setType(SecondFactor::TYPE_TOTP); + $secondFactor->setCreationDate(new \DateTime()); $this->add($secondFactor); $this->persistenceManager->persistAll(); } diff --git a/Migrations/Mysql/Version20240812091514.php b/Migrations/Mysql/Version20240812091514.php new file mode 100644 index 0000000..6a1e36d --- /dev/null +++ b/Migrations/Mysql/Version20240812091514.php @@ -0,0 +1,41 @@ +abortIf( + !$this->connection->getDatabasePlatform() instanceof \Doctrine\DBAL\Platforms\MySqlPlatform, + "Migration can only be executed safely on '\Doctrine\DBAL\Platforms\MySqlPlatform,'." + ); + + $this->addSql('ALTER TABLE sandstorm_neostwofactorauthentication_domain_model_secondfactor ADD creationdate DATETIME DEFAULT NULL'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->abortIf( + !$this->connection->getDatabasePlatform() instanceof \Doctrine\DBAL\Platforms\MySqlPlatform, + "Migration can only be executed safely on '\Doctrine\DBAL\Platforms\MySqlPlatform,'." + ); + + $this->addSql('ALTER TABLE sandstorm_neostwofactorauthentication_domain_model_secondfactor DROP creationdate'); + } +} diff --git a/Resources/Private/Fusion/Presentation/Components/SecondFactorList.fusion b/Resources/Private/Fusion/Presentation/Components/SecondFactorList.fusion index 6c2e3b9..f7275d2 100644 --- a/Resources/Private/Fusion/Presentation/Components/SecondFactorList.fusion +++ b/Resources/Private/Fusion/Presentation/Components/SecondFactorList.fusion @@ -7,6 +7,7 @@ prototype(Sandstorm.NeosTwoFactorAuthentication:Component.SecondFactorList) < pr {I18n.id('module.index.list.header.name').package('Sandstorm.NeosTwoFactorAuthentication').source('Backend').translate()} {I18n.id('module.index.list.header.type').package('Sandstorm.NeosTwoFactorAuthentication').source('Backend').translate()} + {I18n.id('module.index.list.header.creationDate').package('Sandstorm.NeosTwoFactorAuthentication').source('Backend').translate()}   @@ -42,6 +43,7 @@ prototype(Sandstorm.NeosTwoFactorAuthentication:Component.SecondFactorList.Entry {props.factorAndPerson.user.name.fullName} ({props.factorAndPerson.secondFactor.account.accountIdentifier}) {props.factorAndPerson.secondFactor.typeAsName} + {props.factorAndPerson.secondFactor.creationDate == null ? '-' : Date.format(props.factorAndPerson.secondFactor.creationDate, 'Y-m-d H:i')}