mirror of
https://github.com/getnamingo/registry.git
synced 2025-05-17 18:09:22 +02:00
Application create is possible via EPP too
This commit is contained in:
parent
f2326a92e0
commit
c5b2783fbf
3 changed files with 629 additions and 343 deletions
|
@ -9,6 +9,7 @@
|
||||||
"namingo/rately": "^0.1.0",
|
"namingo/rately": "^0.1.0",
|
||||||
"moneyphp/money": "^4.6",
|
"moneyphp/money": "^4.6",
|
||||||
"phpmailer/phpmailer": "^6.9",
|
"phpmailer/phpmailer": "^6.9",
|
||||||
"filips123/monolog-phpmailer": "^2.0"
|
"filips123/monolog-phpmailer": "^2.0",
|
||||||
|
"ramsey/uuid": "^4.7"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -633,6 +633,8 @@ function processDomainCreate($conn, $db, $xml, $clid, $database_type, $trans, $m
|
||||||
// If all validations pass, continue
|
// If all validations pass, continue
|
||||||
} elseif ($launch_phase === 'landrush') {
|
} elseif ($launch_phase === 'landrush') {
|
||||||
// Continue
|
// Continue
|
||||||
|
} elseif ($launch_phase === 'custom') {
|
||||||
|
// Continue
|
||||||
} else {
|
} else {
|
||||||
// Mixed or unsupported form
|
// Mixed or unsupported form
|
||||||
sendEppError($conn, $db, 2101, 'unsupported launch phase or mixed form', $clTRID, $trans);
|
sendEppError($conn, $db, 2101, 'unsupported launch phase or mixed form', $clTRID, $trans);
|
||||||
|
@ -669,11 +671,8 @@ function processDomainCreate($conn, $db, $xml, $clid, $database_type, $trans, $m
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($launch_extension_enabled && isset($launch_create)) {
|
$launch_phases = $db->query("SELECT value FROM settings WHERE name = 'launch_phases' LIMIT 1")->fetchColumn();
|
||||||
$stmt = $db->prepare("SELECT value FROM settings WHERE name = 'launch_phases' LIMIT 1");
|
if ($launch_phases) {
|
||||||
$stmt->execute();
|
|
||||||
$launch_phases = $stmt->fetchColumn();
|
|
||||||
|
|
||||||
$currentDateTime = new \DateTime();
|
$currentDateTime = new \DateTime();
|
||||||
$currentDate = $currentDateTime->format('Y-m-d H:i:s.v'); // Current timestamp
|
$currentDate = $currentDateTime->format('Y-m-d H:i:s.v'); // Current timestamp
|
||||||
|
|
||||||
|
@ -689,7 +688,29 @@ function processDomainCreate($conn, $db, $xml, $clid, $database_type, $trans, $m
|
||||||
$phase_details = $stmt->fetchColumn();
|
$phase_details = $stmt->fetchColumn();
|
||||||
|
|
||||||
// Check if the phase requires application submission
|
// Check if the phase requires application submission
|
||||||
if ($phase_details && $phase_details === 'Application') {
|
if (empty($launch_phase) && $launch_phase !== 'custom' && $phase_details === 'Application') {
|
||||||
|
sendEppError($conn, $db, 2304, 'Domain registration is not allowed for this TLD. You must submit a new application instead.', $clTRID, $trans);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($launch_extension_enabled && isset($launch_create)) {
|
||||||
|
$currentDateTime = new \DateTime();
|
||||||
|
$currentDate = $currentDateTime->format('Y-m-d H:i:s.v'); // Current timestamp
|
||||||
|
|
||||||
|
$stmt = $db->prepare("
|
||||||
|
SELECT phase_category
|
||||||
|
FROM launch_phases
|
||||||
|
WHERE tld_id = ?
|
||||||
|
AND start_date <= ?
|
||||||
|
AND (end_date >= ? OR end_date IS NULL OR end_date = '')
|
||||||
|
LIMIT 1
|
||||||
|
");
|
||||||
|
$stmt->execute([$tld_id, $currentDate, $currentDate]);
|
||||||
|
$phase_details = $stmt->fetchColumn();
|
||||||
|
|
||||||
|
// Check if the phase requires application submission
|
||||||
|
if (empty($launch_phase) && $launch_phase !== 'custom' && $phase_details === 'Application') {
|
||||||
sendEppError($conn, $db, 2304, 'Domain registration is not allowed for this TLD. You must submit a new application instead.', $clTRID, $trans);
|
sendEppError($conn, $db, 2304, 'Domain registration is not allowed for this TLD. You must submit a new application instead.', $clTRID, $trans);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1253,6 +1274,252 @@ function processDomainCreate($conn, $db, $xml, $clid, $database_type, $trans, $m
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isset($phase_details) && $phase_details === 'Application') {
|
||||||
|
try {
|
||||||
|
$db->beginTransaction();
|
||||||
|
|
||||||
|
$currentDateTime = new \DateTime();
|
||||||
|
$crdate = $currentDateTime->format('Y-m-d H:i:s.v'); // Current timestamp
|
||||||
|
|
||||||
|
$response = [];
|
||||||
|
$domainSql = "INSERT INTO application (
|
||||||
|
name, tldid, registrant, crdate, clid, crid, authtype, authinfo, tm_phase, phase_type
|
||||||
|
) VALUES (
|
||||||
|
:name, :tldid, :registrant, :crdate, :clid, :crid, :authtype, :authinfo, :tm_phase, :phase_type
|
||||||
|
)";
|
||||||
|
|
||||||
|
$domainStmt = $db->prepare($domainSql);
|
||||||
|
$domainStmt->execute([
|
||||||
|
':name' => $domainName,
|
||||||
|
':tldid' => $tld_id,
|
||||||
|
':registrant' => $registrant_id,
|
||||||
|
':crdate' => $crdate,
|
||||||
|
':clid' => $clid,
|
||||||
|
':crid' => $clid,
|
||||||
|
':authtype' => 'pw',
|
||||||
|
':authinfo' => $authInfo_pw ?? null,
|
||||||
|
':tm_phase' => $launch_phase_name ?? null,
|
||||||
|
':phase_type' => $launch_phase ?? null,
|
||||||
|
]);
|
||||||
|
$domain_id = $db->lastInsertId();
|
||||||
|
$uuid = createUuidFromId($domain_id);
|
||||||
|
|
||||||
|
// Update application_id in the application table
|
||||||
|
$updateStmt = $db->prepare("UPDATE application SET application_id = :uuid WHERE id = :domain_id");
|
||||||
|
$updateStmt->execute([
|
||||||
|
':uuid' => $uuid,
|
||||||
|
':domain_id' => $domain_id
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Insert into application_status table
|
||||||
|
$insertStmt = $db->prepare("INSERT INTO application_status (domain_id, status) VALUES (:domain_id, :status)");
|
||||||
|
$insertStmt->execute([
|
||||||
|
':domain_id' => $domain_id,
|
||||||
|
':status' => 'pendingValidation'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$updateRegistrarStmt = $db->prepare("UPDATE registrar SET accountBalance = (accountBalance - :price) WHERE id = :registrar_id");
|
||||||
|
$updateRegistrarStmt->execute([
|
||||||
|
':price' => $price,
|
||||||
|
':registrar_id' => $clid
|
||||||
|
]);
|
||||||
|
|
||||||
|
$paymentHistoryStmt = $db->prepare("INSERT INTO payment_history (registrar_id,date,description,amount) VALUES(:registrar_id,CURRENT_TIMESTAMP(3),:description,:amount)");
|
||||||
|
$paymentHistoryStmt->execute([
|
||||||
|
':registrar_id' => $clid,
|
||||||
|
':description' => "create application $domainName for period $date_add MONTH",
|
||||||
|
':amount' => "-$price"
|
||||||
|
]);
|
||||||
|
|
||||||
|
$selectDomainDatesStmt = $db->prepare("SELECT crdate,exdate FROM application WHERE name = :name LIMIT 1");
|
||||||
|
$selectDomainDatesStmt->execute([':name' => $domainName]);
|
||||||
|
[$from, $to] = $selectDomainDatesStmt->fetch(PDO::FETCH_NUM);
|
||||||
|
|
||||||
|
$statementStmt = $db->prepare("INSERT INTO statement (registrar_id,date,command,domain_name,length_in_months,fromS,toS,amount) VALUES(:registrar_id,CURRENT_TIMESTAMP(3),:cmd,:name,:date_add,:from,:to,:price)");
|
||||||
|
$statementStmt->execute([
|
||||||
|
':registrar_id' => $clid,
|
||||||
|
':cmd' => 'create',
|
||||||
|
':name' => $domainName,
|
||||||
|
':date_add' => $date_add,
|
||||||
|
':from' => $from,
|
||||||
|
':to' => $from,
|
||||||
|
':price' => $price
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (!empty($hostObj_list) && is_array($hostObj_list)) {
|
||||||
|
foreach ($hostObj_list as $node) {
|
||||||
|
$hostObj = strtoupper((string)$node);
|
||||||
|
|
||||||
|
$hostExistStmt = $db->prepare("SELECT id FROM host WHERE name = :hostObj LIMIT 1");
|
||||||
|
$hostExistStmt->execute([':hostObj' => $hostObj]);
|
||||||
|
$hostObj_already_exist = $hostExistStmt->fetchColumn();
|
||||||
|
|
||||||
|
if ($hostObj_already_exist) {
|
||||||
|
$domainHostMapStmt = $db->prepare("SELECT domain_id FROM application_host_map WHERE domain_id = :domain_id AND host_id = :host_id LIMIT 1");
|
||||||
|
$domainHostMapStmt->execute([':domain_id' => $domain_id, ':host_id' => $hostObj_already_exist]);
|
||||||
|
$domain_host_map_id = $domainHostMapStmt->fetchColumn();
|
||||||
|
|
||||||
|
if (!$domain_host_map_id) {
|
||||||
|
$insertDomainHostMapStmt = $db->prepare("INSERT INTO application_host_map (domain_id,host_id) VALUES(:domain_id,:host_id)");
|
||||||
|
$insertDomainHostMapStmt->execute([':domain_id' => $domain_id, ':host_id' => $hostObj_already_exist]);
|
||||||
|
} else {
|
||||||
|
$errorLogStmt = $db->prepare("INSERT INTO error_log
|
||||||
|
(channel, level, level_name, message, context, extra, created_at)
|
||||||
|
VALUES ('epp', 3, 'warning', :log, :context, '{}', CURRENT_TIMESTAMP)");
|
||||||
|
$errorLogStmt->execute([
|
||||||
|
':log' => "Domain: $domainName; hostObj: $hostObj - is duplicated",
|
||||||
|
':context' => json_encode(['registrar_id' => $clid, 'domain' => $domainName, 'host' => $hostObj])
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$internal_host = false;
|
||||||
|
$stmt = $db->prepare("SELECT tld FROM domain_tld");
|
||||||
|
$stmt->execute();
|
||||||
|
|
||||||
|
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||||
|
$tld = strtoupper($row['tld']);
|
||||||
|
$tld = str_replace('.', '\\.', $tld); // Escape the dot for regex pattern matching
|
||||||
|
if (preg_match("/$tld$/i", $hostObj)) {
|
||||||
|
$internal_host = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$stmt->closeCursor();
|
||||||
|
|
||||||
|
if ($internal_host) {
|
||||||
|
if (preg_match("/\.$domainName$/i", $hostObj)) {
|
||||||
|
$stmt = $db->prepare("INSERT INTO host (name,domain_id,clid,crid,crdate) VALUES(?, ?, ?, ?, CURRENT_TIMESTAMP(3))");
|
||||||
|
$stmt->execute([$hostObj, $domain_id, $clid, $clid]);
|
||||||
|
$host_id = $db->lastInsertId();
|
||||||
|
|
||||||
|
$stmt = $db->prepare("INSERT INTO application_host_map (domain_id,host_id) VALUES(?, ?)");
|
||||||
|
$stmt->execute([$domain_id, $host_id]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$stmt = $db->prepare("INSERT INTO host (name,clid,crid,crdate) VALUES(?, ?, ?, CURRENT_TIMESTAMP(3))");
|
||||||
|
$stmt->execute([$hostObj, $clid, $clid]);
|
||||||
|
$host_id = $db->lastInsertId();
|
||||||
|
|
||||||
|
$stmt = $db->prepare("INSERT INTO application_host_map (domain_id,host_id) VALUES(?, ?)");
|
||||||
|
$stmt->execute([$domain_id, $host_id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($hostAttr_list) && is_array($hostAttr_list)) {
|
||||||
|
foreach ($hostAttr_list as $node) {
|
||||||
|
// Extract the hostName
|
||||||
|
$hostName = strtoupper((string)$node->xpath('./domain:hostName')[0] ?? '');
|
||||||
|
if (empty($hostName)) {
|
||||||
|
continue; // Skip if no hostName found
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the host already exists
|
||||||
|
$stmt = $db->prepare("SELECT id FROM host WHERE name = ? LIMIT 1");
|
||||||
|
$stmt->execute([$hostName]);
|
||||||
|
$hostName_already_exist = $stmt->fetchColumn();
|
||||||
|
|
||||||
|
if ($hostName_already_exist) {
|
||||||
|
// Check if the host is already mapped to this domain
|
||||||
|
$stmt = $db->prepare("SELECT domain_id FROM application_host_map WHERE domain_id = ? AND host_id = ? LIMIT 1");
|
||||||
|
$stmt->execute([$domain_id, $hostName_already_exist]);
|
||||||
|
$domain_host_map_id = $stmt->fetchColumn();
|
||||||
|
|
||||||
|
if (!$domain_host_map_id) {
|
||||||
|
// Map the host to the domain
|
||||||
|
$stmt = $db->prepare("INSERT INTO application_host_map (domain_id,host_id) VALUES (?, ?)");
|
||||||
|
$stmt->execute([$domain_id, $hostName_already_exist]);
|
||||||
|
} else {
|
||||||
|
// Log duplicate mapping error
|
||||||
|
$stmt = $db->prepare("INSERT INTO error_log
|
||||||
|
(channel, level, level_name, message, context, extra, created_at)
|
||||||
|
VALUES ('epp', 3, 'warning', ?, ?, '{}', CURRENT_TIMESTAMP)");
|
||||||
|
$stmt->execute([
|
||||||
|
"Domain: $domainName; hostName: $hostName - duplicate mapping",
|
||||||
|
json_encode(['registrar_id' => $clid, 'domain' => $domainName, 'host' => $hostName])
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Insert a new host
|
||||||
|
$stmt = $db->prepare("INSERT INTO host (name, domain_id, clid, crid, crdate) VALUES (?, ?, ?, ?, CURRENT_TIMESTAMP(3))");
|
||||||
|
$stmt->execute([$hostName, $domain_id, $clid, $clid]);
|
||||||
|
$host_id = $db->lastInsertId();
|
||||||
|
|
||||||
|
// Map the new host to the domain
|
||||||
|
$stmt = $db->prepare("INSERT INTO application_host_map (domain_id, host_id) VALUES (?, ?)");
|
||||||
|
$stmt->execute([$domain_id, $host_id]);
|
||||||
|
|
||||||
|
// Process and insert host addresses
|
||||||
|
foreach ($node->xpath('./domain:hostAddr') as $nodeAddr) {
|
||||||
|
$hostAddr = (string)$nodeAddr;
|
||||||
|
$addr_type = (string)($nodeAddr->attributes()->ip ?? 'v4');
|
||||||
|
|
||||||
|
// Normalize the address
|
||||||
|
if ($addr_type === 'v6') {
|
||||||
|
$hostAddr = normalize_v6_address($hostAddr);
|
||||||
|
} else {
|
||||||
|
$hostAddr = normalize_v4_address($hostAddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert the address into host_addr table
|
||||||
|
$stmt = $db->prepare("INSERT INTO host_addr (host_id, addr, ip) VALUES (?, ?, ?)");
|
||||||
|
$stmt->execute([$host_id, $hostAddr, $addr_type]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$contact_admin_list = $xml->xpath("//domain:contact[@type='admin']");
|
||||||
|
$contact_billing_list = $xml->xpath("//domain:contact[@type='billing']");
|
||||||
|
$contact_tech_list = $xml->xpath("//domain:contact[@type='tech']");
|
||||||
|
|
||||||
|
$contactTypes = [
|
||||||
|
'admin' => $contact_admin_list,
|
||||||
|
'billing' => $contact_billing_list,
|
||||||
|
'tech' => $contact_tech_list
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($contactTypes as $type => $contact_list) {
|
||||||
|
foreach ($contact_list as $element) {
|
||||||
|
$contact = (string)$element;
|
||||||
|
$stmt = $db->prepare("SELECT id FROM contact WHERE identifier = ? LIMIT 1");
|
||||||
|
$stmt->execute([$contact]);
|
||||||
|
$contact_id = $stmt->fetchColumn();
|
||||||
|
|
||||||
|
$stmt = $db->prepare("INSERT INTO application_contact_map (domain_id,contact_id,type) VALUES(?,?,?)");
|
||||||
|
$stmt->execute([$domain_id, $contact_id, $type]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmt = $db->prepare("SELECT crdate,exdate FROM domain WHERE name = ? LIMIT 1");
|
||||||
|
$stmt->execute([$domainName]);
|
||||||
|
[$crdate, $exdate] = $stmt->fetch(PDO::FETCH_NUM);
|
||||||
|
|
||||||
|
$db->commit();
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$db->rollBack();
|
||||||
|
|
||||||
|
sendEppError($conn, $db, 2400, "Database failure: " . $e->getMessage(), $clTRID, $trans);
|
||||||
|
}
|
||||||
|
$svTRID = generateSvTRID();
|
||||||
|
$response['command'] = 'create_domain';
|
||||||
|
$response['resultCode'] = 1000;
|
||||||
|
$response['lang'] = 'en-US';
|
||||||
|
$response['message'] = 'Command completed successfully';
|
||||||
|
$response['name'] = $domainName;
|
||||||
|
$response['crDate'] = $crdate;
|
||||||
|
$response['exDate'] = null;
|
||||||
|
$response['clTRID'] = $clTRID;
|
||||||
|
$response['svTRID'] = $svTRID;
|
||||||
|
|
||||||
|
$epp = new EPP\EppWriter();
|
||||||
|
$xml = $epp->epp_writer($response);
|
||||||
|
updateTransaction($db, 'create', 'domain', $domainName, 1000, 'Command completed successfully', $svTRID, $xml, $trans);
|
||||||
|
sendEppResponse($conn, $xml);
|
||||||
|
} else {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$db->beginTransaction();
|
$db->beginTransaction();
|
||||||
|
|
||||||
|
@ -1630,4 +1897,5 @@ function processDomainCreate($conn, $db, $xml, $clid, $database_type, $trans, $m
|
||||||
$xml = $epp->epp_writer($response);
|
$xml = $epp->epp_writer($response);
|
||||||
updateTransaction($db, 'create', 'domain', $domainName, 1000, 'Command completed successfully', $svTRID, $xml, $trans);
|
updateTransaction($db, 'create', 'domain', $domainName, 1000, 'Command completed successfully', $svTRID, $xml, $trans);
|
||||||
sendEppResponse($conn, $xml);
|
sendEppResponse($conn, $xml);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -23,6 +23,9 @@ use Money\Currency;
|
||||||
use Money\Converter;
|
use Money\Converter;
|
||||||
use Money\Currencies\ISOCurrencies;
|
use Money\Currencies\ISOCurrencies;
|
||||||
use Money\Exchange\FixedExchange;
|
use Money\Exchange\FixedExchange;
|
||||||
|
use Ramsey\Uuid\Uuid;
|
||||||
|
use Ramsey\Uuid\Guid\Guid;
|
||||||
|
use Ramsey\Uuid\Exception\UnsatisfiedDependencyException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets up and returns a Logger instance.
|
* Sets up and returns a Logger instance.
|
||||||
|
@ -859,6 +862,20 @@ function formatMoney(Money $money) {
|
||||||
return number_format($money->getAmount() / 100, 2, '.', '');
|
return number_format($money->getAmount() / 100, 2, '.', '');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createUuidFromId($id) {
|
||||||
|
// Define a namespace UUID; this should be a UUID that is unique to your application
|
||||||
|
$namespace = '123e4567-e89b-12d3-a456-426614174000';
|
||||||
|
|
||||||
|
// Generate a UUIDv5 based on the namespace and a name (in this case, the $id)
|
||||||
|
try {
|
||||||
|
$uuid5 = Uuid::uuid5($namespace, (string)$id);
|
||||||
|
return $uuid5->toString();
|
||||||
|
} catch (UnsatisfiedDependencyException $e) {
|
||||||
|
// Handle exception
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch a single value from the database using PDO.
|
* Fetch a single value from the database using PDO.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue