Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,11 +160,20 @@ $transfer = $reg->transfer($domain, 'authcode', [$contact]);

```

### Update Auto-Renew
```php
use Utopia\Domains\Registrar\UpdateDetails;

$details = new UpdateDetails(autoRenew: true);
$reg->updateDomain($domain, $details);
```

## Library Registrar API
* **available(string $domain): bool** - Checks to see if a domain is available for registration.
* **purchase(string $domain, array|Contact $contacts, int $periodYears = 1, array $nameservers = []): Registration** - Purchase a domain name and returns a Registration object.
* **suggest(array $query, array $tlds = [], int|null $limit = null, int|null $priceMax = null, int|null $priceMin = null): array** - Suggest or search for domain names.
* **getDomain(string $domain): Domain** - Get domain details and returns a Domain object.
* **updateDomain(string $domain, UpdateDetails $details): bool** - Update domain details such as auto-renew.
* **renew(string $domain, int $periodYears): Renewal** - Renewal a domain name and returns a Renewal object.
* **transfer(string $domain, string $authCode, array|Contact $contacts, int $periodYears = 1, array $nameservers = []): Registration** - Transfer a domain name and returns a Registration object.
* **getAuthCode(string $domain): string** - Retrieve the authorization code for a domain.
Expand Down
9 changes: 2 additions & 7 deletions src/Domains/Registrar/Adapter/Mock.php
Original file line number Diff line number Diff line change
Expand Up @@ -337,20 +337,15 @@ public function renew(string $domain, int $periodYears): Renewal
* @param UpdateDetails $details
* @return bool
* @throws DomainsException
* @throws InvalidContactException
*/
public function updateDomain(string $domain, UpdateDetails $details): bool
{
if (!in_array($domain, $this->purchasedDomains)) {
throw new DomainsException("Domain {$domain} not found in mock registry", self::RESPONSE_CODE_NOT_FOUND);
}

// Extract details from UpdateDetails object
$detailsArray = $details->toArray();

// Validate contacts if present
if (isset($detailsArray['contacts']) && $detailsArray['contacts']) {
$this->validateContacts($detailsArray['contacts']);
if ($details->autoRenew === null) {
throw new DomainsException('Details must include autoRenew', 400);
}

return true;
Expand Down
34 changes: 0 additions & 34 deletions src/Domains/Registrar/Adapter/Mock/UpdateDetails.php

This file was deleted.

14 changes: 8 additions & 6 deletions src/Domains/Registrar/Adapter/NameCom.php
Original file line number Diff line number Diff line change
Expand Up @@ -420,10 +420,8 @@ public function getDomain(string $domain): Domain
*
* Example request:
* <code>
* $details = new NameComUpdateDetails(
* autorenewEnabled: true,
* privacyEnabled: true,
* locked: false
* $details = new UpdateDetails(
* autoRenew: true
* );
* $reg->updateDomain('example.com', $details);
* </code>
Expand All @@ -437,10 +435,14 @@ public function getDomain(string $domain): Domain
public function updateDomain(string $domain, UpdateDetails $details): bool
{
try {
$data = $details->toArray();
$data = [];
if ($details->autoRenew !== null) {
$data['autorenewEnabled'] = $details->autoRenew;
}

if (empty($data)) {
throw new DomainsException(
'Details must contain at least one of: autorenewEnabled, privacyEnabled, locked',
'Details must include autoRenew',
400
);
}
Expand Down
39 changes: 0 additions & 39 deletions src/Domains/Registrar/Adapter/NameCom/UpdateDetails.php

This file was deleted.

47 changes: 19 additions & 28 deletions src/Domains/Registrar/Adapter/OpenSRS.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
use Utopia\Domains\Registrar\TransferStatus;
use Utopia\Domains\Registrar\Domain;
use Utopia\Domains\Registrar\TransferStatusEnum;
use Utopia\Domains\Registrar\UpdateDetails as UpdateDetails;
use Utopia\Domains\Registrar\UpdateDetails;
use Utopia\Domains\Registrar;

class OpenSRS extends Adapter
Expand Down Expand Up @@ -578,23 +578,10 @@ public function getDomain(string $domain): Domain
/**
* Update the domain information
*
* Example request 1:
* Example request:
* <code>
* $details = new OpenSRSUpdateDetails(
* data: 'contact_info',
* contacts: [
* 'owner' => new Contact(...),
* 'admin' => new Contact(...),
* ]
* );
* $reg->updateDomain('example.com', $details);
* </code>
*
* Example request 2:
* <code>
* $details = new OpenSRSUpdateDetails(
* data: 'ca_whois_display_setting',
* display: 'FULL'
* $details = new UpdateDetails(
* autoRenew: true
* );
* $reg->updateDomain('example.com', $details);
* </code>
Expand All @@ -605,11 +592,16 @@ public function getDomain(string $domain): Domain
*/
public function updateDomain(string $domain, UpdateDetails $details): bool
{
if (!$details instanceof OpenSRS\UpdateDetails) {
throw new Exception("Invalid details type: expected OpenSRS\\UpdateDetails");
if ($details->autoRenew === null) {
throw new DomainsException('Details must include autoRenew', 400);
}

$attributes = $details->toArray();
$attributes = [
'data' => 'expire_action',
'affect_domains' => 0,
'auto_renew' => $details->autoRenew ? 1 : 0,
'let_expire' => $details->autoRenew ? 0 : 1,
];

$message = [
'object' => 'DOMAIN',
Expand All @@ -618,14 +610,6 @@ public function updateDomain(string $domain, UpdateDetails $details): bool
'attributes' => $attributes,
];

if ($details->contacts !== null) {
if ($details->data !== 'contact_info') {
throw new Exception("Invalid data: data must be 'contact_info' in order to update contacts");
}
$contacts = $this->sanitizeContacts($details->contacts);
$message['attributes']['contact_set'] = $contacts;
}

$xpath = implode('/', [
'//body',
'data_block',
Expand All @@ -642,6 +626,13 @@ public function updateDomain(string $domain, UpdateDetails $details): bool
$result = $this->send($message);
$result = $this->sanitizeResponse($result);
$elements = $result->xpath($xpath);
if (empty($elements)) {
$elements = $result->xpath('//body/data_block/dt_assoc/item[@key="is_success"]');
}

if (empty($elements)) {
throw new DomainsException('Failed to update domain: invalid response from OpenSRS', 500);
}

return (string) $elements[0] === '1';
}
Expand Down
41 changes: 0 additions & 41 deletions src/Domains/Registrar/Adapter/OpenSRS/UpdateDetails.php

This file was deleted.

11 changes: 6 additions & 5 deletions src/Domains/Registrar/UpdateDetails.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@

namespace Utopia\Domains\Registrar;

abstract class UpdateDetails
final class UpdateDetails
{
/**
* Convert details to array format
*
* @return array
* @param bool|null $autoRenew Enable or disable automatic renewal
*/
abstract public function toArray(): array;
public function __construct(
public ?bool $autoRenew = null,
) {
}
}
13 changes: 3 additions & 10 deletions tests/Registrar/Base.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,10 @@ abstract protected function getExpectedAdapterName(): string;
/**
* Get an UpdateDetails instance for testing
*
* @param array<string,mixed> $details Domain details to update
* @param array<string,Contact>|Contact|null $contacts Contacts to update
* @param bool|null $autoRenew Enable or disable automatic renewal
* @return UpdateDetails
*/
abstract protected function getUpdateDetails(array $details = [], array|Contact|null $contacts = null): UpdateDetails;
abstract protected function getUpdateDetails(?bool $autoRenew = null): UpdateDetails;

/**
* Get purchase contact info
Expand Down Expand Up @@ -270,13 +269,7 @@ public function testUpdateDomain(): void

$result = $this->getRegistrar()->updateDomain(
$testDomain,
$this->getUpdateDetails(
[
'autorenew' => true,
'data' => 'contact_info',
],
$this->getPurchaseContact('2')
)
$this->getUpdateDetails(true)
);

$this->assertTrue($result);
Expand Down
35 changes: 3 additions & 32 deletions tests/Registrar/MockTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
use Utopia\Domains\Registrar\Exception\DomainTakenException;
use Utopia\Domains\Registrar\Exception\InvalidContactException;
use Utopia\Domains\Registrar\Adapter\Mock;
use Utopia\Domains\Registrar\Adapter\Mock\UpdateDetails;
use Utopia\Domains\Registrar\UpdateDetails;

class MockTest extends Base
{
Expand Down Expand Up @@ -64,9 +64,9 @@ protected function getDefaultNameservers(): array
];
}

protected function getUpdateDetails(array $details = [], array|Contact|null $contacts = null): UpdateDetails
protected function getUpdateDetails(?bool $autoRenew = null): UpdateDetails
{
return new UpdateDetails($details, $contacts);
return new UpdateDetails($autoRenew);
}

// Mock-specific tests
Expand Down Expand Up @@ -132,35 +132,6 @@ public function testTransferWithInvalidContact(): void
$this->registrar->transfer('transfer.com', 'auth-code', [$invalidContact]);
}

public function testUpdateDomainWithInvalidContact(): void
{
$domain = 'testdomain.com';
$this->registrar->purchase($domain, $this->getPurchaseContact(), 1);

$this->expectException(InvalidContactException::class);
$this->expectExceptionMessage('missing required field');

$invalidContact = new Contact(
'', // Empty firstname
'Doe',
'+1.5551234567',
'john.doe@example.com',
'123 Main St',
'Suite 100',
'',
'San Francisco',
'CA',
'US',
'94105',
'Test Inc'
);

$this->registrar->updateDomain(
$domain,
new UpdateDetails(['data' => 'contact_info'], [$invalidContact])
);
}

public function testCheckTransferStatusWithRequestAddress(): void
{
$domain = 'example.com';
Expand Down
Loading