mirror of
https://github.com/maelgangloff/domain-watchdog.git
synced 2025-12-29 16:15:04 +00:00
feat: user can force domain refresh
This commit is contained in:
@@ -1,19 +1,22 @@
|
|||||||
import {Form, Input} from 'antd'
|
import {Form, Input} from 'antd'
|
||||||
import {t} from 'ttag'
|
import {t} from 'ttag'
|
||||||
import {SearchOutlined} from '@ant-design/icons'
|
import {SearchOutlined} from '@ant-design/icons'
|
||||||
import React from 'react'
|
import React, {useState} from 'react'
|
||||||
|
|
||||||
export interface FieldType {
|
export interface FieldType {
|
||||||
ldhName: string
|
ldhName: string
|
||||||
|
isRefreshForced: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export function DomainSearchBar({onFinish, initialValue}: {
|
export function DomainSearchBar({onFinish, initialValue}: {
|
||||||
onFinish: (values: FieldType) => void,
|
onFinish: (values: FieldType) => void,
|
||||||
initialValue?: string
|
initialValue?: string
|
||||||
}) {
|
}) {
|
||||||
|
const [isRefreshForced, setRefreshForced] = useState(false)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Form
|
<Form
|
||||||
onFinish={onFinish}
|
onFinish={({ldhName}: FieldType) => onFinish({ldhName, isRefreshForced})}
|
||||||
autoComplete='off'
|
autoComplete='off'
|
||||||
style={{width: '100%'}}
|
style={{width: '100%'}}
|
||||||
>
|
>
|
||||||
@@ -33,6 +36,8 @@ export function DomainSearchBar({onFinish, initialValue}: {
|
|||||||
<Input
|
<Input
|
||||||
style={{textAlign: 'center'}}
|
style={{textAlign: 'center'}}
|
||||||
size='large'
|
size='large'
|
||||||
|
onKeyDown={e => setRefreshForced(e.shiftKey)}
|
||||||
|
onKeyUp={e => setRefreshForced(e.shiftKey)}
|
||||||
prefix={<SearchOutlined/>}
|
prefix={<SearchOutlined/>}
|
||||||
placeholder='example.com'
|
placeholder='example.com'
|
||||||
autoComplete='off'
|
autoComplete='off'
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import {Col, List, Tag, Tooltip, Typography} from 'antd'
|
import {List, Tag, Tooltip, Typography} from 'antd'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import type {Domain} from '../../utils/api'
|
import type {Domain} from '../../utils/api'
|
||||||
import {rdapRoleDetailTranslation, rdapRoleTranslation} from '../../utils/functions/rdapTranslation'
|
import {rdapRoleDetailTranslation, rdapRoleTranslation} from '../../utils/functions/rdapTranslation'
|
||||||
@@ -29,19 +29,15 @@ export function EntitiesList({domain}: { domain: Domain }) {
|
|||||||
const details = extractDetailsFromJCard(e)
|
const details = extractDetailsFromJCard(e)
|
||||||
|
|
||||||
return <List.Item>
|
return <List.Item>
|
||||||
<Col span={14}>
|
<List.Item.Meta
|
||||||
<List.Item.Meta
|
avatar={roleToAvatar(e)}
|
||||||
avatar={roleToAvatar(e)}
|
title={<Typography.Text code>{e.entity.handle}</Typography.Text>}
|
||||||
title={<Typography.Text code>{e.entity.handle}</Typography.Text>}
|
description={<>
|
||||||
description={<>
|
{details.fn && <div>👤 {details.fn}</div>}
|
||||||
{details.fn && <div>👤 {details.fn}</div>}
|
{details.organization && <div>🏢 {details.organization}</div>}
|
||||||
{details.organization && <div>🏢 {details.organization}</div>}
|
</>}
|
||||||
</>}
|
/>
|
||||||
/>
|
{e.roles.map(roleToTag)}
|
||||||
</Col>
|
|
||||||
<Col span={10} flex='none'>
|
|
||||||
{e.roles.map(roleToTag)}
|
|
||||||
</Col>
|
|
||||||
</List.Item>
|
</List.Item>
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -19,13 +19,15 @@ export default function DomainSearchPage() {
|
|||||||
const [messageApi, contextHolder] = message.useMessage()
|
const [messageApi, contextHolder] = message.useMessage()
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const onFinish: FormProps<FieldType>['onFinish'] = (values) => {
|
const onFinish: FormProps<FieldType>['onFinish'] = (values) => {
|
||||||
navigate('/search/domain/' + values.ldhName)
|
navigate('/search/domain/' + values.ldhName)
|
||||||
|
|
||||||
if (loading) return
|
if (loading) return
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
setDomain(null)
|
setDomain(null)
|
||||||
getDomain(values.ldhName).then(d => {
|
getDomain(values.ldhName, values.isRefreshForced).then(d => {
|
||||||
setDomain(d)
|
setDomain(d)
|
||||||
messageApi.success(t`Found !`)
|
messageApi.success(t`Found !`)
|
||||||
}).catch((e: AxiosError) => {
|
}).catch((e: AxiosError) => {
|
||||||
@@ -36,7 +38,7 @@ export default function DomainSearchPage() {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (query === undefined) return
|
if (query === undefined) return
|
||||||
onFinish({ldhName: query})
|
onFinish({ldhName: query, isRefreshForced: false})
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import type {Domain} from '.'
|
import type {Domain} from '.'
|
||||||
import { request} from '.'
|
import {request} from '.'
|
||||||
|
|
||||||
export async function getDomain(ldhName: string): Promise<Domain> {
|
export async function getDomain(ldhName: string, forced = false): Promise<Domain> {
|
||||||
const response = await request<Domain>({
|
const response = await request<Domain>({
|
||||||
url: 'domains/' + ldhName
|
url: 'domains/' + ldhName,
|
||||||
|
params: {forced}
|
||||||
})
|
})
|
||||||
return response.data
|
return response.data
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ use App\Service\RDAPService;
|
|||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
use Random\Randomizer;
|
use Random\Randomizer;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException;
|
use Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException;
|
||||||
use Symfony\Component\HttpKernel\KernelInterface;
|
use Symfony\Component\HttpKernel\KernelInterface;
|
||||||
use Symfony\Component\Messenger\Exception\ExceptionInterface;
|
use Symfony\Component\Messenger\Exception\ExceptionInterface;
|
||||||
@@ -37,7 +38,7 @@ class DomainRefreshController extends AbstractController
|
|||||||
* @throws HttpExceptionInterface
|
* @throws HttpExceptionInterface
|
||||||
* @throws \Throwable
|
* @throws \Throwable
|
||||||
*/
|
*/
|
||||||
public function __invoke(string $ldhName, KernelInterface $kernel): Domain
|
public function __invoke(string $ldhName, KernelInterface $kernel, Request $request): Domain
|
||||||
{
|
{
|
||||||
$idnDomain = strtolower(idn_to_ascii($ldhName));
|
$idnDomain = strtolower(idn_to_ascii($ldhName));
|
||||||
$userId = $this->getUser()->getUserIdentifier();
|
$userId = $this->getUser()->getUserIdentifier();
|
||||||
@@ -49,12 +50,12 @@ class DomainRefreshController extends AbstractController
|
|||||||
|
|
||||||
/** @var ?Domain $domain */
|
/** @var ?Domain $domain */
|
||||||
$domain = $this->domainRepository->findOneBy(['ldhName' => $idnDomain]);
|
$domain = $this->domainRepository->findOneBy(['ldhName' => $idnDomain]);
|
||||||
|
|
||||||
// If the domain name exists in the database, recently updated and not important, we return the stored Domain
|
// If the domain name exists in the database, recently updated and not important, we return the stored Domain
|
||||||
if (null !== $domain
|
if (null !== $domain
|
||||||
&& !$domain->getDeleted()
|
&& !$domain->getDeleted()
|
||||||
&& !$domain->isToBeUpdated()
|
&& !$domain->isToBeUpdated()
|
||||||
&& !$this->kernel->isDebug()
|
&& !$this->kernel->isDebug()
|
||||||
|
&& true !== filter_var($request->get('forced', false), FILTER_VALIDATE_BOOLEAN)
|
||||||
) {
|
) {
|
||||||
$this->logger->info('It is not necessary to update the information of the domain name {idnDomain} with the RDAP protocol.', [
|
$this->logger->info('It is not necessary to update the information of the domain name {idnDomain} with the RDAP protocol.', [
|
||||||
'idnDomain' => $idnDomain,
|
'idnDomain' => $idnDomain,
|
||||||
|
|||||||
Reference in New Issue
Block a user