mirror of
https://github.com/maelgangloff/domain-watchdog.git
synced 2025-12-17 17:55:42 +00:00
feat: add DNSSEC badge in domain response
This commit is contained in:
parent
51593f31d0
commit
363d7a97f3
@ -11,7 +11,7 @@ import {regionNames} from "../../i18n";
|
|||||||
import {getCountryCode} from "../../utils/functions/getCountryCode";
|
import {getCountryCode} from "../../utils/functions/getCountryCode";
|
||||||
import {eppStatusCodeToColor} from "../../utils/functions/eppStatusCodeToColor";
|
import {eppStatusCodeToColor} from "../../utils/functions/eppStatusCodeToColor";
|
||||||
import {DomainLifecycleSteps} from "./DomainLifecycleSteps";
|
import {DomainLifecycleSteps} from "./DomainLifecycleSteps";
|
||||||
import {BankOutlined, SafetyCertificateOutlined} from '@ant-design/icons'
|
import {BankOutlined, KeyOutlined, SafetyCertificateOutlined} from '@ant-design/icons'
|
||||||
|
|
||||||
export function DomainResult({domain}: { domain: Domain }) {
|
export function DomainResult({domain}: { domain: Domain }) {
|
||||||
|
|
||||||
@ -68,6 +68,11 @@ export function DomainResult({domain}: { domain: Domain }) {
|
|||||||
icon={<BankOutlined
|
icon={<BankOutlined
|
||||||
style={{fontSize: '16px'}}/>}>{t`Registrar Lock`}</Tag>
|
style={{fontSize: '16px'}}/>}>{t`Registrar Lock`}</Tag>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
<Tooltip
|
||||||
|
title={t`DNSSEC secures DNS by adding cryptographic signatures to DNS records, ensuring authenticity and integrity of responses`}>
|
||||||
|
<Tag bordered={false} color={domain.delegationSigned ? 'green' : 'default'}
|
||||||
|
icon={<KeyOutlined style={{fontSize: '16px'}}/>}>{t`DNSSEC`}</Tag>
|
||||||
|
</Tooltip>
|
||||||
</Flex>
|
</Flex>
|
||||||
{domain.status.length > 0 &&
|
{domain.status.length > 0 &&
|
||||||
<>
|
<>
|
||||||
|
|||||||
@ -60,6 +60,7 @@ export interface Domain {
|
|||||||
tld: Tld
|
tld: Tld
|
||||||
deleted: boolean
|
deleted: boolean
|
||||||
updatedAt: string
|
updatedAt: string
|
||||||
|
delegationSigned: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface User {
|
export interface User {
|
||||||
|
|||||||
31
migrations/Version20241230131605.php
Normal file
31
migrations/Version20241230131605.php
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace DoctrineMigrations;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
|
use Doctrine\Migrations\AbstractMigration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto-generated Migration: Please modify to your needs!
|
||||||
|
*/
|
||||||
|
final class Version20241230131605 extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return 'Add DNSSEC delegation_signed';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function up(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this up() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('ALTER TABLE domain ADD delegation_signed BOOLEAN NOT NULL DEFAULT FALSE');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this down() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('ALTER TABLE domain DROP delegation_signed');
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -117,6 +117,10 @@ class Domain
|
|||||||
#[SerializedName('oldStatus')]
|
#[SerializedName('oldStatus')]
|
||||||
private Collection $domainStatuses;
|
private Collection $domainStatuses;
|
||||||
|
|
||||||
|
#[ORM\Column(nullable: false)]
|
||||||
|
#[Groups(['domain:item'])]
|
||||||
|
private ?bool $delegationSigned = null;
|
||||||
|
|
||||||
private const IMPORTANT_EVENTS = [EventAction::Deletion->value, EventAction::Expiration->value];
|
private const IMPORTANT_EVENTS = [EventAction::Deletion->value, EventAction::Expiration->value];
|
||||||
private const IMPORTANT_STATUS = [
|
private const IMPORTANT_STATUS = [
|
||||||
'redemption period',
|
'redemption period',
|
||||||
@ -432,8 +436,22 @@ class Domain
|
|||||||
return $this->rdapServer;
|
return $this->rdapServer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setRdapServer(?RdapServer $rdapServer): void
|
public function setRdapServer(?RdapServer $rdapServer): static
|
||||||
{
|
{
|
||||||
$this->rdapServer = $rdapServer;
|
$this->rdapServer = $rdapServer;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isDelegationSigned(): ?bool
|
||||||
|
{
|
||||||
|
return $this->delegationSigned;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setDelegationSigned(bool $delegationSigned): static
|
||||||
|
{
|
||||||
|
$this->delegationSigned = $delegationSigned;
|
||||||
|
|
||||||
|
return $this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -142,14 +142,14 @@ readonly class RDAPService
|
|||||||
$domain = $this->initNewDomain($idnDomain, $tld);
|
$domain = $this->initNewDomain($idnDomain, $tld);
|
||||||
}
|
}
|
||||||
|
|
||||||
$domain->setRdapServer($rdapServer);
|
|
||||||
|
|
||||||
$this->updateDomainStatus($domain, $rdapData);
|
$this->updateDomainStatus($domain, $rdapData);
|
||||||
|
|
||||||
if (in_array('free', $domain->getStatus())) {
|
if (in_array('free', $domain->getStatus())) {
|
||||||
throw new NotFoundHttpException('The domain name is not present in the WHOIS database.');
|
throw new NotFoundHttpException('The domain name is not present in the WHOIS database.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$domain->setRdapServer($rdapServer)->setDelegationSigned(isset($rdapData['secureDNS']['delegationSigned']) && true === $rdapData['secureDNS']['delegationSigned']);
|
||||||
|
|
||||||
$this->updateDomainHandle($domain, $rdapData);
|
$this->updateDomainHandle($domain, $rdapData);
|
||||||
|
|
||||||
$this->updateDomainEvents($domain, $rdapData);
|
$this->updateDomainEvents($domain, $rdapData);
|
||||||
@ -266,7 +266,7 @@ readonly class RDAPService
|
|||||||
|
|
||||||
private function updateDomainStatus(Domain $domain, array $rdapData): void
|
private function updateDomainStatus(Domain $domain, array $rdapData): void
|
||||||
{
|
{
|
||||||
if (array_key_exists('status', $rdapData)) {
|
if (isset($rdapData['status'])) {
|
||||||
$status = array_unique($rdapData['status']);
|
$status = array_unique($rdapData['status']);
|
||||||
$addedStatus = array_diff($status, $domain->getStatus());
|
$addedStatus = array_diff($status, $domain->getStatus());
|
||||||
$deletedStatus = array_diff($domain->getStatus(), $status);
|
$deletedStatus = array_diff($domain->getStatus(), $status);
|
||||||
@ -293,7 +293,7 @@ readonly class RDAPService
|
|||||||
|
|
||||||
private function updateDomainHandle(Domain $domain, array $rdapData): void
|
private function updateDomainHandle(Domain $domain, array $rdapData): void
|
||||||
{
|
{
|
||||||
if (array_key_exists('handle', $rdapData)) {
|
if (isset($rdapData['handle'])) {
|
||||||
$domain->setHandle($rdapData['handle']);
|
$domain->setHandle($rdapData['handle']);
|
||||||
} else {
|
} else {
|
||||||
$this->logger->warning('The domain name {idnDomain} has no handle key.', [
|
$this->logger->warning('The domain name {idnDomain} has no handle key.', [
|
||||||
@ -312,7 +312,7 @@ readonly class RDAPService
|
|||||||
$event->setDeleted(true);
|
$event->setDeleted(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (array_key_exists('events', $rdapData) && is_array($rdapData['events'])) {
|
if (isset($rdapData['events']) && is_array($rdapData['events'])) {
|
||||||
foreach ($rdapData['events'] as $rdapEvent) {
|
foreach ($rdapData['events'] as $rdapEvent) {
|
||||||
if ($rdapEvent['eventAction'] === EventAction::LastUpdateOfRDAPDatabase->value) {
|
if ($rdapEvent['eventAction'] === EventAction::LastUpdateOfRDAPDatabase->value) {
|
||||||
continue;
|
continue;
|
||||||
@ -348,7 +348,7 @@ readonly class RDAPService
|
|||||||
$domainEntity->setDeleted(true);
|
$domainEntity->setDeleted(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (array_key_exists('entities', $rdapData) && is_array($rdapData['entities'])) {
|
if (isset($rdapData['entities']) && is_array($rdapData['entities'])) {
|
||||||
foreach ($rdapData['entities'] as $rdapEntity) {
|
foreach ($rdapData['entities'] as $rdapEntity) {
|
||||||
$roles = $this->extractEntityRoles($rdapData['entities'], $rdapEntity);
|
$roles = $this->extractEntityRoles($rdapData['entities'], $rdapEntity);
|
||||||
$entity = $this->registerEntity($rdapEntity, $roles, $domain->getLdhName());
|
$entity = $this->registerEntity($rdapEntity, $roles, $domain->getLdhName());
|
||||||
@ -422,7 +422,7 @@ readonly class RDAPService
|
|||||||
*/
|
*/
|
||||||
private function updateNameserverEntities(Nameserver $nameserver, array $rdapNameserver): void
|
private function updateNameserverEntities(Nameserver $nameserver, array $rdapNameserver): void
|
||||||
{
|
{
|
||||||
if (!array_key_exists('entities', $rdapNameserver) || !is_array($rdapNameserver['entities'])) {
|
if (!isset($rdapNameserver['entities']) || !is_array($rdapNameserver['entities'])) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -456,10 +456,10 @@ readonly class RDAPService
|
|||||||
fn ($e) => $e['roles'],
|
fn ($e) => $e['roles'],
|
||||||
array_filter(
|
array_filter(
|
||||||
$entities,
|
$entities,
|
||||||
fn ($e) => array_key_exists('handle', $targetEntity) && array_key_exists('handle', $e)
|
fn ($e) => isset($targetEntity['handle']) && isset($e['handle'])
|
||||||
? $targetEntity['handle'] === $e['handle']
|
? $targetEntity['handle'] === $e['handle']
|
||||||
: (
|
: (
|
||||||
array_key_exists('vcardArray', $targetEntity) && array_key_exists('vcardArray', $e)
|
isset($targetEntity['vcardArray']) && isset($e['vcardArray'])
|
||||||
? $targetEntity['vcardArray'] === $e['vcardArray']
|
? $targetEntity['vcardArray'] === $e['vcardArray']
|
||||||
: $targetEntity === $e
|
: $targetEntity === $e
|
||||||
)
|
)
|
||||||
@ -483,9 +483,9 @@ readonly class RDAPService
|
|||||||
* If the RDAP server transmits the entity's IANA number, it is used as a priority to identify the entity
|
* If the RDAP server transmits the entity's IANA number, it is used as a priority to identify the entity
|
||||||
*/
|
*/
|
||||||
$isIANAid = false;
|
$isIANAid = false;
|
||||||
if (array_key_exists('publicIds', $rdapEntity)) {
|
if (isset($rdapEntity['publicIds'])) {
|
||||||
foreach ($rdapEntity['publicIds'] as $publicId) {
|
foreach ($rdapEntity['publicIds'] as $publicId) {
|
||||||
if ('IANA Registrar ID' === $publicId['type'] && array_key_exists('identifier', $publicId) && '' !== $publicId['identifier']) {
|
if ('IANA Registrar ID' === $publicId['type'] && isset($publicId['identifier']) && '' !== $publicId['identifier']) {
|
||||||
$rdapEntity['handle'] = $publicId['identifier'];
|
$rdapEntity['handle'] = $publicId['identifier'];
|
||||||
$isIANAid = true;
|
$isIANAid = true;
|
||||||
break;
|
break;
|
||||||
@ -496,7 +496,7 @@ readonly class RDAPService
|
|||||||
/*
|
/*
|
||||||
* If there is no number to identify the entity, one is generated from the domain name and the roles associated with this entity
|
* If there is no number to identify the entity, one is generated from the domain name and the roles associated with this entity
|
||||||
*/
|
*/
|
||||||
if (!array_key_exists('handle', $rdapEntity) || '' === $rdapEntity['handle'] || in_array($rdapEntity['handle'], self::ENTITY_HANDLE_BLACKLIST)) {
|
if (!isset($rdapEntity['handle']) || '' === $rdapEntity['handle'] || in_array($rdapEntity['handle'], self::ENTITY_HANDLE_BLACKLIST)) {
|
||||||
sort($roles);
|
sort($roles);
|
||||||
$rdapEntity['handle'] = 'DW-FAKEHANDLE-'.$domain.'-'.implode(',', $roles);
|
$rdapEntity['handle'] = 'DW-FAKEHANDLE-'.$domain.'-'.implode(',', $roles);
|
||||||
|
|
||||||
@ -519,11 +519,11 @@ readonly class RDAPService
|
|||||||
|
|
||||||
$entity->setHandle($rdapEntity['handle']);
|
$entity->setHandle($rdapEntity['handle']);
|
||||||
|
|
||||||
if (array_key_exists('remarks', $rdapEntity) && is_array($rdapEntity['remarks']) && !is_numeric($rdapEntity['handle'])) {
|
if (isset($rdapEntity['remarks']) && is_array($rdapEntity['remarks']) && !is_numeric($rdapEntity['handle'])) {
|
||||||
$entity->setRemarks($rdapEntity['remarks']);
|
$entity->setRemarks($rdapEntity['remarks']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (array_key_exists('vcardArray', $rdapEntity) && !in_array($rdapEntity['handle'], self::IANA_RESERVED_IDS)) {
|
if (isset($rdapEntity['vcardArray']) && !in_array($rdapEntity['handle'], self::IANA_RESERVED_IDS)) {
|
||||||
if (empty($entity->getJCard())) {
|
if (empty($entity->getJCard())) {
|
||||||
$entity->setJCard($rdapEntity['vcardArray']);
|
$entity->setJCard($rdapEntity['vcardArray']);
|
||||||
} else {
|
} else {
|
||||||
@ -538,7 +538,7 @@ readonly class RDAPService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($isIANAid || !array_key_exists('events', $rdapEntity) || in_array($rdapEntity['handle'], self::IANA_RESERVED_IDS)) {
|
if ($isIANAid || !isset($rdapEntity['events']) || in_array($rdapEntity['handle'], self::IANA_RESERVED_IDS)) {
|
||||||
return $entity;
|
return $entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -620,7 +620,7 @@ readonly class RDAPService
|
|||||||
$server
|
$server
|
||||||
->setTld($tldReference)
|
->setTld($tldReference)
|
||||||
->setUrl($rdapServerUrl)
|
->setUrl($rdapServerUrl)
|
||||||
->setUpdatedAt(new \DateTimeImmutable(array_key_exists('publication', $dnsRoot) ? $dnsRoot['publication'] : 'now'));
|
->setUpdatedAt(new \DateTimeImmutable($dnsRoot['publication'] ?? 'now'));
|
||||||
|
|
||||||
$this->em->persist($server);
|
$this->em->persist($server);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -122,15 +122,25 @@ msgstr ""
|
|||||||
msgid "Registrar Lock"
|
msgid "Registrar Lock"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: assets/components/search/DomainResult.tsx:72
|
||||||
|
msgid ""
|
||||||
|
"DNSSEC secures DNS by adding cryptographic signatures to DNS records, "
|
||||||
|
"ensuring authenticity and integrity of responses"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: assets/components/search/DomainResult.tsx:74
|
#: assets/components/search/DomainResult.tsx:74
|
||||||
|
msgid "DNSSEC"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: assets/components/search/DomainResult.tsx:79
|
||||||
msgid "EPP Status Codes"
|
msgid "EPP Status Codes"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: assets/components/search/DomainResult.tsx:83
|
#: assets/components/search/DomainResult.tsx:88
|
||||||
msgid "Timeline"
|
msgid "Timeline"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: assets/components/search/DomainResult.tsx:90
|
#: assets/components/search/DomainResult.tsx:95
|
||||||
msgid "Entities"
|
msgid "Entities"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user