mirror of
https://github.com/google/nomulus.git
synced 2025-05-13 16:07:15 +02:00
Remove the web console EPP endpoint
This removes the "create Domain/Host/Contact" forms that were supposed to be used instead of regular EPPs for CC-TLD that wanted to support it. We're removing it because we don't use it and want to reduce unneeded code for the registry 3.0 migration. Also, this is a security risk, as it allowed to do "billable actions" (creating a new domain for example) with the only authentication being access to the registrar's G Suite account. This bypassed the certificate, IP whitelist, and EPP password, which is bad. PUBLIC: Remove the web console EPP endpoint This removes the "create Domain/Host/Contact" forms that were supposed to be used instead of regular EPPs for CC-TLD that wanted to support it. We're removing it because we don't use it and want to reduce unneeded code for the registry 3.0 migration. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=236244195
This commit is contained in:
parent
f12d368da3
commit
dfad79759e
52 changed files with 58 additions and 3788 deletions
|
@ -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
|
||||
* </pre>
|
||||
*
|
||||
* @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:
|
||||
*
|
||||
* <ul>
|
||||
* <li>an add button with id="domain-[type]-add-button".
|
||||
* <li>a table row with id="domain-[type]s-footer".
|
||||
* </ul>
|
||||
*
|
||||
* @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.<Element>|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));
|
||||
});
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 = '';
|
||||
|
|
|
@ -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();
|
||||
};
|
|
@ -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 =
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
};
|
|
@ -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);
|
||||
};
|
|
@ -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();
|
||||
};
|
|
@ -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();
|
||||
};
|
||||
|
|
|
@ -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.<Object>} formFields named form item representations
|
||||
* that have an associated {op: (add|rem)} attribute.
|
||||
* @param {string} fieldType capitalized pluralized type name, e.g. "Contacts".
|
||||
* @param {!Object} queryParams
|
||||
*/
|
||||
registry.registrar.XmlResourceComponent.prototype.addRem =
|
||||
function(formFields, fieldType, queryParams) {
|
||||
var add = [];
|
||||
var rem = [];
|
||||
for (var i = 0; i < formFields.length; i++) {
|
||||
var formField = formFields[i];
|
||||
var op = formField['op'];
|
||||
switch (op) {
|
||||
case 'add':
|
||||
add.push(formField);
|
||||
break;
|
||||
case 'rem':
|
||||
rem.push(formField);
|
||||
break;
|
||||
default:
|
||||
registry.util.log(
|
||||
'Unknown op attribute ' + op + ' on form field:',
|
||||
formField);
|
||||
}
|
||||
}
|
||||
if (add.length > 0) {
|
||||
queryParams['add' + fieldType] = add;
|
||||
}
|
||||
if (rem.length > 0) {
|
||||
queryParams['rem' + fieldType] = rem;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Make the given form input rows removable.
|
||||
* @param {NodeList} elts array of input elements.
|
||||
* @param {function()=} opt_onclickCb called when remove button is clicked.
|
||||
*/
|
||||
registry.registrar.XmlResourceComponent.prototype.formInputRowRemovable =
|
||||
function(elts, opt_onclickCb) {
|
||||
for (var i = 0; i < elts.length; i++) {
|
||||
var parent = goog.dom.getParentElement(elts[i]);
|
||||
this.appendRemoveBtn(parent, goog.partial(function(elt) {
|
||||
var eppRemInput = goog.dom.createDom(goog.dom.TagName.INPUT, {
|
||||
'name': elt.name.replace(/\.value/, '.op'),
|
||||
'value': 'rem',
|
||||
'type': 'hidden'
|
||||
});
|
||||
goog.dom.appendChild(goog.dom.getParentElement(elt), eppRemInput);
|
||||
goog.dom.classlist.add(
|
||||
goog.dom.getParentElement(
|
||||
goog.dom.getParentElement(elt)), goog.getCssName('hidden'));
|
||||
}, elts[i]));
|
||||
}
|
||||
};
|
|
@ -31,8 +31,7 @@ goog.forwardDeclare('goog.Uri');
|
|||
* @constructor
|
||||
*/
|
||||
registry.Resource = function(baseUri, id, xsrfToken) {
|
||||
registry.Resource.base(this, 'constructor', baseUri, xsrfToken,
|
||||
registry.Session.ContentType.JSON);
|
||||
registry.Resource.base(this, 'constructor', baseUri, xsrfToken);
|
||||
/** @const @private {string} the ID of the target resource. */
|
||||
this.id_ = id;
|
||||
};
|
||||
|
|
|
@ -23,14 +23,13 @@ goog.forwardDeclare('goog.Uri');
|
|||
|
||||
|
||||
/**
|
||||
* XHR launcher for both JSON and XML requests.
|
||||
* XHR launcher for JSON requests.
|
||||
* @param {!goog.Uri} defaultUri URI to which requests are POSTed.
|
||||
* @param {string} xsrfToken Cross-site request forgery protection token.
|
||||
* @param {!registry.Session.ContentType} contentType Payload mode.
|
||||
* @constructor
|
||||
* @template REQUEST, RESPONSE
|
||||
*/
|
||||
registry.Session = function(defaultUri, xsrfToken, contentType) {
|
||||
registry.Session = function(defaultUri, xsrfToken) {
|
||||
|
||||
/**
|
||||
* URI to which requests are posted.
|
||||
|
@ -39,36 +38,19 @@ registry.Session = function(defaultUri, xsrfToken, contentType) {
|
|||
*/
|
||||
this.uri = defaultUri;
|
||||
|
||||
/**
|
||||
* Content type set in request body.
|
||||
* @private {!registry.Session.ContentType}
|
||||
* @const
|
||||
*/
|
||||
this.contentType_ = contentType;
|
||||
|
||||
/**
|
||||
* XHR request headers.
|
||||
* @private {!Object<string, string>}
|
||||
* @const
|
||||
*/
|
||||
this.headers_ = {
|
||||
'Content-Type': contentType,
|
||||
'Content-Type': 'application/json; charset=utf-8',
|
||||
'X-CSRF-Token': xsrfToken,
|
||||
'X-Requested-With': 'XMLHttpRequest'
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Payload modes supported by this class.
|
||||
* @enum {string}
|
||||
*/
|
||||
registry.Session.ContentType = {
|
||||
JSON: 'application/json; charset=utf-8',
|
||||
EPP: 'application/epp+xml'
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Abstract method to send a request to the server.
|
||||
* @param {REQUEST} body HTTP request body as a string or JSON object.
|
||||
|
@ -99,9 +81,7 @@ registry.Session.prototype.sendXhrIo =
|
|||
registry.Session.prototype.onXhrComplete_ = function(onSuccess, onError, e) {
|
||||
if (e.target.isSuccess()) {
|
||||
onSuccess(/** @type {!RESPONSE} */ (
|
||||
this.contentType_ == registry.Session.ContentType.JSON ?
|
||||
e.target.getResponseJson(registry.Session.PARSER_BREAKER_) :
|
||||
e.target.getResponseXml()));
|
||||
e.target.getResponseJson(registry.Session.PARSER_BREAKER_)));
|
||||
} else {
|
||||
onError(e.target.getLastError());
|
||||
}
|
||||
|
|
|
@ -1,89 +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.xml');
|
||||
goog.provide('registry.xml.XmlJson');
|
||||
|
||||
goog.require('goog.dom.NodeType');
|
||||
goog.require('goog.object');
|
||||
|
||||
|
||||
/**
|
||||
* Turns XML document into a JSON data structure. This function is similar to
|
||||
* <a href="https://developer.mozilla.org/en-US/docs/JXON">Mozilla JXON</a>
|
||||
* except it handles text differently. This routine will not coalesce text
|
||||
* interspersed with elements. This routine does not coerce string types to
|
||||
* number, boolean, or null.
|
||||
* @param {!Node} node
|
||||
* @return {!Object<string, registry.xml.XmlJson>}
|
||||
* @throws {Error} upon encountering interspersed text.
|
||||
*/
|
||||
registry.xml.convertToJson = function(node) {
|
||||
var result = goog.object.create();
|
||||
if (goog.isDefAndNotNull(node.attributes)) {
|
||||
for (var i = 0; i < node.attributes.length; i++) {
|
||||
var attr = node.attributes.item(i);
|
||||
goog.object.set(result, '@' + attr.name, attr.value || '');
|
||||
}
|
||||
}
|
||||
for (var j = 0; j < node.childNodes.length; j++) {
|
||||
var child = node.childNodes.item(j);
|
||||
switch (child.nodeType) {
|
||||
case goog.dom.NodeType.TEXT:
|
||||
case goog.dom.NodeType.CDATA_SECTION:
|
||||
var text = String(child.nodeValue).trim();
|
||||
if (text != '') {
|
||||
var curr = goog.object.get(result, registry.xml.jsonValueFieldName_);
|
||||
if (goog.isDef(curr)) {
|
||||
throw new Error(
|
||||
'XML text "' + curr + '" interspersed with "' + text + '"');
|
||||
}
|
||||
goog.object.set(result, registry.xml.jsonValueFieldName_, text);
|
||||
}
|
||||
break;
|
||||
case goog.dom.NodeType.ELEMENT:
|
||||
var json = registry.xml.convertToJson(child);
|
||||
var name = child.nodeName;
|
||||
if (goog.object.containsKey(result, name)) {
|
||||
var field = goog.object.get(result, name);
|
||||
if (goog.isArray(field)) {
|
||||
field.push(json);
|
||||
} else {
|
||||
goog.object.set(result, name, [field, json]);
|
||||
}
|
||||
} else {
|
||||
goog.object.set(result, name, json);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* XML JSON object recursive type definition.
|
||||
* @typedef {(string|
|
||||
* !Array<registry.xml.XmlJson>|
|
||||
* !Object<string, registry.xml.XmlJson>)}
|
||||
*/
|
||||
registry.xml.XmlJson;
|
||||
|
||||
|
||||
/**
|
||||
* XML JSON value field name, inherited from JXON.
|
||||
* @private {string}
|
||||
* @const
|
||||
*/
|
||||
registry.xml.jsonValueFieldName_ = 'keyValue';
|
Loading…
Add table
Add a link
Reference in a new issue