1 /*
  2  * ***** BEGIN LICENSE BLOCK *****
  3  * Zimbra Collaboration Suite Web Client
  4  * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2012, 2013, 2014, 2016 Synacor, Inc.
  5  *
  6  * The contents of this file are subject to the Common Public Attribution License Version 1.0 (the "License");
  7  * you may not use this file except in compliance with the License.
  8  * You may obtain a copy of the License at: https://www.zimbra.com/license
  9  * The License is based on the Mozilla Public License Version 1.1 but Sections 14 and 15
 10  * have been added to cover use of software over a computer network and provide for limited attribution
 11  * for the Original Developer. In addition, Exhibit A has been modified to be consistent with Exhibit B.
 12  *
 13  * Software distributed under the License is distributed on an "AS IS" basis,
 14  * WITHOUT WARRANTY OF ANY KIND, either express or implied.
 15  * See the License for the specific language governing rights and limitations under the License.
 16  * The Original Code is Zimbra Open Source Web Client.
 17  * The Initial Developer of the Original Code is Zimbra, Inc.  All rights to the Original Code were
 18  * transferred by Zimbra, Inc. to Synacor, Inc. on September 14, 2015.
 19  *
 20  * All portions of the code are Copyright (C) 2006, 2007, 2008, 2009, 2010, 2012, 2013, 2014, 2016 Synacor, Inc. All Rights Reserved.
 21  * ***** END LICENSE BLOCK *****
 22  */
 23 
 24 /**
 25  * Creates an identity.
 26  * @class
 27  * This class represents an identity.
 28  * 
 29  * @param	{String}	name		the identity name
 30  * 
 31  */
 32 ZmIdentity = function(name) {
 33 
 34 	this.reset();
 35 	this.name = name;
 36 	this.id = "";
 37 };
 38 
 39 ZmIdentity.prototype.toString =
 40 function() {
 41 	return "ZmIdentity";
 42 };
 43 
 44 
 45 // Constants
 46 
 47 ZmIdentity.COMPOSE_SAME				= "same";
 48 ZmIdentity.COMPOSE_TEXT 			= "text";
 49 ZmIdentity.COMPOSE_HTML 			= "html";
 50 ZmIdentity.DEFAULT_NAME 			= "DEFAULT";
 51 
 52 
 53 ZmIdentity.FIELDS	= {};
 54 ZmIdentity._SOAP	= {};
 55 
 56 ZmIdentity.SIG_ID_NONE = "11111111-1111-1111-1111-111111111111";
 57 
 58 // Static inititialization
 59 
 60 ZmIdentity.addField =
 61 function(id, params) {
 62 
 63 	ZmIdentity[id] = id;
 64 	ZmIdentity.FIELDS[id] = params;
 65 	ZmIdentity._SOAP[params.soap] = params;
 66 };
 67 
 68 // Identity fields. The "name" parameter is used to set a property on this object.
 69 
 70 ZmIdentity.addField("NAME",						{ name: "name", soap: "zimbraPrefIdentityName", type: ZmSetting.D_STRING });
 71 ZmIdentity.addField("SEND_FROM_DISPLAY",		{ name: "sendFromDisplay", soap: "zimbraPrefFromDisplay", type: ZmSetting.D_STRING });
 72 ZmIdentity.addField("SEND_FROM_ADDRESS",		{ name: "sendFromAddress", soap: "zimbraPrefFromAddress", type: ZmSetting.D_STRING });
 73 ZmIdentity.addField("SEND_FROM_ADDRESS_TYPE",	{ name: "sendFromAddressType", soap: "zimbraPrefFromAddressType", type: ZmSetting.D_STRING });
 74 ZmIdentity.addField("SET_REPLY_TO",				{ name: "setReplyTo", soap: "zimbraPrefReplyToEnabled", type: ZmSetting.D_BOOLEAN });
 75 ZmIdentity.addField("SET_REPLY_TO_DISPLAY",		{ name: "setReplyToDisplay", soap: "zimbraPrefReplyToDisplay", type: ZmSetting.D_STRING });
 76 ZmIdentity.addField("SET_REPLY_TO_ADDRESS",		{ name: "setReplyToAddress", soap: "zimbraPrefReplyToAddress", type: ZmSetting.D_STRING });
 77 ZmIdentity.addField("SIGNATURE",				{ name: "signature", soap: "zimbraPrefDefaultSignatureId", type: ZmSetting.D_STRING });
 78 ZmIdentity.addField("REPLY_SIGNATURE",			{ name: "replySignature", soap: "zimbraPrefForwardReplySignatureId", type: ZmSetting.D_STRING });
 79 
 80 // Used only for Persona
 81 ZmIdentity.addField("USE_WHEN_SENT_TO",			{ name: "useWhenSentTo", soap: "zimbraPrefWhenSentToEnabled", type: ZmSetting.D_BOOLEAN });
 82 ZmIdentity.addField("WHEN_SENT_TO_ADDRESSES",	{ name: "whenSentToAddresses", soap: "zimbraPrefWhenSentToAddresses", type: ZmSetting.D_LIST });
 83 ZmIdentity.addField("USE_WHEN_IN_FOLDER",		{ name: "useWhenInFolder", soap: "zimbraPrefWhenInFoldersEnabled", type: ZmSetting.D_BOOLEAN });
 84 ZmIdentity.addField("WHEN_IN_FOLDERIDS",		{ name: "whenInFolderIds", soap: "zimbraPrefWhenInFolderIds", type: ZmSetting.D_LIST });
 85 
 86 
 87 // Public methods
 88 
 89 /**
 90  * Gets the field.
 91  * 
 92  * @param	{constant}	fieldId		the id
 93  * @return	{Object}	the value
 94  */
 95 ZmIdentity.prototype.getField =
 96 function(fieldId) {
 97 	return this[ZmIdentity.FIELDS[fieldId].name];
 98 };
 99 
100 /**
101  * Sets the field.
102  * 
103  * @param	{constant}	fieldId		the id
104  * @param	{Object}	value		the value
105  */
106 ZmIdentity.prototype.setField =
107 function(fieldId, value) {
108 	this[ZmIdentity.FIELDS[fieldId].name] = value;
109 };
110 
111 /**
112  * Creates the identity.
113  * 
114  * @param	{AjxCallback}		callback		the callback
115  * @param	{AjxCallback}		errorCallback		the error callback
116  * @param	{ZmBatchCommand}		batchCmd		the batch command
117  */
118 ZmIdentity.prototype.create =
119 function(callback, errorCallback, batchCmd) {
120 	return this._doRequest("Create", this._handleCreateResponse, callback, errorCallback, batchCmd);
121 };
122 
123 /**
124  * Saves the identity.
125  * 
126  * @param	{AjxCallback}		callback		the callback
127  * @param	{AjxCallback}		errorCallback		the error callback
128  * @param	{ZmBatchCommand}		batchCmd		the batch command
129  */
130 ZmIdentity.prototype.save =
131 function(callback, errorCallback, batchCmd) {
132 	return this._doRequest("Modify", this._handleSaveResponse, callback, errorCallback, batchCmd);
133 };
134 
135 /**
136  * Deletes the identity.
137  * 
138  * @param	{AjxCallback}		callback		the callback
139  * @param	{AjxCallback}		errorCallback		the error callback
140  * @param	{ZmBatchCommand}		batchCmd		the batch command
141  */
142 ZmIdentity.prototype.doDelete =
143 function(callback, errorCallback, batchCmd) {
144 	return this._doRequest("Delete", this._handleDeleteResponse, callback, errorCallback, batchCmd);
145 };
146 
147 /**
148  * Clears this identity's fields.
149  */
150 ZmIdentity.prototype.reset =
151 function() {
152 	for (var field in ZmIdentity.FIELDS) {
153 		var props = ZmIdentity.FIELDS[field];
154 		switch (props.type) {
155 			case ZmSetting.D_STRING:	this[props.name] = "";		break;
156 			case ZmSetting.D_BOOLEAN:	this[props.name] = false;	break;
157 			case ZmSetting.D_LIST:		this[props.name] = [];		break;
158 		}
159 	}
160 };
161 
162 // Protected methods
163 
164 ZmIdentity.prototype._doRequest =
165 function(requestType, respFunction, callback, errorCallback, batchCmd) {
166 
167 	var soapDoc = AjxSoapDoc.create(requestType + "IdentityRequest", "urn:zimbraAccount");
168 	var identityNode = soapDoc.set("identity");
169 
170 	var name = this.isDefault ? ZmIdentity.DEFAULT_NAME : this.name;
171 	if (requestType != "Create" && this.id !== "") {
172 		identityNode.setAttribute("id", this.id);
173 	}
174 	else {
175 		identityNode.setAttribute("name", this.name);
176 	}
177 	if (requestType != "Delete") {
178 		for (var i in ZmIdentity.FIELDS) {
179 			var field = ZmIdentity.FIELDS[i];
180 			if (this.hasOwnProperty(field.name)) {
181 				var value = this.getField(i);
182 				if (field.type == ZmSetting.D_LIST) {
183 					for (var j = 0, count = value.length; j < count; j++) {
184 						if (value[j]) {
185 							var propertyNode = soapDoc.set("a", value[j], identityNode);
186 							propertyNode.setAttribute("name", field.soap);
187 						}
188 					}
189 				} else {
190 					if (field.type == ZmSetting.D_BOOLEAN) {
191 						value = value ? "TRUE" : "FALSE";
192 					}
193 					var isSignature = (i == ZmIdentity.SIGNATURE || i == ZmIdentity.REPLY_SIGNATURE);
194 					var isDisplayName = (i == ZmIdentity.SEND_FROM_DISPLAY || i == ZmIdentity.SET_REPLY_TO_DISPLAY);
195 					var isEmailAddress = (i == ZmIdentity.SET_REPLY_TO_ADDRESS);
196 					if (value || isSignature || isDisplayName || isEmailAddress) {
197 						var propertyNode = soapDoc.set("a", value, identityNode);
198 						propertyNode.setAttribute("name", field.soap);
199 					}
200 				}
201 			}
202 		}
203 	}
204 
205 	var respCallback = new AjxCallback(this, respFunction, [callback]);
206 	if (batchCmd) {
207 		batchCmd.addNewRequestParams(soapDoc, respCallback, errorCallback);
208 		return;
209 	}
210 
211 	var params = {
212 		soapDoc: soapDoc,
213 		asyncMode: Boolean(callback),
214 		callback: respCallback,
215 		errorCallback: errorCallback
216 	};
217 
218 	return appCtxt.getAppController().sendRequest(params);
219 };
220 
221 ZmIdentity.prototype._loadFromDom =
222 function(data) {
223 
224 	this.id = data.id;
225 
226     var props = data._attrs;
227 	if (props) {
228 		for (var i in props) {
229 			var field = ZmIdentity._SOAP[i];
230 			if (field) {
231 				var value = props[i];
232 				if (field.type == ZmSetting.D_BOOLEAN) {
233 					this[field.name] = (value.toString().toUpperCase() == "TRUE");
234 				}
235 				else if (field.type == ZmSetting.D_LIST) {
236 					this[field.name] = AjxUtil.isArray(value) ? value : [value];
237 				}
238 				else {
239 					this[field.name] = value;
240 				}
241 			}
242 		}
243 	}
244 
245     if (data.name) {
246 		if (data.name == ZmIdentity.DEFAULT_NAME) {
247 			this.isDefault = true;
248         }
249 	}
250 };
251 
252 ZmIdentity.prototype._handleCreateResponse =
253 function(callback, result, response) {
254 
255 	this.id = response.identity[0].id;
256 	delete this._new;
257 	delete this._dirty;
258 
259 	var collection = appCtxt.getIdentityCollection();
260 	collection.add(this);
261 	collection._notify(ZmEvent.E_CREATE, { item: this } );
262 
263 	if (callback) {
264 		callback.run(this, result);
265 	}
266 };
267 
268 ZmIdentity.prototype._handleSaveResponse =
269 function(callback, result, response) {
270 
271 	delete this._dirty;
272 
273 	var collection = appCtxt.getIdentityCollection();
274 	collection.remove(this);
275 	collection.add(this);
276 	collection._notify(ZmEvent.E_MODIFY, { item: this } );
277 
278 	if (callback) {
279 		callback.run(this, result);
280 	}
281 };
282 
283 ZmIdentity.prototype._handleDeleteResponse =
284 function(callback, result, response) {
285 
286 	var collection = appCtxt.getIdentityCollection();
287 	collection.remove(this);
288 	collection._notify(ZmEvent.E_DELETE, { item: this } );
289 
290 	if (callback) {
291 		callback.run(this, result);
292 	}
293 };
294