summaryrefslogtreecommitdiff
path: root/frontend/beta/js/Clipperz/PM/Components/OTP/MainComponent.js
Unidiff
Diffstat (limited to 'frontend/beta/js/Clipperz/PM/Components/OTP/MainComponent.js') (more/less context) (ignore whitespace changes)
-rw-r--r--frontend/beta/js/Clipperz/PM/Components/OTP/MainComponent.js490
1 files changed, 490 insertions, 0 deletions
diff --git a/frontend/beta/js/Clipperz/PM/Components/OTP/MainComponent.js b/frontend/beta/js/Clipperz/PM/Components/OTP/MainComponent.js
new file mode 100644
index 0000000..9d191f6
--- a/dev/null
+++ b/frontend/beta/js/Clipperz/PM/Components/OTP/MainComponent.js
@@ -0,0 +1,490 @@
1/*
2
3Copyright 2008-2011 Clipperz Srl
4
5This file is part of Clipperz's Javascript Crypto Library.
6Javascript Crypto Library provides web developers with an extensive
7and efficient set of cryptographic functions. The library aims to
8obtain maximum execution speed while preserving modularity and
9reusability.
10For further information about its features and functionalities please
11refer to http://www.clipperz.com
12
13* Javascript Crypto Library is free software: you can redistribute
14 it and/or modify it under the terms of the GNU Affero General Public
15 License as published by the Free Software Foundation, either version
16 3 of the License, or (at your option) any later version.
17
18* Javascript Crypto Library is distributed in the hope that it will
19 be useful, but WITHOUT ANY WARRANTY; without even the implied
20 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
21 See the GNU Affero General Public License for more details.
22
23* You should have received a copy of the GNU Affero General Public
24 License along with Javascript Crypto Library. If not, see
25 <http://www.gnu.org/licenses/>.
26
27*/
28
29if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
30if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; }
31if (typeof(Clipperz.PM.Components) == 'undefined') { Clipperz.PM.Components = {}; }
32if (typeof(Clipperz.PM.Components.OTP) == 'undefined') { Clipperz.PM.Components.OTP = {}; }
33
34//#############################################################################
35
36Clipperz.PM.Components.OTP.MainComponent = function(anElement, args) {
37 args = args || {};
38
39//MochiKit.Logging.logDebug("new OTP.MainComponent");
40 Clipperz.PM.Components.OTP.MainComponent.superclass.constructor.call(this, anElement, args);
41
42 this._user = args.user;
43 this._shouldRender = true;
44
45 this._deleteButton = null;
46 this._printButton = null;
47
48 Clipperz.NotificationCenter.register(null, 'tabSelected', this, 'tabSelectedHandler');
49 //Clipperz.NotificationCenter.register(null, 'oneTimePasswordAdded', this, 'render');
50
51 return this;
52}
53
54//=============================================================================
55
56YAHOO.extendX(Clipperz.PM.Components.OTP.MainComponent, Clipperz.PM.Components.BaseComponent, {
57
58 'toString': function() {
59 return "Clipperz.PM.Components.OTP.MainComponent component";
60 },
61
62 //-------------------------------------------------------------------------
63
64 'render': function() {
65//MochiKit.Logging.logDebug("### OTP.MainComponent.render");
66 Clipperz.NotificationCenter.unregister(this);
67 MochiKit.Signal.disconnectAllTo(this);
68
69 if (Clipperz.PM.Proxy.defaultProxy.isReadOnly()) {
70 this.element().update("");
71 this.domHelper().append(this.element(), {tag:'div', cls:'oneTimePasswordReadOnlyMessage', htmlString:Clipperz.PM.Strings['oneTimePasswordReadOnlyMessage']});
72 } else {
73 var deferredResult;
74
75 deferredResult = new MochiKit.Async.Deferred();
76
77//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("OTP.MainComponent.render - 1: " + res); return res;});
78 deferredResult.addCallback(MochiKit.Base.bind(function() {
79 this.element().update("");
80 Clipperz.YUI.DomHelper.append(this.element(), {tag:'div', htmlString:Clipperz.PM.Strings['oneTimePasswordLoadingMessage']});
81 }, this));
82//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("OTP.MainComponent.render - 2: " + res); return res;});
83 deferredResult.addCallback(MochiKit.Base.method(this.user(), 'loadOneTimePasswords'));
84//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("OTP.MainComponent.render - 3: " + res); return res;});
85//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("OTP.MainComponent.render - 3.1: " + Clipperz.Base.serializeJSON(res.serializedData())); return res;});
86 deferredResult.addCallback(MochiKit.Base.bind(function(aResult) {
87 vartbodyElement;
88 varoneTimePasswordReferenceKeys;
89 var imageExtension;
90 var isThereAnyActiveOneTimePassword;
91
92 isThereAnyActiveOneTimePassword = false;
93
94 this.element().update("");
95 Clipperz.YUI.DomHelper.append(this.element(), {tag:'div', id:'oneTimePasswordList', children:[
96 {tag:'div', id:'oneTimePasswords_header', children:[
97 {tag:'table', width:'100%', children:[
98 {tag:'tbody', children:[
99 {tag:'tr', children:[
100 {tag:'td', width:'10%', children:[
101 {tag:'div', id:this.getId('createNewOneTimePasswordButton')}
102 ]},
103 {tag:'td', width:'40%', children:[
104 {tag:'div', id:this.getId('deleteSelectedOneTimePasswordButton')}
105 ]},
106 {tag:'td', width:'50%', align:'right', children:[
107 {tag:'div', id:this.getId('printOneTimePasswordButton')}
108 ]}
109 ]}
110 ]}
111 ]},
112 {tag:'div', children:[
113 {tag:'ul', children:[
114 {tag:'li', children:[
115 {tag:'span', htmlString:Clipperz.PM.Strings['oneTimePasswordSelectionLink_selectLabel']}
116 ]},
117 {tag:'li', children:[
118 {tag:'a', href:'#', id:this.getId('selectAllOneTimePasswords_link'), htmlString:Clipperz.PM.Strings['oneTimePasswordSelectionLink_all']}
119 ]},
120 {tag:'li', children:[
121 {tag:'a', href:'#', id:this.getId('selectNoneOneTimePasswords_link'), htmlString:Clipperz.PM.Strings['oneTimePasswordSelectionLink_none']}
122 ]},
123 {tag:'li', children:[
124 {tag:'a', href:'#', id:this.getId('selectUsedOneTimePasswords_link'), htmlString:Clipperz.PM.Strings['oneTimePasswordSelectionLink_used']}
125 ]},
126 {tag:'li', children:[
127 {tag:'a', href:'#', id:this.getId('selectUnusedOneTimePasswords_link'), htmlString:Clipperz.PM.Strings['oneTimePasswordSelectionLink_unused']}
128 ]}
129 ]}
130 ]}
131 ]},
132 {tag:'form', id:this.getId('oneTimePasswords_form'), children:[
133 {tag:'table', cls:'oneTimePassword', cellspacing:'0', cellpadding:'2', children:[
134 {tag:'tbody', id:this.getId('oneTimePasswords_tbody'), children:[
135 ]}
136 ]}
137 ]}
138 ]});
139
140 imageExtension = (Clipperz_IEisBroken == true) ? 'gif': 'png';
141
142 tbodyElement = this.getElement('oneTimePasswords_tbody');
143 oneTimePasswordReferenceKeys = MochiKit.Base.keys(this.user().oneTimePasswordManager().oneTimePasswords()).reverse();
144 c = oneTimePasswordReferenceKeys.length;
145 if (c>0) {
146 for (i=0; i<c; i++) {
147 var otpReference;
148 var currentOTP;
149 var loginSessionInfoConfig;
150
151 imageExtension = (Clipperz_IEisBroken == true) ? 'gif': 'png';
152
153 otpReference = oneTimePasswordReferenceKeys[i];
154 currentOTP = this.user().oneTimePasswordManager().oneTimePasswords()[otpReference];
155
156 switch (currentOTP.status()) {
157 case 'USED':
158 var loginSessionInfo;
159
160 loginSessionInfo = currentOTP.connectionInfo();
161 try {
162 var ip;
163
164 ip = (currentOTP.connectionInfo()['ip'].match(/^\d{1,3}(.\d{1,3}){3}$/)) ? currentOTP.connectionInfo()['ip'] : Clipperz.PM.Strings['unknown_ip'];
165
166 loginSessionInfoConfig = [
167 {tag:'div', cls:'oneTimePassword_usageDateDescription', children:[
168 {tag:'span', cls:'value', html:Clipperz.PM.Date.getElapsedTimeDescription(currentOTP.usageDate())}
169 ]},
170 {tag:'div', cls:'oneTimePassword_usageDetails', children:[
171 {tag:'img', cls:'flag', title:Clipperz.PM.Strings['countries'][ loginSessionInfo['country']], src:Clipperz.PM.Strings['icons_baseUrl'] + "/flags/" + loginSessionInfo['country'].toLowerCase() + "." + imageExtension, width:'32', height:'32'},
172 {tag:'img', cls:'browser', title:Clipperz.PM.Strings['browsers'][ loginSessionInfo['browser']], src:Clipperz.PM.Strings['icons_baseUrl'] + "/browsers/" + loginSessionInfo['browser'].toLowerCase() + "." + imageExtension, width:'32', height:'32'},
173 {tag:'img', cls:'operatingSystem', title:Clipperz.PM.Strings['operatingSystems'][loginSessionInfo['operatingSystem']], src:Clipperz.PM.Strings['icons_baseUrl'] + "/operatingSystems/" + loginSessionInfo['operatingSystem'].toLowerCase() + "." + imageExtension, width:'32', height:'32'}
174 ]},
175 {tag:'div', cls:'oneTimePassword_usageDate', html:Clipperz.PM.Date.formatDateWithTemplate(currentOTP.usageDate(), Clipperz.PM.Strings['fullDate_format'])},
176 {tag:'div', cls:'oneTimePassword_IP', children:[
177 {tag:'span', cls:'oneTimePassword_IPLabel', htmlString:Clipperz.PM.Strings['loginHistoryIPLabel']},
178 {tag:'span', cls:'oneTimePassword_IPValue', html:ip}
179 ]}
180 ];
181 } catch(exception) {
182 MochiKit.Logging.logWarning("an error occured while showing the One Time Password session details");
183 loginSessionInfoConfig = [];
184 }
185 break;
186 case 'DISABLED':
187 loginSessionInfoConfig = [
188 {tag:'span', cls:'disabledOneTimePassword', htmlString:Clipperz.PM.Strings['disabledOneTimePassword_warning']}
189 ];
190 break;
191 case 'ACTIVE':
192 default:
193 loginSessionInfoConfig = [];
194 break;
195 }
196
197
198 if (currentOTP.isExpired() == false) {
199 isThereAnyActiveOneTimePassword = true;
200 };
201
202
203 this.domHelper().append(tbodyElement, {tag:'tr', cls:(currentOTP.isExpired() ? 'oneTimePassword_used': 'oneTimePassword_new'), children:[
204 {tag:'td', valign:'top', children:[
205 {tag:'input', type:'checkbox', cls:'otpCheckbox', name:currentOTP.reference()}
206 ]},
207 {tag:'td', valign:'top', children:[
208 {tag:'span', cls:'oneTimePassword_value', html:currentOTP.password()}
209 ]},
210 {tag:'td', valign:'top', children:[
211 {tag:'div', cls:'oneTimePassword_usageStats', children:loginSessionInfoConfig}
212 ]}
213 ]});
214 }
215 } else {
216 this.domHelper().append(tbodyElement, {tag:'tr', children:[
217 {tag:'td', children:[
218 {tag:'div', cls:'oneTimePassword_noPasswordPresent', htmlString:Clipperz.PM.Strings['oneTimePasswordNoPasswordAvailable']}
219 ]}
220 ]});
221 }
222
223 new YAHOO.ext.Button(this.getDom('createNewOneTimePasswordButton'), {text:Clipperz.PM.Strings['createNewOTPButtonLabel'], handler:this.createNewOneTimePassword, scope:this});
224 this.setDeleteButton(new YAHOO.ext.Button(this.getDom('deleteSelectedOneTimePasswordButton'), {text:Clipperz.PM.Strings['deleteOTPButtonLabel'], handler:this.deleteSelectedOneTimePasswords, scope:this}));
225 this.setPrintButton(new YAHOO.ext.Button(this.getDom('printOneTimePasswordButton'), {text:Clipperz.PM.Strings['printOTPButtonLabel'], handler:this.printOneTimePasswords, scope:this}));
226
227 MochiKit.Signal.connect(this.getId('selectAllOneTimePasswords_link'),'onclick', this, 'selectAllOneTimePasswords');
228 MochiKit.Signal.connect(this.getId('selectNoneOneTimePasswords_link'),'onclick', this, 'selectNoneOneTimePasswords');
229 MochiKit.Signal.connect(this.getId('selectUsedOneTimePasswords_link'),'onclick', this, 'selectUsedOneTimePasswords');
230 MochiKit.Signal.connect(this.getId('selectUnusedOneTimePasswords_link'),'onclick', this, 'selectUnusedOneTimePasswords');
231
232 MochiKit.Base.map(MochiKit.Base.bind(function(aCheckbox) {
233 MochiKit.Signal.connect(aCheckbox, 'onclick', this, 'handleCheckboxClick');
234 }, this), this.oneTimePasswordCheckboxes());
235
236 this.updateDeleteButtonStatus();
237
238 if (isThereAnyActiveOneTimePassword == true) {
239 this.printButton().enable();
240 } else {
241 this.printButton().disable();
242 }
243
244 // Clipperz.NotificationCenter.register(null, 'oneTimePasswordAdded', this, 'render');
245 Clipperz.NotificationCenter.register(null, 'oneTimePassword_saveChanges_done', this, 'render');
246
247 }, this));
248//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("OTP.MainComponent.render - 4: " + res); return res;});
249
250 deferredResult.callback();
251 }
252 },
253
254 //-------------------------------------------------------------------------
255
256 'printOneTimePasswords': function() {
257 var newWindow;
258 var activeOneTimePasswords;
259
260//MochiKit.Logging.logDebug(">>> printAllData");
261 newWindow = window.open("", "");
262 newWindow.document.write(
263"<html>" +
264"<header>" +
265 "<title>Clipperz One Time Password</title>" +
266"<style>" +
267"div.oneTimePassword_print h2 {" +
268 "font-family: monospace;" +
269 "font-weight: normal;" +
270 "padding: 10px 20px;" +
271"}" +
272"</style>" +
273"" +
274"<!--[if IE]>" +
275"<style>" +
276"</style>" +
277"<![endif]-->" +
278"" +
279"</header>" +
280"<body>" +
281"</body>" +
282"</html>"
283 );
284
285 activeOneTimePasswords = MochiKit.Base.filter(function(aOneTimePassword) {return (aOneTimePassword.isExpired() == false)}, MochiKit.Base.values(this.user().oneTimePasswordManager().oneTimePasswords()).reverse());
286
287 MochiKit.Iter.forEach(activeOneTimePasswords, MochiKit.Base.partial(function(aWindow, aOneTimePassword) {
288 MochiKit.DOM.withWindow(aWindow, MochiKit.Base.partial(function(aOneTimePassword) {
289 var newBlock;
290
291 newBlock = MochiKit.DOM.DIV({'class': 'oneTimePassword_print'},
292 MochiKit.DOM.H2(null, aOneTimePassword.password())
293 );
294 MochiKit.DOM.appendChildNodes(MochiKit.DOM.currentDocument().body, newBlock);
295
296 }, aOneTimePassword));
297 }, newWindow));
298 },
299
300 //-------------------------------------------------------------------------
301
302 'generateRandomBase32OTPValue': function(aButton) {
303 var randomValue;
304 varresult;
305
306 randomValue = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(160/8);
307 result = randomValue.toBase32String();
308 result = result.replace(/.{4}\B/g, '$&' + ' ');
309 result = result.replace(/(.{4} ){2}/g, '$&' + '- ');
310
311 return result;
312 },
313
314 //-------------------------------------------------------------------------
315
316 'createNewOneTimePassword': function() {
317 var newOneTimePassword;
318 var password;
319
320 password = this.generateRandomBase32OTPValue();
321 newOneTimePassword = new Clipperz.PM.DataModel.OneTimePassword({
322 user:this.user(),
323 password:password
324 });
325 this.user().oneTimePasswordManager().addOneTimePassword(newOneTimePassword);
326 Clipperz.PM.Components.MessageBox.showProgressPanel(MochiKit.Base.method(newOneTimePassword, 'saveChanges'), null, this.getDom('createNewOneTimePasswordButton'));
327 },
328
329 //-------------------------------------------------------------------------
330
331 'oneTimePasswordCheckboxes': function() {
332 return MochiKit.DOM.getElementsByTagAndClassName('input', 'otpCheckbox', this.getId('oneTimePasswords_tbody'));
333 },
334
335 'checkedOneTimePasswordCheckboxes': function() {
336 return MochiKit.Base.filter(function(aCheckbox) {return (aCheckbox.checked == true)}, this.oneTimePasswordCheckboxes());
337 },
338
339 //-------------------------------------------------------------------------
340
341 'selectAllOneTimePasswords': function(anEvent) {
342 var checkboxes;
343 var i,c;
344
345 anEvent.stop();
346 checkboxes = this.oneTimePasswordCheckboxes();
347 c = checkboxes.length;
348 for (i=0; i<c; i++) {
349 checkboxes[i].checked = true;
350 }
351
352 this.updateDeleteButtonStatus();
353 },
354
355 'selectNoneOneTimePasswords': function(anEvent) {
356 var checkboxes;
357 var i,c;
358
359 anEvent.stop();
360 checkboxes = this.oneTimePasswordCheckboxes();
361 c = checkboxes.length;
362 for (i=0; i<c; i++) {
363 checkboxes[i].checked = false;
364 }
365
366 this.updateDeleteButtonStatus();
367 },
368
369 'selectUsedOneTimePasswords': function(anEvent) {
370 var checkboxes;
371 var oneTimePasswordManager;
372 var i,c;
373
374 anEvent.stop();
375 oneTimePasswordManager = this.user().oneTimePasswordManager();
376 checkboxes = this.oneTimePasswordCheckboxes();
377 c = checkboxes.length;
378 for (i=0; i<c; i++) {
379 var matchingOneTimePassword;
380
381 matchingOneTimePassword = oneTimePasswordManager.oneTimePasswordWithReference(checkboxes[i].name);
382 checkboxes[i].checked = matchingOneTimePassword.isExpired();
383 }
384
385 this.updateDeleteButtonStatus();
386 },
387
388 'selectUnusedOneTimePasswords': function(anEvent) {
389 var checkboxes;
390 var oneTimePasswordManager;
391 var i,c;
392
393 anEvent.stop();
394 oneTimePasswordManager = this.user().oneTimePasswordManager();
395 checkboxes = this.oneTimePasswordCheckboxes();
396 c = checkboxes.length;
397 for (i=0; i<c; i++) {
398 var matchingOneTimePassword;
399
400 matchingOneTimePassword = oneTimePasswordManager.oneTimePasswordWithReference(checkboxes[i].name);
401 checkboxes[i].checked = !matchingOneTimePassword.isExpired();
402 }
403
404 this.updateDeleteButtonStatus();
405 },
406
407 //-------------------------------------------------------------------------
408
409 'handleCheckboxClick': function(anEvent) {
410 this.updateDeleteButtonStatus();
411 },
412
413 //-------------------------------------------------------------------------
414
415 'deleteSelectedOneTimePasswords': function() {
416 var deferredResult;
417 var otpToDelete;
418 var i,c;
419
420 otpToDelete = this.checkedOneTimePasswordCheckboxes();
421 c = otpToDelete.length;
422 for (i=0; i<c; i++) {
423//MochiKit.Logging.logDebug("otp to delete: " + otpToDelete[i].name);
424 this.user().oneTimePasswordManager().deleteOneTimePasswordWithReference(otpToDelete[i].name);
425 };
426
427 deferredResult = new MochiKit.Async.Deferred();
428//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("ActiveOTPPanel.deleteSelectedOneTimePasswords - 0: " + res); return res;});
429 deferredResult.addCallback(Clipperz.PM.Components.MessageBox.showProgressPanel, MochiKit.Base.method(this.user().oneTimePasswordManager(), 'saveChanges'), null, null);
430//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("ActiveOTPPanel.deleteSelectedOneTimePasswords - 1: " + res); return res;});
431 deferredResult.addCallback(MochiKit.Base.method(this, 'render'));
432//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("ActiveOTPPanel.deleteSelectedOneTimePasswords - 2: " + res); return res;});
433 deferredResult.callback();
434 },
435
436 //-------------------------------------------------------------------------
437
438 'user': function() {
439 return this._user;
440 },
441
442 //-------------------------------------------------------------------------
443
444 'shouldRender': function() {
445 return this._shouldRender;
446 },
447
448 'setShouldRender': function(aValue) {
449 this._shouldRender = aValue;
450 },
451
452 'tabSelectedHandler': function(anEvent) {
453 if ((this.shouldRender()) && (anEvent.source().selectedTab() == 'manageOTPTab')) {
454 this.render();
455 this.setShouldRender(false);
456 }
457 },
458
459 //-------------------------------------------------------------------------
460
461 'deleteButton': function() {
462 return this._deleteButton;
463 },
464
465 'setDeleteButton': function(aValue) {
466 this._deleteButton = aValue;
467 },
468
469 'updateDeleteButtonStatus': function() {
470 if (this.checkedOneTimePasswordCheckboxes().length > 0) {
471 this.deleteButton().enable();
472 } else {
473 this.deleteButton().disable();
474 }
475 },
476
477 //-------------------------------------------------------------------------
478
479 'printButton': function() {
480 return this._printButton;
481 },
482
483 'setPrintButton': function(aValue) {
484 this._printButton = aValue;
485 },
486
487 //-------------------------------------------------------------------------
488 __syntaxFix__: "syntax fix"
489});
490