summaryrefslogtreecommitdiff
path: root/frontend/beta/js/Clipperz/PM/DataModel
authorGiulio Cesare Solaroli <giulio.cesare@clipperz.com>2011-10-02 23:56:18 (UTC)
committer Giulio Cesare Solaroli <giulio.cesare@clipperz.com>2011-10-02 23:56:18 (UTC)
commitef68436ac04da078ffdcacd7e1f785473a303d45 (patch) (unidiff)
treec403752d66a2c4775f00affd4fa8431b29c5b68c /frontend/beta/js/Clipperz/PM/DataModel
parent597ecfbc0249d83e1b856cbd558340c01237a360 (diff)
downloadclipperz-ef68436ac04da078ffdcacd7e1f785473a303d45.zip
clipperz-ef68436ac04da078ffdcacd7e1f785473a303d45.tar.gz
clipperz-ef68436ac04da078ffdcacd7e1f785473a303d45.tar.bz2
First version of the newly restructured repository
Diffstat (limited to 'frontend/beta/js/Clipperz/PM/DataModel') (more/less context) (show whitespace changes)
-rw-r--r--frontend/beta/js/Clipperz/PM/DataModel/DirectLogin.js536
-rw-r--r--frontend/beta/js/Clipperz/PM/DataModel/DirectLoginBinding.js113
-rw-r--r--frontend/beta/js/Clipperz/PM/DataModel/DirectLoginInput.js229
-rw-r--r--frontend/beta/js/Clipperz/PM/DataModel/DirectLoginReference.js192
-rw-r--r--frontend/beta/js/Clipperz/PM/DataModel/Header.js751
-rw-r--r--frontend/beta/js/Clipperz/PM/DataModel/OneTimePassword.js333
-rw-r--r--frontend/beta/js/Clipperz/PM/DataModel/OneTimePasswordManager.js280
-rw-r--r--frontend/beta/js/Clipperz/PM/DataModel/Record.js759
-rw-r--r--frontend/beta/js/Clipperz/PM/DataModel/RecordField.js220
-rw-r--r--frontend/beta/js/Clipperz/PM/DataModel/RecordVersion.js535
-rw-r--r--frontend/beta/js/Clipperz/PM/DataModel/Statistics.js133
-rw-r--r--frontend/beta/js/Clipperz/PM/DataModel/User.js904
-rw-r--r--frontend/beta/js/Clipperz/PM/DataModel/UserPreferences.js197
13 files changed, 5182 insertions, 0 deletions
diff --git a/frontend/beta/js/Clipperz/PM/DataModel/DirectLogin.js b/frontend/beta/js/Clipperz/PM/DataModel/DirectLogin.js
new file mode 100644
index 0000000..3ebc208
--- a/dev/null
+++ b/frontend/beta/js/Clipperz/PM/DataModel/DirectLogin.js
@@ -0,0 +1,536 @@
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.DataModel) == 'undefined') { Clipperz.PM.DataModel = {}; }
32
33
34//#############################################################################
35
36Clipperz.PM.DataModel.DirectLogin = function(args) {
37//MochiKit.Logging.logDebug(">>> new Clipperz.PM.DataModel.DirectLogin");
38//console.log(">>> new Clipperz.PM.DataModel.DirectLogin - args: %o", args);
39//console.log("--- formData: %s", Clipperz.Base.serializeJSON(args.formData));
40 args = args || {};
41
42//MochiKit.Logging.logDebug("--- new Clipperz.PM.DataModel.DirectLogin - args: " + Clipperz.Base.serializeJSON(MochiKit.Base.keys(args)));
43 this._record = args.record || null;
44 this._label = args.label || "unnamed record"
45 this._reference = args.reference || Clipperz.PM.Crypto.randomKey();
46 this._favicon = args.favicon || null;
47 this._bookmarkletVersion = args.bookmarkletVersion || "0.1";
48
49 this._directLoginInputs = null;
50
51 this._formValues = args.formValues || {};
52 this.setFormData(args.formData || null);
53//console.log("=== formData: %o", this.formData());
54
55 if (args.legacyBindingData == null) {
56 this.setBindingData(args.bindingData || null);
57 } else {
58 this.setLegacyBindingData(args.legacyBindingData);
59 }
60
61 this._fixedFavicon = null;
62
63 //this._formValues = args.formValues || (this.hasValuesToSet() ? {} : null);
64//MochiKit.Logging.logDebug("<<< new Clipperz.PM.DataModel.DirectLogin");
65
66 return this;
67}
68
69Clipperz.PM.DataModel.DirectLogin.prototype = MochiKit.Base.update(null, {
70
71 'remove': function() {
72 this.record().removeDirectLogin(this);
73 },
74
75 //-------------------------------------------------------------------------
76
77 'record': function() {
78 return this._record;
79 },
80
81 //-------------------------------------------------------------------------
82
83 'user': function() {
84 return this.record().user();
85 },
86
87 //-------------------------------------------------------------------------
88
89 'reference': function() {
90 return this._reference;
91 },
92
93 //-------------------------------------------------------------------------
94
95 'label': function() {
96 return this._label;
97 },
98
99 'setLabel': function(aValue) {
100 this._label = aValue;
101 },
102
103 //-------------------------------------------------------------------------
104
105 'favicon': function() {
106 if (this._favicon == null) {
107 varactionUrl;
108 var hostname;
109
110 actionUrl = this.formData()['attributes']['action'];
111 hostname = actionUrl.replace(/^https?:\/\/([^\/]*)\/.*/, '$1');
112 this._favicon = "http://" + hostname + "/favicon.ico";
113 }
114
115 return this._favicon;
116 },
117
118 //-------------------------------------------------------------------------
119
120 'fixedFavicon': function() {
121 var result;
122
123 if (this._fixedFavicon == null) {
124 result = this.favicon();
125
126 if (Clipperz_IEisBroken) {
127 if (this.user().preferences().disableUnsecureFaviconLoadingForIE()) {
128 if (result.indexOf('https://') != 0) {
129 result = Clipperz.PM.Strings['defaultFaviconUrl_IE'];
130 this.setFixedFavicon(result);
131 }
132 }
133 }
134 } else {
135 result = this._fixedFavicon;
136 }
137
138 return result;
139 },
140
141 'setFixedFavicon': function(aValue) {
142 this._fixedFavicon = aValue;
143 },
144
145 //-------------------------------------------------------------------------
146
147 'bookmarkletVersion': function() {
148 return this._bookmarkletVersion;
149 },
150
151 'setBookmarkletVersion': function(aValue) {
152 this._bookmarkletVersion = aValue;
153 },
154
155 //-------------------------------------------------------------------------
156
157 'formData': function() {
158 return this._formData;
159 },
160
161 'setFormData': function(aValue) {
162 var formData;
163
164//MochiKit.Logging.logDebug(">>> DirectLogin.setFormData - " + Clipperz.Base.serializeJSON(aValue));
165 switch (this.bookmarkletVersion()) {
166 case "0.2":
167 formData = aValue;
168 break;
169 case "0.1":
170//MochiKit.Logging.logDebug("--- DirectLogin.setFormData - fixing form data from bookmarklet version 0.1");
171 formData = this.fixFormDataFromBookmarkletVersion_0_1(aValue);
172 break;
173 }
174
175 this._formData = aValue;
176 this.setBookmarkletVersion("0.2");
177
178//MochiKit.Logging.logDebug("--- DirectLogin.setFormData - formData: " + Clipperz.Base.serializeJSON(formData));
179 if (formData != null) {
180 var i,c;
181
182 this._directLoginInputs = [];
183 c = formData['inputs'].length;
184 for (i=0; i<c; i++) {
185 var directLoginInput;
186
187 directLoginInput = new Clipperz.PM.DataModel.DirectLoginInput(this, formData['inputs'][i]);
188 this._directLoginInputs.push(directLoginInput);
189 }
190 }
191//MochiKit.Logging.logDebug("<<< DirectLogin.setFormData");
192 },
193
194 'fixFormDataFromBookmarkletVersion_0_1': function(aValue) {
195//{"type":"radio", "name":"action", "value":"new-user", "checked":false }, { "type":"radio", "name":"action", "value":"sign-in", "checked":true }
196 // ||
197 // \ /
198 // \/
199//{"name":"dominio", "type":"radio", "options":[{"value":"@alice.it", "checked":true}, {"value":"@tin.it", "checked":false}, {"value":"@virgilio.it", "checked":false}, {"value":"@tim.it", "checked":false}]}
200 var result;
201 var inputs;
202 var updatedInputs;
203 var radios;
204
205//MochiKit.Logging.logDebug(">>> DirectLogin.fixFormDataFromBookmarkletVersion_0_1");
206 result = aValue;
207 inputs = aValue['inputs'];
208
209 updatedInputs = MochiKit.Base.filter(function(anInput) {
210 varresult;
211 var type;
212
213 type = anInput['type'] || 'text';
214 result = type.toLowerCase() != 'radio';
215
216 return result;
217 }, inputs);
218 radios = MochiKit.Base.filter(function(anInput) {
219 varresult;
220 var type;
221
222 type = anInput['type'] || 'text';
223 result = type.toLowerCase() == 'radio';
224
225 return result;
226 }, inputs);
227
228 if (radios.length > 0) {
229 var updatedRadios;
230
231 updatedRadios = {};
232 MochiKit.Iter.forEach(radios, MochiKit.Base.bind(function(aRadio) {
233 varradioConfiguration;
234
235 radioConfiguration = updatedRadios[aRadio['name']];
236 if (radioConfiguration == null) {
237 radioConfiguration = {type:'radio', name:aRadio['name'], options:[]};
238 updatedRadios[aRadio['name']] = radioConfiguration;
239 }
240
241 //TODO: remove the value: field and replace it with element.dom.value = <some value>
242 radioConfiguration.options.push({value:aRadio['value'], checked:aRadio['checked']});
243
244 if ((aRadio['checked'] == true) && (this.formValues()[aRadio['name']] == null)) {
245//MochiKit.Logging.logDebug("+++ setting value '" + aRadio['value'] + "' for key: '" + aRadio['name'] + "'");
246 this.formValues()[aRadio['name']] = aRadio['value'];
247 }
248 }, this))
249
250 updatedInputs = MochiKit.Base.concat(updatedInputs, MochiKit.Base.values(updatedRadios));
251 }
252
253 delete result.inputs;
254 result.inputs = updatedInputs;
255//MochiKit.Logging.logDebug("<<< DirectLogin.fixFormDataFromBookmarkletVersion_0_1");
256
257 return result;
258 },
259
260 //.........................................................................
261
262 'directLoginInputs': function() {
263 return this._directLoginInputs;
264 },
265
266 //-------------------------------------------------------------------------
267
268 'formValues': function() {
269 return this._formValues;
270 },
271
272 'hasValuesToSet': function() {
273 var result;
274
275//MochiKit.Logging.logDebug(">>> DirectLogin.hasValuesToSet");
276 if (this.directLoginInputs() != null) {
277 result = MochiKit.Iter.some(this.directLoginInputs(), MochiKit.Base.methodcaller('shouldSetValue'));
278 } else {
279 result = false;
280 }
281//MochiKit.Logging.logDebug("<<< DirectLogin.hasValuesToSet");
282
283 return result;
284 },
285
286 //'additionalValues': function() {
287 'inputsRequiringAdditionalValues': function() {
288 varresult;
289 var inputs;
290
291//MochiKit.Logging.logDebug(">>> DirectLogin.additionalValues");
292 result = {};
293 if (this.directLoginInputs() != null) {
294 inputs = MochiKit.Base.filter(MochiKit.Base.methodcaller('shouldSetValue'), this.directLoginInputs());
295 MochiKit.Iter.forEach(inputs, function(anInput) {
296 result[anInput.name()] = anInput;
297 })
298 }
299//MochiKit.Logging.logDebug("<<< DirectLogin.additionalValues");
300
301 return result;
302 },
303
304 //-------------------------------------------------------------------------
305
306 'bindingData': function() {
307 return this._bindingData;
308 },
309
310 'setBindingData': function(aValue) {
311//MochiKit.Logging.logDebug(">>> DirectLogin.setBindingData");
312 if (aValue != null) {
313 var bindingKey;
314
315 this._bindingData = aValue;
316 this._bindings = {};
317
318 for (bindingKey in aValue) {
319 var directLoginBinding;
320
321 directLoginBinding = new Clipperz.PM.DataModel.DirectLoginBinding(this, bindingKey, {fieldKey:aValue[bindingKey]});
322 this._bindings[bindingKey] = directLoginBinding;
323 }
324 } else {
325 var editableFields;
326 var bindings;
327
328 bindings = {};
329
330 editableFields = MochiKit.Base.filter(function(aField) {
331 var result;
332 var type;
333
334 type = aField['type'].toLowerCase();
335 result = ((type != 'hidden') && (type != 'submit') && (type != 'checkbox') && (type != 'radio') && (type != 'select'));
336
337 return result;
338 }, this.formData().inputs);
339
340 MochiKit.Iter.forEach(editableFields, function(anEditableField) {
341 bindings[anEditableField['name']] = new Clipperz.PM.DataModel.DirectLoginBinding(this, anEditableField['name']);
342 }, this);
343
344 this._bindings = bindings;
345 }
346//MochiKit.Logging.logDebug("<<< DirectLogin.setBindingData");
347 },
348
349 'setLegacyBindingData': function(aValue) {
350//MochiKit.Logging.logDebug(">>> DirectLogin.setLegacyBindingData");
351 var bindingKey;
352
353 this._bindingData = aValue;
354 this._bindings = {};
355
356 for (bindingKey in aValue) {
357 var directLoginBinding;
358
359 directLoginBinding = new Clipperz.PM.DataModel.DirectLoginBinding(this, bindingKey, {fieldName:aValue[bindingKey]});
360 this._bindings[bindingKey] = directLoginBinding;
361 }
362//MochiKit.Logging.logDebug("<<< DirectLogin.setLegacyBindingData");
363 },
364
365 //.........................................................................
366
367 'bindings': function() {
368 return this._bindings;
369 },
370
371 //-------------------------------------------------------------------------
372
373 'serializedData': function() {
374 var result;
375 varbindingKey;
376
377 result = {};
378 // result.reference = this.reference();
379 result.label = this.label();
380 result.favicon = this.favicon() || "";
381 result.bookmarkletVersion = this.bookmarkletVersion();
382 result.formData = this.formData();
383 if (this.hasValuesToSet) {
384 result.formValues = this.formValues();
385 }
386 result.bindingData = {};
387
388 for (bindingKey in this.bindings()) {
389 result.bindingData[bindingKey] = this.bindings()[bindingKey].serializedData();
390 }
391
392 return result;
393 },
394
395 //-------------------------------------------------------------------------
396
397 'handleMissingFaviconImage': function(anEvent) {
398 anEvent.stop();
399 MochiKit.Signal.disconnectAll(anEvent.src());
400 this.setFixedFavicon(Clipperz.PM.Strings['defaultFaviconUrl']);
401 anEvent.src().src = this.fixedFavicon();
402 },
403
404 //=========================================================================
405
406 'runHttpAuthDirectLogin': function(aWindow) {
407 MochiKit.DOM.withWindow(aWindow, MochiKit.Base.bind(function() {
408 var completeUrl;
409 var url;
410
411 url = this.bindings()['url'].field().value();
412
413 if (/^https?\:\/\//.test(url) == false) {
414 url = 'http://' + url;
415 }
416
417 if (Clipperz_IEisBroken === true) {
418 completeUrl = url;
419 } else {
420 var username;
421 var password;
422
423 username = this.bindings()['username'].field().value();
424 password = this.bindings()['password'].field().value();
425
426 /(^https?\:\/\/)?(.*)/.test(url);
427
428 completeUrl = RegExp.$1 + username + ':' + password + '@' + RegExp.$2;
429 }
430
431 MochiKit.DOM.currentWindow().location.href = completeUrl;
432 }, this));
433 },
434
435 //-------------------------------------------------------------------------
436
437 'runSubmitFormDirectLogin': function(aWindow) {
438 MochiKit.DOM.withWindow(aWindow, MochiKit.Base.bind(function() {
439 var formElement;
440 varformSubmitFunction;
441 var submitButtons;
442
443//MochiKit.Logging.logDebug("### runDirectLogin - 3");
444 // MochiKit.DOM.currentDocument().write('<html><head><title>' + this.label() + '</title><META http-equiv="Content-Type" content="text/html; charset=utf-8" /></head><body></body></html>')
445//MochiKit.Logging.logDebug("### runDirectLogin - 3.1");
446 MochiKit.DOM.appendChildNodes(MochiKit.DOM.currentDocument().body, MochiKit.DOM.H3(null, "Loading " + this.label() + " ..."));
447//MochiKit.Logging.logDebug("### runDirectLogin - 4");
448//console.log(this.formData()['attributes']);
449 formElement = MochiKit.DOM.FORM(MochiKit.Base.update({id:'directLoginForm'}, {'method':this.formData()['attributes']['method'],
450 'action':this.formData()['attributes']['action']}));
451//MochiKit.Logging.logDebug("### runDirectLogin - 5");
452 formSubmitFunction = MochiKit.Base.method(formElement, 'submit');
453//MochiKit.Logging.logDebug("### runDirectLogin - 6");
454
455 MochiKit.DOM.appendChildNodes(MochiKit.DOM.currentDocument().body,
456 MochiKit.DOM.DIV({style:'display:none; visibility:hidden;'}, formElement)
457 );
458//MochiKit.Logging.logDebug("### runDirectLogin - 7");
459 MochiKit.DOM.appendChildNodes(formElement, MochiKit.Base.map(MochiKit.Base.methodcaller("formConfiguration"),
460 this.directLoginInputs()));
461//MochiKit.Logging.logDebug("### runDirectLogin - 8");
462
463 submitButtons = MochiKit.Base.filter(function(anInputElement) {
464//MochiKit.Logging.logDebug("### runDirectLogin - 8.1 - " + anInputElement);
465//MochiKit.Logging.logDebug("### runDirectLogin - 8.2 - " + anInputElement.tagName);
466//MochiKit.Logging.logDebug("### runDirectLogin - 8.3 - " + anInputElement.getAttribute('type'));
467 return ((anInputElement.tagName.toLowerCase() == 'input') && (anInputElement.getAttribute('type').toLowerCase() == 'submit'));
468 }, formElement.elements)
469//MochiKit.Logging.logDebug("### runDirectLogin - 9");
470
471 if (submitButtons.length == 0) {
472//MochiKit.Logging.logDebug("### OLD submit")
473 if (Clipperz_IEisBroken == true) {
474//MochiKit.Logging.logDebug("### runDirectLogin - 10");
475 formElement.submit();
476 } else {
477//MochiKit.Logging.logDebug("### runDirectLogin - 11");
478 formSubmitFunction();
479 }
480 } else {
481//MochiKit.Logging.logDebug("### NEW submit")
482 submitButtons[0].click();
483 }
484
485 }, this));
486 },
487
488 //-------------------------------------------------------------------------
489
490 'runDirectLogin': function(aNewWindow) {
491 varnewWindow;
492
493//console.log("formData.attributes", this.formData()['attributes']);
494 // if (/^javascript/.test(this.formData()['attributes']['action'])) {
495 if ((/^(https?|webdav|ftp)\:/.test(this.formData()['attributes']['action']) == false) &&
496 (this.formData()['attributes']['type'] != 'http_auth'))
497 {
498 var messageBoxConfiguration;
499
500 if (typeof(aNewWindow) != 'undefined') {
501 aNewWindow.close();
502 }
503
504 messageBoxConfiguration = {};
505 messageBoxConfiguration.title = Clipperz.PM.Strings['VulnerabilityWarning_Panel_title'];
506 messageBoxConfiguration.msg = Clipperz.PM.Strings['VulnerabilityWarning_Panel_message'];
507 messageBoxConfiguration.animEl = YAHOO.ext.Element.get("mainDiv");
508 messageBoxConfiguration.progress = false;
509 messageBoxConfiguration.closable = false;
510 messageBoxConfiguration.buttons = {'cancel': Clipperz.PM.Strings['VulnerabilityWarning_Panel_buttonLabel']};
511
512 Clipperz.YUI.MessageBox.show(messageBoxConfiguration);
513
514 throw Clipperz.Base.exception.VulnerabilityIssue;
515 }
516
517//MochiKit.Logging.logDebug("### runDirectLogin - 1 : " + Clipperz.Base.serializeJSON(this.serializedData()));
518 if (typeof(aNewWindow) == 'undefined') {
519 newWindow = window.open(Clipperz.PM.Strings['directLoginJumpPageUrl'], "");
520 } else {
521 newWindow = aNewWindow;
522 }
523//MochiKit.Logging.logDebug("### runDirectLogin - 2");
524
525 if (this.formData()['attributes']['type'] == 'http_auth') {
526 this.runHttpAuthDirectLogin(newWindow);
527 } else {
528 this.runSubmitFormDirectLogin(newWindow)
529 }
530 },
531
532 //-------------------------------------------------------------------------
533 __syntaxFix__: "syntax fix"
534
535});
536
diff --git a/frontend/beta/js/Clipperz/PM/DataModel/DirectLoginBinding.js b/frontend/beta/js/Clipperz/PM/DataModel/DirectLoginBinding.js
new file mode 100644
index 0000000..19aa9cb
--- a/dev/null
+++ b/frontend/beta/js/Clipperz/PM/DataModel/DirectLoginBinding.js
@@ -0,0 +1,113 @@
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.DataModel) == 'undefined') { Clipperz.PM.DataModel = {}; }
32
33
34//#############################################################################
35
36Clipperz.PM.DataModel.DirectLoginBinding = function(aDirectLogin, aKey, args) {
37//MochiKit.Logging.logDebug(">>> new DirectLoginBinding")
38 args = args || {};
39//MochiKit.Logging.logDebug("--- new DirectLoginBinding - args: " + Clipperz.Base.serializeJSON(args));
40
41 this._directLogin = aDirectLogin || args.directLogin || null;
42 this._key = aKey;
43
44 this._fieldKey = args.fieldKey || null;
45 this._fieldName = args.fieldName || null;
46//MochiKit.Logging.logDebug("<<< new DirectLoginBinding")
47
48 return this;
49}
50
51Clipperz.PM.DataModel.DirectLoginBinding.prototype = MochiKit.Base.update(null, {
52
53 'directLogin': function() {
54 return this._directLogin;
55 },
56
57 //-------------------------------------------------------------------------
58
59 'key': function() {
60 return this._key;
61 },
62
63 //-------------------------------------------------------------------------
64
65 'fieldKey': function() {
66//MochiKit.Logging.logDebug("=== Clipperz.PM.DataModel.DirectLoginBinding.fieldKey");
67//MochiKit.Logging.logDebug("=== Clipperz.PM.DataModel.DirectLoginBinding.fieldKey - " + this._fieldKey);
68 return this._fieldKey;
69 },
70
71 'setFieldKey': function(aValue) {
72 this._fieldKey = aValue;
73 },
74
75 'fieldName': function() {
76 return this._fieldName;
77 },
78
79 //-------------------------------------------------------------------------
80
81 'field': function() {
82 var result;
83
84 //MochiKit.Logging.logDebug(">>> Clipperz.PM.DataModel.DirectLoginBinding.field")
85//MochiKit.Logging.logDebug("--- Clipperz.PM.DataModel.DirectLoginBinding.field - 1 - this.fieldKey(): " + this.fieldKey());
86//MochiKit.Logging.logDebug("--- Clipperz.PM.DataModel.DirectLoginBinding.field - 2 - this.fieldName(): " + this.fieldName());
87 if (this.fieldKey() != null) {
88 result = this.directLogin().record().currentVersion().fields()[this.fieldKey()];
89//MochiKit.Logging.logDebug("--- Clipperz.PM.DataModel.DirectLoginBinding.field - 3 - result: " + result);
90 } else if (this.fieldName() != null) {
91 result = this.directLogin().record().currentVersion().fieldWithName(this.fieldName());
92//MochiKit.Logging.logDebug("--- Clipperz.PM.DataModel.DirectLoginBinding.field - 4 - result: " + result);
93
94 this.setFieldKey(result.key());
95 } else {
96 result = null;
97 }
98 //MochiKit.Logging.logDebug("<<< Clipperz.PM.DataModel.DirectLoginBinding.field")
99
100 return result;
101 },
102
103 //-------------------------------------------------------------------------
104
105 'serializedData': function() {
106 return this.fieldKey();
107 },
108
109 //-------------------------------------------------------------------------
110 __syntaxFix__: "syntax fix"
111
112});
113
diff --git a/frontend/beta/js/Clipperz/PM/DataModel/DirectLoginInput.js b/frontend/beta/js/Clipperz/PM/DataModel/DirectLoginInput.js
new file mode 100644
index 0000000..3302ed6
--- a/dev/null
+++ b/frontend/beta/js/Clipperz/PM/DataModel/DirectLoginInput.js
@@ -0,0 +1,229 @@
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.DataModel) == 'undefined') { Clipperz.PM.DataModel = {}; }
32
33//#############################################################################
34
35Clipperz.PM.DataModel.DirectLoginInput = function(aDirectLogin, args) {
36 args = args || {};
37
38//console.log(">>> new DirectLoginInput - args: %o" + args);
39 this._directLogin = aDirectLogin;
40 this._args = args;
41
42 return this;
43}
44
45Clipperz.PM.DataModel.DirectLoginInput.prototype = MochiKit.Base.update(null, {
46
47 'directLogin': function() {
48 return this._directLogin;
49 },
50
51 //-------------------------------------------------------------------------
52
53 'args': function() {
54 return this._args;
55 },
56
57 //-------------------------------------------------------------------------
58
59 'name': function() {
60 return this.args()['name'];
61 },
62
63 //-------------------------------------------------------------------------
64
65 'type': function() {
66 var result;
67
68 result = this.args()['type'];
69
70 if (result != null) {
71 result = result.toLowerCase();
72 }
73 return result;
74 },
75
76 //-------------------------------------------------------------------------
77
78 'value': function() {
79 return this.args()['value'];
80 },
81
82 //-------------------------------------------------------------------------
83
84 'formConfiguration': function() {
85 var result;
86
87//MochiKit.Logging.logDebug(">>> DirectLoginInput.formConfiguration - " + this.name());
88 if (this.shouldSetValue()) {
89//MochiKit.Logging.logDebug("--- DirectLoginInput.formConfiguration - 1");
90 switch (this.type()) {
91 case 'select':
92 var currentValue;
93 var options;
94
95//MochiKit.Logging.logDebug("--- DirectLoginInput.formConfiguration - 2");
96 currentValue = this.directLogin().formValues()[this.name()];
97//MochiKit.Logging.logDebug("--- DirectLoginInput.formConfiguration - 2.1");
98 options = this.args()['options'];
99//MochiKit.Logging.logDebug("--- DirectLoginInput.formConfiguration - 2.2");
100
101 result = MochiKit.DOM.SELECT({name:this.name()},
102 MochiKit.Base.map(function(anOption) {
103 var options;
104
105//MochiKit.Logging.logDebug("--- DirectLoginInput.formConfiguration - 2.3");
106 //TODO: remove the value: field and replace it with element.dom.value = <some value>
107 options = {value:anOption['value']};
108//MochiKit.Logging.logDebug("--- DirectLoginInput.formConfiguration - 2.4");
109 if (currentValue == anOption['value']) {
110//MochiKit.Logging.logDebug("--- DirectLoginInput.formConfiguration - 2.5");
111 options.selected = true;
112//MochiKit.Logging.logDebug("--- DirectLoginInput.formConfiguration - 2.6");
113 }
114//MochiKit.Logging.logDebug("--- DirectLoginInput.formConfiguration - 2.7");
115
116 return MochiKit.DOM.OPTION(options, anOption['label'])
117 }, options)
118 )
119//MochiKit.Logging.logDebug("--- DirectLoginInput.formConfiguration - 2.8");
120 break;
121 case 'checkbox':
122 var options;
123
124//MochiKit.Logging.logDebug("--- DirectLoginInput.formConfiguration - 3");
125 options = {type:'checkbox', name: this.name()};
126 if (this.directLogin().formValues()[this.name()] == true) {
127 options['checked'] = true;
128 };
129
130 result = MochiKit.DOM.INPUT(options, null);
131 break;
132 case 'radio':
133 var currentName;
134 var currentValue;
135 var options;
136
137//MochiKit.Logging.logDebug("--- DirectLoginInput.formConfiguration - 4");
138 currentName = this.name();
139//MochiKit.Logging.logDebug("--- DirectLoginInput.formConfiguration - 4.1");
140 currentValue = this.directLogin().formValues()[this.name()];
141//MochiKit.Logging.logDebug("--- DirectLoginInput.formConfiguration - 4.2");
142 options = this.args()['options'];
143//MochiKit.Logging.logDebug("--- DirectLoginInput.formConfiguration - 4.3");
144
145 result = MochiKit.DOM.DIV(null,
146 MochiKit.Base.map(function(anOption) {
147 var options;
148 var isChecked;
149 var inputNode;
150 var divNode;
151
152//MochiKit.Logging.logDebug("--- DirectLoginInput.formConfiguration - 4.4");
153 //TODO: remove the value: field and replace it with element.dom.value = <some value>
154 options = {type:'radio', name:currentName, value:anOption['value']}
155 isChecked = (currentValue == anOption['value']);
156//MochiKit.Logging.logDebug("--- DirectLoginInput.formConfiguration - 4.5");
157 if (isChecked) {
158//MochiKit.Logging.logDebug("--- DirectLoginInput.formConfiguration - 4.6");
159 options.checked = true;
160//MochiKit.Logging.logDebug("--- DirectLoginInput.formConfiguration - 4.7");
161 }
162//MochiKit.Logging.logDebug("--- DirectLoginInput.formConfiguration - 4.8 - options: " + Clipperz.Base.serializeJSON(options));
163//MochiKit.Logging.logDebug("--- DirectLoginInput.formConfiguration - 4.8 - value: " + anOption['value']);
164
165 if (Clipperz_IEisBroken == true) {
166 var checkedValue;
167
168//MochiKit.Logging.logDebug("--- DirectLoginInput.formConfiguration - 4.8.1");
169 checkedValue = (isChecked ? " CHECKED" : "");
170//MochiKit.Logging.logDebug("--- DirectLoginInput.formConfiguration - 4.8.2");
171 inputNode = MochiKit.DOM.currentDocument().createElement("<INPUT TYPE='RADIO' NAME='" + currentName + "' VALUE='" + anOption['value'] + "'" + checkedValue + ">");
172//MochiKit.Logging.logDebug("--- DirectLoginInput.formConfiguration - 4.8.3");
173 } else {
174//MochiKit.Logging.logDebug("--- DirectLoginInput.formConfiguration - 4.8.4");
175 inputNode = MochiKit.DOM.INPUT(options, anOption['value']);
176//MochiKit.Logging.logDebug("--- DirectLoginInput.formConfiguration - 4.8.5");
177 }
178//MochiKit.Logging.logDebug("--- DirectLoginInput.formConfiguration - 4.9");
179 divNode = MochiKit.DOM.DIV(null, inputNode);
180//MochiKit.Logging.logDebug("--- DirectLoginInput.formConfiguration - 4.10");
181
182 return divNode;
183 // return MochiKit.DOM.DIV(null, MochiKit.DOM.INPUT(options, anOption['value']));
184 }, options)
185 );
186//MochiKit.Logging.logDebug("--- DirectLoginInput.formConfiguration - 4.9");
187 break;
188 }
189 } else {
190 var binding;
191//MochiKit.Logging.logDebug("--- DirectLoginInput.formConfiguration - 5");
192 binding = this.directLogin().bindings()[this.name()];
193
194//MochiKit.Logging.logDebug("--- DirectLoginInput.formConfiguration - 6");
195 //TODO: remove the value: field and replace it with element.dom.value = <some value>
196 result = MochiKit.DOM.INPUT({
197 type:((this.type() != 'password') ? this.type() : 'text'),
198 // type:(((this.type() != 'password') && (this.type() != 'submit')) ? this.type() : 'text'),
199 name:this.name(),
200 value:((binding != null)? binding.field().value() : this.value())
201 }, null);
202//MochiKit.Logging.logDebug("--- DirectLoginInput.formConfiguration - 7");
203 }
204
205//MochiKit.Logging.logDebug("<<< DirectLoginInput.formConfiguration: ");
206 return result;
207 },
208
209 //-------------------------------------------------------------------------
210
211 'shouldSetValue': function() {
212 var type;
213 var result;
214
215//MochiKit.Logging.logDebug(">>> DirectLoginInput.shouldSetValue");
216 type = this.type();
217 result = ((type == 'checkbox') || (type == 'radio') || (type == 'select'));
218//if (result == true) {
219 //MochiKit.Logging.logDebug("DIRECT LOGIN INPUT need value: " + Clipperz.Base.serializeJSON(this.args()));
220//}
221//MochiKit.Logging.logDebug("<<< DirectLoginInput.shouldSetValue");
222 return result;
223 },
224
225 //-------------------------------------------------------------------------
226 __syntaxFix__: "syntax fix"
227
228});
229
diff --git a/frontend/beta/js/Clipperz/PM/DataModel/DirectLoginReference.js b/frontend/beta/js/Clipperz/PM/DataModel/DirectLoginReference.js
new file mode 100644
index 0000000..b067a21
--- a/dev/null
+++ b/frontend/beta/js/Clipperz/PM/DataModel/DirectLoginReference.js
@@ -0,0 +1,192 @@
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.DataModel) == 'undefined') { Clipperz.PM.DataModel = {}; }
32
33
34//#############################################################################
35
36Clipperz.PM.DataModel.DirectLoginReference = function(args) {
37 args = args || {};
38
39//MochiKit.Logging.logDebug(">>> new DirectLoginReference: " + Clipperz.Base.serializeJSON(MochiKit.Base.keys(args)));
40//MochiKit.Logging.logDebug(">>> new DirectLoginReference - record: " + args.record);
41 this._user = args.user;
42
43 if (args.directLogin != null) {
44 this._reference = args.directLogin.reference();
45 this._recordReference = args.directLogin.record().reference();
46 this._label = args.directLogin.label();
47 this._favicon = args.directLogin.favicon() || null;
48
49 this._directLogin = args.directLogin;
50 this._record = args.directLogin.record();
51 } else {
52 this._reference = args.reference;
53 this._recordReference = args.record;
54 this._label = args.label;
55 this._favicon = args.favicon || null;
56
57 this._directLogin = null;
58 this._record = null;
59 }
60
61 this._fixedFavicon = null;
62
63 return this;
64}
65
66Clipperz.PM.DataModel.DirectLoginReference.prototype = MochiKit.Base.update(null, {
67
68 'user': function() {
69 return this._user;
70 },
71
72 //-------------------------------------------------------------------------
73
74 'reference': function() {
75 return this._reference;
76 },
77
78 //-------------------------------------------------------------------------
79
80 'synchronizeValues': function(aDirectLogin) {
81 this._label = aDirectLogin.label();
82 this._favicon = aDirectLogin.favicon();
83 },
84
85 //-------------------------------------------------------------------------
86
87 'label': function() {
88 return this._label;
89 },
90
91 //-------------------------------------------------------------------------
92
93 'recordReference': function() {
94 return this._recordReference;
95 },
96
97 //-------------------------------------------------------------------------
98
99 'record': function() {
100//MochiKit.Logging.logDebug(">>> DirectLoginReference.record");
101 if (this._record == null) {
102 this._record = this.user().records()[this.recordReference()];
103 }
104
105//MochiKit.Logging.logDebug("<<< DirectLoginReference.record");
106 return this._record;
107 },
108
109 //-------------------------------------------------------------------------
110
111 'favicon': function() {
112 return this._favicon;
113 },
114
115 //-------------------------------------------------------------------------
116
117 'fixedFavicon': function() {
118 var result;
119
120 if (this._fixedFavicon == null) {
121 result = this.favicon();
122
123 if (Clipperz_IEisBroken && (this.user().preferences().disableUnsecureFaviconLoadingForIE()) && (result.indexOf('https://') != 0)) {
124 result = Clipperz.PM.Strings['defaultFaviconUrl_IE'];
125 this.setFixedFavicon(result);
126 }
127 } else {
128 result = this._fixedFavicon;
129 }
130
131 return result;
132 },
133
134 'setFixedFavicon': function(aValue) {
135 this._fixedFavicon = aValue;
136 },
137
138 //-------------------------------------------------------------------------
139
140 'setupJumpPageWindow': function(aWindow) {
141//MochiKit.Logging.logDebug(">>> DirectLoginReference.setupJumpPageWindow - " + aWindow);
142 try {
143 MochiKit.DOM.withWindow(aWindow, MochiKit.Base.bind(function() {
144 MochiKit.DOM.appendChildNodes(MochiKit.DOM.currentDocument().body,
145 MochiKit.DOM.H1(null, "Loading " + this.label())
146 );
147 }, this));
148 } catch(e) {
149 MochiKit.Logging.logDebug("EXCEPTION: " + e);
150 }
151//MochiKit.Logging.logDebug("<<< DirectLoginReference.setupJumpPageWindow");
152 },
153
154 //-------------------------------------------------------------------------
155
156 'deferredDirectLogin': function() {
157 var deferredResult;
158
159//MochiKit.Logging.logDebug(">>> DirectLoginReference.deferredDirectLogin - " + this);
160 deferredResult = new MochiKit.Async.Deferred();
161//MochiKit.Logging.logDebug("--- DirectLoginReference.deferredDirectLogin - 1");
162 deferredResult.addCallback(MochiKit.Base.method(this.record(), 'deferredData'));
163//MochiKit.Logging.logDebug("--- DirectLoginReference.deferredDirectLogin - 2");
164 deferredResult.addCallback(function(aRecord, aDirectLoginReference) {
165 return aRecord.directLogins()[aDirectLoginReference];
166 }, this.record(), this.reference());
167//MochiKit.Logging.logDebug("--- DirectLoginReference.deferredDirectLogin - 3");
168 deferredResult.callback();
169//MochiKit.Logging.logDebug("<<< DirectLoginReference.deferredDirectLogin");
170
171 return deferredResult;
172 },
173
174 //-------------------------------------------------------------------------
175
176 'handleMissingFaviconImage': function(anEvent) {
177//MochiKit.Logging.logDebug(">>> DirectLoginReference.handleMissingFaviconImage");
178 anEvent.stop();
179 MochiKit.Signal.disconnectAll(anEvent.src());
180 this.setFixedFavicon(Clipperz.PM.Strings['defaultFaviconUrl']);
181//MochiKit.Logging.logDebug("--- DirectLoginReference.handleMissingFaviconImage - fixedFavicon: " + this.fixedFavicon());
182//MochiKit.Logging.logDebug("--- DirectLoginReference.handleMissingFaviconImage - anEvent.src().src: " + anEvent.src().src);
183 // MochiKit.DOM.swapDOM(anEvent.src(), MochiKit.DOM.IMG({src:'this.fixedFavicon()'}));
184 anEvent.src().src = this.fixedFavicon();
185//MochiKit.Logging.logDebug("<<< DirectLoginReference.handleMissingFaviconImage");
186 },
187
188 //-------------------------------------------------------------------------
189 __syntaxFix__: "syntax fix"
190
191});
192
diff --git a/frontend/beta/js/Clipperz/PM/DataModel/Header.js b/frontend/beta/js/Clipperz/PM/DataModel/Header.js
new file mode 100644
index 0000000..ef34732
--- a/dev/null
+++ b/frontend/beta/js/Clipperz/PM/DataModel/Header.js
@@ -0,0 +1,751 @@
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.DataModel) == 'undefined') { Clipperz.PM.DataModel = {}; }
32
33
34//#############################################################################
35
36Clipperz.PM.DataModel.Header = function(args) {
37 args = args || {};
38
39 this._user = args.user;
40
41 this._serverData = null;
42 this._serverDataVersion = null;
43 this._jsonEvaledServerData = null;
44
45 this._decryptedLegacyServerData = null;
46 this._isDecryptingLegacyServerData = false;
47 this._decryptingLegacyServerDataPendingQueue = [];
48
49 this.resetUpdatedSections();
50
51 this._shouldLoadSections = {};
52
53 Clipperz.NotificationCenter.register(this.user(), 'updatedSection', this, 'updatedSectionHandler');
54
55 return this;
56}
57
58Clipperz.PM.DataModel.Header.prototype = MochiKit.Base.update(null, {
59
60 //-------------------------------------------------------------------------
61
62 'user': function() {
63 return this._user;
64 },
65
66 //-------------------------------------------------------------------------
67 //-------------------------------------------------------------------------
68 //-------------------------------------------------------------------------
69 //-------------------------------------------------------------------------
70 //-------------------------------------------------------------------------
71 //-------------------------------------------------------------------------
72 //-------------------------------------------------------------------------
73 //-------------------------------------------------------------------------
74 //-------------------------------------------------------------------------
75
76 'updatedSections': function() {
77 return this._updatedSections;
78 },
79
80 'markSectionAsUpdated': function(aSectionName) {
81 this.updatedSections().push(aSectionName);
82 },
83
84 'resetUpdatedSections': function() {
85 this._updatedSections = []
86 },
87
88 'hasSectionBeenUpdated': function(aSectionName) {
89 return (this.updatedSections().join().indexOf(aSectionName) != -1);
90 },
91
92 'cachedServerDataSection': function(aSectionName) {
93 return (this.hasSectionBeenUpdated(aSectionName)) ? {} : this.jsonEvaledServerData()[aSectionName];
94 },
95
96 'updateAllSections': function() {
97 this.resetUpdatedSections();
98 this.markSectionAsUpdated('records');
99 this.markSectionAsUpdated('directLogins');
100 this.markSectionAsUpdated('preferences');
101 this.markSectionAsUpdated('oneTimePasswords');
102
103 return MochiKit.Async.succeed(this);
104 },
105
106 'updatedSectionHandler': function(anEvent) {
107 this.markSectionAsUpdated(anEvent.parameters());
108 },
109
110 //-------------------------------------------------------------------------
111
112 'getObjectKeyIndex': function(anObject) {
113 var result;
114 varitemReference;
115 var index;
116
117 result = {};
118 index = 0;
119
120 for (itemReference in anObject) {
121 result[itemReference] = index.toString();
122 index ++;
123 }
124
125 return result;
126 },
127
128 //-------------------------------------------------------------------------
129
130 'serializedDataWithRecordAndDirectLoginIndexes': function(aRecordIndexes, aDirectLoginIndexs) {
131 var result;
132 var records;
133 var recordReference;
134
135//MochiKit.Logging.logDebug(">>> Header.serializedData");
136 result = {
137 'records': {},
138 'directLogins': {}
139 };
140
141 records = this.user().records();
142 for (recordReference in records) {
143 result['records'][aRecordIndexes[recordReference]] = this.user().records()[recordReference].headerData();
144 }
145
146 for (directLoginReference in this.user().directLoginReferences()) {
147 var currentDirectLogin;
148 vardirectLoginData;
149
150 currentDirectLogin = this.user().directLoginReferences()[directLoginReference];
151 if (aRecordIndexes[currentDirectLogin.recordReference()] != null) {
152 directLoginData = {
153 // reference: currentDirectLogin.reference(),
154 record: aRecordIndexes[currentDirectLogin.recordReference()].toString(),
155 label: currentDirectLogin.label(),
156 favicon:currentDirectLogin.favicon() || ""
157 }
158
159 result['directLogins'][aDirectLoginIndexs[directLoginReference]] = directLoginData;
160 }
161
162 }
163//MochiKit.Logging.logDebug("<<< Header.serializedData - result: " + Clipperz.Base.serializeJSON(result));
164//MochiKit.Logging.logDebug("<<< Header.serializedData");
165
166 return result;
167 },
168
169 //-------------------------------------------------------------------------
170
171 'encryptedData': function() {
172 var deferredResult;
173 var recordIndex;
174 var directLoginIndex;
175 varserializedData;
176 var result;
177
178//MochiKit.Logging.logDebug(">>> [" + (new Date()).valueOf() + "] Header.encryptedData");
179//MochiKit.Logging.logDebug("### Header.encryptedData - " + Clipperz.Base.serializeJSON(this.updatedSections()));
180 result = {
181 'records': this.cachedServerDataSection('records'),
182 'directLogins': this.cachedServerDataSection('directLogins'),
183 'preferences': this.cachedServerDataSection('preferences'),
184 'oneTimePasswords': this.cachedServerDataSection('oneTimePasswords'),
185 'version': '0.1'
186 };
187
188 if (this.hasSectionBeenUpdated('records')) {
189 recordIndex = this.getObjectKeyIndex(this.user().records());
190 result['records']['index'] = recordIndex;
191 } else {
192 recordIndex = result['records']['index'];
193 }
194
195 if (this.hasSectionBeenUpdated('directLogins')) {
196 directLoginIndex = this.getObjectKeyIndex(this.user().directLoginReferences());
197 result['directLogins']['index'] = directLoginIndex;
198 } else {
199 directLoginIndex = result['directLogins']['index'];
200 }
201
202 if (this.hasSectionBeenUpdated('records') || this.hasSectionBeenUpdated('directLogins')) {
203 serializedData = this.serializedDataWithRecordAndDirectLoginIndexes(recordIndex, directLoginIndex);
204 }
205
206 deferredResult = new MochiKit.Async.Deferred();
207
208//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.encryptedData - 1: " + res); return res;});
209 if (this.hasSectionBeenUpdated('records')) {
210//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.encryptedData - 1.1: " + res); return res;});
211 deferredResult.addCallback(function(anHeader, aResult, aSerializedData, aValue) {
212 return Clipperz.PM.Crypto.deferredEncryptWithCurrentVersion(anHeader.user().passphrase(), aSerializedData['records']);
213 }, this, result, serializedData);
214//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.encryptedData - 1.2: " + res); return res;});
215 deferredResult.addCallback(function(anHeader, aResult, aValue) {
216 aResult['records']['data'] = aValue;
217 }, this, result);
218//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.encryptedData - 1.3: " + res); return res;});
219 }
220
221//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.encryptedData - 2: " + res); return res;});
222 if (this.hasSectionBeenUpdated('directLogins')) {
223//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.encryptedData - 2.1: " + res); return res;});
224 deferredResult.addCallback(function(anHeader, aResult, aSerializedData, aValue) {
225 return Clipperz.PM.Crypto.deferredEncryptWithCurrentVersion(anHeader.user().passphrase(), aSerializedData['directLogins']);
226 }, this, result, serializedData);
227//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.encryptedData - 2.2: " + res); return res;});
228 deferredResult.addCallback(function(anHeader, aResult, aValue) {
229 aResult['directLogins']['data'] = aValue;
230 }, this, result);
231//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.encryptedData - 2.3: " + res); return res;});
232 }
233
234//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.encryptedData - 3: " + res); return res;});
235 if (this.hasSectionBeenUpdated('preferences')) {
236//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.encryptedData - 3.1: " + res); return res;});
237 deferredResult.addCallback(function(anHeader, aResult, aValue) {
238 return Clipperz.PM.Crypto.deferredEncryptWithCurrentVersion(anHeader.user().passphrase(), anHeader.user().preferences().serializedData());
239 }, this, result);
240//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.encryptedData - 3.2: " + res); return res;});
241 deferredResult.addCallback(function(anHeader, aResult, aValue) {
242 aResult['preferences']['data'] = aValue;
243 }, this, result);
244//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.encryptedData - 3.3: " + res); return res;});
245 }
246
247//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.encryptedData - 4: " + res); return res;});
248 if (this.hasSectionBeenUpdated('oneTimePasswords')) {
249//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.encryptedData - 4.1: " + res); return res;});
250 // deferredResult.addCallback(MochiKit.Base.method(this, 'loadOneTimePasswords'));
251//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.encryptedData - 4.2: " + res); return res;});
252 deferredResult.addCallback(function(anHeader, aResult, aValue) {
253 return Clipperz.PM.Crypto.deferredEncryptWithCurrentVersion(anHeader.user().passphrase(), anHeader.user().oneTimePasswordManager().serializedData());
254 }, this, result);
255//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.encryptedData - 4.3: " + res); return res;});
256 deferredResult.addCallback(function(anHeader, aResult, aValue) {
257 aResult['oneTimePasswords']['data'] = aValue;
258 }, this, result);
259//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.encryptedData - 4.4: " + res); return res;});
260 }
261
262//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.encryptedData - 5: " + res); return res;});
263 deferredResult.addCallback(function(anHeader, aResult, aValue) {
264 var serverData;
265
266 serverData = Clipperz.Base.serializeJSON(aResult);
267 anHeader.setServerData(serverData);
268
269 return serverData;
270 }, this, result);
271//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.encryptedData - 6: " + res); return res;});
272
273 deferredResult.callback();
274//MochiKit.Logging.logDebug("<<< [" + (new Date()).valueOf() + "] Header.encryptedData");
275
276 return deferredResult;
277 },
278
279 //-------------------------------------------------------------------------
280
281 'serverData': function() {
282 return this._serverData;
283 },
284
285 'setServerData': function(aValue) {
286//MochiKit.Logging.logDebug(">>> Header.setServerData");
287//MochiKit.Logging.logDebug("[start]=============================================");
288//MochiKit.Logging.logDebug("SERVER_DATA: " + aValue);
289//MochiKit.Logging.logDebug("[end]===============================================");
290 this._serverData = aValue;
291//MochiKit.Logging.logDebug("--- Header.setServerData - 1");
292 this.resetUpdatedSections();
293//MochiKit.Logging.logDebug("--- Header.setServerData - 2");
294 this.resetJsonEvaledServerData();
295//MochiKit.Logging.logDebug("<<< Header.setServerData");
296 },
297
298 'jsonEvaledServerData': function() {
299 if (this._jsonEvaledServerData == null) {
300 this._jsonEvaledServerData = Clipperz.Base.evalJSON(this.serverData());
301 }
302
303 return this._jsonEvaledServerData;
304 },
305
306 'resetJsonEvaledServerData': function() {
307 this._jsonEvaledServerData = null;
308 },
309
310 //-------------------------------------------------------------------------
311
312 'serverDataVersion': function() {
313 return this._serverDataVersion;
314 },
315
316 'setServerDataVersion': function(aValue) {
317 this._serverDataVersion = aValue;
318 },
319
320 //-------------------------------------------------------------------------
321
322 'decryptedLegacyServerData': function() {
323 var deferredResult;
324
325//MochiKit.Logging.logDebug(">>> Header.decryptedLegacyServerData");
326 deferredResult = new MochiKit.Async.Deferred();
327//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.decryptedLegacyServerData 1: "/* + res*/); return res;});
328//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
329 deferredResult.addCallback(MochiKit.Base.method(this, 'updateAllSections'));
330//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.decryptedLegacyServerData 2: "/* + res*/); return res;});
331//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
332 if (this._decryptedLegacyServerData == null) {
333//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.decryptedLegacyServerData 3: "/* + res*/); return res;});
334//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
335 deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'connection_decryptingUserData');
336//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.decryptedLegacyServerData 4: "/* + res*/); return res;});
337//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
338 deferredResult.addCallback(Clipperz.PM.Crypto.deferredDecrypt, this.user().passphrase(), this.serverData(), this.serverDataVersion());
339//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.decryptedLegacyServerData 5: "/* + res*/); return res;});
340//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
341 deferredResult.addCallback(function(anHeader, aValue) {
342 anHeader._decryptedLegacyServerData = aValue;
343 }, this);
344//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.decryptedLegacyServerData 6: "/* + res*/); return res;});
345//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
346 };
347//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.decryptedLegacyServerData 7: "/* + res*/); return res;});
348//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
349
350 deferredResult.addCallback(function(anHeader) {
351 return anHeader._decryptedLegacyServerData;
352 }, this);
353//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.decryptedLegacyServerData 8: "/* + res*/); return res;});
354//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
355 deferredResult.callback();
356//MochiKit.Logging.logDebug("<<< Header.decryptedLegacyServerData");
357
358 return deferredResult;
359 },
360
361 //-------------------------------------------------------------------------
362
363 'serverDataFormat': function() {
364 var result;
365
366//MochiKit.Logging.logDebug(">>> Header.serverDataFormat");
367 if (this.serverData().charAt(0) == '{') {
368 varserverData;
369
370 serverData = Clipperz.Base.evalJSON(this.serverData());
371 result = serverData['version'];
372 } else {
373 result = 'LEGACY';
374 }
375//MochiKit.Logging.logDebug("<<< Header.serverDataFormat");
376
377 return result;
378 },
379
380 //-------------------------------------------------------------------------
381
382 'extractHeaderDataFromUserDetails': function(someUserDetails) {
383 if (this.serverData() == null) {
384 this.setServerData(someUserDetails['header']);
385 this.setServerDataVersion(someUserDetails['version'])
386 }
387 },
388
389 //-------------------------------------------------------------------------
390
391 'extractDataWithKey': function(aKey) {
392 var deferredResult;
393
394//MochiKit.Logging.logDebug(">>> Header.extractDataWithKey");
395 deferredResult = new MochiKit.Async.Deferred();
396
397 switch (this.serverDataFormat()) {
398 case 'LEGACY':
399//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.extractDataWithKey 1: "/* + res*/); return res;});
400//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
401 deferredResult.addCallback(MochiKit.Base.method(this, 'decryptedLegacyServerData'));
402//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.extractDataWithKey 2: "/* + res*/); return res;});
403//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
404 deferredResult.addCallback(function(someDecryptedValues) {
405 return someDecryptedValues[aKey] || {};
406 })
407//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.extractDataWithKey 3: "/* + res*/); return res;});
408//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
409 break;
410 case '0.1':
411 var data;
412
413 //# data = Clipperz.Base.evalJSON(this.serverData());
414 data = this.jsonEvaledServerData();
415 if (typeof(data[aKey]) != 'undefined') {
416//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.extractDataWithKey 4: "/* + res*/); return res;});
417//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
418 deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'connection_decryptingUserData');
419//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.extractDataWithKey 5: "/* + res*/); return res;});
420//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
421 deferredResult.addCallback(Clipperz.PM.Crypto.deferredDecrypt, this.user().passphrase(), data[aKey]['data'], this.serverDataVersion());
422//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.extractDataWithKey 6: "/* + res*/); return res;});
423//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
424 deferredResult.addCallback(function(/*anHeader,*/ aKey, aData, aRecordIndex, aValue) {
425 var result;
426//MochiKit.Logging.logDebug(">>> [start] ===============================================");
427//MochiKit.Logging.logDebug("--- extractDataWithKey - 0 [" + aKey + "]: " + Clipperz.Base.serializeJSON(aValue));
428//MochiKit.Logging.logDebug("<<< [end] =================================================");
429 if (aKey == 'records') {
430 var recordKey;
431
432 result = {};
433 for (recordKey in aData['index']) {
434 result[recordKey] = aValue[aData['index'][recordKey]];
435 }
436 } else if (aKey == 'directLogins') {
437 varrecordKeyReversedIndex;
438 var recordKey;
439 var directLoginKey;
440
441 result = {};
442 recordKeyReversedIndex = {};
443
444 for (recordKey in aRecordIndex) {
445 recordKeyReversedIndex[aRecordIndex[recordKey]] = recordKey;
446 }
447
448//MochiKit.Logging.logDebug("--- extractDataWithKey - 1 - aData['index']: " + Clipperz.Base.serializeJSON(aData['index']));
449 for (directLoginKey in aData['index']) {
450try {
451 if ((aData['index'][directLoginKey] != null) && (aValue[aData['index'][directLoginKey]] != null)) {
452 result[directLoginKey] = aValue[aData['index'][directLoginKey]];
453 result[directLoginKey]['record'] = recordKeyReversedIndex[result[directLoginKey]['record']];
454 }
455} catch(exception) {
456 //result[directLoginKey] has no properties
457 MochiKit.Logging.logDebug("[Header 391] EXCEPTION: " + exception);
458 throw exception;
459}
460 }
461//MochiKit.Logging.logDebug("--- extractDataWithKey - 2");
462 } else {
463 result = aValue;
464 }
465
466 return result;
467 }, /*this,*/ aKey, data[aKey], data['records']['index']);
468//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.extractDataWithKey 6: "/* + res*/); return res;});
469//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
470 } else {
471//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.extractDataWithKey 7: "/* + res*/); return res;});
472//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
473 deferredResult.addCallback(MochiKit.Async.succeed, {});
474//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.extractDataWithKey 8: "/* + res*/); return res;});
475//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
476 }
477 break;
478 }
479
480//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.extractDataWithKey 9: "/* + res*/); return res;});
481//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
482 deferredResult.callback();
483//MochiKit.Logging.logDebug("<<< Header.extractDataWithKey");
484
485 return deferredResult;
486 },
487
488 //-------------------------------------------------------------------------
489
490 'processRecordData': function(someRecordData) {
491 var records;
492 varrecordReference;
493
494//console.log("HeaderRecordData parameters", someRecordData);
495//MochiKit.Logging.logDebug(">>> Header.processRecordData");
496 records = someRecordData;
497//MochiKit.Logging.logDebug("--- Header.processRecordData - 1");
498 if (records != null) {
499//MochiKit.Logging.logDebug("--- Header.processRecordData - records: " + Clipperz.Base.serializeJSON(records));
500 for (recordReference in records) {
501 var newRecord;
502 var parameters;
503
504//MochiKit.Logging.logDebug("--- Header.processRecordData - 2 - recordReference: " + recordReference);
505 if (recordReference != "stacktrace") {
506 parameters = records[recordReference];//.slice();
507//MochiKit.Logging.logDebug("--- Header.processRecordData - 3");
508 if (typeof(parameters['notes']) != 'undefined') {
509//MochiKit.Logging.logDebug("--- Header.processRecordData - 4");
510 if (parameters['notes'] != "") {
511//MochiKit.Logging.logDebug("--- Header.processRecordData - 5");
512 parameters['headerNotes'] = parameters['notes'];
513//MochiKit.Logging.logDebug("--- Header.processRecordData - 6");
514 }
515//MochiKit.Logging.logDebug("--- Header.processRecordData - 7");
516 delete parameters['notes'];
517//MochiKit.Logging.logDebug("--- Header.processRecordData - 8");
518 }
519//MochiKit.Logging.logDebug("--- Header.processRecordData - 9");
520 parameters['reference'] = recordReference;
521//MochiKit.Logging.logDebug("--- Header.processRecordData - 10");
522 parameters['user'] = this.user();
523//MochiKit.Logging.logDebug("--- Header.processRecordData - 11");
524
525 newRecord = new Clipperz.PM.DataModel.Record(parameters);
526//MochiKit.Logging.logDebug("--- Header.processRecordData - 12");
527 this.user().addRecord(newRecord, true);
528//MochiKit.Logging.logDebug("--- Header.processRecordData - 13");
529 }
530 }
531
532//MochiKit.Logging.logDebug("--- Header.processRecordData - 14");
533 Clipperz.NotificationCenter.notify(null, 'recordAdded', null, true);
534//MochiKit.Logging.logDebug("--- Header.processRecordData - 15");
535 }
536//MochiKit.Logging.logDebug("<<< Header.processRecordData");
537
538 return this.user().records();
539 },
540
541 //-------------------------------------------------------------------------
542
543 'processDirectLoginData': function(someDirectLoginData) {
544 var directLogins;
545 var directLoginReference;
546
547//MochiKit.Logging.logDebug(">>> Header.processDirectLoginData");
548 directLogins = someDirectLoginData;
549 if (directLogins != null) {
550 for (directLoginReference in directLogins) {
551 var directLoginReference;
552 var parameters;
553
554 parameters = directLogins[directLoginReference];//.slice();
555 parameters.user = this.user();
556 parameters.reference = directLoginReference;
557 directLoginReference = new Clipperz.PM.DataModel.DirectLoginReference(parameters);
558 if (directLoginReference.record() != null) {
559 this.user().addDirectLoginReference(directLoginReference, true);
560 }
561 }
562 }
563
564 Clipperz.NotificationCenter.notify(null, 'directLoginAdded', null, true);
565//MochiKit.Logging.logDebug("<<< Header.processDirectLoginData");
566
567 return this.user().directLoginReferences();
568 },
569
570 //-------------------------------------------------------------------------
571
572 'shouldLoadSections': function() {
573 return this._shouldLoadSections;
574 },
575
576 'shouldLoadSection': function(aSectionName) {
577 var result;
578
579 if (typeof(this.shouldLoadSections()[aSectionName]) != 'undefined') {
580 result = this.shouldLoadSections()[aSectionName];
581 } else {
582 result = true;
583 }
584
585 return result;
586 },
587
588 'setShouldLoadSection': function(aSectionName, aValue) {
589 this.shouldLoadSections()[aSectionName] = aValue;
590 },
591
592 //-------------------------------------------------------------------------
593
594 'loadRecords': function() {
595 var deferredResult;
596
597 if (this.shouldLoadSection('records') == true) {
598 this.setShouldLoadSection('records', false);
599
600 deferredResult = new MochiKit.Async.Deferred();
601//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.loadRecords 1: "/* + res*/); return res;});
602//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
603 deferredResult.addCallback(MochiKit.Base.method(this.user(), 'getUserDetails'));
604//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.loadRecords 2: "/* + res*/); return res;});
605//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
606 deferredResult.addCallback(MochiKit.Base.method(this, 'extractHeaderDataFromUserDetails'));
607//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.loadRecords 3: "/* + res*/); return res;});
608//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
609 deferredResult.addCallback(MochiKit.Base.method(this, 'extractDataWithKey', 'records'));
610//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.loadRecords 4: "/* + res*/); return res;});
611//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
612 deferredResult.addCallback(MochiKit.Base.method(this, 'processRecordData'));
613//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.loadRecords 5: "/* + res*/); return res;});
614//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
615 deferredResult.callback();
616 } else {
617 deferredResult = MochiKit.Async.succeed(this.user().records());
618 }
619
620 return deferredResult;
621 },
622
623 //-------------------------------------------------------------------------
624
625 'loadDirectLogins': function() {
626 var deferredResult;
627
628 if (this.shouldLoadSection('directLogins') == true) {
629 this.setShouldLoadSection('directLogins', false);
630
631 deferredResult = new MochiKit.Async.Deferred();
632//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.loadDirectLogins - 1: "/* + res*/); return res;});
633//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
634 deferredResult.addCallback(MochiKit.Base.method(this.user(), 'getUserDetails'));
635//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.loadDirectLogins - 2: "/* + res*/); return res;});
636//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
637 deferredResult.addCallback(MochiKit.Base.method(this, 'extractHeaderDataFromUserDetails'));
638//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.loadDirectLogins - 3: "/* + res*/); return res;});
639//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
640 deferredResult.addCallback(MochiKit.Base.method(this, 'extractDataWithKey', 'directLogins'));
641//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.loadDirectLogins - 4: "/* + res*/); return res;});
642//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
643 deferredResult.addCallback(MochiKit.Base.method(this, 'processDirectLoginData'));
644//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.loadDirectLogins - 5: "/* + res*/); return res;});
645//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
646 deferredResult.callback();
647 } else {
648 deferredResult = MochiKit.Async.succeed(this.user().directLoginReferences());
649 }
650
651 return deferredResult;
652 },
653
654 //-------------------------------------------------------------------------
655
656 'loadPreferences': function() {
657 var deferredResult;
658
659 if (this.shouldLoadSection('preferences') == true) {
660 this.setShouldLoadSection('preferences', false);
661
662 deferredResult = new MochiKit.Async.Deferred();
663//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.loadPreferences - 1: "/* + res*/); return res;});
664//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
665 deferredResult.addCallback(MochiKit.Base.method(this.user(), 'getUserDetails'));
666//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.loadPreferences - 2: "/* + res*/); return res;});
667//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
668 deferredResult.addCallback(MochiKit.Base.method(this, 'extractHeaderDataFromUserDetails'));
669//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.loadPreferences - 3: "/* + res*/); return res;});
670//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
671 deferredResult.addCallback(MochiKit.Base.method(this, 'extractDataWithKey', 'preferences'));
672//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.loadPreferences - 4: "/* + res*/); return res;});
673//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
674 deferredResult.addCallback(MochiKit.Base.method(this.user().preferences(), 'updateWithData'));
675//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.loadPreferences - 5: "/* + res*/); return res;});
676//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
677 deferredResult.callback();
678 } else {
679 deferredResult = MochiKit.Async.succeed(this.user().preferences());
680 }
681
682 return deferredResult;
683 },
684
685 //-------------------------------------------------------------------------
686
687 'loadOneTimePasswords': function() {
688 var deferredResult;
689
690 if (this.shouldLoadSection('oneTimePasswords') == true) {
691 this.setShouldLoadSection('oneTimePasswords', false);
692
693 deferredResult = new MochiKit.Async.Deferred();
694//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.loadOneTimePasswords - 1: "/* + res*/); return res;});
695//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
696 deferredResult.addCallback(MochiKit.Base.method(this.user(), 'getUserDetails'));
697//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.loadOneTimePasswords - 2: "/* + res*/); return res;});
698//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
699 deferredResult.addCallback(MochiKit.Base.method(this, 'extractHeaderDataFromUserDetails'));
700//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.loadOneTimePasswords - 3: "/* + res*/); return res;});
701//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
702 deferredResult.addCallback(MochiKit.Base.method(this, 'extractDataWithKey', 'oneTimePasswords'));
703//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.loadOneTimePasswords - 4: "/* + res*/); return res;});
704//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
705 deferredResult.addCallback(MochiKit.Base.method(this.user().oneTimePasswordManager(), 'updateWithData'));
706//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.loadOneTimePasswords - 5: "/* + res*/); return res;});
707//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
708 deferredResult.addCallback(MochiKit.Base.method(this.user().connection(), 'message'), 'getOneTimePasswordsDetails', {});
709//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.loadOneTimePasswords - 6: "/* + res*/); return res;});
710//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
711 deferredResult.addCallback(MochiKit.Base.method(this.user().oneTimePasswordManager(), 'updateWithServerData'));
712//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.loadOneTimePasswords - 7: "/* + res*/); return res;});
713//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
714 deferredResult.callback();
715 } else {
716 deferredResult = MochiKit.Async.succeed(this.user().oneTimePasswordManager());
717 }
718
719 return deferredResult;
720 },
721
722 //-------------------------------------------------------------------------
723
724 'loadAllSections': function() {
725 var deferredResult;
726
727 deferredResult = new MochiKit.Async.Deferred();
728//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.loadAllSections - 1: "/* + res*/); return res;});
729//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
730 deferredResult.addCallback(MochiKit.Base.method(this, 'loadRecords'));
731//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.loadAllSections - 2: "/* + res*/); return res;});
732//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
733 deferredResult.addCallback(MochiKit.Base.method(this, 'loadDirectLogins'));
734//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.loadAllSections - 3: "/* + res*/); return res;});
735//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
736 deferredResult.addCallback(MochiKit.Base.method(this, 'loadPreferences'));
737//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.loadAllSections - 4: "/* + res*/); return res;});
738//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
739 deferredResult.addCallback(MochiKit.Base.method(this, 'loadOneTimePasswords'));
740//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Header.loadAllSections - 5: "/* + res*/); return res;});
741//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
742 deferredResult.callback();
743
744 return deferredResult;
745 },
746
747 //-------------------------------------------------------------------------
748 __syntaxFix__: "syntax fix"
749
750});
751
diff --git a/frontend/beta/js/Clipperz/PM/DataModel/OneTimePassword.js b/frontend/beta/js/Clipperz/PM/DataModel/OneTimePassword.js
new file mode 100644
index 0000000..dd8d5c9
--- a/dev/null
+++ b/frontend/beta/js/Clipperz/PM/DataModel/OneTimePassword.js
@@ -0,0 +1,333 @@
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.DataModel) == 'undefined') { Clipperz.PM.DataModel = {}; }
32
33
34//#############################################################################
35
36Clipperz.PM.DataModel.OneTimePassword = function(args) {
37 args = args || {};
38
39//console.log("new OneTimePassword", args);
40//MochiKit.Logging.logDebug("---");
41 this._user = args['user'];
42 this._password = args['password'];
43 this._passwordValue = Clipperz.PM.DataModel.OneTimePassword.normalizedOneTimePassword(args['password']);
44 this._reference = args['reference'] || Clipperz.PM.Crypto.randomKey();
45 this._creationDate = args['created'] ? Clipperz.PM.Date.parseDateWithUTCFormat(args['created']) : new Date();
46 this._usageDate = args['used'] ? Clipperz.PM.Date.parseDateWithUTCFormat(args['used']) : null;
47
48 this._status = args['status'] || 'ACTIVE';
49 this._connectionInfo = null;
50
51 this._key = null;
52 this._keyChecksum = null;
53
54 return this;
55}
56
57Clipperz.PM.DataModel.OneTimePassword.prototype = MochiKit.Base.update(null, {
58
59 'toString': function() {
60 return "Clipperz.PM.DataModel.OneTimePassword";
61 },
62
63 //-------------------------------------------------------------------------
64
65 'user': function() {
66 return this._user;
67 },
68
69 //-------------------------------------------------------------------------
70
71 'password': function() {
72 return this._password;
73 },
74
75 //-------------------------------------------------------------------------
76
77 'passwordValue': function() {
78 return this._passwordValue;
79 },
80
81 //-------------------------------------------------------------------------
82
83 'creationDate': function() {
84 return this._creationDate;
85 },
86
87 //-------------------------------------------------------------------------
88
89 'reference': function() {
90 return this._reference;
91 },
92
93 //-------------------------------------------------------------------------
94
95 'key': function() {
96 if (this._key == null) {
97 this._key = Clipperz.PM.DataModel.OneTimePassword.computeKeyWithUsernameAndPassword(this.user().username(), this.passwordValue());
98 }
99
100 return this._key;
101 },
102
103 //-------------------------------------------------------------------------
104
105 'keyChecksum': function() {
106 if (this._keyChecksum == null) {
107 this._keyChecksum = Clipperz.PM.DataModel.OneTimePassword.computeKeyChecksumWithUsernameAndPassword(this.user().username(), this.passwordValue());
108 }
109
110 return this._keyChecksum;
111 },
112
113 //-------------------------------------------------------------------------
114
115 'status': function() {
116 return this._status;
117 },
118
119 'setStatus': function(aValue) {
120 this._status = aValue;
121 },
122
123 //-------------------------------------------------------------------------
124
125 'serializedData': function() {
126 var result;
127
128 result = {
129 'password': this.password(),
130 'created': this.creationDate() ? Clipperz.PM.Date.formatDateWithUTCFormat(this.creationDate()) : null,
131 'used': this.usageDate() ? Clipperz.PM.Date.formatDateWithUTCFormat(this.usageDate()) : null,
132 'status': this.status()
133 };
134
135 return result;
136 },
137
138 //-------------------------------------------------------------------------
139
140 'packedPassphrase': function() {
141 var result;
142 var packedPassphrase;
143 var encodedPassphrase;
144 varprefixPadding;
145 var suffixPadding;
146 var getRandomBytes;
147
148 getRandomBytes = MochiKit.Base.method(Clipperz.Crypto.PRNG.defaultRandomGenerator(), 'getRandomBytes');
149
150 encodedPassphrase = new Clipperz.ByteArray(this.user().passphrase()).toBase64String();
151//MochiKit.Logging.logDebug("--- encodedPassphrase.length: " + encodedPassphrase.length);
152 prefixPadding = getRandomBytes(getRandomBytes(1).byteAtIndex(0)).toBase64String();
153//MochiKit.Logging.logDebug("--- prefixPadding.length: " + prefixPadding.length);
154 suffixPadding = getRandomBytes((500 - prefixPadding.length - encodedPassphrase.length) * 6 / 8).toBase64String();
155//MochiKit.Logging.logDebug("--- suffixPadding.length: " + suffixPadding.length);
156//MochiKit.Logging.logDebug("--- total.length: " + (prefixPadding.length + encodedPassphrase.length + suffixPadding.length));
157
158 packedPassphrase = {
159 'prefix': prefixPadding,
160 'passphrase': encodedPassphrase,
161 'suffix': suffixPadding
162 };
163
164 // result = Clipperz.Base.serializeJSON(packedPassphrase);
165 result = packedPassphrase;
166//MochiKit.Logging.logDebug("===== OTP packedPassprase: [" + result.length + "]" + result);
167//MochiKit.Logging.logDebug("<<< OneTimePassword.packedPassphrase");
168
169 return result;
170 },
171
172 //-------------------------------------------------------------------------
173
174 'encryptedPackedPassphrase': function() {
175 return Clipperz.PM.Crypto.deferredEncryptWithCurrentVersion(this.passwordValue(), this.packedPassphrase())
176 },
177
178 //-------------------------------------------------------------------------
179
180 'encryptedData': function() {
181 var deferredResult;
182 varresult;
183
184//MochiKit.Logging.logDebug(">>> OneTimePassword.encryptedData");
185//MochiKit.Logging.logDebug("--- OneTimePassword.encryptedData - id: " + this.reference());
186 result = {
187 'reference': this.reference(),
188 'key': this.key(),
189 'keyChecksum': this.keyChecksum(),
190 'data': "",
191 'version': Clipperz.PM.Crypto.encryptingFunctions.currentVersion
192 }
193//MochiKit.Logging.logDebug("--- OneTimePassword.encryptedData - 2: " + Clipperz.Base.serializeJSON(result));
194 deferredResult = new MochiKit.Async.Deferred();
195//MochiKit.Logging.logDebug("--- OneTimePassword.encryptedData - 3");
196//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("OneTimePassword.encryptedData - 1: " + res); return res;});
197 //# deferredResult.addCallback(Clipperz.PM.Crypto.deferredEncryptWithCurrentVersion, this.passwordValue(), this.packedPassphrase());
198 deferredResult.addCallback(MochiKit.Base.method(this, 'encryptedPackedPassphrase'));
199//MochiKit.Logging.logDebug("--- OneTimePassword.encryptedData - 4");
200//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("OneTimePassword.encryptedData - 2: [" + res.length + "]" + res); return res;});
201 deferredResult.addCallback(function(aResult, res) {
202 aResult['data'] = res;
203 return aResult;
204 }, result);
205//MochiKit.Logging.logDebug("--- OneTimePassword.encryptedData - 5");
206//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("OneTimePassword.encryptedData - 3: " + Clipperz.Base.serializeJSON(res)); return res;});
207 deferredResult.callback();
208//MochiKit.Logging.logDebug("--- OneTimePassword.encryptedData - 6");
209
210 return deferredResult;
211 },
212
213 //-------------------------------------------------------------------------
214
215 'saveChanges': function() {
216 var deferredResult;
217 varresult;
218
219//MochiKit.Logging.logDebug(">>> OneTimePassword.saveChanges");
220 result = {};
221 deferredResult = new MochiKit.Async.Deferred();
222
223 deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'saveOTP_encryptUserData');
224 deferredResult.addCallback(MochiKit.Base.method(this.user(), 'encryptedData'));
225 deferredResult.addCallback(function(aResult, res) {
226 aResult['user'] = res;
227 return aResult;
228 }, result);
229
230 deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'saveOTP_encryptOTPData');
231 deferredResult.addCallback(MochiKit.Base.method(this, 'encryptedData'));
232 deferredResult.addCallback(function(aResult, res) {
233 aResult['oneTimePassword'] = res;
234 return aResult;
235 }, result);
236
237 deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'saveOTP_sendingData');
238//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("OneTimePassword.saveChanges - 1: " + Clipperz.Base.serializeJSON(res)); return res;});
239 deferredResult.addCallback(MochiKit.Base.method(this.user().connection(), 'message'), 'addNewOneTimePassword');
240
241 deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'saveOTP_updatingInterface');
242//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("OneTimePassword.saveChanges - 2: " + res); return res;});
243 deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'notify', 'OTPUpdated');
244 deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'oneTimePassword_saveChanges_done', null);
245//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("OneTimePassword.saveChanges - 2: " + res); return res;});
246 deferredResult.callback();
247//MochiKit.Logging.logDebug("<<< OneTimePassword.saveChanges");
248
249 return deferredResult;
250 },
251
252 //-------------------------------------------------------------------------
253
254 'usageDate': function() {
255 return this._usageDate;
256 },
257
258 'setUsageDate': function(aValue) {
259 this._usageDate = aValue;
260 },
261
262 //-------------------------------------------------------------------------
263
264 'connectionInfo': function() {
265 return this._connectionInfo;
266 },
267
268 'setConnectionInfo': function(aValue) {
269 this._connectionInfo = aValue;
270 },
271
272 //-------------------------------------------------------------------------
273
274 'isExpired': function() {
275 return (this.usageDate() != null);
276 },
277
278 //-------------------------------------------------------------------------
279
280 'updateStatusWithValues': function(someValues) {
281 var result;
282
283 result = false;
284
285 if (someValues['status'] != this.status()) {
286 result = true;
287 }
288
289 this.setStatus(someValues['status']);
290 this.setUsageDate(Clipperz.PM.Date.parseDateWithUTCFormat(someValues['requestDate']));
291 this.setConnectionInfo(someValues['connection']);
292
293 return result;
294 },
295
296 //-------------------------------------------------------------------------
297 __syntaxFix__: "syntax fix"
298});
299
300//=============================================================================
301
302Clipperz.PM.DataModel.OneTimePassword.computeKeyWithUsernameAndPassword = function(anUsername, aPassword) {
303 return Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aPassword)).toHexString().substring(2);
304}
305
306Clipperz.PM.DataModel.OneTimePassword.computeKeyChecksumWithUsernameAndPassword = function(anUsername, aPassword) {
307 return Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(anUsername + aPassword)).toHexString().substring(2);
308}
309
310//=============================================================================
311
312Clipperz.PM.DataModel.OneTimePassword.normalizedOneTimePassword = function(aPassword) {
313 varresult;
314
315 if (aPassword.replace(/[\s\-]/g, '').length == 32) {
316 try {
317 var passwordByteArray;
318
319 passwordByteArray = new Clipperz.ByteArray();
320 passwordByteArray.appendBase32String(aPassword);
321
322 result = passwordByteArray.toBase64String();
323 } catch(exception) {
324 result = aPassword;
325 }
326 } else {
327 result = aPassword;
328 }
329
330 return result;
331}
332
333//=============================================================================
diff --git a/frontend/beta/js/Clipperz/PM/DataModel/OneTimePasswordManager.js b/frontend/beta/js/Clipperz/PM/DataModel/OneTimePasswordManager.js
new file mode 100644
index 0000000..d90100a
--- a/dev/null
+++ b/frontend/beta/js/Clipperz/PM/DataModel/OneTimePasswordManager.js
@@ -0,0 +1,280 @@
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.DataModel) == 'undefined') { Clipperz.PM.DataModel = {}; }
32
33
34//#############################################################################
35
36Clipperz.PM.DataModel.OneTimePasswordManager = function(anUser, args) {
37 args = args || {};
38
39 this._user = anUser;
40 this._oneTimePasswords = {};
41
42 this.updateWithData(args);
43
44 Clipperz.NotificationCenter.notify(null, 'oneTimePasswordAdded', null, true);
45
46 return this;
47}
48
49Clipperz.PM.DataModel.OneTimePasswordManager.prototype = MochiKit.Base.update(null, {
50
51 'toString': function() {
52 return "Clipperz.PM.DataModel.OneTimePasswordManager";
53 },
54
55 //-------------------------------------------------------------------------
56
57 'updateWithData': function(someValues) {
58 varotpReference;
59
60//console.log("OneTimePasswordManager.updateWithData", someValues);
61//MochiKit.Logging.logDebug("OneTimePasswordManager.updateWithData: " + Clipperz.Base.serializeJSON(someValues));
62 for (otpReference in someValues) {
63 var otp;
64 var otpConfiguration;
65
66 otpConfiguration = someValues[otpReference];
67 otpConfiguration['user'] = this.user();
68 otpConfiguration['reference'] = otpReference;
69 otp = new Clipperz.PM.DataModel.OneTimePassword(otpConfiguration);
70 this._oneTimePasswords[otpReference] = otp;
71 }
72
73 return this;
74 },
75
76 //-------------------------------------------------------------------------
77
78 'updateWithServerData': function(someValues) {
79 var deferredResult;
80 varoneTimePasswordReference;
81 var wereChangesApplied;
82
83//MochiKit.Logging.logDebug(">>> OneTimePasswordManager.updateWithServerData");
84 deferredResult = new MochiKit.Async.Deferred();
85 wereChangesApplied = false;
86
87 for (oneTimePasswordReference in someValues) {
88 var oneTimePassword;
89
90 oneTimePassword = this.oneTimePasswordWithReference(oneTimePasswordReference);
91 if (oneTimePassword != null) {
92 var oneTimePasswordHasBeenUpdated;
93
94 oneTimePasswordHasBeenUpdated = oneTimePassword.updateStatusWithValues(someValues[oneTimePasswordReference]);
95 wereChangesApplied = oneTimePasswordHasBeenUpdated || wereChangesApplied;
96 } else {
97
98 }
99 }
100
101 if (wereChangesApplied == true) {
102 this.user().header().markSectionAsUpdated('oneTimePasswords');
103 }
104
105 for (oneTimePasswordReference in this.oneTimePasswords()) {
106 if (typeof(someValues[oneTimePasswordReference]) == 'undefind') {
107 deferredResult.addCallback(MochiKit.Base.method(this.oneTimePasswordWithReference(oneTimePasswordReference), 'saveChanges'));
108 }
109 }
110
111 deferredResult.addCallback(MochiKit.Async.succeed, this);
112
113 deferredResult.callback();
114//MochiKit.Logging.logDebug("<<< OneTimePasswordManager.updateWithServerData");
115
116 return deferredResult;
117 },
118
119 //-------------------------------------------------------------------------
120
121 'user': function() {
122 return this._user;
123 },
124
125 //-------------------------------------------------------------------------
126
127 'addOneTimePassword': function(aOneTimePassword, isBatchUpdate) {
128 this.oneTimePasswords()[aOneTimePassword.reference()] = aOneTimePassword;
129
130 if (isBatchUpdate != true) {
131 Clipperz.NotificationCenter.notify(aOneTimePassword, 'oneTimePasswordAdded');
132 Clipperz.NotificationCenter.notify(this.user(), 'updatedSection', 'oneTimePasswords', true);
133 }
134 },
135
136 //-------------------------------------------------------------------------
137
138 'archiveOneTimePassword': function(aOneTimePasswordReference) {
139 var deferredResult;
140
141//MochiKit.Logging.logDebug(">>> OneTimePasswordManager.archiveOneTimePassword");
142//MochiKit.Logging.logDebug("--- OneTimePasswordManager.archiveOneTimePassword - 0 otp.reference: " + aOneTimePasswordReference);
143 deferredResult = new MochiKit.Async.Deferred();
144 deferredResult.addCallback(MochiKit.Base.method(this.user(), 'loadOneTimePasswords'));
145 deferredResult.addCallback(MochiKit.Base.bind(function(aOneTimePasswordReference) {
146 var oneTimePassword;
147
148//MochiKit.Logging.logDebug("--- OneTimePasswordManager.archiveOneTimePassword - 1 serializedData: " + Clipperz.Base.serializeJSON(this.serializedData()));
149 oneTimePassword = this.oneTimePasswords()[aOneTimePasswordReference];
150
151 if (oneTimePassword != null) {
152 oneTimePassword.setUsageDate(new Date());
153
154 // while (this.usedOneTimePasswords().length > 10) {
155 // var referenceOfOneTimePasswordToRemove;
156 //
157 // referenceOfOneTimePasswordToRemove = this.usedOneTimePasswords()[0];
158 // delete this.oneTimePasswords()[referenceOfOneTimePasswordToRemove];
159 // this.usedOneTimePasswords().shift();
160 // }
161
162 Clipperz.NotificationCenter.notify(this.user(), 'updatedSection', 'oneTimePasswords', true);
163 } else {
164 MochiKit.Logging.logError("### OneTimePasswordManager.archiveOneTimePassword - the used OneTimePassword has not been found on the index-card. :-(");
165 }
166
167//MochiKit.Logging.logDebug("--- OneTimePasswordManager.archiveOneTimePassword - 2 serializedData: " + Clipperz.Base.serializeJSON(this.serializedData()));
168 }, this), aOneTimePasswordReference);
169 deferredResult.addCallback(MochiKit.Base.method(this, 'saveChanges'));
170 deferredResult.callback();
171//MochiKit.Logging.logDebug("<<< OneTimePasswordManager.archiveOneTimePassword");
172
173 return deferredResult;
174 },
175
176 //-------------------------------------------------------------------------
177
178 'serializedData': function() {
179 var result;
180 varkey;
181
182 result = {};
183
184 for (key in this.oneTimePasswords()) {
185 result[key] = this.oneTimePasswords()[key].serializedData();
186 }
187
188 return result;
189 },
190
191 //-------------------------------------------------------------------------
192
193 'oneTimePasswords': function() {
194 return this._oneTimePasswords;
195 },
196
197 //-------------------------------------------------------------------------
198
199 'oneTimePasswordWithReference': function(aOneTimePasswordReference) {
200 return this.oneTimePasswords()[aOneTimePasswordReference];
201 },
202
203 //-------------------------------------------------------------------------
204
205 'deleteOneTimePasswordWithReference': function(aOneTimePasswordReference) {
206 delete(this.oneTimePasswords()[aOneTimePasswordReference]);
207 Clipperz.NotificationCenter.notify(this.user(), 'updatedSection', 'oneTimePasswords', true);
208 },
209
210 //-------------------------------------------------------------------------
211
212 'encryptedData': function() {
213 var deferredResult;
214 var oneTimePasswordReferences;
215 var result;
216 var i, c;
217
218 result = {};
219 deferredResult = new MochiKit.Async.Deferred();
220 deferredResult.addCallback(MochiKit.Async.succeed);
221
222 oneTimePasswordReferences = MochiKit.Base.keys(this.oneTimePasswords());
223 c = oneTimePasswordReferences.length;
224 for (i=0; i<c; i++) {
225 var currentOneTimePassword;
226
227 currentOneTimePassword = this.oneTimePasswords()[oneTimePasswordReferences[i]];
228 deferredResult.addCallback(MochiKit.Base.method(currentOneTimePassword, 'encryptedPackedPassphrase'));
229 deferredResult.addCallback(function(aResult, aOneTimePasswordReference, anEncryptedPackedPassphrase) {
230 aResult[aOneTimePasswordReference] = anEncryptedPackedPassphrase;
231 return aResult;
232 }, result, oneTimePasswordReferences[i]);
233 }
234//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("OneTimePasswordManager.encryptedData: " + res); return res;});
235
236 deferredResult.callback(result);
237
238 return deferredResult;
239 },
240
241 //-------------------------------------------------------------------------
242
243 'saveChanges': function() {
244 var deferredResult;
245 varresult;
246
247//MochiKit.Logging.logDebug(">>> OneTimePasswordManager.saveChanges");
248 result = {};
249 deferredResult = new MochiKit.Async.Deferred();
250 deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'saveOTP_encryptUserData');
251 deferredResult.addCallback(MochiKit.Base.method(this.user(), 'encryptedData'));
252 deferredResult.addCallback(function(aResult, res) {
253 aResult['user'] = res;
254 return aResult;
255 }, result);
256
257 deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'saveOTP_encryptOTPData');
258 deferredResult.addCallback(MochiKit.Base.bind(function(res) {
259 res['oneTimePasswords'] = MochiKit.Base.keys(this.oneTimePasswords());
260 return res;
261 }, this));
262
263 deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'saveOTP_sendingData');
264//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("OneTimePasswordManager.saveChanges - 1: " + Clipperz.Base.serializeJSON(res)); return res;});
265 deferredResult.addCallback(MochiKit.Base.method(this.user().connection(), 'message'), 'updateOneTimePasswords');
266
267 deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'saveOTP_updatingInterface');
268//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("OneTimePasswordManager.saveChanges - 2: " + res); return res;});
269 deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'notify', 'OTPUpdated');
270//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("OneTimePasswordManager.saveChanges - 3: " + res); return res;});
271 deferredResult.callback();
272//MochiKit.Logging.logDebug("<<< OneTimePasswordManager.saveChanges");
273
274 return deferredResult;
275 },
276
277 //-------------------------------------------------------------------------
278 __syntaxFix__: "syntax fix"
279});
280
diff --git a/frontend/beta/js/Clipperz/PM/DataModel/Record.js b/frontend/beta/js/Clipperz/PM/DataModel/Record.js
new file mode 100644
index 0000000..b4b5023
--- a/dev/null
+++ b/frontend/beta/js/Clipperz/PM/DataModel/Record.js
@@ -0,0 +1,759 @@
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.DataModel) == 'undefined') { Clipperz.PM.DataModel = {}; }
32
33
34//#############################################################################
35
36Clipperz.PM.DataModel.Record = function(args) {
37 args = args || {};
38
39 this._user = args['user'] || null;
40 this._reference = args['reference'] || Clipperz.PM.Crypto.randomKey();
41 this._version = args['version'] || Clipperz.PM.Crypto.encryptingFunctions.currentVersion;
42 this._key = args['key'] || Clipperz.PM.Crypto.randomKey();
43
44 this.setLabel(args['label'] || Clipperz.PM.Strings['newRecordTitleLabel']);
45
46 this.setHeaderNotes(args['headerNotes'] || null);
47 this.setNotes(args['notes'] || args['headerNotes'] || "");
48//MochiKit.Logging.logDebug("--- new Record ('" + this._label + "')- _headerNotes: '" + this._headerNotes + "'");
49//MochiKit.Logging.logDebug("--- new Record ('" + this._label + "')- _notes: '" + this._notes + "'");
50 //this._notes = args.notes || "";
51
52 this._versions = {};
53 this._directLogins = {};
54 this._removedDirectLogins = [];
55
56 this.setIsBrandNew(args['reference'] == null);
57
58 this.setShouldLoadData(this.isBrandNew() ? false: true);
59 this.setShouldDecryptData(this.isBrandNew() ? false: true);
60 this.setShouldProcessData(this.isBrandNew() ? false: true);
61
62 this.setCurrentVersion(this.isBrandNew() ? new Clipperz.PM.DataModel.RecordVersion(this, null): null);
63 this.setCurrentVersionKey(null);
64
65 this._serverData = null;
66 this._decryptedData = null;
67 this._cachedData = null;
68
69 return this;
70}
71
72Clipperz.PM.DataModel.Record.prototype = MochiKit.Base.update(null, {
73
74 'toString': function() {
75 return "Record (" + this.label() + ")";
76 },
77
78 //-------------------------------------------------------------------------
79
80 'isBrandNew': function() {
81 return this._isBrandNew;
82 },
83
84 'setIsBrandNew': function(aValue) {
85 this._isBrandNew = aValue;
86 },
87
88 //-------------------------------------------------------------------------
89/*
90 'shouldRunTheRecordCreationWizard': function() {
91 return (this.isBrandNew() && (MochiKit.Base.keys(this.currentVersion().fields()).length == 0));
92 },
93 */
94 //-------------------------------------------------------------------------
95
96 'user': function() {
97 return this._user;
98 },
99
100 //-------------------------------------------------------------------------
101
102 'reference': function() {
103 return this._reference;
104 },
105
106 //-------------------------------------------------------------------------
107
108 'key': function() {
109 return this._key;
110 },
111
112 'updateKey': function() {
113 this._key = Clipperz.PM.Crypto.randomKey();
114 },
115
116 //-------------------------------------------------------------------------
117
118 'label': function() {
119 return this._label;
120 },
121
122 'setLabel': function(aValue) {
123 this._label = aValue;
124 },
125
126 'lowerCaseLabel': function() {
127 return this.label().toLowerCase();
128 },
129
130 //-------------------------------------------------------------------------
131
132 'versions': function() {
133 return this._versions;
134 },
135
136 //-------------------------------------------------------------------------
137
138 'currentVersion': function() {
139 return this._currentVersion;
140 },
141
142 'setCurrentVersion': function(aValue) {
143 this._currentVersion = aValue;
144 },
145
146 //-------------------------------------------------------------------------
147
148 'currentVersionKey': function() {
149 return this._currentVersionKey;
150 },
151
152 'setCurrentVersionKey': function(aValue) {
153 this._currentVersionKey = aValue;
154 },
155
156 //-------------------------------------------------------------------------
157
158 'deferredData': function() {
159 vardeferredResult;
160
161//MochiKit.Logging.logDebug(">>> [" + (new Date()).valueOf() + "] Record.deferredData - this: " + this);
162 deferredResult = new MochiKit.Async.Deferred();
163 deferredResult.addCallback(MochiKit.Base.method(this, 'loadData'));
164 deferredResult.addCallback(MochiKit.Base.method(this, 'decryptData'));
165 deferredResult.addCallback(MochiKit.Base.method(this, 'processData'));
166 deferredResult.addCallback(function(aRecord) {
167 return aRecord.currentVersion().deferredData();
168 });
169 deferredResult.addCallback(MochiKit.Base.method(this, 'takeSnapshotOfCurrentData'));
170 deferredResult.addCallback(MochiKit.Async.succeed, this);
171 deferredResult.callback();
172//MochiKit.Logging.logDebug("<<< [" + (new Date()).valueOf() + "] Record.deferredData");
173
174 return deferredResult;
175 },
176
177 //-------------------------------------------------------------------------
178
179 'exportedData': function() {
180 var result;
181
182 result = {};
183 result['label'] = this.label();
184 result['data'] = this.serializedData();
185 result['currentVersion'] = this.currentVersion().serializedData();
186 result['currentVersion']['reference'] = this.currentVersion().reference();
187 // result['versions'] = MochiKit.Base.map(MochiKit.Base.methodcaller("serializedData"), MochiKit.Base.values(this.versions()));
188
189 return Clipperz.Base.serializeJSON(result);
190 },
191
192 //-------------------------------------------------------------------------
193
194 'shouldLoadData': function() {
195 return this._shouldLoadData;
196 },
197
198 'setShouldLoadData': function(aValue) {
199 this._shouldLoadData = aValue;
200 },
201
202 //-------------------------------------------------------------------------
203
204 'shouldDecryptData': function() {
205 return this._shouldDecryptData;
206 },
207
208 'setShouldDecryptData': function(aValue) {
209 this._shouldDecryptData = aValue;
210 },
211
212 //-------------------------------------------------------------------------
213
214 'shouldProcessData': function() {
215 return this._shouldProcessData;
216 },
217
218 'setShouldProcessData': function(aValue) {
219 this._shouldProcessData = aValue;
220 },
221
222 //-------------------------------------------------------------------------
223
224 'loadData': function() {
225 var result;
226
227//MochiKit.Logging.logDebug(">>> [" + (new Date()).valueOf() + "] Record.loadData - this: " + this);
228 if (this.shouldLoadData()) {
229 var deferredResult;
230
231 deferredResult = new MochiKit.Async.Deferred();
232 deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'notify', 'loadingRecordData');
233 deferredResult.addCallback(MochiKit.Base.method(this.user().connection(), 'message'), 'getRecordDetail', {reference: this.reference()});
234 deferredResult.addCallback(MochiKit.Base.method(this,'setServerData'));
235 deferredResult.callback();
236 result = deferredResult;
237 } else {
238 result = MochiKit.Async.succeed(this.serverData());
239 }
240//MochiKit.Logging.logDebug("<<< [" + (new Date()).valueOf() + "] Record.loadData");
241
242 return result;
243 },
244
245 //-------------------------------------------------------------------------
246
247 'decryptData': function(anEncryptedData) {
248 var result;
249
250//MochiKit.Logging.logDebug(">>> [" + (new Date()).valueOf() + "] Record.decryptData - this: " + this + " (" + anEncryptedData + ")");
251 if (this.shouldDecryptData()) {
252 var deferredResult;
253
254 deferredResult = new MochiKit.Async.Deferred();
255 deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'notify', 'decryptingRecordData');
256 deferredResult.addCallback(Clipperz.PM.Crypto.deferredDecrypt, this.key(), anEncryptedData['data'], anEncryptedData['version']);
257 deferredResult.addCallback(function(anEncryptedData, someDecryptedValues) {
258 varresult;
259
260 result = anEncryptedData;
261 result['data'] = someDecryptedValues;
262
263 return result;
264 }, anEncryptedData);
265 deferredResult.addCallback(MochiKit.Base.method(this, 'setDecryptedData'));
266 deferredResult.callback();
267
268 result = deferredResult;
269 } else {
270 result = MochiKit.Async.succeed(this.decryptedData());
271 }
272//MochiKit.Logging.logDebug("<<< [" + (new Date()).valueOf() + "] Record.decryptData");
273
274 return result;
275 },
276
277 //-------------------------------------------------------------------------
278
279 'processData': function(someValues) {
280//MochiKit.Logging.logDebug(">>> [" + (new Date()).valueOf() + "] Record.processData");
281//MochiKit.Logging.logDebug("--- Record.processData: " + Clipperz.Base.serializeJSON(someValues));
282 if (this.shouldProcessData()) {
283 var currentVersionParameters;
284
285 this.processDataToExtractLegacyValues(someValues['data']);
286
287 if (typeof(someValues['data']['notes']) != 'undefined') {
288 this.setNotes(someValues['data']['notes']);
289 }
290 if (someValues['data']['currentVersionKey'] != null) {
291 this.setCurrentVersionKey(someValues['data']['currentVersionKey']);
292 } else {
293 this.setCurrentVersionKey(this.key());
294 }
295
296 currentVersionParameters = someValues['currentVersion'];
297 currentVersionParameters['key'] = this.currentVersionKey();
298 this.setCurrentVersion(new Clipperz.PM.DataModel.RecordVersion(this, currentVersionParameters));
299
300 if (someValues['data']['directLogins'] != null) {
301 vardirectLoginReference;
302
303 for (directLoginReference in someValues['data']['directLogins']) {
304 var directLogin;
305 var directLoginParameters;
306
307 directLoginParameters = someValues['data']['directLogins'][directLoginReference];
308 directLoginParameters.record = this;
309 directLoginParameters.reference = directLoginReference;
310
311 directLogin = new Clipperz.PM.DataModel.DirectLogin(directLoginParameters);
312 this.addDirectLogin(directLogin, true);
313 }
314 }
315 this.setShouldProcessData(false);
316 }
317
318 Clipperz.NotificationCenter.notify(this, 'recordDataReady');
319//MochiKit.Logging.logDebug("<<< [" + (new Date()).valueOf() + "] Record.processData");
320//MochiKit.Logging.logDebug("<<< Record.processData");
321
322 return this;
323 },
324
325 //-------------------------------------------------------------------------
326
327 'processDataToExtractLegacyValues': function(someValues) {
328//MochiKit.Logging.logDebug(">>> Record.processDataToExtractLegacyValues");
329 if (someValues['data'] != null) {
330 this.setNotes(someValues['data']);
331 }
332
333 if (
334 (typeof(someValues['loginFormData']) != "undefined")
335 &&(typeof(someValues['loginBindings'] != "undefined"))
336 &&(someValues['loginFormData'] != "")
337 &&(someValues['loginBindings'] != "")
338 ) {
339 vardirectLogin;
340
341 directLogin = new Clipperz.PM.DataModel.DirectLogin({
342 record:this,
343 label:this.label() + Clipperz.PM.Strings['newDirectLoginLabelSuffix'],
344 reference:Clipperz.Crypto.SHA.sha256(new Clipperz.ByteArray(this.label() +
345 someValues['loginFormData'] +
346 someValues['loginBindings'])).toHexString().substring(2),
347 formData:Clipperz.Base.evalJSON(someValues['loginFormData']),
348 legacyBindingData:Clipperz.Base.evalJSON(someValues['loginBindings']),
349 bookmarkletVersion:'0.1'
350 });
351 this.addDirectLogin(directLogin, true);
352 }
353//MochiKit.Logging.logDebug("<<< Record.processDataToExtractLegacyValues");
354 },
355
356 //-------------------------------------------------------------------------
357
358 'getReadyBeforeUpdatingVersionValues': function() {
359 },
360
361 //-------------------------------------------------------------------------
362
363 'addNewField': function() {
364 varnewField;
365
366//MochiKit.Logging.logDebug(">>> Record.addNewField - " + this);
367 this.getReadyBeforeUpdatingVersionValues();
368 newField = this.currentVersion().addNewField();
369 Clipperz.NotificationCenter.notify(this, 'recordUpdated');
370//MochiKit.Logging.logDebug("<<< Record.addNewField");
371
372 return newField;
373 },
374
375 //-------------------------------------------------------------------------
376
377 'removeField': function(aField) {
378 this.getReadyBeforeUpdatingVersionValues();
379 this.currentVersion().removeField(aField);
380 Clipperz.NotificationCenter.notify(this, 'recordUpdated');
381 },
382
383 'removeEmptyFields': function() {
384 MochiKit.Iter.forEach(MochiKit.Base.values(this.currentVersion().fields()), MochiKit.Base.bind(function(aField) {
385 if (aField.isEmpty()) {
386 this.removeField(aField);
387 // this.currentVersion().removeField(aField);
388 }
389 }, this));
390 },
391
392 //-------------------------------------------------------------------------
393
394 'notes': function() {
395 return this._notes;
396 },
397
398 'setNotes': function(aValue) {
399 this._notes = aValue;
400 this.setHeaderNotes(null);
401 },
402
403 //-------------------------------------------------------------------------
404
405 'headerNotes': function() {
406 return this._headerNotes;
407 },
408
409 'setHeaderNotes': function(aValue) {
410 this._headerNotes = aValue;
411 },
412
413 //-------------------------------------------------------------------------
414
415 'remove': function() {
416//MochiKit.Logging.logDebug(">>> Record.remove - " + this);
417 MochiKit.Iter.forEach(MochiKit.Base.values(this.directLogins()), MochiKit.Base.method(this, 'removeDirectLogin'));
418
419 this.syncDirectLoginReferenceValues();
420 this.user().removeRecord(this);
421//MochiKit.Logging.logDebug("<<< Record.remove");
422 },
423
424 //-------------------------------------------------------------------------
425
426 'directLogins': function() {
427 return this._directLogins;
428 },
429
430 'addDirectLogin': function(aDirectLogin, shouldUpdateUser) {
431 this.directLogins()[aDirectLogin.reference()] = aDirectLogin;
432 if (shouldUpdateUser == true) {
433 this.user().addDirectLogin(aDirectLogin);
434 }
435 },
436
437 'removeDirectLogin': function(aDirectLogin) {
438 this.removedDirectLogins().push(aDirectLogin);
439 delete this.directLogins()[aDirectLogin.reference()];
440 // this.user().removeDirectLogin(aDirectLogin);
441 },
442
443 'resetDirectLogins': function() {
444 this._directLogins = {};
445 },
446
447 'removedDirectLogins': function() {
448 return this._removedDirectLogins;
449 },
450
451 'resetRemovedDirectLogins': function() {
452 this._removedDirectLogins = [];
453 },
454
455 //-------------------------------------------------------------------------
456
457 'serverData': function() {
458 return this._serverData;
459 },
460
461 'setServerData': function(aValue) {
462 this._serverData = aValue;
463 this.setShouldLoadData(false);
464 return aValue;
465 },
466
467 //-------------------------------------------------------------------------
468
469 'decryptedData': function() {
470 return this._decryptedData;
471 },
472
473 'setDecryptedData': function(aValue) {
474 this._decryptedData = aValue;
475 this.setShouldDecryptData(false);
476 return aValue;
477 },
478
479 //-------------------------------------------------------------------------
480
481 'cachedData': function() {
482 return this._cachedData;
483 },
484
485 'setCachedData': function(aValue) {
486//MochiKit.Logging.logDebug(">>> Record.setCachedData");
487//MochiKit.Logging.logDebug("--- Record.setCachedData - aValue: " + Clipperz.Base.serializeJSON(aValue));
488 this._cachedData = aValue;
489 this.setShouldProcessData(false);
490//MochiKit.Logging.logDebug("<<< Record.setCachedData");
491
492 return aValue;
493 },
494
495 //-------------------------------------------------------------------------
496
497 'hasPendingChanges': function() {
498 var result;
499
500//MochiKit.Logging.logDebug(">>> [" + (new Date()).valueOf() + "] Record.hasPendingChanges");
501//MochiKit.Logging.logDebug(">>> Record.hasPendingChanges - cachedData: " + this.cachedData());
502//MochiKit.Logging.logDebug(">>> Record.hasPendingChanges - cachedData: " + Clipperz.Base.serializeJSON(this.cachedData()));
503//MochiKit.Logging.logDebug(">>> Record.hasPendingChanges - currentSnapshot: " + this.currentDataSnapshot());
504//MochiKit.Logging.logDebug(">>> Record.hasPendingChanges - currentSnapshot: " + Clipperz.Base.serializeJSON(this.currentDataSnapshot()));
505//console.log(">>> Record.hasPendingChanges - cachedData: %o", this.cachedData());
506//console.log(">>> Record.hasPendingChanges - currentSnapshot: %o", this.currentDataSnapshot());
507 result = (MochiKit.Base.compare(this.cachedData(), this.currentDataSnapshot()) != 0);
508//MochiKit.Logging.logDebug("<<< Record.hasPendingChanges - " + result);
509
510 if ((result == false) && this.isBrandNew() && (this.label() != Clipperz.PM.Strings['newRecordTitleLabel'])) {
511 result = true;
512 }
513//MochiKit.Logging.logDebug("<<< [" + (new Date()).valueOf() + "] Record.hasPendingChanges");
514
515 return result;
516 },
517
518 //-------------------------------------------------------------------------
519
520 'currentDataSnapshot': function() {
521 varresult;
522
523//MochiKit.Logging.logDebug(">>> [" + (new Date()).valueOf() + "] Record.currentDataSnapshot");
524 result = {
525 'label': this.label(),
526 'data': this.serializedData(),
527 'currentVersion': this.currentVersion().currentDataSnapshot()
528 };
529
530 // result['data']['data'] = this.notes();
531 result = Clipperz.Base.serializeJSON(result);
532
533//MochiKit.Logging.logDebug("<<< [" + (new Date()).valueOf() + "] Record.currentDataSnapshot");
534//MochiKit.Logging.logDebug("<<< Record.currentDataSnapshot");
535
536 return result;
537 },
538
539 //.........................................................................
540
541 'takeSnapshotOfCurrentData': function() {
542 this.setCachedData(this.currentDataSnapshot());
543 },
544
545 //-------------------------------------------------------------------------
546
547 'headerData': function() {
548 var result;
549
550 result = {
551 'label': this.label(),
552 'key': this.key()
553 };
554
555 if (this.headerNotes() != null) {
556 result['headerNotes'] = this.headerNotes();
557 }
558
559 return result;
560 },
561
562 //-------------------------------------------------------------------------
563
564 'serializedData': function() {
565 var result;
566 var directLoginReference;
567
568 result = {};
569 result['currentVersionKey'] = this.currentVersion().key();
570
571 result['directLogins'] = {};
572 for (directLoginReference in this.directLogins()) {
573 result['directLogins'][directLoginReference] = this.directLogins()[directLoginReference].serializedData();
574 }
575 result['notes'] = this.notes();
576
577 return result;
578 },
579
580 //-------------------------------------------------------------------------
581
582 'encryptedData': function() {
583 var deferredResult;
584 varresult;
585
586//MochiKit.Logging.logDebug(">>> [" + (new Date()).valueOf() + "] Record.encryptedData");
587 result = {}
588//MochiKit.Logging.logDebug("--- Record.encryptedData - 1");
589 deferredResult = new MochiKit.Async.Deferred();
590//MochiKit.Logging.logDebug("--- Record.encryptedData - 2");
591//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Record.encryptedData - 1: " + res); return res;});
592 deferredResult.addCallback(function(aResult, aRecord) {
593 aResult['reference'] = aRecord.reference();
594 return aResult;
595 }, result, this);
596//MochiKit.Logging.logDebug("--- Record.encryptedData - 3");
597//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Record.encryptedData - 2: " + res); return res;});
598 deferredResult.addCallback(Clipperz.PM.Crypto.deferredEncryptWithCurrentVersion, this.key(), this.serializedData());
599//MochiKit.Logging.logDebug("--- Record.encryptedData - 4");
600//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Record.encryptedData - 3: " + res); return res;});
601 deferredResult.addCallback(function(aResult, res) {
602 aResult['data'] = res;
603 return aResult;
604 }, result);
605//MochiKit.Logging.logDebug("--- Record.encryptedData - 5");
606//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Record.encryptedData - 4: " + res); return res;});
607 deferredResult.addCallback(function(aResult) {
608 aResult['version'] = Clipperz.PM.Crypto.encryptingFunctions.currentVersion;
609 return aResult;
610 }, result);
611//MochiKit.Logging.logDebug("--- Record.encryptedData - 6");
612//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Record.encryptedData - 5: " + res); return res;});
613 deferredResult.callback();
614//MochiKit.Logging.logDebug("<<< [" + (new Date()).valueOf() + "] Record.encryptedData");
615
616 return deferredResult;
617 },
618
619 //-------------------------------------------------------------------------
620
621 'syncDirectLoginReferenceValues': function() {
622//MochiKit.Logging.logDebug(">>> Record.syncDirectLoginReferenceValues");
623 MochiKit.Iter.forEach(MochiKit.Base.values(this.directLogins()), function(aDirectLogin) {
624 aDirectLogin.record().user().synchronizeDirectLogin(aDirectLogin);
625 });
626
627 MochiKit.Iter.forEach(this.removedDirectLogins(), function(aDirectLogin) {
628 aDirectLogin.record().user().removeDirectLogin(aDirectLogin);
629 });
630
631 this.resetRemovedDirectLogins();
632//MochiKit.Logging.logDebug("<<< Record.syncDirectLoginReferenceValues");
633 },
634
635 //-------------------------------------------------------------------------
636
637 'saveChanges': function() {
638 var result;
639
640 if (this.isBrandNew() == false) {
641 result = this.user().saveRecords([this], 'updateData');
642 } else {
643 result = this.user().saveRecords([this], 'addNewRecords');
644 }
645
646 return result;
647 },
648
649/*
650 'saveChanges': function() {
651 var deferredResult;
652 varresult;
653
654 Clipperz.NotificationCenter.notify(this.user(), 'updatedSection', 'records', true);
655//MochiKit.Logging.logDebug(">>> Record.saveChanges");
656//MochiKit.Logging.logDebug(">>> [" + (new Date()).valueOf() + "] Record.saveChanges");
657 if (this.headerNotes() != null) {
658 this.setNotes(this.headerNotes());
659 }
660 this.syncDirectLoginReferenceValues();
661 this.currentVersion().createNewVersion();
662
663 result = {'records': [{}]};
664
665 deferredResult = new MochiKit.Async.Deferred();
666 deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'saveCard_collectRecordInfo');
667 deferredResult.addCallback(MochiKit.Base.method(this, 'updateKey'));
668
669 deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'saveCard_encryptUserData');
670 deferredResult.addCallback(MochiKit.Base.method(this.user(), 'encryptedData'));
671 deferredResult.addCallback(function(aResult, res) {
672 aResult['user'] = res;
673 return aResult;
674 }, result);
675
676 deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'saveCard_encryptRecordData');
677 deferredResult.addCallback(MochiKit.Base.method(this, 'encryptedData'));
678 deferredResult.addCallback(function(aResult, res) {
679 //# aResult['record'] = res;
680 aResult['records'][0]['record'] = res;
681 return aResult;
682 }, result);
683
684 deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'saveCard_encryptRecordVersions');
685 deferredResult.addCallback(MochiKit.Base.method(this.currentVersion(), 'encryptedData'));
686 deferredResult.addCallback(function(aResult, res) {
687 // aResult['currentRecordVersion'] = res;
688 aResult['records'][0]['currentRecordVersion'] = res;
689 return aResult;
690 }, result);
691
692 deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'saveCard_sendingData');
693 if (this.isBrandNew() == false) {
694 deferredResult.addCallback(MochiKit.Base.method(this.user().connection(), 'message'), 'updateData');
695 } else {
696 //# deferredResult.addCallback(MochiKit.Base.method(this.user().connection(), 'message'), 'addNewRecord');
697 deferredResult.addCallback(MochiKit.Base.method(this.user().connection(), 'message'), 'addNewRecords');
698 }
699
700 deferredResult.addCallback(MochiKit.Base.method(this, 'takeSnapshotOfCurrentData'));
701 deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'saveCard_updatingInterface');
702 deferredResult.addCallback(MochiKit.Base.method(this, 'setIsBrandNew'), false);
703 deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'notify', 'recordUpdated');
704 deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'notify', 'directLoginUpdated');
705 deferredResult.callback();
706
707 return deferredResult;
708 },
709 */
710 //-------------------------------------------------------------------------
711
712 'cancelChanges': function() {
713//MochiKit.Logging.logDebug(">>> Record.cancelChanges");
714//MochiKit.Logging.logDebug("--- Record.cancelChanges - cachedData: " + Clipperz.Base.serializeJSON(this.cachedData()));
715 if (this.isBrandNew()) {
716 this.user().removeRecord(this);
717 } else {
718 this.restoreValuesFromSnapshot(this.cachedData());
719 }
720//MochiKit.Logging.logDebug("<<< Record.cancelChanges");
721 },
722
723 //-------------------------------------------------------------------------
724
725 'restoreValuesFromSnapshot': function(someSnapshotData) {
726 varsnapshotData;
727
728//MochiKit.Logging.logDebug(">>> [" + (new Date()).valueOf() + "] Record.restoreValuesFromSnapshot");
729 snapshotData = Clipperz.Base.evalJSON(someSnapshotData);
730//MochiKit.Logging.logDebug("--- Record.restoreValuesFromSnapshot - someSnapshotData (1): " + Clipperz.Base.serializeJSON(someSnapshotData));
731 this.setLabel(snapshotData['label']);
732 this.resetDirectLogins();
733 this.setShouldProcessData(true);
734 this.processData(snapshotData);
735//MochiKit.Logging.logDebug("--- Record.restoreValuesFromSnapshot - snapshotData: (2)" + Clipperz.Base.serializeJSON(snapshotData));
736
737 this.resetRemovedDirectLogins();
738
739 {
740 var currentSnapshot;
741 varcomparisonResult;
742
743 currentSnapshot = this.currentDataSnapshot();
744//MochiKit.Logging.logDebug("--- Record.restoreValuesFromSnapshot - 1");
745//console.log("snapshot data: %o", someSnapshotData.currentVersion);
746//console.log("current data: %o", currentSnapshot.currentVersion);
747//MochiKit.Logging.logDebug("--- Record.restoreValuesFromSnapshot - someSnapshotData: " + Clipperz.Base.serializeJSON(someSnapshotData.currentVersion));
748//MochiKit.Logging.logDebug("--- Record.restoreValuesFromSnapshot - currentSnapshot: " + Clipperz.Base.serializeJSON(currentSnapshot.currentVersion));
749 comparisonResult = MochiKit.Base.compare(someSnapshotData.currentVersion, currentSnapshot.currentVersion);
750//MochiKit.Logging.logDebug("--- Record.restoreValuesFromSnapshot - " + comparisonResult);
751 }
752//MochiKit.Logging.logDebug("<<< [" + (new Date()).valueOf() + "] Record.restoreValuesFromSnapshot");
753 },
754
755 //-------------------------------------------------------------------------
756 __syntaxFix__: "syntax fix"
757});
758
759
diff --git a/frontend/beta/js/Clipperz/PM/DataModel/RecordField.js b/frontend/beta/js/Clipperz/PM/DataModel/RecordField.js
new file mode 100644
index 0000000..2063825
--- a/dev/null
+++ b/frontend/beta/js/Clipperz/PM/DataModel/RecordField.js
@@ -0,0 +1,220 @@
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.DataModel) == 'undefined') { Clipperz.PM.DataModel = {}; }
32
33//#############################################################################
34
35Clipperz.PM.DataModel.RecordField = function(args) {
36 args = args || {};
37
38 this._recordVersion = args.recordVersion || null;
39 this._key = args.key || Clipperz.PM.Crypto.randomKey();
40 this.setLabel(args.label || '');
41 this.setValue(args.value || '');
42 this.setType(args.type || 'TXT'); //valid types: 'TXT', 'PWD', 'URL', 'DATE', 'ADDR', 'CHECK', 'RADIO', ('NOTE' probably not), ...
43 this._hidden = args.hidden || (args.type == 'PWD') || false;
44
45 return this;
46}
47
48Clipperz.PM.DataModel.RecordField.prototype = MochiKit.Base.update(null, {
49
50 'toString': function() {
51 return "Clipperz.PM.DataModel.RecordField - " + this.label() + " (" + this.key() + ")";
52 },
53
54 //-------------------------------------------------------------------------
55
56 'recordVersion': function() {
57 return this._recordVersion;
58 },
59
60 //-------------------------------------------------------------------------
61
62 'key': function() {
63 return this._key;
64 },
65
66 //-------------------------------------------------------------------------
67
68 'label': function() {
69 return this._label;
70 },
71
72 'setLabel': function(aValue) {
73 this._label = aValue;
74 },
75
76 //-------------------------------------------------------------------------
77
78 'value': function() {
79 return this._value;
80 },
81
82 'setValue': function(aValue) {
83 this._value = aValue;
84 },
85
86 //-------------------------------------------------------------------------
87
88 'type': function() {
89 return this._type;
90 },
91
92 'setType': function(aValue) {
93 this._type = aValue;
94
95 if (aValue == 'PWD') {
96 this.setHidden(true);
97 } else {
98 this.setHidden(false);
99 }
100 },
101
102 //-------------------------------------------------------------------------
103
104 'serializeData': function() {
105 var result;
106
107//MochiKit.Logging.logDebug(">>> RecordField.serializeData - " + this);
108 result = {
109 label: this.label(),
110 value:this.value(),
111 type: this.type(),
112 hidden: this.hidden()
113 };
114//MochiKit.Logging.logDebug("<<< RecordField.serializeData");
115
116 return result;
117 },
118
119 //-------------------------------------------------------------------------
120
121 'typeShortDescription': function() {
122 // return Clipperz.PM.DataModel.RecordField.TypeDescriptions[this.type()]['shortDescription'];
123 return Clipperz.PM.Strings['recordFieldTypologies'][this.type()]['shortDescription'];
124 },
125
126 //-------------------------------------------------------------------------
127
128 'hidden': function() {
129 return this._hidden;
130 },
131
132 'setHidden': function(aValue) {
133 this._hidden = aValue;
134 },
135
136 //-------------------------------------------------------------------------
137
138 'clone': function(aRecordVersion) {
139 var result;
140
141 result = new Clipperz.PM.DataModel.RecordField({
142 recordVersion:aRecordVersion,
143 label:this.label(),
144 value:this.value(),
145 type:this.type(),
146 hidden:this.hidden()
147 });
148
149 return result;
150 },
151
152 //-------------------------------------------------------------------------
153
154 'isEmpty': function() {
155 var result;
156
157 if ((this.label() == "") && (this.value() == "") && (this.type() == 'TXT')) {
158 result = true;
159 } else {
160 result = false;
161 }
162
163 return result;
164 },
165
166 //-------------------------------------------------------------------------
167 __syntaxFix__: "syntax fix"
168
169});
170
171//#############################################################################
172/*
173Clipperz.PM.DataModel.RecordField.TypeDescriptions = {
174 'TXT': {
175 description: 'simple text field',
176 shortDescription: 'txt'
177 },
178 'PWD': {
179 description: 'simple text field, with default status set to hidden',
180 shortDescription: 'pwd'
181 },
182 'URL': {
183 description: 'simple text field in edit mode, that became an active url in view mode',
184 shortDescription: 'url'
185 },
186 'DATE': {
187 description: 'a value set with a calendar helper',
188 shortDescription: 'date'
189 },
190 'ADDR': {
191 description: 'just like the URL, but the active link points to Google Maps (or similar service) passing the address value as argument',
192 shortDescription: 'addr'
193 },
194 'CHECK': {
195 description: 'check description',
196 shortDescription: 'check'
197 },
198 'RADIO': {
199 description: 'radio description',
200 shortDescription: 'radio'
201 },
202 'SELECT': {
203 description: 'select description',
204 shortDescription: 'select'
205 }
206
207 //'NOTE': {
208 // description: 'a simple text field, but with a bigger component dimension; possibly with "smart edit components"',
209 // shortDescription: 'note'
210 //}
211};
212
213Clipperz.PM.DataModel.RecordField.InputTypeToRecordFieldType = {
214 'text': 'TXT',
215 'password': 'PWD',
216 'checkbox': 'CHECK',
217 'radio': 'RADIO',
218 'select': 'SELECT'
219};
220*/
diff --git a/frontend/beta/js/Clipperz/PM/DataModel/RecordVersion.js b/frontend/beta/js/Clipperz/PM/DataModel/RecordVersion.js
new file mode 100644
index 0000000..d2b3e12
--- a/dev/null
+++ b/frontend/beta/js/Clipperz/PM/DataModel/RecordVersion.js
@@ -0,0 +1,535 @@
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.DataModel) == 'undefined') { Clipperz.PM.DataModel = {}; }
32
33
34//#############################################################################
35
36Clipperz.PM.DataModel.RecordVersion = function(aRecord, args) {
37 args = args || {};
38
39 this._record = aRecord;
40
41 this._reference = args.reference || Clipperz.PM.Crypto.randomKey();
42 this._version = args.version || Clipperz.PM.Crypto.encryptingFunctions.currentVersion;
43 this._key = args.key || Clipperz.PM.Crypto.randomKey();;
44
45 this._previousVersion = args.previousVersion || null;
46 this._previousVersionKey = args.previousVersionKey || null;
47
48 this.setIsBrandNew(args.reference == null);
49
50 if (this.isBrandNew()) {
51 this._fields = {};
52
53 this.setShouldLoadData(false);
54 this.setShouldDecryptData(false);
55 this.setShouldProcessData(false);
56 } else {
57 if (typeof(args.fields) != 'undefined') {
58 this.processFieldData(args.fields);
59
60 this.setShouldLoadData(false);
61 this.setShouldDecryptData(false);
62 this.setShouldProcessData(false);
63 } else {
64 if (typeof(args.data) != 'undefined') {
65 this.setShouldLoadData(false);
66 } else {
67 this.setShouldLoadData(true);
68 }
69 this.setShouldDecryptData(true);
70 this.setShouldProcessData(true);
71 }
72 }
73
74 this._serverData = args.data;
75 this._decryptedData = null;
76
77 return this;
78}
79
80Clipperz.PM.DataModel.RecordVersion.prototype = MochiKit.Base.update(null, {
81
82 'toString': function() {
83 return "RecordVersion";
84 },
85
86 //-------------------------------------------------------------------------
87
88 'record': function() {
89 return this._record;
90 },
91
92 //-------------------------------------------------------------------------
93
94 'reference': function() {
95 return this._reference;
96 },
97
98 'setReference': function(aValue) {
99 this._reference = aValue;
100 },
101
102 //-------------------------------------------------------------------------
103
104 'key': function() {
105//MochiKit.Logging.logDebug(">>> RecordVersion.key");
106//MochiKit.Logging.logDebug("--- RecordVersion.key - " + this._key);
107 return this._key;
108 },
109
110 'setKey': function(aValue) {
111 this._key = aValue;
112 },
113
114 //-------------------------------------------------------------------------
115
116 'serverData': function() {
117 return this._serverData;
118 },
119
120 'setServerData': function(aValue) {
121 this._serverData = aValue;
122 this.setShouldLoadData(false);
123 return aValue;
124 },
125
126 //-------------------------------------------------------------------------
127
128 'decryptedData': function() {
129//MochiKit.Logging.logDebug(">>> RecordVersion.decryptedData: " + (this._decryptedData ? Clipperz.Base.serializeJSON(aValue) : "null"));
130 return this._decryptedData;
131 },
132
133 'setDecryptedData': function(aValue) {
134//MochiKit.Logging.logDebug(">>> RecordVersion.setDecryptedData: " + Clipperz.Base.serializeJSON(aValue));
135 this._decryptedData = aValue;
136 this.setShouldDecryptData(false);
137 return aValue;
138 },
139
140 //-------------------------------------------------------------------------
141
142 'version': function() {
143 return this._version;
144 },
145
146 //-------------------------------------------------------------------------
147
148 'isBrandNew': function() {
149 return this._isBrandNew;
150 },
151
152 'setIsBrandNew': function(aValue) {
153 this._isBrandNew = aValue;
154 },
155
156 //-------------------------------------------------------------------------
157
158 'fields': function() {
159 return this._fields;
160 },
161
162 'addField': function(aField) {
163 this.fields()[aField.key()] = aField;
164 },
165
166 'addNewField': function() {
167 varnewRecordField;
168
169 newRecordField = new Clipperz.PM.DataModel.RecordField({recordVersion:this});
170 this.addField(newRecordField);
171
172 return newRecordField;
173 },
174
175 'fieldWithName': function(aValue) {
176 varresult;
177 var fieldValues;
178 var i,c;
179
180 result = null;
181 fieldValues = MochiKit.Base.values(this.fields());
182 c = fieldValues.length;
183 for (i=0; (i<c) && (result == null); i++) {
184 varcurrentField;
185
186 currentField = fieldValues[i];
187 if (currentField.label() == aValue) {
188 result = currentField;
189 }
190 }
191
192 return result;
193 },
194
195 //-------------------------------------------------------------------------
196
197 'shouldLoadData': function() {
198 return this._shouldLoadData;
199 },
200
201 'setShouldLoadData': function(aValue) {
202 this._shouldLoadData = aValue;
203 },
204
205 //-------------------------------------------------------------------------
206
207 'shouldDecryptData': function() {
208 return this._shouldDecryptData;
209 },
210
211 'setShouldDecryptData': function(aValue) {
212 this._shouldDecryptData = aValue;
213 },
214
215 //-------------------------------------------------------------------------
216
217 'shouldProcessData': function() {
218 return this._shouldProcessData;
219 },
220
221 'setShouldProcessData': function(aValue) {
222 this._shouldProcessData = aValue;
223 },
224
225 //-------------------------------------------------------------------------
226
227 'deferredData': function() {
228 var deferredResult;
229
230//MochiKit.Logging.logDebug(">>> RecordVersion.deferredData - this: " + this);
231 deferredResult = new MochiKit.Async.Deferred();
232 deferredResult.addCallback(MochiKit.Base.method(this, 'loadData'));
233 deferredResult.addCallback(MochiKit.Base.method(this, 'decryptData'));
234 deferredResult.addCallback(MochiKit.Base.method(this, 'processData'));
235 deferredResult.callback();
236//MochiKit.Logging.logDebug("<<< RecordVersion.deferredData");
237
238 return deferredResult;
239 },
240
241 //-------------------------------------------------------------------------
242
243 'loadData': function() {
244 var result;
245
246//MochiKit.Logging.logDebug(">>> RecordVersion.loadData - this: " + this);
247 if (this.shouldLoadData()) {
248 var deferredResult;
249
250 alert("ERROR: this should have not happened yet!");
251//MochiKit.Logging.logDebug("--- RecordVersion.loadData - 1");
252 deferredResult = new MochiKit.Async.Deferred();
253//MochiKit.Logging.logDebug("--- RecordVersion.loadData - 2");
254 deferredResult.addCallback(MochiKit.Base.method(this, 'notify'), 'loadingRecordVersionData');
255//MochiKit.Logging.logDebug("--- RecordVersion.loadData - 3");
256 deferredResult.addCallback(MochiKit.Base.method(this.user().connection(), 'message'), 'getRecordVersionDetail', {reference: this.reference()});
257//MochiKit.Logging.logDebug("--- RecordVersion.loadData - 4");
258 deferredResult.addCallback(MochiKit.Base.method(this, 'setServerData'));
259//MochiKit.Logging.logDebug("--- RecordVersion.loadData - 5");
260 deferredResult.callback();
261//MochiKit.Logging.logDebug("--- RecordVersion.loadData - 6");
262 result = deferredResult;
263//MochiKit.Logging.logDebug("--- RecordVersion.loadData - 7");
264 } else {
265//MochiKit.Logging.logDebug("--- RecordVersion.loadData - 8");
266 result = MochiKit.Async.succeed(this.serverData());
267//MochiKit.Logging.logDebug("--- RecordVersion.loadData - 9");
268 }
269//MochiKit.Logging.logDebug("<<< RecordVersion.loadData");
270
271 return result;
272 },
273
274 //-------------------------------------------------------------------------
275
276 'decryptData': function(anEncryptedData) {
277 var result;
278
279//MochiKit.Logging.logDebug(">>> RecordVersion.decryptData - this: " + this + " (" + anEncryptedData + ")");
280 if (this.shouldDecryptData()) {
281 var deferredResult;
282
283//MochiKit.Logging.logDebug("--- RecordVersion.decryptData - 1");
284 deferredResult = new MochiKit.Async.Deferred();
285//MochiKit.Logging.logDebug("--- RecordVersion.decryptData - 2");
286//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("RecordVersion.decryptData 1: " + res); return res;});
287 deferredResult.addCallback(MochiKit.Base.method(this, 'notify'), 'decryptingRecordVersionData');
288//MochiKit.Logging.logDebug("--- RecordVersion.decryptData - 3");
289//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("RecordVersion.decryptData 2: " + res); return res;});
290 deferredResult.addCallback(Clipperz.PM.Crypto.deferredDecrypt, this.key(), anEncryptedData, this.version());
291//MochiKit.Logging.logDebug("--- RecordVersion.decryptData - 4");
292//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("RecordVersion.decryptData 3: " + res); return res;});
293//MochiKit.Logging.logDebug("--- RecordVersion.decryptData - 5");
294//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("RecordVersion.decryptData 4: " + res); return res;});
295 deferredResult.addCallback(MochiKit.Base.method(this, 'setDecryptedData'));
296//MochiKit.Logging.logDebug("--- RecordVersion.decryptData - 6");
297//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("RecordVersion.decryptData 5: " + res); return res;});
298 deferredResult.callback();
299//MochiKit.Logging.logDebug("--- RecordVersion.decryptData - 7");
300 result = deferredResult;
301//MochiKit.Logging.logDebug("--- RecordVersion.decryptData - 8");
302 } else {
303//MochiKit.Logging.logDebug("--- RecordVersion.decryptData - 9");
304 result = MochiKit.Async.succeed(this.decryptedData());
305//MochiKit.Logging.logDebug("--- RecordVersion.decryptData - 10");
306 }
307//MochiKit.Logging.logDebug("<<< RecordVersion.decryptData");
308
309 return result;
310 },
311
312 //-------------------------------------------------------------------------
313
314 'processFieldData': function(someValues) {
315 var fieldValues;
316
317 this._fields = {};
318
319 if (typeof(someValues) == 'undefined') {
320 fieldValues = {};
321 } else {
322 fieldValues = someValues;
323 }
324
325 if (fieldValues.constructor == Array) {
326 var i, c;
327 c = fieldValues.length;
328 for (i=0; i<c; i++) {
329 var newRecordField;
330 var currentFieldValues;
331
332 currentFieldValues = fieldValues[i];
333 currentFieldValues['recordVersion'] = this;
334 newRecordField = new Clipperz.PM.DataModel.RecordField(currentFieldValues);
335 this._fields[newRecordField.key()] = newRecordField;
336 }
337
338 } else {
339 var fieldKey;
340
341 for (fieldKey in fieldValues) {
342 var newRecordField;
343 var currentFieldValues;
344
345 currentFieldValues = fieldValues[fieldKey];
346 currentFieldValues['key'] = fieldKey;
347 currentFieldValues['recordVersion'] = this;
348 newRecordField = new Clipperz.PM.DataModel.RecordField(currentFieldValues);
349 this._fields[fieldKey] = newRecordField;
350 }
351 }
352
353 },
354
355 'processData': function(someValues) {
356 if (this.shouldProcessData()) {
357 this.processFieldData(someValues.fields);
358 this.setShouldProcessData(false);
359 }
360
361 this.notify('recordVersionDataReady');
362
363 return this;
364 },
365
366 //-------------------------------------------------------------------------
367
368 'notify': function(aValue) {
369 Clipperz.NotificationCenter.notify(this, aValue);
370 },
371
372 //-------------------------------------------------------------------------
373
374 'removeField': function(aField) {
375 delete this.fields()[aField.key()];
376 },
377
378 //-------------------------------------------------------------------------
379
380 'previousVersion': function() {
381 return this._previousVersion;
382 },
383
384 'setPreviousVersion': function(aValue) {
385 this._previousVersion = aValue;
386 },
387
388 //-------------------------------------------------------------------------
389
390 'previousVersionKey': function() {
391 return this._previousVersionKey;
392 },
393
394 'setPreviousVersionKey': function(aValue) {
395 this._previousVersionKey = aValue;
396 },
397
398 //-------------------------------------------------------------------------
399
400 'serializedData': function() {
401 var result;
402 varfieldKey;
403
404//MochiKit.Logging.logDebug(">>> RecordVersion.serializedData");
405 result = {
406 fields: {}
407 };
408//MochiKit.Logging.logDebug("--- RecordVersion.serializedData - 1");
409
410 for (fieldKey in this.fields()) {
411//MochiKit.Logging.logDebug("--- RecordVersion.serializedData - 2");
412 result.fields[fieldKey] = this.fields()[fieldKey].serializeData();
413//MochiKit.Logging.logDebug("--- RecordVersion.serializedData - 3");
414 }
415//MochiKit.Logging.logDebug("--- RecordVersion.serializedData - 4");
416//MochiKit.Logging.logDebug("<<< RecordVersion.serializedData: " + Clipperz.Base.serializeJSON(result));
417
418 return result;
419 },
420
421 'currentDataSnapshot': function() {
422 var result;
423
424 result = this.serializedData();
425 result['version'] = this.version();
426 result['reference'] = this.reference();
427 result['previousVersionKey'] = this.previousVersionKey();
428
429 return result;
430 },
431
432 //-------------------------------------------------------------------------
433
434 'encryptedData': function() {
435 var deferredResult;
436 var result;
437
438//MochiKit.Logging.logDebug(">>> RecordVersion.encryptedData - " + this);
439 result = {};
440 deferredResult = new MochiKit.Async.Deferred();
441//MochiKit.Logging.logDebug("--- RecordVersion.encryptedData - 1");
442//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("RecordVersion.encryptedData - 1: " + res); return res;});
443 deferredResult.addCallback(function(aResult, aRecordVersion) {
444 aResult['reference'] = aRecordVersion.reference();
445 aResult['recordReference'] = aRecordVersion.record().reference();// TODO - this seems to be completely useless
446 return aResult;
447 }, result, this);
448//MochiKit.Logging.logDebug("--- RecordVersion.encryptedData - 2");
449//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("RecordVersion.encryptedData - 2: " + res); return res;});
450 deferredResult.addCallback(Clipperz.PM.Crypto.deferredEncryptWithCurrentVersion, this.key(), this.serializedData());
451//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("RecordVersion.encryptedData - 3: " + res); return res;});
452 deferredResult.addCallback(function(aResult, res) {
453 aResult['data'] = res;
454 return aResult;
455 }, result);
456//MochiKit.Logging.logDebug("--- RecordVersion.encryptedData - 3");
457//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("RecordVersion.encryptedData - 4: " + res); return res;});
458 deferredResult.addCallback(function(aResult) {
459 aResult['version'] = Clipperz.PM.Crypto.encryptingFunctions.currentVersion;
460 return aResult;
461 }, result);
462//MochiKit.Logging.logDebug("--- RecordVersion.encryptedData - 4");
463 if (this.previousVersion() != null) {
464//MochiKit.Logging.logDebug("--- RecordVersion.encryptedData - 5");
465//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("RecordVersion.encryptedData - 5: " + res); return res;});
466 deferredResult.addCallback(function(aResult, aRecordVersion) {
467 aResult['previousVersion'] = aRecordVersion.previousVersion();
468 return aResult;
469 }, result, this);
470//MochiKit.Logging.logDebug("--- RecordVersion.encryptedData - 6");
471//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("RecordVersion.encryptedData - 6: " + res); return res;});
472 deferredResult.addCallback(Clipperz.PM.Crypto.deferredEncryptWithCurrentVersion, this.key(), this.previousVersionKey());
473//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("RecordVersion.encryptedData - 7: " + res); return res;});
474 deferredResult.addCallback(function(aResult, res) {
475 aResult['previousVersionKey'] = res;
476 return aResult;
477 }, result);
478//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("RecordVersion.encryptedData - 8: " + res); return res;});
479//MochiKit.Logging.logDebug("--- RecordVersion.encryptedData - 7");
480 } else {
481//MochiKit.Logging.logDebug("--- RecordVersion.encryptedData - 8");
482//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("RecordVersion.encryptedData - 9: " + res); return res;});
483 deferredResult.addCallback(function(aResult) {
484 aResult['previousVersionKey'] = Clipperz.PM.Crypto.nullValue;
485 return aResult;
486 }, result);
487//MochiKit.Logging.logDebug("--- RecordVersion.encryptedData - 9");
488//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("RecordVersion.encryptedData - 10: " + res); return res;});
489 };
490//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("RecordVersion.encryptedData - 11: " + res); return res;});
491 deferredResult.callback();
492//MochiKit.Logging.logDebug("<<< RecordVersion.encryptedData");
493
494 return deferredResult;
495 },
496
497 //-------------------------------------------------------------------------
498
499 'createNewVersion': function() {
500 if (this.record().isBrandNew() == false) {
501 this.setPreviousVersion(this.reference());
502 this.setPreviousVersionKey(this.key());
503
504 this.setReference(Clipperz.PM.Crypto.randomKey());
505 this.setKey(Clipperz.PM.Crypto.randomKey());
506 }
507 },
508
509 //-------------------------------------------------------------------------
510/*
511 'shouldLoadData': function() {
512 return ((this.data() == null) && (this.isBrandNew() === false));
513 },
514
515 'loadData': function() {
516//MochiKit.Logging.logDebug(">>> Record.loadData (" + this.label() + ")");
517 // if (this.shouldLoadData()) {
518 // this.user().connection().message('getRecordDetail',
519 // {recordReference: this.reference()},
520 // {callback:MochiKit.Base.bind(this.loadDataCallback, this),
521 // errorHandler:Clipperz.PM.defaultErrorHandler });
522 // } else {
523 // this.notify('loadDataDone');
524 // }
525 },
526
527 'loadDataCallback': function() {
528MochiKit.Logging.logDebug("RecordVersion.loadDataCallback: " + Clipperz.Base.serializeJSON(arguments));
529 },
530*/
531 //-------------------------------------------------------------------------
532 __syntaxFix__: "syntax fix"
533
534});
535
diff --git a/frontend/beta/js/Clipperz/PM/DataModel/Statistics.js b/frontend/beta/js/Clipperz/PM/DataModel/Statistics.js
new file mode 100644
index 0000000..fb5eb01
--- a/dev/null
+++ b/frontend/beta/js/Clipperz/PM/DataModel/Statistics.js
@@ -0,0 +1,133 @@
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.DataModel) == 'undefined') { Clipperz.PM.DataModel = {}; }
32
33
34//#############################################################################
35
36Clipperz.PM.DataModel.Statistics = function(args) {
37 args = args || {};
38
39 this._user = args.user;
40 this._data = args.data || null;
41
42 return this;
43}
44
45Clipperz.PM.DataModel.Statistics.prototype = MochiKit.Base.update(null, {
46
47 //-------------------------------------------------------------------------
48
49 'decrypt': function(aVersion, someEncryptedData) {
50 var deferredResult;
51
52//MochiKit.Logging.logDebug(">>> Statistics.decrypt");
53 if (someEncryptedData == Clipperz.PM.Crypto.nullValue) {
54 this.setData({});
55 deferredResult = MochiKit.Async.succeed(this.data());
56 } else {
57 varstatistic;
58 var user;
59
60 statistic = this;
61 user = this.user();
62 deferredResult = new MochiKit.Async.Deferred();
63//deferredResult.addCallback(function() { console.time("Statistics.decrypt.deferredDecrypt")});
64 deferredResult.addCallback(Clipperz.PM.Crypto.deferredDecrypt, user.passphrase(), someEncryptedData, aVersion);
65//deferredResult.addCallback(function() { console.timeEnd("Statistics.decrypt.deferredDecrypt")});
66//deferredResult.addCallback(function() { console.time("Statistics.decrypt.setup")});
67 deferredResult.addCallbacks(
68 MochiKit.Base.partial(function (aStatistic, someData) {
69 aStatistic.setData(someData);
70 return aStatistic.data();
71 }, statistic),
72 MochiKit.Base.partial(function (aStatistic) {
73 MochiKit.Logging.logWarning("resetting user statistics due to an error while decrypting stored data");
74 aStatistic.setData({});
75 return aStatistic.data();
76 }, statistic)
77 );
78//deferredResult.addCallback(function() { console.timeEnd("Statistics.decrypt.setup")});
79
80 deferredResult.callback();
81 }
82//MochiKit.Logging.logDebug("<<< Statistics.decrypt");
83
84 return deferredResult;
85 },
86
87 //-------------------------------------------------------------------------
88
89 'user': function() {
90 return this._user;
91 },
92
93 //-------------------------------------------------------------------------
94
95 'data': function() {
96 return this._data;
97 },
98
99 'setData': function(aValue) {
100 this._data = aValue;
101
102 this.extractInfoFromData(aValue);
103 },
104
105 //-------------------------------------------------------------------------
106
107 'extractInfoFromData': function(someValues) {
108
109 },
110
111 //-------------------------------------------------------------------------
112
113 'encryptedData': function() {
114 return Clipperz.PM.Crypto.deferredEncryptWithCurrentVersion(this.user().passphrase(), this.serializedData());
115 },
116
117 //-------------------------------------------------------------------------
118
119 'serializedData': function() {
120 var result;
121
122//MochiKit.Logging.logDebug(">>> Statistics.serializedData");
123 result = {};
124//MochiKit.Logging.logDebug("<<< Statistics.serializedData");
125
126 return result;
127 },
128
129 //-------------------------------------------------------------------------
130 __syntaxFix__: "syntax fix"
131
132});
133
diff --git a/frontend/beta/js/Clipperz/PM/DataModel/User.js b/frontend/beta/js/Clipperz/PM/DataModel/User.js
new file mode 100644
index 0000000..5aaaff7
--- a/dev/null
+++ b/frontend/beta/js/Clipperz/PM/DataModel/User.js
@@ -0,0 +1,904 @@
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.DataModel) == 'undefined') { Clipperz.PM.DataModel = {}; }
32
33
34//#############################################################################
35
36Clipperz.PM.DataModel.User = function(args) {
37//MochiKit.Logging.logDebug(">>> new User");
38 args = args || {};
39
40 this._username = args.username || null;
41 this._passphrase = args.passphrase || null;
42
43 this._connection = null;
44 this._connectionVersion = 'current';
45
46 this._header = null;
47 this._statistics = null;
48 this._lock = 'new lock';
49
50 this._preferences = null;
51 this._records = {};
52 this._directLoginReferences = {};
53 this._oneTimePasswordManager = null;
54
55 this._isLoadingUserDetails = false;
56 this._loadingUserDetailsPendingQueue = [];
57
58 this._maxNumberOfRecords = Number.MAX_VALUE;
59
60 this._shouldDownloadOfflineCopy = false;
61
62 this._loginInfo = null;
63 this._loginHistory = null;
64
65 this._serverData = null;
66//MochiKit.Logging.logDebug("<<< new User");
67
68 return this;
69}
70
71Clipperz.PM.DataModel.User.prototype = MochiKit.Base.update(null, {
72
73 'toString': function() {
74 return "Clipperz.PM.DataModel.User - " + this.username();
75 },
76
77 //-------------------------------------------------------------------------
78
79 'username': function() {
80 return this._username;
81 },
82
83 'setUsername': function(aValue) {
84 this._username = aValue;
85 },
86
87 //-------------------------------------------------------------------------
88
89 'passphrase': function() {
90 return this._passphrase;
91 },
92
93 'setPassphrase': function(aValue) {
94 this._passphrase = aValue;
95 },
96
97 //-------------------------------------------------------------------------
98
99 'maxNumberOfRecords': function() {
100 return this._maxNumberOfRecords;
101 },
102
103 'setMaxNumberOfRecords': function(aValue) {
104 this._maxNumberOfRecords = aValue;
105 },
106
107 //-------------------------------------------------------------------------
108
109 'errorHandler': function(anErrorString, anException) {
110MochiKit.Logging.logError("- User.errorHandler: " + anErrorString + " (" + anException + ")");
111 },
112
113 //-------------------------------------------------------------------------
114
115 'connectionVersion': function() {
116 return this._connectionVersion;
117 },
118
119 'setConnectionVersion': function(aValue) {
120 this._connectionVersion = aValue;
121 },
122
123 //-------------------------------------------------------------------------
124
125 'connection': function() {
126 if ((this._connection == null) && (this.connectionVersion() != null) ){
127 this._connection = new Clipperz.PM.Crypto.communicationProtocol.versions[this.connectionVersion()]({user:this});
128 }
129
130 return this._connection;
131 },
132
133 'resetConnection': function(aValue) {
134 this._connection = null;
135 },
136
137 //=========================================================================
138
139 'register': function(anInvitationCode) {
140 vardeferredResult;
141 var prng;
142
143//MochiKit.Logging.logError(">>> User.register: " + this);
144 prng = Clipperz.Crypto.PRNG.defaultRandomGenerator();
145
146 deferredResult = new MochiKit.Async.Deferred()
147//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.register - 1: " + res); return res;});
148 deferredResult.addCallback(MochiKit.Base.method(prng, 'deferredEntropyCollection'));
149//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.register - 2: " + res); return res;});
150 deferredResult.addCallback(MochiKit.Base.method(this.header(), 'updateAllSections'), anInvitationCode);
151//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.register - 2.1: " + res); return res;});
152 deferredResult.addCallback(MochiKit.Base.method(this.connection(), 'register'), anInvitationCode);
153//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.register - 3: " + res); return res;});
154 deferredResult.callback();
155//MochiKit.Logging.logError("<<< User.register");
156
157 return deferredResult;
158 },
159
160 //=========================================================================
161
162 'connect': function(aValue) {
163 vardeferredResult;
164 var prng;
165
166 prng = Clipperz.Crypto.PRNG.defaultRandomGenerator();
167
168//MochiKit.Logging.logDebug(">>> User.connect");
169 deferredResult = new MochiKit.Async.Deferred();
170//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("1.2.1 - User.connect - 1: "/* + res*/); return res;});
171//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
172 deferredResult.addCallback(MochiKit.Base.method(prng, 'deferredEntropyCollection'));
173//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("1.2.2 - User.connect - 2: "/* + res*/); return res;});
174//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
175 deferredResult.addCallback(MochiKit.Base.method(this.connection(), 'login'));
176//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("1.2.3 - User.connect - 3: "/* + res*/); return res;});
177//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
178
179 // TODO:add an addErrback call here to manage a wrong login. Any error after this point is due to some other causes.
180 // possibly the same exact 'handleConnectionFallback use at the end of this same method.
181
182 if (this.connectionVersion() != 'current') {
183 varcurrentConnection;
184
185 currentVersionConnection = new Clipperz.PM.Crypto.communicationProtocol.versions['current']({user:this});
186
187//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("1.2.4 - User.connect - 4: "/* + res*/); return res;});
188//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
189 deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'connection_upgrading');
190//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("1.2.5 - User.connect - 5: "/* + res*/); return res;});
191//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
192 deferredResult.addCallback(MochiKit.Base.method(this.connection(), 'message'), 'upgradeUserCredentials', currentVersionConnection.serverSideUserCredentials());
193//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("1.2.6 - User.connect - 6: "/* + res*/); return res;});
194//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
195 }
196
197//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("1.2.7 - User.connect - 7: "/* + res*/); return res;});
198//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
199 deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'userConnected', null);
200//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("1.2.8 - User.connect - 8: "/* + res*/); return res;});
201//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
202 deferredResult.addErrback(MochiKit.Base.method(this, 'handleConnectionFallback'));
203//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("1.2.9 - User.connect - 9: "/* + res*/); return res;});
204//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
205
206 deferredResult.callback(aValue);
207//MochiKit.Logging.logDebug("<<< User.connect");
208
209 return deferredResult;
210 },
211
212 //.........................................................................
213
214 'handleConnectionFallback': function(aValue) {
215 var result;
216//MochiKit.Logging.logDebug(">>> User.handleConnectionFallback");
217 if (aValue instanceof MochiKit.Async.CancelledError) {
218//MochiKit.Logging.logDebug("--- User.handleConnectionFallback - operation cancelled");
219 result = aValue;
220 } else {
221
222//MochiKit.Logging.logDebug("--- User.handleConnectionFallback - an ERROR has occurred - " + aValue);
223 this.resetConnection();
224 this.setConnectionVersion(Clipperz.PM.Crypto.communicationProtocol.fallbackVersions[this.connectionVersion()]);
225
226 if (this.connectionVersion() != null) {
227 result = new MochiKit.Async.Deferred();
228
229 result.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'connection_tryOlderSchema');
230 result.addCallback(MochiKit.Base.method(this, 'connect'));
231 result.callback();
232 } else {
233 result = MochiKit.Async.fail(Clipperz.PM.DataModel.User.exception.LoginFailed);
234 }
235 }
236//MochiKit.Logging.logDebug("<<< User.handleConnectionFallback");
237 return result;
238 },
239
240 //=========================================================================
241
242 'header': function() {
243 if (this._header == null) {
244 this._header = new Clipperz.PM.DataModel.Header({user:this});
245 }
246 return this._header;
247 },
248
249 //-------------------------------------------------------------------------
250
251 'statistics': function() {
252 if (this._statistics == null) {
253 this._statistics = new Clipperz.PM.DataModel.Statistics({user:this});
254 }
255 return this._statistics;
256 },
257
258 //-------------------------------------------------------------------------
259
260 'records': function() {
261 return this._records;
262 },
263
264 //.........................................................................
265
266 'addRecord': function(aValue, isBatchUpdate) {
267 this.records()[aValue.reference()] = aValue;
268
269 if (isBatchUpdate != true) {
270 Clipperz.NotificationCenter.notify(aValue, 'recordAdded', null, true);
271 Clipperz.NotificationCenter.notify(this, 'updatedSection', 'records', true);
272 }
273 },
274
275 //-----------------------------------------------------------------------------
276
277 'addNewRecord': function() {
278 varrecord;
279
280//MochiKit.Logging.logDebug(">>> User.addNewRecord");
281 record = new Clipperz.PM.DataModel.Record({user:this});
282 this.addRecord(record);
283 Clipperz.NotificationCenter.notify(this, 'updatedSection', 'records', true);
284//MochiKit.Logging.logDebug("<<< User.addNewRecord");
285
286 return record;
287 },
288
289 //-------------------------------------------------------------------------
290
291 'saveRecords': function(someRecords, aMethodName) {
292 var deferredResult;
293 var methodName;
294 varresult;
295 var i,c;
296
297//console.log("User.saveRecords - someRecords", someRecords);
298 methodName = aMethodName || 'addNewRecords';
299
300 Clipperz.NotificationCenter.notify(this, 'updatedSection', 'records', true);
301//MochiKit.Logging.logDebug(">>> User.saveRecords");
302//MochiKit.Logging.logDebug(">>> [" + (new Date()).valueOf() + "] User.saveRecords");
303/*
304MochiKit.Logging.logDebug("--- User.saveRecords - 1");
305 MochiKit.Iter.forEach(someRecords, function(aRecord) {
306 if (aRecord.headerNotes() != null) {
307 aRecord.setNotes(aRecord.headerNotes());
308 }
309 aRecord.syncDirectLoginReferenceValues();
310 aRecord.currentVersion().createNewVersion();
311 aRecord.updateKey();
312 });
313MochiKit.Logging.logDebug("--- User.saveRecords - 2");
314*/
315
316 result = {'records': []};
317
318 deferredResult = new MochiKit.Async.Deferred();
319 c = someRecords.length;
320 for (i=0; i<c; i++) {
321 deferredResult.addCallback(function(aRecord) {
322 if (aRecord.headerNotes() != null) {
323 aRecord.setNotes(aRecord.headerNotes());
324 }
325 aRecord.syncDirectLoginReferenceValues();
326 aRecord.currentVersion().createNewVersion();
327 aRecord.updateKey();
328 }, someRecords[i]);
329 deferredResult.addCallback(MochiKit.Async.wait, 0.1);
330 }
331//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.saveRecords - 1 " + res); return res;});
332 deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'saveCard_collectRecordInfo');
333//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.saveRecords - 2 " + res); return res;});
334
335 deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'saveCard_encryptUserData');
336//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.saveRecords - 3 " + res); return res;});
337 deferredResult.addCallback(MochiKit.Base.method(this, 'encryptedData'));
338//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.saveRecords - 4 " + res); return res;});
339 deferredResult.addCallback(function(aResult, res) {
340 aResult['user'] = res;
341 return aResult;
342 }, result);
343//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.saveRecords - 5 " + res); return res;});
344
345 c = someRecords.length;
346 for (i=0; i<c; i++) {
347 var recordData;
348
349 recordData = {};
350
351//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.saveRecords - 6.1 " + res); return res;});
352 deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'saveCard_encryptRecordData');
353//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.saveRecords - 6.2 " + res); return res;});
354 deferredResult.addCallback(MochiKit.Base.method(someRecords[i], 'encryptedData'));
355//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.saveRecords - 6.3 " + res); return res;});
356 deferredResult.addCallback(function(aResult, res) {
357 aResult['record'] = res;
358 return aResult;
359 }, recordData);
360//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.saveRecords - 6.4 " + res); return res;});
361
362 deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', {} /*'saveCard_encryptRecordVersions'*/);
363//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.saveRecords - 6.5 " + res); return res;});
364 deferredResult.addCallback(MochiKit.Base.method(someRecords[i].currentVersion(), 'encryptedData'));
365//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.saveRecords - 6.6 " + res); return res;});
366 deferredResult.addCallback(function(aResult, res) {
367 aResult['currentRecordVersion'] = res;
368 return aResult;
369 }, recordData);
370//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.saveRecords - 6.7 " + res); return res;});
371
372 deferredResult.addCallback(function(aResult, res) {
373 aResult['records'].push(res);
374 return aResult;
375 }, result);
376//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.saveRecords - 6.8 " + res); return res;});
377 }
378
379//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.saveRecords - 7 " + res); return res;});
380 deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'saveCard_sendingData');
381//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.saveRecords - 8 " + res); return res;});
382 deferredResult.addCallback(MochiKit.Base.method(this.connection(), 'message'), methodName);
383//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.saveRecords - 9 " + res); return res;});
384
385 for (i=0; i<c; i++) {
386//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.saveRecords - 9.1 " + res); return res;});
387 deferredResult.addCallback(MochiKit.Base.method(someRecords[i], 'takeSnapshotOfCurrentData'));
388//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.saveRecords - 9.2 " + res); return res;});
389 deferredResult.addCallback(MochiKit.Base.method(someRecords[i], 'setIsBrandNew'), false);
390//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.saveRecords - 9.3 " + res); return res;});
391 }
392
393//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.saveRecords - 10 " + res); return res;});
394 deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'notify', 'recordUpdated');
395//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.saveRecords - 11 " + res); return res;});
396 deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'notify', 'directLoginUpdated');
397//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.saveRecords - 12 " + res); return res;});
398 deferredResult.callback();
399
400 return deferredResult;
401 },
402
403 //-------------------------------------------------------------------------
404
405 'removeRecord': function(aRecord) {
406//MochiKit.Logging.logDebug(">>> User.removeRecord");
407 delete this.records()[aRecord.reference()];
408//MochiKit.Logging.logDebug("--- User.removeRecord - 1");
409 Clipperz.NotificationCenter.notify(aRecord, 'recordRemoved', null, false);
410 Clipperz.NotificationCenter.notify(this, 'updatedSection', 'records', true);
411//MochiKit.Logging.logDebug("<<< User.removeRecord");
412 },
413
414 //-------------------------------------------------------------------------
415
416 'deleteRecordsAction': function(someRecords) {
417 vardeferredResult;
418 var parameters;
419
420//MochiKit.Logging.logDebug(">>> User.deleteRecordsAction - someRecords.length: " + someRecords.length);
421 parameters = {};
422 deferredResult = new MochiKit.Async.Deferred();
423//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.deleteRecordsAction - 1 " + res); return res;});
424 deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'deleteRecord_collectData');
425//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.deleteRecordsAction - 2 " + res); return res;});
426 deferredResult.addCallback(function(someParameters, someRecords) {
427 var recordReferences;
428
429 recordReferences = MochiKit.Base.map(function(aRecord) {
430 var result;
431
432 result = aRecord.reference();
433 aRecord.remove();
434
435 return result;
436 }, someRecords);
437 someParameters.recordReferences = recordReferences;
438
439 return someParameters;
440 }, parameters);
441//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.deleteRecordsAction - 3 " + res); return res;});
442 deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'deleteRecord_encryptData');
443//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.deleteRecordsAction - 4 " + res); return res;});
444 deferredResult.addCallback(MochiKit.Base.method(this, 'encryptedData'));
445//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.deleteRecordsAction - 5 " + res); return res;});
446 deferredResult.addCallback(function(someParameters, anUserEncryptedData) {
447 someParameters.user = anUserEncryptedData;
448 return someParameters;
449 }, parameters);
450//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.deleteRecordsAction - 6 " + res); return res;});
451 deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'deleteRecord_sendingData');
452//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.deleteRecords parameters: " + Clipperz.Base.serializeJSON(res)); return res;});
453//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.deleteRecordsAction - 7 " + res); return res;});
454 deferredResult.addCallback(MochiKit.Base.method(this.connection(), 'message'), 'deleteRecords');
455//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.deleteRecordsAction - 8 " + res); return res;});
456 deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'deleteRecord_updatingInterface');
457//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.deleteRecordsAction - 9 " + res); return res;});
458 deferredResult.callback(someRecords);
459//MochiKit.Logging.logDebug("<<< User.deleteRecordsAction");
460
461 return deferredResult;
462 },
463
464 //-------------------------------------------------------------------------
465
466 'resetAllLocalData': function() {
467 this.resetConnection();
468
469 this.setUsername("");
470 this.setPassphrase("");
471
472 this._header = null;
473 this._statistics = null;
474 this._preferences = null;
475 this._records = {};
476 this._directLoginReferences = {};
477 },
478
479 //-------------------------------------------------------------------------
480
481 'deleteAccountAction': function() {
482 var deferredResult;
483
484//MochiKit.Logging.logDebug(">>> user.deleteAccountAction - " + this);
485 deferredResult = new MochiKit.Async.Deferred();
486 deferredResult.addCallback(MochiKit.Base.method(this.connection(), 'message'), 'deleteUser');
487 deferredResult.addCallback(MochiKit.Base.method(this, 'resetAllLocalData'));
488 deferredResult.callback();
489//MochiKit.Logging.logDebug("<<< user.deleteAccountAction - " + this);
490
491 return deferredResult;
492 },
493
494 //-------------------------------------------------------------------------
495
496 'encryptedData': function() {
497 var deferredResult;
498 varresult;
499
500 result = {};
501
502 deferredResult = new MochiKit.Async.Deferred();
503
504//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.encryptedData - 0: " + res); return res;});
505 deferredResult.addCallback(MochiKit.Base.method(this.header(), 'encryptedData'));
506//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.encryptedData - 1: " + res); return res;});
507 deferredResult.addCallback(function(aResult, aValue) {
508 aResult['header'] = aValue;
509 }, result);
510//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.encryptedData - 2: " + res); return res;});
511
512 deferredResult.addCallback(MochiKit.Base.method(this.statistics(), 'encryptedData'));
513//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.encryptedData - 3: " + res); return res;});
514 deferredResult.addCallback(function(aResult, aValue) {
515 aResult['statistics'] = aValue;
516 }, result);
517//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.encryptedData - 4: " + res); return res;});
518
519 deferredResult.addCallback(MochiKit.Base.bind(function(aResult, aValue) {
520 aResult['version'] = Clipperz.PM.Crypto.encryptingFunctions.currentVersion;
521 aResult['lock'] = this.lock();
522
523 return aResult;
524 }, this), result);
525//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.encryptedData - 5: " + res); return res;});
526 deferredResult.callback();
527
528 return deferredResult;
529 },
530
531 //-------------------------------------------------------------------------
532
533 'preferences': function() {
534 if (this._preferences == null) {
535 this._preferences = new Clipperz.PM.DataModel.UserPreferences({user:this});
536 }
537
538 return this._preferences;
539 },
540/*
541 'setPreferences': function(aValue) {
542 this._preferences = aValue;
543
544 if (this._preferences.preferredLanguage() != null) {
545 Clipperz.PM.Strings.Languages.setSelectedLanguage(this._preferences.preferredLanguage());
546 } else {
547//MochiKit.Logging.logDebug("### keepping the browser selected language: " + Clipperz.PM.Strings.selectedLanguage);
548 }
549 },
550*/
551 //-------------------------------------------------------------------------
552
553 'oneTimePasswordManager': function() {
554 if (this._oneTimePasswordManager == null) {
555 this._oneTimePasswordManager = new Clipperz.PM.DataModel.OneTimePasswordManager(this, null);
556 }
557
558 return this._oneTimePasswordManager;
559 },
560
561 //-------------------------------------------------------------------------
562
563 'directLoginReferences': function() {
564 return this._directLoginReferences;
565 },
566
567 'addDirectLoginReference': function(aDirectLoginReference, isBatchUpdate) {
568//MochiKit.Logging.logDebug(">>> User.addDirectLoginReference");
569 this.directLoginReferences()[aDirectLoginReference.reference()] = aDirectLoginReference;
570
571 if (isBatchUpdate != true) {
572 Clipperz.NotificationCenter.notify(aDirectLoginReference, 'directLoginAdded');
573 Clipperz.NotificationCenter.notify(this, 'updatedSection', 'directLogins', true);
574 }
575 },
576
577 'removeDirectLoginReference': function(aDirectLoginReference) {
578 delete this.directLoginReferences()[aDirectLoginReference.reference()];
579 Clipperz.NotificationCenter.notify(aDirectLoginReference, 'directLoginRemoved');
580 Clipperz.NotificationCenter.notify(this, 'updatedSection', 'directLogins', true);
581 },
582
583 //.........................................................................
584
585 'addDirectLogin': function(aDirectLogin) {
586 varnewDirectLoginReference;
587
588 newDirectLoginReference = new Clipperz.PM.DataModel.DirectLoginReference({user:this, directLogin:aDirectLogin})
589 this.addDirectLoginReference(newDirectLoginReference);
590 },
591
592 'synchronizeDirectLogin': function(aDirectLogin) {
593 var directLoginReference;
594
595 directLoginReference = this.directLoginReferences()[aDirectLogin.reference()];
596 if (typeof(directLoginReference) != 'undefined') {
597 directLoginReference.synchronizeValues(aDirectLogin);
598 } else {
599 this.addDirectLogin(aDirectLogin);
600 }
601 },
602
603 'removeDirectLogin': function(aDirectLogin) {
604 this.removeDirectLoginReference(aDirectLogin);
605 },
606
607 //-------------------------------------------------------------------------
608
609 'changeCredentials': function(aUsername, aPassphrase) {
610 vardeferredResult;
611 var result;
612
613 result = {};
614
615 deferredResult = new MochiKit.Async.Deferred();
616
617 deferredResult.addCallback(MochiKit.Base.method(this.header(), 'loadAllSections'));
618 deferredResult.addCallback(MochiKit.Base.method(this.header(), 'updateAllSections'));
619
620 deferredResult.addCallback(MochiKit.Base.bind(function(aUsername, aPssphrase) {
621 this.setUsername(aUsername);
622 this.setPassphrase(aPassphrase);
623 }, this), aUsername, aPassphrase)
624
625//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.changeCredentials - 1: " + res); return res;});
626 deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'changeCredentials_encryptingData');
627//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.changeCredentials - 2: " + res); return res;});
628 deferredResult.addCallback(MochiKit.Base.method(this, 'encryptedData'));
629//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.changeCredentials - 3: " + res); return res;});
630 deferredResult.addCallback(function(aResult, anEncryptedData) {
631 aResult['user'] = anEncryptedData;
632
633 return aResult;
634 }, result);
635//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.changeCredentials - 4: " + res); return res;});
636 deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'changeCredentials_creatingNewCredentials');
637//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.changeCredentials - 5: " + res); return res;});
638 deferredResult.addCallback(function(aResult, anUser) {
639 varnewConnection;
640
641 newConnection = new Clipperz.PM.Crypto.communicationProtocol.versions[Clipperz.PM.Crypto.communicationProtocol.currentVersion]({user:anUser})
642 aResult['credentials'] = newConnection.serverSideUserCredentials();
643
644 return aResult;
645 }, result, this);
646//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.changeCredentials - 6: " + res); return res;});
647 deferredResult.addCallback(MochiKit.Base.method(this.oneTimePasswordManager(), 'encryptedData'));
648//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.changeCredentials - 7: " + res); return res;});
649 deferredResult.addCallback(function(aResult, anEncryptedData) {
650 aResult['oneTimePasswords'] = anEncryptedData;
651
652 return aResult;
653 }, result);
654//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.changeCredentials - 8: " + res); return res;});
655 deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'changeCredentials_sendingCredentials');
656//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.changeCredentials - 9: " + res); return res;});
657 deferredResult.addCallback(MochiKit.Base.method(this.connection(), 'message'), 'upgradeUserCredentials');
658//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.changeCredentials - 10: " + res); return res;});
659 deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'changeCredentials_done');
660//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.changeCredentials - 11: " + res); return res;});
661 deferredResult.callback();
662
663 return deferredResult;
664 },
665
666 //-------------------------------------------------------------------------
667
668 'doLogout': function() {
669 var deferredResult;
670
671 deferredResult = new MochiKit.Async.Deferred();
672//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.doLogout - 1: " + res); return res;});
673 deferredResult.addCallback(MochiKit.Base.method(this.connection(), 'logout'));
674//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.doLogout - 2: " + res); return res;});
675 deferredResult.addCallback(MochiKit.Base.method(this, 'resetAllLocalData'));
676//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.doLogout - 3: " + res); return res;});
677
678 deferredResult.callback();
679
680 return deferredResult;
681 },
682
683 //-------------------------------------------------------------------------
684
685 'lock': function() {
686 this.setPassphrase("")
687 this.connection().logout();
688 this.connection().resetSrpConnection();
689 },
690
691 'unlockWithPassphrase': function(aValue) {
692 vardeferredResult;
693 // varconnection;
694
695 // connection = this.connection();
696
697 deferredResult = new MochiKit.Async.Deferred();
698//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.unlockWithPassphrase 1: " + res); return res;});
699 deferredResult.addCallback(MochiKit.Base.method(this, 'setPassphrase'));
700//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.unlockWithPassphrase 2: " + res); return res;});
701 // deferredResult.addCallback(MochiKit.Base.method(connection, 'message'), 'echo', {'echo':"echo"});
702 deferredResult.addCallback(MochiKit.Base.method(this.connection(), 'reestablishConnection'));
703//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.unlockWithPassphrase 3: " + res); return res;});
704 // deferredResult.addErrback(MochiKit.Base.method(this, 'setPassphrase', ""));
705 deferredResult.addErrback(MochiKit.Base.bind(function(anError) {
706 this.setPassphrase("");
707 this.connection().resetSrpConnection();
708
709 return anError;
710 }, this));
711//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.unlockWithPassphrase 4: " + res); return res;});
712 deferredResult.callback(aValue);
713
714 return deferredResult;
715 },
716
717 //-------------------------------------------------------------------------
718 //-------------------------------------------------------------------------
719 //-------------------------------------------------------------------------
720 //-------------------------------------------------------------------------
721 //-------------------------------------------------------------------------
722 //-------------------------------------------------------------------------
723 //-------------------------------------------------------------------------
724 //-------------------------------------------------------------------------
725 //-------------------------------------------------------------------------
726 //-------------------------------------------------------------------------
727 //-------------------------------------------------------------------------
728 //-------------------------------------------------------------------------
729
730 'serverData': function() {
731 return this._serverData;
732 },
733
734 'setServerData': function(aValue) {
735//MochiKit.Logging.logDebug(">>> User.setServerData");
736 this._serverData = aValue;
737
738 if (typeof(aValue.maxNumberOfRecords) != 'undefined') {
739 this.setMaxNumberOfRecords(aValue.maxNumberOfRecords);
740 }
741//MochiKit.Logging.logDebug("<<< User.setServerData");
742 },
743
744 //-------------------------------------------------------------------------
745
746 'isLoadingUserDetails': function() {
747 return this._isLoadingUserDetails;
748 },
749
750 'setIsLoadingUserDetails': function(aValue) {
751 this._isLoadingUserDetails = aValue;
752 },
753
754 //-------------------------------------------------------------------------
755
756 'loadingUserDetailsPendingQueue': function() {
757 return this._loadingUserDetailsPendingQueue;
758 },
759
760 'flushLoadingUserDetailsPendingQueue': function() {
761 var queue;
762
763//MochiKit.Logging.logDebug(">>> User.flushLoadingUserDetailsPendingQueue");
764 queue = this.loadingUserDetailsPendingQueue();
765
766 while(queue.length > 0) {
767//MochiKit.Logging.logDebug("--- User.flushLoadingUserDetailsPendingQueue - pop");
768 queue.pop().callback();
769 }
770//MochiKit.Logging.logDebug("<<< User.flushLoadingUserDetailsPendingQueue");
771 },
772
773 //-------------------------------------------------------------------------
774
775 'getUserDetails': function() {
776 var deferredResult;
777
778//MochiKit.Logging.logDebug(">>> User.getUserDetails");
779 deferredResult = new MochiKit.Async.Deferred();
780 if ((this.serverData() == null) && (this.isLoadingUserDetails() == false)) {
781 deferredResult.addCallback(MochiKit.Base.method(this, 'setIsLoadingUserDetails', true));
782 deferredResult.addCallback(MochiKit.Base.method(this.connection(), 'message'), 'getUserDetails');
783 deferredResult.addCallback(MochiKit.Base.method(this, 'setServerData'));
784 deferredResult.addCallback(MochiKit.Base.method(this, 'flushLoadingUserDetailsPendingQueue'));
785 deferredResult.addCallback(MochiKit.Base.method(this, 'setIsLoadingUserDetails', false));
786 }
787
788 deferredResult.addCallback(MochiKit.Base.method(this, 'serverData'));
789
790 if (this.isLoadingUserDetails() == false) {
791 deferredResult.callback();
792 } else {
793 this.loadingUserDetailsPendingQueue().push(deferredResult);
794 }
795//MochiKit.Logging.logDebug("<<< User.getUserDetails");
796
797 return deferredResult;
798 },
799
800 //-------------------------------------------------------------------------
801
802 'loadRecords': function() {
803 return this.header().loadRecords();
804 },
805
806 'loadDirectLogins': function() {
807 return this.header().loadDirectLogins();
808 },
809
810 'loadPreferences': function() {
811 return this.header().loadPreferences();
812 },
813
814 'loadOneTimePasswords': function() {
815 return this.header().loadOneTimePasswords();
816 },
817
818 //-------------------------------------------------------------------------
819
820 'loadLoginHistory': function() {
821 var deferredResult;
822
823 deferredResult = new MochiKit.Async.Deferred();
824 deferredResult.addCallback(MochiKit.Base.method(this.connection(), 'message'), 'getLoginHistory');
825 deferredResult.addCallback(function(aResult) {
826 return aResult['result'];
827 });
828 deferredResult.addCallback(MochiKit.Base.method(this, 'setLoginHistory'));
829 deferredResult.addCallback(MochiKit.Base.method(this, 'loginHistory'));
830 deferredResult.callback();
831
832 return deferredResult;
833 },
834
835 //-------------------------------------------------------------------------
836
837 'shouldDownloadOfflineCopy': function() {
838 return this._shouldDownloadOfflineCopy;
839 },
840
841 'setShouldDownloadOfflineCopy': function(aValue) {
842 this._shouldDownloadOfflineCopy = aValue;
843 },
844
845 //-------------------------------------------------------------------------
846
847 'loginInfo': function() {
848 return this._loginInfo;
849 },
850
851 'setLoginInfo': function(aValue) {
852 this._loginInfo = aValue;
853//MochiKit.Logging.logDebug("### LoginInfo: " + Clipperz.Base.serializeJSON(aValue));
854 },
855
856 //-------------------------------------------------------------------------
857
858 'loginHistory': function() {
859 return this._loginHistory;
860 },
861
862 'setLoginHistory': function(aValue) {
863 this._loginHistory = aValue;
864 },
865/*
866 'loginInfoWithOneTimePasswordReference': function(aOneTimePasswordReference) {
867 var result;
868 var i,c;
869
870 result = null;
871 c = this.loginHistory().length;
872 for (i=0; (i<c) && (result == null); i++) {
873 var currentLoginInfo;
874
875 currentLoginInfo = this.loginHistory()[i];
876 if (currentLoginInfo['oneTimePasswordReference'] == aOneTimePasswordReference) {
877 result = currentLoginInfo;
878 }
879 }
880
881 return result;
882 },
883 */
884 //-------------------------------------------------------------------------
885
886 'lock': function() {
887 return this._lock;
888 },
889
890 'setLock': function(aValue) {
891//MochiKit.Logging.logDebug("=== User.setLock: " + aValue);
892 this._lock = aValue;
893 },
894
895 //-------------------------------------------------------------------------
896 __syntaxFix__: "syntax fix"
897
898});
899
900
901Clipperz.PM.DataModel.User.exception = {
902 LoginFailed: new MochiKit.Base.NamedError("Clipperz.PM.DataModel.User.exception.LoginFailed")
903};
904
diff --git a/frontend/beta/js/Clipperz/PM/DataModel/UserPreferences.js b/frontend/beta/js/Clipperz/PM/DataModel/UserPreferences.js
new file mode 100644
index 0000000..dc73ce1
--- a/dev/null
+++ b/frontend/beta/js/Clipperz/PM/DataModel/UserPreferences.js
@@ -0,0 +1,197 @@
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.DataModel) == 'undefined') { Clipperz.PM.DataModel = {}; }
32
33
34//#############################################################################
35
36Clipperz.PM.DataModel.UserPreferences = function(args) {
37 args = args || {};
38
39 this._user = args['user']; delete args['user'];
40 this._config = args;
41
42 return this;
43}
44
45Clipperz.PM.DataModel.UserPreferences.prototype = MochiKit.Base.update(null, {
46
47 //-------------------------------------------------------------------------
48
49 'config': function() {
50 return this._config;
51 },
52
53 //-------------------------------------------------------------------------
54
55 'user': function() {
56 return this._user;
57 },
58
59 //-------------------------------------------------------------------------
60
61 'updateWithData': function(someValues) {
62 var currentLanguage;
63
64//MochiKit.Logging.logDebug(">>> Clipperz.PM.DataModel.UserPreferences.updateWithData: " + Clipperz.Base.serializeJSON(someValues));
65 currentLanguage = this.preferredLanguage();
66
67 MochiKit.Base.update(this._config, someValues);
68
69 if (this.preferredLanguage() != currentLanguage) {
70 Clipperz.PM.Strings.Languages.setSelectedLanguage(this.preferredLanguage());
71 } else {
72//MochiKit.Logging.logDebug("### keepping the browser selected language: " + Clipperz.PM.Strings.selectedLanguage);
73 }
74
75 return this;
76 },
77
78 //-------------------------------------------------------------------------
79
80 'configValue': function(aConfigName, aDefaultValue) {
81 var result;
82
83//MochiKit.Logging.logDebug(">>> UserPreferences.configValue - config: " + Clipperz.Base.serializeJSON(this.config()));
84 if (typeof(this.config()[aConfigName]) == 'undefined') {
85 result = aDefaultValue;
86 } else {
87 result = this.config()[aConfigName];
88 }
89//MochiKit.Logging.logDebug("<<< UserPreferences.configValue");
90
91 return result;
92 },
93
94 'setConfigValue': function(aConfigName, aValue) {
95 var result;
96
97 if (aValue != this.configValue(aConfigName)) {
98 if (aValue == null) {
99 delete this.config()[aConfigName]
100 } else {
101 this.config()[aConfigName] = aValue;
102 }
103
104 Clipperz.NotificationCenter.notify(this.user(), 'updatedSection', 'preferences', true);
105
106 result = true;
107 } else {
108 result = false;
109 }
110
111 return result;
112 },
113
114 //-------------------------------------------------------------------------
115
116 'useSafeEditMode': function() {
117 return this.configValue('useSafeEditMode', true);
118 },
119
120 'setUseSafeEditMode': function(aValue) {
121 this.setConfigValue('useSafeEditMode', aValue);
122 },
123
124 //-------------------------------------------------------------------------
125
126 'preferredLanguage': function() {
127 return this.configValue('preferredLanguage', null);
128 },
129
130 'setPreferredLanguage': function(aValue) {
131 if (this.setConfigValue('preferredLanguage', aValue)) {
132 Clipperz.PM.Strings.Languages.setSelectedLanguage(this.preferredLanguage());
133 }
134 },
135
136 //-------------------------------------------------------------------------
137
138 'shouldShowDonationPanel': function() {
139 return this.configValue('shouldShowDonationPanel', true);
140 },
141
142 'setShouldShowDonationPanel': function(aValue) {
143 this.setConfigValue('shouldShowDonationPanel', aValue);
144 },
145
146 //-------------------------------------------------------------------------
147
148 'disableUnsecureFaviconLoadingForIE': function() {
149 return this.configValue('disableUnsecureFaviconLoadingForIE', false);
150 },
151
152 'setDisableUnsecureFaviconLoadingForIE': function(aValue) {
153 this.setConfigValue('disableUnsecureFaviconLoadingForIE', aValue);
154 },
155
156 //-------------------------------------------------------------------------
157
158 'serializedData': function() {
159 return this.config();
160 },
161
162 //-------------------------------------------------------------------------
163
164 'saveChanges': function(aReferenceElement) {
165 vardeferredResult;
166
167 deferredResult = new MochiKit.Async.Deferred();
168
169 deferredResult.addCallback(MochiKit.Base.method(Clipperz.PM.Components.MessageBox(), 'deferredShow'),
170 {
171 title:"", //Clipperz.PM.Strings['accountPreferencesSavingPanelTitle_Step1'],
172 text:"", //Clipperz.PM.Strings['accountPreferencesSavingPanelText_Step1'],
173 width:240,
174 showProgressBar:true,
175 showCloseButton:false
176 },
177 aReferenceElement
178 );
179 deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'account_savingPreferences_1');
180 deferredResult.addCallback(MochiKit.Base.method(this.user(), 'encryptedData'));
181 deferredResult.addCallback(function(res) {
182 return {user:res};
183 })
184 deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'account_savingPreferences_2');
185 deferredResult.addCallback(MochiKit.Base.method(this.user().connection(), 'message'), 'updateData');
186 deferredResult.addCallback(Clipperz.PM.Components.MessageBox().hide, YAHOO.ext.Element.get('main'));
187 deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedPreferences', null);
188
189 deferredResult.callback();
190
191 return deferredResult;
192 },
193
194 //-------------------------------------------------------------------------
195 __syntaxFix__: "syntax fix"
196});
197