mirror of
https://github.com/google/nomulus.git
synced 2025-04-30 03:57:51 +02:00
Add REMOVEPACKAGE token functionality to domain transfer flow (#1792)
This commit is contained in:
parent
527bf82370
commit
5ec4ec3af5
5 changed files with 119 additions and 19 deletions
|
@ -32,6 +32,8 @@ import static google.registry.flows.domain.DomainTransferUtils.createLosingTrans
|
||||||
import static google.registry.flows.domain.DomainTransferUtils.createPendingTransferData;
|
import static google.registry.flows.domain.DomainTransferUtils.createPendingTransferData;
|
||||||
import static google.registry.flows.domain.DomainTransferUtils.createTransferResponse;
|
import static google.registry.flows.domain.DomainTransferUtils.createTransferResponse;
|
||||||
import static google.registry.flows.domain.DomainTransferUtils.createTransferServerApproveEntities;
|
import static google.registry.flows.domain.DomainTransferUtils.createTransferServerApproveEntities;
|
||||||
|
import static google.registry.flows.domain.token.AllocationTokenFlowUtils.maybeApplyPackageRemovalToken;
|
||||||
|
import static google.registry.flows.domain.token.AllocationTokenFlowUtils.verifyTokenAllowedOnDomain;
|
||||||
import static google.registry.model.eppoutput.Result.Code.SUCCESS_WITH_ACTION_PENDING;
|
import static google.registry.model.eppoutput.Result.Code.SUCCESS_WITH_ACTION_PENDING;
|
||||||
import static google.registry.model.reporting.HistoryEntry.Type.DOMAIN_TRANSFER_REQUEST;
|
import static google.registry.model.reporting.HistoryEntry.Type.DOMAIN_TRANSFER_REQUEST;
|
||||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||||
|
@ -63,6 +65,7 @@ import google.registry.model.domain.fee.FeeTransferCommandExtension;
|
||||||
import google.registry.model.domain.fee.FeeTransformResponseExtension;
|
import google.registry.model.domain.fee.FeeTransformResponseExtension;
|
||||||
import google.registry.model.domain.metadata.MetadataExtension;
|
import google.registry.model.domain.metadata.MetadataExtension;
|
||||||
import google.registry.model.domain.superuser.DomainTransferRequestSuperuserExtension;
|
import google.registry.model.domain.superuser.DomainTransferRequestSuperuserExtension;
|
||||||
|
import google.registry.model.domain.token.AllocationToken;
|
||||||
import google.registry.model.domain.token.AllocationTokenExtension;
|
import google.registry.model.domain.token.AllocationTokenExtension;
|
||||||
import google.registry.model.eppcommon.AuthInfo;
|
import google.registry.model.eppcommon.AuthInfo;
|
||||||
import google.registry.model.eppcommon.StatusValue;
|
import google.registry.model.eppcommon.StatusValue;
|
||||||
|
@ -132,6 +135,8 @@ import org.joda.time.DateTime;
|
||||||
* google.registry.flows.domain.token.AllocationTokenFlowUtils.AllocationTokenNotValidForTldException}
|
* google.registry.flows.domain.token.AllocationTokenFlowUtils.AllocationTokenNotValidForTldException}
|
||||||
* @error {@link
|
* @error {@link
|
||||||
* google.registry.flows.domain.token.AllocationTokenFlowUtils.AlreadyRedeemedAllocationTokenException}
|
* google.registry.flows.domain.token.AllocationTokenFlowUtils.AlreadyRedeemedAllocationTokenException}
|
||||||
|
* @error {@link
|
||||||
|
* google.registry.flows.domain.token.AllocationTokenFlowUtils.MissingRemovePackageTokenOnPackageDomainException}
|
||||||
*/
|
*/
|
||||||
@ReportingSpec(ActivityReportField.DOMAIN_TRANSFER_REQUEST)
|
@ReportingSpec(ActivityReportField.DOMAIN_TRANSFER_REQUEST)
|
||||||
public final class DomainTransferRequestFlow implements TransactionalFlow {
|
public final class DomainTransferRequestFlow implements TransactionalFlow {
|
||||||
|
@ -169,19 +174,24 @@ public final class DomainTransferRequestFlow implements TransactionalFlow {
|
||||||
extensionManager.validate();
|
extensionManager.validate();
|
||||||
DateTime now = tm().getTransactionTime();
|
DateTime now = tm().getTransactionTime();
|
||||||
Domain existingDomain = loadAndVerifyExistence(Domain.class, targetId, now);
|
Domain existingDomain = loadAndVerifyExistence(Domain.class, targetId, now);
|
||||||
allocationTokenFlowUtils.verifyAllocationTokenIfPresent(
|
Optional<AllocationToken> allocationToken =
|
||||||
existingDomain,
|
allocationTokenFlowUtils.verifyAllocationTokenIfPresent(
|
||||||
Registry.get(existingDomain.getTld()),
|
existingDomain,
|
||||||
gainingClientId,
|
Registry.get(existingDomain.getTld()),
|
||||||
now,
|
gainingClientId,
|
||||||
eppInput.getSingleExtension(AllocationTokenExtension.class));
|
now,
|
||||||
|
eppInput.getSingleExtension(AllocationTokenExtension.class));
|
||||||
Optional<DomainTransferRequestSuperuserExtension> superuserExtension =
|
Optional<DomainTransferRequestSuperuserExtension> superuserExtension =
|
||||||
eppInput.getSingleExtension(DomainTransferRequestSuperuserExtension.class);
|
eppInput.getSingleExtension(DomainTransferRequestSuperuserExtension.class);
|
||||||
Period period =
|
Period period =
|
||||||
superuserExtension.isPresent()
|
superuserExtension.isPresent()
|
||||||
? superuserExtension.get().getRenewalPeriod()
|
? superuserExtension.get().getRenewalPeriod()
|
||||||
: ((Transfer) resourceCommand).getPeriod();
|
: ((Transfer) resourceCommand).getPeriod();
|
||||||
verifyTransferAllowed(existingDomain, period, now, superuserExtension);
|
verifyTransferAllowed(existingDomain, period, now, superuserExtension, allocationToken);
|
||||||
|
|
||||||
|
// If client passed an applicable static token this updates the domain
|
||||||
|
existingDomain = maybeApplyPackageRemovalToken(existingDomain, allocationToken);
|
||||||
|
|
||||||
String tld = existingDomain.getTld();
|
String tld = existingDomain.getTld();
|
||||||
Registry registry = Registry.get(tld);
|
Registry registry = Registry.get(tld);
|
||||||
// An optional extension from the client specifying what they think the transfer should cost.
|
// An optional extension from the client specifying what they think the transfer should cost.
|
||||||
|
@ -293,9 +303,11 @@ public final class DomainTransferRequestFlow implements TransactionalFlow {
|
||||||
Domain existingDomain,
|
Domain existingDomain,
|
||||||
Period period,
|
Period period,
|
||||||
DateTime now,
|
DateTime now,
|
||||||
Optional<DomainTransferRequestSuperuserExtension> superuserExtension)
|
Optional<DomainTransferRequestSuperuserExtension> superuserExtension,
|
||||||
|
Optional<AllocationToken> allocationToken)
|
||||||
throws EppException {
|
throws EppException {
|
||||||
verifyNoDisallowedStatuses(existingDomain, DISALLOWED_STATUSES);
|
verifyNoDisallowedStatuses(existingDomain, DISALLOWED_STATUSES);
|
||||||
|
verifyTokenAllowedOnDomain(existingDomain, allocationToken);
|
||||||
if (!isSuperuser) {
|
if (!isSuperuser) {
|
||||||
verifyAuthInfoPresentForResourceTransfer(authInfo);
|
verifyAuthInfoPresentForResourceTransfer(authInfo);
|
||||||
verifyAuthInfo(authInfo.get(), existingDomain);
|
verifyAuthInfo(authInfo.get(), existingDomain);
|
||||||
|
|
|
@ -293,11 +293,11 @@ public class AllocationTokenFlowUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The __REMOVEPACKAGE__ token is missing on a renew package domain command */
|
/** The __REMOVEPACKAGE__ token is missing on a package domain command */
|
||||||
public static class MissingRemovePackageTokenOnPackageDomainException
|
public static class MissingRemovePackageTokenOnPackageDomainException
|
||||||
extends AssociationProhibitsOperationException {
|
extends AssociationProhibitsOperationException {
|
||||||
MissingRemovePackageTokenOnPackageDomainException() {
|
MissingRemovePackageTokenOnPackageDomainException() {
|
||||||
super("Domains that are inside packages cannot be explicitly renewed");
|
super("Domains that are inside packages cannot be explicitly renewed or transferred");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,9 @@ import static com.google.common.truth.Truth8.assertThat;
|
||||||
import static google.registry.batch.AsyncTaskEnqueuer.PARAM_REQUESTED_TIME;
|
import static google.registry.batch.AsyncTaskEnqueuer.PARAM_REQUESTED_TIME;
|
||||||
import static google.registry.batch.AsyncTaskEnqueuer.PARAM_RESOURCE_KEY;
|
import static google.registry.batch.AsyncTaskEnqueuer.PARAM_RESOURCE_KEY;
|
||||||
import static google.registry.batch.AsyncTaskEnqueuer.QUEUE_ASYNC_ACTIONS;
|
import static google.registry.batch.AsyncTaskEnqueuer.QUEUE_ASYNC_ACTIONS;
|
||||||
|
import static google.registry.model.billing.BillingEvent.RenewalPriceBehavior.DEFAULT;
|
||||||
|
import static google.registry.model.billing.BillingEvent.RenewalPriceBehavior.SPECIFIED;
|
||||||
|
import static google.registry.model.domain.token.AllocationToken.TokenType.PACKAGE;
|
||||||
import static google.registry.model.domain.token.AllocationToken.TokenType.SINGLE_USE;
|
import static google.registry.model.domain.token.AllocationToken.TokenType.SINGLE_USE;
|
||||||
import static google.registry.model.domain.token.AllocationToken.TokenType.UNLIMITED_USE;
|
import static google.registry.model.domain.token.AllocationToken.TokenType.UNLIMITED_USE;
|
||||||
import static google.registry.model.reporting.DomainTransactionRecord.TransactionReportField.TRANSFER_SUCCESSFUL;
|
import static google.registry.model.reporting.DomainTransactionRecord.TransactionReportField.TRANSFER_SUCCESSFUL;
|
||||||
|
@ -61,6 +64,7 @@ import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import com.google.common.collect.Streams;
|
import com.google.common.collect.Streams;
|
||||||
|
import com.google.common.truth.Truth8;
|
||||||
import com.googlecode.objectify.Key;
|
import com.googlecode.objectify.Key;
|
||||||
import google.registry.batch.ResaveEntityAction;
|
import google.registry.batch.ResaveEntityAction;
|
||||||
import google.registry.flows.EppException;
|
import google.registry.flows.EppException;
|
||||||
|
@ -85,6 +89,7 @@ import google.registry.flows.domain.token.AllocationTokenFlowUtils.AllocationTok
|
||||||
import google.registry.flows.domain.token.AllocationTokenFlowUtils.AllocationTokenNotValidForTldException;
|
import google.registry.flows.domain.token.AllocationTokenFlowUtils.AllocationTokenNotValidForTldException;
|
||||||
import google.registry.flows.domain.token.AllocationTokenFlowUtils.AlreadyRedeemedAllocationTokenException;
|
import google.registry.flows.domain.token.AllocationTokenFlowUtils.AlreadyRedeemedAllocationTokenException;
|
||||||
import google.registry.flows.domain.token.AllocationTokenFlowUtils.InvalidAllocationTokenException;
|
import google.registry.flows.domain.token.AllocationTokenFlowUtils.InvalidAllocationTokenException;
|
||||||
|
import google.registry.flows.domain.token.AllocationTokenFlowUtils.MissingRemovePackageTokenOnPackageDomainException;
|
||||||
import google.registry.flows.exceptions.AlreadyPendingTransferException;
|
import google.registry.flows.exceptions.AlreadyPendingTransferException;
|
||||||
import google.registry.flows.exceptions.InvalidTransferPeriodValueException;
|
import google.registry.flows.exceptions.InvalidTransferPeriodValueException;
|
||||||
import google.registry.flows.exceptions.MissingTransferRequestAuthInfoException;
|
import google.registry.flows.exceptions.MissingTransferRequestAuthInfoException;
|
||||||
|
@ -1700,13 +1705,15 @@ class DomainTransferRequestFlowTest
|
||||||
.setDomainName("example.tld")
|
.setDomainName("example.tld")
|
||||||
.build());
|
.build());
|
||||||
doSuccessfulTest(
|
doSuccessfulTest(
|
||||||
"domain_transfer_request_allocation_token.xml", "domain_transfer_request_response.xml");
|
"domain_transfer_request_allocation_token.xml",
|
||||||
|
"domain_transfer_request_response.xml",
|
||||||
|
ImmutableMap.of("TOKEN", "abc123"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testFailure_invalidAllocationToken() throws Exception {
|
void testFailure_invalidAllocationToken() throws Exception {
|
||||||
setupDomain("example", "tld");
|
setupDomain("example", "tld");
|
||||||
setEppInput("domain_transfer_request_allocation_token.xml");
|
setEppInput("domain_transfer_request_allocation_token.xml", ImmutableMap.of("TOKEN", "abc123"));
|
||||||
EppException thrown = assertThrows(InvalidAllocationTokenException.class, this::runFlow);
|
EppException thrown = assertThrows(InvalidAllocationTokenException.class, this::runFlow);
|
||||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||||
}
|
}
|
||||||
|
@ -1720,7 +1727,7 @@ class DomainTransferRequestFlowTest
|
||||||
.setTokenType(SINGLE_USE)
|
.setTokenType(SINGLE_USE)
|
||||||
.setDomainName("otherdomain.tld")
|
.setDomainName("otherdomain.tld")
|
||||||
.build());
|
.build());
|
||||||
setEppInput("domain_transfer_request_allocation_token.xml");
|
setEppInput("domain_transfer_request_allocation_token.xml", ImmutableMap.of("TOKEN", "abc123"));
|
||||||
EppException thrown =
|
EppException thrown =
|
||||||
assertThrows(AllocationTokenNotValidForDomainException.class, this::runFlow);
|
assertThrows(AllocationTokenNotValidForDomainException.class, this::runFlow);
|
||||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||||
|
@ -1741,7 +1748,7 @@ class DomainTransferRequestFlowTest
|
||||||
.put(clock.nowUtc().plusDays(60), TokenStatus.ENDED)
|
.put(clock.nowUtc().plusDays(60), TokenStatus.ENDED)
|
||||||
.build())
|
.build())
|
||||||
.build());
|
.build());
|
||||||
setEppInput("domain_transfer_request_allocation_token.xml");
|
setEppInput("domain_transfer_request_allocation_token.xml", ImmutableMap.of("TOKEN", "abc123"));
|
||||||
EppException thrown = assertThrows(AllocationTokenNotInPromotionException.class, this::runFlow);
|
EppException thrown = assertThrows(AllocationTokenNotInPromotionException.class, this::runFlow);
|
||||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||||
}
|
}
|
||||||
|
@ -1762,7 +1769,7 @@ class DomainTransferRequestFlowTest
|
||||||
.put(clock.nowUtc().plusDays(1), TokenStatus.ENDED)
|
.put(clock.nowUtc().plusDays(1), TokenStatus.ENDED)
|
||||||
.build())
|
.build())
|
||||||
.build());
|
.build());
|
||||||
setEppInput("domain_transfer_request_allocation_token.xml");
|
setEppInput("domain_transfer_request_allocation_token.xml", ImmutableMap.of("TOKEN", "abc123"));
|
||||||
EppException thrown =
|
EppException thrown =
|
||||||
assertThrows(AllocationTokenNotValidForRegistrarException.class, this::runFlow);
|
assertThrows(AllocationTokenNotValidForRegistrarException.class, this::runFlow);
|
||||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||||
|
@ -1784,7 +1791,7 @@ class DomainTransferRequestFlowTest
|
||||||
.put(clock.nowUtc().plusDays(1), TokenStatus.ENDED)
|
.put(clock.nowUtc().plusDays(1), TokenStatus.ENDED)
|
||||||
.build())
|
.build())
|
||||||
.build());
|
.build());
|
||||||
setEppInput("domain_transfer_request_allocation_token.xml");
|
setEppInput("domain_transfer_request_allocation_token.xml", ImmutableMap.of("TOKEN", "abc123"));
|
||||||
EppException thrown = assertThrows(AllocationTokenNotValidForTldException.class, this::runFlow);
|
EppException thrown = assertThrows(AllocationTokenNotValidForTldException.class, this::runFlow);
|
||||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||||
}
|
}
|
||||||
|
@ -1800,9 +1807,89 @@ class DomainTransferRequestFlowTest
|
||||||
.setTokenType(SINGLE_USE)
|
.setTokenType(SINGLE_USE)
|
||||||
.setRedemptionHistoryEntry(HistoryEntry.createVKey(historyEntryKey))
|
.setRedemptionHistoryEntry(HistoryEntry.createVKey(historyEntryKey))
|
||||||
.build());
|
.build());
|
||||||
setEppInput("domain_transfer_request_allocation_token.xml");
|
setEppInput("domain_transfer_request_allocation_token.xml", ImmutableMap.of("TOKEN", "abc123"));
|
||||||
EppException thrown =
|
EppException thrown =
|
||||||
assertThrows(AlreadyRedeemedAllocationTokenException.class, this::runFlow);
|
assertThrows(AlreadyRedeemedAllocationTokenException.class, this::runFlow);
|
||||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFailsPackageDomainInvalidAllocationToken() throws Exception {
|
||||||
|
AllocationToken token =
|
||||||
|
persistResource(
|
||||||
|
new AllocationToken.Builder()
|
||||||
|
.setToken("abc123")
|
||||||
|
.setTokenType(PACKAGE)
|
||||||
|
.setAllowedRegistrarIds(ImmutableSet.of("NewRegistrar"))
|
||||||
|
.setAllowedTlds(ImmutableSet.of("example", "tld"))
|
||||||
|
.setRenewalPriceBehavior(SPECIFIED)
|
||||||
|
.build());
|
||||||
|
setupDomain("example", "tld");
|
||||||
|
persistResource(
|
||||||
|
reloadResourceByForeignKey()
|
||||||
|
.asBuilder()
|
||||||
|
.setCurrentPackageToken(token.createVKey())
|
||||||
|
.build());
|
||||||
|
|
||||||
|
setEppInput("domain_transfer_request_allocation_token.xml", ImmutableMap.of("TOKEN", "abc123"));
|
||||||
|
assertThrows(MissingRemovePackageTokenOnPackageDomainException.class, this::runFlow);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFailsToTransferPackageDomainNoRemovePackageToken() throws Exception {
|
||||||
|
AllocationToken token =
|
||||||
|
persistResource(
|
||||||
|
new AllocationToken.Builder()
|
||||||
|
.setToken("abc123")
|
||||||
|
.setTokenType(PACKAGE)
|
||||||
|
.setAllowedRegistrarIds(ImmutableSet.of("NewRegistrar"))
|
||||||
|
.setAllowedTlds(ImmutableSet.of("example", "tld"))
|
||||||
|
.setRenewalPriceBehavior(SPECIFIED)
|
||||||
|
.build());
|
||||||
|
setupDomain("example", "tld");
|
||||||
|
persistResource(
|
||||||
|
reloadResourceByForeignKey()
|
||||||
|
.asBuilder()
|
||||||
|
.setCurrentPackageToken(token.createVKey())
|
||||||
|
.build());
|
||||||
|
|
||||||
|
setEppInput("domain_transfer_request.xml");
|
||||||
|
assertThrows(MissingRemovePackageTokenOnPackageDomainException.class, this::runFlow);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testSuccesfullyAppliesRemovePackageToken() throws Exception {
|
||||||
|
setupDomain("example", "tld");
|
||||||
|
AllocationToken token =
|
||||||
|
persistResource(
|
||||||
|
new AllocationToken.Builder()
|
||||||
|
.setToken("abc123")
|
||||||
|
.setTokenType(PACKAGE)
|
||||||
|
.setAllowedRegistrarIds(ImmutableSet.of("TheRegistrar"))
|
||||||
|
.setAllowedTlds(ImmutableSet.of("tld"))
|
||||||
|
.setRenewalPriceBehavior(SPECIFIED)
|
||||||
|
.build());
|
||||||
|
domain = loadByEntity(domain);
|
||||||
|
persistResource(
|
||||||
|
loadByKey(domain.getAutorenewBillingEvent())
|
||||||
|
.asBuilder()
|
||||||
|
.setRenewalPriceBehavior(RenewalPriceBehavior.SPECIFIED)
|
||||||
|
.setRenewalPrice(Money.of(USD, new BigDecimal("10.00")))
|
||||||
|
.build());
|
||||||
|
persistResource(
|
||||||
|
reloadResourceByForeignKey()
|
||||||
|
.asBuilder()
|
||||||
|
.setCurrentPackageToken(token.createVKey())
|
||||||
|
.build());
|
||||||
|
|
||||||
|
doSuccessfulTest(
|
||||||
|
"domain_transfer_request_allocation_token.xml",
|
||||||
|
"domain_transfer_request_response.xml",
|
||||||
|
ImmutableMap.of("TOKEN", "__REMOVEPACKAGE__"));
|
||||||
|
Domain domain = reloadResourceByForeignKey();
|
||||||
|
Truth8.assertThat(domain.getCurrentPackageToken()).isEmpty();
|
||||||
|
RenewalPriceBehavior priceBehavior =
|
||||||
|
loadByKey(domain.getAutorenewBillingEvent()).getRenewalPriceBehavior();
|
||||||
|
assertThat(priceBehavior).isEqualTo(DEFAULT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
<allocationToken:allocationToken
|
<allocationToken:allocationToken
|
||||||
xmlns:allocationToken=
|
xmlns:allocationToken=
|
||||||
"urn:ietf:params:xml:ns:allocationToken-1.0">
|
"urn:ietf:params:xml:ns:allocationToken-1.0">
|
||||||
abc123
|
%TOKEN%
|
||||||
</allocationToken:allocationToken>
|
</allocationToken:allocationToken>
|
||||||
</extension>
|
</extension>
|
||||||
<clTRID>ABC-12345</clTRID>
|
<clTRID>ABC-12345</clTRID>
|
||||||
|
|
|
@ -498,7 +498,7 @@ comes in at the exact millisecond that the domain would have expired.
|
||||||
* Resource status prohibits this operation.
|
* Resource status prohibits this operation.
|
||||||
* The allocation token is not currently valid.
|
* The allocation token is not currently valid.
|
||||||
* 2305
|
* 2305
|
||||||
* The __REMOVEPACKAGE__ token is missing on a renew package domain command
|
* The __REMOVEPACKAGE__ token is missing on a package domain command
|
||||||
* The __REMOVEPACKAGE__ token is not allowed on non package domains
|
* The __REMOVEPACKAGE__ token is not allowed on non package domains
|
||||||
* The allocation token is not valid for this domain.
|
* The allocation token is not valid for this domain.
|
||||||
* The allocation token is not valid for this registrar.
|
* The allocation token is not valid for this registrar.
|
||||||
|
@ -754,6 +754,7 @@ new ones with the correct approval time).
|
||||||
* The allocation token is not valid for this registrar.
|
* The allocation token is not valid for this registrar.
|
||||||
* The allocation token is not valid for this TLD.
|
* The allocation token is not valid for this TLD.
|
||||||
* The allocation token was already redeemed.
|
* The allocation token was already redeemed.
|
||||||
|
* The __REMOVEPACKAGE__ token is missing on a package domain command
|
||||||
* 2306
|
* 2306
|
||||||
* Domain transfer period must be one year.
|
* Domain transfer period must be one year.
|
||||||
* Domain transfer period must be zero or one year when using the superuser
|
* Domain transfer period must be zero or one year when using the superuser
|
||||||
|
|
Loading…
Add table
Reference in a new issue