diff --git a/docs/flows.md b/docs/flows.md
index d69a5caa1..1330ee3c0 100644
--- a/docs/flows.md
+++ b/docs/flows.md
@@ -945,7 +945,6 @@ An EPP flow for login.
* 2103
* Specified extension is not implemented.
* 2200
- * GAE User can't access the requested registrar.
* Registrar certificate does not match stored certificate.
* Registrar IP address is not in stored whitelist.
* Registrar certificate not present.
diff --git a/java/google/registry/flows/EppConsoleAction.java b/java/google/registry/flows/EppConsoleAction.java
deleted file mode 100644
index 339d8074d..000000000
--- a/java/google/registry/flows/EppConsoleAction.java
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2017 The Nomulus Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package google.registry.flows;
-
-import com.google.appengine.api.users.UserService;
-import google.registry.model.eppcommon.ProtocolDefinition;
-import google.registry.request.Action;
-import google.registry.request.Action.Method;
-import google.registry.request.Parameter;
-import google.registry.request.Payload;
-import google.registry.request.auth.Auth;
-import google.registry.request.auth.AuthenticatedRegistrarAccessor;
-import javax.inject.Inject;
-import javax.servlet.http.HttpSession;
-
-/** Runs EPP from the console and requires GAE user authentication. */
-@Action(
- service = Action.Service.DEFAULT,
- path = "/registrar-xhr",
- method = Method.POST,
- auth = Auth.AUTH_PUBLIC_LOGGED_IN)
-public class EppConsoleAction implements Runnable {
-
- @Inject @Payload byte[] inputXmlBytes;
- @Inject HttpSession session;
- @Inject EppRequestHandler eppRequestHandler;
- @Inject UserService userService;
- @Inject AuthenticatedRegistrarAccessor registrarAccessor;
- @Inject @Parameter("clientId") String clientId;
- @Inject EppConsoleAction() {}
-
- @Override
- public void run() {
- eppRequestHandler.executeEpp(
- new StatelessRequestSessionMetadata(clientId,
- ProtocolDefinition.getVisibleServiceExtensionUris()),
- new GaeUserCredentials(registrarAccessor),
- EppRequestSource.CONSOLE,
- false, // This endpoint is never a dry run.
- false, // This endpoint is never a superuser.
- inputXmlBytes);
- }
-}
diff --git a/java/google/registry/flows/GaeUserCredentials.java b/java/google/registry/flows/GaeUserCredentials.java
deleted file mode 100644
index 9e773e000..000000000
--- a/java/google/registry/flows/GaeUserCredentials.java
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2017 The Nomulus Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package google.registry.flows;
-
-import static com.google.common.base.MoreObjects.toStringHelper;
-
-import google.registry.flows.EppException.AuthenticationErrorException;
-import google.registry.model.registrar.Registrar;
-import google.registry.request.auth.AuthenticatedRegistrarAccessor;
-import google.registry.request.auth.AuthenticatedRegistrarAccessor.RegistrarAccessDeniedException;
-
-/** Credentials provided by {@link com.google.appengine.api.users.UserService}. */
-public class GaeUserCredentials implements TransportCredentials {
-
- private final AuthenticatedRegistrarAccessor registrarAccessor;
-
- public GaeUserCredentials(AuthenticatedRegistrarAccessor registrarAccessor) {
- this.registrarAccessor = registrarAccessor;
- }
-
- @Override
- public void validate(Registrar registrar, String ignoredPassword)
- throws AuthenticationErrorException {
- try {
- registrarAccessor.verifyAccess(registrar.getClientId());
- } catch (RegistrarAccessDeniedException e) {
- throw new UserForbiddenException(e);
- }
- }
-
- @Override
- public String toString() {
- return toStringHelper(getClass()).add("user", registrarAccessor.userIdForLogging()).toString();
- }
-
- /** GAE User can't access the requested registrar. */
- public static class UserForbiddenException extends AuthenticationErrorException {
- public UserForbiddenException(RegistrarAccessDeniedException e) {
- super(e.getMessage());
- }
- }
-}
diff --git a/java/google/registry/flows/session/LoginFlow.java b/java/google/registry/flows/session/LoginFlow.java
index 78b949ad6..ea02e8438 100644
--- a/java/google/registry/flows/session/LoginFlow.java
+++ b/java/google/registry/flows/session/LoginFlow.java
@@ -51,7 +51,6 @@ import javax.inject.Inject;
* @error {@link google.registry.flows.EppException.UnimplementedExtensionException}
* @error {@link google.registry.flows.EppException.UnimplementedObjectServiceException}
* @error {@link google.registry.flows.EppException.UnimplementedProtocolVersionException}
- * @error {@link google.registry.flows.GaeUserCredentials.UserForbiddenException}
* @error {@link google.registry.flows.TlsCredentials.BadRegistrarCertificateException}
* @error {@link google.registry.flows.TlsCredentials.BadRegistrarIpAddressException}
* @error {@link google.registry.flows.TlsCredentials.MissingRegistrarCertificateException}
diff --git a/java/google/registry/module/frontend/FrontendRequestComponent.java b/java/google/registry/module/frontend/FrontendRequestComponent.java
index 42743cb83..c8d2b1352 100644
--- a/java/google/registry/module/frontend/FrontendRequestComponent.java
+++ b/java/google/registry/module/frontend/FrontendRequestComponent.java
@@ -17,7 +17,6 @@ package google.registry.module.frontend;
import dagger.Module;
import dagger.Subcomponent;
import google.registry.dns.DnsModule;
-import google.registry.flows.EppConsoleAction;
import google.registry.flows.EppTlsAction;
import google.registry.flows.FlowComponent;
import google.registry.flows.TlsCredentials.EppTlsModule;
@@ -46,7 +45,6 @@ interface FrontendRequestComponent {
ConsoleOteSetupAction consoleOteSetupAction();
ConsoleRegistrarCreatorAction consoleRegistrarCreatorAction();
ConsoleUiAction consoleUiAction();
- EppConsoleAction eppConsoleAction();
EppTlsAction eppTlsAction();
FlowComponent.Builder flowComponentBuilder();
OteStatusAction oteStatusAction();
diff --git a/java/google/registry/ui/js/component.js b/java/google/registry/ui/js/component.js
index e0f899d06..0a03269d1 100644
--- a/java/google/registry/ui/js/component.js
+++ b/java/google/registry/ui/js/component.js
@@ -14,13 +14,7 @@
goog.provide('registry.Component');
-goog.require('goog.dom');
-goog.require('goog.dom.TagName');
-goog.require('goog.dom.classlist');
-goog.require('goog.events');
goog.require('goog.events.EventHandler');
-goog.require('goog.events.EventType');
-goog.require('registry.soy.forms');
goog.require('registry.util');
goog.forwardDeclare('registry.Console');
@@ -38,16 +32,9 @@ goog.forwardDeclare('registry.Console');
* ^
* \
* |-ui/js/resource_component.js - JSON resources
- * | ^
- * | \
- * | |- ui/js/registrar/settings.js
- * |
- * |-ui/js/registrar/xml_resource_component.js - EPP resources
- * ^
- * \
- * |- ui/js/registrar/contact.js
- * |- ui/js/registrar/domain.js
- * |- ui/js/registrar/host.js
+ * ^
+ * \
+ * |- ui/js/registrar/settings.js
*
*
* @param {!registry.Console} cons the console singleton.
@@ -91,122 +78,3 @@ goog.inherits(registry.Component, goog.events.EventHandler);
registry.Component.prototype.bindToDom = function(id) {
registry.util.unbutter();
};
-
-
-// XXX: Should clean up the many remove button handler setup funcs.
-/**
- * Shared functionality for contact and host add button click events
- * to add form elements for inputing a new item name. Requires the
- * template to have:
- *
- *
- * - an add button with id="domain-[type]-add-button".
- *
- a table row with id="domain-[type]s-footer".
- *
- *
- * @param {string} type e.g. 'contact', 'host'.
- * @param {function(): string} newFieldNameFn generates new form field's name.
- * @param {function(string): (?Element)=} opt_onAddFn currying further setup.
- * @param {function()=} opt_tmpl input element template.
- * @param {!Object=} opt_tmplArgs input element template parameter object.
- * @param {boolean=} opt_disable optionally disable the add button.
- * @protected
- */
-registry.Component.prototype.addRemBtnHandlers = function(
- type,
- newFieldNameFn,
- opt_onAddFn,
- opt_tmpl,
- opt_tmplArgs,
- opt_disable) {
- var addBtnId = 'domain-' + type + '-add-button';
- var addBtn = goog.dom.getRequiredElement(addBtnId);
- if (!opt_disable) {
- addBtn.removeAttribute('disabled');
- }
- var addButtonClickCallback = function() {
- var fieldElts = [];
- var newFieldName = newFieldNameFn();
- var tmpl =
- opt_tmpl ? opt_tmpl : registry.soy.forms.inputFieldRow;
- var tmplArgs = opt_tmplArgs ? opt_tmplArgs : {
- label: 'New ' + type,
- name: newFieldName + '.value'
- };
- var newFieldInputRow = registry.util.renderBeforeRow(
- 'domain-' + type + 's-footer', tmpl, tmplArgs);
- fieldElts.push(newFieldInputRow);
- // Save the add/rem op type as a hidden elt for use by
- // determine EPP add/remove semantics in subclasses.
- // e.g. domain.js#saveItem()
- var opElt = goog.dom.createDom(goog.dom.TagName.INPUT, {
- 'type': 'hidden',
- 'name': newFieldName + '.op',
- 'value': 'add'
- });
- newFieldInputRow.lastChild.appendChild(opElt);
- if (opt_onAddFn) {
- var elt = opt_onAddFn(newFieldName);
- if (elt) {
- fieldElts.push(elt);
- }
- }
- this.appendRemoveBtn(
- goog.dom.getLastElementChild(newFieldInputRow),
- fieldElts,
- goog.bind(function() {
- this.typeCounts[type]--;
- }, this));
- this.typeCounts[type]++;
- };
- goog.events.listen(goog.dom.getRequiredElement(addBtnId),
- goog.events.EventType.CLICK,
- goog.bind(addButtonClickCallback, this));
-};
-
-
-/**
- * Helper for making an element removable.
- * @param {Element} parent The element to append the remove button to.
- * @param {(Array.|function())=} opt_eltsToRemove
- * Elements to remove when the button is clicked or Function to do
- * the removing for full customization.
- * @param {function()=} opt_cb callback will be called if no
- * customized function is given.
- */
-registry.Component.prototype.appendRemoveBtn =
- function(parent, opt_eltsToRemove, opt_cb) {
- var rmBtn = goog.dom.createDom(goog.dom.TagName.BUTTON,
- goog.getCssName('kd-button'),
- 'Remove');
- goog.dom.appendChild(parent, rmBtn);
- var clickCb;
- if (opt_eltsToRemove instanceof Function) {
- clickCb = opt_eltsToRemove;
- } else {
- var eltsToRemove = opt_eltsToRemove ? opt_eltsToRemove : [parent];
- clickCb = function() {
- for (var i = 0; i < eltsToRemove.length; i++) {
- goog.dom.removeNode(eltsToRemove[i]);
- }
- if (opt_cb) {
- opt_cb();
- }
- };
- }
- goog.events.listen(rmBtn, goog.events.EventType.CLICK, clickCb, true);
-};
-
-
-/**
- * Bind the remove button action for the given container element.
- * @param {!Element} containerElt
- */
-registry.Component.prototype.enableRemoveButton = function(containerElt) {
- var rmBtn = goog.dom.getElementByClass(
- goog.getCssName('remove'), containerElt);
- goog.dom.classlist.toggle(rmBtn, goog.getCssName('hidden'));
- goog.events.listen(rmBtn, goog.events.EventType.CLICK, function() {
- goog.dom.removeNode(goog.dom.getParentElement(rmBtn));
- });
-};
diff --git a/java/google/registry/ui/js/console.js b/java/google/registry/ui/js/console.js
index 2de59f4b6..309576b76 100644
--- a/java/google/registry/ui/js/console.js
+++ b/java/google/registry/ui/js/console.js
@@ -24,17 +24,15 @@ goog.require('goog.history.EventType');
goog.require('registry.util');
goog.forwardDeclare('goog.events.KeyEvent');
-goog.forwardDeclare('registry.Session');
/**
* Abstract console for both admin and registrar console UIs.
- * @param {?registry.Session} session server request session.
* @constructor
* @extends {goog.Disposable}
*/
-registry.Console = function(session) {
+registry.Console = function() {
registry.Console.base(this, 'constructor');
/**
@@ -42,19 +40,37 @@ registry.Console = function(session) {
* @protected
*/
this.history = new goog.History();
+};
+goog.inherits(registry.Console, goog.Disposable);
+
+/**
+ * Registers the console's events and sets everything up.
+ *
+ * Should be called after the constructor.
+ *
+ * The reason this isn't done in the constructor is that this is a base class
+ * designed to be extended. We have to wait for the actual implementation to
+ * finish constructing before using it.
+ */
+registry.Console.prototype.setUp = function() {
goog.events.listen(
this.history,
goog.history.EventType.NAVIGATE,
goog.bind(this.handleHashChange, this));
- /**
- * @type {?registry.Session} The server session.
- */
- this.session = session;
-
this.bindToDom();
+
+ // goog.History always starts off as "not enabled", meaning it doesn't trigger
+ // the listeners on change.
+ //
+ // When it's set to be enabled, it will start triggering the listeners on
+ // every change, but it also triggers the listeners immediately with the
+ // current history entry.
+ //
+ // This means the handleHashChange listener registered above will be called
+ // now.
+ this.history.setEnabled(true);
};
-goog.inherits(registry.Console, goog.Disposable);
/**
@@ -86,6 +102,8 @@ registry.Console.prototype.handleHashChange = goog.abstractMethod;
* @param {string} resourcePath Resource description path.
*/
registry.Console.prototype.view = function(resourcePath) {
+ // Setting the new history token will also trigger the handleHashChange
+ // listener registered in the setUp() function.
this.history.setToken(resourcePath);
};
diff --git a/java/google/registry/ui/js/edit_item.js b/java/google/registry/ui/js/edit_item.js
index 4ee507f1b..d0e8428b7 100644
--- a/java/google/registry/ui/js/edit_item.js
+++ b/java/google/registry/ui/js/edit_item.js
@@ -305,9 +305,9 @@ registry.EditItem.prototype.prepareUpdate = goog.abstractMethod;
/**
- * Subclasses should provide a function to parse either XML or JSON response
- * from server and return a result object as described below.
- * @param {!Object} rsp Decoded XML/JSON response from the server.
+ * Subclasses should provide a function to parse JSON response from server and
+ * return a result object as described below.
+ * @param {!Object} rsp Decoded JSON response from the server.
* @return {!Object} a result object describing next steps. On
* success, if next is defined, visit(ret.next) is called, otherwise
* if err is set, the butterbar message is set to it.
diff --git a/java/google/registry/ui/js/registrar/console.js b/java/google/registry/ui/js/registrar/console.js
index 6542c03ea..2da01a153 100644
--- a/java/google/registry/ui/js/registrar/console.js
+++ b/java/google/registry/ui/js/registrar/console.js
@@ -22,13 +22,9 @@ goog.require('goog.net.XhrIo');
goog.require('registry.Console');
goog.require('registry.Resource');
goog.require('registry.registrar.AdminSettings');
-goog.require('registry.registrar.Contact');
goog.require('registry.registrar.ContactSettings');
goog.require('registry.registrar.ContactUs');
goog.require('registry.registrar.Dashboard');
-goog.require('registry.registrar.Domain');
-goog.require('registry.registrar.EppSession');
-goog.require('registry.registrar.Host');
goog.require('registry.registrar.Resources');
goog.require('registry.registrar.SecuritySettings');
goog.require('registry.registrar.WhoisSettings');
@@ -49,16 +45,13 @@ goog.forwardDeclare('registry.Component');
* @final
*/
registry.registrar.Console = function(params) {
+ registry.registrar.Console.base(this, 'constructor');
+
/**
* @type {!Object}
*/
- // We have to define this before creating an EppSession because EppSession's
- // constructor expects us to have it as an attribute.
this.params = params;
- registry.registrar.Console.base(
- this, 'constructor', new registry.registrar.EppSession(this));
-
/**
* Component that's currently embedded in the page.
* @type {?registry.Component}
@@ -66,13 +59,9 @@ registry.registrar.Console = function(params) {
*/
this.component_ = null;
- // XXX: This was in parent ctor but was triggering event dispatching before
- // ready here.
- this.history.setEnabled(true);
-
/**
* Last active nav element.
- * @type {Element}
+ * @type {?Element}
*/
this.lastActiveNavElt;
@@ -107,13 +96,6 @@ registry.registrar.Console = function(params) {
if (this.params.isAdmin) {
this.pageMap['admin-settings'] = registry.registrar.AdminSettings;
}
-
- // sending EPPs through the console. Currently hidden (doesn't have a "tab")
- // but still accessible if the user manually puts #domain (or other) in the
- // fragment
- this.pageMap['contact'] = registry.registrar.Contact;
- this.pageMap['domain'] = registry.registrar.Domain;
- this.pageMap['host'] = registry.registrar.Host;
};
goog.inherits(registry.registrar.Console, registry.Console);
@@ -134,17 +116,7 @@ goog.inherits(registry.registrar.Console, registry.Console);
*/
registry.registrar.Console.prototype.handleHashChange = function() {
var hashToken = this.history.getToken();
- // On page reloads, opening a new tab, etc. it's possible that the
- // session cookie for a logged-in session exists, but the
- // this.session is not yet aware, so come back here after syncing.
- //
- // XXX: Method should be refactored to avoid this 2-stage behavior.
- if (!this.session.isEppLoggedIn()) {
- this.session.login(goog.bind(this.handleHashChange, this));
- return;
- }
- // Otherwise, a resource operation.
var parts = hashToken.split('/');
var type = '';
var id = '';
diff --git a/java/google/registry/ui/js/registrar/contact.js b/java/google/registry/ui/js/registrar/contact.js
deleted file mode 100644
index 5aa9611fd..000000000
--- a/java/google/registry/ui/js/registrar/contact.js
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright 2017 The Nomulus Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-goog.provide('registry.registrar.Contact');
-
-goog.require('goog.dom');
-goog.require('registry.registrar.XmlResourceComponent');
-goog.require('registry.soy.registrar.contact');
-goog.require('registry.soy.registrar.contactepp');
-
-goog.forwardDeclare('registry.registrar.Console');
-
-
-
-/**
- * The `Contact` class respresents a registry contact object and
- * binds UI CRUD operations to it.
- * @param {!registry.registrar.Console} console the
- * console singleton.
- * @constructor
- * @extends {registry.registrar.XmlResourceComponent}
- * @final
- */
-registry.registrar.Contact = function(console) {
- registry.registrar.Contact.base(
- this, 'constructor',
- /** @type {function()} */(registry.soy.registrar.contact.item),
- registry.soy.registrar.contactepp,
- console);
-};
-goog.inherits(registry.registrar.Contact,
- registry.registrar.XmlResourceComponent);
-
-
-/** @override */
-registry.registrar.Contact.prototype.processItem = function() {
- this.model.item = this.model['epp']['response']['resData']['contact:infData'];
- if (!goog.isArray(this.model.item['contact:postalInfo'])) {
- this.model.item['contact:postalInfo'] =
- [this.model.item['contact:postalInfo']];
- }
-
- // XXX: Is this code necessary?
- var fixPlus = function(val) {
- var str = (val || '') + '';
- if (str == '' || str.match(/\+.*/)) {
- return str;
- } else {
- return '+' + str;
- }
- };
-
- // Both of these are optional.
- if (this.model.item['contact:voice']) {
- this.model.item['contact:voice']['keyValue'] =
- fixPlus(this.model.item['contact:voice']['keyValue']);
- }
- if (this.model.item['contact:voice']) {
- this.model.item['contact:fax']['keyValue'] =
- fixPlus(this.model.item['contact:fax']['keyValue']);
- }
-};
-
-
-/** @override */
-registry.registrar.Contact.prototype.setupEditor = function(objArgs) {
- // For now always keep the first contact and make it i18n. Toggle button
- // disables to enforce state.
- //
- // XXX: Should be simplified to make more modular.
- var postalElt = goog.dom.getRequiredElement('contact-postalInfo');
- var addPostalInfoBtn = goog.dom.getRequiredElement(
- 'domain-contact-postalInfo-add-button');
- this.typeCounts['contact-postalInfo'] = postalElt.childNodes.length;
- // 4 child nodes means both addresses are present:
- // 2 data tables, the footer id elt and a hidden input.
- var setupRemoveBtns = this.typeCounts['contact-postalInfo'] == 4;
- if (setupRemoveBtns) {
- this.appendRemoveBtn(/** @type {!Element} */ (postalElt.childNodes[0]));
- this.appendRemoveBtn(/** @type {!Element} */ (postalElt.childNodes[1]));
- } else {
- addPostalInfoBtn.removeAttribute('disabled');
- }
-
- this.addRemBtnHandlers(
- 'contact-postalInfo',
- function() {
- return 'contact:postalInfo[1].contact:';
- },
- function() {
- addPostalInfoBtn.setAttribute('disabled', true);
- return null;
- },
- /** @type {function()} */ (registry.soy.registrar.contact.postalInfo),
- {
- item: {},
- localized: true,
- itemPrefix: 'contact:',
- namePrefix: 'contact:postalInfo[1].contact:'
- },
- setupRemoveBtns);
-};
-
-
-/** @override */
-registry.registrar.Contact.prototype.prepareCreate = function(params) {
- params.nextId = params.item['contact:id'];
- return registry.soy.registrar.contactepp.create(
- /** @type {{clTrid: ?, item: ?}} */ (params)).toString();
-};
-
-
-/** @override */
-registry.registrar.Contact.prototype.prepareUpdate = function(params) {
- params.nextId = params.item['contact:id'];
- return registry.soy.registrar.contactepp.update(
- /** @type {{clTrid: ?, item: ?}} */(params)).toString();
-};
diff --git a/java/google/registry/ui/js/registrar/contact_settings.js b/java/google/registry/ui/js/registrar/contact_settings.js
index 5284f6ad1..a09a85a36 100644
--- a/java/google/registry/ui/js/registrar/contact_settings.js
+++ b/java/google/registry/ui/js/registrar/contact_settings.js
@@ -221,7 +221,7 @@ registry.registrar.ContactSettings.prototype.prepareUpdate =
* Handler for contact save that navigates to that item on success.
* Does nothing on failure as UI will be left with error messages for
* the user to resolve.
- * @param {!Object} rsp Decoded XML/JSON response from the server.
+ * @param {!Object} rsp Decoded JSON response from the server.
* @override
*/
registry.registrar.ContactSettings.prototype.handleCreateResponse =
@@ -238,7 +238,7 @@ registry.registrar.ContactSettings.prototype.handleCreateResponse =
* Handler for contact delete that navigates back to the collection on success.
* Does nothing on failure as UI will be left with error messages for
* the user to resolve.
- * @param {!Object} rsp Decoded XML/JSON response from the server.
+ * @param {!Object} rsp Decoded JSON response from the server.
* @override
*/
registry.registrar.ContactSettings.prototype.handleDeleteResponse =
diff --git a/java/google/registry/ui/js/registrar/dashboard.js b/java/google/registry/ui/js/registrar/dashboard.js
index 17ffbaad7..660a87c3a 100644
--- a/java/google/registry/ui/js/registrar/dashboard.js
+++ b/java/google/registry/ui/js/registrar/dashboard.js
@@ -40,10 +40,10 @@ registry.registrar.Dashboard = function(console) {
/** @private {number} */
this.x_ = 0;
- /** @private {Element} */
+ /** @private {?Element} */
this.gear_ = null;
- /** @private {goog.Timer} */
+ /** @private {?goog.Timer} */
this.timer_ = null;
};
goog.inherits(registry.registrar.Dashboard, registry.Component);
@@ -63,14 +63,6 @@ registry.registrar.Dashboard.prototype.bindToDom = function(id) {
};
-/**
- * Do EPP logout.
- */
-registry.registrar.Dashboard.prototype.doEppLogout = function() {
- this.console.session.logout();
-};
-
-
/**
* Let's do the twist.
* @private
diff --git a/java/google/registry/ui/js/registrar/domain.js b/java/google/registry/ui/js/registrar/domain.js
deleted file mode 100644
index 4dc5156c8..000000000
--- a/java/google/registry/ui/js/registrar/domain.js
+++ /dev/null
@@ -1,167 +0,0 @@
-// Copyright 2017 The Nomulus Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-goog.provide('registry.registrar.Domain');
-
-goog.require('goog.json');
-goog.require('registry.registrar.XmlResourceComponent');
-goog.require('registry.soy.forms');
-goog.require('registry.soy.registrar.domain');
-goog.require('registry.soy.registrar.domainepp');
-goog.require('registry.util');
-
-goog.forwardDeclare('registry.registrar.Console');
-
-
-
-/**
- * CRUD for EPP domain objects.
- * @param {!registry.registrar.Console} console
- * @constructor
- * @extends {registry.registrar.XmlResourceComponent}
- * @final
- */
-registry.registrar.Domain = function(console) {
- registry.registrar.Domain.base(
- this, 'constructor',
- /** @type {function()} */ (registry.soy.registrar.domain.item),
- registry.soy.registrar.domainepp,
- console);
-};
-goog.inherits(registry.registrar.Domain,
- registry.registrar.XmlResourceComponent);
-
-
-/** @override */
-registry.registrar.Domain.prototype.newModel = function() {
- var newModel = {item: {'domain:period': ''}};
- return newModel;
-};
-
-
-/**
- * Prepare a fetch query for the domain by its id.
- * @param {!Object} params should have a name field with a
- * possibly extended domain name id of the form "example.tld:1234"
- * where the 1234 is the domain application id assigned by the
- * backend flows.
- * @override
- */
-registry.registrar.Domain.prototype.prepareFetch = function(params) {
- return registry.soy.registrar.domainepp.info(
- /** @type {{clTrid: ?, id: ?}} */ (params)).toString();
-};
-
-
-/** @override */
-registry.registrar.Domain.prototype.processItem = function() {
- this.model.item = this.model['epp']['response']['resData']['domain:infData'];
- // Hoist extensions for easy soy access.
- var extension = this.model['epp']['response']['extension'];
- if (extension && extension['launch:infData']) {
- var extendedInfData = extension['launch:infData'];
-
- var mark = extendedInfData['mark:mark'];
- if (mark) {
- this.model.item['mark:mark'] = {'keyValue': goog.json.serialize(mark)};
- }
- }
-
- // Wrap single item into an array.
- if (this.model.item['domain:ns'] &&
- this.model.item['domain:ns']['domain:hostObj']) {
- var hostObj = this.model.item['domain:ns']['domain:hostObj'];
- if (!goog.isArray(hostObj)) {
- this.model.item['domain:ns']['domain:hostObj'] = [hostObj];
- }
- }
-};
-
-
-/** @override */
-registry.registrar.Domain.prototype.setupEditor = function(objArgs) {
- this.typeCounts['contact'] = objArgs.item['domain:contact'] ?
- objArgs.item['domain:contact'].length : 0;
-
- var ji = objArgs.item['domain:ns'];
- this.typeCounts['host'] =
- ji && ji['domain:hostObj'] ? ji['domain:hostObj'].length : 0;
-
- this.formInputRowRemovable(
- document.querySelectorAll('input.domain-hostObj[readonly]'));
-
- this.formInputRowRemovable(
- document.querySelectorAll('input.domain-contact[readonly]'));
-
- this.addRemBtnHandlers(
- 'contact',
- goog.bind(function() {
- return 'domain:contact[' + this.typeCounts['contact'] + ']';
- }, this),
- goog.bind(function(newFieldName) {
- return registry.util.renderBeforeRow(
- 'domain-contacts-footer',
- /** @type {function()} */(registry.soy.forms.selectRow), {
- label: 'Type',
- name: newFieldName + '.@type',
- options: ['admin', 'tech', 'billing']
- });
- }, this));
-
- this.addRemBtnHandlers('host', goog.bind(function() {
- return 'domain:ns.domain:hostObj[' + this.typeCounts['host'] + ']';
- }, this));
-};
-
-
-/** @override */
-registry.registrar.Domain.prototype.prepareCreate = function(params) {
- var form = params.item;
- params.nextId = form['domain:name'];
-
- // The presence of this field is used to signal extended template, so remove
- // if not used.
- if (form['smd:encodedSignedMark'] == '') {
- delete form['smd:encodedSignedMark'];
- }
- var xml = registry.soy.registrar.domainepp.create(
- /** @type {{clTrid: ?, item: ?}} */(params));
- return xml.toString();
-};
-
-
-/** @override */
-registry.registrar.Domain.prototype.prepareUpdate =
- function(params) {
- var form = params.item;
- var nextId = form['domain:name'];
- params.nextId = nextId;
-
- if (form['domain:contact']) {
- this.addRem(form['domain:contact'], 'Contacts', params);
- }
-
- if (form['domain:ns'] && form['domain:ns']['domain:hostObj']) {
- this.addRem(form['domain:ns']['domain:hostObj'], 'Hosts', params);
- }
-
- if (form['domain:ns'] && form['domain:ns']['domain:hostObj']) {
- this.addRem(form['domain:ns']['domain:hostObj'], 'Hosts', params);
- }
- this.addRem(form['domain:contact'], 'Contacts', params);
- var xml = registry.soy.registrar.domainepp.update(
- /** @type {{clTrid: ?, item: ?}} */(params));
-
- return xml.toString();
-};
diff --git a/java/google/registry/ui/js/registrar/epp_session.js b/java/google/registry/ui/js/registrar/epp_session.js
deleted file mode 100644
index ab0c9e89e..000000000
--- a/java/google/registry/ui/js/registrar/epp_session.js
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright 2017 The Nomulus Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-goog.provide('registry.registrar.EppSession');
-
-goog.require('goog.Uri');
-goog.require('registry.Session');
-goog.require('registry.soy.registrar.epp');
-goog.require('registry.util');
-goog.require('registry.xml');
-
-goog.forwardDeclare('registry.registrar.Console');
-
-
-
-/**
- * Session state for console.
- * @param {!registry.registrar.Console} console
- * @constructor
- * @extends {registry.Session}
- * @final
- */
-registry.registrar.EppSession = function(console) {
- registry.registrar.EppSession.base(
- this, 'constructor',
- new goog.Uri('/registrar-xhr')
- .setParameterValue('clientId', console.params.clientId),
- console.params.xsrfToken,
- registry.Session.ContentType.EPP);
-
- /**
- * @type {!registry.registrar.Console}
- */
- this.console = console;
-
- /**
- * @type {!boolean}
- * @private
- */
- this.isEppLoggedIn_ = false;
-};
-goog.inherits(registry.registrar.EppSession, registry.Session);
-
-
-/**
- * Whether the session has received an EPP success response to an EPP
- * login attempt.
- * @return {boolean} Whether the user is logged into an EPP session.
- */
-registry.registrar.EppSession.prototype.isEppLoggedIn = function() {
- return this.isEppLoggedIn_;
-};
-
-
-/**
- * Get the clientId if the user is logged in, or throw Error.
- * @throws Error if the user is not logged in.
- * @return {string} the clientId.
- */
-registry.registrar.EppSession.prototype.getClientId = function() {
- return this.console.params.clientId;
-};
-
-
-/**
- * Login or display butterbar info about error.
- * @param {function()} successCb to be called on success.
- */
-registry.registrar.EppSession.prototype.login = function(successCb) {
- var eppArgs = {clId: this.console.params.clientId, clTrid: 'asdf-1235'};
- this.send(
- registry.soy.registrar.epp.login(eppArgs).getContent(),
- goog.bind(function(xml) {
- var result = xml['epp']['response']['result'];
- var eppCode = result['@code'];
- if (eppCode == '1000' || eppCode == '2002') {
- // Success || Already logged in.
- this.isEppLoggedIn_ = true;
- successCb();
- } else {
- // Failure.
- this.isEppLoggedIn_ = false;
- registry.util.butter('login error: ' + eppCode);
- }
- }, this));
-};
-
-
-/**
- * Logout or display butterbar info about error.
- */
-registry.registrar.EppSession.prototype.logout = function() {
- this.send(
- registry.soy.registrar.epp.logout(
- {clTrid: 'asdf-1235'}).getContent(),
- goog.bind(function(xml) {
- var result = xml['epp']['response']['result'];
- var eppCode = result['@code'];
- registry.util.butter(
- 'logout ' + eppCode + ': ' + result['msg']['keyValue']);
- // Going to be safe here and force a login either way.
- this.isEppLoggedIn_ = false;
- }, this));
-};
-
-
-/**
- * Send xml to the server.
- * @param {string} xml Request document.
- * @param {function(!Object)} callback For XhrIo result throws.
- */
-registry.registrar.EppSession.prototype.send = function(xml, callback) {
- var toXmlJsonCb = function(rspXml) {
- callback(registry.xml.convertToJson(rspXml));
- };
- this.sendXhrIo(xml, toXmlJsonCb);
-};
diff --git a/java/google/registry/ui/js/registrar/host.js b/java/google/registry/ui/js/registrar/host.js
deleted file mode 100644
index 45bd03f43..000000000
--- a/java/google/registry/ui/js/registrar/host.js
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright 2017 The Nomulus Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-goog.provide('registry.registrar.Host');
-
-goog.require('registry.registrar.XmlResourceComponent');
-goog.require('registry.soy.registrar.host');
-goog.require('registry.soy.registrar.hostepp');
-
-goog.forwardDeclare('registry.registrar.Console');
-
-
-
-/**
- * CRUD for EPP host objects.
- * @param {!registry.registrar.Console} console
- * @constructor
- * @extends {registry.registrar.XmlResourceComponent}
- * @final
- */
-registry.registrar.Host = function(console) {
- registry.registrar.Host.base(
- this, 'constructor',
- registry.soy.registrar.host.item,
- registry.soy.registrar.hostepp,
- console);
-};
-goog.inherits(registry.registrar.Host,
- registry.registrar.XmlResourceComponent);
-
-
-/** @override */
-registry.registrar.Host.prototype.processItem = function() {
- this.model.item = this.model['epp']['response']['resData']['host:infData'];
- if (this.model.item['host:addr']) {
- if (!goog.isArray(this.model.item['host:addr'])) {
- this.model.item['host:addr'] = [this.model.item['host:addr']];
- }
- } else {
- this.model.item['host:addr'] = [];
- }
-};
-
-
-/** @override */
-registry.registrar.Host.prototype.setupEditor = function(objArgs) {
- this.typeCounts['host-addr'] =
- objArgs.item['host:addr'] ? objArgs.item['host:addr'].length : 0;
- this.addRemBtnHandlers('host-addr', goog.bind(function() {
- return 'host:addr[' + this.typeCounts['host-addr'] + ']';
- }, this));
-
- this.formInputRowRemovable(document.querySelectorAll('input[readonly]'));
-};
-
-
-/** @override */
-registry.registrar.Host.prototype.prepareCreate = function(params) {
- params.nextId = params.item['host:name'];
- return registry.soy.registrar.hostepp.create(
- /** @type {{clTrid: ?, item: ?}} */(params)).toString();
-};
-
-
-/** @override */
-registry.registrar.Host.prototype.prepareUpdate = function(params) {
- var form = params.item;
- var addAddrs = [];
- var remAddrs = [];
- if (form['host:addr']) {
- var oldAddrs = form['host:oldAddr'] || [];
- var newAddrs = form['host:addr'];
- var length = Math.max(oldAddrs.length, newAddrs.length);
- for (var i = 0; i < length; i++) {
- if (i >= oldAddrs.length) {
- addAddrs.push(newAddrs[i]['value']);
- } else if (i >= newAddrs.length) {
- remAddrs.push(oldAddrs[i]['value']);
- } else {
- if (newAddrs[i]['value'] == oldAddrs[i]['value']) {
- // Do nothing.
- } else if (newAddrs[i]['value'] == '') {
- remAddrs.push(oldAddrs[i]['value']);
- } else {
- remAddrs.push(oldAddrs[i]['value']);
- addAddrs.push(newAddrs[i]['value']);
- }
- }
- }
- }
- params.addAddrs = addAddrs;
- params.remAddrs = remAddrs;
- params.nextId = form['host:chgName'];
- return registry.soy.registrar.hostepp.update(
- /** @type {{clTrid: ?, item: ?}} */(params)).toString();
-};
diff --git a/java/google/registry/ui/js/registrar/main.js b/java/google/registry/ui/js/registrar/main.js
index 1a8ad1df4..1bfbd7030 100644
--- a/java/google/registry/ui/js/registrar/main.js
+++ b/java/google/registry/ui/js/registrar/main.js
@@ -38,11 +38,10 @@ goog.require('registry.registrar.Console');
* @param {string} technicalDocsUrl
* @export
*/
-registry.registrar.main = function(xsrfToken, clientId, isAdmin, isOwner,
- productName, integrationEmail, supportEmail,
- announcementsEmail, supportPhoneNumber,
- technicalDocsUrl) {
- new registry.registrar.Console({
+registry.registrar.main = function(
+ xsrfToken, clientId, isAdmin, isOwner, productName, integrationEmail,
+ supportEmail, announcementsEmail, supportPhoneNumber, technicalDocsUrl) {
+ const console = new registry.registrar.Console({
xsrfToken: xsrfToken,
clientId: clientId,
isAdmin: isAdmin,
@@ -54,4 +53,6 @@ registry.registrar.main = function(xsrfToken, clientId, isAdmin, isOwner,
supportPhoneNumber: supportPhoneNumber,
technicalDocsUrl: technicalDocsUrl
});
+
+ console.setUp();
};
diff --git a/java/google/registry/ui/js/registrar/xml_resource_component.js b/java/google/registry/ui/js/registrar/xml_resource_component.js
deleted file mode 100644
index 2f736bc08..000000000
--- a/java/google/registry/ui/js/registrar/xml_resource_component.js
+++ /dev/null
@@ -1,219 +0,0 @@
-// Copyright 2017 The Nomulus Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-goog.provide('registry.registrar.XmlResourceComponent');
-
-goog.require('goog.dom');
-goog.require('goog.dom.TagName');
-goog.require('goog.dom.classlist');
-goog.require('registry.EditItem');
-goog.require('registry.util');
-
-goog.forwardDeclare('registry.registrar.Console');
-
-
-
-/**
- * The ResourceComponent class respresents server state for a named
- * resource and binds UI CRUD operations on it, or its constituent
- * collection.
- * @param {function()} itemTmpl
- * @param {!Object} eppTmpls Epp xml templates for info requests.
- * @param {!registry.registrar.Console} console
- * @constructor
- * @extends {registry.EditItem}
- */
-registry.registrar.XmlResourceComponent = function(
- itemTmpl, eppTmpls, console) {
- registry.registrar.XmlResourceComponent.base(
- this, 'constructor', console, itemTmpl, console.params.isOwner);
-
- /** @type {!Object} */
- this.eppTmpls = eppTmpls;
-};
-goog.inherits(registry.registrar.XmlResourceComponent, registry.EditItem);
-
-
-/** @override */
-registry.registrar.XmlResourceComponent.prototype.bindToDom =
- function(id) {
- // XXX: EPP resources still use null state.
- registry.registrar.XmlResourceComponent.base(
- this, 'bindToDom', (id || ''));
- if (id) {
- this.fetchItem(id);
- } else {
- // Start edit of empty object.
- this.edit();
- }
-};
-
-
-/** @override */
-registry.registrar.XmlResourceComponent.prototype.fetchItem = function(id) {
- var queryParams = {id: id, clTrid: 'abc-1234'};
- var xml = this.prepareFetch(queryParams);
- this.console.session.send(xml, goog.bind(this.handleFetchItem, this, id));
-};
-
-
-/** @override */
-registry.registrar.XmlResourceComponent.prototype.handleFetchItem =
- function(id, rsp) {
- this.model = rsp;
- var result = rsp['epp']['response']['result'];
- var resCode = result['@code'];
- // XXX: Should use enum.
- if (resCode == 1000) { // OK
- this.model.readonly = true;
- this.processItem();
- this.renderItem(this.model);
- } else if (resCode == 2303) { // Missing
- registry.util.butter(
- 'Could not find: "' + id + '". Please enter as "type/id"');
- } else {
- // includes general failure.
- registry.util.butter(resCode + ':' + result['msg']['keyValue']);
- }
-};
-
-
-/**
- * Sublcasses should override to populate create queryParams with form
- * fields as needed. `queryParams.nextId` MUST be set to the
- * new object's ID.
- * @param {!Object} queryParams
- */
-registry.registrar.XmlResourceComponent.prototype.prepareCreate =
- goog.abstractMethod;
-
-
-/**
- * Calls prepareCreate with template params and then send the returned
- * XML to the server
- * @override
- */
-registry.registrar.XmlResourceComponent.prototype.sendCreate = function() {
- var form = registry.util.parseForm('item');
- var queryParams = {item: form, clTrid: 'abc-1234'};
- var xml = this.prepareCreate(queryParams);
- this.nextId = queryParams.nextId;
- this.console.session.send(xml, goog.bind(this.handleUpdateResponse, this));
-};
-
-
-/**
- * Calls prepareUpdate with template params and then send the returned
- * XML to the server.
- * @override
- */
-registry.registrar.XmlResourceComponent.prototype.sendUpdate = function() {
- var form = registry.util.parseForm('item');
- var queryParams = {item: form, clTrid: 'abc-1234'};
- var xml = this.prepareUpdate(queryParams);
- this.nextId = queryParams.nextId;
- this.console.session.send(xml, goog.bind(this.handleUpdateResponse, this));
-};
-
-
-/**
- * Sublcasses should override to populate fetch queryParams with form
- * fields as needed.
- * @param {!Object} queryParams
- * @return {string} EPP xml string
- */
-registry.registrar.XmlResourceComponent.prototype.prepareFetch =
- function(queryParams) {
- return this.eppTmpls.info(queryParams).toString();
-};
-
-
-/** @override */
-registry.registrar.XmlResourceComponent.prototype.handleUpdateResponse =
- function(rsp) {
- var result = rsp['epp']['response']['result'];
- if (result['@code'] == 1000) {
- // XXX: Consider timer, probably just as a seconds arg with impl in butter.
- registry.util.butter('Saved.');
- this.fetchItem(this.nextId || '');
- this.nextId = null;
- this.toggleEdit();
- } else {
- registry.util.butter(result['msg']['keyValue']);
- }
- return rsp;
-};
-
-
-/**
- * Helper to add add/remove hosts/contacts on queryParams:
- *
- * queryParams[op + fieldType] = formFields.
- *
- * @param {Array.