From 9c58836b9b3c8362ace26b2fc7cf8fe0da35c595 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Wed, 17 Jul 2024 22:43:13 +0200 Subject: [PATCH] fix: add default createdAt updatedAt when domain is created --- .gitignore | 1 - README.md | 50 ++++++++++---------- composer.json | 1 + composer.lock | 48 ++++++++++++++++++- src/Controller/DomainCalendarController.php | 51 +++++++++++++++++++-- src/Entity/Domain.php | 2 + src/Entity/User.php | 2 + src/Entity/WatchList.php | 10 ++++ symfony.lock | 3 ++ 9 files changed, 136 insertions(+), 32 deletions(-) diff --git a/.gitignore b/.gitignore index 4daae38..6810194 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ - ###> symfony/framework-bundle ### /.env.local /.env.local.php diff --git a/README.md b/README.md index ab1202a..62d706d 100644 --- a/README.md +++ b/README.md @@ -38,35 +38,33 @@ on [How to deploy a Symfony application](https://symfony.com/doc/current/deploym ### Steps 1. Clone the repository: - -```shell -git clone https://github.com/maelgangloff/domain-watchdog.git -``` + ```shell + git clone https://github.com/maelgangloff/domain-watchdog.git + ``` 2. Navigate to the project directory: - -```shell -cd domain-watchdog -``` + ```shell + cd domain-watchdog + ``` 3. Install dependencies: - -```shell -composer install -``` + ```shell + composer install + ``` 4. Set up your environment variables: - -```shell -cp .env .env.local -``` -5. Run database migrations: - -```shell -php bin/console doctrine:migrations:migrate -``` -6. Start the Symfony server: - -```shell -symfony server:start -``` + ```shell + cp .env .env.local + ``` +5. Generate the cryptographic key pair for the JWT signature + ```shell + php bin/console lexik:jwt:generate-keypair + ``` +6. Run database migrations: + ```shell + php bin/console doctrine:migrations:migrate + ``` +7. Start the Symfony server: + ```shell + symfony server:start + ``` > [!NOTE] > ## Useful documentation diff --git a/composer.json b/composer.json index ab35de9..439171a 100644 --- a/composer.json +++ b/composer.json @@ -48,6 +48,7 @@ "symfony/validator": "7.1.*", "symfony/web-link": "7.1.*", "symfony/yaml": "7.1.*", + "symfonycasts/verify-email-bundle": "^1.17", "twig/extra-bundle": "^2.12|^3.0", "twig/twig": "^2.12|^3.0" }, diff --git a/composer.lock b/composer.lock index 9b3a4f9..2238b10 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "cad4d9a9dfcfdf50a0cf2e374b7b666c", + "content-hash": "69d6c31e997e87a8200c72e415cb9f2c", "packages": [ { "name": "api-platform/core", @@ -8147,6 +8147,52 @@ ], "time": "2024-05-31T14:57:53+00:00" }, + { + "name": "symfonycasts/verify-email-bundle", + "version": "v1.17.0", + "source": { + "type": "git", + "url": "https://github.com/SymfonyCasts/verify-email-bundle.git", + "reference": "f72af149070b39ef82a7095074378d0a98b4d2ef" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/SymfonyCasts/verify-email-bundle/zipball/f72af149070b39ef82a7095074378d0a98b4d2ef", + "reference": "f72af149070b39ef82a7095074378d0a98b4d2ef", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": ">=8.1", + "symfony/config": "^5.4 | ^6.0 | ^7.0", + "symfony/dependency-injection": "^5.4 | ^6.0 | ^7.0", + "symfony/deprecation-contracts": "^2.2 | ^3.0", + "symfony/http-kernel": "^5.4 | ^6.0 | ^7.0", + "symfony/routing": "^5.4 | ^6.0 | ^7.0" + }, + "require-dev": { + "doctrine/orm": "^2.7", + "doctrine/persistence": "^2.0", + "symfony/framework-bundle": "^5.4 | ^6.0 | ^7.0", + "symfony/phpunit-bridge": "^5.4 | ^6.0 | ^7.0" + }, + "type": "symfony-bundle", + "autoload": { + "psr-4": { + "SymfonyCasts\\Bundle\\VerifyEmail\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Simple, stylish Email Verification for Symfony", + "support": { + "issues": "https://github.com/SymfonyCasts/verify-email-bundle/issues", + "source": "https://github.com/SymfonyCasts/verify-email-bundle/tree/v1.17.0" + }, + "time": "2024-03-17T02:29:53+00:00" + }, { "name": "twig/extra-bundle", "version": "v3.10.0", diff --git a/src/Controller/DomainCalendarController.php b/src/Controller/DomainCalendarController.php index 5d3a46d..9475898 100644 --- a/src/Controller/DomainCalendarController.php +++ b/src/Controller/DomainCalendarController.php @@ -2,18 +2,61 @@ namespace App\Controller; -use App\Service\RDAPService; +use App\Entity\DomainEntity; +use App\Entity\DomainEvent; +use App\Repository\DomainRepository; +use Eluceo\iCal\Domain\Entity\Attendee; +use Eluceo\iCal\Domain\Entity\Calendar; +use Eluceo\iCal\Domain\Entity\Event; +use Eluceo\iCal\Domain\ValueObject\Category; +use Eluceo\iCal\Domain\ValueObject\Date; +use Eluceo\iCal\Domain\ValueObject\EmailAddress; +use Eluceo\iCal\Domain\ValueObject\SingleDay; +use Eluceo\iCal\Presentation\Factory\CalendarFactory; use Exception; +use Sabre\VObject\Reader; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use Symfony\Component\HttpFoundation\Response; -class DomainRefreshController extends AbstractController +class DomainCalendarController extends AbstractController { + public function __construct( + private readonly DomainRepository $domainRepository + ) + { + + } /** * @throws Exception */ - public function __invoke(string $ldhName, RDAPService $RDAPService): void + public function __invoke(string $ldhName): Response { - $RDAPService->registerDomains([$ldhName]); + $calendar = new Calendar(); + + $domain = $this->domainRepository->findOneBy(["ldhName" => $ldhName]); + $attendees = []; + + /** @var DomainEntity $entity */ + foreach ($domain->getDomainEntities()->toArray() as $entity) { + $vCard = Reader::readJson($entity->getEntity()->getJCard()); + $email = (string)$vCard->EMAIL; + if (!filter_var($email, FILTER_VALIDATE_EMAIL)) continue; + + $attendees[] = (new Attendee(new EmailAddress($email)))->setDisplayName((string)$vCard->FN); + } + + /** @var DomainEvent $event */ + foreach ($domain->getEvents()->toArray() as $event) { + $calendar->addEvent((new Event()) + ->setSummary($domain->getLdhName() . ' (' . $event->getAction()->value . ')') + ->addCategory(new Category($event->getAction()->value)) + ->setAttendees($attendees) + ->setOccurrence(new SingleDay(new Date($event->getDate()))) + ); + } + return new Response((new CalendarFactory())->createCalendar($calendar), Response::HTTP_OK, [ + "Content-Type" => 'text/calendar; charset=utf-8' + ]); } } \ No newline at end of file diff --git a/src/Entity/Domain.php b/src/Entity/Domain.php index 0f73e42..6a32956 100644 --- a/src/Entity/Domain.php +++ b/src/Entity/Domain.php @@ -111,6 +111,8 @@ class Domain $this->domainEntities = new ArrayCollection(); $this->watchLists = new ArrayCollection(); $this->nameservers = new ArrayCollection(); + $this->createdAt = new DateTimeImmutable('now'); + $this->updatedAt = new DateTimeImmutable('now'); } public function getLdhName(): ?string diff --git a/src/Entity/User.php b/src/Entity/User.php index 32d449b..9bac4a1 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -6,11 +6,13 @@ use App\Repository\UserRepository; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; +use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface; use Symfony\Component\Security\Core\User\UserInterface; #[ORM\Entity(repositoryClass: UserRepository::class)] #[ORM\UniqueConstraint(name: 'UNIQ_IDENTIFIER_EMAIL', fields: ['email'])] +#[UniqueEntity(fields: ['email'], message: 'There is already an account with this email')] class User implements UserInterface, PasswordAuthenticatedUserInterface { #[ORM\Id] diff --git a/src/Entity/WatchList.php b/src/Entity/WatchList.php index cc78e62..38fc9ef 100644 --- a/src/Entity/WatchList.php +++ b/src/Entity/WatchList.php @@ -2,17 +2,26 @@ namespace App\Entity; +use ApiPlatform\Metadata\ApiResource; use App\Repository\WatchListRepository; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; +use Symfony\Component\Serializer\Attribute\Groups; use Symfony\Component\Uid\Uuid; #[ORM\Entity(repositoryClass: WatchListRepository::class)] +#[ApiResource( + shortName: 'Watchlist', + normalizationContext: ['groups' => 'watchlist:item', 'domain:list'], + denormalizationContext: ['groups' => 'watchlist:item', 'domain:list'], + paginationEnabled: false +)] class WatchList { #[ORM\Id] #[ORM\Column(length: 36)] + #[Groups(['watchlist:item'])] private string $token; #[ORM\ManyToOne(targetEntity: User::class, inversedBy: 'watchLists')] @@ -26,6 +35,7 @@ class WatchList #[ORM\JoinTable(name: 'watch_lists_domains', joinColumns: [new ORM\JoinColumn(name: 'watch_list_token', referencedColumnName: 'token')], inverseJoinColumns: [new ORM\JoinColumn(name: 'domain_ldh_name', referencedColumnName: 'ldh_name')])] + #[Groups(['watchlist:item'])] private Collection $domains; public function __construct() diff --git a/symfony.lock b/symfony.lock index 71c72da..5ab7499 100644 --- a/symfony.lock +++ b/symfony.lock @@ -311,6 +311,9 @@ "config/routes/web_profiler.yaml" ] }, + "symfonycasts/verify-email-bundle": { + "version": "v1.17.0" + }, "twig/extra-bundle": { "version": "v3.10.0" }