Conversation
added 13 commits
August 21, 2026 10:23
- Add CURLOPT_CONNECTTIMEOUT (30s) and CURLOPT_TIMEOUT (60s) to prevent hanging requests on unresponsive API endpoints - Return empty OpensrsResponse instead of passing false to constructor when curl_exec fails, preventing downstream type errors - Fix $siganture typo to $signature (cosmetic, no functional impact as the variable was used consistently) - Escape XML attribute values with htmlspecialchars() to prevent malformed XML from special characters in domain contact data - Make raw() null-safe with ?? '' fallback - status() no longer returns null for invalid responses, so callers can safely compare without null checks - Harden validateConnection() with try/catch and status()/is_success null-safety now that curl failures return an empty response object rather than throwing or returning malformed data
- Replace deterministic password (md5 of client ID) with cryptographically random password using random_bytes() - Add null-coalescing defaults for registrar_lock and whois_privacy_state POST values to prevent PHP notices - Add null check for $client before WHOIS fields loop in addService() to prevent fatal error when client_id is missing validateConnection() try/catch and null-safety already applied in the previous commit (cURL/response hardening).
- Add getModuleRowOrFail() helper that sets a user-friendly error when the module row cannot be found, instead of causing a fatal PHP error from accessing properties on null - Replace all direct getModuleRow() call sites with getModuleRowOrFail() plus early returns in: getFilteredTldPricing, manageSettings, checkAvailability, getDomainContacts, setDomainContacts, getDomainInfo, getDomainIsLocked, getDomainIsPrivate, setDomainNameservers, lockDomain, unlockDomain, registerDomain, renewDomain, getExpirationDate, getRegistrationDate - Rename misleading $domains_provisioning to $domains_ns in setDomainNameservers (it was instantiating OpensrsDomainsNs) - Add language key for module_row.missing error
- Handle null from response->errors() gracefully with fallback message - Add early returns after processResponse() in getDomainContacts, getDomainInfo, getDomainIsLocked, getDomainIsPrivate, and getDomainNameServers to prevent dereferencing null responses - Add null-coalescing for attribute access (lock_state, state) to prevent undefined index errors - Replace gethostbyname() fallback with empty string for missing IPs to avoid DNS lookups that could hang or return wrong data (a later commit reinstates a safer gethostbyname() fallback) - Guard nameserver_list iteration with ?? [] for missing key - Fix addService() blanket Input::setErrors([]) that was clearing real registration errors along with nameserver errors - Filter empty nameservers before passing to setDomainNameservers
setDomainContacts() was discarding any real postal_code value supplied in $vars, always falling back to $contact['zip'], and defaulting to '00000' when neither was present. Preserve an explicit postal_code when one is provided. Partial port of a8d5787 (upstream master) — only the postal_code fix; the DNSSEC get-endpoint fix from that commit is applied separately alongside the new DNSSEC feature port.
- Mask API key in manage view, showing only last 4 characters - Change API key input to a password field in add/edit row views - Remove unused $i variable in client WHOIS tab view - Namespace .FR domain language keys (fr_registrant_type) to prevent collision with .UK registrant_type keys that share the same key name; also fixes a pre-existing bug where .FR referenced a nonexistent Opensrs.domain.registrant_type.company language key - Update .FR config to reference the namespaced language keys
- Remove dead foreach(range(1,10)) loops wrapping pricing API calls; the API returns all periods in a single response via all_periods=1, so the loop just overwrote the same key 10 times - Fix .FR domain validation: unset company fields (VAT ID, SIREN, trademark) for 'individual' registrants, not 'organization' ones (the condition was inverted) - Replace naive checkTransferAvailability() inverse-lookup with proper OpensrsDomainsTransfer::checkTransfer() API call that checks the transferrable attribute, with fallback to old behavior
…address Restores a DNS lookup fallback so getDomainNameServers() still returns a usable IP when OpenSRS doesn't supply one, at the cost of the occasional slow/hanging lookup that an earlier commit in this branch deliberately avoided. Reinstated per explicit prioritization from upstream master.
…downs Defines Opensrs.countries as a full ISO 3166-1 alpha-2 country code map at the top of the config file. Converts free-text country inputs (owner, tech, admin, billing WHOIS contacts and the .law/.abogado jurisdiction country) to select fields backed by this lookup table.
- Create OpensrsDomainsDnssec class wrapping provisioning modify with
data='dnssec' for add/remove, and get with type='dnssec' for
fetching existing DS records
- Register tabDnssec/tabClientDnssec unconditionally in the admin and
client service tabs
- Add manageDnssec() private method handling:
- GET: Fetches existing DS records
- POST add_ds_record: Adds DS record with key_tag, algorithm,
digest_type, and digest fields
- POST delete_ds_record: Removes DS record by index
- Create tab_dnssec.pdt (admin, Bootstrap 5) and tab_client_dnssec.pdt
(client) views with a DS record table and add form
- Provide algorithm (3-16) and digest type (1,2,4) dropdowns with
human-readable labels
- Add all DNSSEC-related language keys
- Treat empty arrays as lists in buildRecursiveAttributes() so a
cleared DS record set serializes as <dt_array/> instead of
<dt_assoc/>, which OpenSRS rejects on delete
Includes fixes from upstream master applied directly during the port:
the get-DS-records endpoint uses type='dnssec' (not the incorrect
domain_auth_info from the original commit), all DNSSEC API fetches are
logged via logRequest(), and no blanket Input::setErrors([]) clears
preceding errors when the fetch fails.
- Create OpensrsDomainsForwarding class with get/set/create/delete
methods for domain forwarding via the OpenSRS API
- Register tabUrlForwarding/tabClientUrlForwarding in service tabs,
conditional on the dns_management service feature
- Add manageUrlForwarding() private method handling:
- GET: Fetches forwarding records from the DNS zone
- POST set_forwarding: Adds forwarding rule with subdomain,
destination URL, and redirect type (301/302/frame)
- POST delete_forwarding: Removes forwarding rule by index
- Create tab_url_forwarding.pdt (admin, Bootstrap 5) and
tab_client_url_forwarding.pdt (client) views
- Add language keys for all forwarding labels
Built on the existing OpensrsDomainsDns::getDnsZone()/setDnsZone()
commands already present in this codebase. Logs the final DS-zone
fetch via logRequest() and avoids clearing preceding errors on
failure, consistent with the DNSSEC tab added in the previous commit.
- Register tabDns/tabClientDns in service tab arrays, conditional on
the dns_management feature being enabled for the service
- Add manageDns() private method handling:
- GET: Fetches DNS zone records via OpensrsDomainsDns::getDnsZone()
- POST add_record: Appends new record to zone via setDnsZone()
- POST delete_record: Removes record by type and index via
setDnsZone()
- POST reset_zone: Resets zone to defaults via resetDnsZone()
- Create tab_dns.pdt (admin, Bootstrap 5) with record table, add form,
and reset button
- Create tab_client_dns.pdt (client) with a table and form matching
existing client tab patterns
- Add all DNS-related language keys
The OpensrsDomainsDns class already existed in this codebase but was
never wired into the module UI. Logs the final zone fetch via
logRequest() and avoids clearing preceding errors on failure,
consistent with the DNSSEC and URL forwarding tabs added previously.
…toreDomain - cancelService: Disables auto-renew and sets expire_action to let the domain expire at the end of the current period via the provisioning modify API - suspendService: Delegates to cancelService (standard Blesta pattern for domain modules — no OpenSRS suspend API exists) - unsuspendService: Re-enables auto-renew via provisioning modify - editService: Minimal implementation returning null to preserve existing service meta fields - restoreDomain: Wires up the existing OpensrsDomainsProvisioning::redeem() method for domains in the redemption grace period, matching the three-argument RegistrarModule::restoreDomain() parent signature (including the unused $vars parameter) so the override doesn't diverge from the base class - Add language keys for service lifecycle error messages Previously these methods fell through to RegistrarModule's default "unsupported" implementations, so cancel/suspend/unsuspend/restore from the admin or client UI silently did nothing against OpenSRS.
Contributor
Author
|
Splitting this into individual PRs per your one-fix-per-PR guidance:
Note: the nameserver-IP Closing this combined PR in favor of the above. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
An audit against the shipped 2.0.2 release found that a batch of earlier fixes and features on this fork's
masterhad diverged from upstream around Feb 2026 and never landed. This PR re-applies/re-implements them against the current2.0.2baseline as individual commits, security/correctness fixes first:Security & correctness
curl_execfailure, and escape XML attribute values inbuildRecursiveAttributes(attribute injection hardening)substr(base64_encode(md5($client->id_value)), 0, 15)) with a properly random one; add null-safety aroundregistrar_lock/whois_privacy_statePOST handlinggetModuleRow()at its ~15 call sites to prevent fatal errorsprocessResponsenull handling and add early returns on API failuressetDomainContacts.FRregistrant_typecollision bug present in the shipped 2.0.2 views)Other fixes
.FRvalidation, and inverted transfer-availability logicgethostbyname()for nameserver IPs when OpenSRS omitsipaddressOpensrs.countrieslookup table and convert country fields to dropdownsNew features
cancelService/suspendService/unsuspendService/editService/restoreDomainTest plan
php -lpasses on every changed/new file (verified locally)