diff --git a/epp/src/epp-create.php b/epp/src/epp-create.php index 5d8aca0..7ef39ca 100644 --- a/epp/src/epp-create.php +++ b/epp/src/epp-create.php @@ -575,12 +575,66 @@ function processDomainCreate($conn, $db, $xml, $clid, $database_type, $trans, $m $clTRID = (string) $xml->command->clTRID; $extensionNode = $xml->command->extension; + $launch_create = null; if (isset($extensionNode)) { $fee_create = $xml->xpath('//fee:create')[0] ?? null; $launch_create = $xml->xpath('//launch:create')[0] ?? null; $allocation_token = $xml->xpath('//allocationToken:allocationToken')[0] ?? null; } + if ($launch_create) { + $launch_phase = (string) $launch_create->xpath('launch:phase')[0] ?? null; + $smd_encodedSignedMark = $launch_create->xpath('smd:encodedSignedMark')[0] ?? null; + $launch_notice = $launch_create->xpath('launch:notice')[0] ?? null; + $launch_noticeID = $launch_notice ? (string) $launch_notice->xpath('launch:noticeID')[0] ?? null : null; + $launch_notAfter = $launch_notice ? (string) $launch_notice->xpath('launch:notAfter')[0] ?? null : null; + $launch_acceptedDate = $launch_notice ? (string) $launch_notice->xpath('launch:acceptedDate')[0] ?? null : null; + + // Validate and handle each specific case + if ($launch_phase === 'sunrise' && $smd_encodedSignedMark) { + // Parse and validate SMD encoded signed mark, then return unimplemented error + sendEppError($conn, $db, 2101, 'sunrise with encodedSignedMark', $clTRID, $trans); + return; + } elseif ($launch_phase === 'claims') { + // Check for missing notice elements and validate dates + if (!$launch_notice || !$launch_noticeID || !$launch_notAfter || !$launch_acceptedDate) { + sendEppError($conn, $db, 2003, 'Missing required elements in claims phase', $clTRID, $trans); + return; + } + + // Validate that acceptedDate is before notAfter + try { + $acceptedDate = DateTime::createFromFormat('Y-m-d\TH:i:s.u\Z', $launch_acceptedDate); + $notAfterDate = DateTime::createFromFormat('Y-m-d\TH:i:s.u\Z', $launch_notAfter); + + if (!$acceptedDate || !$notAfterDate) { + sendEppError($conn, $db, 2003, 'Invalid date format', $clTRID, $trans); + return; + } + + if ($acceptedDate >= $notAfterDate) { + sendEppError($conn, $db, 2003, 'Invalid dates: acceptedDate must be before notAfter', $clTRID, $trans); + return; + } + } catch (Exception $e) { + sendEppError($conn, $db, 2003, 'Invalid date format', $clTRID, $trans); + return; + } + + // If all validations pass, return unimplemented error + sendEppError($conn, $db, 2101, 'claims with notice', $clTRID, $trans); + return; + } elseif ($launch_phase === 'landrush') { + // Parse phase and type attributes, then return unimplemented error + sendEppError($conn, $db, 2101, 'landrush', $clTRID, $trans); + return; + } else { + // Mixed or unsupported form + sendEppError($conn, $db, 2101, 'unsupported or mixed form', $clTRID, $trans); + return; + } + } + $parts = extractDomainAndTLD($domainName); $label = $parts['domain']; $domain_extension = $parts['tld']; diff --git a/epp/src/epp-update.php b/epp/src/epp-update.php index d81d871..851afbc 100644 --- a/epp/src/epp-update.php +++ b/epp/src/epp-update.php @@ -928,6 +928,8 @@ function processDomainUpdate($conn, $db, $xml, $clid, $database_type, $trans) { $domainAdd = $xml->xpath('//domain:add')[0] ?? null; $domainChg = $xml->xpath('//domain:chg')[0] ?? null; $extensionNode = $xml->command->extension; + $launch_update = null; + if (isset($extensionNode)) { $rgp_update = $xml->xpath('//rgp:update')[0] ?? null; $secdns_update = $xml->xpath('//secDNS:update')[0] ?? null; @@ -965,6 +967,40 @@ function processDomainUpdate($conn, $db, $xml, $clid, $database_type, $trans) { } $domain_id = $row['id']; + + // Check if launch extension is enabled in database settings + $stmt = $db->prepare("SELECT value FROM settings WHERE name = 'launch_phases' LIMIT 1"); + $stmt->execute(); + $launch_extension_enabled = $stmt->fetchColumn(); + + if ($launch_extension_enabled && isset($launch_update)) { + $phase = (string) $launch_update->xpath('launch:phase')[0]; + $applicationID = (string) $launch_update->xpath('launch:applicationID')[0]; + + if (!$phase || !$applicationID) { + sendEppError($conn, $db, 2003, 'Launch phase or applicationID is missing', $clTRID, $trans); + return; + } + + // Validate the phase and application ID in the appropriate table + if ($phase === 'sunrise') { + $stmt = $db->prepare("SELECT COUNT(*) FROM application WHERE id = ? AND phase_type = ? AND application_id = ?"); + $stmt->execute([$domain_id, $phase, $applicationID]); + } elseif (in_array($phase, ['landrush', 'custom', 'claims'])) { + $stmt = $db->prepare("SELECT COUNT(*) FROM domain WHERE id = ? AND phase_name = ?"); + $stmt->execute([$domain_id, $phase]); + } else { + sendEppError($conn, $db, 2003, 'Unsupported phase name', $clTRID, $trans); + return; + } + + $launch_valid = $stmt->fetchColumn(); + + if (!$launch_valid) { + sendEppError($conn, $db, 2304, 'Invalid launch phase or applicationID for this domain', $clTRID, $trans); + return; + } + } $stmt = $db->prepare("SELECT status FROM domain_status WHERE domain_id = ?"); $stmt->execute([$row['id']]);