1 /*
  2  * ***** BEGIN LICENSE BLOCK *****
  3  *
  4  * Zimbra Collaboration Suite Web Client
  5  * Copyright (C) 2015, 2016 Synacor, Inc.
  6  *
  7  * The contents of this file are subject to the Common Public Attribution License Version 1.0 (the "License");
  8  * you may not use this file except in compliance with the License.
  9  * You may obtain a copy of the License at: https://www.zimbra.com/license
 10  * The License is based on the Mozilla Public License Version 1.1 but Sections 14 and 15
 11  * have been added to cover use of software over a computer network and provide for limited attribution
 12  * for the Original Developer. In addition, Exhibit A has been modified to be consistent with Exhibit B.
 13  *
 14  * Software distributed under the License is distributed on an "AS IS" basis,
 15  * WITHOUT WARRANTY OF ANY KIND, either express or implied.
 16  * See the License for the specific language governing rights and limitations under the License.
 17  * The Original Code is Zimbra Open Source Web Client.
 18  * The Initial Developer of the Original Code is Zimbra, Inc.  All rights to the Original Code were
 19  * transferred by Zimbra, Inc. to Synacor, Inc. on September 14, 2015.
 20  *
 21  * All portions of the code are Copyright (C) 2015, 2016 Synacor, Inc. All Rights Reserved.
 22  *
 23  * ***** END LICENSE BLOCK *****
 24  */
 25 /**
 26  * Created by administrator on 29/05/15.
 27  */
 28 
 29 /**
 30  * Creates a application code dialog.
 31  * @constructor
 32  * @class
 33  * @author  Hem Aravind
 34  *
 35  * @extends	DwtDialog
 36  */
 37 ZmApplicationCodeDialog = function(appPasscodeCallback) {
 38 	var nextButton = new DwtDialog_ButtonDescriptor(ZmApplicationCodeDialog.NEXT_BUTTON, ZmMsg.next, DwtDialog.ALIGN_RIGHT, this._nextButtonListener.bind(this));
 39 	var cancelButton = new DwtDialog_ButtonDescriptor(ZmApplicationCodeDialog.CANCEL_BUTTON, ZmMsg.cancel, DwtDialog.ALIGN_RIGHT, this._cancelButtonListener.bind(this));
 40 	var params = {
 41 		parent : appCtxt.getShell(),
 42 		title : ZmMsg.twoStepAuthAddAppCode,
 43 		standardButtons : [DwtDialog.NO_BUTTONS],
 44 		extraButtons : [nextButton, cancelButton]
 45 	};
 46 	DwtDialog.call(this, params);
 47 	this.setContent(this._contentHtml());
 48 	this._createControls();
 49 	this._setAllowSelection();
 50 	this.appPasscodeCallback = appPasscodeCallback;
 51 };
 52 
 53 ZmApplicationCodeDialog.prototype = new DwtDialog;
 54 ZmApplicationCodeDialog.prototype.constructor = ZmApplicationCodeDialog;
 55 
 56 ZmApplicationCodeDialog.NEXT_BUTTON = ++DwtDialog.LAST_BUTTON;
 57 ZmApplicationCodeDialog.CANCEL_BUTTON = ++DwtDialog.LAST_BUTTON;
 58 
 59 ZmApplicationCodeDialog.prototype._nextButtonListener =
 60 function() {
 61 	this.setButtonEnabled(ZmApplicationCodeDialog.NEXT_BUTTON, false);
 62 	var appName = this._appNameInput.value;
 63 	var callback = this._handleAppSpecificPassword.bind(this, appName);
 64 	var errorCallback = this._handleAppSpecificPasswordError.bind(this, appName);
 65 	this._createAppSpecificPassword(appName, callback, errorCallback);
 66 };
 67 
 68 ZmApplicationCodeDialog.prototype._cancelButtonListener =
 69 function() {
 70 	this.popdown();
 71 };
 72 
 73 ZmApplicationCodeDialog.prototype._contentHtml =
 74 function() {
 75 	var id = this._htmlElId;
 76 	this._appName = id + "_app_name";
 77 	this._appPassCode = id + "_app_passcode";
 78 	this._appPassCodeValue = id + "_app_passcode_value";
 79 	return AjxTemplate.expand("prefs.Pages#AddApplicationCode", {id : id});
 80 };
 81 
 82 ZmApplicationCodeDialog.prototype._createControls =
 83 function() {
 84 	var id = this._htmlElId;
 85 	this.setButtonEnabled(ZmApplicationCodeDialog.NEXT_BUTTON, false);
 86 	this._appNameInput = Dwt.getElement(id + "_app_name_input");
 87 	Dwt.setHandler(this._appNameInput, DwtEvent.ONKEYUP, this._handleKeyUp.bind(this));
 88 	this._appNameError = Dwt.getElement(id + "_app_name_error");
 89 };
 90 
 91 ZmApplicationCodeDialog.prototype._handleKeyUp =
 92 function(ev) {
 93 	var value = ev && ev.target && ev.target.value && ev.target.value.length;
 94 	this.setButtonEnabled(ZmApplicationCodeDialog.NEXT_BUTTON, !!value);
 95 };
 96 
 97 /**
 98  ** an array of input fields that will be cleaned up between instances of the dialog being popped up and down
 99  *
100  * @return An array of the input fields to be reset
101  */
102 ZmApplicationCodeDialog.prototype._getInputFields =
103 function() {
104 	return [this._appNameInput];
105 };
106 
107 /**
108  * Pops-up the dialog.
109  */
110 ZmApplicationCodeDialog.prototype.popup =
111 function() {
112 	this.reset();
113 	DwtDialog.prototype.popup.call(this);
114 	this._appNameInput.focus();
115 };
116 
117 /**
118  * Resets the dialog back to its original state.
119  */
120 ZmApplicationCodeDialog.prototype.reset =
121 function() {
122 	Dwt.show(this._appName);
123 	Dwt.setInnerHtml(this._appNameError, "");
124 	Dwt.hide(this._appPassCode);
125 	DwtDialog.prototype.reset.call(this);
126 	this.setButtonEnabled(ZmApplicationCodeDialog.NEXT_BUTTON, false);
127 	this.setButtonVisible(ZmApplicationCodeDialog.NEXT_BUTTON, true);
128 	this.getButton(ZmApplicationCodeDialog.CANCEL_BUTTON).setText(ZmMsg.cancel);
129 };
130 
131 ZmApplicationCodeDialog.prototype._createAppSpecificPassword =
132 function(appName, callback, errorCallback) {
133 	var jsonObj = {CreateAppSpecificPasswordRequest : {_jsns:"urn:zimbraAccount", appName:{_content : appName}}};
134 	appCtxt.getAppController().sendRequest({jsonObj:jsonObj, asyncMode:true, callback:callback, errorCallback:errorCallback});
135 };
136 
137 ZmApplicationCodeDialog.prototype._handleAppSpecificPassword =
138 function(appName, result) {
139 	var response = result.getResponse();
140 	if (!response || !response.CreateAppSpecificPasswordResponse) {
141 		this._handleAppSpecificPasswordError(appName);
142 		return;
143 	}
144 	Dwt.hide(this._appName);
145 	Dwt.setInnerHtml(Dwt.getElement(this._appPassCodeValue), response.CreateAppSpecificPasswordResponse.pw);
146 	Dwt.show(this._appPassCode);
147 	this.setButtonVisible(ZmApplicationCodeDialog.NEXT_BUTTON, false);
148 	this.getButton(ZmApplicationCodeDialog.CANCEL_BUTTON).setText(ZmMsg.close);
149 	this.appPasscodeCallback && this.appPasscodeCallback();
150 };
151 
152 ZmApplicationCodeDialog.prototype._handleAppSpecificPasswordError =
153 function(appName, exception) {
154 	var errorMsg;
155 	if (exception) {
156 		if (exception.msg === "system failure: app-specific password already exists for the name " + appName) {
157 			errorMsg = ZmMsg.twoStepAuthAppNameError1;
158 		}
159 		else {
160 			errorMsg = exception.getErrorMsg();
161 		}
162 	}
163 	else {
164 		errorMsg = ZmMsg.twoStepAuthAppNameError2;
165 	}
166 	Dwt.setInnerHtml(this._appNameError, errorMsg);
167 	this._appNameInput.focus();
168 	this.setButtonEnabled(ZmApplicationCodeDialog.NEXT_BUTTON, true);
169 	return true;
170 };
171