mirror of
https://github.com/google/nomulus.git
synced 2025-05-02 21:17:50 +02:00
Thanks to [] shared libraries at Google now produce valid JSON which allows using JSON.parse. It is safer and faster than goog.json.parse which uses eval by default. NOTE: All shared libraries producing JSON at Google were changed to produce valid JSON. However, if your code uses a custom way of producing JSON (not using the shared libraries) or if your code parses JSON generated a long time ago and stored, this CL might break you so please review with care. Design doc: [] Tested: TAP --sample for global presubmit queue [] ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=166454709
256 lines
8 KiB
JavaScript
256 lines
8 KiB
JavaScript
// 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.ContactSettings');
|
|
|
|
goog.require('goog.Uri');
|
|
goog.require('goog.array');
|
|
goog.require('goog.dom');
|
|
goog.require('goog.dom.TagName');
|
|
goog.require('goog.events');
|
|
goog.require('goog.events.EventType');
|
|
goog.require('goog.json');
|
|
goog.require('goog.soy');
|
|
goog.require('registry.Resource');
|
|
goog.require('registry.ResourceComponent');
|
|
goog.require('registry.soy.registrar.contacts');
|
|
goog.require('registry.util');
|
|
|
|
goog.forwardDeclare('registry.registrar.Console');
|
|
|
|
|
|
|
|
/**
|
|
* Contact Settings page. Registrar Contacts are not really a proper
|
|
* REST resource as they're still passed from the server as a member
|
|
* field of Registrar, so this class behaves like an item page,
|
|
* updating only that field of the Registrar object and not
|
|
* implementing the create action from edit_item.
|
|
* @param {!registry.registrar.Console} console
|
|
* @param {string} xsrfToken Security token to pass back to the server.
|
|
* @constructor
|
|
* @extends {registry.ResourceComponent}
|
|
* @final
|
|
*/
|
|
registry.registrar.ContactSettings = function(console, xsrfToken) {
|
|
registry.registrar.ContactSettings.base(
|
|
this, 'constructor',
|
|
console,
|
|
new registry.Resource(new goog.Uri('/registrar-settings'), xsrfToken),
|
|
registry.soy.registrar.contacts.contact,
|
|
null);
|
|
};
|
|
goog.inherits(registry.registrar.ContactSettings, registry.ResourceComponent);
|
|
|
|
|
|
/** @override */
|
|
registry.registrar.ContactSettings.prototype.setupAppbar = function() {
|
|
registry.registrar.ContactSettings.base(this, 'setupAppbar');
|
|
// Setup delete only on existing items, not on creates.
|
|
if (goog.isDefAndNotNull(this.model)) {
|
|
var deleteBtn = goog.dom.createDom(
|
|
goog.dom.TagName.BUTTON, {
|
|
type: 'button',
|
|
id: 'reg-app-btn-delete',
|
|
className: goog.getCssName('kd-button')
|
|
},
|
|
'Delete');
|
|
goog.events.listen(deleteBtn, goog.events.EventType.CLICK,
|
|
goog.bind(this.sendDelete, this));
|
|
goog.dom.insertSiblingBefore(deleteBtn,
|
|
goog.dom.getRequiredElement('reg-app-btn-cancel'));
|
|
}
|
|
};
|
|
|
|
|
|
/** @override */
|
|
registry.registrar.ContactSettings.prototype.renderItem = function(rspObj) {
|
|
var contentElt = goog.dom.getRequiredElement('reg-content');
|
|
/** @type {!registry.json.RegistrarContact} */
|
|
var contacts = rspObj.contacts;
|
|
if (this.id) {
|
|
var targetContactNdx;
|
|
var targetContact;
|
|
for (var c in contacts) {
|
|
var ct = contacts[c];
|
|
if (ct.emailAddress == this.id) {
|
|
targetContactNdx = c;
|
|
targetContact = ct;
|
|
break;
|
|
}
|
|
}
|
|
if (!targetContact) {
|
|
registry.util.butter('No contact with the given email.');
|
|
return;
|
|
}
|
|
var typesList = targetContact.types.toLowerCase().split(',');
|
|
var actualTypesLookup = {};
|
|
for (var t in typesList) {
|
|
actualTypesLookup[typesList[t]] = true;
|
|
}
|
|
goog.soy.renderElement(
|
|
contentElt,
|
|
registry.soy.registrar.contacts.contact,
|
|
{
|
|
item: targetContact,
|
|
namePrefix: 'contacts[' + targetContactNdx + '].',
|
|
actualTypesLookup: actualTypesLookup,
|
|
readonly: (rspObj.readonly || false)
|
|
});
|
|
this.setupAppbar();
|
|
} else {
|
|
var contactsByType = {};
|
|
for (var c in contacts) {
|
|
var contact = contacts[c];
|
|
var types = contact.types;
|
|
if (!types) {
|
|
// If the contact has no types, synthesize an "OTHER" type so that it
|
|
// still will be displayed in the console.
|
|
types = 'OTHER';
|
|
}
|
|
types = types.split(',');
|
|
for (var t in types) {
|
|
var type = types[t].toLowerCase();
|
|
var contactsList = contactsByType[type];
|
|
if (!contactsList) {
|
|
contactsByType[type] = contactsList = [];
|
|
}
|
|
contactsList.push(contact);
|
|
}
|
|
}
|
|
goog.soy.renderElement(
|
|
contentElt,
|
|
registry.soy.registrar.contacts.set,
|
|
{contactsByType: contactsByType });
|
|
}
|
|
};
|
|
|
|
|
|
/** @override */
|
|
registry.registrar.ContactSettings.prototype.add = function() {
|
|
var newContactNdx = this.model.contacts.length;
|
|
goog.soy.renderElement(goog.dom.getRequiredElement('reg-content'),
|
|
registry.soy.registrar.contacts.contact,
|
|
{
|
|
item: {},
|
|
namePrefix: 'contacts[' + newContactNdx + '].',
|
|
actualTypesLookup: {},
|
|
readonly: false
|
|
});
|
|
this.toggleEdit();
|
|
};
|
|
|
|
|
|
/** @override */
|
|
registry.registrar.ContactSettings.prototype.sendDelete = function() {
|
|
var ndxToDel = null;
|
|
for (var i = 0; i < this.model.contacts.length; i++) {
|
|
var contact = this.model.contacts[i];
|
|
if (contact.emailAddress == this.id) {
|
|
ndxToDel = i;
|
|
}
|
|
}
|
|
if (goog.isNull(ndxToDel)) {
|
|
throw new Error('Email to delete does not match model.');
|
|
}
|
|
var modelCopy = /** @type {!Object}
|
|
*/ (JSON.parse(goog.json.serialize(this.model)));
|
|
goog.array.removeAt(modelCopy.contacts, ndxToDel);
|
|
this.resource.update(modelCopy, goog.bind(this.handleDeleteResponse, this));
|
|
};
|
|
|
|
|
|
/** @override */
|
|
registry.registrar.ContactSettings.prototype.prepareUpdate =
|
|
function(modelCopy) {
|
|
var form = registry.util.parseForm('item');
|
|
var contact;
|
|
// Handle update/create.
|
|
if (this.id) {
|
|
// Update contact, so overwrite it in the model before sending
|
|
// back to server.
|
|
var once = false;
|
|
for (var c in form.contacts) {
|
|
if (once) {
|
|
throw new Error('More than one contact parsed from form: ' + c);
|
|
}
|
|
contact = form.contacts[c];
|
|
modelCopy.contacts[c] = contact;
|
|
once = true;
|
|
}
|
|
} else {
|
|
// Add contact.
|
|
contact = form.contacts.pop();
|
|
modelCopy.contacts.push(contact);
|
|
}
|
|
contact.visibleInWhoisAsAdmin = contact.visibleInWhoisAsAdmin == 'true';
|
|
contact.visibleInWhoisAsTech = contact.visibleInWhoisAsTech == 'true';
|
|
contact.visibleInDomainWhoisAsAbuse =
|
|
contact.visibleInDomainWhoisAsAbuse == 'true';
|
|
contact.types = '';
|
|
for (var tNdx in contact.type) {
|
|
if (contact.type[tNdx]) {
|
|
if (contact.types.length > 0) {
|
|
contact.types += ',';
|
|
}
|
|
contact.types += ('' + tNdx).toUpperCase();
|
|
}
|
|
}
|
|
delete contact['type'];
|
|
// Override previous domain WHOIS abuse contact.
|
|
if (contact.visibleInDomainWhoisAsAbuse) {
|
|
for (var c in modelCopy.contacts) {
|
|
if (modelCopy.contacts[c].emailAddress != contact.emailAddress) {
|
|
modelCopy.contacts[c].visibleInDomainWhoisAsAbuse = false;
|
|
}
|
|
}
|
|
}
|
|
this.nextId = contact.emailAddress;
|
|
};
|
|
|
|
|
|
// XXX: Should be hoisted up.
|
|
/**
|
|
* 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.
|
|
* @override
|
|
*/
|
|
registry.registrar.ContactSettings.prototype.handleCreateResponse =
|
|
function(rsp) {
|
|
this.handleUpdateResponse(rsp);
|
|
if (rsp.status == 'SUCCESS') {
|
|
this.console.view('contact-settings/' + this.nextId);
|
|
}
|
|
return rsp;
|
|
};
|
|
|
|
|
|
/**
|
|
* 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.
|
|
* @override
|
|
*/
|
|
registry.registrar.ContactSettings.prototype.handleDeleteResponse =
|
|
function(rsp) {
|
|
this.handleUpdateResponse(rsp);
|
|
if (rsp.status == 'SUCCESS') {
|
|
this.id = null;
|
|
this.console.view('contact-settings');
|
|
}
|
|
return rsp;
|
|
};
|