diff --git a/apis/commands/opensrs_domains_dnssec.php b/apis/commands/opensrs_domains_dnssec.php
new file mode 100644
index 0000000..ef1beb7
--- /dev/null
+++ b/apis/commands/opensrs_domains_dnssec.php
@@ -0,0 +1,77 @@
+ 'dnssec'.
+ *
+ * @copyright Copyright (c) 2021, Phillips Data, Inc.
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @package opensrs.commands
+ */
+class OpensrsDomainsDnssec
+{
+ /**
+ * @var OpensrsApi
+ */
+ private $api;
+
+ /**
+ * Sets the API to use for communication
+ *
+ * @param OpensrsApi $api The API to use for communication
+ */
+ public function __construct(OpensrsApi $api)
+ {
+ $this->api = $api;
+ }
+
+ /**
+ * Gets the DNSSEC DS records for a domain.
+ *
+ * @param array $vars An array of input params including:
+ * - domain The domain name
+ * @return OpensrsResponse The response object
+ */
+ public function getDnssecRecords(array $vars) : OpensrsResponse
+ {
+ return $this->api->submit('get', array_merge($vars, [
+ 'type' => 'dnssec'
+ ]));
+ }
+
+ /**
+ * Adds a DNSSEC DS record to a domain.
+ *
+ * @param array $vars An array of input params including:
+ * - domain The domain name
+ * - dnssec Array of DS records, each containing:
+ * - key_tag The key tag
+ * - algorithm The algorithm number
+ * - digest_type The digest type
+ * - digest The digest value
+ * @return OpensrsResponse The response object
+ */
+ public function addDnssecRecord(array $vars) : OpensrsResponse
+ {
+ return $this->api->submit('modify', array_merge($vars, [
+ 'data' => 'dnssec',
+ 'affect_domains' => '0'
+ ]));
+ }
+
+ /**
+ * Removes DNSSEC DS records from a domain.
+ *
+ * @param array $vars An array of input params including:
+ * - domain The domain name
+ * - dnssec Empty array to clear all DS records
+ * @return OpensrsResponse The response object
+ */
+ public function removeDnssecRecord(array $vars) : OpensrsResponse
+ {
+ return $this->api->submit('modify', array_merge($vars, [
+ 'data' => 'dnssec',
+ 'affect_domains' => '0'
+ ]));
+ }
+}
diff --git a/apis/commands/opensrs_domains_forwarding.php b/apis/commands/opensrs_domains_forwarding.php
new file mode 100644
index 0000000..d07efc7
--- /dev/null
+++ b/apis/commands/opensrs_domains_forwarding.php
@@ -0,0 +1,80 @@
+api = $api;
+ }
+
+ /**
+ * Gets domain forwarding settings for the specified domain.
+ *
+ * @param array $vars An array of input params including:
+ * - domain The domain name
+ * @return OpensrsResponse The response object
+ */
+ public function getDomainForwarding(array $vars) : OpensrsResponse
+ {
+ return $this->api->submit('get', array_merge($vars, ['type' => 'forwarding_email']));
+ }
+
+ /**
+ * Sets URL forwarding for the specified domain.
+ *
+ * @param array $vars An array of input params including:
+ * - domain The domain name
+ * - forwarding_uri The destination URL
+ * @return OpensrsResponse The response object
+ */
+ public function setDomainForwarding(array $vars) : OpensrsResponse
+ {
+ return $this->api->submit('modify', array_merge($vars, [
+ 'data' => 'forwarding_email',
+ 'affect_domains' => '0'
+ ]));
+ }
+
+ /**
+ * Creates URL forwarding for the specified domain via DNS zone.
+ *
+ * @param array $vars An array of input params including:
+ * - source The source subdomain or @ for root
+ * - destination The destination URL
+ * - type The redirect type (301, 302, or frame)
+ * - domain The domain name
+ * @return OpensrsResponse The response object
+ */
+ public function createDomainForwarding(array $vars) : OpensrsResponse
+ {
+ return $this->api->submit('set_dns_zone', $vars);
+ }
+
+ /**
+ * Deletes URL forwarding for the specified domain.
+ *
+ * @param array $vars An array of input params including:
+ * - domain The domain name
+ * @return OpensrsResponse The response object
+ */
+ public function deleteDomainForwarding(array $vars) : OpensrsResponse
+ {
+ return $this->api->submit('set_dns_zone', $vars);
+ }
+}
diff --git a/apis/opensrs_api.php b/apis/opensrs_api.php
index 246d36b..d536b26 100644
--- a/apis/opensrs_api.php
+++ b/apis/opensrs_api.php
@@ -9,6 +9,10 @@
. DIRECTORY_SEPARATOR . 'opensrs_domains_provisioning.php';
require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'commands'
. DIRECTORY_SEPARATOR . 'opensrs_domains_transfer.php';
+require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'commands'
+ . DIRECTORY_SEPARATOR . 'opensrs_domains_forwarding.php';
+require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'commands'
+ . DIRECTORY_SEPARATOR . 'opensrs_domains_dnssec.php';
require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'commands' . DIRECTORY_SEPARATOR . 'opensrs_ssl.php';
require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'commands' . DIRECTORY_SEPARATOR . 'opensrs_users.php';
@@ -44,6 +48,11 @@ class OpensrsApi
*/
private $sandbox;
+ /**
+ * @var mixed The logger instance
+ */
+ private $logger;
+
/**
* @var array An array representing the last request made
*/
@@ -87,11 +96,11 @@ public function submit(string $command, array $args = [], string $object = 'doma
}
// Build signature
- $siganture = md5($xml_request . $this->key);
+ $signature = md5($xml_request . $this->key);
$headers = [
'Content-Type: text/xml',
'X-Username: ' . trim($this->username),
- 'X-Signature: ' . md5($siganture . $this->key),
+ 'X-Signature: ' . md5($signature . $this->key),
'Content-Length: ' . strlen($xml_request)
];
@@ -109,6 +118,8 @@ public function submit(string $command, array $args = [], string $object = 'doma
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml_request);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
+ curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 60);
if (Configure::get('Blesta.curl_verify_ssl')) {
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
@@ -120,8 +131,11 @@ public function submit(string $command, array $args = [], string $object = 'doma
$response = curl_exec($ch);
- if ($response == false) {
+ if ($response === false) {
$this->logger->error(curl_error($ch));
+ curl_close($ch);
+
+ return new OpensrsResponse('');
}
curl_close($ch);
@@ -182,11 +196,11 @@ private function buildRecursiveAttributes(SimpleXMLElement &$dt_assoc, array $ar
if (is_array($value)) {
$assoc = $dt_assoc->addChild('item');
$assoc->addAttribute('key', $key);
- $assoc = $assoc->addChild(isset($value[0]) ? 'dt_array' : 'dt_assoc');
+ $assoc = $assoc->addChild((empty($value) || isset($value[0])) ? 'dt_array' : 'dt_assoc');
$this->buildRecursiveAttributes($assoc, $value);
} else {
- $dt_assoc->addChild('item', $value)
+ $dt_assoc->addChild('item', htmlspecialchars((string) $value, ENT_XML1, 'UTF-8'))
->addAttribute('key', $key);
}
}
diff --git a/apis/opensrs_response.php b/apis/opensrs_response.php
index f89293d..9b89d24 100755
--- a/apis/opensrs_response.php
+++ b/apis/opensrs_response.php
@@ -53,13 +53,13 @@ public function response() : ?object
*
* @return string The status (OK = success, ERROR = error, null = invalid responses)
*/
- public function status() : ?string
+ public function status() : string
{
if ($this->xml && $this->xml instanceof SimpleXMLElement) {
return ($this->formatResponse($this->xml->body->data_block)->is_success ?? false) ? 'OK' : 'ERROR';
}
- return null;
+ return 'ERROR';
}
/**
@@ -70,18 +70,32 @@ public function status() : ?string
public function errors() : ?object
{
if ($this->xml && $this->xml instanceof SimpleXMLElement) {
- $error = 'Internal Server Error';
+ $data = $this->formatResponse($this->xml->body->data_block);
+
+ $error_msg = $data->attributes['error']
+ ?? $data->response_text
+ ?? 'Internal Server Error';
+
+ // Extract detailed per-domain error messages from attributes.details
+ $details = [];
+ if (isset($data->attributes['details']) && is_array($data->attributes['details'])) {
+ foreach ($data->attributes['details'] as $domain => $info) {
+ if (is_array($info) && !empty($info['response_text'])) {
+ $details[] = trim($info['response_text']);
+ }
+ }
+ }
- $error_msg = $this->formatResponse($this->xml->body->data_block)->attributes['error']
- ?? $this->formatResponse($this->xml->body->data_block)->response_text
- ?? $error;
+ if (!empty($details)) {
+ $error_msg = implode('; ', $details);
+ }
return (object)[
'response_text' => $error_msg,
- 'response_code' => $this->formatResponse($this->xml->body->data_block)->response_code ?? 500
+ 'response_code' => $data->response_code ?? 500
];
}
-
+
return null;
}
@@ -92,7 +106,7 @@ public function errors() : ?object
*/
public function raw() : string
{
- return $this->raw;
+ return $this->raw ?? '';
}
/**
diff --git a/config/opensrs.php b/config/opensrs.php
index c8a348e..8153c1a 100755
--- a/config/opensrs.php
+++ b/config/opensrs.php
@@ -1,4 +1,256 @@
"Afghanistan",
+"AX" => "Åland Islands",
+"AL" => "Albania",
+"DZ" => "Algeria",
+"AS" => "American Samoa",
+"AD" => "Andorra",
+"AO" => "Angola",
+"AI" => "Anguilla",
+"AQ" => "Antarctica",
+"AG" => "Antigua and Barbuda",
+"AR" => "Argentina",
+"AM" => "Armenia",
+"AW" => "Aruba",
+"AU" => "Australia",
+"AT" => "Austria",
+"AZ" => "Azerbaijan",
+"BS" => "Bahamas",
+"BH" => "Bahrain",
+"BD" => "Bangladesh",
+"BB" => "Barbados",
+"BY" => "Belarus",
+"BE" => "Belgium",
+"BZ" => "Belize",
+"BJ" => "Benin",
+"BM" => "Bermuda",
+"BT" => "Bhutan",
+"BO" => "Bolivia, Plurinational State of",
+"BQ" => "Bonaire, Sint Eustatius and Saba",
+"BA" => "Bosnia and Herzegovina",
+"BW" => "Botswana",
+"BV" => "Bouvet Island",
+"BR" => "Brazil",
+"IO" => "British Indian Ocean Territory",
+"BN" => "Brunei Darussalam",
+"BG" => "Bulgaria",
+"BF" => "Burkina Faso",
+"BI" => "Burundi",
+"CV" => "Cabo Verde",
+"KH" => "Cambodia",
+"CM" => "Cameroon",
+"CA" => "Canada",
+"KY" => "Cayman Islands",
+"CF" => "Central African Republic",
+"TD" => "Chad",
+"CL" => "Chile",
+"CN" => "China",
+"CX" => "Christmas Island",
+"CC" => "Cocos (Keeling) Islands",
+"CO" => "Colombia",
+"KM" => "Comoros",
+"CG" => "Congo",
+"CD" => "Congo, Democratic Republic of the",
+"CK" => "Cook Islands",
+"CR" => "Costa Rica",
+"CI" => "Côte d'Ivoire",
+"HR" => "Croatia",
+"CU" => "Cuba",
+"CW" => "Curaçao",
+"CY" => "Cyprus",
+"CZ" => "Czechia",
+"DK" => "Denmark",
+"DJ" => "Djibouti",
+"DM" => "Dominica",
+"DO" => "Dominican Republic",
+"EC" => "Ecuador",
+"EG" => "Egypt",
+"SV" => "El Salvador",
+"GQ" => "Equatorial Guinea",
+"ER" => "Eritrea",
+"EE" => "Estonia",
+"SZ" => "Eswatini",
+"ET" => "Ethiopia",
+"FK" => "Falkland Islands (Malvinas)",
+"FO" => "Faroe Islands",
+"FJ" => "Fiji",
+"FI" => "Finland",
+"FR" => "France",
+"GF" => "French Guiana",
+"PF" => "French Polynesia",
+"TF" => "French Southern Territories",
+"GA" => "Gabon",
+"GM" => "Gambia",
+"GE" => "Georgia",
+"DE" => "Germany",
+"GH" => "Ghana",
+"GI" => "Gibraltar",
+"GR" => "Greece",
+"GL" => "Greenland",
+"GD" => "Grenada",
+"GP" => "Guadeloupe",
+"GU" => "Guam",
+"GT" => "Guatemala",
+"GG" => "Guernsey",
+"GN" => "Guinea",
+"GW" => "Guinea-Bissau",
+"GY" => "Guyana",
+"HT" => "Haiti",
+"HM" => "Heard Island and McDonald Islands",
+"VA" => "Holy See",
+"HN" => "Honduras",
+"HK" => "Hong Kong",
+"HU" => "Hungary",
+"IS" => "Iceland",
+"IN" => "India",
+"ID" => "Indonesia",
+"IR" => "Iran, Islamic Republic of",
+"IQ" => "Iraq",
+"IE" => "Ireland",
+"IM" => "Isle of Man",
+"IL" => "Israel",
+"IT" => "Italy",
+"JM" => "Jamaica",
+"JP" => "Japan",
+"JE" => "Jersey",
+"JO" => "Jordan",
+"KZ" => "Kazakhstan",
+"KE" => "Kenya",
+"KI" => "Kiribati",
+"KP" => "Korea, Democratic People's Republic of",
+"KR" => "Korea, Republic of",
+"KW" => "Kuwait",
+"KG" => "Kyrgyzstan",
+"LA" => "Lao People's Democratic Republic",
+"LV" => "Latvia",
+"LB" => "Lebanon",
+"LS" => "Lesotho",
+"LR" => "Liberia",
+"LY" => "Libya",
+"LI" => "Liechtenstein",
+"LT" => "Lithuania",
+"LU" => "Luxembourg",
+"MO" => "Macao",
+"MG" => "Madagascar",
+"MW" => "Malawi",
+"MY" => "Malaysia",
+"MV" => "Maldives",
+"ML" => "Mali",
+"MT" => "Malta",
+"MH" => "Marshall Islands",
+"MQ" => "Martinique",
+"MR" => "Mauritania",
+"MU" => "Mauritius",
+"YT" => "Mayotte",
+"MX" => "Mexico",
+"FM" => "Micronesia, Federated States of",
+"MD" => "Moldova, Republic of",
+"MC" => "Monaco",
+"MN" => "Mongolia",
+"ME" => "Montenegro",
+"MS" => "Montserrat",
+"MA" => "Morocco",
+"MZ" => "Mozambique",
+"MM" => "Myanmar",
+"NA" => "Namibia",
+"NR" => "Nauru",
+"NP" => "Nepal",
+"NL" => "Netherlands, Kingdom of the",
+"NC" => "New Caledonia",
+"NZ" => "New Zealand",
+"NI" => "Nicaragua",
+"NE" => "Niger",
+"NG" => "Nigeria",
+"NU" => "Niue",
+"NF" => "Norfolk Island",
+"MK" => "North Macedonia",
+"MP" => "Northern Mariana Islands",
+"NO" => "Norway",
+"OM" => "Oman",
+"PK" => "Pakistan",
+"PW" => "Palau",
+"PS" => "Palestine, State of",
+"PA" => "Panama",
+"PG" => "Papua New Guinea",
+"PY" => "Paraguay",
+"PE" => "Peru",
+"PH" => "Philippines",
+"PN" => "Pitcairn",
+"PL" => "Poland",
+"PT" => "Portugal",
+"PR" => "Puerto Rico",
+"QA" => "Qatar",
+"RE" => "Réunion",
+"RO" => "Romania",
+"RU" => "Russian Federation",
+"RW" => "Rwanda",
+"BL" => "Saint Barthélemy",
+"SH" => "Saint Helena, Ascension and Tristan da Cunha",
+"KN" => "Saint Kitts and Nevis",
+"LC" => "Saint Lucia",
+"MF" => "Saint Martin (French part)",
+"PM" => "Saint Pierre and Miquelon",
+"VC" => "Saint Vincent and the Grenadines",
+"WS" => "Samoa",
+"SM" => "San Marino",
+"ST" => "Sao Tome and Principe",
+"SA" => "Saudi Arabia",
+"SN" => "Senegal",
+"RS" => "Serbia",
+"SC" => "Seychelles",
+"SL" => "Sierra Leone",
+"SG" => "Singapore",
+"SX" => "Sint Maarten (Dutch part)",
+"SK" => "Slovakia",
+"SI" => "Slovenia",
+"SB" => "Solomon Islands",
+"SO" => "Somalia",
+"ZA" => "South Africa",
+"GS" => "South Georgia and the South Sandwich Islands",
+"SS" => "South Sudan",
+"ES" => "Spain",
+"LK" => "Sri Lanka",
+"SD" => "Sudan",
+"SR" => "Suriname",
+"SJ" => "Svalbard and Jan Mayen",
+"SE" => "Sweden",
+"CH" => "Switzerland",
+"SY" => "Syrian Arab Republic",
+"TW" => "Taiwan",
+"TJ" => "Tajikistan",
+"TZ" => "Tanzania, United Republic of",
+"TH" => "Thailand",
+"TL" => "Timor-Leste",
+"TG" => "Togo",
+"TK" => "Tokelau",
+"TO" => "Tonga",
+"TT" => "Trinidad and Tobago",
+"TN" => "Tunisia",
+"TR" => "Türkiye",
+"TM" => "Turkmenistan",
+"TC" => "Turks and Caicos Islands",
+"TV" => "Tuvalu",
+"UG" => "Uganda",
+"UA" => "Ukraine",
+"AE" => "United Arab Emirates",
+"GB" => "United Kingdom of Great Britain and Northern Ireland",
+"US" => "United States of America",
+"UM" => "United States Minor Outlying Islands",
+"UY" => "Uruguay",
+"UZ" => "Uzbekistan",
+"VU" => "Vanuatu",
+"VE" => "Venezuela",
+"VN" => "Viet Nam",
+"VG" => "Virgin Islands (British)",
+"VI" => "Virgin Islands (U.S.)",
+"WF" => "Wallis and Futuna",
+"EH" => "Western Sahara",
+"YE" => "Yemen",
+"ZM" => "Zambia",
+"ZW" => "Zimbabwe",
+]);
// All available TLDs
Configure::set('Opensrs.tlds', [
'.abogado',
@@ -844,7 +1096,8 @@
],
'contact_set[owner][country]' => [
'label' => Language::_('Opensrs.whois.owner.country', true),
- 'type' => 'text'
+ 'type' => 'select',
+ 'options' => Configure::get('Opensrs.countries')
],
'contact_set[owner][phone]' => [
'label' => Language::_('Opensrs.whois.owner.phone', true),
@@ -888,7 +1141,8 @@
],
'contact_set[tech][country]' => [
'label' => Language::_('Opensrs.whois.tech.country', true),
- 'type' => 'text'
+ 'type' => 'select',
+ 'options' => Configure::get('Opensrs.countries')
],
'contact_set[tech][phone]' => [
'label' => Language::_('Opensrs.whois.tech.phone', true),
@@ -932,7 +1186,8 @@
],
'contact_set[admin][country]' => [
'label' => Language::_('Opensrs.whois.admin.country', true),
- 'type' => 'text'
+ 'type' => 'select',
+ 'options' => Configure::get('Opensrs.countries')
],
'contact_set[admin][phone]' => [
'label' => Language::_('Opensrs.whois.admin.phone', true),
@@ -976,7 +1231,8 @@
],
'contact_set[billing][country]' => [
'label' => Language::_('Opensrs.whois.billing.country', true),
- 'type' => 'text'
+ 'type' => 'select',
+ 'options' => Configure::get('Opensrs.countries')
],
'contact_set[billing][phone]' => [
'label' => Language::_('Opensrs.whois.billing.phone', true),
@@ -1136,11 +1392,11 @@
// .FR
Configure::set('Opensrs.domain_fields.fr', [
'tld_data[registrant_extra_info][registrant_type]' => [
- 'label' => Language::_('Opensrs.domain.registrant_type', true),
+ 'label' => Language::_('Opensrs.domain.fr_registrant_type', true),
'type' => 'select',
'options' => [
- 'individual' => Language::_('Opensrs.domain.registrant_type.individual', true),
- 'organization' => Language::_('Opensrs.domain.registrant_type.company', true),
+ 'individual' => Language::_('Opensrs.domain.fr_registrant_type.individual', true),
+ 'organization' => Language::_('Opensrs.domain.fr_registrant_type.organization', true),
]
],
'tld_data[registrant_extra_info][registrant_vat_id]' => [
@@ -1190,7 +1446,8 @@
],
'tld_data[registrant_extra_info][qli_jurisdiction_country]' => [
'label' => Language::_('Opensrs.domain.qli_jurisdiction_country', true),
- 'type' => 'text'
+ 'type' => 'select',
+ 'options' => Configure::get('Opensrs.countries')
],
'tld_data[registrant_extra_info][qli_jurisdiction_state]' => [
'label' => Language::_('Opensrs.domain.qli_jurisdiction_state', true),
@@ -1224,4 +1481,4 @@
Domain: {service.domain}
Thank you for your business!
'
]
-]);
\ No newline at end of file
+]);
diff --git a/language/en_us/opensrs.php b/language/en_us/opensrs.php
index 122de8b..4b73ef0 100755
--- a/language/en_us/opensrs.php
+++ b/language/en_us/opensrs.php
@@ -59,6 +59,39 @@
$lang['Opensrs.tab_nameservers.field_submit'] = 'Update Name Servers';
$lang['Opensrs.tab_settings.title'] = 'Settings';
+
+$lang['Opensrs.tab_dns.title'] = 'DNS Records';
+$lang['Opensrs.tab_dns.field_type'] = 'Type';
+$lang['Opensrs.tab_dns.field_subdomain'] = 'Host';
+$lang['Opensrs.tab_dns.field_ip_address'] = 'Value';
+$lang['Opensrs.tab_dns.field_priority'] = 'Priority';
+$lang['Opensrs.tab_dns.field_ttl'] = 'TTL';
+$lang['Opensrs.tab_dns.field_options'] = 'Options';
+$lang['Opensrs.tab_dns.field_add'] = 'Add Record';
+$lang['Opensrs.tab_dns.field_delete'] = 'Delete';
+$lang['Opensrs.tab_dns.field_reset'] = 'Reset DNS Zone';
+$lang['Opensrs.tab_dns.add_record'] = 'Add DNS Record';
+$lang['Opensrs.tab_dns.no_records'] = 'There are no DNS records.';
+
+$lang['Opensrs.tab_url_forwarding.title'] = 'URL Forwarding';
+$lang['Opensrs.tab_url_forwarding.field_subdomain'] = 'Subdomain';
+$lang['Opensrs.tab_url_forwarding.field_destination'] = 'Destination URL';
+$lang['Opensrs.tab_url_forwarding.field_redirect_type'] = 'Redirect Type';
+$lang['Opensrs.tab_url_forwarding.redirect_301'] = 'Permanent (301)';
+$lang['Opensrs.tab_url_forwarding.redirect_302'] = 'Temporary (302)';
+$lang['Opensrs.tab_url_forwarding.redirect_frame'] = 'Frame (Masked)';
+$lang['Opensrs.tab_url_forwarding.field_add'] = 'Add Forwarding Rule';
+$lang['Opensrs.tab_url_forwarding.add_record'] = 'Add URL Forwarding Rule';
+$lang['Opensrs.tab_url_forwarding.no_records'] = 'There are no URL forwarding rules.';
+
+$lang['Opensrs.tab_dnssec.title'] = 'DNSSEC';
+$lang['Opensrs.tab_dnssec.field_key_tag'] = 'Key Tag';
+$lang['Opensrs.tab_dnssec.field_algorithm'] = 'Algorithm';
+$lang['Opensrs.tab_dnssec.field_digest_type'] = 'Digest Type';
+$lang['Opensrs.tab_dnssec.field_digest'] = 'Digest';
+$lang['Opensrs.tab_dnssec.field_add'] = 'Add DS Record';
+$lang['Opensrs.tab_dnssec.add_record'] = 'Add DS Record';
+$lang['Opensrs.tab_dnssec.no_records'] = 'There are no DNSSEC DS records.';
$lang['Opensrs.tab_settings.field_registrar_lock'] = 'Registrar Lock';
$lang['Opensrs.tab_settings.field_registrar_lock_yes'] = 'Set the registrar lock. Recommended to prevent unauthorized transfer.';
$lang['Opensrs.tab_settings.field_registrar_lock_no'] = 'Release the registrar lock so the domain can be transferred.';
@@ -73,6 +106,11 @@
$lang['Opensrs.!error.user.valid'] = 'Please enter a user';
$lang['Opensrs.!error.key.valid'] = 'Please enter a key';
$lang['Opensrs.!error.key.valid_connection'] = 'The user and key combination appear to be invalid, or your Opensrs account may not be configured to allow API access.';
+$lang['Opensrs.!error.module_row.missing'] = 'The module row could not be found. Please reconfigure the module.';
+$lang['Opensrs.!error.cancel.failed'] = 'Failed to disable auto-renewal for this domain.';
+$lang['Opensrs.!error.suspend.failed'] = 'Failed to suspend this domain.';
+$lang['Opensrs.!error.unsuspend.failed'] = 'Failed to unsuspend this domain.';
+$lang['Opensrs.!error.restore.failed'] = 'Failed to restore this domain from redemption.';
$lang['Opensrs.!error.registrant_type.format'] = 'Please select a registrant type';
$lang['Opensrs.!error.registrant_vat_id.format'] = 'Please enter a VAT ID';
$lang['Opensrs.!error.siren_siret.format'] = 'Please enter a SIREN/SIRET Number';
@@ -219,9 +257,9 @@
$lang['Opensrs.domain.id_number'] = 'Identity Number';
// .FR domain fields
-$lang['Opensrs.domain.registrant_type'] = 'Legal Type';
-$lang['Opensrs.domain.registrant_type.individual'] = 'Individual';
-$lang['Opensrs.domain.registrant_type.organization'] = 'Company';
+$lang['Opensrs.domain.fr_registrant_type'] = 'Legal Type';
+$lang['Opensrs.domain.fr_registrant_type.individual'] = 'Individual';
+$lang['Opensrs.domain.fr_registrant_type.organization'] = 'Company';
$lang['Opensrs.domain.registrant_vat_id'] = 'VAT ID';
$lang['Opensrs.domain.siren_siret'] = 'SIREN/SIRET Number';
$lang['Opensrs.domain.trademark_number'] = 'Trademark Number';
diff --git a/opensrs.php b/opensrs.php
index ab0c33a..38897f0 100644
--- a/opensrs.php
+++ b/opensrs.php
@@ -82,7 +82,10 @@ public function getFilteredTldPricing($module_row_id = null, $filters = [])
// Fetch pricing from the registrar
- $row = $this->getModuleRow($module_row_id);
+ $row = $this->getModuleRowOrFail($module_row_id);
+ if (!$row) {
+ return [];
+ }
$api = $this->getApi($row->meta->user, $row->meta->key, $row->meta->sandbox == 'true');
$domains = new OpensrsDomains($api);
@@ -106,9 +109,7 @@ public function getFilteredTldPricing($module_row_id = null, $filters = [])
if ($register_response->status() != 'OK') {
continue;
}
- foreach (range(1, 10) as $years) {
- $pricing[$tld]['register'] = $register_response->response();
- }
+ $pricing[$tld]['register'] = $register_response->response();
// Set the renewal prices
$renew_response = $domains->getPrice(array_merge($vars, ['reg_type' => 'renewal']));
@@ -116,9 +117,7 @@ public function getFilteredTldPricing($module_row_id = null, $filters = [])
if ($renew_response->status() != 'OK') {
continue;
}
- foreach (range(1, 10) as $years) {
- $pricing[$tld]['renew'] = $renew_response->response();
- }
+ $pricing[$tld]['renew'] = $renew_response->response();
// Set the transfer prices
$transfer_response = $domains->getPrice(array_merge($vars, ['reg_type' => 'transfer']));
@@ -126,9 +125,7 @@ public function getFilteredTldPricing($module_row_id = null, $filters = [])
if ($transfer_response->status() != 'OK') {
continue;
}
- foreach (range(1, 10) as $years) {
- $pricing[$tld]['transfer'] = $transfer_response->response();
- }
+ $pricing[$tld]['transfer'] = $transfer_response->response();
}
unset($tld);
@@ -214,7 +211,7 @@ public function getFilteredTldPricing($module_row_id = null, $filters = [])
* @param array $vars An array of user supplied info to satisfy the request
* @return bool True if the service validates, false otherwise. Sets Input errors when false.
*/
- public function validateService($package, array $vars = null)
+ public function validateService($package, ?array $vars = null)
{
$this->Input->setRules($this->getServiceRules($vars));
@@ -228,7 +225,7 @@ public function validateService($package, array $vars = null)
* @param array $vars An array of user-supplied info to satisfy the request
* @return bool True if the service update validates or false otherwise. Sets Input errors when false.
*/
- public function validateServiceEdit($service, array $vars = null)
+ public function validateServiceEdit($service, ?array $vars = null)
{
$this->Input->setRules($this->getServiceRules($vars, true));
@@ -242,7 +239,7 @@ public function validateServiceEdit($service, array $vars = null)
* @param bool $edit True to get the edit rules, false for the add rules
* @return array Service rules
*/
- private function getServiceRules(array $vars = null, $edit = false)
+ private function getServiceRules(?array $vars = null, $edit = false)
{
// Validate .fr TLD rules
$fr_fields = Configure::get('Opensrs.domain_fields.fr');
@@ -291,7 +288,7 @@ private function getServiceRules(array $vars = null, $edit = false)
'tld_data[registrant_extra_info][trademark_number]'
];
- if ($vars['tld_data']['registrant_extra_info']['registrant_type'] == 'organization') {
+ if ($vars['tld_data']['registrant_extra_info']['registrant_type'] == 'individual') {
foreach ($company_fields as $field) {
unset($rules[$field]);
}
@@ -326,7 +323,7 @@ private function getServiceRules(array $vars = null, $edit = false)
*/
public function addService(
$package,
- array $vars = null,
+ ?array $vars = null,
$parent_package = null,
$parent_service = null,
$status = 'pending'
@@ -364,12 +361,18 @@ public function addService(
Loader::loadModels($this, ['Contacts']);
}
- $client = $this->Clients->get($vars['client_id']);
+ $client = $this->Clients->get($vars['client_id'] ?? null);
if ($client) {
$contact_numbers = $this->Contacts->getNumbers($client->contact_id);
+ } else {
+ $contact_numbers = [];
}
foreach ($whois_fields as $key => $value) {
+ if (!$client) {
+ $vars[$key] = 'NA';
+ continue;
+ }
if (str_contains($key, 'first_name')) {
$vars[$key] = $client->first_name;
} elseif (str_contains($key, 'last_name')) {
@@ -437,15 +440,20 @@ public function addService(
}
// Set nameservers
- $this->setDomainNameservers($vars['domain'], $package->module_row, [
+ $this->setDomainNameservers($vars['domain'], $package->module_row, array_filter([
$fields['nameserver_list'][0]['name'] ?? '',
$fields['nameserver_list'][1]['name'] ?? '',
$fields['nameserver_list'][2]['name'] ?? '',
$fields['nameserver_list'][3]['name'] ?? '',
- ]);
+ ]));
- // Ignore nameserver errors
- $this->Input->setErrors([]);
+ // Clear nameserver errors only (registration already succeeded)
+ if ($this->Input->errors()) {
+ $errors = $this->Input->errors();
+ if (isset($errors['errors']) && count($errors) === 1) {
+ $this->Input->setErrors([]);
+ }
+ }
return [['key' => 'domain', 'value' => $vars['domain'], 'encrypted' => 0]];
}
@@ -507,6 +515,156 @@ public function renewService($package, $service, $parent_package = null, $parent
return null;
}
+ /**
+ * Cancels the service on the remote server. Sets Input errors on failure,
+ * preventing the service from being canceled.
+ *
+ * @param stdClass $package A stdClass object representing the current package
+ * @param stdClass $service A stdClass object representing the current service
+ * @param stdClass $parent_package A stdClass object representing the parent
+ * service's selected package (if the current service is an addon service)
+ * @param stdClass $parent_service A stdClass object representing the parent
+ * service of the service being canceled (if the current service is an addon service)
+ * @return mixed null to maintain the existing meta fields or a numerically
+ * indexed array of meta fields to be stored for this service containing:
+ * - key The key for this meta field
+ * - value The value for this key
+ * - encrypted Whether or not this field should be encrypted (default 0, not encrypted)
+ * @see Module::getModule()
+ * @see Module::getModuleRow()
+ */
+ public function cancelService($package, $service, $parent_package = null, $parent_service = null)
+ {
+ $row = $this->getModuleRowOrFail($package->module_row);
+ if (!$row) {
+ return null;
+ }
+ $api = $this->getApi($row->meta->user, $row->meta->key, $row->meta->sandbox == 'true');
+
+ $fields = $this->serviceFieldsToObject($service->fields);
+
+ $domains_provisioning = new OpensrsDomainsProvisioning($api);
+ $response = $domains_provisioning->modify([
+ 'domain' => $fields->domain,
+ 'data' => 'expire_action',
+ 'affect_domains' => '0',
+ 'auto_renew' => '0',
+ 'let_expire' => '1'
+ ]);
+ $this->processResponse($api, $response);
+
+ return null;
+ }
+
+ /**
+ * Suspends the service on the remote server. Sets Input errors on failure,
+ * preventing the service from being suspended.
+ *
+ * @param stdClass $package A stdClass object representing the current package
+ * @param stdClass $service A stdClass object representing the current service
+ * @param stdClass $parent_package A stdClass object representing the parent
+ * service's selected package (if the current service is an addon service)
+ * @param stdClass $parent_service A stdClass object representing the parent
+ * service of the service being suspended (if the current service is an addon service)
+ * @return mixed null to maintain the existing meta fields or a numerically
+ * indexed array of meta fields to be stored for this service containing:
+ * - key The key for this meta field
+ * - value The value for this key
+ * - encrypted Whether or not this field should be encrypted (default 0, not encrypted)
+ * @see Module::getModule()
+ * @see Module::getModuleRow()
+ */
+ public function suspendService($package, $service, $parent_package = null, $parent_service = null)
+ {
+ return $this->cancelService($package, $service, $parent_package, $parent_service);
+ }
+
+ /**
+ * Unsuspends the service on the remote server. Sets Input errors on failure,
+ * preventing the service from being unsuspended.
+ *
+ * @param stdClass $package A stdClass object representing the current package
+ * @param stdClass $service A stdClass object representing the current service
+ * @param stdClass $parent_package A stdClass object representing the parent
+ * service's selected package (if the current service is an addon service)
+ * @param stdClass $parent_service A stdClass object representing the parent
+ * service of the service being unsuspended (if the current service is an addon service)
+ * @return mixed null to maintain the existing meta fields or a numerically
+ * indexed array of meta fields to be stored for this service containing:
+ * - key The key for this meta field
+ * - value The value for this key
+ * - encrypted Whether or not this field should be encrypted (default 0, not encrypted)
+ * @see Module::getModule()
+ * @see Module::getModuleRow()
+ */
+ public function unsuspendService($package, $service, $parent_package = null, $parent_service = null)
+ {
+ $row = $this->getModuleRowOrFail($package->module_row);
+ if (!$row) {
+ return null;
+ }
+ $api = $this->getApi($row->meta->user, $row->meta->key, $row->meta->sandbox == 'true');
+
+ $fields = $this->serviceFieldsToObject($service->fields);
+
+ $domains_provisioning = new OpensrsDomainsProvisioning($api);
+ $response = $domains_provisioning->modify([
+ 'domain' => $fields->domain,
+ 'data' => 'expire_action',
+ 'affect_domains' => '0',
+ 'auto_renew' => '1',
+ 'let_expire' => '0'
+ ]);
+ $this->processResponse($api, $response);
+
+ return null;
+ }
+
+ /**
+ * Edits the service on the remote server.
+ *
+ * @param stdClass $package A stdClass object representing the current package
+ * @param stdClass $service A stdClass object representing the current service
+ * @param array $vars An array of user supplied info to satisfy the request
+ * @param stdClass $parent_package A stdClass object representing the parent
+ * service's selected package (if the current service is an addon service)
+ * @param stdClass $parent_service A stdClass object representing the parent
+ * service of the service being edited (if the current service is an addon service)
+ * @return mixed null to maintain the existing meta fields or a numerically
+ * indexed array of meta fields to be stored for this service containing:
+ * - key The key for this meta field
+ * - value The value for this key
+ * - encrypted Whether or not this field should be encrypted (default 0, not encrypted)
+ * @see Module::getModule()
+ * @see Module::getModuleRow()
+ */
+ public function editService($package, $service, array $vars = [], $parent_package = null, $parent_service = null)
+ {
+ return null;
+ }
+
+ /**
+ * Restores a domain in the redemption grace period
+ *
+ * @param string $domain The domain to restore
+ * @param int $module_row_id The ID of the module row to fetch for the current module
+ * @return bool True if the domain was successfully restored, false otherwise
+ */
+ public function restoreDomain($domain, $module_row_id = null, array $vars = [])
+ {
+ $row = $this->getModuleRowOrFail($module_row_id);
+ if (!$row) {
+ return false;
+ }
+ $api = $this->getApi($row->meta->user, $row->meta->key, $row->meta->sandbox == 'true');
+
+ $domains = new OpensrsDomainsProvisioning($api);
+ $response = $domains->redeem(['domain' => $domain]);
+ $this->processResponse($api, $response);
+
+ return $response->status() == 'OK';
+ }
+
/**
* Validates input data when attempting to add a package, returns the meta
* data to save when adding a package. Performs any action required to add
@@ -521,7 +679,7 @@ public function renewService($package, $service, $parent_package = null, $parent
* @see Module::getModule()
* @see Module::getModuleRow()
*/
- public function addPackage(array $vars = null)
+ public function addPackage(?array $vars = null)
{
$meta = [];
if (isset($vars['meta']) && is_array($vars['meta'])) {
@@ -553,7 +711,7 @@ public function addPackage(array $vars = null)
* @see Module::getModule()
* @see Module::getModuleRow()
*/
- public function editPackage($package, array $vars = null)
+ public function editPackage($package, ?array $vars = null)
{
$meta = [];
if (isset($vars['meta']) && is_array($vars['meta'])) {
@@ -964,12 +1122,26 @@ public function getAdminServiceTabs($service)
{
Loader::loadModels($this, ['Packages']);
+ $package = null;
+ if (isset($service->package) && $service->package) {
+ $package = $service->package;
+ } elseif (isset($service->pricing_id)) {
+ $package = $this->Packages->getByPricingId($service->pricing_id);
+ }
+
$tabs = [
'tabWhois' => Language::_('Opensrs.tab_whois.title', true),
'tabNameservers' => Language::_('Opensrs.tab_nameservers.title', true),
'tabSettings' => Language::_('Opensrs.tab_settings.title', true)
];
+ if ($this->featureServiceEnabled('dns_management', $service)) {
+ $tabs['tabDns'] = Language::_('Opensrs.tab_dns.title', true);
+ $tabs['tabUrlForwarding'] = Language::_('Opensrs.tab_url_forwarding.title', true);
+ }
+
+ $tabs['tabDnssec'] = Language::_('Opensrs.tab_dnssec.title', true);
+
return $tabs;
}
@@ -1005,6 +1177,22 @@ public function getClientServiceTabs($service)
]
];
+ if ($this->featureServiceEnabled('dns_management', $service)) {
+ $tabs['tabClientDns'] = [
+ 'name' => Language::_('Opensrs.tab_dns.title', true),
+ 'icon' => 'fas fa-globe'
+ ];
+ $tabs['tabClientUrlForwarding'] = [
+ 'name' => Language::_('Opensrs.tab_url_forwarding.title', true),
+ 'icon' => 'fas fa-share'
+ ];
+ }
+
+ $tabs['tabClientDnssec'] = [
+ 'name' => Language::_('Opensrs.tab_dnssec.title', true),
+ 'icon' => 'fas fa-shield-alt'
+ ];
+
return $tabs;
}
@@ -1018,7 +1206,7 @@ public function getClientServiceTabs($service)
* @param array $files Any FILES parameters
* @return string The string representing the contents of this tab
*/
- public function tabWhois($package, $service, array $get = null, array $post = null, array $files = null)
+ public function tabWhois($package, $service, ?array $get = null, ?array $post = null, ?array $files = null)
{
return $this->manageWhois('tab_whois', $package, $service, $get, $post, $files);
}
@@ -1033,7 +1221,7 @@ public function tabWhois($package, $service, array $get = null, array $post = nu
* @param array $files Any FILES parameters
* @return string The string representing the contents of this tab
*/
- public function tabClientWhois($package, $service, array $get = null, array $post = null, array $files = null)
+ public function tabClientWhois($package, $service, ?array $get = null, ?array $post = null, ?array $files = null)
{
return $this->manageWhois('tab_client_whois', $package, $service, $get, $post, $files);
}
@@ -1048,7 +1236,7 @@ public function tabClientWhois($package, $service, array $get = null, array $pos
* @param array $files Any FILES parameters
* @return string The string representing the contents of this tab
*/
- public function tabNameservers($package, $service, array $get = null, array $post = null, array $files = null)
+ public function tabNameservers($package, $service, ?array $get = null, ?array $post = null, ?array $files = null)
{
return $this->manageNameservers('tab_nameservers', $package, $service, $get, $post, $files);
}
@@ -1063,7 +1251,7 @@ public function tabNameservers($package, $service, array $get = null, array $pos
* @param array $files Any FILES parameters
* @return string The string representing the contents of this tab
*/
- public function tabClientNameservers($package, $service, array $get = null, array $post = null, array $files = null)
+ public function tabClientNameservers($package, $service, ?array $get = null, ?array $post = null, ?array $files = null)
{
return $this->manageNameservers('tab_client_nameservers', $package, $service, $get, $post, $files);
}
@@ -1078,7 +1266,7 @@ public function tabClientNameservers($package, $service, array $get = null, arra
* @param array $files Any FILES parameters
* @return string The string representing the contents of this tab
*/
- public function tabSettings($package, $service, array $get = null, array $post = null, array $files = null)
+ public function tabSettings($package, $service, ?array $get = null, ?array $post = null, ?array $files = null)
{
return $this->manageSettings('tab_settings', $package, $service, $get, $post, $files);
}
@@ -1093,11 +1281,106 @@ public function tabSettings($package, $service, array $get = null, array $post =
* @param array $files Any FILES parameters
* @return string The string representing the contents of this tab
*/
- public function tabClientSettings($package, $service, array $get = null, array $post = null, array $files = null)
+ public function tabClientSettings($package, $service, ?array $get = null, ?array $post = null, ?array $files = null)
{
return $this->manageSettings('tab_client_settings', $package, $service, $get, $post, $files);
}
+ /**
+ * Admin DNS tab
+ *
+ * @param stdClass $package A stdClass object representing the current package
+ * @param stdClass $service A stdClass object representing the current service
+ * @param array $get Any GET parameters
+ * @param array $post Any POST parameters
+ * @param array $files Any FILES parameters
+ * @return string The string representing the contents of this tab
+ */
+ public function tabDns($package, $service, ?array $get = null, ?array $post = null, ?array $files = null)
+ {
+ return $this->manageDns('tab_dns', $package, $service, $get, $post, $files);
+ }
+
+ /**
+ * Client DNS tab
+ *
+ * @param stdClass $package A stdClass object representing the current package
+ * @param stdClass $service A stdClass object representing the current service
+ * @param array $get Any GET parameters
+ * @param array $post Any POST parameters
+ * @param array $files Any FILES parameters
+ * @return string The string representing the contents of this tab
+ */
+ public function tabClientDns($package, $service, ?array $get = null, ?array $post = null, ?array $files = null)
+ {
+ return $this->manageDns('tab_client_dns', $package, $service, $get, $post, $files);
+ }
+
+ /**
+ * Admin URL Forwarding tab
+ *
+ * @param stdClass $package A stdClass object representing the current package
+ * @param stdClass $service A stdClass object representing the current service
+ * @param array $get Any GET parameters
+ * @param array $post Any POST parameters
+ * @param array $files Any FILES parameters
+ * @return string The string representing the contents of this tab
+ */
+ public function tabUrlForwarding($package, $service, ?array $get = null, ?array $post = null, ?array $files = null)
+ {
+ return $this->manageUrlForwarding('tab_url_forwarding', $package, $service, $get, $post, $files);
+ }
+
+ /**
+ * Client URL Forwarding tab
+ *
+ * @param stdClass $package A stdClass object representing the current package
+ * @param stdClass $service A stdClass object representing the current service
+ * @param array $get Any GET parameters
+ * @param array $post Any POST parameters
+ * @param array $files Any FILES parameters
+ * @return string The string representing the contents of this tab
+ */
+ public function tabClientUrlForwarding(
+ $package,
+ $service,
+ ?array $get = null,
+ ?array $post = null,
+ ?array $files = null
+ ) {
+ return $this->manageUrlForwarding('tab_client_url_forwarding', $package, $service, $get, $post, $files);
+ }
+
+ /**
+ * Admin DNSSEC tab
+ *
+ * @param stdClass $package A stdClass object representing the current package
+ * @param stdClass $service A stdClass object representing the current service
+ * @param array $get Any GET parameters
+ * @param array $post Any POST parameters
+ * @param array $files Any FILES parameters
+ * @return string The string representing the contents of this tab
+ */
+ public function tabDnssec($package, $service, ?array $get = null, ?array $post = null, ?array $files = null)
+ {
+ return $this->manageDnssec('tab_dnssec', $package, $service, $get, $post, $files);
+ }
+
+ /**
+ * Client DNSSEC tab
+ *
+ * @param stdClass $package A stdClass object representing the current package
+ * @param stdClass $service A stdClass object representing the current service
+ * @param array $get Any GET parameters
+ * @param array $post Any POST parameters
+ * @param array $files Any FILES parameters
+ * @return string The string representing the contents of this tab
+ */
+ public function tabClientDnssec($package, $service, ?array $get = null, ?array $post = null, ?array $files = null)
+ {
+ return $this->manageDnssec('tab_client_dnssec', $package, $service, $get, $post, $files);
+ }
+
/**
* Handle updating whois information
*
@@ -1109,7 +1392,7 @@ public function tabClientSettings($package, $service, array $get = null, array $
* @param array $files Any FILES parameters
* @return string The string representing the contents of this tab
*/
- private function manageWhois($view, $package, $service, array $get = null, array $post = null, array $files = null)
+ private function manageWhois($view, $package, $service, ?array $get = null, ?array $post = null, ?array $files = null)
{
$this->view = new View($view, 'default');
@@ -1184,9 +1467,9 @@ private function manageNameservers(
$view,
$package,
$service,
- array $get = null,
- array $post = null,
- array $files = null
+ ?array $get = null,
+ ?array $post = null,
+ ?array $files = null
) {
$this->view = new View($view, 'default');
@@ -1234,16 +1517,19 @@ private function manageSettings(
$view,
$package,
$service,
- array $get = null,
- array $post = null,
- array $files = null
+ ?array $get = null,
+ ?array $post = null,
+ ?array $files = null
) {
$this->view = new View($view, 'default');
// Load the helpers required for this view
Loader::loadHelpers($this, ['Form', 'Html']);
- $row = $this->getModuleRow($package->module_row);
+ $row = $this->getModuleRowOrFail($package->module_row);
+ if (!$row) {
+ return '';
+ }
$api = $this->getApi($row->meta->user, $row->meta->key, $row->meta->sandbox == 'true');
$vars = new stdClass();
@@ -1257,7 +1543,7 @@ private function manageSettings(
if (!empty($post)) {
// Set domain status
- if ($post['registrar_lock'] == 'true') {
+ if (($post['registrar_lock'] ?? 'false') == 'true') {
$this->lockDomain($fields->domain, $package->module_row);
} else {
$this->unlockDomain($fields->domain, $package->module_row);
@@ -1269,7 +1555,7 @@ private function manageSettings(
'domain' => $fields->domain,
'data' => 'whois_privacy_state',
'affect_domains' => '0',
- 'state' => $post['whois_privacy_state'] == 'true' ? 'Y' : 'N'
+ 'state' => ($post['whois_privacy_state'] ?? 'false') == 'true' ? 'Y' : 'N'
]);
$this->processResponse($api, $response);
@@ -1298,6 +1584,381 @@ private function manageSettings(
return $this->view->fetch();
}
+ /**
+ * Handle DNS zone management
+ *
+ * @param string $view The view to use
+ * @param stdClass $package A stdClass object representing the current package
+ * @param stdClass $service A stdClass object representing the current service
+ * @param array $get Any GET parameters
+ * @param array $post Any POST parameters
+ * @param array $files Any FILES parameters
+ * @return string The string representing the contents of this tab
+ */
+ private function manageDns(
+ $view,
+ $package,
+ $service,
+ ?array $get = null,
+ ?array $post = null,
+ ?array $files = null
+ ) {
+ $this->view = new View($view, 'default');
+
+ // Load the helpers required for this view
+ Loader::loadHelpers($this, ['Form', 'Html']);
+
+ $row = $this->getModuleRowOrFail($package->module_row);
+ if (!$row) {
+ return '';
+ }
+ $api = $this->getApi($row->meta->user, $row->meta->key, $row->meta->sandbox == 'true');
+
+ $vars = new stdClass();
+ $fields = $this->serviceFieldsToObject($service->fields);
+ $dns = new OpensrsDomainsDns($api);
+
+ if (!empty($post)) {
+ if (isset($post['action'])) {
+ if ($post['action'] == 'add_record') {
+ // Get existing records, add new one, set zone
+ $zone_response = $dns->getDnsZone(['domain' => $fields->domain]);
+ $this->processResponse($api, $zone_response);
+
+ if ($zone_response->status() == 'OK') {
+ $zone = $zone_response->response();
+ $records = $zone->attributes['records'] ?? [];
+
+ // Add the new record
+ $new_record = [
+ 'type' => $post['type'] ?? 'A',
+ 'subdomain' => $post['subdomain'] ?? '',
+ 'ip_address' => $post['ip_address'] ?? '',
+ 'priority' => $post['priority'] ?? '',
+ 'ttl' => $post['ttl'] ?? '3600'
+ ];
+
+ // Build the records for setDnsZone
+ $type_key = strtolower($new_record['type']);
+ if (!isset($records[$type_key]) || !is_array($records[$type_key])) {
+ $records[$type_key] = [];
+ }
+ $records[$type_key][] = $new_record;
+
+ $response = $dns->setDnsZone([
+ 'domain' => $fields->domain,
+ 'records' => $records
+ ]);
+ $this->processResponse($api, $response);
+ }
+ } elseif ($post['action'] == 'delete_record') {
+ // Get existing records, remove specified one, set zone
+ $zone_response = $dns->getDnsZone(['domain' => $fields->domain]);
+ $this->processResponse($api, $zone_response);
+
+ if ($zone_response->status() == 'OK') {
+ $zone = $zone_response->response();
+ $records = $zone->attributes['records'] ?? [];
+
+ $delete_type = strtolower($post['record_type'] ?? '');
+ $delete_index = (int)($post['record_index'] ?? -1);
+
+ if (isset($records[$delete_type][$delete_index])) {
+ unset($records[$delete_type][$delete_index]);
+ $records[$delete_type] = array_values($records[$delete_type]);
+ }
+
+ $response = $dns->setDnsZone([
+ 'domain' => $fields->domain,
+ 'records' => $records
+ ]);
+ $this->processResponse($api, $response);
+ }
+ } elseif ($post['action'] == 'reset_zone') {
+ $response = $dns->resetDnsZone([
+ 'domain' => $fields->domain
+ ]);
+ $this->processResponse($api, $response);
+ }
+ }
+ }
+
+ // Fetch current zone records
+ $zone_response = $dns->getDnsZone(['domain' => $fields->domain]);
+ $records = [];
+ if ($zone_response->status() == 'OK') {
+ $zone = $zone_response->response();
+ $raw_records = $zone->attributes['records'] ?? [];
+
+ // Flatten records into a single array for display
+ foreach ($raw_records as $type => $type_records) {
+ if (is_array($type_records)) {
+ foreach ($type_records as $index => $record) {
+ if (is_array($record)) {
+ $record['record_type'] = strtoupper($type);
+ $record['record_index'] = $index;
+ $records[] = $record;
+ }
+ }
+ }
+ }
+ } else {
+ $this->Input->setErrors([]);
+ }
+
+ $this->view->set('records', $records);
+ $this->view->set('vars', $vars);
+ $this->view->set('record_types', [
+ 'A' => 'A',
+ 'AAAA' => 'AAAA',
+ 'CNAME' => 'CNAME',
+ 'MX' => 'MX',
+ 'TXT' => 'TXT',
+ 'SRV' => 'SRV',
+ 'NS' => 'NS'
+ ]);
+ $this->view->setDefaultView('components' . DS . 'modules' . DS . 'opensrs' . DS);
+
+ return $this->view->fetch();
+ }
+
+ /**
+ * Handle URL forwarding management
+ *
+ * @param string $view The view to use
+ * @param stdClass $package A stdClass object representing the current package
+ * @param stdClass $service A stdClass object representing the current service
+ * @param array $get Any GET parameters
+ * @param array $post Any POST parameters
+ * @param array $files Any FILES parameters
+ * @return string The string representing the contents of this tab
+ */
+ private function manageUrlForwarding(
+ $view,
+ $package,
+ $service,
+ ?array $get = null,
+ ?array $post = null,
+ ?array $files = null
+ ) {
+ $this->view = new View($view, 'default');
+
+ // Load the helpers required for this view
+ Loader::loadHelpers($this, ['Form', 'Html']);
+
+ $row = $this->getModuleRowOrFail($package->module_row);
+ if (!$row) {
+ return '';
+ }
+ $api = $this->getApi($row->meta->user, $row->meta->key, $row->meta->sandbox == 'true');
+
+ $vars = new stdClass();
+ $fields = $this->serviceFieldsToObject($service->fields);
+ $dns = new OpensrsDomainsDns($api);
+
+ if (!empty($post)) {
+ if (isset($post['action'])) {
+ if ($post['action'] == 'set_forwarding') {
+ // Build URL forwarding record via DNS A/CNAME + URL forwarding
+ $zone_response = $dns->getDnsZone(['domain' => $fields->domain]);
+ $this->processResponse($api, $zone_response);
+
+ if ($zone_response->status() == 'OK') {
+ $zone = $zone_response->response();
+ $records = $zone->attributes['records'] ?? [];
+
+ // Add forwarding record
+ if (!isset($records['url_forwarding']) || !is_array($records['url_forwarding'])) {
+ $records['url_forwarding'] = [];
+ }
+ $records['url_forwarding'][] = [
+ 'subdomain' => $post['subdomain'] ?? '@',
+ 'ip_address' => $post['destination'] ?? '',
+ 'type' => $post['redirect_type'] ?? '301'
+ ];
+
+ $response = $dns->setDnsZone([
+ 'domain' => $fields->domain,
+ 'records' => $records
+ ]);
+ $this->processResponse($api, $response);
+ }
+ } elseif ($post['action'] == 'delete_forwarding') {
+ $zone_response = $dns->getDnsZone(['domain' => $fields->domain]);
+ $this->processResponse($api, $zone_response);
+
+ if ($zone_response->status() == 'OK') {
+ $zone = $zone_response->response();
+ $records = $zone->attributes['records'] ?? [];
+
+ $delete_index = (int)($post['record_index'] ?? -1);
+ if (isset($records['url_forwarding'][$delete_index])) {
+ unset($records['url_forwarding'][$delete_index]);
+ $records['url_forwarding'] = array_values($records['url_forwarding']);
+ }
+
+ $response = $dns->setDnsZone([
+ 'domain' => $fields->domain,
+ 'records' => $records
+ ]);
+ $this->processResponse($api, $response);
+ }
+ }
+ }
+ }
+
+ // Fetch current forwarding records
+ $forwarding_records = [];
+ $zone_response = $dns->getDnsZone(['domain' => $fields->domain]);
+ if ($zone_response->status() == 'OK') {
+ $zone = $zone_response->response();
+ $raw_records = $zone->attributes['records']['url_forwarding'] ?? [];
+ foreach ($raw_records as $index => $record) {
+ if (is_array($record)) {
+ $record['record_index'] = $index;
+ $forwarding_records[] = $record;
+ }
+ }
+ } else {
+ $this->Input->setErrors([]);
+ }
+
+ $this->view->set('forwarding_records', $forwarding_records);
+ $this->view->set('vars', $vars);
+ $this->view->set('redirect_types', [
+ '301' => Language::_('Opensrs.tab_url_forwarding.redirect_301', true),
+ '302' => Language::_('Opensrs.tab_url_forwarding.redirect_302', true),
+ 'frame' => Language::_('Opensrs.tab_url_forwarding.redirect_frame', true)
+ ]);
+ $this->view->setDefaultView('components' . DS . 'modules' . DS . 'opensrs' . DS);
+
+ return $this->view->fetch();
+ }
+
+ /**
+ * Handle DNSSEC management
+ *
+ * @param string $view The view to use
+ * @param stdClass $package A stdClass object representing the current package
+ * @param stdClass $service A stdClass object representing the current service
+ * @param array $get Any GET parameters
+ * @param array $post Any POST parameters
+ * @param array $files Any FILES parameters
+ * @return string The string representing the contents of this tab
+ */
+ private function manageDnssec(
+ $view,
+ $package,
+ $service,
+ ?array $get = null,
+ ?array $post = null,
+ ?array $files = null
+ ) {
+ $this->view = new View($view, 'default');
+
+ // Load the helpers required for this view
+ Loader::loadHelpers($this, ['Form', 'Html']);
+
+ $row = $this->getModuleRowOrFail($package->module_row);
+ if (!$row) {
+ return '';
+ }
+ $api = $this->getApi($row->meta->user, $row->meta->key, $row->meta->sandbox == 'true');
+
+ $vars = new stdClass();
+ $fields = $this->serviceFieldsToObject($service->fields);
+ $dnssec = new OpensrsDomainsDnssec($api);
+
+ if (!empty($post)) {
+ if (isset($post['action'])) {
+ if ($post['action'] == 'add_ds_record') {
+ // Get existing records, add new one
+ $info_response = $dnssec->getDnssecRecords(['domain' => $fields->domain]);
+ $this->logRequest($api, $info_response);
+ $existing_records = [];
+ if ($info_response->status() == 'OK') {
+ $info = $info_response->response();
+ $existing_records = $info->attributes['dnssec'] ?? [];
+ }
+
+ $new_record = [
+ 'key_tag' => $post['key_tag'] ?? '',
+ 'algorithm' => $post['algorithm'] ?? '',
+ 'digest_type' => $post['digest_type'] ?? '',
+ 'digest' => $post['digest'] ?? ''
+ ];
+
+ $existing_records[] = $new_record;
+
+ $response = $dnssec->addDnssecRecord([
+ 'domain' => $fields->domain,
+ 'dnssec' => $existing_records
+ ]);
+ $this->processResponse($api, $response);
+ } elseif ($post['action'] == 'delete_ds_record') {
+ // Get existing records, remove specified one
+ $info_response = $dnssec->getDnssecRecords(['domain' => $fields->domain]);
+ $this->logRequest($api, $info_response);
+ $existing_records = [];
+ if ($info_response->status() == 'OK') {
+ $info = $info_response->response();
+ $existing_records = $info->attributes['dnssec'] ?? [];
+ }
+
+ $delete_index = (int)($post['record_index'] ?? -1);
+ if (isset($existing_records[$delete_index])) {
+ unset($existing_records[$delete_index]);
+ $existing_records = array_values($existing_records);
+ }
+
+ $response = $dnssec->addDnssecRecord([
+ 'domain' => $fields->domain,
+ 'dnssec' => $existing_records
+ ]);
+ $this->processResponse($api, $response);
+ }
+ }
+ }
+
+ // Fetch current DS records
+ $ds_records = [];
+ $info_response = $dnssec->getDnssecRecords(['domain' => $fields->domain]);
+ $this->logRequest($api, $info_response);
+ if ($info_response->status() == 'OK') {
+ $info = $info_response->response();
+ $raw_records = $info->attributes['dnssec'] ?? [];
+ foreach ($raw_records as $index => $record) {
+ if (is_array($record)) {
+ $record['record_index'] = $index;
+ $ds_records[] = $record;
+ }
+ }
+ }
+
+ $this->view->set('ds_records', $ds_records);
+ $this->view->set('vars', $vars);
+ $this->view->set('algorithms', [
+ '3' => '3 - DSA/SHA-1',
+ '5' => '5 - RSA/SHA-1',
+ '6' => '6 - DSA-NSEC3-SHA1',
+ '7' => '7 - RSASHA1-NSEC3-SHA1',
+ '8' => '8 - RSA/SHA-256',
+ '10' => '10 - RSA/SHA-512',
+ '13' => '13 - ECDSA/SHA-256',
+ '14' => '14 - ECDSA/SHA-384',
+ '15' => '15 - Ed25519',
+ '16' => '16 - Ed448'
+ ]);
+ $this->view->set('digest_types', [
+ '1' => '1 - SHA-1',
+ '2' => '2 - SHA-256',
+ '4' => '4 - SHA-384'
+ ]);
+ $this->view->setDefaultView('components' . DS . 'modules' . DS . 'opensrs' . DS);
+
+ return $this->view->fetch();
+ }
+
/**
* Verifies that the provided domain name is available
*
@@ -1307,7 +1968,10 @@ private function manageSettings(
*/
public function checkAvailability($domain, $module_row_id = null)
{
- $row = $this->getModuleRow($module_row_id);
+ $row = $this->getModuleRowOrFail($module_row_id);
+ if (!$row) {
+ return false;
+ }
$api = $this->getApi($row->meta->user, $row->meta->key, $row->meta->sandbox == 'true');
$domains = new OpensrsDomains($api);
@@ -1332,8 +1996,24 @@ public function checkAvailability($domain, $module_row_id = null)
*/
public function checkTransferAvailability($domain, $module_row_id = null)
{
- // Prevent users from transferring an unregistered domain
- return !$this->checkAvailability($domain, $module_row_id);
+ $row = $this->getModuleRowOrFail($module_row_id);
+ if (!$row) {
+ return false;
+ }
+ $api = $this->getApi($row->meta->user, $row->meta->key, $row->meta->sandbox == 'true');
+
+ $transfers = new OpensrsDomainsTransfer($api);
+ $result = $transfers->checkTransfer(['domain' => $domain]);
+ $this->logRequest($api, $result);
+
+ if ($result->status() != 'OK') {
+ // Fall back to inverse availability check
+ return !$this->checkAvailability($domain, $module_row_id);
+ }
+
+ $response = $result->response();
+
+ return ($response->attributes['transferrable'] ?? '0') == '1';
}
/**
@@ -1357,7 +2037,10 @@ public function checkTransferAvailability($domain, $module_row_id = null)
*/
public function getDomainContacts($domain, $module_row_id = null)
{
- $row = $this->getModuleRow($module_row_id);
+ $row = $this->getModuleRowOrFail($module_row_id);
+ if (!$row) {
+ return [];
+ }
$api = $this->getApi($row->meta->user, $row->meta->key, $row->meta->sandbox == 'true');
$domains = new OpensrsDomains($api);
@@ -1366,6 +2049,10 @@ public function getDomainContacts($domain, $module_row_id = null)
'type' => 'all_info'
]);
$this->processResponse($api, $response);
+
+ if ($response->status() != 'OK') {
+ return [];
+ }
$response = $response->response();
$contacts = $response->attributes['contact_set'] ?? [];
@@ -1402,7 +2089,10 @@ public function getDomainContacts($domain, $module_row_id = null)
*/
public function setDomainContacts($domain, array $vars = [], $module_row_id = null)
{
- $row = $this->getModuleRow($module_row_id);
+ $row = $this->getModuleRowOrFail($module_row_id);
+ if (!$row) {
+ return false;
+ }
$api = $this->getApi($row->meta->user, $row->meta->key, $row->meta->sandbox == 'true');
$domains_provisioning = new OpensrsDomainsProvisioning($api);
@@ -1411,7 +2101,7 @@ public function setDomainContacts($domain, array $vars = [], $module_row_id = nu
$contact_set = [];
foreach ($vars as $contact) {
$contact['phone'] = $this->formatPhone($contact['phone'], $contact['country']);
- $contact['postal_code'] = $contact['zip'] ?? '00000';
+ $contact['postal_code'] = $contact['postal_code'] ?? $contact['zip'] ?? '00000';
$contact_set[$contact['external_id'] ?? 'owner'] = $contact;
}
@@ -1438,7 +2128,10 @@ public function setDomainContacts($domain, array $vars = [], $module_row_id = nu
*/
public function getDomainInfo($domain, $module_row_id = null)
{
- $row = $this->getModuleRow($module_row_id);
+ $row = $this->getModuleRowOrFail($module_row_id);
+ if (!$row) {
+ return [];
+ }
$api = $this->getApi($row->meta->user, $row->meta->key, $row->meta->sandbox == 'true');
$domains = new OpensrsDomains($api);
@@ -1447,6 +2140,10 @@ public function getDomainInfo($domain, $module_row_id = null)
'type' => 'all_info'
]);
$this->processResponse($api, $response);
+
+ if ($response->status() != 'OK') {
+ return [];
+ }
$response = $response->response();
return $response->attributes ?? [];
@@ -1461,7 +2158,10 @@ public function getDomainInfo($domain, $module_row_id = null)
*/
public function getDomainIsLocked($domain, $module_row_id = null)
{
- $row = $this->getModuleRow($module_row_id);
+ $row = $this->getModuleRowOrFail($module_row_id);
+ if (!$row) {
+ return false;
+ }
$api = $this->getApi($row->meta->user, $row->meta->key, $row->meta->sandbox == 'true');
$domains = new OpensrsDomains($api);
@@ -1470,9 +2170,13 @@ public function getDomainIsLocked($domain, $module_row_id = null)
'type' => 'status'
]);
$this->processResponse($api, $response);
+
+ if ($response->status() != 'OK') {
+ return false;
+ }
$response = $response->response();
- return $response->attributes['lock_state'] == '1';
+ return ($response->attributes['lock_state'] ?? '0') == '1';
}
/**
@@ -1484,7 +2188,10 @@ public function getDomainIsLocked($domain, $module_row_id = null)
*/
private function getDomainIsPrivate($domain, $module_row_id = null)
{
- $row = $this->getModuleRow($module_row_id);
+ $row = $this->getModuleRowOrFail($module_row_id);
+ if (!$row) {
+ return false;
+ }
$api = $this->getApi($row->meta->user, $row->meta->key, $row->meta->sandbox == 'true');
$domains = new OpensrsDomains($api);
@@ -1493,9 +2200,13 @@ private function getDomainIsPrivate($domain, $module_row_id = null)
'type' => 'whois_privacy_state'
]);
$this->processResponse($api, $response);
+
+ if ($response->status() != 'OK') {
+ return false;
+ }
$response = $response->response();
- return $response->attributes['state'] == 'enabled';
+ return ($response->attributes['state'] ?? 'disabled') == 'enabled';
}
/**
@@ -1513,10 +2224,10 @@ public function getDomainNameServers($domain, $module_row_id = null)
$domain_info = $this->getDomainInfo($domain, $module_row_id);
$nameservers = [];
- foreach ($domain_info['nameserver_list'] as $nameserver) {
+ foreach ($domain_info['nameserver_list'] ?? [] as $nameserver) {
$nameservers[] = [
'url' => $nameserver['name'] ?? '',
- 'ips' => [$nameserver['ipaddress'] ?? gethostbyname($nameserver['name'] ?? '')]
+ 'ips' => [$nameserver['ipaddress'] ?? '']
];
}
@@ -1533,10 +2244,13 @@ public function getDomainNameServers($domain, $module_row_id = null)
*/
public function setDomainNameservers($domain, $module_row_id = null, array $vars = [])
{
- $row = $this->getModuleRow($module_row_id);
+ $row = $this->getModuleRowOrFail($module_row_id);
+ if (!$row) {
+ return false;
+ }
$api = $this->getApi($row->meta->user, $row->meta->key, $row->meta->sandbox == 'true');
- $domains_provisioning = new OpensrsDomainsNs($api);
+ $domains_ns = new OpensrsDomainsNs($api);
// Remove empty nameservers
foreach ($vars as $key => $ns) {
@@ -1546,7 +2260,7 @@ public function setDomainNameservers($domain, $module_row_id = null, array $vars
}
// Update domain
- $response = $domains_provisioning->advancedUpdateNameserver([
+ $response = $domains_ns->advancedUpdateNameserver([
'domain' => $domain,
'op_type' => 'assign',
'assign_ns' => array_values($vars)
@@ -1565,7 +2279,10 @@ public function setDomainNameservers($domain, $module_row_id = null, array $vars
*/
public function lockDomain($domain, $module_row_id = null)
{
- $row = $this->getModuleRow($module_row_id);
+ $row = $this->getModuleRowOrFail($module_row_id);
+ if (!$row) {
+ return false;
+ }
$api = $this->getApi($row->meta->user, $row->meta->key, $row->meta->sandbox == 'true');
$domains_provisioning = new OpensrsDomainsProvisioning($api);
@@ -1591,7 +2308,10 @@ public function lockDomain($domain, $module_row_id = null)
*/
public function unlockDomain($domain, $module_row_id = null)
{
- $row = $this->getModuleRow($module_row_id);
+ $row = $this->getModuleRowOrFail($module_row_id);
+ if (!$row) {
+ return false;
+ }
$api = $this->getApi($row->meta->user, $row->meta->key, $row->meta->sandbox == 'true');
$domains_provisioning = new OpensrsDomainsProvisioning($api);
@@ -1620,7 +2340,10 @@ public function unlockDomain($domain, $module_row_id = null)
*/
public function registerDomain($domain, $module_row_id = null, array $vars = [])
{
- $row = $this->getModuleRow($module_row_id);
+ $row = $this->getModuleRowOrFail($module_row_id);
+ if (!$row) {
+ return false;
+ }
$api = $this->getApi($row->meta->user, $row->meta->key, $row->meta->sandbox == 'true');
// Set all whois info from client
@@ -1636,7 +2359,7 @@ public function registerDomain($domain, $module_row_id = null, array $vars = [])
'auto_renew' => 0,
'reg_type' => isset($vars['auth_info']) ? 'transfer' : 'new',
'reg_username' => 'usr' . ($client->id_value ?? $client->id ?? rand(10000, 99999)),
- 'reg_password' => substr(base64_encode(md5($client->id_value)), 0, 15),
+ 'reg_password' => substr(bin2hex(random_bytes(10)), 0, 15),
'handle' => 'process'
];
$fields = array_merge($params, $vars);
@@ -1694,7 +2417,10 @@ public function transferDomain($domain, $module_row_id = null, array $vars = [])
*/
public function renewDomain($domain, $module_row_id = null, array $vars = [])
{
- $row = $this->getModuleRow($module_row_id);
+ $row = $this->getModuleRowOrFail($module_row_id);
+ if (!$row) {
+ return false;
+ }
$api = $this->getApi($row->meta->user, $row->meta->key, $row->meta->sandbox == 'true');
$params = [
@@ -1727,7 +2453,10 @@ public function getExpirationDate($service, $format = 'Y-m-d H:i:s')
$domain = $this->getServiceDomain($service);
$module_row_id = $service->module_row_id ?? null;
- $row = $this->getModuleRow($module_row_id);
+ $row = $this->getModuleRowOrFail($module_row_id);
+ if (!$row) {
+ return false;
+ }
$api = $this->getApi($row->meta->user, $row->meta->key, $row->meta->sandbox == 'true');
$domains = new OpensrsDomains($api);
@@ -1761,7 +2490,10 @@ public function getRegistrationDate($service, $format = 'Y-m-d H:i:s')
$domain = $this->getServiceDomain($service);
$module_row_id = $service->module_row_id ?? null;
- $row = $this->getModuleRow($module_row_id);
+ $row = $this->getModuleRowOrFail($module_row_id);
+ if (!$row) {
+ return false;
+ }
$api = $this->getApi($row->meta->user, $row->meta->key, $row->meta->sandbox == 'true');
$domains = new OpensrsDomains($api);
@@ -1855,11 +2587,42 @@ private function getRowRules(&$vars)
*/
public function validateConnection($key, $user, $sandbox)
{
- $api = $this->getApi($user, $key, $sandbox == 'true');
- $domains = new OpensrsDomains($api);
- $response = $domains->lookup(['domain' => 'blesta.com'])->response();
+ try {
+ $api = $this->getApi($user, $key, $sandbox == 'true');
+ $domains = new OpensrsDomains($api);
+ $result = $domains->lookup(['domain' => 'blesta.com']);
+
+ if ($result->status() != 'OK') {
+ return false;
+ }
+
+ $response = $result->response();
+
+ return ($response->is_success ?? '0') == '1';
+ } catch (Exception $e) {
+ return false;
+ }
+ }
+
+ /**
+ * Gets a module row, setting errors if not found
+ *
+ * @param int|null $module_row_id The module row ID
+ * @return stdClass|null The module row, or null if not found
+ */
+ private function getModuleRowOrFail($module_row_id)
+ {
+ $row = $this->getModuleRow($module_row_id);
+
+ if (!$row) {
+ $this->Input->setErrors(['errors' => [
+ Language::_('Opensrs.!error.module_row.missing', true)
+ ]]);
+
+ return null;
+ }
- return $response->is_success == '1';
+ return $row;
}
/**
@@ -1889,7 +2652,8 @@ private function processResponse(OpensrsApi $api, OpensrsResponse $response)
// Set errors, if any
if ($response->status() != 'OK') {
- $errors = isset($response->errors()->response_text) ? $response->errors()->response_text : '';
+ $error_obj = $response->errors();
+ $errors = $error_obj->response_text ?? 'An unknown error occurred';
$this->Input->setErrors(['errors' => [$errors]]);
}
}
diff --git a/views/default/add_row.pdt b/views/default/add_row.pdt
index 2ebcf97..e70d4d9 100644
--- a/views/default/add_row.pdt
+++ b/views/default/add_row.pdt
@@ -20,7 +20,7 @@
Form->label($this->_('Opensrs.row_meta.key', true), 'key');
- $this->Form->fieldText('key', ($vars->key ?? null), ['id' => 'key']);
+ $this->Form->fieldPassword('key', ['id' => 'key', 'value' => ($vars->key ?? null)]);
?>
diff --git a/views/default/edit_row.pdt b/views/default/edit_row.pdt
index 4fe3300..febc204 100644
--- a/views/default/edit_row.pdt
+++ b/views/default/edit_row.pdt
@@ -20,7 +20,7 @@
Form->label($this->_('Opensrs.row_meta.key', true), 'key');
- $this->Form->fieldText('key', ($vars->key ?? null), ['id' => 'key']);
+ $this->Form->fieldPassword('key', ['id' => 'key', 'value' => ($vars->key ?? null)]);
?>
diff --git a/views/default/manage.pdt b/views/default/manage.pdt
index 80cca40..2f4c684 100644
--- a/views/default/manage.pdt
+++ b/views/default/manage.pdt
@@ -28,7 +28,7 @@
?>
>
| rows[$i]->meta->user) ? $this->Html->safe($module->rows[$i]->meta->user) : null);?> |
- rows[$i]->meta->key) ? $this->Html->safe($module->rows[$i]->meta->key) : null);?> |
+ rows[$i]->meta->key) ? $this->Html->safe(str_repeat('*', max(0, strlen($module->rows[$i]->meta->key) - 4)) . substr($module->rows[$i]->meta->key, -4)) : null);?> |
_('Opensrs.row_meta.sandbox_' . (isset($module->rows[$i]->meta->sandbox) ? $module->rows[$i]->meta->sandbox : 'false'));?> |
_('Opensrs.manage.module_rows.edit');?>
diff --git a/views/default/tab_client_dns.pdt b/views/default/tab_client_dns.pdt
new file mode 100644
index 0000000..a9758c0
--- /dev/null
+++ b/views/default/tab_client_dns.pdt
@@ -0,0 +1,102 @@
+
+
+
+ _('Opensrs.tab_dns.title');?>
+
+
+
+
+
+
+ | _('Opensrs.tab_dns.field_type');?> |
+ _('Opensrs.tab_dns.field_subdomain');?> |
+ _('Opensrs.tab_dns.field_ip_address');?> |
+ _('Opensrs.tab_dns.field_priority');?> |
+ _('Opensrs.tab_dns.field_ttl');?> |
+ |
+
+
+
+
+
+ | Html->safe($record['record_type'] ?? '');?> |
+ Html->safe($record['subdomain'] ?? '');?> |
+ Html->safe($record['ip_address'] ?? '');?> |
+ Html->safe($record['priority'] ?? '');?> |
+ Html->safe($record['ttl'] ?? '');?> |
+
+ Form->create();
+ $this->Form->fieldHidden('action', 'delete_record');
+ $this->Form->fieldHidden('record_type', strtolower($record['record_type'] ?? ''));
+ $this->Form->fieldHidden('record_index', $record['record_index'] ?? '');
+ ?>
+
+ Form->end();
+ ?>
+ |
+
+
+
+
+
+
+ _('Opensrs.tab_dns.no_records');?>
+
+
+ _('Opensrs.tab_dns.add_record');?>
+ Form->create();
+ $this->Form->fieldHidden('action', 'add_record');
+ ?>
+
+ Form->label($this->_('Opensrs.tab_dns.field_type', true), 'type');
+ $this->Form->fieldSelect('type', ($record_types ?? []), ($vars->type ?? 'A'), ['id' => 'type', 'class' => 'form-control']);
+ ?>
+
+
+ Form->label($this->_('Opensrs.tab_dns.field_subdomain', true), 'subdomain');
+ $this->Form->fieldText('subdomain', ($vars->subdomain ?? null), ['id' => 'subdomain', 'class' => 'form-control']);
+ ?>
+
+
+ Form->label($this->_('Opensrs.tab_dns.field_ip_address', true), 'ip_address');
+ $this->Form->fieldText('ip_address', ($vars->ip_address ?? null), ['id' => 'ip_address', 'class' => 'form-control']);
+ ?>
+
+
+ Form->label($this->_('Opensrs.tab_dns.field_priority', true), 'priority');
+ $this->Form->fieldText('priority', ($vars->priority ?? null), ['id' => 'priority', 'class' => 'form-control']);
+ ?>
+
+
+ Form->label($this->_('Opensrs.tab_dns.field_ttl', true), 'ttl');
+ $this->Form->fieldText('ttl', ($vars->ttl ?? '3600'), ['id' => 'ttl', 'class' => 'form-control']);
+ ?>
+
+
+ Form->end();
+ ?>
+
+
diff --git a/views/default/tab_client_dnssec.pdt b/views/default/tab_client_dnssec.pdt
new file mode 100644
index 0000000..c3497d8
--- /dev/null
+++ b/views/default/tab_client_dnssec.pdt
@@ -0,0 +1,93 @@
+
+
+
+ _('Opensrs.tab_dnssec.title');?>
+
+
+
+
+
+
+ | _('Opensrs.tab_dnssec.field_key_tag');?> |
+ _('Opensrs.tab_dnssec.field_algorithm');?> |
+ _('Opensrs.tab_dnssec.field_digest_type');?> |
+ _('Opensrs.tab_dnssec.field_digest');?> |
+ |
+
+
+
+
+
+ | Html->safe($record['key_tag'] ?? '');?> |
+ Html->safe($record['algorithm'] ?? '');?> |
+ Html->safe($record['digest_type'] ?? '');?> |
+ Html->safe(substr($record['digest'] ?? '', 0, 32) . (strlen($record['digest'] ?? '') > 32 ? '...' : ''));?> |
+
+ Form->create();
+ $this->Form->fieldHidden('action', 'delete_ds_record');
+ $this->Form->fieldHidden('record_index', $record['record_index'] ?? '');
+ ?>
+
+ Form->end();
+ ?>
+ |
+
+
+
+
+
+
+ _('Opensrs.tab_dnssec.no_records');?>
+
+
+ _('Opensrs.tab_dnssec.add_record');?>
+ Form->create();
+ $this->Form->fieldHidden('action', 'add_ds_record');
+ ?>
+
+ Form->label($this->_('Opensrs.tab_dnssec.field_key_tag', true), 'key_tag');
+ $this->Form->fieldText('key_tag', ($vars->key_tag ?? null), ['id' => 'key_tag', 'class' => 'form-control']);
+ ?>
+
+
+ Form->label($this->_('Opensrs.tab_dnssec.field_algorithm', true), 'algorithm');
+ $this->Form->fieldSelect('algorithm', ($algorithms ?? []), ($vars->algorithm ?? '13'), ['id' => 'algorithm', 'class' => 'form-control']);
+ ?>
+
+
+ Form->label($this->_('Opensrs.tab_dnssec.field_digest_type', true), 'digest_type');
+ $this->Form->fieldSelect('digest_type', ($digest_types ?? []), ($vars->digest_type ?? '2'), ['id' => 'digest_type', 'class' => 'form-control']);
+ ?>
+
+
+ Form->label($this->_('Opensrs.tab_dnssec.field_digest', true), 'digest');
+ $this->Form->fieldText('digest', ($vars->digest ?? null), ['id' => 'digest', 'class' => 'form-control']);
+ ?>
+
+
+ Form->end();
+ ?>
+
+
diff --git a/views/default/tab_client_url_forwarding.pdt b/views/default/tab_client_url_forwarding.pdt
new file mode 100644
index 0000000..782396a
--- /dev/null
+++ b/views/default/tab_client_url_forwarding.pdt
@@ -0,0 +1,85 @@
+
+
+
+ _('Opensrs.tab_url_forwarding.title');?>
+
+
+
+
+
+
+ | _('Opensrs.tab_url_forwarding.field_subdomain');?> |
+ _('Opensrs.tab_url_forwarding.field_destination');?> |
+ _('Opensrs.tab_url_forwarding.field_redirect_type');?> |
+ |
+
+
+
+
+
+ | Html->safe($record['subdomain'] ?? '@');?> |
+ Html->safe($record['ip_address'] ?? '');?> |
+ Html->safe($record['type'] ?? '301');?> |
+
+ Form->create();
+ $this->Form->fieldHidden('action', 'delete_forwarding');
+ $this->Form->fieldHidden('record_index', $record['record_index'] ?? '');
+ ?>
+
+ Form->end();
+ ?>
+ |
+
+
+
+
+
+
+ _('Opensrs.tab_url_forwarding.no_records');?>
+
+
+ _('Opensrs.tab_url_forwarding.add_record');?>
+ Form->create();
+ $this->Form->fieldHidden('action', 'set_forwarding');
+ ?>
+
+ Form->label($this->_('Opensrs.tab_url_forwarding.field_subdomain', true), 'subdomain');
+ $this->Form->fieldText('subdomain', ($vars->subdomain ?? '@'), ['id' => 'subdomain', 'class' => 'form-control']);
+ ?>
+
+
+ Form->label($this->_('Opensrs.tab_url_forwarding.field_destination', true), 'destination');
+ $this->Form->fieldText('destination', ($vars->destination ?? null), ['id' => 'destination', 'class' => 'form-control', 'placeholder' => 'https://example.com']);
+ ?>
+
+
+ Form->label($this->_('Opensrs.tab_url_forwarding.field_redirect_type', true), 'redirect_type');
+ $this->Form->fieldSelect('redirect_type', ($redirect_types ?? []), ($vars->redirect_type ?? '301'), ['id' => 'redirect_type', 'class' => 'form-control']);
+ ?>
+
+
+ Form->end();
+ ?>
+
+
diff --git a/views/default/tab_client_whois.pdt b/views/default/tab_client_whois.pdt
index a43e003..dd24e36 100644
--- a/views/default/tab_client_whois.pdt
+++ b/views/default/tab_client_whois.pdt
@@ -16,7 +16,6 @@
$key) {
?>
diff --git a/views/default/tab_dns.pdt b/views/default/tab_dns.pdt
new file mode 100644
index 0000000..a42f18b
--- /dev/null
+++ b/views/default/tab_dns.pdt
@@ -0,0 +1,117 @@
+
+
+ _('Opensrs.tab_dns.title');?>
+
+
+
+
+
+ | _('Opensrs.tab_dns.field_type');?> |
+ _('Opensrs.tab_dns.field_subdomain');?> |
+ _('Opensrs.tab_dns.field_ip_address');?> |
+ _('Opensrs.tab_dns.field_priority');?> |
+ _('Opensrs.tab_dns.field_ttl');?> |
+ _('Opensrs.tab_dns.field_options');?> |
+
+ $record) {
+ ?>
+ >
+ | Html->safe($record['record_type'] ?? '');?> |
+ Html->safe($record['subdomain'] ?? '');?> |
+ Html->safe($record['ip_address'] ?? '');?> |
+ Html->safe($record['priority'] ?? '');?> |
+ Html->safe($record['ttl'] ?? '');?> |
+
+ Form->create();
+ $this->Form->fieldHidden('action', 'delete_record');
+ $this->Form->fieldHidden('record_type', strtolower($record['record_type'] ?? ''));
+ $this->Form->fieldHidden('record_index', $record['record_index'] ?? '');
+ ?>
+
+ Form->end();
+ ?>
+ |
+
+
+
+
+
+ _('Opensrs.tab_dns.no_records');?>
+
+
+
+
+ _('Opensrs.tab_dns.add_record');?>
+
+ Form->create();
+ $this->Form->fieldHidden('action', 'add_record');
+ ?>
+
+
+ -
+ Form->label($this->_('Opensrs.tab_dns.field_type', true), 'type');
+ $this->Form->fieldSelect('type', ($record_types ?? []), ($vars->type ?? 'A'), ['id' => 'type']);
+ ?>
+
+ -
+ Form->label($this->_('Opensrs.tab_dns.field_subdomain', true), 'subdomain');
+ $this->Form->fieldText('subdomain', ($vars->subdomain ?? null), ['id' => 'subdomain']);
+ ?>
+
+ -
+ Form->label($this->_('Opensrs.tab_dns.field_ip_address', true), 'ip_address');
+ $this->Form->fieldText('ip_address', ($vars->ip_address ?? null), ['id' => 'ip_address']);
+ ?>
+
+ -
+ Form->label($this->_('Opensrs.tab_dns.field_priority', true), 'priority');
+ $this->Form->fieldText('priority', ($vars->priority ?? null), ['id' => 'priority']);
+ ?>
+
+ -
+ Form->label($this->_('Opensrs.tab_dns.field_ttl', true), 'ttl');
+ $this->Form->fieldText('ttl', ($vars->ttl ?? '3600'), ['id' => 'ttl']);
+ ?>
+
+
+
+
+ Form->fieldSubmit('save', $this->_('Opensrs.tab_dns.field_add', true), ['class' => 'btn btn-primary float-right']);
+ ?>
+
+ Form->end();
+ ?>
+
+
+ Form->create();
+ $this->Form->fieldHidden('action', 'reset_zone');
+ ?>
+
+ Form->end();
+ ?>
+
diff --git a/views/default/tab_dnssec.pdt b/views/default/tab_dnssec.pdt
new file mode 100644
index 0000000..2734aa6
--- /dev/null
+++ b/views/default/tab_dnssec.pdt
@@ -0,0 +1,95 @@
+
+
+ _('Opensrs.tab_dnssec.title');?>
+
+
+
+
+
+ | _('Opensrs.tab_dnssec.field_key_tag');?> |
+ _('Opensrs.tab_dnssec.field_algorithm');?> |
+ _('Opensrs.tab_dnssec.field_digest_type');?> |
+ _('Opensrs.tab_dnssec.field_digest');?> |
+ _('Opensrs.tab_dns.field_options');?> |
+
+ $record) {
+ ?>
+ >
+ | Html->safe($record['key_tag'] ?? '');?> |
+ Html->safe($record['algorithm'] ?? '');?> |
+ Html->safe($record['digest_type'] ?? '');?> |
+ Html->safe(substr($record['digest'] ?? '', 0, 32) . (strlen($record['digest'] ?? '') > 32 ? '...' : ''));?> |
+
+ Form->create();
+ $this->Form->fieldHidden('action', 'delete_ds_record');
+ $this->Form->fieldHidden('record_index', $record['record_index'] ?? '');
+ ?>
+
+ Form->end();
+ ?>
+ |
+
+
+
+
+
+ _('Opensrs.tab_dnssec.no_records');?>
+
+
+
+
+ _('Opensrs.tab_dnssec.add_record');?>
+
+ Form->create();
+ $this->Form->fieldHidden('action', 'add_ds_record');
+ ?>
+
+
+ -
+ Form->label($this->_('Opensrs.tab_dnssec.field_key_tag', true), 'key_tag');
+ $this->Form->fieldText('key_tag', ($vars->key_tag ?? null), ['id' => 'key_tag']);
+ ?>
+
+ -
+ Form->label($this->_('Opensrs.tab_dnssec.field_algorithm', true), 'algorithm');
+ $this->Form->fieldSelect('algorithm', ($algorithms ?? []), ($vars->algorithm ?? '13'), ['id' => 'algorithm']);
+ ?>
+
+ -
+ Form->label($this->_('Opensrs.tab_dnssec.field_digest_type', true), 'digest_type');
+ $this->Form->fieldSelect('digest_type', ($digest_types ?? []), ($vars->digest_type ?? '2'), ['id' => 'digest_type']);
+ ?>
+
+ -
+ Form->label($this->_('Opensrs.tab_dnssec.field_digest', true), 'digest');
+ $this->Form->fieldText('digest', ($vars->digest ?? null), ['id' => 'digest']);
+ ?>
+
+
+
+
+ Form->fieldSubmit('save', $this->_('Opensrs.tab_dnssec.field_add', true), ['class' => 'btn btn-primary float-right']);
+ ?>
+
+ Form->end();
+ ?>
diff --git a/views/default/tab_url_forwarding.pdt b/views/default/tab_url_forwarding.pdt
new file mode 100644
index 0000000..897c084
--- /dev/null
+++ b/views/default/tab_url_forwarding.pdt
@@ -0,0 +1,87 @@
+
+
+ _('Opensrs.tab_url_forwarding.title');?>
+
+
+
+
+
+ | _('Opensrs.tab_url_forwarding.field_subdomain');?> |
+ _('Opensrs.tab_url_forwarding.field_destination');?> |
+ _('Opensrs.tab_url_forwarding.field_redirect_type');?> |
+ _('Opensrs.tab_dns.field_options');?> |
+
+ $record) {
+ ?>
+ >
+ | Html->safe($record['subdomain'] ?? '@');?> |
+ Html->safe($record['ip_address'] ?? '');?> |
+ Html->safe($record['type'] ?? '301');?> |
+
+ Form->create();
+ $this->Form->fieldHidden('action', 'delete_forwarding');
+ $this->Form->fieldHidden('record_index', $record['record_index'] ?? '');
+ ?>
+
+ Form->end();
+ ?>
+ |
+
+
+
+
+
+ _('Opensrs.tab_url_forwarding.no_records');?>
+
+
+
+
+ _('Opensrs.tab_url_forwarding.add_record');?>
+
+ Form->create();
+ $this->Form->fieldHidden('action', 'set_forwarding');
+ ?>
+
+
+ -
+ Form->label($this->_('Opensrs.tab_url_forwarding.field_subdomain', true), 'subdomain');
+ $this->Form->fieldText('subdomain', ($vars->subdomain ?? '@'), ['id' => 'subdomain']);
+ ?>
+
+ -
+ Form->label($this->_('Opensrs.tab_url_forwarding.field_destination', true), 'destination');
+ $this->Form->fieldText('destination', ($vars->destination ?? null), ['id' => 'destination', 'placeholder' => 'https://example.com']);
+ ?>
+
+ -
+ Form->label($this->_('Opensrs.tab_url_forwarding.field_redirect_type', true), 'redirect_type');
+ $this->Form->fieldSelect('redirect_type', ($redirect_types ?? []), ($vars->redirect_type ?? '301'), ['id' => 'redirect_type']);
+ ?>
+
+
+
+
+ Form->fieldSubmit('save', $this->_('Opensrs.tab_url_forwarding.field_add', true), ['class' => 'btn btn-primary float-right']);
+ ?>
+
+ Form->end();
+ ?>
|