mirror of
https://github.com/getnamingo/registry.git
synced 2025-08-05 17:18:04 +02:00
Updates to RDAP structure
This commit is contained in:
parent
db00aaffeb
commit
2847d04942
3 changed files with 145 additions and 70 deletions
|
@ -92,25 +92,18 @@ function mapContactToVCard($contactDetails, $role, $c) {
|
|||
'remarks' => [
|
||||
[
|
||||
"description" => [
|
||||
"This object's data has been partially omitted for privacy.",
|
||||
"Only the registrar managing the record can view personal contact data."
|
||||
],
|
||||
"links" => [
|
||||
[
|
||||
"href" => "https://namingo.org",
|
||||
"rel" => "alternate",
|
||||
"type" => "text/html"
|
||||
]
|
||||
"REDACTED FOR PRIVACY",
|
||||
"Visit www.icann.org/privacy for details."
|
||||
],
|
||||
"title" => "REDACTED FOR PRIVACY",
|
||||
"type" => "Details are withheld due to privacy restrictions."
|
||||
"type" => "object redacted due to authorization"
|
||||
],
|
||||
[
|
||||
"description" => [
|
||||
"To obtain contact information for the domain registrant, please refer to the Registrar of Record's RDDS service as indicated in this report."
|
||||
],
|
||||
"title" => "EMAIL REDACTED FOR PRIVACY",
|
||||
"type" => "Details are withheld due to privacy restrictions."
|
||||
"type" => "object truncated due to authorization"
|
||||
],
|
||||
],
|
||||
'vcardArray' => [
|
||||
|
@ -119,7 +112,7 @@ function mapContactToVCard($contactDetails, $role, $c) {
|
|||
['version', new stdClass(), 'text', '4.0'],
|
||||
["fn", new stdClass(), 'text', $disclose_name ? $contactDetails['name'] : "REDACTED FOR PRIVACY"],
|
||||
["org", new stdClass(), 'text', $disclose_org ? $contactDetails['org'] : "REDACTED FOR PRIVACY"],
|
||||
["adr", ["CC" => strtoupper($contactDetails['cc'])], 'text', [ // specify "CC" parameter for country code
|
||||
["adr", ["cc" => strtoupper($contactDetails['cc'])], 'text', [ // specify "cc" parameter for country code
|
||||
$disclose_addr ? $contactDetails['street1'] : "REDACTED FOR PRIVACY", // Extended address
|
||||
$disclose_addr ? $contactDetails['street2'] : "REDACTED FOR PRIVACY", // Street address
|
||||
$disclose_addr ? $contactDetails['street3'] : "REDACTED FOR PRIVACY", // Additional street address
|
||||
|
@ -128,8 +121,8 @@ function mapContactToVCard($contactDetails, $role, $c) {
|
|||
$disclose_addr ? $contactDetails['pc'] : "REDACTED FOR PRIVACY", // Postal code
|
||||
"" // Add empty last element as required for ADR structure
|
||||
]],
|
||||
["tel", ["type" => "voice"], 'uri', $disclose_voice ? "tel:" . $contactDetails['voice'] : "REDACTED FOR PRIVACY"],
|
||||
["tel", ["type" => "fax"], 'uri', $disclose_fax ? "tel:" . $contactDetails['fax'] : "REDACTED FOR PRIVACY"],
|
||||
["tel", ["type" => "voice"], $disclose_voice ? 'uri' : 'text', $disclose_voice ? "tel:" . $contactDetails['voice'] : "REDACTED FOR PRIVACY"],
|
||||
["tel", ["type" => "fax"], $disclose_fax ? 'uri' : 'text', $disclose_fax ? "tel:" . $contactDetails['fax'] : "REDACTED FOR PRIVACY"],
|
||||
["email", new stdClass(), 'text', $disclose_email ? $contactDetails['email'] : "REDACTED FOR PRIVACY"],
|
||||
]
|
||||
],
|
||||
|
@ -193,4 +186,44 @@ function mapStatuses(array $statuses): array {
|
|||
return array_map(function ($status) use ($statusMap) {
|
||||
return $statusMap[$status] ?? $status; // Return mapped value or original if not found
|
||||
}, $statuses);
|
||||
}
|
||||
|
||||
function isValidHostname($hostname) {
|
||||
$hostname = trim($hostname);
|
||||
|
||||
// Convert IDN (Unicode) to ASCII if necessary
|
||||
if (mb_detect_encoding($hostname, 'ASCII', true) === false) {
|
||||
$hostname = idn_to_ascii($hostname, IDNA_NONTRANSITIONAL_TO_ASCII, INTL_IDNA_VARIANT_UTS46);
|
||||
if ($hostname === false) {
|
||||
return false; // Invalid IDN conversion
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure there is at least **one dot** (to prevent single-segment hostnames)
|
||||
if (substr_count($hostname, '.') < 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Regular expression for validating a hostname
|
||||
$pattern = '/^((xn--[a-zA-Z0-9-]{1,63}|[a-zA-Z0-9-]{1,63})\.)*([a-zA-Z0-9-]{1,63}|xn--[a-zA-Z0-9-]{2,63})$/';
|
||||
|
||||
// Ensure it matches the hostname pattern
|
||||
if (!preg_match($pattern, $hostname)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ensure no label exceeds 63 characters
|
||||
$labels = explode('.', $hostname);
|
||||
foreach ($labels as $label) {
|
||||
if (strlen($label) > 63) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure full hostname is not longer than 255 characters
|
||||
if (strlen($hostname) > 255) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
|
@ -514,12 +514,15 @@ function handleDomainQuery($request, $response, $pdo, $domainName, $c, $log) {
|
|||
}
|
||||
|
||||
$abuseContactName = ($registrarAbuseDetails) ? $registrarAbuseDetails['first_name'] . ' ' . $registrarAbuseDetails['last_name'] : '';
|
||||
$rdapClean = rtrim(preg_replace('#^.*?//#', '', $registrarDetails['rdap_server'] ?? ''), '/');
|
||||
|
||||
// Construct the RDAP response in JSON format
|
||||
$rdapResponse = [
|
||||
'rdapConformance' => [
|
||||
'rdap_level_0',
|
||||
'icann_rdap_response_profile_0',
|
||||
'icann_rdap_response_profile_1',
|
||||
'icann_rdap_technical_implementation_guide_0',
|
||||
'icann_rdap_technical_implementation_guide_1',
|
||||
],
|
||||
'objectClassName' => 'domain',
|
||||
|
@ -601,8 +604,8 @@ function handleDomainQuery($request, $response, $pdo, $domainName, $c, $log) {
|
|||
'type' => 'application/rdap+json',
|
||||
],
|
||||
[
|
||||
'href' => $registrarDetails['rdap_server'] . 'domain/' . $domain,
|
||||
'value' => $registrarDetails['rdap_server'] . 'domain/' . $domain,
|
||||
'href' => 'https://' . $rdapClean . '/domain/' . $domain,
|
||||
'value' => 'https://' . $rdapClean . '/domain/' . $domain,
|
||||
'rel' => 'related',
|
||||
'type' => 'application/rdap+json',
|
||||
]
|
||||
|
@ -918,7 +921,7 @@ function handleEntityQuery($request, $response, $pdo, $entityHandle, $c, $log) {
|
|||
// Initialize an array to hold entity blocks
|
||||
$entityBlocks = [];
|
||||
// Define an array of allowed contact types
|
||||
$allowedTypes = ['owner', 'tech', 'abuse'];
|
||||
$allowedTypes = ['owner', 'billing', 'abuse'];
|
||||
|
||||
foreach ($contacts as $contact) {
|
||||
// Check if the contact type is one of the allowed types
|
||||
|
@ -929,14 +932,14 @@ function handleEntityQuery($request, $response, $pdo, $entityHandle, $c, $log) {
|
|||
// Create an entity block for each allowed contact type
|
||||
$entityBlock = [
|
||||
'objectClassName' => 'entity',
|
||||
'roles' => [$contact['type']],
|
||||
'roles' => [($contact['type'] === 'owner') ? 'administrative' : $contact['type']],
|
||||
"status" => ["active"],
|
||||
"vcardArray" => [
|
||||
"vcard",
|
||||
[
|
||||
['version', new stdClass(), 'text', '4.0'],
|
||||
["fn", new stdClass(), "text", $fullName],
|
||||
["tel", ["type" => ["voice"]], "uri", "tel:" . $contact['voice']],
|
||||
["tel", ["type" => ["voice"]], $contact['voice'] ? "uri" : "text", $contact['voice'] ? "tel:" . $contact['voice'] : ""],
|
||||
["email", new stdClass(), "text", $contact['email']]
|
||||
]
|
||||
],
|
||||
|
@ -951,7 +954,9 @@ function handleEntityQuery($request, $response, $pdo, $entityHandle, $c, $log) {
|
|||
$rdapResponse = [
|
||||
'rdapConformance' => [
|
||||
'rdap_level_0',
|
||||
'icann_rdap_response_profile_0',
|
||||
'icann_rdap_response_profile_1',
|
||||
'icann_rdap_technical_implementation_guide_0',
|
||||
'icann_rdap_technical_implementation_guide_1',
|
||||
],
|
||||
'objectClassName' => 'entity',
|
||||
|
@ -1129,11 +1134,11 @@ function handleNameserverQuery($request, $response, $pdo, $nameserverHandle, $c,
|
|||
}
|
||||
}
|
||||
|
||||
// Check for prohibited patterns in nameserver
|
||||
if (!preg_match('/^((xn--[a-zA-Z0-9-]{1,63}|[a-zA-Z0-9-]{1,63})\.){2,}(xn--[a-zA-Z0-9-]{2,63}|[a-zA-Z]{2,63})$/', $ns)) {
|
||||
// Validate nameserver
|
||||
if (!isValidHostname($ns)) {
|
||||
$response->header('Content-Type', 'application/json');
|
||||
$response->status(400); // Bad Request
|
||||
$response->end(json_encode(['error' => 'Nameserver invalid format']));
|
||||
$response->end(json_encode(['error' => 'Nameserver format is invalid. Expected a fully qualified domain name (FQDN), punycode supported (e.g., ns1.example.com)']));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1298,12 +1303,15 @@ function handleNameserverQuery($request, $response, $pdo, $nameserverHandle, $c,
|
|||
if (!empty($associated)) {
|
||||
$statuses[] = 'associated';
|
||||
}
|
||||
$statuses = array_unique(array_map(fn($s) => $s === 'ok' ? 'active' : $s, $statuses));
|
||||
|
||||
// Construct the RDAP response in JSON format
|
||||
$rdapResponse = [
|
||||
'rdapConformance' => [
|
||||
'rdap_level_0',
|
||||
'icann_rdap_response_profile_0',
|
||||
'icann_rdap_response_profile_1',
|
||||
'icann_rdap_technical_implementation_guide_0',
|
||||
'icann_rdap_technical_implementation_guide_1',
|
||||
],
|
||||
'objectClassName' => 'nameserver',
|
||||
|
@ -1366,8 +1374,9 @@ function handleNameserverQuery($request, $response, $pdo, $nameserverHandle, $c,
|
|||
'ldhName' => $hostDetails['name'],
|
||||
'links' => [
|
||||
[
|
||||
'href' => $c['rdap_url'] . '/nameserver/' . $hostDetails['name'],
|
||||
'value' => $c['rdap_url'] . '/nameserver/' . $hostDetails['name'],
|
||||
'rel' => 'self',
|
||||
'href' => $c['rdap_url'] . '/nameserver/' . $hostDetails['name'],
|
||||
'type' => 'application/rdap+json',
|
||||
]
|
||||
],
|
||||
|
@ -1855,7 +1864,9 @@ function handleDomainSearchQuery($request, $response, $pdo, $searchPattern, $c,
|
|||
$rdapResponse = [
|
||||
'rdapConformance' => [
|
||||
'rdap_level_0',
|
||||
'icann_rdap_response_profile_0',
|
||||
'icann_rdap_response_profile_1',
|
||||
'icann_rdap_technical_implementation_guide_0',
|
||||
'icann_rdap_technical_implementation_guide_1',
|
||||
],
|
||||
'domainSearchResults' => [
|
||||
|
@ -2117,14 +2128,14 @@ function handleNameserverSearchQuery($request, $response, $pdo, $searchPattern,
|
|||
}
|
||||
}
|
||||
|
||||
// Check for prohibited patterns in nameserver
|
||||
if (!preg_match('/^((xn--[a-zA-Z0-9-]{1,63}|[a-zA-Z0-9-]{1,63})\.){2,}(xn--[a-zA-Z0-9-]{2,63}|[a-zA-Z]{2,63})$/', $ns)) {
|
||||
// Validate nameserver
|
||||
if (!isValidHostname($ns)) {
|
||||
$response->header('Content-Type', 'application/json');
|
||||
$response->status(400); // Bad Request
|
||||
$response->end(json_encode(['error' => 'Nameserver invalid format']));
|
||||
$response->end(json_encode(['error' => 'Nameserver format is invalid. Expected a fully qualified domain name (FQDN), punycode supported (e.g., ns1.example.com)']));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Extract TLD from the domain
|
||||
$parts = explode('.', $ns);
|
||||
$tld = "." . end($parts);
|
||||
|
@ -2339,7 +2350,9 @@ function handleNameserverSearchQuery($request, $response, $pdo, $searchPattern,
|
|||
$rdapResponse = [
|
||||
'rdapConformance' => [
|
||||
'rdap_level_0',
|
||||
'icann_rdap_response_profile_0',
|
||||
'icann_rdap_response_profile_1',
|
||||
'icann_rdap_technical_implementation_guide_0',
|
||||
'icann_rdap_technical_implementation_guide_1',
|
||||
],
|
||||
'nameserverSearchResults' => $rdapResult,
|
||||
|
@ -2466,7 +2479,9 @@ function handleNameserverSearchQuery($request, $response, $pdo, $searchPattern,
|
|||
$rdapResponse = [
|
||||
'rdapConformance' => [
|
||||
'rdap_level_0',
|
||||
'icann_rdap_response_profile_0',
|
||||
'icann_rdap_response_profile_1',
|
||||
'icann_rdap_technical_implementation_guide_0',
|
||||
'icann_rdap_technical_implementation_guide_1',
|
||||
],
|
||||
'nameserverSearchResults' => [
|
||||
|
@ -2815,7 +2830,7 @@ function handleEntitySearchQuery($request, $response, $pdo, $searchPattern, $c,
|
|||
// Initialize an array to hold entity blocks
|
||||
$entityBlocks = [];
|
||||
// Define an array of allowed contact types
|
||||
$allowedTypes = ['owner', 'tech', 'abuse'];
|
||||
$allowedTypes = ['owner', 'billing', 'abuse'];
|
||||
|
||||
foreach ($contacts as $contact) {
|
||||
// Check if the contact type is one of the allowed types
|
||||
|
@ -2826,14 +2841,14 @@ function handleEntitySearchQuery($request, $response, $pdo, $searchPattern, $c,
|
|||
// Create an entity block for each allowed contact type
|
||||
$entityBlock = [
|
||||
'objectClassName' => 'entity',
|
||||
'roles' => [$contact['type']],
|
||||
'roles' => [($contact['type'] === 'owner') ? 'administrative' : $contact['type']],
|
||||
"status" => ["active"],
|
||||
"vcardArray" => [
|
||||
"vcard",
|
||||
[
|
||||
['version', new stdClass(), 'text', '4.0'],
|
||||
["fn", new stdClass(), "text", $fullName],
|
||||
["tel", ["type" => ["voice"]], "uri", "tel:" . $contact['voice']],
|
||||
["tel", ["type" => ["voice"]], $contact['voice'] ? "uri" : "text", $contact['voice'] ? "tel:" . $contact['voice'] : ""],
|
||||
["email", new stdClass(), "text", $contact['email']]
|
||||
]
|
||||
],
|
||||
|
@ -2848,7 +2863,9 @@ function handleEntitySearchQuery($request, $response, $pdo, $searchPattern, $c,
|
|||
$rdapResponse = [
|
||||
'rdapConformance' => [
|
||||
'rdap_level_0',
|
||||
'icann_rdap_response_profile_0',
|
||||
'icann_rdap_response_profile_1',
|
||||
'icann_rdap_technical_implementation_guide_0',
|
||||
'icann_rdap_technical_implementation_guide_1',
|
||||
],
|
||||
'entitySearchResults' => [
|
||||
|
@ -2993,9 +3010,11 @@ function handleEntitySearchQuery($request, $response, $pdo, $searchPattern, $c,
|
|||
function handleHelpQuery($request, $response, $pdo, $c) {
|
||||
// Set the RDAP conformance levels
|
||||
$rdapConformance = [
|
||||
"rdap_level_0",
|
||||
"icann_rdap_response_profile_1",
|
||||
"icann_rdap_technical_implementation_guide_1"
|
||||
'rdap_level_0',
|
||||
'icann_rdap_response_profile_0',
|
||||
'icann_rdap_response_profile_1',
|
||||
'icann_rdap_technical_implementation_guide_0',
|
||||
'icann_rdap_technical_implementation_guide_1',
|
||||
];
|
||||
|
||||
// Set the descriptions and links for the help section
|
||||
|
@ -3015,13 +3034,15 @@ function handleHelpQuery($request, $response, $pdo, $c) {
|
|||
],
|
||||
'links' => [
|
||||
[
|
||||
'href' => $c['rdap_url'] . '/help',
|
||||
'value' => $c['rdap_url'] . '/help',
|
||||
'rel' => 'self',
|
||||
'href' => $c['rdap_url'] . '/help',
|
||||
'type' => 'application/rdap+json',
|
||||
],
|
||||
[
|
||||
'href' => 'https://namingo.org',
|
||||
'value' => 'https://namingo.org',
|
||||
'rel' => 'related',
|
||||
'href' => 'https://namingo.org',
|
||||
'type' => 'application/rdap+json',
|
||||
]
|
||||
],
|
||||
|
|
|
@ -514,12 +514,15 @@ function handleDomainQuery($request, $response, $pdo, $domainName, $c, $log) {
|
|||
}
|
||||
|
||||
$abuseContactName = ($registrarAbuseDetails) ? $registrarAbuseDetails['first_name'] . ' ' . $registrarAbuseDetails['last_name'] : '';
|
||||
$rdapClean = rtrim(preg_replace('#^.*?//#', '', $registrarDetails['rdap_server'] ?? ''), '/');
|
||||
|
||||
// Construct the RDAP response in JSON format
|
||||
$rdapResponse = [
|
||||
'rdapConformance' => [
|
||||
'rdap_level_0',
|
||||
'icann_rdap_response_profile_0',
|
||||
'icann_rdap_response_profile_1',
|
||||
'icann_rdap_technical_implementation_guide_0',
|
||||
'icann_rdap_technical_implementation_guide_1',
|
||||
],
|
||||
'objectClassName' => 'domain',
|
||||
|
@ -575,20 +578,20 @@ function handleDomainQuery($request, $response, $pdo, $domainName, $c, $log) {
|
|||
],
|
||||
],
|
||||
],
|
||||
!$c['minimum_data'] ? [
|
||||
[
|
||||
mapContactToVCard($registrantDetails, 'registrant', $c)
|
||||
],
|
||||
array_map(function ($contact) use ($c) {
|
||||
return mapContactToVCard($contact, 'admin', $c);
|
||||
}, $adminDetails),
|
||||
array_map(function ($contact) use ($c) {
|
||||
return mapContactToVCard($contact, 'tech', $c);
|
||||
}, $techDetails),
|
||||
array_map(function ($contact) use ($c) {
|
||||
return mapContactToVCard($contact, 'billing', $c);
|
||||
}, $billingDetails)
|
||||
] : []
|
||||
!$c['minimum_data']
|
||||
? array_merge(
|
||||
[mapContactToVCard($registrantDetails, 'registrant', $c)],
|
||||
array_map(function ($contact) use ($c) {
|
||||
return mapContactToVCard($contact, 'administrative', $c);
|
||||
}, $adminDetails),
|
||||
array_map(function ($contact) use ($c) {
|
||||
return mapContactToVCard($contact, 'technical', $c);
|
||||
}, $techDetails),
|
||||
array_map(function ($contact) use ($c) {
|
||||
return mapContactToVCard($contact, 'billing', $c);
|
||||
}, $billingDetails)
|
||||
)
|
||||
: []
|
||||
),
|
||||
'events' => $events,
|
||||
'handle' => 'D' . $domainDetails['id'] . '-' . $c['roid'] . '',
|
||||
|
@ -601,8 +604,8 @@ function handleDomainQuery($request, $response, $pdo, $domainName, $c, $log) {
|
|||
'type' => 'application/rdap+json',
|
||||
],
|
||||
[
|
||||
'href' => $registrarDetails['rdap_server'] . 'domain/' . $domain,
|
||||
'value' => $registrarDetails['rdap_server'] . 'domain/' . $domain,
|
||||
'href' => 'https://' . $rdapClean . '/domain/' . $domain,
|
||||
'value' => 'https://' . $rdapClean . '/domain/' . $domain,
|
||||
'rel' => 'related',
|
||||
'type' => 'application/rdap+json',
|
||||
]
|
||||
|
@ -918,7 +921,7 @@ function handleEntityQuery($request, $response, $pdo, $entityHandle, $c, $log) {
|
|||
// Initialize an array to hold entity blocks
|
||||
$entityBlocks = [];
|
||||
// Define an array of allowed contact types
|
||||
$allowedTypes = ['owner', 'tech', 'abuse'];
|
||||
$allowedTypes = ['owner', 'billing', 'abuse'];
|
||||
|
||||
foreach ($contacts as $contact) {
|
||||
// Check if the contact type is one of the allowed types
|
||||
|
@ -929,14 +932,14 @@ function handleEntityQuery($request, $response, $pdo, $entityHandle, $c, $log) {
|
|||
// Create an entity block for each allowed contact type
|
||||
$entityBlock = [
|
||||
'objectClassName' => 'entity',
|
||||
'roles' => [$contact['type']],
|
||||
'roles' => [($contact['type'] === 'owner') ? 'administrative' : $contact['type']],
|
||||
"status" => ["active"],
|
||||
"vcardArray" => [
|
||||
"vcard",
|
||||
[
|
||||
['version', new stdClass(), 'text', '4.0'],
|
||||
["fn", new stdClass(), "text", $fullName],
|
||||
["tel", ["type" => ["voice"]], "uri", "tel:" . $contact['voice']],
|
||||
["tel", ["type" => ["voice"]], $contact['voice'] ? "uri" : "text", $contact['voice'] ? "tel:" . $contact['voice'] : ""],
|
||||
["email", new stdClass(), "text", $contact['email']]
|
||||
]
|
||||
],
|
||||
|
@ -951,7 +954,9 @@ function handleEntityQuery($request, $response, $pdo, $entityHandle, $c, $log) {
|
|||
$rdapResponse = [
|
||||
'rdapConformance' => [
|
||||
'rdap_level_0',
|
||||
'icann_rdap_response_profile_0',
|
||||
'icann_rdap_response_profile_1',
|
||||
'icann_rdap_technical_implementation_guide_0',
|
||||
'icann_rdap_technical_implementation_guide_1',
|
||||
],
|
||||
'objectClassName' => 'entity',
|
||||
|
@ -1129,11 +1134,11 @@ function handleNameserverQuery($request, $response, $pdo, $nameserverHandle, $c,
|
|||
}
|
||||
}
|
||||
|
||||
// Check for prohibited patterns in nameserver
|
||||
if (!preg_match('/^((xn--[a-zA-Z0-9-]{1,63}|[a-zA-Z0-9-]{1,63})\.){2,}(xn--[a-zA-Z0-9-]{2,63}|[a-zA-Z]{2,63})$/', $ns)) {
|
||||
// Validate nameserver
|
||||
if (!isValidHostname($ns)) {
|
||||
$response->header('Content-Type', 'application/json');
|
||||
$response->status(400); // Bad Request
|
||||
$response->end(json_encode(['error' => 'Nameserver invalid format']));
|
||||
$response->end(json_encode(['error' => 'Nameserver format is invalid. Expected a fully qualified domain name (FQDN), punycode supported (e.g., ns1.example.com)']));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1298,12 +1303,15 @@ function handleNameserverQuery($request, $response, $pdo, $nameserverHandle, $c,
|
|||
if (!empty($associated)) {
|
||||
$statuses[] = 'associated';
|
||||
}
|
||||
$statuses = array_unique(array_map(fn($s) => $s === 'ok' ? 'active' : $s, $statuses));
|
||||
|
||||
// Construct the RDAP response in JSON format
|
||||
$rdapResponse = [
|
||||
'rdapConformance' => [
|
||||
'rdap_level_0',
|
||||
'icann_rdap_response_profile_0',
|
||||
'icann_rdap_response_profile_1',
|
||||
'icann_rdap_technical_implementation_guide_0',
|
||||
'icann_rdap_technical_implementation_guide_1',
|
||||
],
|
||||
'objectClassName' => 'nameserver',
|
||||
|
@ -1366,8 +1374,9 @@ function handleNameserverQuery($request, $response, $pdo, $nameserverHandle, $c,
|
|||
'ldhName' => $hostDetails['name'],
|
||||
'links' => [
|
||||
[
|
||||
'href' => $c['rdap_url'] . '/nameserver/' . $hostDetails['name'],
|
||||
'value' => $c['rdap_url'] . '/nameserver/' . $hostDetails['name'],
|
||||
'rel' => 'self',
|
||||
'href' => $c['rdap_url'] . '/nameserver/' . $hostDetails['name'],
|
||||
'type' => 'application/rdap+json',
|
||||
]
|
||||
],
|
||||
|
@ -1855,7 +1864,9 @@ function handleDomainSearchQuery($request, $response, $pdo, $searchPattern, $c,
|
|||
$rdapResponse = [
|
||||
'rdapConformance' => [
|
||||
'rdap_level_0',
|
||||
'icann_rdap_response_profile_0',
|
||||
'icann_rdap_response_profile_1',
|
||||
'icann_rdap_technical_implementation_guide_0',
|
||||
'icann_rdap_technical_implementation_guide_1',
|
||||
],
|
||||
'domainSearchResults' => [
|
||||
|
@ -2117,14 +2128,14 @@ function handleNameserverSearchQuery($request, $response, $pdo, $searchPattern,
|
|||
}
|
||||
}
|
||||
|
||||
// Check for prohibited patterns in nameserver
|
||||
if (!preg_match('/^((xn--[a-zA-Z0-9-]{1,63}|[a-zA-Z0-9-]{1,63})\.){2,}(xn--[a-zA-Z0-9-]{2,63}|[a-zA-Z]{2,63})$/', $ns)) {
|
||||
// Validate nameserver
|
||||
if (!isValidHostname($ns)) {
|
||||
$response->header('Content-Type', 'application/json');
|
||||
$response->status(400); // Bad Request
|
||||
$response->end(json_encode(['error' => 'Nameserver invalid format']));
|
||||
$response->end(json_encode(['error' => 'Nameserver format is invalid. Expected a fully qualified domain name (FQDN), punycode supported (e.g., ns1.example.com)']));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Extract TLD from the domain
|
||||
$parts = explode('.', $ns);
|
||||
$tld = "." . end($parts);
|
||||
|
@ -2339,7 +2350,9 @@ function handleNameserverSearchQuery($request, $response, $pdo, $searchPattern,
|
|||
$rdapResponse = [
|
||||
'rdapConformance' => [
|
||||
'rdap_level_0',
|
||||
'icann_rdap_response_profile_0',
|
||||
'icann_rdap_response_profile_1',
|
||||
'icann_rdap_technical_implementation_guide_0',
|
||||
'icann_rdap_technical_implementation_guide_1',
|
||||
],
|
||||
'nameserverSearchResults' => $rdapResult,
|
||||
|
@ -2466,7 +2479,9 @@ function handleNameserverSearchQuery($request, $response, $pdo, $searchPattern,
|
|||
$rdapResponse = [
|
||||
'rdapConformance' => [
|
||||
'rdap_level_0',
|
||||
'icann_rdap_response_profile_0',
|
||||
'icann_rdap_response_profile_1',
|
||||
'icann_rdap_technical_implementation_guide_0',
|
||||
'icann_rdap_technical_implementation_guide_1',
|
||||
],
|
||||
'nameserverSearchResults' => [
|
||||
|
@ -2815,7 +2830,7 @@ function handleEntitySearchQuery($request, $response, $pdo, $searchPattern, $c,
|
|||
// Initialize an array to hold entity blocks
|
||||
$entityBlocks = [];
|
||||
// Define an array of allowed contact types
|
||||
$allowedTypes = ['owner', 'tech', 'abuse'];
|
||||
$allowedTypes = ['owner', 'billing', 'abuse'];
|
||||
|
||||
foreach ($contacts as $contact) {
|
||||
// Check if the contact type is one of the allowed types
|
||||
|
@ -2826,14 +2841,14 @@ function handleEntitySearchQuery($request, $response, $pdo, $searchPattern, $c,
|
|||
// Create an entity block for each allowed contact type
|
||||
$entityBlock = [
|
||||
'objectClassName' => 'entity',
|
||||
'roles' => [$contact['type']],
|
||||
'roles' => [($contact['type'] === 'owner') ? 'administrative' : $contact['type']],
|
||||
"status" => ["active"],
|
||||
"vcardArray" => [
|
||||
"vcard",
|
||||
[
|
||||
['version', new stdClass(), 'text', '4.0'],
|
||||
["fn", new stdClass(), "text", $fullName],
|
||||
["tel", ["type" => ["voice"]], "uri", "tel:" . $contact['voice']],
|
||||
["tel", ["type" => ["voice"]], $contact['voice'] ? "uri" : "text", $contact['voice'] ? "tel:" . $contact['voice'] : ""],
|
||||
["email", new stdClass(), "text", $contact['email']]
|
||||
]
|
||||
],
|
||||
|
@ -2848,7 +2863,9 @@ function handleEntitySearchQuery($request, $response, $pdo, $searchPattern, $c,
|
|||
$rdapResponse = [
|
||||
'rdapConformance' => [
|
||||
'rdap_level_0',
|
||||
'icann_rdap_response_profile_0',
|
||||
'icann_rdap_response_profile_1',
|
||||
'icann_rdap_technical_implementation_guide_0',
|
||||
'icann_rdap_technical_implementation_guide_1',
|
||||
],
|
||||
'entitySearchResults' => [
|
||||
|
@ -2993,9 +3010,11 @@ function handleEntitySearchQuery($request, $response, $pdo, $searchPattern, $c,
|
|||
function handleHelpQuery($request, $response, $pdo, $c) {
|
||||
// Set the RDAP conformance levels
|
||||
$rdapConformance = [
|
||||
"rdap_level_0",
|
||||
"icann_rdap_response_profile_1",
|
||||
"icann_rdap_technical_implementation_guide_1"
|
||||
'rdap_level_0',
|
||||
'icann_rdap_response_profile_0',
|
||||
'icann_rdap_response_profile_1',
|
||||
'icann_rdap_technical_implementation_guide_0',
|
||||
'icann_rdap_technical_implementation_guide_1',
|
||||
];
|
||||
|
||||
// Set the descriptions and links for the help section
|
||||
|
@ -3015,13 +3034,15 @@ function handleHelpQuery($request, $response, $pdo, $c) {
|
|||
],
|
||||
'links' => [
|
||||
[
|
||||
'href' => $c['rdap_url'] . '/help',
|
||||
'value' => $c['rdap_url'] . '/help',
|
||||
'rel' => 'self',
|
||||
'href' => $c['rdap_url'] . '/help',
|
||||
'type' => 'application/rdap+json',
|
||||
],
|
||||
[
|
||||
'href' => 'https://namingo.org',
|
||||
'value' => 'https://namingo.org',
|
||||
'rel' => 'related',
|
||||
'href' => 'https://namingo.org',
|
||||
'type' => 'application/rdap+json',
|
||||
]
|
||||
],
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue