1 /* 2 * ***** BEGIN LICENSE BLOCK ***** 3 * Zimbra Collaboration Suite Web Client 4 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 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) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Synacor, Inc. All Rights Reserved. 21 * ***** END LICENSE BLOCK ***** 22 */ 23 24 /** 25 * @overview 26 * This file defines the settings class. 27 */ 28 29 /** 30 * Creates a collection of settings with default values. If no app context is given, 31 * then this is a skeletal, non-live version of settings which can provide default 32 * settings and parse SOAP settings. 33 * @class 34 * This class is a collection of various sorts of settings: config values, preferences, 35 * and COS features. Each setting has an ID which can be used to retrieve it. 36 * 37 * @author Conrad Damon 38 * 39 * @param {Boolean} noInit if <code>true</code>, skip initialization 40 * 41 * @extends ZmModel 42 */ 43 ZmSettings = function(noInit) { 44 45 ZmModel.call(this, ZmEvent.S_SETTINGS); 46 47 this._settings = {}; // settings by ID 48 this._nameToId = {}; // map to get from server setting name to setting ID 49 50 this.getInfoResponse = null; // Cached GetInfoResponse for lazy creation of identities, etc. 51 this._handleImplicitChange = new AjxListener(this, this._implicitChangeListener); 52 53 if (!noInit) { 54 this.initialize(); 55 } 56 }; 57 58 ZmSettings.prototype = new ZmModel; 59 ZmSettings.prototype.constructor = ZmSettings; 60 61 ZmSettings.BASE64_TO_NORMAL_RATIO = 1.34; 62 63 /** 64 * Creates a new setting and adds it to the settings. 65 * 66 * @param {String} id the unique ID of the setting 67 * @param {Hash} params a hash of parameters 68 * @param {String} params.name the name of the pref or attr on the server 69 * @param {constant} params.type config, pref, or COS 70 * @param {constant} params.dataType string, int, or boolean (defaults to string) 71 * @param {Object} params.defaultValue the default value 72 */ 73 ZmSettings.prototype.registerSetting = 74 function(id, params) { 75 ZmSetting[id] = id; 76 var setting = this._settings[id] = new ZmSetting(id, params); 77 if (params.name) { 78 this._nameToId[params.name] = id; 79 } 80 if (params.isImplicit) { 81 setting.addChangeListener(this._handleImplicitChange); 82 } 83 return setting; 84 }; 85 86 /** 87 * Returns a string representation of the object. 88 * 89 * @return {String} a string representation of the object 90 */ 91 ZmSettings.prototype.toString = 92 function() { 93 return "ZmSettings"; 94 }; 95 96 /** 97 * Initializes the settings. 98 * 99 */ 100 ZmSettings.prototype.initialize = 101 function() { 102 this._initialize(); 103 this._setDefaults(); 104 this.userSettingsLoaded = false; 105 106 // set listeners for settings 107 var listener = new AjxListener(this, this._changeListener); 108 if (!appCtxt.multiAccounts) { 109 this.getSetting(ZmSetting.QUOTA_USED).addChangeListener(listener); 110 } 111 this.getSetting(ZmSetting.POLLING_INTERVAL).addChangeListener(listener); 112 this.getSetting(ZmSetting.SKIN_NAME).addChangeListener(listener); 113 this.getSetting(ZmSetting.SHOW_SELECTION_CHECKBOX).addChangeListener(listener); 114 this.getSetting(ZmSetting.LOCALE_NAME).addChangeListener(listener); 115 this.getSetting(ZmSetting.FONT_NAME).addChangeListener(listener); 116 this.getSetting(ZmSetting.FONT_SIZE).addChangeListener(listener); 117 this.getSetting(ZmSetting.SHORTCUTS).addChangeListener(listener); 118 this.getSetting(ZmSetting.CHILD_ACCTS_VISIBLE).addChangeListener(listener); 119 this.getSetting(ZmSetting.ATTACHMENTS_BLOCKED).addChangeListener(listener); 120 this.getSetting(ZmSetting.CHAT_PLAY_SOUND).addChangeListener(listener); 121 this.getSetting(ZmSetting.CHAT_ENABLED).addChangeListener(listener); 122 123 124 if (appCtxt.isOffline) { 125 this.getSetting(ZmSetting.OFFLINE_IS_MAILTO_HANDLER).addChangeListener(listener); 126 this.getSetting(ZmSetting.OFFLINE_BACKUP_ACCOUNT_ID).addChangeListener(listener); 127 this.getSetting(ZmSetting.OFFLINE_BACKUP_INTERVAL).addChangeListener(listener); 128 this.getSetting(ZmSetting.OFFLINE_BACKUP_PATH).addChangeListener(listener); 129 this.getSetting(ZmSetting.OFFLINE_BACKUP_KEEP).addChangeListener(listener); 130 this.getSetting(ZmSetting.OFFLINE_UPDATE_NOTIFY).addChangeListener(listener); 131 } 132 }; 133 134 /** 135 * Gets the value of the given setting. 136 * 137 * @param {String} id the ID of the setting 138 * @param {String} key the key 139 * @return {Object} the value or <code>null</code> for none 140 */ 141 ZmSettings.prototype.get = 142 function(id, key) { 143 return (id && this._settings[id]) ? this._settings[id].getValue(key) : null; 144 }; 145 146 /** 147 * Sets the value of the given setting. 148 * 149 * @param {String} id the ID of the setting 150 * @param {Object} value the new value for the setting 151 * @param {String} key optional key for use by hash table data type 152 * @param {Boolean} setDefault if <code>true</code>, also set the default value 153 * @param {Boolean} skipNotify if <code>true</code>, do not notify listeners 154 * @param {Boolean} skipImplicit if <code>true</code>, do not check for change to implicit pref 155 */ 156 ZmSettings.prototype.set = function(id, value, key, setDefault, skipNotify, skipImplicit) { 157 if (id && this._settings[id]) { 158 this._settings[id].setValue(value, key, setDefault, skipNotify, skipImplicit); 159 } 160 else { 161 DBG.println(AjxDebug.DBG1, "ZmSettings.set: ID missing (value = " + value); 162 } 163 }; 164 165 /** 166 * Gets the setting. 167 * 168 * @param {String} id the ID of the setting 169 * @return {ZmSetting} the setting 170 */ 171 ZmSettings.prototype.getSetting = 172 function(id) { 173 return this._settings[id]; 174 }; 175 176 /** 177 * Populates settings values. 178 * 179 * @param {Hash} list a hash of preference or attribute values 180 */ 181 ZmSettings.prototype.createFromJs = 182 function(list, setDefault, skipNotify, skipImplicit) { 183 // default skipImplicit value is true 184 skipImplicit = skipImplicit == null || skipImplicit; 185 186 for (var i in list) { 187 var val = list[i]; 188 var setting = this._settings[this._nameToId[i]]; 189 if (setting) { 190 if (setting.dataType == ZmSetting.D_HASH) { 191 var pairs = val.split(","); 192 var value = {}; 193 for (var j = 0; j < pairs.length; j++) { 194 var fields = pairs[j].split(":"); 195 value[fields[0]] = fields[1]; 196 } 197 val = value; 198 } 199 setting.setValue(val, null, setDefault, skipNotify, skipImplicit); 200 if (ZmSetting.IS_IMPLICIT[setting.id]) { 201 setting.origValue = setting.copyValue(); 202 } 203 } else { 204 DBG.println(AjxDebug.DBG3, "*** Unrecognized setting: " + i); 205 } 206 } 207 }; 208 209 /** 210 * Gets the setting that is associated with the given server-side setting, if any. 211 * 212 * @param {String} name the server-side setting name (for example, "zimbraFeatureContactsEnabled") 213 * @return {String} the setting id 214 */ 215 ZmSettings.prototype.getSettingByName = 216 function(name) { 217 return this._nameToId[name]; 218 }; 219 220 /** 221 * Checks if the given ID was received from the server. Use this method 222 * to determine whether this ID is supported by a ZCS server. Currently used by 223 * ZDesktop since it can "talk" to both v5 and v6 ZCS. 224 * 225 * @param {String} id the setting ID 226 * @return {Boolean} <code>true</code> if the attribute is supported 227 */ 228 ZmSettings.prototype.attrExists = 229 function(id) { 230 var name = this.getSetting(id).name; 231 return (this.getInfoResponse.prefs._attrs[name] || 232 this.getInfoResponse.attrs._attrs[name]); 233 }; 234 235 /** 236 * Retrieves the preferences, COS settings, and metadata for the current user. 237 * All the data gets stored into the settings collection. 238 * 239 * @param {AjxCallback} callback the callback to run after response is received 240 * @param {AjxCallback} errorCallback the callback to run error is received 241 * @param {String} accountName the name of account to load settings for 242 * @param {Object} response the pre-determined JSON response object 243 * @param {ZmBatchCommand} batchCommand set if part of a batch request 244 */ 245 ZmSettings.prototype.loadUserSettings = 246 function(callback, errorCallback, accountName, response, batchCommand) { 247 var args = [callback, accountName]; 248 249 var soapDoc = AjxSoapDoc.create("GetInfoRequest", "urn:zimbraAccount"); 250 soapDoc.setMethodAttribute("rights", "createDistList"); //not sure when this is called, but let's add it anyway. (on login it's called from within launchZCS.JSP calling GetInfoJSONTag.java 251 var respCallback = this._handleResponseLoadUserSettings.bind(this, args); 252 if (batchCommand) { 253 batchCommand.addNewRequestParams(soapDoc, respCallback); 254 } 255 else { 256 var params = { 257 soapDoc: (response ? null : soapDoc), 258 accountName: accountName, 259 asyncMode: true, 260 callback: respCallback, 261 errorCallback: errorCallback, 262 response: response 263 }; 264 appCtxt.getAppController().sendRequest(params); 265 } 266 }; 267 268 /** 269 * @private 270 */ 271 ZmSettings.prototype._handleResponseLoadUserSettings = 272 function(callback, accountName, result) { 273 this.setUserSettings(result.getResponse().GetInfoResponse, accountName); 274 this.userSettingsLoaded = true; 275 if (callback) { 276 callback.run(result); 277 } 278 }; 279 280 /** 281 * Sets the user settings. 282 * 283 * @param {hash} params 284 * @param {object} params.info The GetInfoResponse object. 285 * @param {string} [params.accountName] The name of the account. 286 * @param {boolean} [params.setDefault] Set default value 287 * @param {boolean} [params.skipNotify] Skip change notification 288 * @param {boolean} [params.skipImplicit] Skip implicit changes 289 * @param {boolean} [params.preInit] Only init base settings for startup 290 */ 291 ZmSettings.prototype.setUserSettings = function(params) { 292 293 params = Dwt.getParams(arguments, ["info", "accountName", "setDefault", "skipNotify", "skipImplicit", "preInit"]); 294 295 var info = this.getInfoResponse = params.info; 296 297 appCtxt.createDistListAllowed = false; 298 appCtxt.createDistListAllowedDomains = []; 299 appCtxt.createDistListAllowedDomainsMap = {}; 300 var rightTargets = info.rights && info.rights.targets; 301 if (rightTargets) { 302 for (var i = 0; i < rightTargets.length; i++) { 303 var target = rightTargets[i]; 304 if (target.right == "createDistList") { 305 if (target.target[0].type == "domain") { 306 appCtxt.createDistListAllowed = true; 307 appCtxt.createDistListAllowedDomains.push(target.target[0].name); 308 appCtxt.createDistListAllowedDomainsMap[target.target[0].name] = true; 309 break; 310 } 311 } 312 313 } 314 } 315 316 // For delegated admin who can see prefs but not mail, we still need to register the mail settings so 317 // they can be created and set below in createFromJs(). 318 if (this.get(ZmSetting.ADMIN_DELEGATED)) { 319 if (!this.get(ZmSetting.ADMIN_MAIL_ENABLED) && this.get(ZmSetting.ADMIN_PREFERENCES_ENABLED)) { 320 (new ZmMailApp()).enableMailPrefs(); 321 } 322 } 323 324 // Voice feature 325 this.set(ZmSetting.VOICE_ENABLED, this._hasVoiceFeature(), null, false, true); 326 327 var accountName = params.accountName; 328 var setDefault = params.preInit ? false : params.setDefault; 329 var skipNotify = params.preInit ? true : params.skipNotify; 330 var skipImplicit = params.preInit ? true : params.skipImplicit; 331 332 var settings = [ 333 ZmSetting.ADMIN_DELEGATED, info.adminDelegated, 334 ZmSetting.MESSAGE_SIZE_LIMIT, this._base64toNormalSize(info.attSizeLimit), 335 ZmSetting.CHANGE_PASSWORD_URL, info.changePasswordURL, 336 ZmSetting.DOCUMENT_SIZE_LIMIT, this._base64toNormalSize(info.docSizeLimit), 337 ZmSetting.LAST_ACCESS, info.accessed, 338 ZmSetting.LICENSE_STATUS, info.license && info.license.status, 339 ZmSetting.PREVIOUS_SESSION, info.prevSession, 340 ZmSetting.PUBLIC_URL, info.publicURL, 341 ZmSetting.ADMIN_URL, info.adminURL, 342 ZmSetting.QUOTA_USED, info.used, 343 ZmSetting.RECENT_MESSAGES, info.recent, 344 ZmSetting.REST_URL, info.rest, 345 ZmSetting.USERNAME, info.name, 346 ZmSetting.EMAIL_VALIDATION_REGEX, info.zimbraMailAddressValidationRegex, 347 ZmSetting.DISABLE_SENSITIVE_ZIMLETS_IN_MIXED_MODE, (info.domainSettings && info.domainSettings.zimbraZimletDataSensitiveInMixedModeDisabled ? info.domainSettings.zimbraZimletDataSensitiveInMixedModeDisabled : "FALSE") 348 ]; 349 for (var i = 0; i < settings.length; i += 2) { 350 var value = settings[i+1]; 351 if (value != null) { 352 this.set(settings[i], value, null, setDefault, skipNotify, skipImplicit); 353 } 354 } 355 356 // features and other settings 357 if (info.attrs && info.attrs._attrs) { 358 this.createFromJs(info.attrs._attrs, setDefault, skipNotify, skipImplicit); 359 } 360 361 // By default, everything but mail is enabled for delegated admin. Require an additional setting to allow admin to view mail. 362 if (this.get(ZmSetting.ADMIN_DELEGATED)) { 363 this.set(ZmSetting.MAIL_ENABLED, this.get(ZmSetting.ADMIN_MAIL_ENABLED), setDefault, skipNotify, skipImplicit); 364 var enableMailPrefs = this.get(ZmSetting.MAIL_ENABLED) || (this.get(ZmSetting.ADMIN_DELEGATED) && this.get(ZmSetting.ADMIN_PREFERENCES_ENABLED)); 365 this.set(ZmSetting.MAIL_PREFERENCES_ENABLED, enableMailPrefs, setDefault, skipNotify, skipImplicit); 366 // Disable other areas where mail could be exposed to a prefs-only admin 367 if (this.get(ZmSetting.MAIL_PREFERENCES_ENABLED) && !this.get(ZmSetting.MAIL__ENABLED)) { 368 this.set(ZmSetting.MAIL_FORWARDING_ENABLED, false, setDefault, skipNotify, skipImplicit); 369 this.set(ZmSetting.FILTERS_MAIL_FORWARDING_ENABLED, false, setDefault, skipNotify, skipImplicit); 370 this.set(ZmSetting.NOTIF_FEATURE_ENABLED, false, setDefault, skipNotify, skipImplicit); 371 } 372 } 373 374 // Server may provide us with SSO-enabled URL for Community integration (integration URL with OAuth signature) 375 if (info.communityURL) { 376 this.set(ZmSetting.SOCIAL_EXTERNAL_URL, info.communityURL, null, setDefault, skipNotify); 377 } 378 379 if (params.preInit) { 380 return; 381 } 382 383 // preferences 384 if (info.prefs && info.prefs._attrs) { 385 this.createFromJs(info.prefs._attrs, setDefault, skipNotify, skipImplicit); 386 } 387 388 // accounts 389 var setting; 390 if (!accountName) { 391 // NOTE: only the main account can have children 392 appCtxt.accountList.createAccounts(this, info); 393 394 // for offline, find out whether this client supports prism-specific features 395 if (appCtxt.isOffline) { 396 if (AjxEnv.isPrism && window.platform) { 397 this.set(ZmSetting.OFFLINE_SUPPORTS_MAILTO, true, null, setDefault, skipNotify, skipImplicit); 398 this.set(ZmSetting.OFFLINE_SUPPORTS_DOCK_UPDATE, true, null, setDefault, skipNotify, skipImplicit); 399 } 400 401 // bug #45804 - sharing always enabled for offline 402 appCtxt.set(ZmSetting.SHARING_ENABLED, true, null, setDefault, skipNotify); 403 } 404 } 405 406 // handle settings whose values may depend on other settings 407 setting = this._settings[ZmSetting.REPLY_TO_ADDRESS]; 408 if (setting) { 409 setting.defaultValue = this.get(ZmSetting.USERNAME); 410 } 411 if (this.get(ZmSetting.FORCE_CAL_OFF)) { 412 this.set(ZmSetting.CALENDAR_ENABLED, false, null, setDefault, skipNotify, skipImplicit); 413 } 414 415 if (!this.get(ZmSetting.OPTIONS_ENABLED)) { 416 this.set(ZmSetting.FILTERS_ENABLED, false, null, setDefault, skipNotify, skipImplicit); 417 } 418 419 // load zimlets *only* for the main account 420 if (!accountName) { 421 if (info.zimlets && info.zimlets.zimlet) { 422 if (this.get(ZmSetting.ZIMLETS_SYNCHRONOUS)) { 423 var action = new AjxTimedAction(this, this._beginLoadZimlets, [info.zimlets.zimlet, info.props.prop, true]); 424 AjxTimedAction.scheduleAction(action, 0); 425 } else { 426 var listener = new AjxListener(this, this._beginLoadZimlets, [info.zimlets.zimlet, info.props.prop, false]); 427 appCtxt.getAppController().addListener(ZmAppEvent.POST_STARTUP, listener); 428 } 429 } else { 430 appCtxt.allZimletsLoaded(); 431 } 432 } 433 434 var value = appCtxt.get(ZmSetting.REPLY_INCLUDE_ORIG); 435 if (value) { 436 var list = ZmMailApp.INC_MAP[value]; 437 appCtxt.set(ZmSetting.REPLY_INCLUDE_WHAT, list[0], null, setDefault, skipNotify); 438 appCtxt.set(ZmSetting.REPLY_USE_PREFIX, list[1], null, setDefault, skipNotify); 439 appCtxt.set(ZmSetting.REPLY_INCLUDE_HEADERS, list[2], null, setDefault, skipNotify); 440 } 441 442 var value = appCtxt.get(ZmSetting.FORWARD_INCLUDE_ORIG); 443 if (value) { 444 var list = ZmMailApp.INC_MAP[value]; 445 appCtxt.set(ZmSetting.FORWARD_INCLUDE_WHAT, list[0], null, setDefault, skipNotify); 446 appCtxt.set(ZmSetting.FORWARD_USE_PREFIX, list[1], null, setDefault, skipNotify); 447 appCtxt.set(ZmSetting.FORWARD_INCLUDE_HEADERS, list[2], null, setDefault, skipNotify); 448 } 449 450 // Populate Sort Order Defaults 451 var sortPref = ZmSettings.DEFAULT_SORT_PREF; 452 sortPref[ZmId.VIEW_CONVLIST] = ZmSearch.DATE_DESC; 453 sortPref[ZmId.VIEW_CONV] = ZmSearch.DATE_DESC; 454 sortPref[ZmId.VIEW_TRAD] = ZmSearch.DATE_DESC; 455 sortPref[ZmId.VIEW_CONTACT_SRC] = ZmSearch.NAME_ASC; 456 sortPref[ZmId.VIEW_CONTACT_TGT] = ZmSearch.NAME_ASC; 457 sortPref[ZmId.VIEW_CONTACT_SIMPLE] = ZmSearch.NAME_ASC; 458 sortPref[ZmId.VIEW_CAL] = ZmSearch.DATE_ASC; 459 sortPref[ZmId.VIEW_TASKLIST] = ZmSearch.DUE_DATE_ASC; 460 sortPref[ZmId.VIEW_BRIEFCASE_DETAIL] = ZmSearch.SUBJ_ASC; 461 462 var sortOrderSetting = this._settings[ZmSetting.SORTING_PREF]; 463 if (sortOrderSetting) { 464 // Populate empty sort pref's with defaultValues 465 for (var pref in sortPref){ 466 if (!sortOrderSetting.getValue(pref)){ 467 sortOrderSetting.setValue(sortPref[pref], pref, false, true); 468 } 469 } 470 471 // Explicitly Set defaultValue 472 sortOrderSetting.defaultValue = AjxUtil.hashCopy(sortPref); 473 } 474 475 DwtControl.useBrowserTooltips = this.get(ZmSetting.BROWSER_TOOLTIPS_ENABLED); 476 477 this._updateUserFontPrefsRule(); 478 }; 479 480 481 ZmSettings.prototype._base64toNormalSize = 482 function(base64) { 483 if (!base64 || base64 === -1) { //-1 is unlimited 484 return base64; 485 } 486 return base64 / ZmSettings.BASE64_TO_NORMAL_RATIO; 487 }; 488 489 490 /** 491 * @private 492 */ 493 ZmSettings.prototype._beginLoadZimlets = 494 function(zimlet, prop, sync) { 495 var zimletsCallback = new AjxCallback(this, this._loadZimletPackage, [zimlet, prop, sync]); 496 AjxDispatcher.require(["Startup2"], false, zimletsCallback); 497 }; 498 499 ZmSettings.prototype._loadZimletPackage = 500 function(zimlet, prop, sync) { 501 var zimletsCallback = new AjxCallback(this, this._loadZimlets, [zimlet, prop, sync]); 502 AjxDispatcher.require("Zimlet", false, zimletsCallback); 503 }; 504 505 /** 506 * @private 507 */ 508 ZmSettings.prototype._loadZimlets = 509 function(allZimlets, props, sync) { 510 511 allZimlets = allZimlets || []; 512 this.registerSetting("ZIMLETS", {type:ZmSetting.T_CONFIG, defaultValue:allZimlets, isGlobal:true}); 513 this.registerSetting("USER_PROPS", {type:ZmSetting.T_CONFIG, defaultValue:props}); 514 515 var zimlets = this._getCheckedZimlets(allZimlets); 516 517 DBG.println(AjxDebug.DBG1, "Zimlets - Loading " + zimlets.length + " Zimlets"); 518 var zimletMgr = appCtxt.getZimletMgr(); 519 zimletMgr.loadZimlets(zimlets, props, null, null, sync); 520 521 if (zimlets && zimlets.length) { 522 var activeApp = appCtxt.getCurrentApp(); 523 if (activeApp) { 524 var overview; 525 if (appCtxt.multiAccounts) { 526 var containerId = activeApp.getOverviewContainer().containerId; 527 var zimletLabel = ZmOrganizer.LABEL[ZmOrganizer.ZIMLET]; 528 var overviewId = [containerId, zimletLabel].join("_"); 529 overview = appCtxt.getOverviewController().getOverview(overviewId); 530 } else { 531 overview = activeApp.getOverview(); 532 } 533 } 534 535 // update overview tree 536 if (overview) { 537 overview.setTreeView(ZmOrganizer.ZIMLET); 538 539 // HACK: for multi-account, hide the zimlet section if no panel zimlets 540 if (appCtxt.multiAccounts && zimletMgr.getPanelZimlets().length == 0) { 541 activeApp.getOverviewContainer().removeZimletSection(); 542 } 543 } 544 545 // create global portlets 546 if (appCtxt.get(ZmSetting.PORTAL_ENABLED)) { 547 var portletMgr = appCtxt.getApp(ZmApp.PORTAL).getPortletMgr(); 548 var portletIds = portletMgr.createPortlets(true); 549 } 550 } 551 }; 552 553 /** 554 * Filters a list of zimlets, returned ones that are checked. 555 * 556 * @param zimlets [array] list of zimlet objects 557 * 558 * @private 559 */ 560 ZmSettings.prototype._getCheckedZimlets = 561 function(allZimlets) { 562 563 var zimlets = []; 564 for (var i = 0; i < allZimlets.length; i++) { 565 var zimletObj = allZimlets[i]; 566 if (zimletObj.zimletContext[0].presence != "disabled") { 567 zimlets.push(zimletObj); 568 } 569 } 570 571 return zimlets; 572 }; 573 574 /** 575 * Loads the preference data. 576 * 577 * @param {AjxCallback} callback the callback 578 */ 579 ZmSettings.prototype.loadPreferenceData = 580 function(callback) { 581 // force main account (in case multi-account) since locale/skins are global 582 var command = new ZmBatchCommand(null, appCtxt.accountList.mainAccount.name); 583 584 var skinDoc = AjxSoapDoc.create("GetAvailableSkinsRequest", "urn:zimbraAccount"); 585 var skinCallback = new AjxCallback(this, this._handleResponseLoadAvailableSkins); 586 command.addNewRequestParams(skinDoc, skinCallback); 587 588 var localeDoc = AjxSoapDoc.create("GetAvailableLocalesRequest", "urn:zimbraAccount"); 589 var localeCallback = new AjxCallback(this, this._handleResponseGetAllLocales); 590 command.addNewRequestParams(localeDoc, localeCallback); 591 592 var csvFormatsDoc = AjxSoapDoc.create("GetAvailableCsvFormatsRequest", "urn:zimbraAccount"); 593 var csvFormatsCallback = new AjxCallback(this, this._handleResponseGetAvailableCsvFormats); 594 command.addNewRequestParams(csvFormatsDoc, csvFormatsCallback); 595 596 command.run(callback); 597 }; 598 599 /** 600 * @private 601 */ 602 ZmSettings.prototype._handleResponseLoadAvailableSkins = 603 function(result) { 604 var resp = result.getResponse().GetAvailableSkinsResponse; 605 var skins = resp.skin; 606 if (skins && skins.length) { 607 var setting = appCtxt.accountList.mainAccount.settings.getSetting(ZmSetting.AVAILABLE_SKINS); 608 for (var i = 0; i < skins.length; i++) { 609 // always save available skins on the main account (in case multi-account) 610 setting.setValue(skins[i].name); 611 } 612 } 613 }; 614 615 /** 616 * @private 617 */ 618 ZmSettings.prototype._handleResponseGetAllLocales = 619 function(response) { 620 var locales = response._data.GetAvailableLocalesResponse.locale; 621 if (locales && locales.length) { 622 for (var i = 0, count = locales.length; i < count; i++) { 623 var locale = locales[i]; 624 // bug: 38038 625 locale.id = locale.id.replace(/^in/,"id"); 626 ZmLocale.create(locale.id, locale.name, ZmMsg["localeName_" + locale.id] || locale.localName); 627 } 628 if (locales.length === 1) { 629 //Fix for bug# 80762 - Set the value to always true in case of only one language/locale present 630 this.set(ZmSetting.LOCALE_CHANGE_ENABLED, true); 631 } 632 else { 633 this.set(ZmSetting.LOCALE_CHANGE_ENABLED, ZmLocale.hasChoices()); 634 } 635 } 636 }; 637 638 /** 639 * @private 640 */ 641 ZmSettings.prototype._handleResponseGetAvailableCsvFormats = 642 function(result){ 643 var formats = result.getResponse().GetAvailableCsvFormatsResponse.csv; 644 if (formats && formats.length) { 645 var setting = appCtxt.accountList.mainAccount.settings.getSetting(ZmSetting.AVAILABLE_CSVFORMATS); 646 for (var i = 0; i < formats.length; i++) { 647 setting.setValue(formats[i].name); 648 } 649 } 650 }; 651 652 /** 653 * Saves one or more settings. 654 * 655 * @param {Array} list a list of {ZmSetting} objects 656 * @param {AjxCallback} callback the callback to run after response is received 657 * @param {ZmBatchCommand} batchCommand the batch command 658 * @param {ZmZimbraAccount} account the account to save under 659 * @param {boolean} isImplicit if true, we are saving implicit settings 660 */ 661 ZmSettings.prototype.save = 662 function(list, callback, batchCommand, account, isImplicit) { 663 if (!(list && list.length)) { return; } 664 665 var acct = account || appCtxt.getActiveAccount(); 666 var soapDoc = AjxSoapDoc.create("ModifyPrefsRequest", "urn:zimbraAccount"); 667 var gotOne = false; 668 var metaData = [], done = {}, setting; 669 for (var i = 0; i < list.length; i++) { 670 setting = list[i]; 671 if (done[setting.id]) { continue; } 672 if (setting.type == ZmSetting.T_METADATA) { 673 metaData.push(setting); 674 // update the local meta data 675 acct.metaData.update(setting.section, setting.name, setting.getValue()); 676 continue; 677 } else if (setting.type != ZmSetting.T_PREF) { 678 DBG.println(AjxDebug.DBG1, "*** Attempt to modify non-pref: " + setting.id + " / " + setting.name); 679 continue; 680 } 681 if (!setting.name) { 682 DBG.println(AjxDebug.DBG2, "Modify internal pref: " + setting.id); 683 continue; 684 } 685 if (setting.dataType == ZmSetting.D_LIST) { 686 // LDAP supports multi-valued attrs, so don't serialize list 687 var value = setting.getValue(); 688 if (value && value.length) { 689 for (var j = 0; j < value.length; j++) { 690 var node = soapDoc.set("pref", value[j]); 691 node.setAttribute("name", setting.name); 692 } 693 } else { 694 var node = soapDoc.set("pref", ""); 695 node.setAttribute("name", setting.name); 696 } 697 } else { 698 var value = setting.getValue(null, true); 699 var node = soapDoc.set("pref", value); 700 node.setAttribute("name", setting.name); 701 } 702 703 done[setting.id] = true; 704 gotOne = true; 705 } 706 707 // bug: 50668 if the setting is implicit and global, use main Account 708 if(appCtxt.isOffline && ZmSetting.IS_IMPLICIT[setting.id] && ZmSetting.IS_GLOBAL[setting.id]) { 709 acct = appCtxt.accountList.mainAccount; 710 } 711 712 if (metaData.length > 0) { 713 var metaDataCallback = new AjxCallback(this, this._handleResponseSaveMetaData, [metaData]); 714 var sections = [ZmSetting.M_IMPLICIT, ZmSetting.M_OFFLINE]; 715 acct.metaData.save(sections, metaDataCallback); 716 } 717 718 if (gotOne) { 719 var respCallback; 720 if (callback || batchCommand) { 721 respCallback = new AjxCallback(this, this._handleResponseSave, [list, callback]); 722 } 723 if (batchCommand) { 724 batchCommand.addNewRequestParams(soapDoc, respCallback); 725 } else { 726 appCtxt.getAppController().sendRequest({soapDoc:soapDoc, asyncMode:true, callback:respCallback, 727 accountName:acct.name, noBusyOverlay:isImplicit}); 728 } 729 } 730 }; 731 732 /** 733 * @private 734 */ 735 ZmSettings.prototype._handleResponseSaveMetaData = 736 function(list, result) { 737 for (var i = 0; i < list.length; i++) { 738 var setting = list[i]; 739 if (!ZmSetting.IS_IMPLICIT[setting.id]) { 740 setting.origValue = setting.copyValue(); 741 setting._notify(ZmEvent.E_MODIFY); 742 } 743 } 744 }; 745 746 /** 747 * @private 748 */ 749 ZmSettings.prototype._handleResponseSave = 750 function(list, callback, result) { 751 var resp = result.getResponse(); 752 if (resp.ModifyPrefsResponse != null) { 753 // notify each changed setting's listeners 754 for (var i = 0; i < list.length; i++) { 755 var setting = list[i]; 756 setting.origValue = setting.copyValue(); 757 if (!ZmSetting.IS_IMPLICIT[setting.id]) { 758 setting._notify(ZmEvent.E_MODIFY); 759 } 760 } 761 // notify any listeners on the settings as a whole 762 this._notify(ZmEvent.E_MODIFY, {settings:list}); 763 } 764 765 if (callback) { 766 callback.run(result); 767 } 768 }; 769 770 ZmSettings.DEFAULT_SORT_PREF = {}; 771 772 /** 773 * Set defaults which are determined dynamically (which can't be set in static code). 774 * 775 * @private 776 */ 777 ZmSettings.prototype._setDefaults = 778 function() { 779 780 var value = AjxUtil.formatUrl({host:location.hostname, path:"/service/soap/", qsReset:true}); 781 this.set(ZmSetting.CSFE_SERVER_URI, value, null, false, true); 782 783 // CSFE_MSG_FETCHER_URI 784 value = AjxUtil.formatUrl({host:location.hostname, path:"/service/home/~/", qsReset:true, qsArgs:{auth:"co"}}); 785 this.set(ZmSetting.CSFE_MSG_FETCHER_URI, value, null, false, true); 786 787 // CSFE_UPLOAD_URI 788 value = AjxUtil.formatUrl({host:location.hostname, path:"/service/upload", qsReset:true, qsArgs:{lbfums:""}}); 789 this.set(ZmSetting.CSFE_UPLOAD_URI, value, null, false, true); 790 791 // CSFE_ATTACHMENT_UPLOAD_URI 792 value = AjxUtil.formatUrl({host:location.hostname, path:"/service/upload", qsReset:true}); 793 this.set(ZmSetting.CSFE_ATTACHMENT_UPLOAD_URI, value, null, false, true); 794 795 // CSFE EXPORT URI 796 value = AjxUtil.formatUrl({host:location.hostname, path:"/service/home/~/", qsReset:true, qsArgs:{auth:"co", id:"{0}", fmt:"csv"}}); 797 this.set(ZmSetting.CSFE_EXPORT_URI, value, null, false, true); 798 799 var h = location.hostname; 800 var isDev = ((h.indexOf(".zimbra.com") != -1) || (window.appDevMode && (/\.local$/.test(h) || (!appCtxt.isOffline && h == "localhost")))); 801 this.set(ZmSetting.IS_DEV_SERVER, isDev); 802 if (isDev || window.isScriptErrorOn) { 803 this.set(ZmSetting.SHOW_SCRIPT_ERRORS, true, null, false, true); 804 } 805 806 this.setReportScriptErrorsSettings(AjxException, ZmController.handleScriptError); 807 }; 808 809 ZmSettings.prototype.persistImplicitSortPrefs = 810 function(id){ 811 return ZmSettings.DEFAULT_SORT_PREF[id]; 812 }; 813 814 /** 815 * sets AjxException static attributes. This is extracted so it can be called from ZmNewwindow as well. 816 * this is since the child window gets its own AjxException variable. 817 * 818 * @param AjxExceptionClassVar 819 * @param handler 820 */ 821 ZmSettings.prototype.setReportScriptErrorsSettings = 822 function(AjxExceptionClassVar, handler) { 823 // script error reporting 824 var rse = AjxExceptionClassVar.reportScriptErrors = this._settings[ZmSetting.SHOW_SCRIPT_ERRORS].getValue(); 825 if (rse) { 826 AjxExceptionClassVar.setScriptErrorHandler(handler); 827 } 828 829 }; 830 831 /** 832 * Loads the standard settings and their default values. 833 * 834 * @private 835 */ 836 ZmSettings.prototype._initialize = 837 function() { 838 // CONFIG SETTINGS 839 this.registerSetting("ADMIN_DELEGATED", {type:ZmSetting.T_CONFIG, dataType:ZmSetting.D_BOOLEAN, defaultValue:false}); 840 this.registerSetting("AC_TIMER_INTERVAL", {type:ZmSetting.T_CONFIG, dataType:ZmSetting.D_INT, defaultValue:300}); 841 this.registerSetting("ASYNC_MODE", {type:ZmSetting.T_CONFIG, dataType:ZmSetting.D_BOOLEAN, defaultValue:true}); 842 this.registerSetting("BRANCH", {type:ZmSetting.T_CONFIG, defaultValue:"JUDASPRIEST"}); 843 844 // next 3 are replaced during deployment 845 this.registerSetting("CLIENT_DATETIME", {type:ZmSetting.T_CONFIG, defaultValue:"@buildDateTime@"}); 846 this.registerSetting("CLIENT_RELEASE", {type:ZmSetting.T_CONFIG, defaultValue:"@buildRelease@"}); 847 this.registerSetting("CLIENT_VERSION", {type:ZmSetting.T_CONFIG, defaultValue:"@buildVersion@"}); 848 this.registerSetting("CONFIG_PATH", {type:ZmSetting.T_CONFIG, defaultValue:appContextPath + "/js/zimbraMail/config"}); 849 this.registerSetting("CSFE_EXPORT_URI", {type:ZmSetting.T_CONFIG}); 850 this.registerSetting("CSFE_MSG_FETCHER_URI", {type:ZmSetting.T_CONFIG}); 851 this.registerSetting("CSFE_SERVER_URI", {type:ZmSetting.T_CONFIG}); 852 this.registerSetting("CSFE_UPLOAD_URI", {type:ZmSetting.T_CONFIG}); 853 this.registerSetting("CSFE_ATTACHMENT_UPLOAD_URI", {type:ZmSetting.T_CONFIG}); 854 this.registerSetting("DEV", {type:ZmSetting.T_CONFIG, dataType:ZmSetting.D_BOOLEAN, defaultValue:false}); 855 this.registerSetting("FORCE_CAL_OFF", {type:ZmSetting.T_CONFIG, dataType:ZmSetting.D_BOOLEAN, defaultValue:false}); 856 this.registerSetting("HELP_URI", {type:ZmSetting.T_CONFIG, defaultValue:appContextPath + ZmMsg.helpURI}); 857 this.registerSetting("HTTP_PORT", {type:ZmSetting.T_CONFIG, defaultValue:ZmSetting.HTTP_DEFAULT_PORT}); 858 this.registerSetting("HTTPS_PORT", {type:ZmSetting.T_CONFIG, defaultValue:ZmSetting.HTTPS_DEFAULT_PORT}); 859 this.registerSetting("INSTANT_NOTIFY_INTERVAL", {type:ZmSetting.T_CONFIG, dataType:ZmSetting.D_INT, defaultValue:500}); // milliseconds 860 this.registerSetting("INSTANT_NOTIFY_TIMEOUT", {type:ZmSetting.T_CONFIG, dataType:ZmSetting.D_INT, defaultValue:300}); // seconds 861 this.registerSetting("IS_DEV_SERVER", {type:ZmSetting.T_CONFIG, dataType:ZmSetting.D_BOOLEAN, defaultValue:false}); 862 this.registerSetting("LOG_REQUEST", {type:ZmSetting.T_CONFIG, dataType:ZmSetting.D_BOOLEAN, defaultValue:true}); 863 this.registerSetting("LOGO_URI", {type:ZmSetting.T_CONFIG, defaultValue:null}); 864 this.registerSetting("PROTOCOL_MODE", {type:ZmSetting.T_CONFIG, defaultValue:ZmSetting.PROTO_HTTP}); 865 this.registerSetting("SERVER_VERSION", {type:ZmSetting.T_CONFIG}); 866 this.registerSetting("SHOW_SCRIPT_ERRORS", {type:ZmSetting.T_CONFIG, dataType:ZmSetting.D_BOOLEAN, defaultValue:false}); 867 this.registerSetting("TIMEOUT", {type:ZmSetting.T_CONFIG, dataType:ZmSetting.D_INT, defaultValue:30}); // seconds 868 this.registerSetting("USE_XML", {type:ZmSetting.T_CONFIG, dataType:ZmSetting.D_BOOLEAN, defaultValue:false}); 869 this.registerSetting("SMIME_HELP_URI", {type:ZmSetting.T_CONFIG, defaultValue:appContextPath + ZmMsg.smimeHelpURI}); 870 871 // DOMAIN SETTINGS 872 this.registerSetting("CHANGE_PASSWORD_URL", {type:ZmSetting.T_CONFIG}); 873 this.registerSetting("PUBLIC_URL", {type:ZmSetting.T_CONFIG}); 874 this.registerSetting("ADMIN_URL", {type:ZmSetting.T_CONFIG}); 875 this.registerSetting("DISABLE_SENSITIVE_ZIMLETS_IN_MIXED_MODE", {type:ZmSetting.T_CONFIG}); 876 877 // COS SETTINGS - APPS 878 this.registerSetting("BRIEFCASE_ENABLED", {name:"zimbraFeatureBriefcasesEnabled", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:false}); 879 this.registerSetting("ATTACHMENTS_BLOCKED", {name:"zimbraAttachmentsBlocked", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:false}); 880 this.registerSetting("CALENDAR_ENABLED", {name:"zimbraFeatureCalendarEnabled", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:false}); 881 this.registerSetting("CALENDAR_UPSELL_ENABLED", {name:"zimbraFeatureCalendarUpsellEnabled", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:false}); 882 this.registerSetting("CALENDAR_UPSELL_URL", {name:"zimbraFeatureCalendarUpsellURL", type:ZmSetting.T_COS}); 883 this.registerSetting("CONTACTS_ENABLED", {name:"zimbraFeatureContactsEnabled", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:false}); 884 this.registerSetting("CONTACTS_UPSELL_ENABLED", {name:"zimbraFeatureContactsUpsellEnabled", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:false}); 885 this.registerSetting("CONTACTS_UPSELL_URL", {name:"zimbraFeatureContactsUpsellURL", type:ZmSetting.T_COS}); 886 this.registerSetting("IMPORT_ENABLED", {name:"zimbraFeatureImportFolderEnabled", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:true}); 887 this.registerSetting("EXPORT_ENABLED", {name:"zimbraFeatureExportFolderEnabled", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:true}); 888 this.registerSetting("MAIL_ENABLED", {name:"zimbraFeatureMailEnabled", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:true}); 889 this.registerSetting("EXTERNAL_USER_MAIL_ADDRESS", {name:"zimbraExternalUserMailAddress", type:ZmSetting.T_COS, dataType:ZmSetting.D_STRING}); 890 this.registerSetting("ADMIN_MAIL_ENABLED", {name:"zimbraFeatureAdminMailEnabled", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:true}); 891 this.registerSetting("ADMIN_PREFERENCES_ENABLED", {name:"zimbraFeatureAdminPreferencesEnabled", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:false}); 892 this.registerSetting("MAIL_UPSELL_ENABLED", {name:"zimbraFeatureMailUpsellEnabled", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:false}); 893 this.registerSetting("MAIL_UPSELL_URL", {name:"zimbraFeatureMailUpsellURL", type:ZmSetting.T_COS}); 894 this.registerSetting("OPTIONS_ENABLED", {name:"zimbraFeatureOptionsEnabled", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:true}); 895 this.registerSetting("PORTAL_ENABLED", {name:"zimbraFeaturePortalEnabled", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:false}); 896 this.registerSetting("SOCIAL_ENABLED", {name:"zimbraFeatureSocialEnabled", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:false}); 897 this.registerSetting("SOCIAL_EXTERNAL_ENABLED", {name:"zimbraFeatureSocialExternalEnabled", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:false}); 898 this.registerSetting("SOCIAL_EXTERNAL_URL", {name:"zimbraFeatureSocialExternalURL", type:ZmSetting.T_COS}); 899 this.registerSetting("SOCIAL_NAME", {name:"zimbraFeatureSocialName", type:ZmSetting.T_COS, defaultValue:ZmMsg.communityName}); 900 this.registerSetting("TASKS_ENABLED", {name:"zimbraFeatureTasksEnabled", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:false}); 901 this.registerSetting("VOICE_ENABLED", {name:"zimbraFeatureVoiceEnabled", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:false}); 902 this.registerSetting("VOICE_UPSELL_ENABLED", {name:"zimbraFeatureVoiceUpsellEnabled", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:false}); 903 this.registerSetting("VOICE_UPSELL_URL", {name:"zimbraFeatureVoiceUpsellURL", type:ZmSetting.T_COS}); 904 this.registerSetting("DLS_FOLDER_ENABLED", {name:"zimbraFeatureDistributionListFolderEnabled", type: ZmSetting.T_COS, dataType: ZmSetting.D_BOOLEAN, defaultValue: true}); 905 906 // COS SETTINGS 907 this.registerSetting("ATTACHMENTS_VIEW_IN_HTML_ONLY", {name:"zimbraAttachmentsViewInHtmlOnly", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:false}); 908 this.registerSetting("AVAILABLE_SKINS", {type:ZmSetting.T_COS, dataType:ZmSetting.D_LIST, isGlobal:true}); 909 this.registerSetting("AVAILABLE_CSVFORMATS", {type:ZmSetting.T_COS, dataType:ZmSetting.D_LIST, isGlobal:true}); 910 this.registerSetting("CHANGE_PASSWORD_ENABLED", {name:"zimbraFeatureChangePasswordEnabled", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:false}); 911 this.registerSetting("DISPLAY_NAME", {name:"displayName", type:ZmSetting.T_COS}); 912 this.registerSetting("DUMPSTER_ENABLED", {name:"zimbraDumpsterEnabled", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:true}); 913 this.registerSetting("ERROR_REPORT_URL", {name:"zimbraErrorReportUrl", type:ZmSetting.T_COS, dataType:ZmSetting.D_STRING}); 914 this.registerSetting("EXPORT_MAX_DAYS", {name:"zimbraExportMaxDays", type:ZmSetting.T_COS, dataType:ZmSetting.D_INT, defaultValue:0}); 915 this.registerSetting("FILTER_BATCH_SIZE", {name:"zimbraFilterBatchSize", type:ZmSetting.T_COS, dataType:ZmSetting.D_INT, defaultValue: 10000}); 916 this.registerSetting("FLAGGING_ENABLED", {name:"zimbraFeatureFlaggingEnabled", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:true}); 917 this.registerSetting("FOLDERS_EXPANDED", {name:"zimbraPrefFoldersExpanded", type:ZmSetting.T_METADATA, dataType: ZmSetting.D_HASH, isImplicit:true, section:ZmSetting.M_IMPLICIT}); 918 this.registerSetting("FOLDER_TREE_OPEN", {name:"zimbraPrefFolderTreeOpen", type:ZmSetting.T_PREF, dataType:ZmSetting.D_BOOLEAN, defaultValue:true, isImplicit:true}); 919 this.registerSetting("FOLDER_TREE_SASH_WIDTH", {name:"zimbraPrefFolderTreeSash", type:ZmSetting.T_METADATA, dataType:ZmSetting.D_INT, isImplicit:true, section:ZmSetting.M_IMPLICIT}); 920 this.registerSetting("GAL_AUTOCOMPLETE_ENABLED", {name:"zimbraFeatureGalAutoCompleteEnabled", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:false}); 921 this.registerSetting("GAL_ENABLED", {name:"zimbraFeatureGalEnabled", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:true}); 922 this.registerSetting("GROUP_CALENDAR_ENABLED", {name:"zimbraFeatureGroupCalendarEnabled", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:true}); 923 this.registerSetting("HTML_COMPOSE_ENABLED", {name:"zimbraFeatureHtmlComposeEnabled", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:true}); 924 this.registerSetting("IDLE_SESSION_TIMEOUT", {name:"zimbraMailIdleSessionTimeout", type:ZmSetting.T_COS, dataType:ZmSetting.D_LDAP_TIME, defaultValue:0}); 925 this.registerSetting("IMAP_ACCOUNTS_ENABLED", {name:"zimbraFeatureImapDataSourceEnabled", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:false}); 926 this.registerSetting("IMPORT_ON_LOGIN_ENABLED", {name:"zimbraDataSourceImportOnLogin", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:false}); 927 this.registerSetting("INSTANT_NOTIFY", {name:"zimbraFeatureInstantNotify", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:false}); 928 this.registerSetting("LOCALE_CHANGE_ENABLED", {name:"zimbraFeatureLocaleChangeEnabled", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:false}); 929 this.registerSetting("LOCALES", {type:ZmSetting.T_COS, dataType:ZmSetting.D_LIST}); 930 this.registerSetting("LOGIN_URL", {name:"zimbraWebClientLoginURL", type:ZmSetting.T_COS}); 931 this.registerSetting("LOGOUT_URL", {name:"zimbraWebClientLogoutURL", type:ZmSetting.T_COS}); 932 this.registerSetting("MIN_POLLING_INTERVAL", {name:"zimbraMailMinPollingInterval", type:ZmSetting.T_COS, dataType:ZmSetting.D_LDAP_TIME, defaultValue:120}); 933 this.registerSetting("MOBILE_SYNC_ENABLED", {name:"zimbraFeatureMobileSyncEnabled", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:false}); 934 this.registerSetting("MOBILE_POLICY_ENABLED", {name:"zimbraFeatureMobilePolicyEnabled", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:false}); 935 this.registerSetting("POP_ACCOUNTS_ENABLED", {name:"zimbraFeaturePop3DataSourceEnabled", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:false}); 936 this.registerSetting("PORTAL_NAME", {name:"zimbraPortalName", type:ZmSetting.T_COS, defaultValue:"example"}); 937 this.registerSetting("PRIORITY_INBOX_ENABLED", {name:"zimbraFeaturePriorityInboxEnabled", type:ZmSetting.T_COS, dataType: ZmSetting.D_BOOLEAN, defaultValue:true}); 938 this.registerSetting("PWD_MAX_LENGTH", {name:"zimbraPasswordMaxLength", type:ZmSetting.T_COS, dataType:ZmSetting.D_INT, defaultValue:64}); 939 this.registerSetting("PWD_MIN_LENGTH", {name:"zimbraPasswordMinLength", type:ZmSetting.T_COS, dataType:ZmSetting.D_INT, defaultValue:6}); 940 this.registerSetting("QUOTA", {name:"zimbraMailQuota", type:ZmSetting.T_COS, dataType:ZmSetting.D_INT, defaultValue:0}); 941 this.registerSetting("SAVED_SEARCHES_ENABLED", {name:"zimbraFeatureSavedSearchesEnabled", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:false}); 942 this.registerSetting("SEARCH_TREE_OPEN", {name:"zimbraPrefSearchTreeOpen", type:ZmSetting.T_PREF, dataType:ZmSetting.D_BOOLEAN, defaultValue:true, isImplicit:true}); 943 this.registerSetting("SHARING_ENABLED", {name:"zimbraFeatureSharingEnabled", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:true}); 944 this.registerSetting("SHARING_PUBLIC_ENABLED", {name:"zimbraPublicSharingEnabled", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:true}); 945 this.registerSetting("SHARING_EXTERNAL_ENABLED", {name:"zimbraExternalSharingEnabled", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:true}); 946 this.registerSetting("SHORTCUT_ALIASES_ENABLED", {name:"zimbraFeatureShortcutAliasesEnabled", type:ZmSetting.T_PREF, dataType:ZmSetting.D_BOOLEAN, defaultValue:true}); 947 this.registerSetting("SHOW_OFFLINE_LINK", {name:"zimbraWebClientShowOfflineLink", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:true}); 948 this.registerSetting("SIGNATURES_ENABLED", {name:"zimbraFeatureSignaturesEnabled", type:ZmSetting.T_PREF, dataType:ZmSetting.D_BOOLEAN, defaultValue:true}); 949 this.registerSetting("SKIN_CHANGE_ENABLED", {name:"zimbraFeatureSkinChangeEnabled", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:true}); 950 this.registerSetting("SOCIAL_FILTERS_ENABLED", {name:"zimbraFeatureSocialFiltersEnabled", type:ZmSetting.T_COS, dataType:ZmSetting.D_LIST, isImplicit: true, section:ZmSetting.M_IMPLICIT}); 951 this.registerSetting("SPAM_ENABLED", {name:"zimbraFeatureAntispamEnabled", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:true}); 952 this.registerSetting("TAG_TREE_OPEN", {name:"zimbraPrefTagTreeOpen", type:ZmSetting.T_PREF, dataType:ZmSetting.D_BOOLEAN, defaultValue:true, isImplicit:true}); 953 this.registerSetting("TAGGING_ENABLED", {name:"zimbraFeatureTaggingEnabled", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:false}); 954 this.registerSetting("VIEW_ATTACHMENT_AS_HTML", {name:"zimbraFeatureViewInHtmlEnabled", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:false}); 955 this.registerSetting("EXPAND_DL_ENABLED", {name:"zimbraFeatureDistributionListExpandMembersEnabled", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:true}); 956 this.registerSetting("FORCE_CLEAR_COOKIES", {name:"zimbraForceClearCookies", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:false}); 957 this.registerSetting("WEBCLIENT_OFFLINE_ENABLED", {name:"zimbraFeatureWebClientOfflineAccessEnabled", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:true}); 958 this.registerSetting("SPELL_DICTIONARY", {name:"zimbraPrefSpellDictionary", type:ZmSetting.T_COS, defaultValue:""}); 959 this.registerSetting("TWO_FACTOR_AUTH_AVAILABLE", {name:"zimbraFeatureTwoFactorAuthAvailable", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:false}); 960 this.registerSetting("TWO_FACTOR_AUTH_REQUIRED", {name:"zimbraFeatureTwoFactorAuthRequired", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:false}); 961 this.registerSetting("TRUSTED_DEVICES_ENABLED", {name:"zimbraFeatureTrustedDevicesEnabled", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:false}); 962 this.registerSetting("APP_PASSWORDS_ENABLED", {name:"zimbraFeatureAppSpecificPasswordsEnabled", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:false}); 963 964 // user metadata (included with COS since the user can't change them) 965 this.registerSetting("LICENSE_STATUS", {type:ZmSetting.T_COS, defaultValue:ZmSetting.LICENSE_GOOD}); 966 this.registerSetting("QUOTA_USED", {type:ZmSetting.T_COS, dataType:ZmSetting.D_INT}); 967 this.registerSetting("USERID", {name:"zimbraId", type:ZmSetting.T_COS}); 968 this.registerSetting("USERNAME", {type:ZmSetting.T_COS}); 969 this.registerSetting("CN", {name:"cn", type:ZmSetting.T_COS}); 970 this.registerSetting("LAST_ACCESS", {type:ZmSetting.T_COS, dataType:ZmSetting.D_INT}); 971 this.registerSetting("PREVIOUS_SESSION", {type:ZmSetting.T_COS, dataType:ZmSetting.D_INT}); 972 this.registerSetting("RECENT_MESSAGES", {type:ZmSetting.T_COS, dataType:ZmSetting.D_INT}); 973 this.registerSetting("REST_URL", {name:"rest" , type:ZmSetting.T_COS}); 974 this.registerSetting("IS_ADMIN", {name:"zimbraIsAdminAccount", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue: false}); 975 this.registerSetting("IS_EXTERNAL", {name:"zimbraIsExternalVirtualAccount", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue: false}); 976 this.registerSetting("IS_DELEGATED_ADMIN", {name:"zimbraIsDelegatedAdminAccount", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue: false}); 977 this.registerSetting("MESSAGE_SIZE_LIMIT", {type:ZmSetting.T_COS, dataType:ZmSetting.D_INT}); 978 this.registerSetting("DOCUMENT_SIZE_LIMIT", {type:ZmSetting.T_COS, dataType:ZmSetting.D_INT}); 979 980 // CLIENT SIDE FEATURE SUPPORT 981 this.registerSetting("ATTACHMENT_ENABLED", {type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:true}); 982 this.registerSetting("ATT_VIEW_ENABLED", {type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:false}); 983 this.registerSetting("BROWSER_TOOLTIPS_ENABLED", {type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:true}); 984 this.registerSetting("EVAL_ENABLED", {type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:false}); 985 this.registerSetting("FEED_ENABLED", {type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:false}); 986 this.registerSetting("HELP_ENABLED", {type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:true}); 987 this.registerSetting("HISTORY_SUPPORT_ENABLED", {type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:("onhashchange" in window)}); 988 this.registerSetting("NOTES_ENABLED", {type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:false}); 989 this.registerSetting("PRINT_ENABLED", {type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:true}); 990 this.registerSetting("SEARCH_ENABLED", {type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:true}); 991 this.registerSetting("SHORTCUT_LIST_ENABLED", {type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:true}); 992 this.registerSetting("OFFLINE_ENABLED", {type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:appCtxt.isOffline}); 993 this.registerSetting("SPELL_CHECK_ENABLED", {type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:!appCtxt.isOffline && (!AjxEnv.isSafari || AjxEnv.isSafari3up || AjxEnv.isChrome)}); 994 this.registerSetting("SPELL_CHECK_ADD_WORD_ENABLED", {type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:!AjxEnv.isSafari || AjxEnv.isSafari3up || AjxEnv.isChrome}); 995 996 //SETTINGS SET AT DOMAIN LEVEL 997 this.registerSetting("EMAIL_VALIDATION_REGEX", {name:"zimbraMailAddressValidationRegex", type:ZmSetting.T_DOMAIN, dataType:ZmSetting.D_LIST}); 998 this.registerSetting("SUPPORTED_HELPS", {name:"zimbraWebClientSupportedHelps", type:ZmSetting.T_DOMAIN, dataType:ZmSetting.D_LIST}); 999 1000 // USER PREFERENCES (mutable) 1001 1002 // general preferences 1003 this.registerSetting("ACCOUNTS", {type: ZmSetting.T_PREF, dataType: ZmSetting.D_HASH}); 1004 this.registerSetting("TWO_FACTOR_AUTH_ENABLED", {name:"zimbraTwoFactorAuthEnabled", type:ZmSetting.T_PREF, dataType:ZmSetting.D_BOOLEAN, defaultValue:false}); 1005 this.registerSetting("ACCOUNT_TREE_OPEN", {name:"zimbraPrefAccountTreeOpen", type:ZmSetting.T_PREF, dataType:ZmSetting.D_BOOLEAN, defaultValue:false, isImplicit:true}); 1006 this.registerSetting("CHILD_ACCTS_VISIBLE", {name:"zimbraPrefChildVisibleAccount", type:ZmSetting.T_PREF, dataType:ZmSetting.D_LIST}); 1007 this.registerSetting("CLIENT_TYPE", {name:"zimbraPrefClientType", type:ZmSetting.T_PREF, defaultValue:ZmSetting.CLIENT_ADVANCED}); 1008 this.registerSetting("COMPOSE_AS_FORMAT", {name:"zimbraPrefComposeFormat", type:ZmSetting.T_PREF, defaultValue:ZmSetting.COMPOSE_HTML, isGlobal:true}); 1009 this.registerSetting("COMPOSE_INIT_FONT_COLOR", {name:"zimbraPrefHtmlEditorDefaultFontColor", type:ZmSetting.T_PREF, defaultValue:ZmSetting.COMPOSE_FONT_COLOR, isGlobal:true}); 1010 this.registerSetting("COMPOSE_INIT_FONT_FAMILY", {name:"zimbraPrefHtmlEditorDefaultFontFamily", type:ZmSetting.T_PREF, defaultValue:ZmSetting.COMPOSE_FONT_FAM, isGlobal:true}); 1011 this.registerSetting("COMPOSE_INIT_FONT_SIZE", {name:"zimbraPrefHtmlEditorDefaultFontSize", type:ZmSetting.T_PREF, defaultValue:ZmSetting.COMPOSE_FONT_SIZE, isGlobal:true}); 1012 this.registerSetting("COMPOSE_INIT_DIRECTION", {name:"zimbraPrefComposeDirection", type:ZmSetting.T_PREF, defaultValue:ZmSetting.LTR, isGlobal:true}); 1013 this.registerSetting("SHOW_COMPOSE_DIRECTION_BUTTONS", {name:"zimbraPrefShowComposeDirection", type:ZmSetting.T_PREF, dataType:ZmSetting.D_BOOLEAN, defaultValue:false, isGlobal:true}); 1014 this.registerSetting("DEFAULT_TIMEZONE", {name:"zimbraPrefTimeZoneId", type:ZmSetting.T_PREF, dataType:ZmSetting.D_STRING, defaultValue:AjxTimezone.getServerId(AjxTimezone.DEFAULT), isGlobal:true}); 1015 this.registerSetting("WEBCLIENT_OFFLINE_BROWSER_KEY", {name:"zimbraPrefWebClientOfflineBrowserKey", type:ZmSetting.T_PREF, dataType:ZmSetting.D_STRING, isImplicit:true}); 1016 this.registerSetting("DEFAULT_PRINTFONTSIZE", {name:"zimbraPrefDefaultPrintFontSize", type:ZmSetting.T_PREF, dataType:ZmSetting.D_STRING, defaultValue:ZmSetting.PRINT_FONT_SIZE, isGlobal:true}); 1017 this.registerSetting("GROUPBY_HASH", {type: ZmSetting.T_PREF, dataType:ZmSetting.D_HASH}); 1018 this.registerSetting("GROUPBY_LIST", {name:"zimbraPrefGroupByList", type:ZmSetting.T_METADATA, dataType:ZmSetting.D_HASH, isImplicit:true, section:ZmSetting.M_IMPLICIT}); 1019 this.registerSetting("FILTERS", {type: ZmSetting.T_PREF, dataType: ZmSetting.D_HASH}); 1020 this.registerSetting("FONT_NAME", {name:"zimbraPrefFont", type:ZmSetting.T_PREF, defaultValue: ZmSetting.FONT_SYSTEM, isGlobal:true}); 1021 this.registerSetting("FONT_SIZE", {name:"zimbraPrefFontSize", type:ZmSetting.T_PREF, defaultValue: ZmSetting.FONT_SIZE_NORMAL, isGlobal:true}); 1022 this.registerSetting("IDENTITIES", {type: ZmSetting.T_PREF, dataType: ZmSetting.D_HASH}); 1023 this.registerSetting("INITIALLY_SEARCH_GAL", {name:"zimbraPrefGalSearchEnabled", type:ZmSetting.T_PREF, dataType:ZmSetting.D_BOOLEAN, defaultValue:true}); 1024 this.registerSetting("LIST_VIEW_COLUMNS", {name:"zimbraPrefListViewColumns", type:ZmSetting.T_PREF, dataType:ZmSetting.D_HASH, isImplicit:true}); 1025 this.registerSetting("LOCALE_NAME", {name:"zimbraPrefLocale", type:ZmSetting.T_PREF, defaultValue:appRequestLocaleId, isGlobal:true}); 1026 this.registerSetting("SHOW_SELECTION_CHECKBOX", {name:"zimbraPrefShowSelectionCheckbox", type:ZmSetting.T_PREF, dataType:ZmSetting.D_BOOLEAN, defaultValue:true, isGlobal:true}); 1027 // PAGE_SIZE: number of items to fetch for virtual paging; also used for number of msgs in one page of a conv 1028 this.registerSetting("PAGE_SIZE", {name: "zimbraPrefItemsPerVirtualPage", type:ZmSetting.T_PREF, dataType:ZmSetting.D_INT, defaultValue:50, isGlobal:true}); 1029 this.registerSetting("PASSWORD", {type:ZmSetting.T_PREF, dataType:ZmSetting.D_NONE}); 1030 this.registerSetting("POLLING_INTERVAL", {name:"zimbraPrefMailPollingInterval", type:ZmSetting.T_PREF, dataType:ZmSetting.D_LDAP_TIME, defaultValue:300}); 1031 this.registerSetting("POLLING_INTERVAL_ENABLED", {name:"zimbraFeatureMailPollingIntervalPreferenceEnabled", type:ZmSetting.T_PREF, dataType:ZmSetting.D_BOOLEAN, defaultValue:true}); 1032 this.registerSetting("SEARCH_INCLUDES_SHARED", {name:"zimbraPrefIncludeSharedItemsInSearch", type:ZmSetting.T_PREF, dataType:ZmSetting.D_BOOLEAN, defaultValue:false, isGlobal:true}); 1033 this.registerSetting("SEARCH_INCLUDES_SPAM", {name:"zimbraPrefIncludeSpamInSearch", type:ZmSetting.T_PREF, dataType:ZmSetting.D_BOOLEAN, defaultValue:false, isGlobal:true}); 1034 this.registerSetting("SEARCH_INCLUDES_TRASH", {name:"zimbraPrefIncludeTrashInSearch", type:ZmSetting.T_PREF, dataType:ZmSetting.D_BOOLEAN, defaultValue:false, isGlobal:true}); 1035 this.registerSetting("SHORT_ADDRESS", {name:"zimbraPrefShortEmailAddress", type:ZmSetting.T_PREF, dataType: ZmSetting.D_BOOLEAN, defaultValue: true}); 1036 this.registerSetting("SHORTCUTS", {name:"zimbraPrefShortcuts", type:ZmSetting.T_PREF}); 1037 this.registerSetting("SHOW_SEARCH_STRING", {name:"zimbraPrefShowSearchString", type:ZmSetting.T_PREF, dataType:ZmSetting.D_BOOLEAN, defaultValue:false, isGlobal:true}); 1038 this.registerSetting("SIGNATURES", {type: ZmSetting.T_PREF, dataType: ZmSetting.D_HASH}); 1039 this.registerSetting("SIGNATURES_MAX", {name:"zimbraSignatureMaxNumEntries", type:ZmSetting.T_COS, dataType:ZmSetting.D_INT, defaultValue:20}); 1040 this.registerSetting("SIGNATURES_MIN", {name:"zimbraSignatureMinNumEntries", type:ZmSetting.T_COS, dataType:ZmSetting.D_INT, defaultValue:1}); 1041 this.registerSetting("SKIN_NAME", {name:"zimbraPrefSkin", type:ZmSetting.T_PREF, defaultValue:"skin", isGlobal:true}); 1042 this.registerSetting("SORTING_PREF", {name:"zimbraPrefSortOrder", type:ZmSetting.T_PREF, dataType:ZmSetting.D_HASH, isImplicit:true, isGlobal:true, dontSaveDefault: true}); 1043 this.registerSetting("USE_KEYBOARD_SHORTCUTS", {name:"zimbraPrefUseKeyboardShortcuts", type:ZmSetting.T_PREF, dataType:ZmSetting.D_BOOLEAN, defaultValue:true}); 1044 this.registerSetting("VIEW_AS_HTML", {name:"zimbraPrefMessageViewHtmlPreferred", type:ZmSetting.T_PREF, dataType:ZmSetting.D_BOOLEAN, defaultValue:false, isGlobal:true}); 1045 this.registerSetting("VOICE_ACCOUNTS", {type: ZmSetting.T_PREF, dataType: ZmSetting.D_HASH}); 1046 this.registerSetting("WARN_ON_EXIT", {name:"zimbraPrefWarnOnExit", type:ZmSetting.T_PREF, dataType:ZmSetting.D_BOOLEAN, defaultValue:true}); 1047 1048 this._registerOfflineSettings(); 1049 this._registerZimletsSettings(); 1050 1051 // need to do this before loadUserSettings(), and zimlet settings are not tied to an app where it would normally be done 1052 this.registerSetting("ZIMLET_TREE_OPEN", {name:"zimbraPrefZimletTreeOpen", type:ZmSetting.T_PREF, dataType:ZmSetting.D_BOOLEAN, defaultValue:false, isImplicit:true}); 1053 1054 //shared settings 1055 this.registerSetting("MAIL_ALIASES", {name:"zimbraMailAlias", type:ZmSetting.T_COS, dataType:ZmSetting.D_LIST}); 1056 this.registerSetting("ALLOW_FROM_ADDRESSES", {name:"zimbraAllowFromAddress", type:ZmSetting.T_COS, dataType:ZmSetting.D_LIST}); 1057 1058 // Internal pref to control display of mail-related preferences. The only time it will be false is for a delegated admin with zimbraFeatureAdminMailEnabled and 1059 // zimbraFeatureAdminPreferencesEnabled set to FALSE. 1060 this.registerSetting("MAIL_PREFERENCES_ENABLED", {type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:true}); 1061 1062 //chat settings 1063 this.registerSetting("CHAT_PLAY_SOUND", {name:"zimbraPrefChatPlaySound", type: ZmSetting.T_PREF, dataType: ZmSetting.D_BOOLEAN, defaultValue:true, isGlobal:true}); 1064 this.registerSetting("CHAT_FEATURE_ENABLED", {name:"zimbraFeatureChatEnabled", type: ZmSetting.T_COS, dataType: ZmSetting.D_BOOLEAN, defaultValue:true, isGlobal:true}); 1065 this.registerSetting("CHAT_ENABLED", {name:"zimbraPrefChatEnabled", type: ZmSetting.T_PREF, dataType: ZmSetting.D_BOOLEAN, defaultValue:true, isGlobal:true}); 1066 1067 ZmApp.runAppFunction("registerSettings", this); 1068 }; 1069 1070 /** 1071 * @private 1072 */ 1073 ZmSettings.prototype._registerZimletsSettings = 1074 function() { 1075 // zimlet-specific 1076 this.registerSetting("CHECKED_ZIMLETS_ENABLED", {name:"zimbraFeatureManageZimlets", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:true, isGlobal:true}); 1077 this.registerSetting("CHECKED_ZIMLETS", {name:"zimbraPrefZimlets", type:ZmSetting.T_PREF, dataType:ZmSetting.D_LIST, isGlobal:true}); 1078 this.registerSetting("MANDATORY_ZIMLETS", {name:"zimbraZimletMandatoryZimlets", type:ZmSetting.T_COS, dataType:ZmSetting.D_LIST}); 1079 this.registerSetting("ZIMLETS_SYNCHRONOUS", {name:"zimbraZimletLoadSynchronously", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:false}); 1080 1081 }; 1082 1083 /** 1084 * @private 1085 */ 1086 ZmSettings.prototype._registerOfflineSettings = 1087 function() { 1088 if (!appCtxt.isOffline) { return; } 1089 1090 // offline-specific 1091 this.registerSetting("OFFLINE_ACCOUNT_FLAVOR", {name:"offlineAccountFlavor", type:ZmSetting.T_PREF, dataType:ZmSetting.D_STRING}); 1092 this.registerSetting("OFFLINE_COMPOSE_ENABLED", {type:ZmSetting.T_CONFIG, dataType:ZmSetting.D_BOOLEAN, defaultValue:false, isGlobal:true}); 1093 this.registerSetting("OFFLINE_DEBUG_TRACE", {type:ZmSetting.T_CONFIG, dataType:ZmSetting.D_BOOLEAN, defaultValue:false}); 1094 this.registerSetting("OFFLINE_IS_MAILTO_HANDLER", {name:"zimbraPrefMailtoHandlerEnabled", type:ZmSetting.T_PREF, dataType:ZmSetting.D_BOOLEAN, defaultValue:false, isGlobal:true}); 1095 this.registerSetting("OFFLINE_REMOTE_SERVER_URI", {name:"offlineRemoteServerUri", type:ZmSetting.T_PREF, dataType:ZmSetting.D_STRING}); 1096 this.registerSetting("OFFLINE_REPORT_EMAIL", {type:ZmSetting.T_PREF, dataType:ZmSetting.D_STRING, defaultValue:"zdesktop-report@zimbra.com", isGlobal:true}); 1097 this.registerSetting("OFFLINE_SHOW_ALL_MAILBOXES", {name:"offlineShowAllMailboxes", type:ZmSetting.T_METADATA, dataType:ZmSetting.D_BOOLEAN, defaultValue:true, section:ZmSetting.M_OFFLINE, isGlobal:true}); 1098 this.registerSetting("OFFLINE_ALL_MAILBOXES_TREE_OPEN", {name:"offlineAllMailboxesTreeOpen", type:ZmSetting.T_METADATA, dataType:ZmSetting.D_BOOLEAN, defaultValue:false, section:ZmSetting.M_OFFLINE, isGlobal:true, isImplicit:true}); 1099 this.registerSetting("OFFLINE_NOTIFY_NEWMAIL_ON_INBOX", {name:"offlineNotifyNewMailOnInbox", type:ZmSetting.T_METADATA, dataType:ZmSetting.D_BOOLEAN, defaultValue:true, section:ZmSetting.M_OFFLINE, isGlobal:true}); 1100 this.registerSetting("OFFLINE_SAVED_SEARCHES_TREE_OPEN",{name:"offlineSavedSearchesTreeOpen", type:ZmSetting.T_METADATA, dataType:ZmSetting.D_BOOLEAN, defaultValue:false, section:ZmSetting.M_OFFLINE, isGlobal:true, isImplicit:true}); 1101 this.registerSetting("OFFLINE_SMTP_ENABLED", {name:"zimbraDataSourceSmtpEnabled", type:ZmSetting.T_PREF, dataType:ZmSetting.D_BOOLEAN, defaultValue:true}); 1102 this.registerSetting("OFFLINE_SUPPORTS_MAILTO", {type:ZmSetting.T_PREF, dataType:ZmSetting.D_BOOLEAN, defaultValue:false, isGlobal:true}); 1103 this.registerSetting("OFFLINE_SUPPORTS_DOCK_UPDATE", {type:ZmSetting.T_PREF, dataType:ZmSetting.D_BOOLEAN, defaultValue:false, isGlobal:true}); 1104 this.registerSetting("OFFLINE_WEBAPP_URI", {name:"offlineWebappUri", type:ZmSetting.T_PREF, dataType:ZmSetting.D_STRING}); 1105 this.registerSetting("OFFLINE_BACKUP_INTERVAL", {name:"zimbraPrefOfflineBackupInterval", type:ZmSetting.T_PREF, dataType:ZmSetting.D_INT, defaultValue:0, isGlobal:true}); 1106 this.registerSetting("OFFLINE_BACKUP_PATH", {name:"zimbraPrefOfflineBackupPath", type:ZmSetting.T_PREF, dataType:ZmSetting.D_STRING, isGlobal:true}); 1107 this.registerSetting("OFFLINE_BACKUP_KEEP", {name:"zimbraPrefOfflineBackupKeep", type:ZmSetting.T_PREF, dataType:ZmSetting.D_INT, isGlobal:true}); 1108 this.registerSetting("OFFLINE_BACKUP_ACCOUNT_ID", {name:"zimbraPrefOfflineBackupAccountId", type:ZmSetting.T_PREF, dataType:ZmSetting.D_INT, isGlobal:true}); 1109 this.registerSetting("OFFLINE_BACKUP_RESTORE", {name:"zimbraPrefOfflineBackupRestore", dataType:ZmSetting.D_INT, isGlobal:true}); 1110 this.registerSetting("OFFLINE_BACKUP_NOW_BUTTON", {name:"zimbraPrefOfflineBackupAccount", dataType:ZmSetting.D_BOOLEAN, defaultValue:false, isGlobal:true}); 1111 this.registerSetting("OFFLINE_ZIMLET_SYNC_ACCOUNT_ID", {name:"zimbraPrefOfflineZimletSyncAccountId", type:ZmSetting.T_PREF, dataType:ZmSetting.D_STRING, isGlobal:true}); 1112 this.registerSetting("OFFLINE_WEBAPP_URI", {name:"offlineWebappUri", type:ZmSetting.T_PREF, dataType:ZmSetting.D_STRING}); 1113 1114 // reset the help URI to zimbra.com for offline 1115 this.registerSetting("HELP_URI", {type:ZmSetting.T_CONFIG, defaultValue:"https://www.zimbra.com/desktop7/"}); 1116 // // make default false for DUMPSTER_ENABLED. shouldn't be necessary since GetInfoResponse includes zimbraDumpsterEnabled:"FALSE", but can't find why settings is not read correctly 1117 this.registerSetting("DUMPSTER_ENABLED", {name:"zimbraDumpsterEnabled", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:false}); 1118 this.registerSetting("OFFLINE_UPDATE_NOTIFY", {name:"zimbraPrefOfflineUpdateChannel", type: ZmSetting.T_PREF, dataType: ZmSetting.D_STRING, isGlobal:true}); 1119 }; 1120 1121 /** 1122 * @private 1123 */ 1124 ZmSettings.prototype._changeListener = 1125 function(ev) { 1126 1127 if (ev.type !== ZmEvent.S_SETTING) { 1128 return; 1129 } 1130 1131 var id = ev.source.id, 1132 value = ev.source.getValue(); 1133 1134 if (id === ZmSetting.QUOTA_USED) { 1135 appCtxt.getAppController().setUserInfo(); 1136 } 1137 else if (id === ZmSetting.POLLING_INTERVAL) { 1138 appCtxt.getAppController().setPollInterval(); 1139 } 1140 else if (id === ZmSetting.SKIN_NAME) { 1141 this._showConfirmDialog(ZmMsg.skinChangeRestart, this._refreshBrowserCallback.bind(this)); 1142 } 1143 else if (id === ZmSetting.SHOW_SELECTION_CHECKBOX) { 1144 this._showConfirmDialog(value ? ZmMsg.checkboxChangeRestartShow : ZmMsg.checkboxChangeRestartHide, this._refreshBrowserCallback.bind(this)); 1145 } 1146 else if (id === ZmSetting.FONT_NAME || id === ZmSetting.FONT_SIZE) { 1147 this._showConfirmDialog(ZmMsg.fontChangeRestart, this._refreshBrowserCallback.bind(this)); 1148 } 1149 else if (id === ZmSetting.LOCALE_NAME) { 1150 // bug: 29786 1151 if (appCtxt.isOffline && AjxEnv.isPrism) { 1152 try { 1153 netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect'); 1154 var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch); 1155 if (prefs) { 1156 var newLocale = appCtxt.get(ZmSetting.LOCALE_NAME).replace("_", "-"); 1157 prefs.setCharPref("general.useragent.locale", newLocale); 1158 prefs.setCharPref("intl.accept_languages", newLocale); 1159 } 1160 } catch (ex) { 1161 // do nothing for now 1162 } 1163 } 1164 this._showConfirmDialog(ZmMsg.localeChangeRestart, this._refreshBrowserCallback.bind(this)); 1165 } 1166 else if (id === ZmSetting.CHILD_ACCTS_VISIBLE) { 1167 this._showConfirmDialog(ZmMsg.accountChangeRestart, this._refreshBrowserCallback.bind(this)); 1168 } 1169 else if (appCtxt.isOffline && id === ZmSetting.OFFLINE_IS_MAILTO_HANDLER) { 1170 appCtxt.getAppController().registerMailtoHandler(true, ev.source.getValue()); 1171 } 1172 else if (appCtxt.isOffline && id === ZmSetting.OFFLINE_UPDATE_NOTIFY) { 1173 appCtxt.getAppController()._offlineUpdateChannelPref(ev.source.getValue()); 1174 } 1175 else if (id === ZmSetting.CHAT_ENABLED || id === ZmSetting.CHAT_PLAY_SOUND || (id === ZmSetting.CHAT_PLAY_SOUND && id === ZmSetting.CHAT_ENABLED)) { 1176 this._showConfirmDialog(ZmMsg.chatFeatureChangeRestart, this._refreshBrowserCallback.bind(this)); 1177 } 1178 }; 1179 1180 // Shows a confirm dialog that asks the user if they want to reload ZCS to show the change they just made 1181 ZmSettings.prototype._showConfirmDialog = function(text, callback, style) { 1182 1183 var confirmDialog = appCtxt.getYesNoMsgDialog(); 1184 confirmDialog.reset(); 1185 confirmDialog.registerCallback(DwtDialog.YES_BUTTON, callback); 1186 confirmDialog.setMessage(text, style || DwtMessageDialog.WARNING_STYLE); 1187 confirmDialog.popup(); 1188 }; 1189 1190 ZmSettings.prototype._implicitChangeListener = 1191 function(ev) { 1192 if (!appCtxt.get(ZmSetting.OPTIONS_ENABLED)) { 1193 return; 1194 } 1195 if (ev.type != ZmEvent.S_SETTING) { return; } 1196 var id = ev.source.id; 1197 var setting = this.getSetting(id); 1198 if (id == ZmSetting.FOLDERS_EXPANDED && window.duringExpandAll) { 1199 if (!window.afterExpandAllCallback) { 1200 window.afterExpandAllCallback = this.save.bind(this, [setting], null, null, appCtxt.getActiveAccount(), true); 1201 } 1202 return; 1203 } 1204 if (ZmSetting.IS_IMPLICIT[id] && setting) { 1205 if (id === ZmSetting.WEBCLIENT_OFFLINE_BROWSER_KEY) { 1206 var callback = this._offlineSettingsSaveCallback.bind(this, setting); 1207 } 1208 else { 1209 //Once implicit preference is saved, reload the application cache to get the latest changes 1210 var callback = appCtxt.reloadAppCache.bind(appCtxt, false); 1211 } 1212 this.save([setting], callback, null, appCtxt.getActiveAccount(), true); 1213 } 1214 }; 1215 1216 /** 1217 * @private 1218 */ 1219 ZmSettings.prototype._refreshBrowserCallback = 1220 function(args) { 1221 appCtxt.getYesNoMsgDialog().popdown(); 1222 window.onbeforeunload = ZmZimbraMail.getConfirmExitMethod(); 1223 var url = AjxUtil.formatUrl({qsArgs : args}); 1224 window.location.replace(url); 1225 }; 1226 1227 // Adds/replaces a CSS rule that comprises user font prefs 1228 ZmSettings.prototype._updateUserFontPrefsRule = 1229 function() { 1230 if (this._userFontPrefsRuleIndex != null) { 1231 DwtCssStyle.removeRule(document.styleSheets[0], this._userFontPrefsRuleIndex); 1232 } 1233 var selector = "." + ZmSetting.USER_FONT_CLASS; 1234 var declaration = "font-family:" + appCtxt.get(ZmSetting.COMPOSE_INIT_FONT_FAMILY) + ";" + 1235 "font-size:" + appCtxt.get(ZmSetting.COMPOSE_INIT_FONT_SIZE) + ";" + 1236 "color:" + appCtxt.get(ZmSetting.COMPOSE_INIT_FONT_COLOR) + ";"; 1237 this._userFontPrefsRuleIndex = DwtCssStyle.addRule(document.styleSheets[0], selector, declaration); 1238 }; 1239 1240 // Check license to see if voice feature is allowed 1241 // License block format: 1242 // 1243 // <license status="OK"> 1244 // <attr name="SMIME">FALSE</attr> 1245 // <attr name="VOICE">TRUE</attr> 1246 // </license> 1247 1248 ZmSettings.prototype._hasVoiceFeature = function() { 1249 1250 var info = this.getInfoResponse; 1251 var license = info && info.license; 1252 var status = license && license.status; 1253 1254 if (!license || !license.attr) { 1255 return false; 1256 } 1257 1258 // License not installed or not activated or expired 1259 if (ZmSetting.LICENSE_MSG[status]) { 1260 return false; 1261 } 1262 1263 // check for VOICE license attribute 1264 1265 for (var i = 0; license && i < license.attr.length; i++) { 1266 var attr = license.attr[i]; 1267 1268 if (attr.name == "VOICE") { 1269 return attr._content == "TRUE"; 1270 } 1271 } 1272 1273 return false; 1274 }; 1275 1276 /** 1277 * @private 1278 */ 1279 ZmSettings.prototype._offlineSettingsSaveCallback = 1280 function(setting) { 1281 var offlineBrowserKey = setting.getValue(); 1282 var localOfflineBrowserKey = localStorage.getItem(ZmSetting.WEBCLIENT_OFFLINE_BROWSER_KEY); 1283 if (offlineBrowserKey && offlineBrowserKey.indexOf(localOfflineBrowserKey) !== -1) { 1284 this._showConfirmDialog(ZmMsg.offlineChangeRestart, this._refreshBrowserCallback.bind(this)); 1285 } 1286 else { 1287 ZmOffline.deleteOfflineData(); 1288 appCtxt.initWebOffline();// To reset the property isWebClientOfflineSupported 1289 //delete outbox folder 1290 var outboxFolder = appCtxt.getById(ZmFolder.ID_OUTBOX); 1291 if (outboxFolder) { 1292 outboxFolder.notifyDelete(); 1293 } 1294 } 1295 //Always reload appcache whenever offline setting is enabled/disabled. Appcache will be updated/emptied depending upon the setting. 1296 appCtxt.reloadAppCache(true); 1297 }; 1298