summaryrefslogtreecommitdiff
path: root/frontend/gamma
authorGiulio Cesare Solaroli <giulio.cesare@clipperz.com>2013-04-19 15:09:28 (UTC)
committer Giulio Cesare Solaroli <giulio.cesare@clipperz.com>2013-04-19 15:09:28 (UTC)
commit074e70457c90344b3c1cb236105638d692a0066b (patch) (unidiff)
treec5ffabd3eaf74cbeb69974beacdb5a5f8c235adc /frontend/gamma
parent48c9280c9a255f2a85ad5729830df884e64a9c5d (diff)
downloadclipperz-074e70457c90344b3c1cb236105638d692a0066b.zip
clipperz-074e70457c90344b3c1cb236105638d692a0066b.tar.gz
clipperz-074e70457c90344b3c1cb236105638d692a0066b.tar.bz2
Fixed an issue on the AES-CTR block mode
The previous version of the CTR encoding was incrementing the counter in a weird way, mixing up data from the previous block. The current fix can correctly decrypt data encoded with AES-CTR using other libraries/languages (currently tested only with Python).
Diffstat (limited to 'frontend/gamma') (more/less context) (ignore whitespace changes)
-rw-r--r--frontend/gamma/js/Clipperz/Crypto/AES_2.js843
-rw-r--r--frontend/gamma/js/Clipperz/PM/Crypto.js106
-rw-r--r--frontend/gamma/js/Clipperz/PM/DataModel/User.js4
-rw-r--r--frontend/gamma/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js4
-rw-r--r--frontend/gamma/js/Clipperz/PM/Proxy/Proxy.Test.js5
-rw-r--r--frontend/gamma/properties/gamma.properties.json1
-rw-r--r--frontend/gamma/properties/mobile.properties.json25
-rw-r--r--frontend/gamma/tests/tests/Clipperz/Crypto/AES_2.html57
-rw-r--r--frontend/gamma/tests/tests/Clipperz/Crypto/AES_2.test.js85
-rw-r--r--frontend/gamma/tests/tests/Clipperz/Crypto/index.html1
-rw-r--r--frontend/gamma/tests/tests/Clipperz/PM/Crypto_v0_4.html60
-rw-r--r--frontend/gamma/tests/tests/Clipperz/PM/Crypto_v0_4.test.js50
-rw-r--r--frontend/gamma/tests/tests/Clipperz/PM/DataModel/DirectLogin.html1
-rw-r--r--frontend/gamma/tests/tests/Clipperz/PM/DataModel/EncryptedRemoteObject.html1
-rw-r--r--frontend/gamma/tests/tests/Clipperz/PM/DataModel/Record.html1
-rw-r--r--frontend/gamma/tests/tests/Clipperz/PM/DataModel/Record.test.js8
-rw-r--r--frontend/gamma/tests/tests/Clipperz/PM/DataModel/User.html1
-rw-r--r--frontend/gamma/tests/tests/Clipperz/PM/DataModel/User.test.js2
-rw-r--r--frontend/gamma/tests/tests/Clipperz/PM/index.html1
19 files changed, 1209 insertions, 47 deletions
diff --git a/frontend/gamma/js/Clipperz/Crypto/AES_2.js b/frontend/gamma/js/Clipperz/Crypto/AES_2.js
new file mode 100644
index 0000000..1627f39
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/Crypto/AES_2.js
@@ -0,0 +1,843 @@
1/*
2
3Copyright 2008-2013 Clipperz Srl
4
5This file is part of Clipperz, the online password manager.
6For further information about its features and functionalities please
7refer to http://www.clipperz.com.
8
9* Clipperz is free software: you can redistribute it and/or modify it
10 under the terms of the GNU Affero General Public License as published
11 by the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14* Clipperz is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU Affero General Public License for more details.
18
19* You should have received a copy of the GNU Affero General Public
20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
21
22*/
23
24try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) {
25 throw "Clipperz.Crypto.AES_2 depends on Clipperz.ByteArray!";
26}
27
28 //Dependency commented to avoid a circular reference
29//try { if (typeof(Clipperz.Crypto.PRNG) == 'undefined') { throw ""; }} catch (e) {
30 //throw "Clipperz.Crypto.AES_2 depends on Clipperz.Crypto.PRNG!";
31//}
32
33if (typeof(Clipperz.Crypto.AES_2) == 'undefined') { Clipperz.Crypto.AES_2 = {}; }
34
35//#############################################################################
36
37Clipperz.Crypto.AES_2.DeferredExecutionContext = function(args) {
38 args = args || {};
39
40 this._key = args.key;
41 this._message = args.message;
42 this._result = args.message.clone();
43 this._nonce = args.nonce;
44 this._messageLength = this._message.length();
45
46 this._messageArray = this._message.arrayValues();
47 this._resultArray = this._result.arrayValues();
48 this._nonceArray = this._nonce.arrayValues();
49
50 this._executionStep = 0;
51
52 // this._elaborationChunkSize = 1024; // 4096; // 16384; //4096;
53 this._elaborationChunks = 10;
54 this._pauseTime = 0.02; // 0.02 //0.2;
55
56 return this;
57}
58
59Clipperz.Crypto.AES_2.DeferredExecutionContext.prototype = MochiKit.Base.update(null, {
60
61 'key': function() {
62 return this._key;
63 },
64
65 'message': function() {
66 return this._message;
67 },
68
69 'messageLength': function() {
70 return this._messageLength;
71 },
72
73 'result': function() {
74 return new Clipperz.ByteArray(this.resultArray());
75 },
76
77 'nonce': function() {
78 return this._nonce;
79 },
80
81 'messageArray': function() {
82 return this._messageArray;
83 },
84
85 'resultArray': function() {
86 return this._resultArray;
87 },
88
89 'nonceArray': function() {
90 return this._nonceArray;
91 },
92
93 'elaborationChunkSize': function() {
94 // return Clipperz.Crypto.AES_2.DeferredExecution.chunkSize;
95 // return this._elaborationChunkSize;
96 return (this._elaborationChunks * 1024);
97 },
98
99 'executionStep': function() {
100 return this._executionStep;
101 },
102
103 'setExecutionStep': function(aValue) {
104 this._executionStep = aValue;
105 },
106
107 'tuneExecutionParameters': function (anElapsedTime) {
108//var originalChunks = this._elaborationChunks;
109 if (anElapsedTime > 0) {
110 this._elaborationChunks = Math.round(this._elaborationChunks * ((anElapsedTime + 1000)/(anElapsedTime * 2)));
111 }
112//Clipperz.log("tuneExecutionParameters - elapsedTime: " + anElapsedTime + /*originalChunks,*/ " chunks # " + this._elaborationChunks + " [" + this._executionStep + " / " + this._messageLength + "]");
113 },
114
115 'pause': function(aValue) {
116 // return MochiKit.Async.wait(Clipperz.Crypto.AES_2.DeferredExecution.pauseTime, aValue);
117 return MochiKit.Async.wait(this._pauseTime, aValue);
118 },
119
120 'isDone': function () {
121 return (this._executionStep >= this._messageLength);
122 },
123
124 //-----------------------------------------------------------------------------
125 __syntaxFix__: "syntax fix"
126
127});
128
129//#############################################################################
130
131Clipperz.Crypto.AES_2.Key = function(args) {
132 args = args || {};
133
134 this._key = args.key;
135 this._keySize = args.keySize || this.key().length();
136
137 if (this.keySize() == 128/8) {
138 this._b = 176;
139 this._numberOfRounds = 10;
140 } else if (this.keySize() == 256/8) {
141 this._b = 240;
142 this._numberOfRounds = 14;
143 } else {
144 Clipperz.logError("AES unsupported key size: " + (this.keySize() * 8) + " bits");
145 throw Clipperz.Crypto.AES_2.exception.UnsupportedKeySize;
146 }
147
148 this._stretchedKey = null;
149
150 return this;
151}
152
153Clipperz.Crypto.AES_2.Key.prototype = MochiKit.Base.update(null, {
154
155 'asString': function() {
156 return "Clipperz.Crypto.AES_2.Key (" + this.key().toHexString() + ")";
157 },
158
159 //-----------------------------------------------------------------------------
160
161 'key': function() {
162 return this._key;
163 },
164
165 'keySize': function() {
166 return this._keySize;
167 },
168
169 'b': function() {
170 return this._b;
171 },
172
173 'numberOfRounds': function() {
174 return this._numberOfRounds;
175 },
176 //=========================================================================
177
178 'keyScheduleCore': function(aWord, aRoundConstantsIndex) {
179 varresult;
180 var sbox;
181
182 sbox = Clipperz.Crypto.AES_2.sbox();
183
184 result = [sbox[aWord[1]] ^ Clipperz.Crypto.AES_2.roundConstants()[aRoundConstantsIndex],
185 sbox[aWord[2]],
186 sbox[aWord[3]],
187 sbox[aWord[0]]];
188
189 return result;
190 },
191
192 //-----------------------------------------------------------------------------
193
194 'xorWithPreviousStretchValues': function(aKey, aWord, aPreviousWordIndex) {
195 varresult;
196 var i,c;
197
198 result = [];
199 c = 4;
200 for (i=0; i<c; i++) {
201 result[i] = aWord[i] ^ aKey.byteAtIndex(aPreviousWordIndex + i);
202 }
203
204 return result;
205 },
206
207 //-----------------------------------------------------------------------------
208
209 'sboxShakeup': function(aWord) {
210 var result;
211 var sbox;
212 var i,c;
213
214 result = [];
215 sbox = Clipperz.Crypto.AES_2.sbox();
216 c =4;
217 for (i=0; i<c; i++) {
218 result[i] = sbox[aWord[i]];
219 }
220
221 return result;
222 },
223
224 //-----------------------------------------------------------------------------
225
226 'stretchKey': function(aKey) {
227 varcurrentWord;
228 varkeyLength;
229 varpreviousStretchIndex;
230 var i,c;
231
232 keyLength = aKey.length();
233 previousStretchIndex = keyLength - this.keySize();
234
235 currentWord = [aKey.byteAtIndex(keyLength - 4),
236 aKey.byteAtIndex(keyLength - 3),
237 aKey.byteAtIndex(keyLength - 2),
238 aKey.byteAtIndex(keyLength - 1)];
239 currentWord = this.keyScheduleCore(currentWord, keyLength / this.keySize());
240
241 if (this.keySize() == 256/8) {
242 c = 8;
243 } else if (this.keySize() == 128/8){
244 c = 4;
245 }
246
247 for (i=0; i<c; i++) {
248 if (i == 4) {
249 //fifth streatch word
250 currentWord = this.sboxShakeup(currentWord);
251 }
252
253 currentWord = this.xorWithPreviousStretchValues(aKey, currentWord, previousStretchIndex + (i*4));
254 aKey.appendBytes(currentWord);
255 }
256
257 return aKey;
258 },
259
260 //-----------------------------------------------------------------------------
261
262 'stretchedKey': function() {
263 if (this._stretchedKey == null) {
264 var stretchedKey;
265
266 stretchedKey = this.key().clone();
267
268 while (stretchedKey.length() < this.keySize()) {
269 stretchedKey.appendByte(0);
270 }
271
272 while (stretchedKey.length() < this.b()) {
273 stretchedKey = this.stretchKey(stretchedKey);
274 }
275
276 this._stretchedKey = stretchedKey.split(0, this.b());
277 }
278
279 return this._stretchedKey;
280 },
281
282 //=========================================================================
283 __syntaxFix__: "syntax fix"
284});
285
286//#############################################################################
287
288Clipperz.Crypto.AES_2.State = function(args) {
289 args = args || {};
290
291 this._data = args.block.slice(0);
292 this._key = args.key;
293
294 return this;
295}
296
297Clipperz.Crypto.AES_2.State.prototype = MochiKit.Base.update(null, {
298
299 'key': function() {
300 return this._key;
301 },
302
303 //-----------------------------------------------------------------------------
304
305 'data': function() {
306 return this._data;
307 },
308
309 'setData': function(aValue) {
310 this._data = aValue;
311 },
312
313 //=========================================================================
314
315 'addRoundKey': function(aRoundNumber) {
316 //each byte of the state is combined with the round key; each round key is derived from the cipher key using a key schedule.
317 vardata;
318 varstretchedKey;
319 varfirstStretchedKeyIndex;
320 var i,c;
321
322 data = this.data();
323 stretchedKey = this.key().stretchedKey();
324 firstStretchedKeyIndex = aRoundNumber * (128/8);
325 c = 128/8;
326 for (i=0; i<c; i++) {
327 data[i] = data[i] ^ stretchedKey.byteAtIndex(firstStretchedKeyIndex + i);
328 }
329 },
330
331 //-----------------------------------------------------------------------------
332
333 'subBytes': function() {
334 // a non-linear substitution step where each byte is replaced with another according to a lookup table.
335 var i,c;
336 vardata;
337 var sbox;
338
339 data = this.data();
340 sbox = Clipperz.Crypto.AES_2.sbox();
341
342 c = 16;
343 for (i=0; i<c; i++) {
344 data[i] = sbox[data[i]];
345 }
346 },
347
348 //-----------------------------------------------------------------------------
349
350 'shiftRows': function() {
351 //a transposition step where each row of the state is shifted cyclically a certain number of steps.
352 varnewValue;
353 vardata;
354 varshiftMapping;
355 vari,c;
356
357 newValue = new Array(16);
358 data = this.data();
359 shiftMapping = Clipperz.Crypto.AES_2.shiftRowMapping();
360 // [0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 1, 6, 11];
361 c = 16;
362 for (i=0; i<c; i++) {
363 newValue[i] = data[shiftMapping[i]];
364 }
365 for (i=0; i<c; i++) {
366 data[i] = newValue[i];
367 }
368 },
369
370 //-----------------------------------------------------------------------------
371/*
372 'mixColumnsWithValues': function(someValues) {
373 varresult;
374 vara;
375 var i,c;
376
377 c = 4;
378 result = [];
379 a = [];
380 for (i=0; i<c; i++) {
381 a[i] = [];
382 a[i][1] = someValues[i]
383 if ((a[i][1] & 0x80) == 0x80) {
384 a[i][2] = (a[i][1] << 1) ^ 0x11b;
385 } else {
386 a[i][2] = a[i][1] << 1;
387 }
388
389 a[i][3] = a[i][2] ^ a[i][1];
390 }
391
392 for (i=0; i<c; i++) {
393 varx;
394
395 x = Clipperz.Crypto.AES_2.mixColumnsMatrix()[i];
396 result[i] = a[0][x[0]] ^ a[1][x[1]] ^ a[2][x[2]] ^ a[3][x[3]];
397 }
398
399 return result;
400 },
401
402 'mixColumns': function() {
403 //a mixing operation which operates on the columns of the state, combining the four bytes in each column using a linear transformation.
404 var data;
405 var i, c;
406
407 data = this.data();
408 c = 4;
409 for(i=0; i<c; i++) {
410 varblockIndex;
411 var mixedValues;
412
413 blockIndex = i * 4;
414 mixedValues = this.mixColumnsWithValues([data[blockIndex + 0],
415 data[blockIndex + 1],
416 data[blockIndex + 2],
417 data[blockIndex + 3]]);
418 data[blockIndex + 0] = mixedValues[0];
419 data[blockIndex + 1] = mixedValues[1];
420 data[blockIndex + 2] = mixedValues[2];
421 data[blockIndex + 3] = mixedValues[3];
422 }
423 },
424*/
425
426 'mixColumns': function() {
427 //a mixing operation which operates on the columns of the state, combining the four bytes in each column using a linear transformation.
428 var data;
429 var i, c;
430 var a_1;
431 var a_2;
432
433 a_1 = new Array(4);
434 a_2 = new Array(4);
435
436 data = this.data();
437 c = 4;
438 for(i=0; i<c; i++) {
439 varblockIndex;
440 var ii, cc;
441
442 blockIndex = i * 4;
443
444 cc = 4;
445 for (ii=0; ii<cc; ii++) {
446 var value;
447
448 value = data[blockIndex + ii];
449 a_1[ii] = value;
450 a_2[ii] = (value & 0x80) ? ((value << 1) ^ 0x011b) : (value << 1);
451 }
452
453 data[blockIndex + 0] = a_2[0] ^ a_1[1] ^ a_2[1] ^ a_1[2] ^ a_1[3];
454 data[blockIndex + 1] = a_1[0] ^ a_2[1] ^ a_1[2] ^ a_2[2] ^ a_1[3];
455 data[blockIndex + 2] = a_1[0] ^ a_1[1] ^ a_2[2] ^ a_1[3] ^ a_2[3];
456 data[blockIndex + 3] = a_1[0] ^ a_2[0] ^ a_1[1] ^ a_1[2] ^ a_2[3];
457 }
458 },
459
460 //=========================================================================
461
462 'spinRound': function(aRoundNumber) {
463 this.addRoundKey(aRoundNumber);
464 this.subBytes();
465 this.shiftRows();
466 this.mixColumns();
467 },
468
469 'spinLastRound': function() {
470 this.addRoundKey(this.key().numberOfRounds() - 1);
471 this.subBytes();
472 this.shiftRows();
473 this.addRoundKey(this.key().numberOfRounds());
474 },
475
476 //=========================================================================
477
478 'encrypt': function() {
479 vari,c;
480
481 c = this.key().numberOfRounds() - 1;
482 for (i=0; i<c; i++) {
483 this.spinRound(i);
484 }
485
486 this.spinLastRound();
487 },
488
489 //=========================================================================
490 __syntaxFix__: "syntax fix"
491});
492
493//#############################################################################
494
495Clipperz.Crypto.AES_2.VERSION = "0.1";
496Clipperz.Crypto.AES_2.NAME = "Clipperz.Crypto.AES_2";
497
498MochiKit.Base.update(Clipperz.Crypto.AES_2, {
499
500 //http://www.cs.eku.edu/faculty/styer/460/Encrypt/JS-AES.html
501 //http://en.wikipedia.org/wiki/Advanced_Encryption_Standard
502 //http://en.wikipedia.org/wiki/Rijndael_key_schedule
503 //http://en.wikipedia.org/wiki/Rijndael_S-box
504
505 '__repr__': function () {
506 return "[" + this.NAME + " " + this.VERSION + "]";
507 },
508
509 'toString': function () {
510 return this.__repr__();
511 },
512
513 //=============================================================================
514
515 '_sbox': null,
516 'sbox': function() {
517 if (Clipperz.Crypto.AES_2._sbox == null) {
518 Clipperz.Crypto.AES_2._sbox = [
5190x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
5200xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
5210xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
5220x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
5230x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
5240x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
5250xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
5260x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
5270xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
5280x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
5290xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
5300xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
5310xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
5320x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
5330xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
5340x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
535 ];
536 }
537
538 return Clipperz.Crypto.AES_2._sbox;
539 },
540
541 //-----------------------------------------------------------------------------
542 //
543 // 0 4 8 12 0 4 812
544 // 1 5 9 13 => 5 9 131
545 // 2 6 10 14 10 14 26
546 // 3 7 11 15 15 3 711
547 //
548 '_shiftRowMapping': null,
549 'shiftRowMapping': function() {
550 if (Clipperz.Crypto.AES_2._shiftRowMapping == null) {
551 Clipperz.Crypto.AES_2._shiftRowMapping = [0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 1, 6, 11];
552 }
553
554 return Clipperz.Crypto.AES_2._shiftRowMapping;
555 },
556
557 //-----------------------------------------------------------------------------
558
559 '_mixColumnsMatrix': null,
560 'mixColumnsMatrix': function() {
561 if (Clipperz.Crypto.AES_2._mixColumnsMatrix == null) {
562 Clipperz.Crypto.AES_2._mixColumnsMatrix = [[2, 3, 1 ,1],
563 [1, 2, 3, 1],
564 [1, 1, 2, 3],
565 [3, 1, 1, 2] ];
566 }
567
568 return Clipperz.Crypto.AES_2._mixColumnsMatrix;
569 },
570
571 '_roundConstants': null,
572 'roundConstants': function() {
573 if (Clipperz.Crypto.AES_2._roundConstants == null) {
574 Clipperz.Crypto.AES_2._roundConstants = [ , 1, 2, 4, 8, 16, 32, 64, 128, 27, 54, 108, 216, 171, 77, 154];
575 // Clipperz.Crypto.AES_2._roundConstants = [ , 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a];
576 }
577
578 return Clipperz.Crypto.AES_2._roundConstants;
579 },
580
581 //=============================================================================
582
583 'incrementNonce': function(nonce) {
584 var i;
585 var done;
586
587 done = false;
588 i = nonce.length - 1;
589
590 while ((i>=0) && (done == false)) {
591 var currentByteValue;
592
593 currentByteValue = nonce[i];
594
595 if (currentByteValue == 0xff) {
596 nonce[i] = 0;
597 if (i>= 0) {
598 i --;
599 } else {
600 done = true;
601 }
602 } else {
603 nonce[i] = currentByteValue + 1;
604 done = true;
605 }
606 }
607 },
608
609 //-----------------------------------------------------------------------------
610
611 'encryptBlock': function(aKey, aBlock) {
612 varresult;
613 varstate;
614
615 state = new Clipperz.Crypto.AES_2.State({block:aBlock, key:aKey});
616//is(state.data(), 'before');
617 state.encrypt();
618 result = state.data();
619
620 return result;
621 },
622
623 //-----------------------------------------------------------------------------
624
625 'encryptBlocks': function(aKey, aMessage, aNonce) {
626 varresult;
627 var nonce;
628 var self;
629 varmessageIndex;
630 varmessageLength;
631 var blockSize;
632
633 self = Clipperz.Crypto.AES_2;
634 blockSize = 128/8;
635 messageLength = aMessage.length;
636 nonce = aNonce;
637
638 result = aMessage;
639 messageIndex = 0;
640 while (messageIndex < messageLength) {
641 var encryptedBlock;
642 var i,c;
643
644 encryptedBlock = self.encryptBlock(aKey, nonce);
645
646 if ((messageLength - messageIndex) > blockSize) {
647 c = blockSize;
648 } else {
649 c = messageLength - messageIndex;
650 }
651
652 for (i=0; i<c; i++) {
653 result[messageIndex + i] = result[messageIndex + i] ^ encryptedBlock[i];
654 }
655
656 messageIndex += blockSize;
657 // nonce = self.incrementNonce(nonce);
658 self.incrementNonce(nonce)
659 }
660
661 return result;
662 },
663
664 //-----------------------------------------------------------------------------
665
666 'encrypt': function(aKey, someData, aNonce) {
667 var result;
668 var nonce;
669 varencryptedData;
670 var key;
671
672 key = new Clipperz.Crypto.AES_2.Key({key:aKey});
673 nonce = aNonce ? aNonce.clone() : Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(128/8);
674
675 encryptedData = Clipperz.Crypto.AES_2.encryptBlocks(key, someData.arrayValues(), nonce.arrayValues());
676
677 result = nonce.appendBytes(encryptedData);
678
679 return result;
680 },
681
682 //-----------------------------------------------------------------------------
683
684 'decrypt': function(aKey, someData) {
685 var result;
686 var nonce;
687 var encryptedData;
688 var decryptedData;
689 vardataIterator;
690 var key;
691
692 key = new Clipperz.Crypto.AES_2.Key({key:aKey});
693
694 encryptedData = someData.arrayValues();
695 nonce = encryptedData.slice(0, (128/8));
696 encryptedData = encryptedData.slice(128/8);
697 decryptedData = Clipperz.Crypto.AES_2.encryptBlocks(key, encryptedData, nonce);
698
699 result = new Clipperz.ByteArray(decryptedData);
700
701 return result;
702 },
703
704 //=============================================================================
705
706 'deferredEncryptExecutionChunk': function(anExecutionContext) {
707 varresult;
708 var nonce;
709 var self;
710 varmessageIndex;
711 varmessageLength;
712 var blockSize;
713 var executionLimit;
714 var startTime, endTime;
715
716 self = Clipperz.Crypto.AES_2;
717 startTime = new Date();
718 blockSize = 128/8;
719 messageLength = anExecutionContext.messageArray().length;
720 nonce = anExecutionContext.nonceArray();
721 result = anExecutionContext.resultArray();
722
723 messageIndex = anExecutionContext.executionStep();
724 executionLimit = messageIndex + anExecutionContext.elaborationChunkSize();
725 executionLimit = Math.min(executionLimit, messageLength);
726
727 while (messageIndex < executionLimit) {
728 var encryptedBlock;
729 var i,c;
730
731//console.log("+++ nonce: [" + nonce + "]")
732 encryptedBlock = self.encryptBlock(anExecutionContext.key(), nonce);
733
734 if ((executionLimit - messageIndex) > blockSize) {
735 c = blockSize;
736 } else {
737 c = executionLimit - messageIndex;
738 }
739
740 for (i=0; i<c; i++) {
741 result[messageIndex + i] = result[messageIndex + i] ^ encryptedBlock[i];
742 }
743
744 messageIndex += blockSize;
745 // nonce = self.incrementNonce(nonce);
746 self.incrementNonce(nonce);
747 }
748 anExecutionContext.setExecutionStep(messageIndex);
749 endTime = new Date();
750 anExecutionContext.tuneExecutionParameters(endTime - startTime);
751
752 return anExecutionContext;
753 },
754
755 //-----------------------------------------------------------------------------
756
757 'deferredEncryptBlocks': function(anExecutionContext) {
758 vardeferredResult;
759
760//console.log("executionContext", anExecutionContext)
761//console.log(" --- nonce: " + anExecutionContext.nonceArray())
762 if (! anExecutionContext.isDone()) {
763 deferredResult = Clipperz.Async.callbacks("Clipperz.Crypto.AES_2.deferredEncryptBloks", [
764 Clipperz.Crypto.AES_2.deferredEncryptExecutionChunk,
765 MochiKit.Base.method(anExecutionContext, 'pause'),
766 Clipperz.Crypto.AES_2.deferredEncryptBlocks
767 ], {trace:false}, anExecutionContext);
768 } else {
769 deferredResult = MochiKit.Async.succeed(anExecutionContext);
770 }
771
772 return deferredResult;
773 },
774
775 //-----------------------------------------------------------------------------
776
777 'deferredEncrypt': function(aKey, someData, aNonce) {
778 var deferredResult;
779 varexecutionContext;
780 var result;
781 var nonce;
782 var key;
783
784 key = new Clipperz.Crypto.AES_2.Key({key:aKey});
785 nonce = aNonce ? aNonce.clone() : Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(128/8);
786
787 executionContext = new Clipperz.Crypto.AES_2.DeferredExecutionContext({key:key, message:someData, nonce:nonce});
788
789 deferredResult = new Clipperz.Async.Deferred("AES.deferredEncrypt");
790 deferredResult.addCallback(Clipperz.Crypto.AES_2.deferredEncryptBlocks);
791 deferredResult.addCallback(function(anExecutionContext) {
792 var result;
793
794 result = anExecutionContext.nonce().clone();
795 result.appendBytes(anExecutionContext.resultArray());
796
797 return result;
798 });
799 deferredResult.callback(executionContext)
800
801 return deferredResult;
802 },
803
804 //-----------------------------------------------------------------------------
805
806 'deferredDecrypt': function(aKey, someData) {
807 var deferredResult
808 var nonce;
809 var message;
810 var key;
811
812 key = new Clipperz.Crypto.AES_2.Key({key:aKey});
813 nonce = someData.split(0, (128/8));
814//console.log("nonce: [" + nonce.arrayValues() + "]")
815 message = someData.split(128/8);
816//console.log("message: [" + message.arrayValues() + "]")
817 executionContext = new Clipperz.Crypto.AES_2.DeferredExecutionContext({key:key, message:message, nonce:nonce});
818
819 deferredResult = new Clipperz.Async.Deferred("AES.deferredDecrypt");
820 deferredResult.addCallback(Clipperz.Crypto.AES_2.deferredEncryptBlocks);
821 deferredResult.addCallback(function(anExecutionContext) {
822 return anExecutionContext.result();
823 });
824 deferredResult.callback(executionContext);
825
826 return deferredResult;
827 },
828
829 //-----------------------------------------------------------------------------
830 __syntaxFix__: "syntax fix"
831
832});
833
834//#############################################################################
835
836//Clipperz.Crypto.AES_2.DeferredExecution = {
837 // 'chunkSize': 16384, // 4096, // 1024 4096 8192 1638432768;
838 // 'pauseTime': 0.02 //0.2
839//}
840
841Clipperz.Crypto.AES_2.exception = {
842 'UnsupportedKeySize': new MochiKit.Base.NamedError("Clipperz.Crypto.AES_2.exception.UnsupportedKeySize")
843};
diff --git a/frontend/gamma/js/Clipperz/PM/Crypto.js b/frontend/gamma/js/Clipperz/PM/Crypto.js
index cd10e33..7edf17f 100644
--- a/frontend/gamma/js/Clipperz/PM/Crypto.js
+++ b/frontend/gamma/js/Clipperz/PM/Crypto.js
@@ -1,508 +1,546 @@
1/* 1/*
2 2
3Copyright 2008-2013 Clipperz Srl 3Copyright 2008-2013 Clipperz Srl
4 4
5This file is part of Clipperz, the online password manager. 5This file is part of Clipperz, the online password manager.
6For further information about its features and functionalities please 6For further information about its features and functionalities please
7refer to http://www.clipperz.com. 7refer to http://www.clipperz.com.
8 8
9* Clipperz is free software: you can redistribute it and/or modify it 9* Clipperz is free software: you can redistribute it and/or modify it
10 under the terms of the GNU Affero General Public License as published 10 under the terms of the GNU Affero General Public License as published
11 by the Free Software Foundation, either version 3 of the License, or 11 by the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version. 12 (at your option) any later version.
13 13
14* Clipperz is distributed in the hope that it will be useful, but 14* Clipperz is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of 15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU Affero General Public License for more details. 17 See the GNU Affero General Public License for more details.
18 18
19* You should have received a copy of the GNU Affero General Public 19* You should have received a copy of the GNU Affero General Public
20 License along with Clipperz. If not, see http://www.gnu.org/licenses/. 20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
21 21
22*/ 22*/
23 23
24if (typeof(Clipperz) == 'undefined') { Clipperz = {}; } 24if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
25if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; } 25if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; }
26if (typeof(Clipperz.PM.Crypto) == 'undefined') { Clipperz.PM.Crypto = {}; } 26if (typeof(Clipperz.PM.Crypto) == 'undefined') { Clipperz.PM.Crypto = {}; }
27 27
28Clipperz.PM.Crypto.VERSION = "0.2"; 28Clipperz.PM.Crypto.VERSION = "0.2";
29Clipperz.PM.Crypto.NAME = "Clipperz.PM.Crypto"; 29Clipperz.PM.Crypto.NAME = "Clipperz.PM.Crypto";
30 30
31Clipperz.PM.Crypto.encryptingFunctions = {}; 31Clipperz.PM.Crypto.encryptingFunctions = {};
32 32
33MochiKit.Base.update(Clipperz.PM.Crypto, { 33MochiKit.Base.update(Clipperz.PM.Crypto, {
34 34
35 '__repr__': function () { 35 '__repr__': function () {
36 return "[" + this.NAME + " " + this.VERSION + "]"; 36 return "[" + this.NAME + " " + this.VERSION + "]";
37 }, 37 },
38 38
39 //------------------------------------------------------------------------- 39 //-------------------------------------------------------------------------
40 40
41 'toString': function () { 41 'toString': function () {
42 return this.__repr__(); 42 return this.__repr__();
43 }, 43 },
44 44
45 //------------------------------------------------------------------------- 45 //-------------------------------------------------------------------------
46/* 46/*
47 'communicationProtocol': { 47 'communicationProtocol': {
48 'currentVersion': '0.2', 48 'currentVersion': '0.2',
49 'versions': { 49 'versions': {
50 '0.1': Clipperz.PM.Connection.SRP['1.0'],//Clipperz.Crypto.SRP.versions['1.0'].Connection, 50 '0.1': Clipperz.PM.Connection.SRP['1.0'],//Clipperz.Crypto.SRP.versions['1.0'].Connection,
51 '0.2': Clipperz.PM.Connection.SRP['1.1']//Clipperz.Crypto.SRP.versions['1.1'].Connection 51 '0.2': Clipperz.PM.Connection.SRP['1.1']//Clipperz.Crypto.SRP.versions['1.1'].Connection
52 }, 52 },
53 'fallbackVersions': { 53 'fallbackVersions': {
54 'current':'0.1', 54 'current':'0.1',
55 '0.2': '0.1', 55 '0.2': '0.1',
56 '0.1': null 56 '0.1': null
57 } 57 }
58 }, 58 },
59*/ 59*/
60 //------------------------------------------------------------------------- 60 //-------------------------------------------------------------------------
61 61
62 'encryptingFunctions': { 62 'encryptingFunctions': {
63 'currentVersion': '0.3', 63 'currentVersion': '0.4',
64 'versions': { 64 'versions': {
65 65
66 //##################################################################### 66 //#####################################################################
67 67
68 '0.1': { 68 '0.1': {
69 'encrypt': function(aKey, aValue) { 69 'encrypt': function(aKey, aValue) {
70 return Clipperz.Crypto.Base.encryptUsingSecretKey(aKey, Clipperz.Base.serializeJSON(aValue)); 70 return Clipperz.Crypto.Base.encryptUsingSecretKey(aKey, Clipperz.Base.serializeJSON(aValue));
71 }, 71 },
72 72
73 'deferredEncrypt': function(aKey, aValue) { 73 'deferredEncrypt': function(aKey, aValue) {
74 var deferredResult; 74 var deferredResult;
75 75
76 deferredResult = new Clipperz.Async.Deferred("Crypto[0.1].deferredEncrypt"); 76 deferredResult = new Clipperz.Async.Deferred("Crypto[0.1].deferredEncrypt");
77 deferredResult.addCallback(Clipperz.PM.Crypto.encryptingFunctions.versions['0.1'].encrypt, aKey, aValue); 77 deferredResult.addCallback(Clipperz.PM.Crypto.encryptingFunctions.versions['0.1'].encrypt, aKey, aValue);
78 deferredResult.callback(); 78 deferredResult.callback();
79 79
80 return deferredResult; 80 return deferredResult;
81 }, 81 },
82 82
83 'decrypt': function(aKey, aValue) { 83 'decrypt': function(aKey, aValue) {
84 var result; 84 var result;
85 85
86 if (aValue != null) { 86 if (aValue != null) {
87 result = Clipperz.Base.evalJSON(Clipperz.Crypto.Base.decryptUsingSecretKey(aKey, aValue)); 87 result = Clipperz.Base.evalJSON(Clipperz.Crypto.Base.decryptUsingSecretKey(aKey, aValue));
88 } else { 88 } else {
89 result = null; 89 result = null;
90 } 90 }
91 91
92 return result; 92 return result;
93 }, 93 },
94 94
95 'deferredDecrypt': function(aKey, aValue) { 95 'deferredDecrypt': function(aKey, aValue) {
96 var deferredResult; 96 var deferredResult;
97 97
98 deferredResult = new Clipperz.Async.Deferred("Crypto.[0.1].deferredDecrypt"); 98 deferredResult = new Clipperz.Async.Deferred("Crypto.[0.1].deferredDecrypt");
99 deferredResult.addCallback(Clipperz.PM.Crypto.encryptingFunctions.versions['0.1'].decrypt, aKey, aValue); 99 deferredResult.addCallback(Clipperz.PM.Crypto.encryptingFunctions.versions['0.1'].decrypt, aKey, aValue);
100 deferredResult.callback(); 100 deferredResult.callback();
101 101
102 return deferredResult; 102 return deferredResult;
103 }, 103 },
104 104
105 'hash': function(aValue) { 105 'hash': function(aValue) {
106 var result; 106 var result;
107 var strngResult; 107 var strngResult;
108 108
109 stringResult = Clipperz.Crypto.Base.computeHashValue(aValue.asString()); //!!!!!!! 109 stringResult = Clipperz.Crypto.Base.computeHashValue(aValue.asString()); //!!!!!!!
110 result = new Clipperz.ByteArray("0x" + stringResult); 110 result = new Clipperz.ByteArray("0x" + stringResult);
111 111
112 return result; 112 return result;
113 }, 113 },
114 114
115 'deriveKey': function(aStringValue) { 115 'deriveKey': function(aStringValue) {
116 return Clipperz.Crypto.Base.computeHashValue(aStringValue); 116 return Clipperz.Crypto.Base.computeHashValue(aStringValue);
117 } 117 }
118 }, 118 },
119 119
120 //##################################################################### 120 //#####################################################################
121 121
122 '0.2': { 122 '0.2': {
123 'encrypt': function(aKey, aValue, aNonce) { 123 'encrypt': function(aKey, aValue, aNonce) {
124 var result; 124 var result;
125 varkey, value; 125 varkey, value;
126 var dataToEncrypt; 126 var dataToEncrypt;
127 var encryptedData; 127 var encryptedData;
128 128
129 key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey)); 129 key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey));
130 value = new Clipperz.ByteArray(Clipperz.Base.serializeJSON(aValue)); 130 value = new Clipperz.ByteArray(Clipperz.Base.serializeJSON(aValue));
131 dataToEncrypt = Clipperz.Crypto.SHA.sha_d256(value).appendBlock(value); 131 dataToEncrypt = Clipperz.Crypto.SHA.sha_d256(value).appendBlock(value);
132 encryptedData = Clipperz.Crypto.AES.encrypt(key, dataToEncrypt, aNonce); 132 encryptedData = Clipperz.Crypto.AES.encrypt(key, dataToEncrypt, aNonce);
133 result = encryptedData.toBase64String(); 133 result = encryptedData.toBase64String();
134 134
135 return result; 135 return result;
136 }, 136 },
137 137
138 'deferredEncrypt': function(aKey, aValue, aNonce) { 138 'deferredEncrypt': function(aKey, aValue, aNonce) {
139 var deferredResult; 139 var deferredResult;
140 varkey, value; 140 varkey, value;
141 var dataToEncrypt; 141 var dataToEncrypt;
142 // var encryptedData; 142 // var encryptedData;
143 143
144 key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey)); 144 key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey));
145 value = new Clipperz.ByteArray(Clipperz.Base.serializeJSON(aValue)); 145 value = new Clipperz.ByteArray(Clipperz.Base.serializeJSON(aValue));
146 dataToEncrypt = Clipperz.Crypto.SHA.sha_d256(value).appendBlock(value); 146 dataToEncrypt = Clipperz.Crypto.SHA.sha_d256(value).appendBlock(value);
147 147
148 deferredResult = new Clipperz.Async.Deferred("Crypto[0.2].deferredEncrypt") 148 deferredResult = new Clipperz.Async.Deferred("Crypto[0.2].deferredEncrypt")
149 deferredResult.addCallback(Clipperz.Crypto.AES.deferredEncrypt, key, dataToEncrypt, aNonce); 149 deferredResult.addCallback(Clipperz.Crypto.AES.deferredEncrypt, key, dataToEncrypt, aNonce);
150 deferredResult.addCallback(function(aResult) { 150 deferredResult.addCallback(function(aResult) {
151 return aResult.toBase64String(); 151 return aResult.toBase64String();
152 }) 152 })
153 deferredResult.callback(); 153 deferredResult.callback();
154 154
155 return deferredResult; 155 return deferredResult;
156 }, 156 },
157 157
158 'decrypt': function(aKey, aValue) { 158 'decrypt': function(aKey, aValue) {
159 var result; 159 var result;
160 160
161 if (aValue != null) { 161 if (aValue != null) {
162 var key, value; 162 var key, value;
163 var decryptedData; 163 var decryptedData;
164 var decryptedValue; 164 var decryptedValue;
165 165
166 key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey)); 166 key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey));
167 value = new Clipperz.ByteArray().appendBase64String(aValue); 167 value = new Clipperz.ByteArray().appendBase64String(aValue);
168 168
169 decryptedData = Clipperz.Crypto.AES.decrypt(key, value); 169 decryptedData = Clipperz.Crypto.AES.decrypt(key, value);
170 decryptedValue = decryptedData.split((256/8)); 170 decryptedValue = decryptedData.split((256/8));
171 171
172 try { 172 try {
173 result = Clipperz.Base.evalJSON(decryptedValue.asString()); 173 result = Clipperz.Base.evalJSON(decryptedValue.asString());
174 } catch (exception) { 174 } catch (exception) {
175 Clipperz.logError("Error while decrypting data [1]"); 175 Clipperz.logError("Error while decrypting data [1]");
176 throw Clipperz.Crypto.Base.exception.CorruptedMessage; 176 throw Clipperz.Crypto.Base.exception.CorruptedMessage;
177 } 177 }
178 } else { 178 } else {
179 result = null; 179 result = null;
180 } 180 }
181 181
182 return result; 182 return result;
183 }, 183 },
184 184
185 'deferredDecrypt': function(aKey, aValue) { 185 'deferredDecrypt': function(aKey, aValue) {
186 var result; 186 var result;
187 187
188 if (aValue != null) { 188 if (aValue != null) {
189 var deferredResult; 189 var deferredResult;
190 var key, value; 190 var key, value;
191 // var decryptedData; 191 // var decryptedData;
192 192
193 key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey)); 193 key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey));
194 value = new Clipperz.ByteArray().appendBase64String(aValue); 194 value = new Clipperz.ByteArray().appendBase64String(aValue);
195 195
196 deferredResult = new Clipperz.Async.Deferred("Crypto.[0.2].deferredDecrypt"); 196 deferredResult = new Clipperz.Async.Deferred("Crypto.[0.2].deferredDecrypt");
197 deferredResult.addCallback(Clipperz.Crypto.AES.deferredDecrypt, key, value); 197 deferredResult.addCallback(Clipperz.Crypto.AES.deferredDecrypt, key, value);
198 deferredResult.addCallback(function(aResult) { 198 deferredResult.addCallback(function(aResult) {
199 var result; 199 var result;
200 var decryptedData; 200 var decryptedData;
201 201
202 decryptedData = aResult.split((256/8)); 202 decryptedData = aResult.split((256/8));
203 203
204 try { 204 try {
205 result = Clipperz.Base.evalJSON(decryptedData.asString()); 205 result = Clipperz.Base.evalJSON(decryptedData.asString());
206 } catch (exception) { 206 } catch (exception) {
207 Clipperz.logError("Error while decrypting data [2]"); 207 Clipperz.logError("Error while decrypting data [2]");
208 throw Clipperz.Crypto.Base.exception.CorruptedMessage; 208 throw Clipperz.Crypto.Base.exception.CorruptedMessage;
209 } 209 }
210 210
211 return result; 211 return result;
212 }) 212 })
213 deferredResult.callback(); 213 deferredResult.callback();
214 214
215 result = deferredResult; 215 result = deferredResult;
216 } else { 216 } else {
217 result = MochiKit.Async.succeed(null); 217 result = MochiKit.Async.succeed(null);
218 } 218 }
219 219
220 return result; 220 return result;
221 }, 221 },
222 222
223 'hash': Clipperz.Crypto.SHA.sha_d256, 223 'hash': Clipperz.Crypto.SHA.sha_d256,
224 224
225 'deriveKey': function(aStringValue) { 225 'deriveKey': function(aStringValue) {
226 varbyteData; 226 varbyteData;
227 var result; 227 var result;
228 228
229 byteData = new Clipperz.ByteArray(aStringValue); 229 byteData = new Clipperz.ByteArray(aStringValue);
230 result = Clipperz.Crypto.SHA.sha_d256(byteData); 230 result = Clipperz.Crypto.SHA.sha_d256(byteData);
231 231
232 return result; 232 return result;
233 } 233 }
234 }, 234 },
235 235
236 //##################################################################### 236 //#####################################################################
237 237
238 '0.3': { 238 '0.3': {
239 'encrypt': function(aKey, aValue, aNonce) { 239 'encrypt': function(aKey, aValue, aNonce) {
240 var result; 240 var result;
241 varkey, value; 241 varkey, value;
242 var data; 242 var data;
243 var dataToEncrypt; 243 var dataToEncrypt;
244 var encryptedData; 244 var encryptedData;
245 245
246 key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey)); 246 key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey));
247 value = Clipperz.Base.serializeJSON(aValue); 247 value = Clipperz.Base.serializeJSON(aValue);
248 data = new Clipperz.ByteArray(value); 248 data = new Clipperz.ByteArray(value);
249 encryptedData = Clipperz.Crypto.AES.encrypt(key, data, aNonce); 249 encryptedData = Clipperz.Crypto.AES.encrypt(key, data, aNonce);
250 result = encryptedData.toBase64String(); 250 result = encryptedData.toBase64String();
251 251
252 return result; 252 return result;
253 }, 253 },
254 254
255 'deferredEncrypt': function(aKey, aValue, aNonce) { 255 'deferredEncrypt': function(aKey, aValue, aNonce) {
256 var deferredResult; 256 var deferredResult;
257 varkey, value; 257 varkey, value;
258 var data; 258 var data;
259 var dataToEncrypt; 259 var dataToEncrypt;
260 var encryptedData; 260 var encryptedData;
261 261
262 key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey)); 262 key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey));
263 value = Clipperz.Base.serializeJSON(aValue); 263 value = Clipperz.Base.serializeJSON(aValue);
264 data = new Clipperz.ByteArray(value); 264 data = new Clipperz.ByteArray(value);
265 265
266 deferredResult = new Clipperz.Async.Deferred("Crypto[0.3].deferredEncrypt") 266 deferredResult = new Clipperz.Async.Deferred("Crypto[0.3].deferredEncrypt")
267 deferredResult.addCallback(Clipperz.Crypto.AES.deferredEncrypt, key, data, aNonce); 267 deferredResult.addCallback(Clipperz.Crypto.AES.deferredEncrypt, key, data, aNonce);
268 deferredResult.addCallback(function(aResult) { 268 deferredResult.addCallback(function(aResult) {
269 return aResult.toBase64String(); 269 return aResult.toBase64String();
270 }) 270 })
271 deferredResult.callback(); 271 deferredResult.callback();
272 272
273 return deferredResult; 273 return deferredResult;
274 }, 274 },
275 275
276 'decrypt': function(aKey, aValue) { 276 'decrypt': function(aKey, aValue) {
277 var result; 277 var result;
278 278
279 if (aValue != null) { 279 if (aValue != null) {
280 var key, value; 280 var key, value;
281 var decryptedData; 281 var decryptedData;
282 282
283 key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey)); 283 key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey));
284 value = new Clipperz.ByteArray().appendBase64String(aValue); 284 value = new Clipperz.ByteArray().appendBase64String(aValue);
285 285
286 decryptedData = Clipperz.Crypto.AES.decrypt(key, value); 286 decryptedData = Clipperz.Crypto.AES.decrypt(key, value);
287 287
288 value = decryptedData.asString(); 288 value = decryptedData.asString();
289 try { 289 try {
290 result = Clipperz.Base.evalJSON(value); 290 result = Clipperz.Base.evalJSON(value);
291 } catch (exception) { 291 } catch (exception) {
292 Clipperz.logError("Error while decrypting data [3]"); 292 Clipperz.logError("Error while decrypting data [3]");
293 throw Clipperz.Crypto.Base.exception.CorruptedMessage; 293 throw Clipperz.Crypto.Base.exception.CorruptedMessage;
294 } 294 }
295 } else { 295 } else {
296 result = null; 296 result = null;
297 } 297 }
298 298
299 return result; 299 return result;
300 }, 300 },
301 301
302 'deferredDecrypt': function(aKey, aValue) { 302 'deferredDecrypt': function(aKey, aValue) {
303 var deferredResult; 303 var deferredResult;
304 304
305 deferredResult = new Clipperz.Async.Deferred("Crypto[0.3].deferredDecrypt", {trace: false}); 305 deferredResult = new Clipperz.Async.Deferred("Crypto[0.3].deferredDecrypt", {trace: false});
306 // now = new Date; 306 // now = new Date;
307 307
308 if (aValue != null) { 308 if (aValue != null) {
309 var key, value; 309 var key, value;
310 // var decryptedData; 310 // var decryptedData;
311 311
312 key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey)); 312 key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey));
313 value = new Clipperz.ByteArray().appendBase64String(aValue); 313 value = new Clipperz.ByteArray().appendBase64String(aValue);
314 314
315 deferredResult.addCallback(Clipperz.Crypto.AES.deferredDecrypt, key, value); 315 deferredResult.addCallback(Clipperz.Crypto.AES.deferredDecrypt, key, value);
316 deferredResult.addCallback(MochiKit.Async.wait, 0.1); 316 deferredResult.addCallback(MochiKit.Async.wait, 0.1);
317 deferredResult.addCallback(function(aResult) { 317 deferredResult.addCallback(function(aResult) {
318 return aResult.asString(); 318 return aResult.asString();
319 }); 319 });
320 deferredResult.addCallback(MochiKit.Async.wait, 0.1); 320 deferredResult.addCallback(MochiKit.Async.wait, 0.1);
321 deferredResult.addCallback(Clipperz.Base.evalJSON); 321 deferredResult.addCallback(Clipperz.Base.evalJSON);
322 deferredResult.addErrback(function(anError) { 322 deferredResult.addErrback(function(anError) {
323console.log("PIPPO_1", anError)
323 Clipperz.logError("Error while decrypting data [4]"); 324 Clipperz.logError("Error while decrypting data [4]");
324 throw Clipperz.Crypto.Base.exception.CorruptedMessage; 325 throw Clipperz.Crypto.Base.exception.CorruptedMessage;
325 }) 326 })
326 } else { 327 } else {
327 deferredResult.addCallback(function() { 328 deferredResult.addCallback(function() {
328 return null; 329 return null;
329 }); 330 });
330 } 331 }
331 deferredResult.callback(); 332 deferredResult.callback();
332 333
333 return deferredResult; 334 return deferredResult;
334 }, 335 },
335 336
336 'hash': Clipperz.Crypto.SHA.sha_d256, 337 'hash': Clipperz.Crypto.SHA.sha_d256,
337 338
338 'deriveKey': function(aStringValue) { 339 'deriveKey': function(aStringValue) {
339 varbyteData; 340 varbyteData;
340 var result; 341 var result;
341 342
342 byteData = new Clipperz.ByteArray(aStringValue); 343 byteData = new Clipperz.ByteArray(aStringValue);
343 result = Clipperz.Crypto.SHA.sha_d256(byteData); 344 result = Clipperz.Crypto.SHA.sha_d256(byteData);
344 345
345 return result; 346 return result;
346 } 347 }
347
348 }, 348 },
349 349
350 //##################################################################### 350 //#####################################################################
351/* 351
352 '0.4': { 352 '0.4': {
353 'encrypt': function(aKey, aValue, aNonce) { 353 'encrypt': function(aKey, aValue, aNonce) {
354 var result; 354 var result;
355 varkey, value; 355 varkey, value;
356 var data; 356 var data;
357 var dataToEncrypt; 357 var dataToEncrypt;
358 var encryptedData; 358 var encryptedData;
359 359
360//Clipperz.logDebug(">>> [" + (new Date()).valueOf() + "] Clipperz.PM.Crypto.versions[0.3].encrypt");
361 key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey)); 360 key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey));
362//Clipperz.logDebug("--- [" + (new Date()).valueOf() + "] Clipperz.PM.Crypto.versions[0.3].encrypt - 1");
363 value = Clipperz.Base.serializeJSON(aValue); 361 value = Clipperz.Base.serializeJSON(aValue);
364//Clipperz.logDebug("--- [" + (new Date()).valueOf() + "] Clipperz.PM.Crypto.versions[0.3].encrypt - 2");
365/ *
366//Clipperz.logDebug("--> encrypt.fullSize: " + value.length);
367 value = value.replace(/":{"label":"/g, '":{l:"');
368 value = value.replace(/":{"key":"/g, '":{k:"');
369 value = value.replace(/":{"notes":"/g, '":{n:"');
370 value = value.replace(/":{"record":"/g, '":{r:"');
371 value = value.replace(/", "label":"/g, '",l:"');
372 value = value.replace(/", "favicon":"/g,'",f:"');
373//Clipperz.logDebug("<-- encrypt.compressed: " + value.length);
374* /
375 data = new Clipperz.ByteArray(value); 362 data = new Clipperz.ByteArray(value);
376//Clipperz.logDebug("--- [" + (new Date()).valueOf() + "] Clipperz.PM.Crypto.versions[0.3].encrypt - 3"); 363 encryptedData = Clipperz.Crypto.AES_2.encrypt(key, data, aNonce);
377 encryptedData = Clipperz.Crypto.AES.encrypt(key, data, aNonce);
378//Clipperz.logDebug("--- [" + (new Date()).valueOf() + "] Clipperz.PM.Crypto.versions[0.3].encrypt - 4");
379 result = encryptedData.toBase64String(); 364 result = encryptedData.toBase64String();
380//Clipperz.logDebug("<<< [" + (new Date()).valueOf() + "] Clipperz.PM.Crypto.versions[0.3].encrypt");
381 365
382 return result; 366 return result;
383 }, 367 },
368
369 'deferredEncrypt': function(aKey, aValue, aNonce) {
370 var deferredResult;
371 varkey, value;
372 var data;
373 var dataToEncrypt;
374 var encryptedData;
375
376 key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey));
377 value = Clipperz.Base.serializeJSON(aValue);
378 data = new Clipperz.ByteArray(value);
379
380 deferredResult = new Clipperz.Async.Deferred("Crypto[0.4].deferredEncrypt")
381 deferredResult.addCallback(Clipperz.Crypto.AES_2.deferredEncrypt, key, data, aNonce);
382 deferredResult.addCallback(function(aResult) {
383 return aResult.toBase64String();
384 })
385 deferredResult.callback();
386
387 return deferredResult;
388 },
384 389
385 'decrypt': function(aKey, aValue) { 390 'decrypt': function(aKey, aValue) {
386 var result; 391 var result;
387 392
388 if (aValue != null) { 393 if (aValue != null) {
389 var key, value; 394 var key, value;
390 var decryptedData; 395 var decryptedData;
391 396
392 key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey)); 397 key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey));
393 value = new Clipperz.ByteArray().appendBase64String(aValue); 398 value = new Clipperz.ByteArray().appendBase64String(aValue);
394 399
395 decryptedData = Clipperz.Crypto.AES.decrypt(key, value); 400 decryptedData = Clipperz.Crypto.AES_2.decrypt(key, value);
396 401
397 value = decryptedData.asString(); 402 value = decryptedData.asString();
398/ *
399 value = value.replace(/":{l:"/g,'":{"label":"');
400 value = value.replace(/":{k:"/g,'":{"key":"');
401 value = value.replace(/":{n:"/g,'":{"notes":"');
402 value = value.replace(/":{r:"/g,'":{"record":"');
403 value = value.replace(/",l:"/g, '", "label":"');
404 value = value.replace(/",f:"/g, '", "favicon":"');
405* /
406 try { 403 try {
407 result = Clipperz.Base.evalJSON(value); 404 result = Clipperz.Base.evalJSON(value);
408 } catch (exception) { 405 } catch (exception) {
409 Clipperz.logError("Error while decrypting data"); 406 console.log("PIPPO_2", anError)
407 Clipperz.logError("Error while decrypting data [4]");
410 throw Clipperz.Crypto.Base.exception.CorruptedMessage; 408 throw Clipperz.Crypto.Base.exception.CorruptedMessage;
411 } 409 }
412
413
414 } else { 410 } else {
415 result = null; 411 result = null;
416 } 412 }
417 413
418 return result; 414 return result;
419 }, 415 },
420 416
421 'hash': Clipperz.Crypto.SHA.sha_d256 417 'deferredDecrypt': function(aKey, aValue) {
418 var deferredResult;
419
420 deferredResult = new Clipperz.Async.Deferred("Crypto[0.4].deferredDecrypt", {trace: false});
421
422 if (aValue != null) {
423 var key, value;
424
425 key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey));
426 value = new Clipperz.ByteArray().appendBase64String(aValue);
427
428 deferredResult.addCallback(Clipperz.Crypto.AES_2.deferredDecrypt, key, value);
429 deferredResult.addCallback(MochiKit.Async.wait, 0.1);
430 deferredResult.addCallback(function(aResult) {
431 return aResult.asString();
432 });
433 deferredResult.addCallback(MochiKit.Async.wait, 0.1);
434 deferredResult.addCallback(Clipperz.Base.evalJSON);
435 deferredResult.addErrback(function(anError) {
436 Clipperz.logError("Error while decrypting data [4]");
437 throw Clipperz.Crypto.Base.exception.CorruptedMessage;
438 })
439 } else {
440 deferredResult.addCallback(function() {
441 return null;
442 });
443 }
444 deferredResult.callback();
445
446 return deferredResult;
447 },
448
449 'hash': Clipperz.Crypto.SHA.sha_d256,
450
451 'deriveKey': function(aStringValue) {
452 varbyteData;
453 var result;
454
455 byteData = new Clipperz.ByteArray(aStringValue);
456 result = Clipperz.Crypto.SHA.sha_d256(byteData);
457
458 return result;
459 }
422 }, 460 },
423*/ 461
424 //##################################################################### 462 //#####################################################################
425 __syntaxFix__: "syntax fix" 463 __syntaxFix__: "syntax fix"
426 } 464 }
427 }, 465 },
428 466
429 //------------------------------------------------------------------------- 467 //-------------------------------------------------------------------------
430 468
431 'encrypt': function(aKey, aValue, aVersion) { 469 'encrypt': function(aKey, aValue, aVersion) {
432 return Clipperz.PM.Crypto.encryptingFunctions.versions[aVersion].encrypt(aKey, aValue); 470 return Clipperz.PM.Crypto.encryptingFunctions.versions[aVersion].encrypt(aKey, aValue);
433 }, 471 },
434 472
435 'deferredEncrypt': function(someParameters) { 473 'deferredEncrypt': function(someParameters) {
436 return Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters['version']].deferredEncrypt(someParameters['key'], someParameters['value']); 474 return Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters['version']].deferredEncrypt(someParameters['key'], someParameters['value']);
437 }, 475 },
438 476
439 //......................................................................... 477 //.........................................................................
440 478
441 'decrypt': function(aKey, aValue, aVersion) { 479 'decrypt': function(aKey, aValue, aVersion) {
442 return Clipperz.PM.Crypto.encryptingFunctions.versions[aVersion].decrypt(aKey, aValue); 480 return Clipperz.PM.Crypto.encryptingFunctions.versions[aVersion].decrypt(aKey, aValue);
443 }, 481 },
444 482
445 'deferredDecrypt': function(someParameters) { 483 'deferredDecrypt': function(someParameters) {
446 return Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters['version']].deferredDecrypt(someParameters['key'], someParameters['value']); 484 return Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters['version']].deferredDecrypt(someParameters['key'], someParameters['value']);
447 }, 485 },
448 486
449 //------------------------------------------------------------------------- 487 //-------------------------------------------------------------------------
450 488
451 'hash': function(aValue) { 489 'hash': function(aValue) {
452 return Clipperz.PM.Crypto.encryptingFunctions.versions[Clipperz.PM.Crypto.encryptingFunctions.currentVersion]['hash'](aValue); 490 return Clipperz.PM.Crypto.encryptingFunctions.versions[Clipperz.PM.Crypto.encryptingFunctions.currentVersion]['hash'](aValue);
453 }, 491 },
454 492
455 //------------------------------------------------------------------------- 493 //-------------------------------------------------------------------------
456 494
457 'randomKey': function() { 495 'randomKey': function() {
458 return Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2); 496 return Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2);
459 }, 497 },
460 498
461 //------------------------------------------------------------------------- 499 //-------------------------------------------------------------------------
462 500
463 'deriveKey': function(aValue) { 501 'deriveKey': function(aValue) {
464 return Clipperz.PM.Crypto.encryptingFunctions.versions[Clipperz.PM.Crypto.encryptingFunctions.currentVersion].deriveKey(aValue); 502 return Clipperz.PM.Crypto.encryptingFunctions.versions[Clipperz.PM.Crypto.encryptingFunctions.currentVersion].deriveKey(aValue);
465 }, 503 },
466 504
467 //------------------------------------------------------------------------- 505 //-------------------------------------------------------------------------
468 506
469 'passwordEntropy': function(aValue) { 507 'passwordEntropy': function(aValue) {
470 var result; 508 var result;
471 varbitPerChar; 509 varbitPerChar;
472 510
473 bitPerChar = 4; 511 bitPerChar = 4;
474 if (/[a-z]/.test(aValue)) { 512 if (/[a-z]/.test(aValue)) {
475 bitPerChar ++; 513 bitPerChar ++;
476 } 514 }
477 if (/[A-Z]/.test(aValue)) { 515 if (/[A-Z]/.test(aValue)) {
478 bitPerChar ++; 516 bitPerChar ++;
479 } 517 }
480 if (/[^a-zA-Z0-9]/.test(aValue)) { 518 if (/[^a-zA-Z0-9]/.test(aValue)) {
481 bitPerChar ++; 519 bitPerChar ++;
482 } 520 }
483 521
484 result = aValue.length * bitPerChar; 522 result = aValue.length * bitPerChar;
485 523
486 return result; 524 return result;
487 }, 525 },
488 526
489 //------------------------------------------------------------------------- 527 //-------------------------------------------------------------------------
490 528
491 'nullValue': '####', 529 'nullValue': '####',
492 530
493 //------------------------------------------------------------------------- 531 //-------------------------------------------------------------------------
494 __syntaxFix__: "syntax fix" 532 __syntaxFix__: "syntax fix"
495 533
496}); 534});
497 535
498//***************************************************************************** 536//*****************************************************************************
499 537
500//MochiKit.Base.update(Clipperz.PM.Connection.communicationProtocol.versions, { 538//MochiKit.Base.update(Clipperz.PM.Connection.communicationProtocol.versions, {
501 //'current': Clipperz.PM.Connection.communicationProtocol.versions[Clipperz.PM.Connection.communicationProtocol.currentVersion] 539 //'current': Clipperz.PM.Connection.communicationProtocol.versions[Clipperz.PM.Connection.communicationProtocol.currentVersion]
502//}); 540//});
503 541
504MochiKit.Base.update(Clipperz.PM.Crypto.encryptingFunctions.versions, { 542MochiKit.Base.update(Clipperz.PM.Crypto.encryptingFunctions.versions, {
505 'current': Clipperz.PM.Crypto.encryptingFunctions.versions[Clipperz.PM.Crypto.encryptingFunctions.currentVersion] 543 'current': Clipperz.PM.Crypto.encryptingFunctions.versions[Clipperz.PM.Crypto.encryptingFunctions.currentVersion]
506}); 544});
507 545
508//***************************************************************************** 546//*****************************************************************************
diff --git a/frontend/gamma/js/Clipperz/PM/DataModel/User.js b/frontend/gamma/js/Clipperz/PM/DataModel/User.js
index fd18faf..b94fe4c 100644
--- a/frontend/gamma/js/Clipperz/PM/DataModel/User.js
+++ b/frontend/gamma/js/Clipperz/PM/DataModel/User.js
@@ -1,810 +1,810 @@
1/* 1/*
2 2
3Copyright 2008-2013 Clipperz Srl 3Copyright 2008-2013 Clipperz Srl
4 4
5This file is part of Clipperz, the online password manager. 5This file is part of Clipperz, the online password manager.
6For further information about its features and functionalities please 6For further information about its features and functionalities please
7refer to http://www.clipperz.com. 7refer to http://www.clipperz.com.
8 8
9* Clipperz is free software: you can redistribute it and/or modify it 9* Clipperz is free software: you can redistribute it and/or modify it
10 under the terms of the GNU Affero General Public License as published 10 under the terms of the GNU Affero General Public License as published
11 by the Free Software Foundation, either version 3 of the License, or 11 by the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version. 12 (at your option) any later version.
13 13
14* Clipperz is distributed in the hope that it will be useful, but 14* Clipperz is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of 15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU Affero General Public License for more details. 17 See the GNU Affero General Public License for more details.
18 18
19* You should have received a copy of the GNU Affero General Public 19* You should have received a copy of the GNU Affero General Public
20 License along with Clipperz. If not, see http://www.gnu.org/licenses/. 20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
21 21
22*/ 22*/
23 23
24if (typeof(Clipperz) == 'undefined') { Clipperz = {}; } 24if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
25if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; } 25if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; }
26if (typeof(Clipperz.PM.DataModel) == 'undefined') { Clipperz.PM.DataModel = {}; } 26if (typeof(Clipperz.PM.DataModel) == 'undefined') { Clipperz.PM.DataModel = {}; }
27 27
28 28
29//############################################################################# 29//#############################################################################
30 30
31Clipperz.PM.DataModel.User = function (args) { 31Clipperz.PM.DataModel.User = function (args) {
32 args = args || {}; 32 args = args || {};
33 33
34 Clipperz.PM.DataModel.User.superclass.constructor.apply(this, arguments); 34 Clipperz.PM.DataModel.User.superclass.constructor.apply(this, arguments);
35 35
36 this._username = args.username || null; 36 this._username = args.username || null;
37 this._getPassphraseFunction = args.getPassphraseFunction || null; 37 this._getPassphraseFunction = args.getPassphraseFunction || null;
38 38
39 this._data = null; 39 this._data = null;
40 40
41 this._connection = null; 41 this._connection = null;
42 this._connectionVersion = 'current'; 42 this._connectionVersion = 'current';
43 43
44 this._serverData = null; 44 this._serverData = null;
45 //this._serverLockValue = null; 45 //this._serverLockValue = null;
46 this._transientState = null; 46 this._transientState = null;
47 47
48 this._deferredLocks = { 48 this._deferredLocks = {
49 'passphrase': new MochiKit.Async.DeferredLock(), 49 'passphrase': new MochiKit.Async.DeferredLock(),
50 'serverData': new MochiKit.Async.DeferredLock(), 50 'serverData': new MochiKit.Async.DeferredLock(),
51 // 'recordsIndex': new MochiKit.Async.DeferredLock(), 51 // 'recordsIndex': new MochiKit.Async.DeferredLock(),
52 // 'directLoginsIndex':new MochiKit.Async.DeferredLock() 52 // 'directLoginsIndex':new MochiKit.Async.DeferredLock()
53 // 'preferences': new MochiKit.Async.DeferredLock() 53 // 'preferences': new MochiKit.Async.DeferredLock()
54 // 'oneTimePasswords': new MochiKit.Async.DeferredLock() 54 // 'oneTimePasswords': new MochiKit.Async.DeferredLock()
55 '__syntaxFix__': 'syntax fix' 55 '__syntaxFix__': 'syntax fix'
56 }; 56 };
57 57
58 return this; 58 return this;
59} 59}
60 60
61Clipperz.Base.extend(Clipperz.PM.DataModel.User, Object, { 61Clipperz.Base.extend(Clipperz.PM.DataModel.User, Object, {
62 62
63 'toString': function () { 63 'toString': function () {
64 return "Clipperz.PM.DataModel.User - " + this.username(); 64 return "Clipperz.PM.DataModel.User - " + this.username();
65 }, 65 },
66 66
67 //------------------------------------------------------------------------- 67 //-------------------------------------------------------------------------
68 68
69 'username': function () { 69 'username': function () {
70 return this._username; 70 return this._username;
71 }, 71 },
72 72
73 'setUsername': function (aValue) { 73 'setUsername': function (aValue) {
74 this._username = aValue; 74 this._username = aValue;
75 }, 75 },
76 76
77 //------------------------------------------------------------------------- 77 //-------------------------------------------------------------------------
78 78
79 'displayName': function() { 79 'displayName': function() {
80 return "" + this.username() + ""; 80 return "" + this.username() + "";
81 }, 81 },
82 82
83 //------------------------------------------------------------------------- 83 //-------------------------------------------------------------------------
84 84
85 'data': function () { 85 'data': function () {
86 if (this._data == null) { 86 if (this._data == null) {
87 this._data = new Clipperz.KeyValueObjectStore(/*{'name':'User.data [1]'}*/); 87 this._data = new Clipperz.KeyValueObjectStore(/*{'name':'User.data [1]'}*/);
88 }; 88 };
89 89
90 return this._data; 90 return this._data;
91 }, 91 },
92 92
93 //------------------------------------------------------------------------- 93 //-------------------------------------------------------------------------
94/* 94/*
95 'serverLockValue': function () { 95 'serverLockValue': function () {
96 return this._serverLockValue; 96 return this._serverLockValue;
97 }, 97 },
98 98
99 'setServerLockValue': function (aValue) { 99 'setServerLockValue': function (aValue) {
100 this._serverLockValue = aValue; 100 this._serverLockValue = aValue;
101 }, 101 },
102*/ 102*/
103 //------------------------------------------------------------------------- 103 //-------------------------------------------------------------------------
104 104
105 'transientState': function () { 105 'transientState': function () {
106 if (this._transientState == null) { 106 if (this._transientState == null) {
107 this._transientState = {} 107 this._transientState = {}
108 } 108 }
109 109
110 return this._transientState; 110 return this._transientState;
111 }, 111 },
112 112
113 'resetTransientState': function (isCommitting) { 113 'resetTransientState': function (isCommitting) {
114 this._transientState = null; 114 this._transientState = null;
115 }, 115 },
116 116
117 //------------------------------------------------------------------------- 117 //-------------------------------------------------------------------------
118 118
119 'deferredLockForSection': function(aSectionName) { 119 'deferredLockForSection': function(aSectionName) {
120 return this._deferredLocks[aSectionName]; 120 return this._deferredLocks[aSectionName];
121 }, 121 },
122 122
123 //------------------------------------------------------------------------- 123 //-------------------------------------------------------------------------
124 124
125 'getPassphrase': function() { 125 'getPassphrase': function() {
126 var deferredResult; 126 var deferredResult;
127 127
128 deferredResult = new Clipperz.Async.Deferred("User.getPassphrase", {trace:false}); 128 deferredResult = new Clipperz.Async.Deferred("User.getPassphrase", {trace:false});
129 deferredResult.acquireLock(this.deferredLockForSection('passphrase')); 129 deferredResult.acquireLock(this.deferredLockForSection('passphrase'));
130 deferredResult.addMethod(this.data(), 'deferredGetOrSet', 'passphrase', this.getPassphraseFunction()); 130 deferredResult.addMethod(this.data(), 'deferredGetOrSet', 'passphrase', this.getPassphraseFunction());
131 deferredResult.releaseLock(this.deferredLockForSection('passphrase')); 131 deferredResult.releaseLock(this.deferredLockForSection('passphrase'));
132 deferredResult.callback(); 132 deferredResult.callback();
133 133
134 return deferredResult; 134 return deferredResult;
135 }, 135 },
136 136
137 'getPassphraseFunction': function () { 137 'getPassphraseFunction': function () {
138 return this._getPassphraseFunction; 138 return this._getPassphraseFunction;
139 }, 139 },
140 140
141 //------------------------------------------------------------------------- 141 //-------------------------------------------------------------------------
142 142
143 'getCredentials': function () { 143 'getCredentials': function () {
144 return Clipperz.Async.collectResults("User; get username and passphrase", { 144 return Clipperz.Async.collectResults("User; get username and passphrase", {
145 'username': MochiKit.Base.method(this, 'username'), 145 'username': MochiKit.Base.method(this, 'username'),
146 'password': MochiKit.Base.method(this, 'getPassphrase') 146 'password': MochiKit.Base.method(this, 'getPassphrase')
147 }, {trace:false})(); 147 }, {trace:false})();
148 }, 148 },
149 149
150 //------------------------------------------------------------------------- 150 //-------------------------------------------------------------------------
151 151
152 'changePassphrase': function (aNewValue) { 152 'changePassphrase': function (aNewValue) {
153 return this.updateCredentials(this.username(), aNewValue); 153 return this.updateCredentials(this.username(), aNewValue);
154 }, 154 },
155 155
156 //......................................................................... 156 //.........................................................................
157 157
158 'updateCredentials': function (aUsername, aPassphrase) { 158 'updateCredentials': function (aUsername, aPassphrase) {
159 vardeferredResult; 159 vardeferredResult;
160 160
161 deferredResult = new Clipperz.Async.Deferred("User.updateCredentials", {trace:false}); 161 deferredResult = new Clipperz.Async.Deferred("User.updateCredentials", {trace:false});
162 // deferredResult.addMethod(this, 'getPassphrase'); 162 // deferredResult.addMethod(this, 'getPassphrase');
163 // deferredResult.setValue('currentPassphrase'); 163 // deferredResult.setValue('currentPassphrase');
164 deferredResult.addMethod(this.connection(), 'ping'); 164 deferredResult.addMethod(this.connection(), 'ping');
165 deferredResult.addMethod(this, 'setUsername', aUsername) 165 deferredResult.addMethod(this, 'setUsername', aUsername)
166 deferredResult.acquireLock(this.deferredLockForSection('passphrase')); 166 deferredResult.acquireLock(this.deferredLockForSection('passphrase'));
167 deferredResult.addMethod(this.data(), 'deferredGetOrSet', 'passphrase', aPassphrase); 167 deferredResult.addMethod(this.data(), 'deferredGetOrSet', 'passphrase', aPassphrase);
168 deferredResult.releaseLock(this.deferredLockForSection('passphrase')); 168 deferredResult.releaseLock(this.deferredLockForSection('passphrase'));
169 // deferredResult.getValue('currentPassphrase'); 169 // deferredResult.getValue('currentPassphrase');
170 deferredResult.addMethod(this, 'prepareRemoteDataWithKey', aPassphrase); 170 deferredResult.addMethod(this, 'prepareRemoteDataWithKey', aPassphrase);
171 deferredResult.addMethod(this.connection(), 'updateCredentials', aUsername, aPassphrase); 171 deferredResult.addMethod(this.connection(), 'updateCredentials', aUsername, aPassphrase);
172 deferredResult.callback(); 172 deferredResult.callback();
173 173
174 return deferredResult; 174 return deferredResult;
175 }, 175 },
176 176
177 //------------------------------------------------------------------------- 177 //-------------------------------------------------------------------------
178 178
179 'initialSetupWithNoData': function () { 179 'initialSetupWithNoData': function () {
180 this._serverData = { 180 this._serverData = {
181 'version': '0.1', 181 'version': '0.1',
182 'statistics': "", 182 'statistics': "",
183 'header': { 183 'header': {
184 'data': null, 184 'data': null,
185 'version': Clipperz.PM.Crypto.encryptingFunctions.currentVersion, 185 'version': Clipperz.PM.Crypto.encryptingFunctions.currentVersion,
186 186
187 'recordsIndex': new Clipperz.PM.DataModel.User.Header.RecordIndex({ 187 'recordsIndex': new Clipperz.PM.DataModel.User.Header.RecordIndex({
188 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase'), 188 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase'),
189 'recordsData': {'data':null, 'index':{}}, 189 'recordsData': {'data':null, 'index':{}},
190 'recordsStats': null, 190 'recordsStats': null,
191 'directLoginsData': {'data':null, 'index':{}}, 191 'directLoginsData': {'data':null, 'index':{}},
192 'encryptedDataVersion': Clipperz.PM.Crypto.encryptingFunctions.currentVersion, 192 'encryptedDataVersion': Clipperz.PM.Crypto.encryptingFunctions.currentVersion,
193 'retrieveRecordDetailFunction':MochiKit.Base.method(this, 'getRecordDetail') 193 'retrieveRecordDetailFunction':MochiKit.Base.method(this, 'getRecordDetail')
194 }), 194 }),
195 'preferences': new Clipperz.PM.DataModel.User.Header.Preferences({ 195 'preferences': new Clipperz.PM.DataModel.User.Header.Preferences({
196 'name':'preferences', 196 'name':'preferences',
197 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase') 197 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase')
198 }), 198 }),
199 'oneTimePasswords': new Clipperz.PM.DataModel.User.Header.OneTimePasswords({ 199 'oneTimePasswords': new Clipperz.PM.DataModel.User.Header.OneTimePasswords({
200 'name':'preferences', 200 'name':'preferences',
201 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase') 201 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase')
202 }) 202 })
203 } 203 }
204 }; 204 };
205 205
206 // this._serverLockValue = Clipperz.PM.Crypto.randomKey(); 206 // this._serverLockValue = Clipperz.PM.Crypto.randomKey();
207 }, 207 },
208 208
209 //......................................................................... 209 //.........................................................................
210 210
211 'registerAsNewAccount': function () { 211 'registerAsNewAccount': function () {
212 var deferredResult; 212 var deferredResult;
213 213
214 deferredResult = new Clipperz.Async.Deferred("User.registerAsNewAccount", {trace:false}); 214 deferredResult = new Clipperz.Async.Deferred("User.registerAsNewAccount", {trace:false});
215 deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'updateProgress', {'extraSteps':3}); 215 deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'updateProgress', {'extraSteps':3});
216 deferredResult.addMethod(this, 'initialSetupWithNoData') 216 deferredResult.addMethod(this, 'initialSetupWithNoData')
217 deferredResult.addMethod(this, 'getPassphrase'); 217 deferredResult.addMethod(this, 'getPassphrase');
218 deferredResult.addMethod(this, 'prepareRemoteDataWithKey'); 218 deferredResult.addMethod(this, 'prepareRemoteDataWithKey');
219 deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress'); 219 deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress');
220 deferredResult.addMethod(this.connection(), 'register'); 220 deferredResult.addMethod(this.connection(), 'register');
221 // deferredResult.addCallback(MochiKit.Base.itemgetter('lock')); 221 // deferredResult.addCallback(MochiKit.Base.itemgetter('lock'));
222 // deferredResult.addMethod(this, 'setServerLockValue'); 222 // deferredResult.addMethod(this, 'setServerLockValue');
223 deferredResult.addCallbackPass(MochiKit.Signal.signal,Clipperz.Signal.NotificationCenter, 'userSuccessfullyRegistered'); 223 deferredResult.addCallbackPass(MochiKit.Signal.signal,Clipperz.Signal.NotificationCenter, 'userSuccessfullyRegistered');
224 224
225 // deferredResult.addErrback (MochiKit.Base.method(this, 'handleRegistrationFailure')); 225 // deferredResult.addErrback (MochiKit.Base.method(this, 'handleRegistrationFailure'));
226 226
227 deferredResult.callback(); 227 deferredResult.callback();
228 228
229 return deferredResult; 229 return deferredResult;
230 }, 230 },
231 231
232 //------------------------------------------------------------------------- 232 //-------------------------------------------------------------------------
233 233
234 'login': function () { 234 'login': function () {
235 var deferredResult; 235 var deferredResult;
236 236
237 deferredResult = new Clipperz.Async.Deferred("User.login", {trace:false}); 237 deferredResult = new Clipperz.Async.Deferred("User.login", {trace:false});
238 deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'updateProgress', {'extraSteps':3}); 238 deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'updateProgress', {'extraSteps':3});
239 deferredResult.addMethod(this, 'getPassphrase'); 239 deferredResult.addMethod(this, 'getPassphrase');
240 deferredResult.addCallback(Clipperz.PM.DataModel.OneTimePassword.isValidOneTimePasswordValue); 240 deferredResult.addCallback(Clipperz.PM.DataModel.OneTimePassword.isValidOneTimePasswordValue);
241 deferredResult.addCallback(Clipperz.Async.deferredIf("Is the passphrase an OTP", [ 241 deferredResult.addCallback(Clipperz.Async.deferredIf("Is the passphrase an OTP", [
242 MochiKit.Base.partial(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'updateProgress', {'extraSteps':1}), 242 MochiKit.Base.partial(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'updateProgress', {'extraSteps':1}),
243 MochiKit.Base.method(this, 'getCredentials'), 243 MochiKit.Base.method(this, 'getCredentials'),
244 MochiKit.Base.method(this.connection(), 'redeemOneTimePassword'), 244 MochiKit.Base.method(this.connection(), 'redeemOneTimePassword'),
245 MochiKit.Base.method(this.data(), 'setValue', 'passphrase') 245 MochiKit.Base.method(this.data(), 'setValue', 'passphrase')
246 ], [])); 246 ], []));
247 deferredResult.addErrback(MochiKit.Base.method(this, 'getPassphrase')); 247 deferredResult.addErrback(MochiKit.Base.method(this, 'getPassphrase'));
248 deferredResult.addMethod(this.connection(), 'login', false); 248 deferredResult.addMethod(this.connection(), 'login', false);
249 deferredResult.addCallbackPass(MochiKit.Signal.signal,Clipperz.Signal.NotificationCenter, 'userSuccessfullyLoggedIn'); 249 deferredResult.addCallbackPass(MochiKit.Signal.signal,Clipperz.Signal.NotificationCenter, 'userSuccessfullyLoggedIn');
250 deferredResult.addErrback (MochiKit.Base.method(this, 'handleConnectionFallback')); 250 deferredResult.addErrback (MochiKit.Base.method(this, 'handleConnectionFallback'));
251 251
252 deferredResult.callback(); 252 deferredResult.callback();
253 253
254 return deferredResult; 254 return deferredResult;
255 }, 255 },
256 256
257 //......................................................................... 257 //.........................................................................
258 258
259 'handleConnectionFallback': function(aValue) { 259 'handleConnectionFallback': function(aValue) {
260 var result; 260 var result;
261 261
262 if (aValue instanceof MochiKit.Async.CancelledError) { 262 if (aValue instanceof MochiKit.Async.CancelledError) {
263 result = aValue; 263 result = aValue;
264 } else { 264 } else {
265 this.setConnectionVersion(Clipperz.PM.Connection.communicationProtocol.fallbackVersions[this.connectionVersion()]); 265 this.setConnectionVersion(Clipperz.PM.Connection.communicationProtocol.fallbackVersions[this.connectionVersion()]);
266 266
267 if (this.connectionVersion() != null) { 267 if (this.connectionVersion() != null) {
268 result = new Clipperz.Async.Deferred("User.handleConnectionFallback - retry"); 268 result = new Clipperz.Async.Deferred("User.handleConnectionFallback - retry");
269 269
270 result.addMethod(this, 'login'); 270 result.addMethod(this, 'login');
271 result.callback(); 271 result.callback();
272 } else { 272 } else {
273 result = Clipperz.Async.callbacks("User.handleConnectionFallback - failed", [ 273 result = Clipperz.Async.callbacks("User.handleConnectionFallback - failed", [
274 MochiKit.Base.method(this.data(), 'removeValue', 'passphrase'), 274 MochiKit.Base.method(this.data(), 'removeValue', 'passphrase'),
275 MochiKit.Base.method(this, 'setConnectionVersion', 'current'), 275 MochiKit.Base.method(this, 'setConnectionVersion', 'current'),
276 MochiKit.Base.partial(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'userLoginFailed'), 276 MochiKit.Base.partial(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'userLoginFailed'),
277 MochiKit.Base.partial(MochiKit.Async.fail, Clipperz.PM.DataModel.User.exception.LoginFailed) 277 MochiKit.Base.partial(MochiKit.Async.fail, Clipperz.PM.DataModel.User.exception.LoginFailed)
278 ], {trace:false}); 278 ], {trace:false});
279 } 279 }
280 } 280 }
281 281
282 return result; 282 return result;
283 }, 283 },
284 284
285 //------------------------------------------------------------------------- 285 //-------------------------------------------------------------------------
286 286
287 'lock': function () { 287 'lock': function () {
288 return Clipperz.Async.callbacks("User.lock", [ 288 return Clipperz.Async.callbacks("User.lock", [
289 MochiKit.Base.method(this, 'deleteAllCleanTextData') 289 MochiKit.Base.method(this, 'deleteAllCleanTextData')
290 ], {trace:false}); 290 ], {trace:false});
291 }, 291 },
292 292
293 //------------------------------------------------------------------------- 293 //-------------------------------------------------------------------------
294 294
295 'logout': function () { 295 'logout': function () {
296 return Clipperz.Async.callbacks("User.logout", [ 296 return Clipperz.Async.callbacks("User.logout", [
297 MochiKit.Base.method(this, 'deleteAllCleanTextData'), 297 MochiKit.Base.method(this, 'deleteAllCleanTextData'),
298 MochiKit.Base.method(this.connection(), 'logout') 298 MochiKit.Base.method(this.connection(), 'logout')
299 ], {trace:false}); 299 ], {trace:false});
300 }, 300 },
301 301
302 //------------------------------------------------------------------------- 302 //-------------------------------------------------------------------------
303 303
304 'headerFormatVersion': function(anHeader) { 304 'headerFormatVersion': function(anHeader) {
305 var result; 305 var result;
306 306
307 if (anHeader.charAt(0) == '{') { 307 if (anHeader.charAt(0) == '{') {
308 varheaderData; 308 varheaderData;
309 309
310 headerData = Clipperz.Base.evalJSON(anHeader); 310 headerData = Clipperz.Base.evalJSON(anHeader);
311 result = headerData['version']; 311 result = headerData['version'];
312 } else { 312 } else {
313 result = 'LEGACY'; 313 result = 'LEGACY';
314 } 314 }
315 315
316 return result; 316 return result;
317 }, 317 },
318 318
319 //------------------------------------------------------------------------- 319 //-------------------------------------------------------------------------
320 320
321 'unpackServerData': function (someServerData) { 321 'unpackServerData': function (someServerData) {
322 var unpackedData; 322 var unpackedData;
323 var headerVersion; 323 var headerVersion;
324 324
325 varrecordsIndex; 325 varrecordsIndex;
326 var preferences; 326 var preferences;
327 var oneTimePasswords; 327 var oneTimePasswords;
328 328
329 // this.setServerLockValue(someServerData['lock']); 329 // this.setServerLockValue(someServerData['lock']);
330 330
331 headerVersion = this.headerFormatVersion(someServerData['header']); 331 headerVersion = this.headerFormatVersion(someServerData['header']);
332 332
333 switch (headerVersion) { 333 switch (headerVersion) {
334 case 'LEGACY': 334 case 'LEGACY':
335 varlegacyHeader; 335 varlegacyHeader;
336 336
337 legacyHeader = new Clipperz.PM.DataModel.User.Header.Legacy({ 337 legacyHeader = new Clipperz.PM.DataModel.User.Header.Legacy({
338 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase'), 338 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase'),
339 'remoteData': { 339 'remoteData': {
340 'data': someServerData['header'], 340 'data': someServerData['header'],
341 'version': someServerData['version'], 341 'version': someServerData['version'],
342 'recordsStats': someServerData['recordsStats'] 342 'recordsStats': someServerData['recordsStats']
343 }, 343 },
344 // 'encryptedDataKeypath': 'data', 344 // 'encryptedDataKeypath': 'data',
345 // 'encryptedVersionKeypath': 'version', 345 // 'encryptedVersionKeypath': 'version',
346 'retrieveRecordDetailFunction':MochiKit.Base.method(this, 'getRecordDetail') 346 'retrieveRecordDetailFunction':MochiKit.Base.method(this, 'getRecordDetail')
347 }); 347 });
348 348
349 recordsIndex = legacyHeader; 349 recordsIndex = legacyHeader;
350 preferences = legacyHeader; 350 preferences = legacyHeader;
351 oneTimePasswords= legacyHeader; 351 oneTimePasswords= legacyHeader;
352 break; 352 break;
353 case '0.1': 353 case '0.1':
354 varheaderData; 354 varheaderData;
355 355
356 headerData = Clipperz.Base.evalJSON(someServerData['header']); 356 headerData = Clipperz.Base.evalJSON(someServerData['header']);
357 357
358 recordsIndex = new Clipperz.PM.DataModel.User.Header.RecordIndex({ 358 recordsIndex = new Clipperz.PM.DataModel.User.Header.RecordIndex({
359 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase'), 359 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase'),
360 'recordsData': headerData['records'], 360 'recordsData': headerData['records'],
361 'recordsStats': someServerData['recordsStats'], 361 'recordsStats': someServerData['recordsStats'],
362 'directLoginsData': headerData['directLogins'], 362 'directLoginsData': headerData['directLogins'],
363 'encryptedDataVersion': someServerData['version'], 363 'encryptedDataVersion': someServerData['version'],
364 'retrieveRecordDetailFunction':MochiKit.Base.method(this, 'getRecordDetail') 364 'retrieveRecordDetailFunction':MochiKit.Base.method(this, 'getRecordDetail')
365 }); 365 });
366 366
367 //Still missing a test case that actually fais with the old version of the code, where the check for undefined was missing 367 //Still missing a test case that actually fais with the old version of the code, where the check for undefined was missing
368 if (typeof(headerData['preferences']) != 'undefined') { 368 if (typeof(headerData['preferences']) != 'undefined') {
369 preferences= new Clipperz.PM.DataModel.User.Header.Preferences({ 369 preferences= new Clipperz.PM.DataModel.User.Header.Preferences({
370 'name':'preferences', 370 'name':'preferences',
371 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase'), 371 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase'),
372 'remoteData': { 372 'remoteData': {
373 'data': headerData['preferences']['data'], 373 'data': headerData['preferences']['data'],
374 'version': someServerData['version'] 374 'version': someServerData['version']
375 } 375 }
376 }); 376 });
377 } else { 377 } else {
378 preferences= new Clipperz.PM.DataModel.User.Header.Preferences({ 378 preferences= new Clipperz.PM.DataModel.User.Header.Preferences({
379 'name':'preferences', 379 'name':'preferences',
380 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase') 380 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase')
381 }); 381 });
382 } 382 }
383 383
384 if (typeof(headerData['oneTimePasswords']) != 'undefined') { 384 if (typeof(headerData['oneTimePasswords']) != 'undefined') {
385 oneTimePasswords = new Clipperz.PM.DataModel.User.Header.OneTimePasswords({ 385 oneTimePasswords = new Clipperz.PM.DataModel.User.Header.OneTimePasswords({
386 'name':'preferences', 386 'name':'preferences',
387 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase'), 387 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase'),
388 'remoteData': { 388 'remoteData': {
389 'data': headerData['oneTimePasswords']['data'], 389 'data': headerData['oneTimePasswords']['data'],
390 'version': someServerData['version'] 390 'version': someServerData['version']
391 } 391 }
392 }); 392 });
393 } else { 393 } else {
394 oneTimePasswords = new Clipperz.PM.DataModel.User.Header.OneTimePasswords({ 394 oneTimePasswords = new Clipperz.PM.DataModel.User.Header.OneTimePasswords({
395 'name':'preferences', 395 'name':'preferences',
396 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase') 396 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase')
397 }); 397 });
398 } 398 }
399 399
400 break; 400 break;
401 } 401 }
402 402
403 unpackedData = { 403 unpackedData = {
404 'version': someServerData['version'], 404 'version': someServerData['version'],
405 'statistics': someServerData['statistics'], 405 'statistics': someServerData['statistics'],
406 'header': { 406 'header': {
407 'data': someServerData['header'], 407 'data': someServerData['header'],
408 'version': headerVersion, 408 'version': headerVersion,
409 409
410 'recordsIndex': recordsIndex, 410 'recordsIndex': recordsIndex,
411 'preferences': preferences, 411 'preferences': preferences,
412 'oneTimePasswords': oneTimePasswords 412 'oneTimePasswords': oneTimePasswords
413 } 413 }
414 }; 414 };
415 415
416 this._serverData = unpackedData; 416 this._serverData = unpackedData;
417 417
418 return this._serverData; 418 return this._serverData;
419 }, 419 },
420 420
421 //------------------------------------------------------------------------- 421 //-------------------------------------------------------------------------
422 422
423 'getServerData': function() { 423 'getServerData': function() {
424 var deferredResult; 424 var deferredResult;
425 425
426 deferredResult = new Clipperz.Async.Deferred("User.getServerData", {trace:false}); 426 deferredResult = new Clipperz.Async.Deferred("User.getServerData", {trace:false});
427 deferredResult.acquireLock(this.deferredLockForSection('serverData')); 427 deferredResult.acquireLock(this.deferredLockForSection('serverData'));
428 deferredResult.addCallback(MochiKit.Base.bind(function(aResult) { 428 deferredResult.addCallback(MochiKit.Base.bind(function(aResult) {
429 var innerDeferredResult; 429 var innerDeferredResult;
430 430
431 innerDeferredResult = new Clipperz.Async.Deferred("User.getUserDetails.innerDeferred", {trace:false}); 431 innerDeferredResult = new Clipperz.Async.Deferred("User.getUserDetails.innerDeferred", {trace:false});
432 if (this._serverData == null) { 432 if (this._serverData == null) {
433 innerDeferredResult.addCallbackPass(MochiKit.Signal.signal, this, 'loadingUserDetails'); 433 innerDeferredResult.addCallbackPass(MochiKit.Signal.signal, this, 'loadingUserDetails');
434 innerDeferredResult.addMethod(this.connection(), 'message', 'getUserDetails'); 434 innerDeferredResult.addMethod(this.connection(), 'message', 'getUserDetails');
435 innerDeferredResult.addMethod(this, 'unpackServerData'); 435 innerDeferredResult.addMethod(this, 'unpackServerData');
436 innerDeferredResult.addCallbackPass(MochiKit.Signal.signal, this, 'loadedUserDetails'); 436 innerDeferredResult.addCallbackPass(MochiKit.Signal.signal, this, 'loadedUserDetails');
437 } 437 }
438 438
439 innerDeferredResult.addCallback(MochiKit.Base.bind(function () { 439 innerDeferredResult.addCallback(MochiKit.Base.bind(function () {
440 return this._serverData; 440 return this._serverData;
441 },this)); 441 },this));
442 innerDeferredResult.callback(); 442 innerDeferredResult.callback();
443 443
444 return innerDeferredResult; 444 return innerDeferredResult;
445 }, this)); 445 }, this));
446 deferredResult.releaseLock(this.deferredLockForSection('serverData')); 446 deferredResult.releaseLock(this.deferredLockForSection('serverData'));
447 deferredResult.callback(); 447 deferredResult.callback();
448 448
449 return deferredResult; 449 return deferredResult;
450 }, 450 },
451 451
452 //------------------------------------------------------------------------- 452 //-------------------------------------------------------------------------
453 453
454 'connectionVersion': function() { 454 'connectionVersion': function() {
455 return this._connectionVersion; 455 return this._connectionVersion;
456 }, 456 },
457 457
458 'setConnectionVersion': function(aValue) { 458 'setConnectionVersion': function(aValue) {
459 if (this._connectionVersion != aValue) { 459 if (this._connectionVersion != aValue) {
460 this.resetConnection(); 460 this.resetConnection();
461 } 461 }
462 this._connectionVersion = aValue; 462 this._connectionVersion = aValue;
463 }, 463 },
464 464
465 //------------------------------------------------------------------------- 465 //-------------------------------------------------------------------------
466 466
467 'connection': function() { 467 'connection': function() {
468 if ((this._connection == null) && (this.connectionVersion() != null) ){ 468 if ((this._connection == null) && (this.connectionVersion() != null) ){
469 this._connection = new Clipperz.PM.Connection.communicationProtocol.versions[this.connectionVersion()]({ 469 this._connection = new Clipperz.PM.Connection.communicationProtocol.versions[this.connectionVersion()]({
470 getCredentialsFunction: MochiKit.Base.method(this, 'getCredentials') 470 getCredentialsFunction: MochiKit.Base.method(this, 'getCredentials')
471 }); 471 });
472 } 472 }
473 473
474 return this._connection; 474 return this._connection;
475 }, 475 },
476 476
477 'resetConnection': function(aValue) { 477 'resetConnection': function(aValue) {
478 if (this._connection != null) { 478 if (this._connection != null) {
479 this._connection.reset(); 479 this._connection.reset();
480 } 480 }
481 481
482 this._connection = null; 482 this._connection = null;
483 }, 483 },
484 484
485 //========================================================================= 485 //=========================================================================
486 486
487 'getHeaderIndex': function (aKey) { 487 'getHeaderIndex': function (aKey) {
488 return Clipperz.Async.callbacks("User.getHeaderIndex", [ 488 return Clipperz.Async.callbacks("User.getHeaderIndex", [
489 MochiKit.Base.method(this, 'getServerData'), 489 MochiKit.Base.method(this, 'getServerData'),
490 MochiKit.Base.itemgetter('header'), 490 MochiKit.Base.itemgetter('header'),
491 MochiKit.Base.itemgetter(aKey) 491 MochiKit.Base.itemgetter(aKey)
492 ], {trace:false}) 492 ], {trace:false})
493 }, 493 },
494 494
495 //========================================================================= 495 //=========================================================================
496 496
497 'getRecords': function () { 497 'getRecords': function () {
498 return Clipperz.Async.callbacks("User.getRecords", [ 498 return Clipperz.Async.callbacks("User.getRecords", [
499 MochiKit.Base.method(this, 'getHeaderIndex', 'recordsIndex'), 499 MochiKit.Base.method(this, 'getHeaderIndex', 'recordsIndex'),
500 MochiKit.Base.methodcaller('records'), 500 MochiKit.Base.methodcaller('records'),
501 MochiKit.Base.values 501 MochiKit.Base.values
502 ], {trace:false}); 502 ], {trace:false});
503 }, 503 },
504 504
505 'recordWithLabel': function (aLabel) { 505 'recordWithLabel': function (aLabel) {
506 return Clipperz.Async.callbacks("User.recordWithLabel", [ 506 return Clipperz.Async.callbacks("User.recordWithLabel", [
507 MochiKit.Base.method(this, 'getRecords'), 507 MochiKit.Base.method(this, 'getRecords'),
508 MochiKit.Base.partial(Clipperz.Async.deferredFilter, function (aRecord) { 508 MochiKit.Base.partial(Clipperz.Async.deferredFilter, function (aRecord) {
509 return Clipperz.Async.callbacks("User.recordWithLabel - check record label", [ 509 return Clipperz.Async.callbacks("User.recordWithLabel - check record label", [
510 MochiKit.Base.methodcaller('label'), 510 MochiKit.Base.methodcaller('label'),
511 MochiKit.Base.partial(MochiKit.Base.operator.eq, aLabel) 511 MochiKit.Base.partial(MochiKit.Base.operator.eq, aLabel)
512 ], {trace:false}, aRecord); 512 ], {trace:false}, aRecord);
513 }), 513 }),
514 function (someFilteredResults) { 514 function (someFilteredResults) {
515 var result; 515 var result;
516 516
517 switch (someFilteredResults.length) { 517 switch (someFilteredResults.length) {
518 case 0: 518 case 0:
519 result = null; 519 result = null;
520 break; 520 break;
521 case 1: 521 case 1:
522 result = someFilteredResults[0]; 522 result = someFilteredResults[0];
523 break; 523 break;
524 default: 524 default:
525 WTF = TODO; 525 WTF = TODO;
526 break; 526 break;
527 } 527 }
528 528
529 return result; 529 return result;
530 } 530 }
531 ], {trace:false}); 531 ], {trace:false});
532 }, 532 },
533 533
534 //------------------------------------------------------------------------- 534 //-------------------------------------------------------------------------
535 535
536 'getRecord': function (aRecordReference) { 536 'getRecord': function (aRecordReference) {
537 return Clipperz.Async.callbacks("User.getRecord", [ 537 return Clipperz.Async.callbacks("User.getRecord", [
538 MochiKit.Base.method(this, 'getHeaderIndex', 'recordsIndex'), 538 MochiKit.Base.method(this, 'getHeaderIndex', 'recordsIndex'),
539 MochiKit.Base.methodcaller('records'), 539 MochiKit.Base.methodcaller('records'),
540 MochiKit.Base.itemgetter(aRecordReference), 540 MochiKit.Base.itemgetter(aRecordReference),
541 541
542 Clipperz.Async.deferredIf("record != null", [ 542 Clipperz.Async.deferredIf("record != null", [
543 MochiKit.Base.operator.identity 543 MochiKit.Base.operator.identity
544 ], [ 544 ], [
545 function () { throw "Record does not exists"} 545 function () { throw "Record does not exists"}
546 ]) 546 ])
547 ], {trace:false}); 547 ], {trace:false});
548 }, 548 },
549 549
550 //------------------------------------------------------------------------- 550 //-------------------------------------------------------------------------
551 551
552 'getRecordDetail': function (aRecordReference) { 552 'getRecordDetail': function (aRecordReference) {
553 return this.connection().message('getRecordDetail', {reference: aRecordReference}); 553 return this.connection().message('getRecordDetail', {reference: aRecordReference});
554 }, 554 },
555 555
556 //------------------------------------------------------------------------- 556 //-------------------------------------------------------------------------
557 557
558 'deleteRecord': function (aRecord) { 558 'deleteRecord': function (aRecord) {
559 return Clipperz.Async.callbacks("User.deleteRecord", [ 559 return Clipperz.Async.callbacks("User.deleteRecord", [
560 MochiKit.Base.method(this, 'getHeaderIndex', 'recordsIndex'), 560 MochiKit.Base.method(this, 'getHeaderIndex', 'recordsIndex'),
561 MochiKit.Base.methodcaller('deleteRecord', aRecord) 561 MochiKit.Base.methodcaller('deleteRecord', aRecord)
562 ], {trace:false}); 562 ], {trace:false});
563 }, 563 },
564 564
565 //------------------------------------------------------------------------- 565 //-------------------------------------------------------------------------
566 566
567 'createNewRecord': function () { 567 'createNewRecord': function () {
568 return Clipperz.Async.callbacks("User.createNewRecord", [ 568 return Clipperz.Async.callbacks("User.createNewRecord", [
569 MochiKit.Base.method(this, 'getHeaderIndex', 'recordsIndex'), 569 MochiKit.Base.method(this, 'getHeaderIndex', 'recordsIndex'),
570 MochiKit.Base.methodcaller('createNewRecord') 570 MochiKit.Base.methodcaller('createNewRecord')
571 ], {trace:false}); 571 ], {trace:false});
572 }, 572 },
573 573
574 //========================================================================= 574 //=========================================================================
575 575
576 'getDirectLogins': function() { 576 'getDirectLogins': function() {
577 var deferredResult; 577 var deferredResult;
578 578
579 deferredResult = new Clipperz.Async.Deferred("User.getDirectLogins", {trace:false}); 579 deferredResult = new Clipperz.Async.Deferred("User.getDirectLogins", {trace:false});
580 deferredResult.addMethod(this, 'getRecords'); 580 deferredResult.addMethod(this, 'getRecords');
581 deferredResult.addCallback(MochiKit.Base.map, MochiKit.Base.compose(MochiKit.Base.values, MochiKit.Base.methodcaller('directLogins'))); 581 deferredResult.addCallback(MochiKit.Base.map, MochiKit.Base.compose(MochiKit.Base.values, MochiKit.Base.methodcaller('directLogins')));
582 deferredResult.addCallback(MochiKit.Base.flattenArray); 582 deferredResult.addCallback(MochiKit.Base.flattenArray);
583 deferredResult.callback(); 583 deferredResult.callback();
584 584
585 return deferredResult; 585 return deferredResult;
586 }, 586 },
587 587
588 //========================================================================= 588 //=========================================================================
589 589
590 'getOneTimePasswords': function () { 590 'getOneTimePasswords': function () {
591 return Clipperz.Async.callbacks("User.getOneTimePasswords", [ 591 return Clipperz.Async.callbacks("User.getOneTimePasswords", [
592 MochiKit.Base.method(this, 'getHeaderIndex', 'oneTimePasswords'), 592 MochiKit.Base.method(this, 'getHeaderIndex', 'oneTimePasswords'),
593 MochiKit.Base.methodcaller('oneTimePasswords'), 593 MochiKit.Base.methodcaller('oneTimePasswords'),
594 MochiKit.Base.values 594 MochiKit.Base.values
595 ], {trace:false}); 595 ], {trace:false});
596 }, 596 },
597 597
598 //========================================================================= 598 //=========================================================================
599 599
600 'invokeMethodNamedOnHeader': function (aMethodName, aValue) { 600 'invokeMethodNamedOnHeader': function (aMethodName, aValue) {
601 return Clipperz.Async.collectResults("User.invokeMethodNamedOnHeader [" + aMethodName + "]", { 601 return Clipperz.Async.collectResults("User.invokeMethodNamedOnHeader [" + aMethodName + "]", {
602 'recordIndex': [ 602 'recordIndex': [
603 MochiKit.Base.method(this, 'getHeaderIndex', 'recordsIndex'), 603 MochiKit.Base.method(this, 'getHeaderIndex', 'recordsIndex'),
604 MochiKit.Base.methodcaller(aMethodName, aValue) 604 MochiKit.Base.methodcaller(aMethodName, aValue)
605 ], 605 ],
606 'preferences': [ 606 'preferences': [
607 MochiKit.Base.method(this, 'getHeaderIndex', 'preferences'), 607 MochiKit.Base.method(this, 'getHeaderIndex', 'preferences'),
608 MochiKit.Base.methodcaller(aMethodName, aValue) 608 MochiKit.Base.methodcaller(aMethodName, aValue)
609 ], 609 ],
610 'oneTimePasswords': [ 610 'oneTimePasswords': [
611 MochiKit.Base.method(this, 'getHeaderIndex', 'oneTimePasswords'), 611 MochiKit.Base.method(this, 'getHeaderIndex', 'oneTimePasswords'),
612 MochiKit.Base.methodcaller(aMethodName, aValue) 612 MochiKit.Base.methodcaller(aMethodName, aValue)
613 ]//, 613 ]//,
614 // 'statistics': [ 614 // 'statistics': [
615 // MochiKit.Base.method(this, 'getStatistics'), 615 // MochiKit.Base.method(this, 'getStatistics'),
616 // MochiKit.Base.methodcaller(aMethodName, aValue) 616 // MochiKit.Base.methodcaller(aMethodName, aValue)
617 // ] 617 // ]
618 }, {trace:false})(); 618 }, {trace:false})();
619 }, 619 },
620 620
621 //------------------------------------------------------------------------- 621 //-------------------------------------------------------------------------
622 622
623 'invokeMethodNamedOnRecords': function (aMethodName, aValue) { 623 'invokeMethodNamedOnRecords': function (aMethodName, aValue) {
624 return Clipperz.Async.callbacks("User.invokeMethodNamedOnRecords[" + aMethodName + "]", [ 624 return Clipperz.Async.callbacks("User.invokeMethodNamedOnRecords[" + aMethodName + "]", [
625 MochiKit.Base.method(this, 'getRecords'), 625 MochiKit.Base.method(this, 'getRecords'),
626 MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.methodcaller(aMethodName, aValue)), 626 MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.methodcaller(aMethodName, aValue)),
627 Clipperz.Async.collectAll 627 Clipperz.Async.collectAll
628 ], {trace:false}); 628 ], {trace:false});
629 }, 629 },
630 630
631 //========================================================================= 631 //=========================================================================
632 632
633 'hasPendingChanges': function () { 633 'hasPendingChanges': function () {
634 vardeferredResult; 634 vardeferredResult;
635 635
636 deferredResult = new Clipperz.Async.Deferred("User.hasPendingChanges", {trace:false}); 636 deferredResult = new Clipperz.Async.Deferred("User.hasPendingChanges", {trace:false});
637 deferredResult.collectResults({ 637 deferredResult.collectResults({
638 'header': [ 638 'header': [
639 MochiKit.Base.method(this, 'invokeMethodNamedOnHeader', 'hasPendingChanges'), 639 MochiKit.Base.method(this, 'invokeMethodNamedOnHeader', 'hasPendingChanges'),
640 MochiKit.Base.values 640 MochiKit.Base.values
641 ], 641 ],
642 'records': MochiKit.Base.method(this, 'invokeMethodNamedOnRecords', 'hasPendingChanges') 642 'records': MochiKit.Base.method(this, 'invokeMethodNamedOnRecords', 'hasPendingChanges')
643 }); 643 });
644 deferredResult.addCallback(Clipperz.Async.or); 644 deferredResult.addCallback(Clipperz.Async.or);
645 deferredResult.callback(); 645 deferredResult.callback();
646 // recordsIndex = legacyHeader; 646 // recordsIndex = legacyHeader;
647 // preferences = legacyHeader; 647 // preferences = legacyHeader;
648 // oneTimePasswords= legacyHeader; 648 // oneTimePasswords= legacyHeader;
649 649
650 return deferredResult; 650 return deferredResult;
651 }, 651 },
652 652
653 //========================================================================= 653 //=========================================================================
654 654
655 'commitTransientState': function () { 655 'commitTransientState': function () {
656 return Clipperz.Async.callbacks("User.commitTransientState", [ 656 return Clipperz.Async.callbacks("User.commitTransientState", [
657 MochiKit.Base.method(this, 'invokeMethodNamedOnHeader', 'commitTransientState'), 657 MochiKit.Base.method(this, 'invokeMethodNamedOnHeader', 'commitTransientState'),
658 MochiKit.Base.method(this, 'invokeMethodNamedOnRecords', 'commitTransientState'), 658 MochiKit.Base.method(this, 'invokeMethodNamedOnRecords', 'commitTransientState'),
659 659
660 MochiKit.Base.method(this, 'transientState'), 660 MochiKit.Base.method(this, 'transientState'),
661 // MochiKit.Base.itemgetter('lock'), 661 // MochiKit.Base.itemgetter('lock'),
662 // MochiKit.Base.method(this, 'setServerLockValue'), 662 // MochiKit.Base.method(this, 'setServerLockValue'),
663 MochiKit.Base.method(this, 'resetTransientState', true) 663 MochiKit.Base.method(this, 'resetTransientState', true)
664 ], {trace:false}); 664 ], {trace:false});
665 }, 665 },
666 666
667 //------------------------------------------------------------------------- 667 //-------------------------------------------------------------------------
668 668
669 'revertChanges': function () { 669 'revertChanges': function () {
670 return Clipperz.Async.callbacks("User.revertChanges", [ 670 return Clipperz.Async.callbacks("User.revertChanges", [
671 MochiKit.Base.method(this, 'invokeMethodNamedOnHeader', 'revertChanges'), 671 MochiKit.Base.method(this, 'invokeMethodNamedOnHeader', 'revertChanges'),
672 MochiKit.Base.method(this, 'invokeMethodNamedOnRecords', 'revertChanges'), 672 MochiKit.Base.method(this, 'invokeMethodNamedOnRecords', 'revertChanges'),
673 MochiKit.Base.method(this, 'resetTransientState', false) 673 MochiKit.Base.method(this, 'resetTransientState', false)
674 ], {trace:false}); 674 ], {trace:false});
675 }, 675 },
676 676
677 //========================================================================= 677 //=========================================================================
678 678
679 'deleteAllCleanTextData': function () { 679 'deleteAllCleanTextData': function () {
680 return Clipperz.Async.callbacks("User.deleteAllCleanTextData", [ 680 return Clipperz.Async.callbacks("User.deleteAllCleanTextData", [
681 MochiKit.Base.method(this, 'invokeMethodNamedOnRecords', 'deleteAllCleanTextData'), 681 MochiKit.Base.method(this, 'invokeMethodNamedOnRecords', 'deleteAllCleanTextData'),
682 MochiKit.Base.method(this, 'invokeMethodNamedOnHeader', 'deleteAllCleanTextData'), 682 MochiKit.Base.method(this, 'invokeMethodNamedOnHeader', 'deleteAllCleanTextData'),
683 683
684 MochiKit.Base.method(this.data(), 'removeAllData'), 684 MochiKit.Base.method(this.data(), 'removeAllData'),
685 MochiKit.Base.method(this, 'resetTransientState', false) 685 MochiKit.Base.method(this, 'resetTransientState', false)
686 ], {trace:false}); 686 ], {trace:false});
687 }, 687 },
688 688
689 //------------------------------------------------------------------------- 689 //-------------------------------------------------------------------------
690 690
691 'hasAnyCleanTextData': function () { 691 'hasAnyCleanTextData': function () {
692 vardeferredResult; 692 vardeferredResult;
693 693
694 deferredResult = new Clipperz.Async.Deferred("User.hasAnyCleanTextData", {trace:false}); 694 deferredResult = new Clipperz.Async.Deferred("User.hasAnyCleanTextData", {trace:false});
695 deferredResult.collectResults({ 695 deferredResult.collectResults({
696 'header':[ 696 'header':[
697 MochiKit.Base.method(this, 'invokeMethodNamedOnHeader', 'hasAnyCleanTextData'), 697 MochiKit.Base.method(this, 'invokeMethodNamedOnHeader', 'hasAnyCleanTextData'),
698 MochiKit.Base.values 698 MochiKit.Base.values
699 ], 699 ],
700 'records':MochiKit.Base.method(this, 'invokeMethodNamedOnRecords', 'hasAnyCleanTextData'), 700 'records':MochiKit.Base.method(this, 'invokeMethodNamedOnRecords', 'hasAnyCleanTextData'),
701 'data': MochiKit.Base.bind(function () { 701 'data': MochiKit.Base.bind(function () {
702 return MochiKit.Async.succeed(! this.data().isEmpty()); 702 return MochiKit.Async.succeed(! this.data().isEmpty());
703 }, this), 703 }, this),
704 'transientState':MochiKit.Base.bind(function () { 704 'transientState':MochiKit.Base.bind(function () {
705 return MochiKit.Async.succeed(MochiKit.Base.keys(this.transientState()).length != 0); 705 return MochiKit.Async.succeed(MochiKit.Base.keys(this.transientState()).length != 0);
706 }, this) 706 }, this)
707 }); 707 });
708 deferredResult.addCallback(Clipperz.Async.or); 708 deferredResult.addCallback(Clipperz.Async.or);
709 deferredResult.callback(); 709 deferredResult.callback();
710 710
711 return deferredResult; 711 return deferredResult;
712 }, 712 },
713 713
714 //========================================================================= 714 //=========================================================================
715 715
716 'prepareRemoteDataWithKey': function (aKey /*, aCurrentKey*/) { 716 'prepareRemoteDataWithKey': function (aKey /*, aCurrentKey*/) {
717 var deferredResult; 717 var deferredResult;
718 varresult; 718 varresult;
719 719
720 result = {}; 720 result = {};
721 deferredResult = new Clipperz.Async.Deferred("User.prepareRemoteDataWithKey", {trace:false}); 721 deferredResult = new Clipperz.Async.Deferred("User.prepareRemoteDataWithKey", {trace:false});
722 deferredResult.addMethod(this, 'invokeMethodNamedOnHeader', 'prepareRemoteDataWithKey', aKey /*, aCurrentKey*/); 722 deferredResult.addMethod(this, 'invokeMethodNamedOnHeader', 'prepareRemoteDataWithKey', aKey /*, aCurrentKey*/);
723 deferredResult.addCallback(MochiKit.Base.bind(function (aResult, someHeaderPackedData) { 723 deferredResult.addCallback(MochiKit.Base.bind(function (aResult, someHeaderPackedData) {
724 var header; 724 var header;
725 725
726 header = {}; 726 header = {};
727 header['records'] = someHeaderPackedData['recordIndex']['records']; 727 header['records'] = someHeaderPackedData['recordIndex']['records'];
728 header['directLogins'] = someHeaderPackedData['recordIndex']['directLogins']; 728 header['directLogins'] = someHeaderPackedData['recordIndex']['directLogins'];
729 header['preferences'] = {'data': someHeaderPackedData['preferences']['data']}; // this._serverData['header']['preferences']; // Clipperz.Base.evalJSON(this._serverData['header']['data'])['preferences']; //??????????? 729 header['preferences'] = {'data': someHeaderPackedData['preferences']['data']};
730 header['oneTimePasswords'] = {'data': someHeaderPackedData['oneTimePasswords']['data']}; // this._serverData['header']['oneTimePasswords']; // Clipperz.Base.evalJSON(this._serverData['header']['data'])['oneTimePasswords']; //??????????? 730 header['oneTimePasswords']= {'data': someHeaderPackedData['oneTimePasswords']['data']};
731 header['version'] = '0.1'; 731 header['version'] = '0.1';
732 732
733 aResult['header'] = Clipperz.Base.serializeJSON(header); 733 aResult['header'] = Clipperz.Base.serializeJSON(header);
734 aResult['statistics'] = this._serverData['statistics']; //"someHeaderPackedData['statistics']['data']"; 734 aResult['statistics'] = this._serverData['statistics']; //"someHeaderPackedData['statistics']['data']";
735 735
736 return aResult; 736 return aResult;
737 }, this), result); 737 }, this), result);
738 deferredResult.addCallback(Clipperz.Async.setItem, result, 'version', Clipperz.PM.Crypto.encryptingFunctions.currentVersion); 738 deferredResult.addCallback(Clipperz.Async.setItem, result, 'version', Clipperz.PM.Crypto.encryptingFunctions.currentVersion);
739 // deferredResult.addCallback(Clipperz.Async.setItem, result, 'lock', this.serverLockValue()); 739 // deferredResult.addCallback(Clipperz.Async.setItem, result, 'lock', this.serverLockValue());
740 deferredResult.callback(); 740 deferredResult.callback();
741 741
742 return deferredResult; 742 return deferredResult;
743 }, 743 },
744 744
745 //========================================================================= 745 //=========================================================================
746 746
747 'saveChanges': function () { 747 'saveChanges': function () {
748 vardeferredResult; 748 vardeferredResult;
749 var messageParameters; 749 var messageParameters;
750 750
751 messageParameters = {}; 751 messageParameters = {};
752 752
753 deferredResult = new Clipperz.Async.Deferred("User.saveChangaes", {trace:false}); 753 deferredResult = new Clipperz.Async.Deferred("User.saveChangaes", {trace:false});
754 754
755 deferredResult.addMethod(this, 'getHeaderIndex', 'recordsIndex'); 755 deferredResult.addMethod(this, 'getHeaderIndex', 'recordsIndex');
756 deferredResult.addCallback(MochiKit.Base.methodcaller('prepareRemoteDataForChangedRecords')); 756 deferredResult.addCallback(MochiKit.Base.methodcaller('prepareRemoteDataForChangedRecords'));
757 deferredResult.addCallback(Clipperz.Async.setItem, messageParameters, 'records'); 757 deferredResult.addCallback(Clipperz.Async.setItem, messageParameters, 'records');
758 deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress'); 758 deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress');
759 759
760 deferredResult.addMethod(this, 'getPassphrase'); 760 deferredResult.addMethod(this, 'getPassphrase');
761 deferredResult.addMethod(this, 'prepareRemoteDataWithKey'); 761 deferredResult.addMethod(this, 'prepareRemoteDataWithKey');
762 deferredResult.addCallback(Clipperz.Async.setItem, messageParameters, 'user'); 762 deferredResult.addCallback(Clipperz.Async.setItem, messageParameters, 'user');
763 deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress'); 763 deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress');
764 764
765 deferredResult.addCallback(MochiKit.Async.succeed, messageParameters); 765 deferredResult.addCallback(MochiKit.Async.succeed, messageParameters);
766 deferredResult.addMethod(this.connection(), 'message', 'saveChanges'); 766 deferredResult.addMethod(this.connection(), 'message', 'saveChanges');
767 deferredResult.addCallback(MochiKit.Base.update, this.transientState()) 767 deferredResult.addCallback(MochiKit.Base.update, this.transientState())
768 deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress'); 768 deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress');
769 769
770 deferredResult.addMethod(this, 'commitTransientState'); 770 deferredResult.addMethod(this, 'commitTransientState');
771 deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress'); 771 deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress');
772 deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'userDataSuccessfullySaved'); 772 deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'userDataSuccessfullySaved');
773 773
774 deferredResult.addErrbackPass(MochiKit.Base.method(this, 'revertChanges')); 774 deferredResult.addErrbackPass(MochiKit.Base.method(this, 'revertChanges'));
775 deferredResult.addErrbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'failureWhileSavingUserData'); 775 deferredResult.addErrbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'failureWhileSavingUserData');
776 776
777 deferredResult.callback(); 777 deferredResult.callback();
778 778
779 return deferredResult; 779 return deferredResult;
780 }, 780 },
781 781
782 //========================================================================= 782 //=========================================================================
783 __syntaxFix__: "syntax fix" 783 __syntaxFix__: "syntax fix"
784}); 784});
785 785
786//----------------------------------------------------------------------------- 786//-----------------------------------------------------------------------------
787 787
788Clipperz.PM.DataModel.User.registerNewAccount = function (anUsername, aPassphraseFunction) { 788Clipperz.PM.DataModel.User.registerNewAccount = function (anUsername, aPassphraseFunction) {
789 vardeferredResult; 789 vardeferredResult;
790 var user; 790 var user;
791 791
792 user = new Clipperz.PM.DataModel.User({'username':anUsername, 'getPassphraseFunction':aPassphraseFunction}); 792 user = new Clipperz.PM.DataModel.User({'username':anUsername, 'getPassphraseFunction':aPassphraseFunction});
793 793
794 deferredResult = new Clipperz.Async.Deferred("Clipperz.PM.DataModel.User.registerNewAccount", {trace:false}); 794 deferredResult = new Clipperz.Async.Deferred("Clipperz.PM.DataModel.User.registerNewAccount", {trace:false});
795 deferredResult.addMethod(user, 'registerAsNewAccount'); 795 deferredResult.addMethod(user, 'registerAsNewAccount');
796 deferredResult.addMethod(user, 'login'); 796 deferredResult.addMethod(user, 'login');
797 deferredResult.addCallback(MochiKit.Async.succeed, user); 797 deferredResult.addCallback(MochiKit.Async.succeed, user);
798 deferredResult.callback(); 798 deferredResult.callback();
799 799
800 return deferredResult; 800 return deferredResult;
801} 801}
802 802
803//----------------------------------------------------------------------------- 803//-----------------------------------------------------------------------------
804 804
805Clipperz.PM.DataModel.User.exception = { 805Clipperz.PM.DataModel.User.exception = {
806 LoginFailed: new MochiKit.Base.NamedError("Clipperz.PM.DataModel.User.exception.LoginFailed"), 806 LoginFailed: new MochiKit.Base.NamedError("Clipperz.PM.DataModel.User.exception.LoginFailed"),
807 CredentialUpgradeFailed:new MochiKit.Base.NamedError("Clipperz.PM.DataModel.User.exception.CredentialUpgradeFailed") 807 CredentialUpgradeFailed:new MochiKit.Base.NamedError("Clipperz.PM.DataModel.User.exception.CredentialUpgradeFailed")
808}; 808};
809 809
810//----------------------------------------------------------------------------- 810//-----------------------------------------------------------------------------
diff --git a/frontend/gamma/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js b/frontend/gamma/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js
index 326022c..b806cb7 100644
--- a/frontend/gamma/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js
+++ b/frontend/gamma/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js
@@ -1,788 +1,788 @@
1/* 1/*
2 2
3Copyright 2008-2013 Clipperz Srl 3Copyright 2008-2013 Clipperz Srl
4 4
5This file is part of Clipperz, the online password manager. 5This file is part of Clipperz, the online password manager.
6For further information about its features and functionalities please 6For further information about its features and functionalities please
7refer to http://www.clipperz.com. 7refer to http://www.clipperz.com.
8 8
9* Clipperz is free software: you can redistribute it and/or modify it 9* Clipperz is free software: you can redistribute it and/or modify it
10 under the terms of the GNU Affero General Public License as published 10 under the terms of the GNU Affero General Public License as published
11 by the Free Software Foundation, either version 3 of the License, or 11 by the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version. 12 (at your option) any later version.
13 13
14* Clipperz is distributed in the hope that it will be useful, but 14* Clipperz is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of 15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU Affero General Public License for more details. 17 See the GNU Affero General Public License for more details.
18 18
19* You should have received a copy of the GNU Affero General Public 19* You should have received a copy of the GNU Affero General Public
20 License along with Clipperz. If not, see http://www.gnu.org/licenses/. 20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
21 21
22*/ 22*/
23 23
24try { if (typeof(Clipperz.PM.Proxy.Offline) == 'undefined') { throw ""; }} catch (e) { 24try { if (typeof(Clipperz.PM.Proxy.Offline) == 'undefined') { throw ""; }} catch (e) {
25 throw "Clipperz.PM.Proxy.Offline.DataStore depends on Clipperz.PM.Proxy.Offline!"; 25 throw "Clipperz.PM.Proxy.Offline.DataStore depends on Clipperz.PM.Proxy.Offline!";
26} 26}
27 27
28//============================================================================= 28//=============================================================================
29 29
30Clipperz.PM.Proxy.Offline.DataStore = function(args) { 30Clipperz.PM.Proxy.Offline.DataStore = function(args) {
31 args = args || {}; 31 args = args || {};
32 32
33 this._data = args.data || (typeof(_clipperz_dump_data_) != 'undefined' ? _clipperz_dump_data_ : null); 33 this._data = args.data || (typeof(_clipperz_dump_data_) != 'undefined' ? _clipperz_dump_data_ : null);
34 this._isReadOnly = (typeof(args.readOnly) == 'undefined' ? true : args.readOnly); 34 this._isReadOnly = (typeof(args.readOnly) == 'undefined' ? true : args.readOnly);
35 this._shouldPayTolls = args.shouldPayTolls || false; 35 this._shouldPayTolls = args.shouldPayTolls || false;
36 36
37 this._tolls = {}; 37 this._tolls = {};
38 this._currentStaticConnection = null; 38 this._currentStaticConnection = null;
39 39
40 return this; 40 return this;
41} 41}
42 42
43Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.DataStore, Object, { 43Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.DataStore, Object, {
44 44
45 //------------------------------------------------------------------------- 45 //-------------------------------------------------------------------------
46 46
47 'isReadOnly': function () { 47 'isReadOnly': function () {
48 return this._isReadOnly; 48 return this._isReadOnly;
49 }, 49 },
50 50
51 //------------------------------------------------------------------------- 51 //-------------------------------------------------------------------------
52 52
53 'shouldPayTolls': function() { 53 'shouldPayTolls': function() {
54 return this._shouldPayTolls; 54 return this._shouldPayTolls;
55 }, 55 },
56 56
57 //------------------------------------------------------------------------- 57 //-------------------------------------------------------------------------
58 58
59 'data': function () { 59 'data': function () {
60 return this._data; 60 return this._data;
61 }, 61 },
62 62
63 //------------------------------------------------------------------------- 63 //-------------------------------------------------------------------------
64 64
65 'tolls': function () { 65 'tolls': function () {
66 return this._tolls; 66 return this._tolls;
67 }, 67 },
68 68
69 //========================================================================= 69 //=========================================================================
70 70
71 'resetData': function() { 71 'resetData': function() {
72 this._data = { 72 this._data = {
73 'users': { 73 'users': {
74 'catchAllUser': { 74 'catchAllUser': {
75 __masterkey_test_value__: 'masterkey', 75 __masterkey_test_value__: 'masterkey',
76 s: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00', 76 s: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00',
77 v: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00' 77 v: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00'
78 } 78 }
79 } 79 }
80 }; 80 };
81 }, 81 },
82 82
83 //------------------------------------------------------------------------- 83 //-------------------------------------------------------------------------
84 84
85 'setupWithEncryptedData': function(someData) { 85 'setupWithEncryptedData': function(someData) {
86 this._data = Clipperz.Base.deepClone(someData); 86 this._data = Clipperz.Base.deepClone(someData);
87 }, 87 },
88 88
89 //------------------------------------------------------------------------- 89 //-------------------------------------------------------------------------
90 90
91 'setupWithData': function(someData) { 91 'setupWithData': function(someData) {
92 var deferredResult; 92 var deferredResult;
93 var resultData; 93 var resultData;
94 var i, c; 94 var i, c;
95 95
96//Clipperz.log(">>> Proxy.Test.setupWithData"); 96//Clipperz.log(">>> Proxy.Test.setupWithData");
97 resultData = this._data; 97 resultData = this._data;
98 98
99 deferredResult = new Clipperz.Async.Deferred("Proxy.Test.seupWithData", {trace:false}); 99 deferredResult = new Clipperz.Async.Deferred("Proxy.Test.seupWithData", {trace:false});
100 c = someData['users'].length; 100 c = someData['users'].length;
101 101
102 for (i=0; i<c; i++) { 102 for (i=0; i<c; i++) {
103 varnewConnection; 103 varnewConnection;
104 varrecordConfiguration; 104 varrecordConfiguration;
105 105
106 deferredResult.addMethod(this, 'userSerializedEncryptedData', someData['users'][i]); 106 deferredResult.addMethod(this, 'userSerializedEncryptedData', someData['users'][i]);
107 deferredResult.addCallback(MochiKit.Base.bind(function(aUserSerializationContext) { 107 deferredResult.addCallback(MochiKit.Base.bind(function(aUserSerializationContext) {
108 resultData['users'][aUserSerializationContext['credentials']['C']] = { 108 resultData['users'][aUserSerializationContext['credentials']['C']] = {
109 's': aUserSerializationContext['credentials']['s'], 109 's': aUserSerializationContext['credentials']['s'],
110 'v': aUserSerializationContext['credentials']['v'], 110 'v': aUserSerializationContext['credentials']['v'],
111 'version': aUserSerializationContext['data']['connectionVersion'], 111 'version': aUserSerializationContext['data']['connectionVersion'],
112 'userDetails': aUserSerializationContext['encryptedData']['user']['header'], 112 'userDetails': aUserSerializationContext['encryptedData']['user']['header'],
113 'userDetailsVersion':aUserSerializationContext['encryptedData']['user']['version'], 113 'userDetailsVersion':aUserSerializationContext['encryptedData']['user']['version'],
114 'statistics': aUserSerializationContext['encryptedData']['user']['statistics'], 114 'statistics': aUserSerializationContext['encryptedData']['user']['statistics'],
115 'lock': aUserSerializationContext['encryptedData']['user']['lock'], 115 'lock': aUserSerializationContext['encryptedData']['user']['lock'],
116 'records': this.rearrangeRecordsData(aUserSerializationContext['encryptedData']['records']) 116 'records': this.rearrangeRecordsData(aUserSerializationContext['encryptedData']['records'])
117 } 117 }
118 }, this)); 118 }, this));
119 } 119 }
120 120
121 deferredResult.addCallback(MochiKit.Base.bind(function() { 121 deferredResult.addCallback(MochiKit.Base.bind(function() {
122 this._data = resultData; 122 this._data = resultData;
123 }, this)); 123 }, this));
124 124
125 deferredResult.callback(); 125 deferredResult.callback();
126//Clipperz.log("<<< Proxy.Test.setupWithData"); 126//Clipperz.log("<<< Proxy.Test.setupWithData");
127 127
128 return deferredResult; 128 return deferredResult;
129 }, 129 },
130 130
131 //========================================================================= 131 //=========================================================================
132 132
133 'getTollForRequestType': function (aRequestType) { 133 'getTollForRequestType': function (aRequestType) {
134 varresult; 134 varresult;
135 vartargetValue; 135 vartargetValue;
136 var cost; 136 var cost;
137 137
138 targetValue = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2); 138 targetValue = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2);
139 switch (aRequestType) { 139 switch (aRequestType) {
140 case 'REGISTER': 140 case 'REGISTER':
141 cost = 5; 141 cost = 5;
142 break; 142 break;
143 case 'CONNECT': 143 case 'CONNECT':
144 cost = 5; 144 cost = 5;
145 break; 145 break;
146 case 'MESSAGE': 146 case 'MESSAGE':
147 cost = 2; 147 cost = 2;
148 break; 148 break;
149 } 149 }
150 150
151 result = { 151 result = {
152 requestType: aRequestType, 152 requestType: aRequestType,
153 targetValue: targetValue, 153 targetValue: targetValue,
154 cost: cost 154 cost: cost
155 } 155 }
156 156
157 if (this.shouldPayTolls()) { 157 if (this.shouldPayTolls()) {
158 this.tolls()[targetValue] = result; 158 this.tolls()[targetValue] = result;
159 } 159 }
160 160
161 return result; 161 return result;
162 }, 162 },
163 163
164 //------------------------------------------------------------------------- 164 //-------------------------------------------------------------------------
165 165
166 'checkToll': function (aFunctionName, someParameters) { 166 'checkToll': function (aFunctionName, someParameters) {
167 if (this.shouldPayTolls()) { 167 if (this.shouldPayTolls()) {
168 var localToll; 168 var localToll;
169 vartollParameters; 169 vartollParameters;
170 170
171 tollParameters = someParameters['toll']; 171 tollParameters = someParameters['toll'];
172 localToll = this.tolls()[tollParameters['targetValue']]; 172 localToll = this.tolls()[tollParameters['targetValue']];
173 173
174 if (localToll != null) { 174 if (localToll != null) {
175 if (! Clipperz.PM.Toll.validate(tollParameters['targetValue'], tollParameters['toll'], localToll['cost'])) { 175 if (! Clipperz.PM.Toll.validate(tollParameters['targetValue'], tollParameters['toll'], localToll['cost'])) {
176 throw "Toll value too low."; 176 throw "Toll value too low.";
177 }; 177 };
178 } else { 178 } else {
179 throw "Missing toll"; 179 throw "Missing toll";
180 } 180 }
181 } 181 }
182 }, 182 },
183 183
184 //========================================================================= 184 //=========================================================================
185 185
186 'currentStaticConnection': function () { 186 'currentStaticConnection': function () {
187 if (this._currentStaticConnection == null) { 187 if (this._currentStaticConnection == null) {
188 this._currentStaticConnection = {}; 188 this._currentStaticConnection = {};
189 } 189 }
190 190
191 return this._currentStaticConnection; 191 return this._currentStaticConnection;
192 }, 192 },
193 193
194 //------------------------------------------------------------------------- 194 //-------------------------------------------------------------------------
195 195
196 'getConnectionForRequest': function (aFunctionName, someParameters) { 196 'getConnectionForRequest': function (aFunctionName, someParameters) {
197 varresult; 197 varresult;
198 198
199 if (this.shouldPayTolls()) { 199 if (this.shouldPayTolls()) {
200 if ((typeof(someParameters['toll']) != 'undefined') && (typeof(someParameters['toll']['targetValue']) != 'undefined')) { 200 if ((typeof(someParameters['toll']) != 'undefined') && (typeof(someParameters['toll']['targetValue']) != 'undefined')) {
201 result = this.tolls()[someParameters['toll']['targetValue']]['connection']; 201 result = this.tolls()[someParameters['toll']['targetValue']]['connection'];
202 if (typeof(result) == 'undefined') { 202 if (typeof(result) == 'undefined') {
203 result = {}; 203 result = {};
204 } 204 }
205 } else { 205 } else {
206 result = {}; 206 result = {};
207 } 207 }
208 } else { 208 } else {
209 result = this.currentStaticConnection(); 209 result = this.currentStaticConnection();
210 } 210 }
211 211
212 return result; 212 return result;
213 }, 213 },
214 214
215 //------------------------------------------------------------------------- 215 //-------------------------------------------------------------------------
216 216
217 'storeConnectionForRequestWithConnectionAndResponse': function (aFunctionName, someParameters, aConnection, aResponse) { 217 'storeConnectionForRequestWithConnectionAndResponse': function (aFunctionName, someParameters, aConnection, aResponse) {
218 if (this.shouldPayTolls()) { 218 if (this.shouldPayTolls()) {
219 if ((typeof(aResponse['toll']) != 'undefined') 219 if ((typeof(aResponse['toll']) != 'undefined')
220 &&(typeof(aResponse['toll']['targetValue']) != 'undefined') 220 &&(typeof(aResponse['toll']['targetValue']) != 'undefined')
221 &&(typeof(this.tolls()[aResponse['toll']['targetValue']]) != 'undefined') 221 &&(typeof(this.tolls()[aResponse['toll']['targetValue']]) != 'undefined')
222 ) { 222 ) {
223 this.tolls()[aResponse['toll']['targetValue']]['connection'] = aConnection; 223 this.tolls()[aResponse['toll']['targetValue']]['connection'] = aConnection;
224 } 224 }
225 } 225 }
226 }, 226 },
227 227
228 //========================================================================= 228 //=========================================================================
229 229
230 'processMessage': function (aFunctionName, someParameters) { 230 'processMessage': function (aFunctionName, someParameters) {
231 var result; 231 var result;
232 varconnection; 232 varconnection;
233 233
234 connection = this.getConnectionForRequest(aFunctionName, someParameters); 234 connection = this.getConnectionForRequest(aFunctionName, someParameters);
235 235
236 switch(aFunctionName) { 236 switch(aFunctionName) {
237 case 'knock': 237 case 'knock':
238 result = this._knock(connection, someParameters); 238 result = this._knock(connection, someParameters);
239 break; 239 break;
240 case 'registration': 240 case 'registration':
241 this.checkToll(aFunctionName, someParameters); 241 this.checkToll(aFunctionName, someParameters);
242 result = this._registration(connection, someParameters.parameters); 242 result = this._registration(connection, someParameters.parameters);
243 break; 243 break;
244 case 'handshake': 244 case 'handshake':
245 this.checkToll(aFunctionName, someParameters); 245 this.checkToll(aFunctionName, someParameters);
246 result = this._handshake(connection, someParameters.parameters); 246 result = this._handshake(connection, someParameters.parameters);
247 break; 247 break;
248 case 'message': 248 case 'message':
249 this.checkToll(aFunctionName, someParameters); 249 this.checkToll(aFunctionName, someParameters);
250 result = this._message(connection, someParameters.parameters); 250 result = this._message(connection, someParameters.parameters);
251 break; 251 break;
252 case 'logout': 252 case 'logout':
253 this._currentStaticConnection = null; 253 this._currentStaticConnection = null;
254 result = this._logout(connection, someParameters.parameters); 254 result = this._logout(connection, someParameters.parameters);
255 break; 255 break;
256 } 256 }
257 257
258 this.storeConnectionForRequestWithConnectionAndResponse(aFunctionName, someParameters, connection, result); 258 this.storeConnectionForRequestWithConnectionAndResponse(aFunctionName, someParameters, connection, result);
259 259
260 return MochiKit.Async.succeed(result); 260 return MochiKit.Async.succeed(result);
261 }, 261 },
262 262
263 //========================================================================= 263 //=========================================================================
264 264
265 '_knock': function(aConnection, someParameters) { 265 '_knock': function(aConnection, someParameters) {
266 var result; 266 var result;
267 267
268 result = { 268 result = {
269 toll: this.getTollForRequestType(someParameters['requestType']) 269 toll: this.getTollForRequestType(someParameters['requestType'])
270 } 270 }
271 271
272 return result; 272 return result;
273 }, 273 },
274 274
275 //------------------------------------------------------------------------- 275 //-------------------------------------------------------------------------
276 276
277 '_registration': function(aConnection, someParameters) { 277 '_registration': function(aConnection, someParameters) {
278 if (this.isReadOnly() == false) { 278 if (this.isReadOnly() == false) {
279 if (typeof(this.data()['users'][someParameters['credentials']['C']]) == 'undefined') { 279 if (typeof(this.data()['users'][someParameters['credentials']['C']]) == 'undefined') {
280 this.data()['users'][someParameters['credentials']['C']] = { 280 this.data()['users'][someParameters['credentials']['C']] = {
281 's': someParameters['credentials']['s'], 281 's': someParameters['credentials']['s'],
282 'v': someParameters['credentials']['v'], 282 'v': someParameters['credentials']['v'],
283 'version':someParameters['credentials']['version'], 283 'version':someParameters['credentials']['version'],
284 'lock': Clipperz.Crypto.Base.generateRandomSeed(), 284 // 'lock': Clipperz.Crypto.Base.generateRandomSeed(),
285 'userDetails': someParameters['user']['header'], 285 'userDetails': someParameters['user']['header'],
286 'statistics': someParameters['user']['statistics'], 286 'statistics': someParameters['user']['statistics'],
287 'userDetailsVersion':someParameters['user']['version'], 287 'userDetailsVersion':someParameters['user']['version'],
288 'records':{} 288 'records':{}
289 } 289 }
290 } else { 290 } else {
291 throw "user already exists"; 291 throw "user already exists";
292 } 292 }
293 } else { 293 } else {
294 throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly; 294 throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly;
295 } 295 }
296 296
297 result = { 297 result = {
298 result: { 298 result: {
299 'lock': this.data()['users'][someParameters['credentials']['C']]['lock'], 299 'lock': this.data()['users'][someParameters['credentials']['C']]['lock'],
300 'result':'done' 300 'result':'done'
301 }, 301 },
302 toll: this.getTollForRequestType('CONNECT') 302 toll: this.getTollForRequestType('CONNECT')
303 } 303 }
304 304
305 return result; 305 return result;
306 }, 306 },
307 307
308 //------------------------------------------------------------------------- 308 //-------------------------------------------------------------------------
309 309
310 '_handshake': function(aConnection, someParameters) { 310 '_handshake': function(aConnection, someParameters) {
311 var result; 311 var result;
312 varnextTollRequestType; 312 varnextTollRequestType;
313 313
314 result = {}; 314 result = {};
315 if (someParameters.message == "connect") { 315 if (someParameters.message == "connect") {
316 var userData; 316 var userData;
317 var randomBytes; 317 var randomBytes;
318 var v; 318 var v;
319 319
320 userData = this.data()['users'][someParameters.parameters.C]; 320 userData = this.data()['users'][someParameters.parameters.C];
321 321
322 if ((typeof(userData) != 'undefined') && (userData['version'] == someParameters.version)) { 322 if ((typeof(userData) != 'undefined') && (userData['version'] == someParameters.version)) {
323 aConnection['userData'] = userData; 323 aConnection['userData'] = userData;
324 aConnection['C'] = someParameters.parameters.C; 324 aConnection['C'] = someParameters.parameters.C;
325 } else { 325 } else {
326 aConnection['userData'] = this.data()['users']['catchAllUser']; 326 aConnection['userData'] = this.data()['users']['catchAllUser'];
327 } 327 }
328 328
329 randomBytes = Clipperz.Crypto.Base.generateRandomSeed(); 329 randomBytes = Clipperz.Crypto.Base.generateRandomSeed();
330 aConnection['b'] = new Clipperz.Crypto.BigInt(randomBytes, 16); 330 aConnection['b'] = new Clipperz.Crypto.BigInt(randomBytes, 16);
331 v = new Clipperz.Crypto.BigInt(aConnection['userData']['v'], 16); 331 v = new Clipperz.Crypto.BigInt(aConnection['userData']['v'], 16);
332 aConnection['B'] = v.add(Clipperz.Crypto.SRP.g().powerModule(aConnection['b'], Clipperz.Crypto.SRP.n())); 332 aConnection['B'] = v.add(Clipperz.Crypto.SRP.g().powerModule(aConnection['b'], Clipperz.Crypto.SRP.n()));
333 333
334 aConnection['A'] = someParameters.parameters.A; 334 aConnection['A'] = someParameters.parameters.A;
335 335
336 result['s'] = aConnection['userData']['s']; 336 result['s'] = aConnection['userData']['s'];
337 result['B'] = aConnection['B'].asString(16); 337 result['B'] = aConnection['B'].asString(16);
338 338
339 nextTollRequestType = 'CONNECT'; 339 nextTollRequestType = 'CONNECT';
340 } else if (someParameters.message == "credentialCheck") { 340 } else if (someParameters.message == "credentialCheck") {
341 var v, u, S, A, K, M1; 341 var v, u, S, A, K, M1;
342 342
343 v = new Clipperz.Crypto.BigInt(aConnection['userData']['v'], 16); 343 v = new Clipperz.Crypto.BigInt(aConnection['userData']['v'], 16);
344 u = new Clipperz.Crypto.BigInt(Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(aConnection['B'].asString(10))).toHexString(), 16); 344 u = new Clipperz.Crypto.BigInt(Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(aConnection['B'].asString(10))).toHexString(), 16);
345 A = new Clipperz.Crypto.BigInt(aConnection['A'], 16); 345 A = new Clipperz.Crypto.BigInt(aConnection['A'], 16);
346 S = (A.multiply(v.powerModule(u, Clipperz.Crypto.SRP.n()))).powerModule(aConnection['b'], Clipperz.Crypto.SRP.n()); 346 S = (A.multiply(v.powerModule(u, Clipperz.Crypto.SRP.n()))).powerModule(aConnection['b'], Clipperz.Crypto.SRP.n());
347 347
348 K = Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(S.asString(10))).toHexString().slice(2); 348 K = Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(S.asString(10))).toHexString().slice(2);
349 349
350 M1 = Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(A.asString(10) + aConnection['B'].asString(10) + K)).toHexString().slice(2); 350 M1 = Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(A.asString(10) + aConnection['B'].asString(10) + K)).toHexString().slice(2);
351 if (someParameters.parameters.M1 == M1) { 351 if (someParameters.parameters.M1 == M1) {
352 var M2; 352 var M2;
353 353
354 M2 = Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(A.asString(10) + someParameters.parameters.M1 + K)).toHexString().slice(2); 354 M2 = Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(A.asString(10) + someParameters.parameters.M1 + K)).toHexString().slice(2);
355 result['M2'] = M2; 355 result['M2'] = M2;
356 } else { 356 } else {
357 throw new Error("Client checksum verification failed! Expected <" + M1 + ">, received <" + someParameters.parameters.M1 + ">.", "Error"); 357 throw new Error("Client checksum verification failed! Expected <" + M1 + ">, received <" + someParameters.parameters.M1 + ">.", "Error");
358 } 358 }
359 359
360 nextTollRequestType = 'MESSAGE'; 360 nextTollRequestType = 'MESSAGE';
361 } else if (someParameters.message == "oneTimePassword") { 361 } else if (someParameters.message == "oneTimePassword") {
362 var otpData; 362 var otpData;
363 363
364 otpData = this.data()['onetimePasswords'][someParameters.parameters.oneTimePasswordKey]; 364 otpData = this.data()['onetimePasswords'][someParameters.parameters.oneTimePasswordKey];
365 365
366 try { 366 try {
367 if (typeof(otpData) != 'undefined') { 367 if (typeof(otpData) != 'undefined') {
368 if (otpData['status'] == 'ACTIVE') { 368 if (otpData['status'] == 'ACTIVE') {
369 if (otpData['key_checksum'] == someParameters.parameters.oneTimePasswordKeyChecksum) { 369 if (otpData['key_checksum'] == someParameters.parameters.oneTimePasswordKeyChecksum) {
370 result = { 370 result = {
371 'data': otpData['data'], 371 'data': otpData['data'],
372 'version':otpData['version'] 372 'version':otpData['version']
373 } 373 }
374 374
375 otpData['status'] = 'REQUESTED'; 375 otpData['status'] = 'REQUESTED';
376 } else { 376 } else {
377 otpData['status'] = 'DISABLED'; 377 otpData['status'] = 'DISABLED';
378 throw "The requested One Time Password has been disabled, due to a wrong keyChecksum"; 378 throw "The requested One Time Password has been disabled, due to a wrong keyChecksum";
379 } 379 }
380 } else { 380 } else {
381 throw "The requested One Time Password was not active"; 381 throw "The requested One Time Password was not active";
382 } 382 }
383 } else { 383 } else {
384 throw "The requested One Time Password has not been found" 384 throw "The requested One Time Password has not been found"
385 } 385 }
386 } catch (exception) { 386 } catch (exception) {
387 result = { 387 result = {
388 'data': Clipperz.PM.Crypto.randomKey(), 388 'data': Clipperz.PM.Crypto.randomKey(),
389 'version':Clipperz.PM.Connection.communicationProtocol.currentVersion 389 'version':Clipperz.PM.Connection.communicationProtocol.currentVersion
390 } 390 }
391 } 391 }
392 nextTollRequestType = 'CONNECT'; 392 nextTollRequestType = 'CONNECT';
393 } else { 393 } else {
394 Clipperz.logError("Clipperz.PM.Proxy.Test.handshake - unhandled message: " + someParameters.message); 394 Clipperz.logError("Clipperz.PM.Proxy.Test.handshake - unhandled message: " + someParameters.message);
395 } 395 }
396 396
397 result = { 397 result = {
398 result: result, 398 result: result,
399 toll: this.getTollForRequestType(nextTollRequestType) 399 toll: this.getTollForRequestType(nextTollRequestType)
400 } 400 }
401 401
402 return result; 402 return result;
403 }, 403 },
404 404
405 //------------------------------------------------------------------------- 405 //-------------------------------------------------------------------------
406 406
407 '_message': function(aConnection, someParameters) { 407 '_message': function(aConnection, someParameters) {
408 var result; 408 var result;
409 409
410 result = {}; 410 result = {};
411 411
412 //===================================================================== 412 //=====================================================================
413 // 413 //
414 // R E A D - O N L Y M e t h o d s 414 // R E A D - O N L Y M e t h o d s
415 // 415 //
416 //===================================================================== 416 //=====================================================================
417 if (someParameters.message == 'getUserDetails') { 417 if (someParameters.message == 'getUserDetails') {
418 var recordsStats; 418 var recordsStats;
419 var recordReference; 419 var recordReference;
420 420
421 recordsStats = {}; 421 recordsStats = {};
422 for (recordReference in aConnection['userData']['records']) { 422 for (recordReference in aConnection['userData']['records']) {
423 recordsStats[recordReference] = { 423 recordsStats[recordReference] = {
424 'updateDate': aConnection['userData']['records'][recordReference]['updateDate'] 424 'updateDate': aConnection['userData']['records'][recordReference]['updateDate']
425 } 425 }
426 } 426 }
427 427
428 result['header'] = this.userDetails(aConnection); 428 result['header'] = this.userDetails(aConnection);
429 result['statistics'] = this.statistics(aConnection); 429 result['statistics'] = this.statistics(aConnection);
430 result['maxNumberOfRecords'] = aConnection['userData']['maxNumberOfRecords']; 430 result['maxNumberOfRecords'] = aConnection['userData']['maxNumberOfRecords'];
431 result['version'] = aConnection['userData']['userDetailsVersion']; 431 result['version'] = aConnection['userData']['userDetailsVersion'];
432 result['recordsStats'] = recordsStats; 432 result['recordsStats'] = recordsStats;
433 433
434 if (this.isReadOnly() == false) { 434 if (this.isReadOnly() == false) {
435 varlock; 435 varlock;
436 436
437 if (typeof(aConnection['userData']['lock']) == 'undefined') { 437 if (typeof(aConnection['userData']['lock']) == 'undefined') {
438 aConnection['userData']['lock'] = "<<LOCK>>"; 438 aConnection['userData']['lock'] = "<<LOCK>>";
439 } 439 }
440 440
441 result['lock'] = aConnection['userData']['lock']; 441 result['lock'] = aConnection['userData']['lock'];
442 } 442 }
443 443
444 //===================================================================== 444 //=====================================================================
445 } else if (someParameters.message == 'getRecordDetail') { 445 } else if (someParameters.message == 'getRecordDetail') {
446/* 446/*
447 varrecordData; 447 varrecordData;
448 var currentVersionData; 448 var currentVersionData;
449 449
450 recordData = this.userData()['records'][someParameters['parameters']['reference']]; 450 recordData = this.userData()['records'][someParameters['parameters']['reference']];
451 result['reference'] = someParameters['parameters']['reference']; 451 result['reference'] = someParameters['parameters']['reference'];
452 result['data'] = recordData['data']; 452 result['data'] = recordData['data'];
453 result['version'] = recordData['version']; 453 result['version'] = recordData['version'];
454 result['creationData'] = recordData['creationDate']; 454 result['creationData'] = recordData['creationDate'];
455 result['updateDate'] = recordData['updateDate']; 455 result['updateDate'] = recordData['updateDate'];
456 result['accessDate'] = recordData['accessDate']; 456 result['accessDate'] = recordData['accessDate'];
457 457
458 currentVersionData = recordData['versions'][recordData['currentVersion']]; 458 currentVersionData = recordData['versions'][recordData['currentVersion']];
459 459
460 result['currentVersion'] = {}; 460 result['currentVersion'] = {};
461 result['currentVersion']['reference'] = recordData['currentVersion']; 461 result['currentVersion']['reference'] = recordData['currentVersion'];
462 result['currentVersion']['version'] = currentVersionData['version']; 462 result['currentVersion']['version'] = currentVersionData['version'];
463 result['currentVersion']['header'] = currentVersionData['header']; 463 result['currentVersion']['header'] = currentVersionData['header'];
464 result['currentVersion']['data'] = currentVersionData['data']; 464 result['currentVersion']['data'] = currentVersionData['data'];
465 result['currentVersion']['creationData'] = currentVersionData['creationDate']; 465 result['currentVersion']['creationData'] = currentVersionData['creationDate'];
466 result['currentVersion']['updateDate'] = currentVersionData['updateDate']; 466 result['currentVersion']['updateDate'] = currentVersionData['updateDate'];
467 result['currentVersion']['accessDate'] = currentVersionData['accessDate']; 467 result['currentVersion']['accessDate'] = currentVersionData['accessDate'];
468 if (typeof(currentVersionData['previousVersion']) != 'undefined') { 468 if (typeof(currentVersionData['previousVersion']) != 'undefined') {
469 result['currentVersion']['previousVersionKey'] = currentVersionData['previousVersionKey']; 469 result['currentVersion']['previousVersionKey'] = currentVersionData['previousVersionKey'];
470 result['currentVersion']['previousVersion'] = currentVersionData['previousVersion']; 470 result['currentVersion']['previousVersion'] = currentVersionData['previousVersion'];
471 } 471 }
472*/ 472*/
473 MochiKit.Base.update(result, aConnection['userData']['records'][someParameters['parameters']['reference']]); 473 MochiKit.Base.update(result, aConnection['userData']['records'][someParameters['parameters']['reference']]);
474 result['reference'] = someParameters['parameters']['reference']; 474 result['reference'] = someParameters['parameters']['reference'];
475 475
476 //===================================================================== 476 //=====================================================================
477 // 477 //
478 // R E A D - W R I T E M e t h o d s 478 // R E A D - W R I T E M e t h o d s
479 // 479 //
480 //===================================================================== 480 //=====================================================================
481 } else if (someParameters.message == 'upgradeUserCredentials') { 481 } else if (someParameters.message == 'upgradeUserCredentials') {
482 if (this.isReadOnly() == false) { 482 if (this.isReadOnly() == false) {
483 var parameters; 483 var parameters;
484 var credentials; 484 var credentials;
485 485
486 parameters = someParameters['parameters']; 486 parameters = someParameters['parameters'];
487 credentials = parameters['credentials']; 487 credentials = parameters['credentials'];
488 488
489 if ((credentials['C'] == null) 489 if ((credentials['C'] == null)
490 ||(credentials['s'] == null) 490 ||(credentials['s'] == null)
491 ||(credentials['v'] == null) 491 ||(credentials['v'] == null)
492 ||(credentials['version'] != Clipperz.PM.Connection.communicationProtocol.currentVersion) 492 ||(credentials['version'] != Clipperz.PM.Connection.communicationProtocol.currentVersion)
493 ) { 493 ) {
494 result = Clipperz.PM.DataModel.User.exception.CredentialUpgradeFailed; 494 result = Clipperz.PM.DataModel.User.exception.CredentialUpgradeFailed;
495 } else { 495 } else {
496 varoldCValue; 496 varoldCValue;
497 oldCValue = aConnection['C']; 497 oldCValue = aConnection['C'];
498 498
499 this.data()['users'][credentials['C']] = aConnection['userData']; 499 this.data()['users'][credentials['C']] = aConnection['userData'];
500 aConnection['C'] = credentials['C']; 500 aConnection['C'] = credentials['C'];
501 501
502 aConnection['userData']['s'] = credentials['s']; 502 aConnection['userData']['s'] = credentials['s'];
503 aConnection['userData']['v'] = credentials['v']; 503 aConnection['userData']['v'] = credentials['v'];
504 aConnection['userData']['version'] = credentials['version']; 504 aConnection['userData']['version'] = credentials['version'];
505 505
506 aConnection['userData']['userDetails'] = parameters['user']['header']; 506 aConnection['userData']['userDetails'] = parameters['user']['header'];
507 aConnection['userData']['userDetailsVersion'] = parameters['user']['version']; 507 aConnection['userData']['userDetailsVersion'] = parameters['user']['version'];
508 aConnection['userData']['statistics'] = parameters['user']['statistics']; 508 aConnection['userData']['statistics'] = parameters['user']['statistics'];
509 509
510 aConnection['userData']['lock'] = parameters['user']['lock']; 510 aConnection['userData']['lock'] = parameters['user']['lock'];
511 511
512 delete this.data()['users'][oldCValue]; 512 delete this.data()['users'][oldCValue];
513 513
514 result = {result:"done", parameters:parameters}; 514 result = {result:"done", parameters:parameters};
515 } 515 }
516 } else { 516 } else {
517 throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly; 517 throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly;
518 } 518 }
519 //===================================================================== 519 //=====================================================================
520 /* } else if (someParameters.message == 'updateData') { 520 /* } else if (someParameters.message == 'updateData') {
521 if (this.isReadOnly() == false) { 521 if (this.isReadOnly() == false) {
522 var i, c; 522 var i, c;
523 523
524 if (this.userData()['lock']!= someParameters['parameters']['user']['lock']) { 524 if (this.userData()['lock']!= someParameters['parameters']['user']['lock']) {
525 throw "the lock attribute is not processed correctly" 525 throw "the lock attribute is not processed correctly"
526 } 526 }
527 527
528 this.userData()['userDetails'] = someParameters['parameters']['user']['header']; 528 this.userData()['userDetails'] = someParameters['parameters']['user']['header'];
529 this.userData()['statistics'] = someParameters['parameters']['user']['statistics']; 529 this.userData()['statistics'] = someParameters['parameters']['user']['statistics'];
530 this.userData()['userDetailsVersions']= someParameters['parameters']['user']['version']; 530 this.userData()['userDetailsVersions']= someParameters['parameters']['user']['version'];
531 531
532 c = someParameters['parameters']['records'].length; 532 c = someParameters['parameters']['records'].length;
533 for (i=0; i<c; i++) { 533 for (i=0; i<c; i++) {
534 var currentRecord; 534 var currentRecord;
535 var currentRecordData; 535 var currentRecordData;
536 536
537 currentRecordData = someParameters['parameters']['records'][i]; 537 currentRecordData = someParameters['parameters']['records'][i];
538 currentRecord = this.userData()['records'][currentRecordData['record']['reference']]; 538 currentRecord = this.userData()['records'][currentRecordData['record']['reference']];
539 539
540 if (currentRecord == null) { 540 if (currentRecord == null) {
541 } 541 }
542 542
543 currentRecord['data'] = currentRecordData['record']['data']; 543 currentRecord['data'] = currentRecordData['record']['data'];
544 currentRecord['version'] = currentRecordData['record']['version']; 544 currentRecord['version'] = currentRecordData['record']['version'];
545 currentRecord['currentVersion'] = currentRecordData['currentRecordVersion']['reference']; 545 currentRecord['currentVersion'] = currentRecordData['currentRecordVersion']['reference'];
546 546
547 currentRecord['versions'][currentRecordData['currentRecordVersion']['reference']] = { 547 currentRecord['versions'][currentRecordData['currentRecordVersion']['reference']] = {
548 'data': currentRecordData['currentRecordVersion']['data'], 548 'data': currentRecordData['currentRecordVersion']['data'],
549 'version': currentRecordData['currentRecordVersion']['version'], 549 'version': currentRecordData['currentRecordVersion']['version'],
550 'previousVersion': currentRecordData['currentRecordVersion']['previousVersion'], 550 'previousVersion': currentRecordData['currentRecordVersion']['previousVersion'],
551 'previousVersionKey':currentRecordData['currentRecordVersion']['previousVersionKey'] 551 'previousVersionKey':currentRecordData['currentRecordVersion']['previousVersionKey']
552 } 552 }
553 } 553 }
554 554
555 this.userData()['lock'] = Clipperz.PM.Crypto.randomKey(); 555 this.userData()['lock'] = Clipperz.PM.Crypto.randomKey();
556 result['lock'] = this.userData()['lock']; 556 result['lock'] = this.userData()['lock'];
557 result['result'] = 'done'; 557 result['result'] = 'done';
558 } else { 558 } else {
559 throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly; 559 throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly;
560 } 560 }
561 */ //===================================================================== 561 */ //=====================================================================
562 } else if (someParameters.message == 'saveChanges') { 562 } else if (someParameters.message == 'saveChanges') {
563 if (this.isReadOnly() == false) { 563 if (this.isReadOnly() == false) {
564 var i, c; 564 var i, c;
565 565
566 if (aConnection['userData']['lock']!= someParameters['parameters']['user']['lock']) { 566 if (aConnection['userData']['lock']!= someParameters['parameters']['user']['lock']) {
567 throw "the lock attribute is not processed correctly" 567 throw "the lock attribute is not processed correctly"
568 } 568 }
569 569
570 aConnection['userData']['userDetails'] = someParameters['parameters']['user']['header']; 570 aConnection['userData']['userDetails'] = someParameters['parameters']['user']['header'];
571 aConnection['userData']['statistics'] = someParameters['parameters']['user']['statistics']; 571 aConnection['userData']['statistics'] = someParameters['parameters']['user']['statistics'];
572 aConnection['userData']['userDetailsVersions']= someParameters['parameters']['user']['version']; 572 aConnection['userData']['userDetailsVersion']= someParameters['parameters']['user']['version'];
573 573
574 c = someParameters['parameters']['records']['updated'].length; 574 c = someParameters['parameters']['records']['updated'].length;
575 for (i=0; i<c; i++) { 575 for (i=0; i<c; i++) {
576 var currentRecord; 576 var currentRecord;
577 var currentRecordData; 577 var currentRecordData;
578 578
579 currentRecordData = someParameters['parameters']['records']['updated'][i]; 579 currentRecordData = someParameters['parameters']['records']['updated'][i];
580 currentRecord = aConnection['userData']['records'][currentRecordData['record']['reference']]; 580 currentRecord = aConnection['userData']['records'][currentRecordData['record']['reference']];
581 581
582 if ( 582 if (
583 (typeof(aConnection['userData']['records'][currentRecordData['record']['reference']]) == 'undefined') 583 (typeof(aConnection['userData']['records'][currentRecordData['record']['reference']]) == 'undefined')
584 && 584 &&
585 (typeof(currentRecordData['currentRecordVersion']) == 'undefined') 585 (typeof(currentRecordData['currentRecordVersion']) == 'undefined')
586 ) { 586 ) {
587 throw "Record added without a recordVersion"; 587 throw "Record added without a recordVersion";
588 } 588 }
589 589
590 if (currentRecord == null) { 590 if (currentRecord == null) {
591 currentRecord = {}; 591 currentRecord = {};
592 currentRecord['versions'] = {}; 592 currentRecord['versions'] = {};
593 currentRecord['creationDate']= Clipperz.PM.Date.formatDateWithUTCFormat(new Date()); 593 currentRecord['creationDate']= Clipperz.PM.Date.formatDateWithUTCFormat(new Date());
594 currentRecord['accessDate'] = Clipperz.PM.Date.formatDateWithUTCFormat(new Date()); 594 currentRecord['accessDate'] = Clipperz.PM.Date.formatDateWithUTCFormat(new Date());
595 595
596 aConnection['userData']['records'][currentRecordData['record']['reference']] = currentRecord; 596 aConnection['userData']['records'][currentRecordData['record']['reference']] = currentRecord;
597 } 597 }
598 598
599 currentRecord['data'] = currentRecordData['record']['data']; 599 currentRecord['data'] = currentRecordData['record']['data'];
600 currentRecord['version']= currentRecordData['record']['version']; 600 currentRecord['version']= currentRecordData['record']['version'];
601 currentRecord['updateDate']= Clipperz.PM.Date.formatDateWithUTCFormat(new Date()); 601 currentRecord['updateDate']= Clipperz.PM.Date.formatDateWithUTCFormat(new Date());
602 602
603 if (typeof(currentRecordData['currentRecordVersion']) != 'undefined') { 603 if (typeof(currentRecordData['currentRecordVersion']) != 'undefined') {
604 currentRecord['currentVersion'] = currentRecordData['currentRecordVersion']['reference']; 604 currentRecord['currentVersion'] = currentRecordData['currentRecordVersion']['reference'];
605 currentRecord['versions'][currentRecordData['currentRecordVersion']['reference']] = { 605 currentRecord['versions'][currentRecordData['currentRecordVersion']['reference']] = {
606 'data': currentRecordData['currentRecordVersion']['data'], 606 'data': currentRecordData['currentRecordVersion']['data'],
607 'version': currentRecordData['currentRecordVersion']['version'], 607 'version': currentRecordData['currentRecordVersion']['version'],
608 'previousVersion': currentRecordData['currentRecordVersion']['previousVersion'], 608 'previousVersion': currentRecordData['currentRecordVersion']['previousVersion'],
609 'previousVersionKey':currentRecordData['currentRecordVersion']['previousVersionKey'], 609 'previousVersionKey':currentRecordData['currentRecordVersion']['previousVersionKey'],
610 'creationDate':Clipperz.PM.Date.formatDateWithUTCFormat(new Date()), 610 'creationDate':Clipperz.PM.Date.formatDateWithUTCFormat(new Date()),
611 'updateDate':Clipperz.PM.Date.formatDateWithUTCFormat(new Date()), 611 'updateDate':Clipperz.PM.Date.formatDateWithUTCFormat(new Date()),
612 'accessDate':Clipperz.PM.Date.formatDateWithUTCFormat(new Date()) 612 'accessDate':Clipperz.PM.Date.formatDateWithUTCFormat(new Date())
613 } 613 }
614 } 614 }
615 } 615 }
616 616
617 c = someParameters['parameters']['records']['deleted'].length; 617 c = someParameters['parameters']['records']['deleted'].length;
618 for (i=0; i<c; i++) { 618 for (i=0; i<c; i++) {
619 var currentRecordReference; 619 var currentRecordReference;
620 620
621 currentRecordReference = someParameters['parameters']['records']['deleted'][i]; 621 currentRecordReference = someParameters['parameters']['records']['deleted'][i];
622 delete aConnection['userData']['records'][currentRecordReference]; 622 delete aConnection['userData']['records'][currentRecordReference];
623 } 623 }
624 624
625 aConnection['userData']['lock'] = Clipperz.PM.Crypto.randomKey(); 625 aConnection['userData']['lock'] = Clipperz.PM.Crypto.randomKey();
626 result['lock'] = aConnection['userData']['lock']; 626 result['lock'] = aConnection['userData']['lock'];
627 result['result'] = 'done'; 627 result['result'] = 'done';
628 } else { 628 } else {
629 throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly; 629 throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly;
630 } 630 }
631 631
632 //===================================================================== 632 //=====================================================================
633 // 633 //
634 // U N H A N D L E D M e t h o d 634 // U N H A N D L E D M e t h o d
635 // 635 //
636 //===================================================================== 636 //=====================================================================
637 } else { 637 } else {
638 Clipperz.logError("Clipperz.PM.Proxy.Test.message - unhandled message: " + someParameters.message); 638 Clipperz.logError("Clipperz.PM.Proxy.Test.message - unhandled message: " + someParameters.message);
639 } 639 }
640 640
641 result = { 641 result = {
642 result: result, 642 result: result,
643 toll: this.getTollForRequestType('MESSAGE') 643 toll: this.getTollForRequestType('MESSAGE')
644 } 644 }
645 645
646 // return MochiKit.Async.succeed(result); 646 // return MochiKit.Async.succeed(result);
647 return result; 647 return result;
648 }, 648 },
649 649
650 //------------------------------------------------------------------------- 650 //-------------------------------------------------------------------------
651 651
652 '_logout': function(someParameters) { 652 '_logout': function(someParameters) {
653 // return MochiKit.Async.succeed({result: 'done'}); 653 // return MochiKit.Async.succeed({result: 'done'});
654 return {result: 'done'}; 654 return {result: 'done'};
655 }, 655 },
656 656
657 //========================================================================= 657 //=========================================================================
658 //######################################################################### 658 //#########################################################################
659 659
660 'isTestData': function(aConnection) { 660 'isTestData': function(aConnection) {
661 return (typeof(aConnection['userData']['__masterkey_test_value__']) != 'undefined'); 661 return (typeof(aConnection['userData']['__masterkey_test_value__']) != 'undefined');
662 }, 662 },
663 663
664 'userDetails': function(aConnection) { 664 'userDetails': function(aConnection) {
665 var result; 665 var result;
666 666
667 if (this.isTestData(aConnection)) { 667 if (this.isTestData(aConnection)) {
668 var serializedHeader; 668 var serializedHeader;
669 var version; 669 var version;
670 670
671//Clipperz.logDebug("### test data"); 671//Clipperz.logDebug("### test data");
672 version = aConnection['userData']['userDetailsVersion']; 672 version = aConnection['userData']['userDetailsVersion'];
673 serializedHeader = Clipperz.Base.serializeJSON(aConnection['userData']['userDetails']); 673 serializedHeader = Clipperz.Base.serializeJSON(aConnection['userData']['userDetails']);
674 result = Clipperz.PM.Crypto.encryptingFunctions.versions[version].encrypt(aConnection['userData']['__masterkey_test_value__'], serializedHeader); 674 result = Clipperz.PM.Crypto.encryptingFunctions.versions[version].encrypt(aConnection['userData']['__masterkey_test_value__'], serializedHeader);
675 } else { 675 } else {
676//Clipperz.logDebug("### NOT test data"); 676//Clipperz.logDebug("### NOT test data");
677 result = aConnection['userData']['userDetails']; 677 result = aConnection['userData']['userDetails'];
678 } 678 }
679 679
680 return result; 680 return result;
681 }, 681 },
682 682
683 'statistics': function(aConnection) { 683 'statistics': function(aConnection) {
684 var result; 684 var result;
685 685
686 if (aConnection['userData']['statistics'] != null) { 686 if (aConnection['userData']['statistics'] != null) {
687 if (this.isTestData(aConnection)) { 687 if (this.isTestData(aConnection)) {
688 var serializedStatistics; 688 var serializedStatistics;
689 var version; 689 var version;
690 690
691 version = aConnection['userData']['userDetailsVersion']; 691 version = aConnection['userData']['userDetailsVersion'];
692 serializedStatistics = Clipperz.Base.serializeJSON(aConnection['userData']['statistics']); 692 serializedStatistics = Clipperz.Base.serializeJSON(aConnection['userData']['statistics']);
693 result = Clipperz.PM.Crypto.encryptingFunctions.versions[version].encrypt(aConnection['userData']['__masterkey_test_value__'], serializedStatistics); 693 result = Clipperz.PM.Crypto.encryptingFunctions.versions[version].encrypt(aConnection['userData']['__masterkey_test_value__'], serializedStatistics);
694 } else { 694 } else {
695 result = aConnection['userData']['statistics']; 695 result = aConnection['userData']['statistics'];
696 } 696 }
697 } else { 697 } else {
698 result = null; 698 result = null;
699 } 699 }
700 700
701 return result; 701 return result;
702 }, 702 },
703 703
704/* 704/*
705 'userSerializedEncryptedData': function(someData) { 705 'userSerializedEncryptedData': function(someData) {
706 var deferredResult; 706 var deferredResult;
707 var deferredContext; 707 var deferredContext;
708 708
709 deferredContext = { 'data': someData }; 709 deferredContext = { 'data': someData };
710 710
711 deferredResult = new Clipperz.Async.Deferred('Proxy.Test.serializeUserEncryptedData', {trace:false}); 711 deferredResult = new Clipperz.Async.Deferred('Proxy.Test.serializeUserEncryptedData', {trace:false});
712 deferredResult.addCallback(MochiKit.Base.bind(function(aDeferredContext) { 712 deferredResult.addCallback(MochiKit.Base.bind(function(aDeferredContext) {
713 aDeferredContext['user'] = this.createUserUsingConfigurationData(aDeferredContext['data']); 713 aDeferredContext['user'] = this.createUserUsingConfigurationData(aDeferredContext['data']);
714 return aDeferredContext; 714 return aDeferredContext;
715 }, this)); 715 }, this));
716 deferredResult.addCallback(function(aDeferredContext) { 716 deferredResult.addCallback(function(aDeferredContext) {
717 // return aDeferredContext['user'].encryptedDataUsingVersion(aDeferredContext['data']['version']); 717 // return aDeferredContext['user'].encryptedDataUsingVersion(aDeferredContext['data']['version']);
718 return aDeferredContext['user'].serializedDataUsingVersion(MochiKit.Base.values(aDeferredContext['user'].records()), aDeferredContext['data']['version']); 718 return aDeferredContext['user'].serializedDataUsingVersion(MochiKit.Base.values(aDeferredContext['user'].records()), aDeferredContext['data']['version']);
719 }); 719 });
720 deferredResult.addCallback(function(aUserEncryptedData) { 720 deferredResult.addCallback(function(aUserEncryptedData) {
721 deferredContext['encryptedData'] = aUserEncryptedData; 721 deferredContext['encryptedData'] = aUserEncryptedData;
722 return deferredContext; 722 return deferredContext;
723 }); 723 });
724 deferredResult.addCallback(function(aDeferredContext) { 724 deferredResult.addCallback(function(aDeferredContext) {
725 var connection; 725 var connection;
726 726
727 connection = new Clipperz.PM.Connection.communicationProtocol.versions[aDeferredContext['data']['connectionVersion']]() 727 connection = new Clipperz.PM.Connection.communicationProtocol.versions[aDeferredContext['data']['connectionVersion']]()
728 aDeferredContext['credentials'] = connection.serverSideUserCredentials(aDeferredContext['user'].username(),aDeferredContext['user'].passphrase()); 728 aDeferredContext['credentials'] = connection.serverSideUserCredentials(aDeferredContext['user'].username(),aDeferredContext['user'].passphrase());
729 729
730 return aDeferredContext; 730 return aDeferredContext;
731 }); 731 });
732 732
733 // deferredResult.addCallback(function(aDeferredContext) { 733 // deferredResult.addCallback(function(aDeferredContext) {
734 // return aDeferredContext['user'].serializedDataUsingVersion(MochiKit.Base.values(aDeferredContext['user'].records()), aDeferredContext['data']['version']); 734 // return aDeferredContext['user'].serializedDataUsingVersion(MochiKit.Base.values(aDeferredContext['user'].records()), aDeferredContext['data']['version']);
735 // }, deferredContext); 735 // }, deferredContext);
736 // deferredResult.addCallback(function(aUserSerializedData) { 736 // deferredResult.addCallback(function(aUserSerializedData) {
737 // }); 737 // });
738// 738//
739 // deferredResult.addCallback(MochiKit.Async.succeed, deferredContext); 739 // deferredResult.addCallback(MochiKit.Async.succeed, deferredContext);
740 deferredResult.callback(deferredContext); 740 deferredResult.callback(deferredContext);
741 741
742 return deferredResult; 742 return deferredResult;
743 }, 743 },
744 744
745 'createUserUsingConfigurationData': function(someData) { 745 'createUserUsingConfigurationData': function(someData) {
746 var result; 746 var result;
747 var user; 747 var user;
748 var recordLabel; 748 var recordLabel;
749 749
750 user = new Clipperz.PM.DataModel.User(); 750 user = new Clipperz.PM.DataModel.User();
751 user.initForTests(); 751 user.initForTests();
752 user.setUsername(someData['username']); 752 user.setUsername(someData['username']);
753 user.setPassphrase(someData['passphrase']); 753 user.setPassphrase(someData['passphrase']);
754 754
755 for (recordLabel in someData['records']) { 755 for (recordLabel in someData['records']) {
756 var recordData; 756 var recordData;
757 var record; 757 var record;
758 var i, c; 758 var i, c;
759 759
760 recordData = someData['records'][recordLabel]; 760 recordData = someData['records'][recordLabel];
761 record = new Clipperz.PM.DataModel.Record({user:user, label:recordLabel}); 761 record = new Clipperz.PM.DataModel.Record({user:user, label:recordLabel});
762 record.setNotes(recordData['notes']); 762 record.setNotes(recordData['notes']);
763 763
764 c = recordData['fields'].length; 764 c = recordData['fields'].length;
765 for (i=0; i<c; i++) { 765 for (i=0; i<c; i++) {
766 var recordField; 766 var recordField;
767 767
768 recordField = new Clipperz.PM.DataModel.RecordField(); 768 recordField = new Clipperz.PM.DataModel.RecordField();
769 recordField.setLabel(recordData['fields'][i]['name']); 769 recordField.setLabel(recordData['fields'][i]['name']);
770 recordField.setValue(recordData['fields'][i]['value']); 770 recordField.setValue(recordData['fields'][i]['value']);
771 recordField.setType(recordData['fields'][i]['type']); 771 recordField.setType(recordData['fields'][i]['type']);
772 record.addField(recordField); 772 record.addField(recordField);
773 } 773 }
774 user.addRecord(record, true); 774 user.addRecord(record, true);
775 } 775 }
776 776
777 result = user; 777 result = user;
778 778
779 return result; 779 return result;
780 }, 780 },
781*/ 781*/
782 //========================================================================= 782 //=========================================================================
783 __syntaxFix__: "syntax fix" 783 __syntaxFix__: "syntax fix"
784}); 784});
785 785
786Clipperz.PM.Proxy.Offline.DataStore['exception'] = { 786Clipperz.PM.Proxy.Offline.DataStore['exception'] = {
787 'ReadOnly': new MochiKit.Base.NamedError("Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly") 787 'ReadOnly': new MochiKit.Base.NamedError("Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly")
788}; \ No newline at end of file 788}; \ No newline at end of file
diff --git a/frontend/gamma/js/Clipperz/PM/Proxy/Proxy.Test.js b/frontend/gamma/js/Clipperz/PM/Proxy/Proxy.Test.js
index d459726..1a860c5 100644
--- a/frontend/gamma/js/Clipperz/PM/Proxy/Proxy.Test.js
+++ b/frontend/gamma/js/Clipperz/PM/Proxy/Proxy.Test.js
@@ -1,156 +1,161 @@
1/* 1/*
2 2
3Copyright 2008-2013 Clipperz Srl 3Copyright 2008-2013 Clipperz Srl
4 4
5This file is part of Clipperz, the online password manager. 5This file is part of Clipperz, the online password manager.
6For further information about its features and functionalities please 6For further information about its features and functionalities please
7refer to http://www.clipperz.com. 7refer to http://www.clipperz.com.
8 8
9* Clipperz is free software: you can redistribute it and/or modify it 9* Clipperz is free software: you can redistribute it and/or modify it
10 under the terms of the GNU Affero General Public License as published 10 under the terms of the GNU Affero General Public License as published
11 by the Free Software Foundation, either version 3 of the License, or 11 by the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version. 12 (at your option) any later version.
13 13
14* Clipperz is distributed in the hope that it will be useful, but 14* Clipperz is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of 15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU Affero General Public License for more details. 17 See the GNU Affero General Public License for more details.
18 18
19* You should have received a copy of the GNU Affero General Public 19* You should have received a copy of the GNU Affero General Public
20 License along with Clipperz. If not, see http://www.gnu.org/licenses/. 20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
21 21
22*/ 22*/
23 23
24if (typeof(Clipperz) == 'undefined') { Clipperz = {}; } 24if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
25if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; } 25if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; }
26if (typeof(Clipperz.PM.Proxy) == 'undefined') { Clipperz.PM.Proxy = {}; } 26if (typeof(Clipperz.PM.Proxy) == 'undefined') { Clipperz.PM.Proxy = {}; }
27 27
28//============================================================================= 28//=============================================================================
29 29
30Clipperz.PM.Proxy.Test = function(args) { 30Clipperz.PM.Proxy.Test = function(args) {
31 Clipperz.PM.Proxy.Test.superclass.constructor.call(this, args); 31 Clipperz.PM.Proxy.Test.superclass.constructor.call(this, args);
32 32
33 args = args || {}; 33 args = args || {};
34 34
35 this._expectedRequests = (args.shouldCheckExpectedRequests === true) ? [] : null; 35 this._expectedRequests = (args.shouldCheckExpectedRequests === true) ? [] : null;
36 this._isExpectingRequests = true; 36 this._isExpectingRequests = true;
37 this._unexpectedRequests = []; 37 this._unexpectedRequests = [];
38 38
39 this.dataStore().resetData(); 39 this.dataStore().resetData();
40 40
41 return this; 41 return this;
42} 42}
43 43
44Clipperz.Base.extend(Clipperz.PM.Proxy.Test, Clipperz.PM.Proxy.Offline, { 44Clipperz.Base.extend(Clipperz.PM.Proxy.Test, Clipperz.PM.Proxy.Offline, {
45 45
46 'toString': function() { 46 'toString': function() {
47 return "Clipperz.PM.Proxy.Test"; 47 return "Clipperz.PM.Proxy.Test";
48 }, 48 },
49 49
50 //========================================================================= 50 //=========================================================================
51 51
52 'expectedRequests': function () { 52 'expectedRequests': function () {
53 return this._expectedRequests; 53 return this._expectedRequests;
54 }, 54 },
55 55
56 //------------------------------------------------------------------------- 56 //-------------------------------------------------------------------------
57 57
58 'shouldCheckExpectedRequests': function () { 58 'shouldCheckExpectedRequests': function () {
59 return (this._expectedRequests != null); 59 return (this._expectedRequests != null);
60 }, 60 },
61 61
62 'setShouldCheckExpectedRequests': function(aValue) { 62 'setShouldCheckExpectedRequests': function(aValue) {
63 if (aValue) { 63 if (aValue) {
64 this._expectedRequests = aValue; 64 this._expectedRequests = aValue;
65 } else { 65 } else {
66 this._expectedRequests = null; 66 this._expectedRequests = null;
67 } 67 }
68 }, 68 },
69 69
70 //------------------------------------------------------------------------- 70 //-------------------------------------------------------------------------
71 71
72 'shouldNotReceiveAnyFurtherRequest': function () { 72 'shouldNotReceiveAnyFurtherRequest': function () {
73 this._isExpectingRequests = false; 73 this._isExpectingRequests = false;
74 }, 74 },
75 75
76 'mayReceiveMoreRequests': function () { 76 'mayReceiveMoreRequests': function () {
77 this._isExpectingRequests = true; 77 this._isExpectingRequests = true;
78 this.resetUnexpectedRequests(); 78 this.resetUnexpectedRequests();
79 }, 79 },
80 80
81 'isExpectingRequests': function () { 81 'isExpectingRequests': function () {
82 return this._isExpectingRequests; 82 return this._isExpectingRequests;
83 }, 83 },
84 84
85 //------------------------------------------------------------------------- 85 //-------------------------------------------------------------------------
86 86
87 'unexpectedRequests': function () { 87 'unexpectedRequests': function () {
88 return this._unexpectedRequests; 88 return this._unexpectedRequests;
89 }, 89 },
90 90
91 'resetUnexpectedRequests': function () { 91 'resetUnexpectedRequests': function () {
92 this._unexpectedRequests = []; 92 this._unexpectedRequests = [];
93 }, 93 },
94 94
95 //------------------------------------------------------------------------- 95 //-------------------------------------------------------------------------
96 96
97 'testExpectedRequestParameters': function (aPath, anActualRequest, anExpectedRequest) { 97 'testExpectedRequestParameters': function (aPath, anActualRequest, anExpectedRequest) {
98 var aKey; 98 var aKey;
99 for (aKey in anExpectedRequest) { 99 for (aKey in anExpectedRequest) {
100 if (typeof(anActualRequest[aKey]) == 'undefined') { 100 if (typeof(anActualRequest[aKey]) == 'undefined') {
101 throw "the expected paramter [" + aKey + "] is missing from the actual request"; 101 throw "the expected paramter [" + aKey + "] is missing from the actual request";
102 } 102 }
103 if (typeof(anExpectedRequest[aKey]) == 'object') { 103 if (typeof(anExpectedRequest[aKey]) == 'object') {
104 this.testExpectedRequestParameters(aPath + "." + aKey, anActualRequest[aKey], anExpectedRequest[aKey]) 104 this.testExpectedRequestParameters(aPath + "." + aKey, anActualRequest[aKey], anExpectedRequest[aKey])
105 } else { 105 } else {
106 if (! anExpectedRequest[aKey](anActualRequest[aKey])) { 106 if (! anExpectedRequest[aKey](anActualRequest[aKey])) {
107 throw "wrong value for paramter [" + aKey + "]; got '" + anActualRequest[aKey] + "'"; 107 throw "wrong value for paramter [" + aKey + "]; got '" + anActualRequest[aKey] + "'";
108 } 108 }
109 } 109 }
110 } 110 }
111 }, 111 },
112 112
113 //------------------------------------------------------------------------- 113 //-------------------------------------------------------------------------
114 114
115 'checkRequest': function(aFunctionName, someParameters) { 115 'checkRequest': function(aFunctionName, someParameters) {
116 if (this.shouldCheckExpectedRequests()) { 116 if (this.shouldCheckExpectedRequests()) {
117 var expectedRequest; 117 var expectedRequest;
118 118
119 expectedRequest = this.expectedRequests().pop(); 119 expectedRequest = this.expectedRequests().pop();
120 if (expectedRequest == null) { 120 if (expectedRequest == null) {
121 throw "Proxy.Test.sentMessage: no expected result specified. Got request '" + aFunctionName + "': " + someParameters; 121 throw "Proxy.Test.sentMessage: no expected result specified. Got request '" + aFunctionName + "': " + someParameters;
122 } 122 }
123 123
124 try { 124 try {
125 if (aFunctionName != expectedRequest.functionName) { 125 if (aFunctionName != expectedRequest.functionName) {
126 throw "wrong function name. Got '" + aFunctionName + "', expected '" + expectedRequest.request.functionName + "'"; 126 throw "wrong function name. Got '" + aFunctionName + "', expected '" + expectedRequest.request.functionName + "'";
127 } 127 }
128 128
129 this.testExpectedRequestParameters("parameters", someParameters, expectedRequest.parameters); 129 this.testExpectedRequestParameters("parameters", someParameters, expectedRequest.parameters);
130 } catch(exception) { 130 } catch(exception) {
131 throw "Proxy.Test.sentMessage[" + expectedRequest.name + "]: " + exception; 131 throw "Proxy.Test.sentMessage[" + expectedRequest.name + "]: " + exception;
132 } 132 }
133 } 133 }
134 }, 134 },
135 135
136 //========================================================================= 136 //=========================================================================
137 137
138 'sendMessage': function(aFunctionName, someParameters) { 138 'sendMessage': function(aFunctionName, someParameters) {
139 var result; 139 var result;
140 140
141 if (this.isExpectingRequests() == false) { 141 if (this.isExpectingRequests() == false) {
142 // throw Clipperz.PM.Connection.exception.UnexpectedRequest; 142 // throw Clipperz.PM.Connection.exception.UnexpectedRequest;
143Clipperz.log("UNEXPECTED REQUEST " + aFunctionName /* + ": " + Clipperz.Base.serializeJSON(someParameters) */); 143Clipperz.log("UNEXPECTED REQUEST " + aFunctionName /* + ": " + Clipperz.Base.serializeJSON(someParameters) */);
144 this.unexpectedRequests().push({'functionName':aFunctionName, 'someParameters': someParameters}); 144 this.unexpectedRequests().push({'functionName':aFunctionName, 'someParameters': someParameters});
145 }; 145 };
146//if (aFunctionName == 'knock') {
147 //console.log(">>> send message - " + aFunctionName, someParameters);
148//} else {
149 //console.log(">>> SEND MESSAGE - " + aFunctionName + " [" + someParameters['parameters']['message'] + "]", someParameters['parameters']['parameters']);
150//}
146 this.checkRequest(aFunctionName, someParameters); 151 this.checkRequest(aFunctionName, someParameters);
147 result = Clipperz.PM.Proxy.Test.superclass.sendMessage.call(this, aFunctionName, someParameters); 152 result = Clipperz.PM.Proxy.Test.superclass.sendMessage.call(this, aFunctionName, someParameters);
148 153
149 return result; 154 return result;
150 }, 155 },
151 156
152 //========================================================================= 157 //=========================================================================
153 __syntaxFix__: "syntax fix" 158 __syntaxFix__: "syntax fix"
154 159
155}); 160});
156 161
diff --git a/frontend/gamma/properties/gamma.properties.json b/frontend/gamma/properties/gamma.properties.json
index d00e03a..1bc9e27 100644
--- a/frontend/gamma/properties/gamma.properties.json
+++ b/frontend/gamma/properties/gamma.properties.json
@@ -1,191 +1,192 @@
1{ 1{
2 "copyright.values": { 2 "copyright.values": {
3 "mochikit.repository":"https://github.com/mochi/mochikit.git", 3 "mochikit.repository":"https://github.com/mochi/mochikit.git",
4 "mochikit.version": "fe8d17bb9ac0a4e5ad4a8d5c2c94a6fac1c92d75" 4 "mochikit.version": "fe8d17bb9ac0a4e5ad4a8d5c2c94a6fac1c92d75"
5 }, 5 },
6 6
7 "html.template": "index_template.html", 7 "html.template": "index_template.html",
8 8
9 "js": [ 9 "js": [
10 "MochiKit/Base.js", 10 "MochiKit/Base.js",
11 "MochiKit/Iter.js", 11 "MochiKit/Iter.js",
12 "-- MochiKit/Logging.js", 12 "-- MochiKit/Logging.js",
13 "-- MochiKit/DateTime.js", 13 "-- MochiKit/DateTime.js",
14 "MochiKit/Format.js", 14 "MochiKit/Format.js",
15 "MochiKit/Async.js", 15 "MochiKit/Async.js",
16 "MochiKit/DOM.js", 16 "MochiKit/DOM.js",
17 "MochiKit/Style.js", 17 "MochiKit/Style.js",
18 "-- MochiKit/LoggingPane.js", 18 "-- MochiKit/LoggingPane.js",
19 "MochiKit/Color.js", 19 "MochiKit/Color.js",
20 "MochiKit/Signal.js", 20 "MochiKit/Signal.js",
21 "MochiKit/Position.js", 21 "MochiKit/Position.js",
22 "MochiKit/Selector.js", 22 "MochiKit/Selector.js",
23 "MochiKit/Visual.js", 23 "MochiKit/Visual.js",
24 24
25 "JSON/json2.js", 25 "JSON/json2.js",
26 26
27 "Clipperz/YUI/Utils.js", 27 "Clipperz/YUI/Utils.js",
28 "Clipperz/YUI/DomHelper.js", 28 "Clipperz/YUI/DomHelper.js",
29 29
30 "Clipperz/ByteArray.js", 30 "Clipperz/ByteArray.js",
31 "Clipperz/Base.js", 31 "Clipperz/Base.js",
32 "Clipperz/Async.js", 32 "Clipperz/Async.js",
33 "Clipperz/CSVProcessor.js", 33 "Clipperz/CSVProcessor.js",
34 "Clipperz/KeePassExportProcessor.js", 34 "Clipperz/KeePassExportProcessor.js",
35 "Clipperz/Date.js", 35 "Clipperz/Date.js",
36 "Clipperz/DOM.js", 36 "Clipperz/DOM.js",
37 "Clipperz/Logging.js", 37 "Clipperz/Logging.js",
38 "Clipperz/Signal.js", 38 "Clipperz/Signal.js",
39 "Clipperz/Style.js", 39 "Clipperz/Style.js",
40 "Clipperz/Visual.js", 40 "Clipperz/Visual.js",
41 "Clipperz/Set.js", 41 "Clipperz/Set.js",
42 "-- Clipperz/Profile.js", 42 "-- Clipperz/Profile.js",
43 "Clipperz/KeyValueObjectStore.js", 43 "Clipperz/KeyValueObjectStore.js",
44 44
45 "Clipperz/Crypto/SHA.js", 45 "Clipperz/Crypto/SHA.js",
46 "Clipperz/Crypto/AES.js", 46 "Clipperz/Crypto/AES.js",
47 "Clipperz/Crypto/AES_2.js",
47 "Clipperz/Crypto/PRNG.js", 48 "Clipperz/Crypto/PRNG.js",
48 "Clipperz/Crypto/BigInt.js", 49 "Clipperz/Crypto/BigInt.js",
49 "Clipperz/Crypto/Base.js", 50 "Clipperz/Crypto/Base.js",
50 "Clipperz/Crypto/SRP.js", 51 "Clipperz/Crypto/SRP.js",
51 "Clipperz/Crypto/RSA.js", 52 "Clipperz/Crypto/RSA.js",
52 53
53 "Clipperz/PM/Strings/Strings_defaults.js", 54 "Clipperz/PM/Strings/Strings_defaults.js",
54 "Clipperz/PM/Strings/Strings_en-US.js", 55 "Clipperz/PM/Strings/Strings_en-US.js",
55 "-- # Clipperz/PM/Strings/Strings_en-GB.js", 56 "-- # Clipperz/PM/Strings/Strings_en-GB.js",
56 "-- # Clipperz/PM/Strings/Strings_en-CA.js", 57 "-- # Clipperz/PM/Strings/Strings_en-CA.js",
57 "-- Clipperz/PM/Strings/Strings_it-IT.js", 58 "-- Clipperz/PM/Strings/Strings_it-IT.js",
58 "-- Clipperz/PM/Strings/Strings_pt-BR.js", 59 "-- Clipperz/PM/Strings/Strings_pt-BR.js",
59 "-- # Clipperz/PM/Strings/Strings_pt-PT.js", 60 "-- # Clipperz/PM/Strings/Strings_pt-PT.js",
60 "-- Clipperz/PM/Strings/Strings_ja-JP.js", 61 "-- Clipperz/PM/Strings/Strings_ja-JP.js",
61 "-- Clipperz/PM/Strings/Strings_zh-CN.js", 62 "-- Clipperz/PM/Strings/Strings_zh-CN.js",
62 "-- Clipperz/PM/Strings/Strings_es-ES.js", 63 "-- Clipperz/PM/Strings/Strings_es-ES.js",
63 "-- Clipperz/PM/Strings/Strings_fr-FR.js", 64 "-- Clipperz/PM/Strings/Strings_fr-FR.js",
64 "-- # Clipperz/PM/Strings/Strings_de-DE.js", 65 "-- # Clipperz/PM/Strings/Strings_de-DE.js",
65 "-- # Clipperz/PM/Strings/Strings_el-GR.js", 66 "-- # Clipperz/PM/Strings/Strings_el-GR.js",
66 "-- # Clipperz/PM/Strings/Strings_ru-RU.js", 67 "-- # Clipperz/PM/Strings/Strings_ru-RU.js",
67 "-- # Clipperz/PM/Strings/Strings_he-IL.js", 68 "-- # Clipperz/PM/Strings/Strings_he-IL.js",
68 "Clipperz/PM/Strings.js", 69 "Clipperz/PM/Strings.js",
69 "-- Clipperz/PM/Strings/MessagePanelConfigurations.js", 70 "-- Clipperz/PM/Strings/MessagePanelConfigurations.js",
70 71
71 "Clipperz/PM/Date.js", 72 "Clipperz/PM/Date.js",
72 73
73 "Clipperz/PM/Toll.js", 74 "Clipperz/PM/Toll.js",
74 "Clipperz/PM/Proxy.js", 75 "Clipperz/PM/Proxy.js",
75 "Clipperz/PM/Proxy/Proxy.JSON.js", 76 "Clipperz/PM/Proxy/Proxy.JSON.js",
76 "Clipperz/PM/Proxy/Proxy.Offline.js", 77 "Clipperz/PM/Proxy/Proxy.Offline.js",
77 "Clipperz/PM/Proxy/Proxy.Offline.DataStore.js", 78 "Clipperz/PM/Proxy/Proxy.Offline.DataStore.js",
78 "Clipperz/PM/Connection.js", 79 "Clipperz/PM/Connection.js",
79 "Clipperz/PM/Crypto.js", 80 "Clipperz/PM/Crypto.js",
80 "Clipperz/PM/BookmarkletProcessor.js", 81 "Clipperz/PM/BookmarkletProcessor.js",
81 82
82 "Clipperz/PM/DataModel/EncryptedRemoteObject.js", 83 "Clipperz/PM/DataModel/EncryptedRemoteObject.js",
83 "Clipperz/PM/DataModel/User.js", 84 "Clipperz/PM/DataModel/User.js",
84 "Clipperz/PM/DataModel/User.Header.Legacy.js", 85 "Clipperz/PM/DataModel/User.Header.Legacy.js",
85 "Clipperz/PM/DataModel/User.Header.RecordIndex.js", 86 "Clipperz/PM/DataModel/User.Header.RecordIndex.js",
86 "Clipperz/PM/DataModel/User.Header.Preferences.js", 87 "Clipperz/PM/DataModel/User.Header.Preferences.js",
87 "Clipperz/PM/DataModel/User.Header.OneTimePasswords.js", 88 "Clipperz/PM/DataModel/User.Header.OneTimePasswords.js",
88 "Clipperz/PM/DataModel/Record.js", 89 "Clipperz/PM/DataModel/Record.js",
89 "Clipperz/PM/DataModel/Record.Version.js", 90 "Clipperz/PM/DataModel/Record.Version.js",
90 "Clipperz/PM/DataModel/Record.Version.Field.js", 91 "Clipperz/PM/DataModel/Record.Version.Field.js",
91 "Clipperz/PM/DataModel/DirectLogin.js", 92 "Clipperz/PM/DataModel/DirectLogin.js",
92 "Clipperz/PM/DataModel/DirectLoginInput.js", 93 "Clipperz/PM/DataModel/DirectLoginInput.js",
93 "Clipperz/PM/DataModel/DirectLoginBinding.js", 94 "Clipperz/PM/DataModel/DirectLoginBinding.js",
94 "Clipperz/PM/DataModel/DirectLoginFormValue.js", 95 "Clipperz/PM/DataModel/DirectLoginFormValue.js",
95 "Clipperz/PM/DataModel/OneTimePassword.js", 96 "Clipperz/PM/DataModel/OneTimePassword.js",
96 97
97 "Clipperz/PM/UI/Canvas/Marks/exclamationMark.js", 98 "Clipperz/PM/UI/Canvas/Marks/exclamationMark.js",
98 "Clipperz/PM/UI/Canvas/Marks/questionMark.js", 99 "Clipperz/PM/UI/Canvas/Marks/questionMark.js",
99 "Clipperz/PM/UI/Canvas/Marks/info.js", 100 "Clipperz/PM/UI/Canvas/Marks/info.js",
100 101
101 "Clipperz/PM/UI/Canvas/Features/store.js", 102 "Clipperz/PM/UI/Canvas/Features/store.js",
102 "Clipperz/PM/UI/Canvas/Features/protect.js", 103 "Clipperz/PM/UI/Canvas/Features/protect.js",
103 "Clipperz/PM/UI/Canvas/Features/directLogin.js", 104 "Clipperz/PM/UI/Canvas/Features/directLogin.js",
104 "Clipperz/PM/UI/Canvas/Features/share.js", 105 "Clipperz/PM/UI/Canvas/Features/share.js",
105 106
106 "Clipperz/PM/UI/Canvas/Star/normal.js", 107 "Clipperz/PM/UI/Canvas/Star/normal.js",
107 108
108 "Clipperz/PM/UI/Canvas/CoverActions/look.js", 109 "Clipperz/PM/UI/Canvas/CoverActions/look.js",
109 "Clipperz/PM/UI/Canvas/CoverActions/download.js", 110 "Clipperz/PM/UI/Canvas/CoverActions/download.js",
110 111
111 "Clipperz/PM/UI/Canvas/Tips/open.js", 112 "Clipperz/PM/UI/Canvas/Tips/open.js",
112 "Clipperz/PM/UI/Canvas/Tips/close.js", 113 "Clipperz/PM/UI/Canvas/Tips/close.js",
113 114
114 "Clipperz/PM/UI/Canvas/RegisterButton/normal.js", 115 "Clipperz/PM/UI/Canvas/RegisterButton/normal.js",
115 116
116 "Clipperz/PM/UI/Canvas/Logo/normal.js", 117 "Clipperz/PM/UI/Canvas/Logo/normal.js",
117 118
118 "Clipperz/PM/UI/Canvas/GraphicFunctions.js", 119 "Clipperz/PM/UI/Canvas/GraphicFunctions.js",
119 120
120 "Clipperz/PM/UI/Common/Components/BaseComponent.js", 121 "Clipperz/PM/UI/Common/Components/BaseComponent.js",
121 "Clipperz/PM/UI/Common/Components/Button.js", 122 "Clipperz/PM/UI/Common/Components/Button.js",
122 "Clipperz/PM/UI/Common/Components/ComponentSlot.js", 123 "Clipperz/PM/UI/Common/Components/ComponentSlot.js",
123 "Clipperz/PM/UI/Common/Components/FaviconComponent.js", 124 "Clipperz/PM/UI/Common/Components/FaviconComponent.js",
124 "Clipperz/PM/UI/Common/Components/PasswordEntropyDisplay.js", 125 "Clipperz/PM/UI/Common/Components/PasswordEntropyDisplay.js",
125 "Clipperz/PM/UI/Common/Components/ProgressBar.js", 126 "Clipperz/PM/UI/Common/Components/ProgressBar.js",
126 "Clipperz/PM/UI/Common/Components/SimpleMessagePanel.js", 127 "Clipperz/PM/UI/Common/Components/SimpleMessagePanel.js",
127 "Clipperz/PM/UI/Common/Components/MessagePanelWithProgressBar.js", 128 "Clipperz/PM/UI/Common/Components/MessagePanelWithProgressBar.js",
128 "Clipperz/PM/UI/Common/Components/TabPanelComponent.js", 129 "Clipperz/PM/UI/Common/Components/TabPanelComponent.js",
129 "Clipperz/PM/UI/Common/Components/Tooltip.js", 130 "Clipperz/PM/UI/Common/Components/Tooltip.js",
130 "Clipperz/PM/UI/Common/Components/TranslatorWidget.js", 131 "Clipperz/PM/UI/Common/Components/TranslatorWidget.js",
131 132
132 "Clipperz/PM/UI/Common/Controllers/DirectLoginRunner.js", 133 "Clipperz/PM/UI/Common/Controllers/DirectLoginRunner.js",
133 "Clipperz/PM/UI/Common/Controllers/ProgressBarController.js", 134 "Clipperz/PM/UI/Common/Controllers/ProgressBarController.js",
134 "Clipperz/PM/UI/Common/Controllers/TabPanelController.js", 135 "Clipperz/PM/UI/Common/Controllers/TabPanelController.js",
135 "Clipperz/PM/UI/Common/Controllers/WizardController.js", 136 "Clipperz/PM/UI/Common/Controllers/WizardController.js",
136 137
137 "Clipperz/PM/UI/Web/Components/Page.js", 138 "Clipperz/PM/UI/Web/Components/Page.js",
138 "Clipperz/PM/UI/Web/Components/PageHeader.js", 139 "Clipperz/PM/UI/Web/Components/PageHeader.js",
139 "Clipperz/PM/UI/Web/Components/PageFooter.js", 140 "Clipperz/PM/UI/Web/Components/PageFooter.js",
140 "Clipperz/PM/UI/Web/Components/LoginPage.js", 141 "Clipperz/PM/UI/Web/Components/LoginPage.js",
141 "Clipperz/PM/UI/Web/Components/LoginForm.js", 142 "Clipperz/PM/UI/Web/Components/LoginForm.js",
142 "Clipperz/PM/UI/Web/Components/LoginProgress.js", 143 "Clipperz/PM/UI/Web/Components/LoginProgress.js",
143 "Clipperz/PM/UI/Web/Components/AppPage.js", 144 "Clipperz/PM/UI/Web/Components/AppPage.js",
144 "Clipperz/PM/UI/Web/Components/UserInfoBox.js", 145 "Clipperz/PM/UI/Web/Components/UserInfoBox.js",
145 "Clipperz/PM/UI/Web/Components/TabSidePanel.js", 146 "Clipperz/PM/UI/Web/Components/TabSidePanel.js",
146 "Clipperz/PM/UI/Web/Components/GridComponent.js", 147 "Clipperz/PM/UI/Web/Components/GridComponent.js",
147 148
148 "Clipperz/PM/UI/Web/Components/ColumnManager.js", 149 "Clipperz/PM/UI/Web/Components/ColumnManager.js",
149 "Clipperz/PM/UI/Web/Components/TextColumnManager.js", 150 "Clipperz/PM/UI/Web/Components/TextColumnManager.js",
150 "Clipperz/PM/UI/Web/Components/FaviconColumnManager.js", 151 "Clipperz/PM/UI/Web/Components/FaviconColumnManager.js",
151 "Clipperz/PM/UI/Web/Components/ImageColumnManager.js", 152 "Clipperz/PM/UI/Web/Components/ImageColumnManager.js",
152 "Clipperz/PM/UI/Web/Components/DateColumnManager.js", 153 "Clipperz/PM/UI/Web/Components/DateColumnManager.js",
153 "Clipperz/PM/UI/Web/Components/LinkColumnManager.js", 154 "Clipperz/PM/UI/Web/Components/LinkColumnManager.js",
154 "Clipperz/PM/UI/Web/Components/DirectLoginColumnManager.js", 155 "Clipperz/PM/UI/Web/Components/DirectLoginColumnManager.js",
155 "Clipperz/PM/UI/Web/Components/DirectLoginsColumnManager.js", 156 "Clipperz/PM/UI/Web/Components/DirectLoginsColumnManager.js",
156 "Clipperz/PM/UI/Web/Components/DeleteObjectColumnManager.js", 157 "Clipperz/PM/UI/Web/Components/DeleteObjectColumnManager.js",
157 "Clipperz/PM/UI/Web/Components/CreateNewCardSplashComponent.js", 158 "Clipperz/PM/UI/Web/Components/CreateNewCardSplashComponent.js",
158 159
159 "Clipperz/PM/UI/Web/Components/AccountPanel.js", 160 "Clipperz/PM/UI/Web/Components/AccountPanel.js",
160 "Clipperz/PM/UI/Web/Components/DataPanel.js", 161 "Clipperz/PM/UI/Web/Components/DataPanel.js",
161 "Clipperz/PM/UI/Web/Components/ToolsPanel.js", 162 "Clipperz/PM/UI/Web/Components/ToolsPanel.js",
162 "Clipperz/PM/UI/Web/Components/RulerComponent.js", 163 "Clipperz/PM/UI/Web/Components/RulerComponent.js",
163 "Clipperz/PM/UI/Web/Components/CardDialogComponent.js", 164 "Clipperz/PM/UI/Web/Components/CardDialogComponent.js",
164 "Clipperz/PM/UI/Web/Components/CardDialogRecordFieldComponent.js", 165 "Clipperz/PM/UI/Web/Components/CardDialogRecordFieldComponent.js",
165 "Clipperz/PM/UI/Web/Components/CardDialogRecordDirectLoginComponent.js", 166 "Clipperz/PM/UI/Web/Components/CardDialogRecordDirectLoginComponent.js",
166 "Clipperz/PM/UI/Web/Components/DirectLoginEditingComponent.js", 167 "Clipperz/PM/UI/Web/Components/DirectLoginEditingComponent.js",
167 "Clipperz/PM/UI/Web/Components/DirectLoginEditingBindingComponent.js", 168 "Clipperz/PM/UI/Web/Components/DirectLoginEditingBindingComponent.js",
168 "Clipperz/PM/UI/Web/Components/DirectLoginEditingFormValueComponent.js", 169 "Clipperz/PM/UI/Web/Components/DirectLoginEditingFormValueComponent.js",
169 "Clipperz/PM/UI/Web/Components/BookmarkletComponent.js", 170 "Clipperz/PM/UI/Web/Components/BookmarkletComponent.js",
170 "Clipperz/PM/UI/Web/Components/UnlockPasswordComponent.js", 171 "Clipperz/PM/UI/Web/Components/UnlockPasswordComponent.js",
171 "Clipperz/PM/UI/Web/Components/NewUserCreationComponent.js", 172 "Clipperz/PM/UI/Web/Components/NewUserCreationComponent.js",
172 "Clipperz/PM/UI/Web/Components/PasswordTooltip.js", 173 "Clipperz/PM/UI/Web/Components/PasswordTooltip.js",
173 174
174 "Clipperz/PM/UI/Web/Controllers/MainController.js", 175 "Clipperz/PM/UI/Web/Controllers/MainController.js",
175 "Clipperz/PM/UI/Web/Controllers/LoginController.js", 176 "Clipperz/PM/UI/Web/Controllers/LoginController.js",
176 "Clipperz/PM/UI/Web/Controllers/AppController.js", 177 "Clipperz/PM/UI/Web/Controllers/AppController.js",
177 "Clipperz/PM/UI/Web/Controllers/FilterController.js", 178 "Clipperz/PM/UI/Web/Controllers/FilterController.js",
178 "Clipperz/PM/UI/Web/Controllers/GridController.js", 179 "Clipperz/PM/UI/Web/Controllers/GridController.js",
179 "Clipperz/PM/UI/Web/Controllers/CardsController.js", 180 "Clipperz/PM/UI/Web/Controllers/CardsController.js",
180 "Clipperz/PM/UI/Web/Controllers/DirectLoginsController.js", 181 "Clipperz/PM/UI/Web/Controllers/DirectLoginsController.js",
181 "Clipperz/PM/UI/Web/Controllers/CardDialogController.js", 182 "Clipperz/PM/UI/Web/Controllers/CardDialogController.js",
182 "Clipperz/PM/UI/Web/Controllers/DirectLoginWizardController.js", 183 "Clipperz/PM/UI/Web/Controllers/DirectLoginWizardController.js",
183 "Clipperz/PM/UI/Web/Controllers/NewUserWizardController.js", 184 "Clipperz/PM/UI/Web/Controllers/NewUserWizardController.js",
184 185
185 "main.js" 186 "main.js"
186 ], 187 ],
187 188
188 "css": [ 189 "css": [
189 "web.css" 190 "web.css"
190 ] 191 ]
191} 192}
diff --git a/frontend/gamma/properties/mobile.properties.json b/frontend/gamma/properties/mobile.properties.json
index 0127ce6..2b3b49d 100644
--- a/frontend/gamma/properties/mobile.properties.json
+++ b/frontend/gamma/properties/mobile.properties.json
@@ -1,156 +1,165 @@
1{ 1{
2 "copyright.values": { 2 "copyright.values": {
3 "mochikit.repository": "https://github.com/mochi/mochikit.git", 3 "mochikit.repository": "https://github.com/mochi/mochikit.git",
4 "mochikit.version": "fe8d17bb9ac0a4e5ad4a8d5c2c94a6fac1c92d75" 4 "mochikit.version": "fe8d17bb9ac0a4e5ad4a8d5c2c94a6fac1c92d75"
5 }, 5 },
6 6
7 "html.template": "mobile_template.html", 7 "html.template": "mobile_template.html",
8 8
9 "js": [ 9 "js": [
10 "MochiKit/Base.js", 10 "MochiKit/Base.js",
11 "MochiKit/Iter.js", 11 "MochiKit/Iter.js",
12 "MochiKit/Logging.js", 12 "-- MochiKit/Logging.js",
13 "MochiKit/DateTime.js", 13 "MochiKit/DateTime.js",
14 "MochiKit/Format.js", 14 "MochiKit/Format.js",
15 "MochiKit/Async.js", 15 "MochiKit/Async.js",
16 "MochiKit/DOM.js", 16 "MochiKit/DOM.js",
17 "MochiKit/Style.js", 17 "MochiKit/Style.js",
18 "MochiKit/LoggingPane.js", 18 "-- MochiKit/LoggingPane.js",
19 "-- MochiKit/Color.js", 19 "-- MochiKit/Color.js",
20 "MochiKit/Signal.js", 20 "MochiKit/Signal.js",
21 "-- MochiKit/Position.js", 21 "-- MochiKit/Position.js",
22 "MochiKit/Selector.js", 22 "MochiKit/Selector.js",
23 "-- MochiKit/Visual.js", 23 "-- MochiKit/Visual.js",
24 24
25 "JSON/json2.js", 25 "-- JSON/json2.js",
26 26
27 "Clipperz/YUI/Utils.js", 27 "Clipperz/YUI/Utils.js",
28 "Clipperz/YUI/DomHelper.js", 28 "Clipperz/YUI/DomHelper.js",
29 29
30 "Clipperz/ByteArray.js", 30 "Clipperz/ByteArray.js",
31 "Clipperz/Base.js", 31 "Clipperz/Base.js",
32 "Clipperz/Async.js", 32 "Clipperz/Async.js",
33 "-- Clipperz/CSVProcessor.js", 33 "-- Clipperz/CSVProcessor.js",
34 "-- Clipperz/KeePassExportProcessor.js", 34 "-- Clipperz/KeePassExportProcessor.js",
35 "Clipperz/Date.js", 35 "Clipperz/Date.js",
36 "Clipperz/DOM.js", 36 "Clipperz/DOM.js",
37 "Clipperz/Logging.js", 37 "Clipperz/Logging.js",
38 "Clipperz/Signal.js", 38 "Clipperz/Signal.js",
39 "-- Clipperz/Style.js", 39 "-- Clipperz/Style.js",
40 "-- Clipperz/Visual.js", 40 "-- Clipperz/Visual.js",
41 "Clipperz/Set.js", 41 "Clipperz/Set.js",
42 "Clipperz/KeyValueObjectStore.js", 42 "Clipperz/KeyValueObjectStore.js",
43 43
44 "Clipperz/Crypto/SHA.js", 44 "Clipperz/Crypto/SHA.js",
45 "Clipperz/Crypto/AES.js", 45 "Clipperz/Crypto/AES.js",
46 "Clipperz/Crypto/AES_2.js",
46 "Clipperz/Crypto/PRNG.js", 47 "Clipperz/Crypto/PRNG.js",
47 "Clipperz/Crypto/BigInt.js", 48 "Clipperz/Crypto/BigInt.js",
48 "Clipperz/Crypto/Base.js", 49 "Clipperz/Crypto/Base.js",
49 "Clipperz/Crypto/SRP.js", 50 "Clipperz/Crypto/SRP.js",
50 "Clipperz/Crypto/RSA.js", 51 "Clipperz/Crypto/RSA.js",
51 52
52 "Clipperz/PM/Strings/Strings_defaults.js", 53 "Clipperz/PM/Strings/Strings_defaults.js",
53 "Clipperz/PM/Strings/Strings_en-US.js", 54 "Clipperz/PM/Strings/Strings_en-US.js",
54 "-- # Clipperz/PM/Strings/Strings_en-GB.js", 55 "-- # Clipperz/PM/Strings/Strings_en-GB.js",
55 "-- # Clipperz/PM/Strings/Strings_en-CA.js", 56 "-- # Clipperz/PM/Strings/Strings_en-CA.js",
56 "-- Clipperz/PM/Strings/Strings_it-IT.js", 57 "-- Clipperz/PM/Strings/Strings_it-IT.js",
57 "-- Clipperz/PM/Strings/Strings_pt-BR.js", 58 "-- Clipperz/PM/Strings/Strings_pt-BR.js",
58 "-- # Clipperz/PM/Strings/Strings_pt-PT.js", 59 "-- # Clipperz/PM/Strings/Strings_pt-PT.js",
59 "-- Clipperz/PM/Strings/Strings_ja-JP.js", 60 "-- Clipperz/PM/Strings/Strings_ja-JP.js",
60 "-- Clipperz/PM/Strings/Strings_zh-CN.js", 61 "-- Clipperz/PM/Strings/Strings_zh-CN.js",
61 "-- Clipperz/PM/Strings/Strings_es-ES.js", 62 "-- Clipperz/PM/Strings/Strings_es-ES.js",
62 "-- Clipperz/PM/Strings/Strings_fr-FR.js", 63 "-- Clipperz/PM/Strings/Strings_fr-FR.js",
63 "-- # Clipperz/PM/Strings/Strings_de-DE.js", 64 "-- # Clipperz/PM/Strings/Strings_de-DE.js",
64 "-- # Clipperz/PM/Strings/Strings_el-GR.js", 65 "-- # Clipperz/PM/Strings/Strings_el-GR.js",
65 "-- # Clipperz/PM/Strings/Strings_ru-RU.js", 66 "-- # Clipperz/PM/Strings/Strings_ru-RU.js",
66 "-- # Clipperz/PM/Strings/Strings_he-IL.js", 67 "-- # Clipperz/PM/Strings/Strings_he-IL.js",
67 "Clipperz/PM/Strings.js", 68 "Clipperz/PM/Strings.js",
68 "-- Clipperz/PM/Strings/MessagePanelConfigurations.js", 69 "-- Clipperz/PM/Strings/MessagePanelConfigurations.js",
69 70
70 "Clipperz/PM/Date.js", 71 "Clipperz/PM/Date.js",
71 72
72 "Clipperz/PM/Toll.js", 73 "Clipperz/PM/Toll.js",
73 "Clipperz/PM/Proxy.js", 74 "Clipperz/PM/Proxy.js",
74 "Clipperz/PM/Proxy/Proxy.JSON.js", 75 "Clipperz/PM/Proxy/Proxy.JSON.js",
75 "-- Clipperz/PM/Proxy/Proxy.OfflineCache.js", 76 "-- Clipperz/PM/Proxy/Proxy.OfflineCache.js",
76 "Clipperz/PM/Proxy/Proxy.Offline.js", 77 "Clipperz/PM/Proxy/Proxy.Offline.js",
77 "Clipperz/PM/Proxy/Proxy.Offline.DataStore.js", 78 "Clipperz/PM/Proxy/Proxy.Offline.DataStore.js",
78 79
79 "Clipperz/PM/Connection.js", 80 "Clipperz/PM/Connection.js",
80 "Clipperz/PM/Crypto.js", 81 "Clipperz/PM/Crypto.js",
81 "Clipperz/PM/PIN.js", 82 "Clipperz/PM/PIN.js",
82 83
83 "Clipperz/PM/DataModel/EncryptedRemoteObject.js", 84 "Clipperz/PM/DataModel/EncryptedRemoteObject.js",
84 "Clipperz/PM/DataModel/User.js", 85 "Clipperz/PM/DataModel/User.js",
85 "Clipperz/PM/DataModel/User.Header.Legacy.js", 86 "Clipperz/PM/DataModel/User.Header.Legacy.js",
86 "Clipperz/PM/DataModel/User.Header.RecordIndex.js", 87 "Clipperz/PM/DataModel/User.Header.RecordIndex.js",
87 "Clipperz/PM/DataModel/User.Header.Preferences.js", 88 "Clipperz/PM/DataModel/User.Header.Preferences.js",
88 "Clipperz/PM/DataModel/User.Header.OneTimePasswords.js", 89 "Clipperz/PM/DataModel/User.Header.OneTimePasswords.js",
89 "Clipperz/PM/DataModel/Record.js", 90 "Clipperz/PM/DataModel/Record.js",
90 "Clipperz/PM/DataModel/Record.Version.js", 91 "Clipperz/PM/DataModel/Record.Version.js",
91 "Clipperz/PM/DataModel/Record.Version.Field.js", 92 "Clipperz/PM/DataModel/Record.Version.Field.js",
92 "Clipperz/PM/DataModel/DirectLogin.js", 93 "Clipperz/PM/DataModel/DirectLogin.js",
93 "Clipperz/PM/DataModel/DirectLoginInput.js", 94 "Clipperz/PM/DataModel/DirectLoginInput.js",
94 "Clipperz/PM/DataModel/DirectLoginBinding.js", 95 "Clipperz/PM/DataModel/DirectLoginBinding.js",
95 "Clipperz/PM/DataModel/DirectLoginFormValue.js", 96 "Clipperz/PM/DataModel/DirectLoginFormValue.js",
96 "Clipperz/PM/DataModel/OneTimePassword.js", 97 "Clipperz/PM/DataModel/OneTimePassword.js",
97 98
99 "JQuery/1.9.1/jquery.js",
100 "Clipperz/PM/UI/Mobile/CustomizeJQueryMobile.js",
101 "JQuery/Mobile/1.3.0-rc.1/jquery.mobile.js",
102
98 "-- Zepto/zepto.js", 103 "-- Zepto/zepto.js",
99 "-- Zepto/ajax.js", 104 "-- Zepto/ajax.js",
100 "-- Zepto/assets.js", 105 "-- Zepto/assets.js",
101 "-- Zepto/data.js", 106 "-- Zepto/data.js",
102 "-- Zepto/detect.js", 107 "-- Zepto/detect.js",
103 "-- Zepto/event.js", 108 "-- Zepto/event.js",
104 "-- Zepto/form.js", 109 "-- Zepto/form.js",
105 "-- Zepto/fx.js", 110 "-- Zepto/fx.js",
106 "-- Zepto/fx_methods.js", 111 "-- Zepto/fx_methods.js",
107 "-- Zepto/gesture.js", 112 "-- Zepto/gesture.js",
108 "-- Zepto/polyfill.js", 113 "-- Zepto/polyfill.js",
109 "-- Zepto/selector.js", 114 "-- Zepto/selector.js",
110 "-- Zepto/stack.js", 115 "-- Zepto/stack.js",
111 "-- Zepto/touch.js", 116 "-- Zepto/touch.js",
112 117
113 "-- JQTouch/jqtouch.js", 118 "-- JQTouch/jqtouch.js",
114 119
115 "-- Bootstrap/bootstrap-affix.js", 120 "-- Bootstrap/bootstrap-affix.js",
116 "-- Bootstrap/bootstrap-alert.js", 121 "-- Bootstrap/bootstrap-alert.js",
117 "-- Bootstrap/bootstrap-button.js", 122 "-- Bootstrap/bootstrap-button.js",
118 "-- Bootstrap/bootstrap-carousel.js", 123 "-- Bootstrap/bootstrap-carousel.js",
119 "-- Bootstrap/bootstrap-collapse.js", 124 "-- Bootstrap/bootstrap-collapse.js",
120 "-- Bootstrap/bootstrap-dropdown.js", 125 "-- Bootstrap/bootstrap-dropdown.js",
121 "-- Bootstrap/bootstrap-modal.js", 126 "-- Bootstrap/bootstrap-modal.js",
122 "-- Bootstrap/bootstrap-popover.js", 127 "-- Bootstrap/bootstrap-popover.js",
123 "-- Bootstrap/bootstrap-scrollspy.js", 128 "-- Bootstrap/bootstrap-scrollspy.js",
124 "-- Bootstrap/bootstrap-tab.js", 129 "-- Bootstrap/bootstrap-tab.js",
125 "-- Bootstrap/bootstrap-tooltip.js", 130 "-- Bootstrap/bootstrap-tooltip.js",
126 "-- Bootstrap/bootstrap-transition.js", 131 "-- Bootstrap/bootstrap-transition.js",
127 "-- Bootstrap/bootstrap-typeahead.js", 132 "-- Bootstrap/bootstrap-typeahead.js",
128 133
129 "Clipperz/PM/UI/Common/Components/BaseComponent.js", 134 "-- Clipperz/PM/UI/Common/Components/BaseComponent.js",
130 "-- Clipperz/PM/UI/Common/Components/Button.js", 135 "-- Clipperz/PM/UI/Common/Components/Button.js",
131 "Clipperz/PM/UI/Common/Components/ComponentSlot.js", 136 "-- Clipperz/PM/UI/Common/Components/ComponentSlot.js",
132 "-- Clipperz/PM/UI/Common/Components/PasswordEntropyDisplay.js", 137 "-- Clipperz/PM/UI/Common/Components/PasswordEntropyDisplay.js",
133 "Clipperz/PM/UI/Common/Components/ProgressBar.js", 138 "-- Clipperz/PM/UI/Common/Components/ProgressBar.js",
134 "-- Clipperz/PM/UI/Common/Components/SimpleMessagePanel.js", 139 "-- Clipperz/PM/UI/Common/Components/SimpleMessagePanel.js",
135 "-- Clipperz/PM/UI/Common/Components/MessagePanelWithProgressBar.js", 140 "-- Clipperz/PM/UI/Common/Components/MessagePanelWithProgressBar.js",
136 "-- Clipperz/PM/UI/Common/Components/TabPanelComponent.js", 141 "-- Clipperz/PM/UI/Common/Components/TabPanelComponent.js",
137 "-- Clipperz/PM/UI/Common/Components/Tooltip.js", 142 "-- Clipperz/PM/UI/Common/Components/Tooltip.js",
138 "-- Clipperz/PM/UI/Common/Components/TranslatorWidget.js", 143 "-- Clipperz/PM/UI/Common/Components/TranslatorWidget.js",
139 144
140 "Clipperz/PM/UI/Common/Controllers/DirectLoginRunner.js", 145 "-- Clipperz/PM/UI/Common/Controllers/DirectLoginRunner.js",
141 "Clipperz/PM/UI/Common/Controllers/ProgressBarController.js", 146 "-- Clipperz/PM/UI/Common/Controllers/ProgressBarController.js",
142 "-- Clipperz/PM/UI/Common/Controllers/TabPanelController.js", 147 "-- Clipperz/PM/UI/Common/Controllers/TabPanelController.js",
143 148
149 "Clipperz/PM/UI/Mobile/Components/BaseComponent.js",
150 "Clipperz/PM/UI/Mobile/Components/Overlay.js",
144 "Clipperz/PM/UI/Mobile/Components/LoginForm.js", 151 "Clipperz/PM/UI/Mobile/Components/LoginForm.js",
145 "Clipperz/PM/UI/Mobile/Components/CardList.js", 152 "Clipperz/PM/UI/Mobile/Components/CardList.js",
153 "Clipperz/PM/UI/Mobile/Components/Preferences.js",
146 "-- Clipperz/PM/UI/Mobile/Components/CardDetail.js", 154 "-- Clipperz/PM/UI/Mobile/Components/CardDetail.js",
147 155
148 "Clipperz/PM/UI/Mobile/Controllers/MainController.js", 156 "Clipperz/PM/UI/Mobile/Controllers/MainController.js",
149 157
150 "main.mobile.js" 158 "main.mobile.js"
151 ], 159 ],
152 160
153 "css": [ 161 "css": [
162 "jquery.mobile-1.3.0-rc.1.css",
154 "mobile.css" 163 "mobile.css"
155 ] 164 ]
156} \ No newline at end of file 165} \ No newline at end of file
diff --git a/frontend/gamma/tests/tests/Clipperz/Crypto/AES_2.html b/frontend/gamma/tests/tests/Clipperz/Crypto/AES_2.html
new file mode 100644
index 0000000..8f922fb
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/Crypto/AES_2.html
@@ -0,0 +1,57 @@
1<!--
2
3Copyright 2008-2013 Clipperz Srl
4
5This file is part of Clipperz, the online password manager.
6For further information about its features and functionalities please
7refer to http://www.clipperz.com.
8
9* Clipperz is free software: you can redistribute it and/or modify it
10 under the terms of the GNU Affero General Public License as published
11 by the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14* Clipperz is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU Affero General Public License for more details.
18
19* You should have received a copy of the GNU Affero General Public
20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
21
22-->
23
24<html>
25<head>
26 <title>Clipperz.Crypto.AES_2 - tests</title>
27
28 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
29
30 <script type="text/javascript" src="../../../../js/MochiKit/MochiKit.js"></script>
31 <script type="text/javascript" src="../../../SimpleTest/SimpleTest.js"></script>
32 <link rel="stylesheet" type="text/css" href="../../../SimpleTest/test.css">
33
34 <script type='text/javascript' src='../../../../js/JSON/json2.js'></script>
35
36 <script type='text/javascript' src='../../../../js/Clipperz/YUI/Utils.js'></script>
37 <script type='text/javascript' src='../../../../js/Clipperz/YUI/DomHelper.js'></script>
38 <script type='text/javascript' src='../../../../js/Clipperz/Base.js'></script>
39 <script type='text/javascript' src='../../../../js/Clipperz/ByteArray.js'></script>
40 <script type='text/javascript' src='../../../../js/Clipperz/Async.js'></script>
41 <script type='text/javascript' src='../../../../js/Clipperz/Logging.js'></script>
42 <script type='text/javascript' src='../../../../js/Clipperz/Crypto/Base.js'></script>
43 <script type='text/javascript' src='../../../../js/Clipperz/Crypto/BigInt.js'></script>
44 <script type='text/javascript' src='../../../../js/Clipperz/Crypto/AES.js'></script>
45 <script type='text/javascript' src='../../../../js/Clipperz/Crypto/AES_2.js'></script>
46 <script type='text/javascript' src='../../../../js/Clipperz/Crypto/SHA.js'></script>
47 <script type='text/javascript' src='../../../../js/Clipperz/Crypto/PRNG.js'></script>
48
49 <script type="text/javascript" src="../../../SimpleTest/SimpleTest.Async.js"></script>
50
51</head>
52<body>
53<pre id="test">
54<script type="text/javascript" src="AES_2.test.js"></script>
55</pre>
56</body>
57</html>
diff --git a/frontend/gamma/tests/tests/Clipperz/Crypto/AES_2.test.js b/frontend/gamma/tests/tests/Clipperz/Crypto/AES_2.test.js
new file mode 100644
index 0000000..f753747
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/Crypto/AES_2.test.js
@@ -0,0 +1,85 @@
1/*
2
3Copyright 2008-2013 Clipperz Srl
4
5This file is part of Clipperz, the online password manager.
6For further information about its features and functionalities please
7refer to http://www.clipperz.com.
8
9* Clipperz is free software: you can redistribute it and/or modify it
10 under the terms of the GNU Affero General Public License as published
11 by the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14* Clipperz is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU Affero General Public License for more details.
18
19* You should have received a copy of the GNU Affero General Public
20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
21
22*/
23
24function testEncryptedData (tool, keyValue, encryptedText, expectedCleanText, someTestArgs) {
25 key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(keyValue));
26 value = new Clipperz.ByteArray().appendBase64String(encryptedText);
27
28 deferredResult = new Clipperz.Async.Deferred("pythonCompatibility_test", someTestArgs);
29 deferredResult.addCallback(Clipperz.Crypto.AES_2.deferredDecrypt, key, value);
30 deferredResult.addCallback(function(aResult) {
31 return aResult.asString();
32 });
33 deferredResult.addTest(expectedCleanText, tool);
34 deferredResult.callback();
35
36 return deferredResult;
37}
38
39//=============================================================================
40
41var tests = {
42
43 'incrementNonce_test': function (someTestArgs) {
44 var nonce;
45
46 nonce = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
47 Clipperz.Crypto.AES_2.incrementNonce(nonce)
48 SimpleTest.eq(nonce, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], "increment 0 based nonce");
49
50 nonce = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
51 Clipperz.Crypto.AES_2.incrementNonce(nonce)
52 SimpleTest.eq(nonce, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2], "increment '1' nonce");
53
54 nonce = [58,231,19,199,48,86,154,169,188,141,46,196,83,34,37,89]
55 Clipperz.Crypto.AES_2.incrementNonce(nonce)
56 SimpleTest.eq(nonce, [58,231,19,199,48,86,154,169,188,141,46,196,83,34,37,90], "increment '1' nonce");
57 return
58 },
59
60 'pythonCompatibility_test': function (someTestArgs) {
61 var keyValue = "clipperz"
62 var cleanText = "Lorem īpsum dōlōr siÞ ǽmēt, stet voluptatum ei eum, quō pērfecto lobortis eā, vel ċu deserūisse comprehēƿsam. Eu sed cībō veniam effīciendi, Þe legere ðominġ est, ðuō ċu saperet inermis pērfeċto. Vim ei essent consetētūr, quo etīam saepē æpeirian in, et atqūi velīÞ sǣepe his? Æn porrō putanÞ sinġulis mei, ēx sonet noster mea, tē alterum praesent percipitur qūo. ViÞaē neċessitatibus ne vim, per ex communē sentēntiǣe! Qui stet ǽdhūċ uÞ."
63
64 // def testEncrypt (keyValue, cleanText):
65 // key = keyDerivation(keyValue)
66 // iv = random.getrandbits(128)
67 // ctr = Crypto.Util.Counter.new(128, initial_value=iv)
68 // cipher = AES.new(key, Crypto.Cipher.AES.MODE_CTR, counter=ctr)
69 // encryptedValue = cipher.encrypt(cleanText.encode('utf-8'))
70 // data = base64.b64encode(base64.b16decode(hex(iv).upper()[2:-1]) + encryptedValue)
71 //
72 // return data
73
74 var pythonEncryptedData = "9AFIXRO2nY0mkLJI6Xd4bd+Ov1g+kYUh73nICEVUM8OGt5FnfV/w2BfmTvdMGZjs+rF8w0ksrS9Ny8j2+2zPUUrKnVRXO6eGVPSN5VfuYFSHucV98msINH0FpOZHftuKCuJkB/orjQhoIbj9SXT0yUwB3b4R2bk48Br7R8G2bhxqrHRmnYQn22AQVA83UstNvCOdXT7ArfwJZbVSSMkdmvcziZ8ObMvaH+FXD/K8i7dzS1yP03MMBtIkYN8PnyUMS2uAHKiR11jGuha9QfXjLJlWUQWZgNB9NKyOKf7tN+OgtAoWmHmKlpTshfwbfFD8wBPR0kkhR0cC+7queIjpCDnBJ+Nod78zWgPDR8g64sph7OB686HkP03cO66aH/LNuAt03gxaVyE8ufvoStRjlIthOuys5xYWP+hTFYDC7OhCOLKvhZoY4Tr/FP+TjporX3ivCJUEEvwvXeftAxFVRl4JDin0ys0iPTQ7QlbtVa+iep2n9FUG1NOn5boD9y+iw64UJAcex4MqEIdpCHne9LjpiqshcwLmfEeLlFab28LHnvYPGkXDrSRjCujx8ZmmTw96sAIDqER8p1AqaSojwvONYBGrq+f5/f4xjzZJAknMmxYEN14Phbxc8WEhpe5omWdB80C1Kv6CLsoQnGAIshURSZryToXL"
75 return testEncryptedData("python", keyValue, pythonEncryptedData, cleanText, someTestArgs)
76 },
77
78 //-------------------------------------------------------------------------
79 'syntaxFix': MochiKit.Base.noop
80}
81
82//=============================================================================
83
84Clipperz.Crypto.PRNG.defaultRandomGenerator().fastEntropyAccumulationForTestingPurpose();
85SimpleTest.runDeferredTests("Clipperz.Crypto.AES_2", tests, {trace:false});
diff --git a/frontend/gamma/tests/tests/Clipperz/Crypto/index.html b/frontend/gamma/tests/tests/Clipperz/Crypto/index.html
index 5ee8b8c..0679739 100644
--- a/frontend/gamma/tests/tests/Clipperz/Crypto/index.html
+++ b/frontend/gamma/tests/tests/Clipperz/Crypto/index.html
@@ -1,53 +1,54 @@
1<!-- 1<!--
2 2
3Copyright 2008-2013 Clipperz Srl 3Copyright 2008-2013 Clipperz Srl
4 4
5This file is part of Clipperz, the online password manager. 5This file is part of Clipperz, the online password manager.
6For further information about its features and functionalities please 6For further information about its features and functionalities please
7refer to http://www.clipperz.com. 7refer to http://www.clipperz.com.
8 8
9* Clipperz is free software: you can redistribute it and/or modify it 9* Clipperz is free software: you can redistribute it and/or modify it
10 under the terms of the GNU Affero General Public License as published 10 under the terms of the GNU Affero General Public License as published
11 by the Free Software Foundation, either version 3 of the License, or 11 by the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version. 12 (at your option) any later version.
13 13
14* Clipperz is distributed in the hope that it will be useful, but 14* Clipperz is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of 15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU Affero General Public License for more details. 17 See the GNU Affero General Public License for more details.
18 18
19* You should have received a copy of the GNU Affero General Public 19* You should have received a copy of the GNU Affero General Public
20 License along with Clipperz. If not, see http://www.gnu.org/licenses/. 20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
21 21
22--> 22-->
23 23
24<html> 24<html>
25<head> 25<head>
26 <title>Clipperz.Crypto.* - tests</title> 26 <title>Clipperz.Crypto.* - tests</title>
27 27
28 <script type="text/javascript" src="../../../../js/MochiKit/MochiKit.js"></script> 28 <script type="text/javascript" src="../../../../js/MochiKit/MochiKit.js"></script>
29 <script type="text/javascript" src="../../../SimpleTest/TestRunner.js"></script> 29 <script type="text/javascript" src="../../../SimpleTest/TestRunner.js"></script>
30</head> 30</head>
31<body> 31<body>
32<script> 32<script>
33TestRunner.runTests( 33TestRunner.runTests(
34 'AES.html', 34 'AES.html',
35 //'AES_2.html',
35 'AES.performance.html', 36 'AES.performance.html',
36 'Base.html', 37 'Base.html',
37 'BigInt.html', 38 'BigInt.html',
38 39
39 //'ECC.B283.deferred.html', 40 //'ECC.B283.deferred.html',
40 //'ECC.BinaryField.FiniteField.html', 41 //'ECC.BinaryField.FiniteField.html',
41 //'ECC.BinaryField.FiniteField.B283.html', 42 //'ECC.BinaryField.FiniteField.B283.html',
42 //'ECC.BinaryField.Value.html', 43 //'ECC.BinaryField.Value.html',
43 //#'ECC.K283.deferred.html', 44 //#'ECC.K283.deferred.html',
44 45
45 'PRNG.html', 46 'PRNG.html',
46 //'RSA.html', 47 //'RSA.html',
47 'SHA.html', 48 'SHA.html',
48 'SRP.html', 49 'SRP.html',
49 'Usage.html' 50 'Usage.html'
50); 51);
51</script> 52</script>
52</body> 53</body>
53</html> \ No newline at end of file 54</html> \ No newline at end of file
diff --git a/frontend/gamma/tests/tests/Clipperz/PM/Crypto_v0_4.html b/frontend/gamma/tests/tests/Clipperz/PM/Crypto_v0_4.html
new file mode 100644
index 0000000..1ed863a
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/PM/Crypto_v0_4.html
@@ -0,0 +1,60 @@
1<!--
2
3Copyright 2008-2013 Clipperz Srl
4
5This file is part of Clipperz, the online password manager.
6For further information about its features and functionalities please
7refer to http://www.clipperz.com.
8
9* Clipperz is free software: you can redistribute it and/or modify it
10 under the terms of the GNU Affero General Public License as published
11 by the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14* Clipperz is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU Affero General Public License for more details.
18
19* You should have received a copy of the GNU Affero General Public
20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
21
22-->
23
24<html>
25<head>
26 <title>Clipperz.PM.Crypto [0.4] - tests</title>
27
28 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
29
30 <script type="text/javascript" src="../../../../js/MochiKit/MochiKit.js"></script>
31 <script type="text/javascript" src="../../../SimpleTest/SimpleTest.js"></script>
32 <link rel="stylesheet" type="text/css" href="../../../SimpleTest/test.css">
33
34 <script type='text/javascript' src='../../../../js/JSON/json2.js'></script>
35
36 <script type='text/javascript' src='../../../../js/Clipperz/YUI/Utils.js'></script>
37 <script type='text/javascript' src='../../../../js/Clipperz/YUI/DomHelper.js'></script>
38 <script type='text/javascript' src='../../../../js/Clipperz/Base.js'></script>
39 <script type='text/javascript' src='../../../../js/Clipperz/ByteArray.js'></script>
40 <script type='text/javascript' src='../../../../js/Clipperz/Async.js'></script>
41 <script type='text/javascript' src='../../../../js/Clipperz/Logging.js'></script>
42 <script type='text/javascript' src='../../../../js/Clipperz/Crypto/Base.js'></script>
43 <script type='text/javascript' src='../../../../js/Clipperz/Crypto/BigInt.js'></script>
44 <script type='text/javascript' src='../../../../js/Clipperz/Crypto/AES.js'></script>
45 <script type='text/javascript' src='../../../../js/Clipperz/Crypto/AES_2.js'></script>
46 <script type='text/javascript' src='../../../../js/Clipperz/Crypto/SHA.js'></script>
47 <script type='text/javascript' src='../../../../js/Clipperz/Crypto/PRNG.js'></script>
48 <script type='text/javascript' src='../../../../js/Clipperz/PM/Proxy.js'></script>
49 <script type='text/javascript' src='../../../../js/Clipperz/PM/Connection.js'></script>
50 <script type='text/javascript' src='../../../../js/Clipperz/PM/Crypto.js'></script>
51
52 <script type="text/javascript" src="../../../SimpleTest/SimpleTest.Async.js"></script>
53
54</head>
55<body>
56<pre id="test">
57<script type="text/javascript" src="Crypto_v0_4.test.js"></script>
58</pre>
59</body>
60</html>
diff --git a/frontend/gamma/tests/tests/Clipperz/PM/Crypto_v0_4.test.js b/frontend/gamma/tests/tests/Clipperz/PM/Crypto_v0_4.test.js
new file mode 100644
index 0000000..ecfbec3
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/PM/Crypto_v0_4.test.js
@@ -0,0 +1,50 @@
1/*
2
3Copyright 2008-2013 Clipperz Srl
4
5This file is part of Clipperz, the online password manager.
6For further information about its features and functionalities please
7refer to http://www.clipperz.com.
8
9* Clipperz is free software: you can redistribute it and/or modify it
10 under the terms of the GNU Affero General Public License as published
11 by the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14* Clipperz is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU Affero General Public License for more details.
18
19* You should have received a copy of the GNU Affero General Public
20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
21
22*/
23
24var tests = {
25
26 'decryptDataEncryptedUsingPythonLibrary_test': function (someTestArgs) {
27 var deferredResult;
28
29 passphrase = 'trustno1';
30 encryptedData = 'OucTxzBWmqm8jS7EUyIlWUWDPSFKvulL5iM4WwLPbNVIH7jtaK9pmzpm9w5ioVy2/tyebVwWr36t7QXSBOPwUPo2SlGmARCozA==';
31
32 deferredResult = new Clipperz.Async.Deferred("decryptDataEncryptedUsingPythonLibrary_test", someTestArgs);
33 deferredResult.addCallback(Clipperz.PM.Crypto.deferredDecrypt, {key:passphrase, value:encryptedData, version:'0.4'});
34 deferredResult.addCallback(MochiKit.Base.itemgetter('message'));
35 deferredResult.addTest("The quick brown fox jumps over the lazy dog", "expected value");
36
37 deferredResult.callback();
38
39 return deferredResult;
40
41 },
42
43 //-------------------------------------------------------------------------
44 'syntaxFix': MochiKit.Base.noop
45}
46
47//=============================================================================
48
49Clipperz.Crypto.PRNG.defaultRandomGenerator().fastEntropyAccumulationForTestingPurpose();
50SimpleTest.runDeferredTests("Clipperz.PM.Crypto [0.4]", tests, {trace:false});
diff --git a/frontend/gamma/tests/tests/Clipperz/PM/DataModel/DirectLogin.html b/frontend/gamma/tests/tests/Clipperz/PM/DataModel/DirectLogin.html
index 73b8225..74d1a07 100644
--- a/frontend/gamma/tests/tests/Clipperz/PM/DataModel/DirectLogin.html
+++ b/frontend/gamma/tests/tests/Clipperz/PM/DataModel/DirectLogin.html
@@ -1,98 +1,99 @@
1<!-- 1<!--
2 2
3Copyright 2008-2013 Clipperz Srl 3Copyright 2008-2013 Clipperz Srl
4 4
5This file is part of Clipperz, the online password manager. 5This file is part of Clipperz, the online password manager.
6For further information about its features and functionalities please 6For further information about its features and functionalities please
7refer to http://www.clipperz.com. 7refer to http://www.clipperz.com.
8 8
9* Clipperz is free software: you can redistribute it and/or modify it 9* Clipperz is free software: you can redistribute it and/or modify it
10 under the terms of the GNU Affero General Public License as published 10 under the terms of the GNU Affero General Public License as published
11 by the Free Software Foundation, either version 3 of the License, or 11 by the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version. 12 (at your option) any later version.
13 13
14* Clipperz is distributed in the hope that it will be useful, but 14* Clipperz is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of 15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU Affero General Public License for more details. 17 See the GNU Affero General Public License for more details.
18 18
19* You should have received a copy of the GNU Affero General Public 19* You should have received a copy of the GNU Affero General Public
20 License along with Clipperz. If not, see http://www.gnu.org/licenses/. 20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
21 21
22--> 22-->
23 23
24<html> 24<html>
25<head> 25<head>
26 <title>Clipperz.PM.DataModel.DirectLogin - test</title> 26 <title>Clipperz.PM.DataModel.DirectLogin - test</title>
27 27
28 <script type="text/javascript" src="../../../../../js/MochiKit/MochiKit.js"></script> 28 <script type="text/javascript" src="../../../../../js/MochiKit/MochiKit.js"></script>
29 <script type="text/javascript" src="../../../../SimpleTest/SimpleTest.js"></script> 29 <script type="text/javascript" src="../../../../SimpleTest/SimpleTest.js"></script>
30 <link rel="stylesheet" type="text/css" href="../../../../SimpleTest/test.css"> 30 <link rel="stylesheet" type="text/css" href="../../../../SimpleTest/test.css">
31 31
32 <script type='text/javascript' src='../../../../../js/JSON/json2.js'></script> 32 <script type='text/javascript' src='../../../../../js/JSON/json2.js'></script>
33 33
34 <script type='text/javascript' src='../../../../../js/Clipperz/YUI/Utils.js'></script> 34 <script type='text/javascript' src='../../../../../js/Clipperz/YUI/Utils.js'></script>
35 <script type='text/javascript' src='../../../../../js/Clipperz/Base.js'></script> 35 <script type='text/javascript' src='../../../../../js/Clipperz/Base.js'></script>
36 <script type='text/javascript' src='../../../../../js/Clipperz/Date.js'></script> 36 <script type='text/javascript' src='../../../../../js/Clipperz/Date.js'></script>
37 <script type='text/javascript' src='../../../../../js/Clipperz/ByteArray.js'></script> 37 <script type='text/javascript' src='../../../../../js/Clipperz/ByteArray.js'></script>
38 <script type='text/javascript' src='../../../../../js/Clipperz/Logging.js'></script> 38 <script type='text/javascript' src='../../../../../js/Clipperz/Logging.js'></script>
39 <script type='text/javascript' src='../../../../../js/Clipperz/Async.js'></script> 39 <script type='text/javascript' src='../../../../../js/Clipperz/Async.js'></script>
40 <script type='text/javascript' src='../../../../../js/Clipperz/Signal.js'></script> 40 <script type='text/javascript' src='../../../../../js/Clipperz/Signal.js'></script>
41 <script type='text/javascript' src='../../../../../js/Clipperz/KeyValueObjectStore.js'></script> 41 <script type='text/javascript' src='../../../../../js/Clipperz/KeyValueObjectStore.js'></script>
42 42
43 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/Base.js'></script> 43 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/Base.js'></script>
44 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/BigInt.js'></script> 44 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/BigInt.js'></script>
45 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/AES.js'></script> 45 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/AES.js'></script>
46 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/AES_2.js'></script>
46 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/SHA.js'></script> 47 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/SHA.js'></script>
47 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/PRNG.js'></script> 48 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/PRNG.js'></script>
48 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/SRP.js'></script> 49 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/SRP.js'></script>
49 50
50 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Toll.js'></script> 51 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Toll.js'></script>
51 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy.js'></script> 52 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy.js'></script>
52 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy/Proxy.Offline.js'></script> 53 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy/Proxy.Offline.js'></script>
53 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy/Proxy.Test.js'></script> 54 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy/Proxy.Test.js'></script>
54 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js'></script> 55 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js'></script>
55 56
56 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Connection.js'></script> 57 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Connection.js'></script>
57 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Crypto.js'></script> 58 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Crypto.js'></script>
58 59
59 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Strings.js'></script> 60 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Strings.js'></script>
60 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Strings/Strings_en-US.js'></script> 61 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Strings/Strings_en-US.js'></script>
61 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Date.js'></script> 62 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Date.js'></script>
62 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/EncryptedRemoteObject.js'></script> 63 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/EncryptedRemoteObject.js'></script>
63 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/Record.js'></script> 64 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/Record.js'></script>
64 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/Record.Version.js'></script> 65 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/Record.Version.js'></script>
65 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/Record.Version.Field.js'></script> 66 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/Record.Version.Field.js'></script>
66 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLogin.js'></script> 67 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLogin.js'></script>
67 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLoginInput.js'></script> 68 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLoginInput.js'></script>
68 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLoginBinding.js'></script> 69 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLoginBinding.js'></script>
69 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.js'></script> 70 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.js'></script>
70 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.Legacy.js'></script> 71 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.Legacy.js'></script>
71 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.RecordIndex.js'></script> 72 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.RecordIndex.js'></script>
72 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.Preferences.js'></script> 73 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.Preferences.js'></script>
73 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.OneTimePasswords.js'></script> 74 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.OneTimePasswords.js'></script>
74 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/OneTimePassword.js'></script> 75 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/OneTimePassword.js'></script>
75 76
76 <script type="text/javascript" src="../../../../SimpleTest/SimpleTest.Async.js"></script> 77 <script type="text/javascript" src="../../../../SimpleTest/SimpleTest.Async.js"></script>
77<script> 78<script>
78 Clipperz_IEisBroken = false; 79 Clipperz_IEisBroken = false;
79</script> 80</script>
80 81
81<!--[if IE]><script> 82<!--[if IE]><script>
82Clipperz_IEisBroken = true; 83Clipperz_IEisBroken = true;
83Clipperz_normalizedNewLine = '\x0d\x0a'; 84Clipperz_normalizedNewLine = '\x0d\x0a';
84</script><![endif]--> 85</script><![endif]-->
85 86
86</head> 87</head>
87<body> 88<body>
88 89
89<pre id="test"> 90<pre id="test">
90<script> 91<script>
91 Clipperz.PM.Strings.Languages.setSelectedLanguage('en-us'); 92 Clipperz.PM.Strings.Languages.setSelectedLanguage('en-us');
92</script> 93</script>
93<script type="text/javascript" src="User.data.js"></script> 94<script type="text/javascript" src="User.data.js"></script>
94<script type="text/javascript" src="User.data.old.js"></script> 95<script type="text/javascript" src="User.data.old.js"></script>
95<script type="text/javascript" src="DirectLogin.test.js"></script> 96<script type="text/javascript" src="DirectLogin.test.js"></script>
96</pre> 97</pre>
97</body> 98</body>
98</html> 99</html>
diff --git a/frontend/gamma/tests/tests/Clipperz/PM/DataModel/EncryptedRemoteObject.html b/frontend/gamma/tests/tests/Clipperz/PM/DataModel/EncryptedRemoteObject.html
index a711ba9..c264ff7 100644
--- a/frontend/gamma/tests/tests/Clipperz/PM/DataModel/EncryptedRemoteObject.html
+++ b/frontend/gamma/tests/tests/Clipperz/PM/DataModel/EncryptedRemoteObject.html
@@ -1,61 +1,62 @@
1<!-- 1<!--
2 2
3Copyright 2008-2013 Clipperz Srl 3Copyright 2008-2013 Clipperz Srl
4 4
5This file is part of Clipperz, the online password manager. 5This file is part of Clipperz, the online password manager.
6For further information about its features and functionalities please 6For further information about its features and functionalities please
7refer to http://www.clipperz.com. 7refer to http://www.clipperz.com.
8 8
9* Clipperz is free software: you can redistribute it and/or modify it 9* Clipperz is free software: you can redistribute it and/or modify it
10 under the terms of the GNU Affero General Public License as published 10 under the terms of the GNU Affero General Public License as published
11 by the Free Software Foundation, either version 3 of the License, or 11 by the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version. 12 (at your option) any later version.
13 13
14* Clipperz is distributed in the hope that it will be useful, but 14* Clipperz is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of 15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU Affero General Public License for more details. 17 See the GNU Affero General Public License for more details.
18 18
19* You should have received a copy of the GNU Affero General Public 19* You should have received a copy of the GNU Affero General Public
20 License along with Clipperz. If not, see http://www.gnu.org/licenses/. 20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
21 21
22--> 22-->
23 23
24<html> 24<html>
25<head> 25<head>
26 <title>Clipperz.PM.DataModel.EncryptedRemoteObject - test</title> 26 <title>Clipperz.PM.DataModel.EncryptedRemoteObject - test</title>
27 27
28 <script type="text/javascript" src="../../../../../js/MochiKit/MochiKit.js"></script> 28 <script type="text/javascript" src="../../../../../js/MochiKit/MochiKit.js"></script>
29 <script type="text/javascript" src="../../../../SimpleTest/SimpleTest.js"></script> 29 <script type="text/javascript" src="../../../../SimpleTest/SimpleTest.js"></script>
30 <link rel="stylesheet" type="text/css" href="../../../../SimpleTest/test.css"> 30 <link rel="stylesheet" type="text/css" href="../../../../SimpleTest/test.css">
31 31
32 <script type='text/javascript' src='../../../../../js/JSON/json2.js'></script> 32 <script type='text/javascript' src='../../../../../js/JSON/json2.js'></script>
33 33
34 <script type='text/javascript' src='../../../../../js/Clipperz/YUI/Utils.js'></script> 34 <script type='text/javascript' src='../../../../../js/Clipperz/YUI/Utils.js'></script>
35 <script type='text/javascript' src='../../../../../js/Clipperz/Base.js'></script> 35 <script type='text/javascript' src='../../../../../js/Clipperz/Base.js'></script>
36 <script type='text/javascript' src='../../../../../js/Clipperz/ByteArray.js'></script> 36 <script type='text/javascript' src='../../../../../js/Clipperz/ByteArray.js'></script>
37 <script type='text/javascript' src='../../../../../js/Clipperz/Logging.js'></script> 37 <script type='text/javascript' src='../../../../../js/Clipperz/Logging.js'></script>
38 <script type='text/javascript' src='../../../../../js/Clipperz/Async.js'></script> 38 <script type='text/javascript' src='../../../../../js/Clipperz/Async.js'></script>
39 <script type='text/javascript' src='../../../../../js/Clipperz/Signal.js'></script> 39 <script type='text/javascript' src='../../../../../js/Clipperz/Signal.js'></script>
40 <script type='text/javascript' src='../../../../../js/Clipperz/KeyValueObjectStore.js'></script> 40 <script type='text/javascript' src='../../../../../js/Clipperz/KeyValueObjectStore.js'></script>
41 41
42 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/Base.js'></script> 42 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/Base.js'></script>
43 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/BigInt.js'></script> 43 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/BigInt.js'></script>
44 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/AES.js'></script> 44 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/AES.js'></script>
45 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/AES_2.js'></script>
45 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/SHA.js'></script> 46 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/SHA.js'></script>
46 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/PRNG.js'></script> 47 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/PRNG.js'></script>
47 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/SRP.js'></script> 48 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/SRP.js'></script>
48 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy.js'></script> 49 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy.js'></script>
49 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Connection.js'></script> 50 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Connection.js'></script>
50 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Crypto.js'></script> 51 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Crypto.js'></script>
51 52
52 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/EncryptedRemoteObject.js'></script> 53 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/EncryptedRemoteObject.js'></script>
53 <script type="text/javascript" src="../../../../SimpleTest/SimpleTest.Async.js"></script> 54 <script type="text/javascript" src="../../../../SimpleTest/SimpleTest.Async.js"></script>
54</head> 55</head>
55<body> 56<body>
56 57
57<pre id="test"> 58<pre id="test">
58<script type="text/javascript" src="EncryptedRemoteObject.test.js"></script> 59<script type="text/javascript" src="EncryptedRemoteObject.test.js"></script>
59</pre> 60</pre>
60</body> 61</body>
61</html> 62</html>
diff --git a/frontend/gamma/tests/tests/Clipperz/PM/DataModel/Record.html b/frontend/gamma/tests/tests/Clipperz/PM/DataModel/Record.html
index 0332008..4d6bc5d 100644
--- a/frontend/gamma/tests/tests/Clipperz/PM/DataModel/Record.html
+++ b/frontend/gamma/tests/tests/Clipperz/PM/DataModel/Record.html
@@ -1,93 +1,94 @@
1<!-- 1<!--
2 2
3Copyright 2008-2013 Clipperz Srl 3Copyright 2008-2013 Clipperz Srl
4 4
5This file is part of Clipperz, the online password manager. 5This file is part of Clipperz, the online password manager.
6For further information about its features and functionalities please 6For further information about its features and functionalities please
7refer to http://www.clipperz.com. 7refer to http://www.clipperz.com.
8 8
9* Clipperz is free software: you can redistribute it and/or modify it 9* Clipperz is free software: you can redistribute it and/or modify it
10 under the terms of the GNU Affero General Public License as published 10 under the terms of the GNU Affero General Public License as published
11 by the Free Software Foundation, either version 3 of the License, or 11 by the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version. 12 (at your option) any later version.
13 13
14* Clipperz is distributed in the hope that it will be useful, but 14* Clipperz is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of 15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU Affero General Public License for more details. 17 See the GNU Affero General Public License for more details.
18 18
19* You should have received a copy of the GNU Affero General Public 19* You should have received a copy of the GNU Affero General Public
20 License along with Clipperz. If not, see http://www.gnu.org/licenses/. 20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
21 21
22--> 22-->
23 23
24<html> 24<html>
25<head> 25<head>
26 <title>Clipperz.PM.DataModel.Record - test</title> 26 <title>Clipperz.PM.DataModel.Record - test</title>
27 27
28 <script type="text/javascript" src="../../../../../js/MochiKit/MochiKit.js"></script> 28 <script type="text/javascript" src="../../../../../js/MochiKit/MochiKit.js"></script>
29 <script type="text/javascript" src="../../../../SimpleTest/SimpleTest.js"></script> 29 <script type="text/javascript" src="../../../../SimpleTest/SimpleTest.js"></script>
30 <link rel="stylesheet" type="text/css" href="../../../../SimpleTest/test.css"> 30 <link rel="stylesheet" type="text/css" href="../../../../SimpleTest/test.css">
31 31
32 <script type='text/javascript' src='../../../../../js/JSON/json2.js'></script> 32 <script type='text/javascript' src='../../../../../js/JSON/json2.js'></script>
33 33
34 <script type='text/javascript' src='../../../../../js/Clipperz/YUI/Utils.js'></script> 34 <script type='text/javascript' src='../../../../../js/Clipperz/YUI/Utils.js'></script>
35 <script type='text/javascript' src='../../../../../js/Clipperz/Base.js'></script> 35 <script type='text/javascript' src='../../../../../js/Clipperz/Base.js'></script>
36 <script type='text/javascript' src='../../../../../js/Clipperz/Date.js'></script> 36 <script type='text/javascript' src='../../../../../js/Clipperz/Date.js'></script>
37 <script type='text/javascript' src='../../../../../js/Clipperz/ByteArray.js'></script> 37 <script type='text/javascript' src='../../../../../js/Clipperz/ByteArray.js'></script>
38 <script type='text/javascript' src='../../../../../js/Clipperz/Logging.js'></script> 38 <script type='text/javascript' src='../../../../../js/Clipperz/Logging.js'></script>
39 <script type='text/javascript' src='../../../../../js/Clipperz/Async.js'></script> 39 <script type='text/javascript' src='../../../../../js/Clipperz/Async.js'></script>
40 <script type='text/javascript' src='../../../../../js/Clipperz/Signal.js'></script> 40 <script type='text/javascript' src='../../../../../js/Clipperz/Signal.js'></script>
41 <script type='text/javascript' src='../../../../../js/Clipperz/KeyValueObjectStore.js'></script> 41 <script type='text/javascript' src='../../../../../js/Clipperz/KeyValueObjectStore.js'></script>
42 42
43 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/Base.js'></script> 43 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/Base.js'></script>
44 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/BigInt.js'></script> 44 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/BigInt.js'></script>
45 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/AES.js'></script> 45 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/AES.js'></script>
46 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/AES_2.js'></script>
46 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/SHA.js'></script> 47 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/SHA.js'></script>
47 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/PRNG.js'></script> 48 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/PRNG.js'></script>
48 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/SRP.js'></script> 49 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/SRP.js'></script>
49 50
50 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Toll.js'></script> 51 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Toll.js'></script>
51 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Strings.js'></script> 52 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Strings.js'></script>
52 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Strings/Strings_en-US.js'></script> 53 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Strings/Strings_en-US.js'></script>
53 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Date.js'></script> 54 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Date.js'></script>
54 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy.js'></script> 55 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy.js'></script>
55 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy/Proxy.Offline.js'></script> 56 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy/Proxy.Offline.js'></script>
56 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy/Proxy.Test.js'></script> 57 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy/Proxy.Test.js'></script>
57 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js'></script> 58 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js'></script>
58 59
59 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Connection.js'></script> 60 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Connection.js'></script>
60 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Crypto.js'></script> 61 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Crypto.js'></script>
61 62
62 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Strings.js'></script> 63 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Strings.js'></script>
63 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Strings/Strings_en-US.js'></script> 64 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Strings/Strings_en-US.js'></script>
64 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Date.js'></script> 65 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Date.js'></script>
65 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/EncryptedRemoteObject.js'></script> 66 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/EncryptedRemoteObject.js'></script>
66 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/Record.js'></script> 67 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/Record.js'></script>
67 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/Record.Version.js'></script> 68 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/Record.Version.js'></script>
68 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/Record.Version.Field.js'></script> 69 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/Record.Version.Field.js'></script>
69 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLogin.js'></script> 70 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLogin.js'></script>
70 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLoginInput.js'></script> 71 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLoginInput.js'></script>
71 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLoginBinding.js'></script> 72 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLoginBinding.js'></script>
72 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLoginFormValue.js'></script> 73 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLoginFormValue.js'></script>
73 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.js'></script> 74 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.js'></script>
74 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.Legacy.js'></script> 75 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.Legacy.js'></script>
75 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.RecordIndex.js'></script> 76 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.RecordIndex.js'></script>
76 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.Preferences.js'></script> 77 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.Preferences.js'></script>
77 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.OneTimePasswords.js'></script> 78 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.OneTimePasswords.js'></script>
78 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/OneTimePassword.js'></script> 79 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/OneTimePassword.js'></script>
79 80
80 <script type="text/javascript" src="../../../../SimpleTest/SimpleTest.Async.js"></script> 81 <script type="text/javascript" src="../../../../SimpleTest/SimpleTest.Async.js"></script>
81</head> 82</head>
82<body> 83<body>
83 84
84<pre id="test"> 85<pre id="test">
85<script> 86<script>
86 Clipperz.PM.Strings.Languages.setSelectedLanguage('en-us'); 87 Clipperz.PM.Strings.Languages.setSelectedLanguage('en-us');
87</script> 88</script>
88<script type="text/javascript" src="DirectLoginConfigurations.data.js"></script> 89<script type="text/javascript" src="DirectLoginConfigurations.data.js"></script>
89<script type="text/javascript" src="User.data.js"></script> 90<script type="text/javascript" src="User.data.js"></script>
90<script type="text/javascript" src="Record.test.js"></script> 91<script type="text/javascript" src="Record.test.js"></script>
91</pre> 92</pre>
92</body> 93</body>
93</html> 94</html>
diff --git a/frontend/gamma/tests/tests/Clipperz/PM/DataModel/Record.test.js b/frontend/gamma/tests/tests/Clipperz/PM/DataModel/Record.test.js
index 3478743..af1ffe8 100644
--- a/frontend/gamma/tests/tests/Clipperz/PM/DataModel/Record.test.js
+++ b/frontend/gamma/tests/tests/Clipperz/PM/DataModel/Record.test.js
@@ -1,957 +1,965 @@
1/* 1/*
2 2
3Copyright 2008-2013 Clipperz Srl 3Copyright 2008-2013 Clipperz Srl
4 4
5This file is part of Clipperz, the online password manager. 5This file is part of Clipperz, the online password manager.
6For further information about its features and functionalities please 6For further information about its features and functionalities please
7refer to http://www.clipperz.com. 7refer to http://www.clipperz.com.
8 8
9* Clipperz is free software: you can redistribute it and/or modify it 9* Clipperz is free software: you can redistribute it and/or modify it
10 under the terms of the GNU Affero General Public License as published 10 under the terms of the GNU Affero General Public License as published
11 by the Free Software Foundation, either version 3 of the License, or 11 by the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version. 12 (at your option) any later version.
13 13
14* Clipperz is distributed in the hope that it will be useful, but 14* Clipperz is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of 15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU Affero General Public License for more details. 17 See the GNU Affero General Public License for more details.
18 18
19* You should have received a copy of the GNU Affero General Public 19* You should have received a copy of the GNU Affero General Public
20 License along with Clipperz. If not, see http://www.gnu.org/licenses/. 20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
21 21
22*/ 22*/
23 23
24Clipperz.Crypto.PRNG.defaultRandomGenerator().fastEntropyAccumulationForTestingPurpose(); 24Clipperz.Crypto.PRNG.defaultRandomGenerator().fastEntropyAccumulationForTestingPurpose();
25 25
26var tests = { 26var tests = {
27 27
28 //------------------------------------------------------------------------- 28 //-------------------------------------------------------------------------
29 29
30 'recordUseOf_retrieveIndexDataFunction_and_getRemoteDataFunction_test': function (someTestArgs) { 30 'recordUseOf_retrieveIndexDataFunction_and_getRemoteDataFunction_test': function (someTestArgs) {
31 var deferredResult; 31 var deferredResult;
32 var record; 32 var record;
33 33
34//console.log("#### new Clipperz.PM.DataModel.Record [5]"); 34//console.log("#### new Clipperz.PM.DataModel.Record [5]");
35 record = new Clipperz.PM.DataModel.Record({ 35 record = new Clipperz.PM.DataModel.Record({
36 'reference': '<<< record reference >>>', 36 'reference': '<<< record reference >>>',
37 'retrieveKeyFunction': MochiKit.Base.noop, 37 'retrieveKeyFunction': MochiKit.Base.noop,
38 'retrieveRemoteDataFunction': function (aRecordReference) { 38 'retrieveRemoteDataFunction': function (aRecordReference) {
39 SimpleTest.is(aRecordReference, '<<< record reference >>>', "Record correctly passes its record reference when asking for encrypted data"); 39 SimpleTest.is(aRecordReference, '<<< record reference >>>', "Record correctly passes its record reference when asking for encrypted data");
40 return MochiKit.Async.succeed({ 40 return MochiKit.Async.succeed({
41 // fake server payload 41 // fake server payload
42 'data': "#### fake encrypted data ####", 42 'data': "#### fake encrypted data ####",
43 'version': "0.x", 43 'version': "0.x",
44 'currentVersion': { 44 'currentVersion': {
45 'reference': "<<< fake record version reference >>>", 45 'reference': "<<< fake record version reference >>>",
46 'data': "#### fake encrypted data ####", 46 'data': "#### fake encrypted data ####",
47 'version': "0.x" 47 'version': "0.x"
48 } 48 }
49 }); 49 });
50 }, 50 },
51 'updateDate': "Thu, 10 May 2007 13:01:21 UTC", 51 'updateDate': "Thu, 10 May 2007 13:01:21 UTC",
52 // 'encryptedDataKeypath': 'data', 52 // 'encryptedDataKeypath': 'data',
53 // 'encryptedVersionKeypath': 'version', 53 // 'encryptedVersionKeypath': 'version',
54 54
55 'retrieveIndexDataFunction':function (aRecordReference) { 55 'retrieveIndexDataFunction':function (aRecordReference) {
56 SimpleTest.is(aRecordReference, '<<< record reference >>>', "Record correctly passes its record reference when asking for index data"); 56 SimpleTest.is(aRecordReference, '<<< record reference >>>', "Record correctly passes its record reference when asking for index data");
57 return MochiKit.Async.succeed({ 57 return MochiKit.Async.succeed({
58 key:'<< key >>', 58 key:'<< key >>',
59 label:'<< label >>', 59 label:'<< label >>',
60 notes:'<< notes >>' 60 notes:'<< notes >>'
61 }); 61 });
62 }, 62 },
63 'updateIndexDataFunction': MochiKit.Base.noop 63 'updateIndexDataFunction': MochiKit.Base.noop
64 64
65 }); 65 });
66 66
67 deferredResult = new Clipperz.Async.Deferred("recordUseOf_retrieveIndexDataFunction_and_getEncryptedDataFunction_test", someTestArgs); 67 deferredResult = new Clipperz.Async.Deferred("recordUseOf_retrieveIndexDataFunction_and_getEncryptedDataFunction_test", someTestArgs);
68 deferredResult.addMethod(record, 'label'); 68 deferredResult.addMethod(record, 'label');
69 deferredResult.addTest('<< label >>', "Record returns the right value for label"); 69 deferredResult.addTest('<< label >>', "Record returns the right value for label");
70 deferredResult.addMethod(record, 'notes'); 70 deferredResult.addMethod(record, 'notes');
71 deferredResult.addTest('<< notes >>', "Record returns the right value for notes - even the legacy one, stored on the header"); 71 deferredResult.addTest('<< notes >>', "Record returns the right value for notes - even the legacy one, stored on the header");
72 deferredResult.addMethod(record, 'getRemoteData'); 72 deferredResult.addMethod(record, 'getRemoteData');
73 deferredResult.addCallback(Clipperz.Async.Test.isDeeply({ 'data': "#### fake encrypted data ####", 'version': "0.x", 'currentVersion': { 'reference': "<<< fake record version reference >>>", 'data': "#### fake encrypted data ####", 'version': "0.x" } }, "Record returns the expected encrypted data")); 73 deferredResult.addCallback(Clipperz.Async.Test.isDeeply({ 'data': "#### fake encrypted data ####", 'version': "0.x", 'currentVersion': { 'reference': "<<< fake record version reference >>>", 'data': "#### fake encrypted data ####", 'version': "0.x" } }, "Record returns the expected encrypted data"));
74 deferredResult.callback(); 74 deferredResult.callback();
75 75
76 return deferredResult; 76 return deferredResult;
77 }, 77 },
78 78
79 //------------------------------------------------------------------------- 79 //-------------------------------------------------------------------------
80 80
81 'createRecordWithoutAllRequiredParameters_test': function (someTestArgs) { 81 'createRecordWithoutAllRequiredParameters_test': function (someTestArgs) {
82 varrecord; 82 varrecord;
83 83
84 try { 84 try {
85//console.log("#### new Clipperz.PM.DataModel.Record [6]"); 85//console.log("#### new Clipperz.PM.DataModel.Record [6]");
86 record = new Clipperz.PM.DataModel.Record({reference:'--'}); 86 record = new Clipperz.PM.DataModel.Record({reference:'--'});
87 SimpleTest.ok(false, "creating a record without all parameters should raise an exception"); 87 SimpleTest.ok(false, "creating a record without all parameters should raise an exception");
88 } catch(exception) { 88 } catch(exception) {
89 // SimpleTest.is(exception.name, "Clipperz.Base.exception.MandatoryParameter", "creating a record without all parameters raises an exception"); 89 // SimpleTest.is(exception.name, "Clipperz.Base.exception.MandatoryParameter", "creating a record without all parameters raises an exception");
90 SimpleTest.ok(/Clipperz\.Base\.exception\.MandatoryParameter.*/.test(exception.name), "creating a record without all parameters raises an exception"); 90 SimpleTest.ok(/Clipperz\.Base\.exception\.MandatoryParameter.*/.test(exception.name), "creating a record without all parameters raises an exception");
91 } 91 }
92 }, 92 },
93 93
94 //------------------------------------------------------------------------- 94 //-------------------------------------------------------------------------
95 95
96 'recordFromOldData_version_0.1_test': function (someTestArgs) { 96 'recordFromOldData_version_0.1_test': function (someTestArgs) {
97 var deferredResult; 97 var deferredResult;
98 var proxy; 98 var proxy;
99 var user; 99 var user;
100 var recordID; 100 var recordID;
101 101
102//console.log("#### new Clipperz.PM.DataModel.Record [7]"); 102//console.log("#### new Clipperz.PM.DataModel.Record [7]");
103/* 103/*
104 record = new Clipperz.PM.DataModel.Record({ 104 record = new Clipperz.PM.DataModel.Record({
105 'reference':'05aad20ee399b11ddc923e601fcd1d096233634f2ad4c55db4f6435e5f9cc17a', 105 'reference':'05aad20ee399b11ddc923e601fcd1d096233634f2ad4c55db4f6435e5f9cc17a',
106 'retrieveKeyFunction': MochiKit.Base.partial(MochiKit.Async.succeed, 'e038652297f981d5ca917d88fa2c4c3251a12c0fa41bf7313a4d24a9738fe6c6'), 106 'retrieveKeyFunction': MochiKit.Base.partial(MochiKit.Async.succeed, 'e038652297f981d5ca917d88fa2c4c3251a12c0fa41bf7313a4d24a9738fe6c6'),
107 'retrieveRemoteDataFunction':MochiKit.Base.partial(MochiKit.Async.succeed, { 107 'retrieveRemoteDataFunction':MochiKit.Base.partial(MochiKit.Async.succeed, {
108 'data': '4ec19a7093534e7dcf7c796b889283c6cec224b1895720ba3ff43ce091dc72c61fd5ea56def418ba3f15239f73228c6c8558585311f5e6673efe57482a1f9c9fe71e921576989eace671ec543685e3ad8f976bbfa4c2dbc629fab936c227d4fd4da3a1561ea79e553bae7b758ff91762572c1448a2d18bec797e12721238ef5ba18ddf1fba8ae773a8debe1040b3b158220aec6be9c7190687139f589a30d9c8887792fd7040e3c7cf3f9999fb9dde1f9f334d17c996996d538a7e374ac93135acafdaf5fce738a1702182897b63d2cb8e308b94156473cba63dcc557d17dcbdb55fcff63d9ba5edf68c42855052e34207d6fabe94fe024c3db616b45f494da42c62224d3897e320080072cc442d4212e7b1e8d5b3d9e3c25d48f4e7c37112ef4c6b2c0c8aff0bd3ce05694370e4378701463dde26c7c0322f8a9eb5a724106039b16b35050a9a9b5717b2eec803efa962b88b9655742f5e7b180ea567449671fb5a2ce563d8b47bc25705821938192eae420391c208182a788dd06fb6448b9858a4104a14efd7717671c65cd08fd979a4da7c01712bc5d4e949a10ef1ea65caf1f07cee34b063bab01bfb7a59047fef30c3059ea652f1c92b9e72aac515ac8851756703772e1fa05384ee7f0d5c7a3c', 108 'data': '4ec19a7093534e7dcf7c796b889283c6cec224b1895720ba3ff43ce091dc72c61fd5ea56def418ba3f15239f73228c6c8558585311f5e6673efe57482a1f9c9fe71e921576989eace671ec543685e3ad8f976bbfa4c2dbc629fab936c227d4fd4da3a1561ea79e553bae7b758ff91762572c1448a2d18bec797e12721238ef5ba18ddf1fba8ae773a8debe1040b3b158220aec6be9c7190687139f589a30d9c8887792fd7040e3c7cf3f9999fb9dde1f9f334d17c996996d538a7e374ac93135acafdaf5fce738a1702182897b63d2cb8e308b94156473cba63dcc557d17dcbdb55fcff63d9ba5edf68c42855052e34207d6fabe94fe024c3db616b45f494da42c62224d3897e320080072cc442d4212e7b1e8d5b3d9e3c25d48f4e7c37112ef4c6b2c0c8aff0bd3ce05694370e4378701463dde26c7c0322f8a9eb5a724106039b16b35050a9a9b5717b2eec803efa962b88b9655742f5e7b180ea567449671fb5a2ce563d8b47bc25705821938192eae420391c208182a788dd06fb6448b9858a4104a14efd7717671c65cd08fd979a4da7c01712bc5d4e949a10ef1ea65caf1f07cee34b063bab01bfb7a59047fef30c3059ea652f1c92b9e72aac515ac8851756703772e1fa05384ee7f0d5c7a3c',
109 'version': '0.1', 109 'version': '0.1',
110 'currentVersion': { 110 'currentVersion': {
111 'reference': '05aad20ee399b11ddc923e601fcd1d096233634f2ad4c55db4f6435e5f9cc17a', 111 'reference': '05aad20ee399b11ddc923e601fcd1d096233634f2ad4c55db4f6435e5f9cc17a',
112 'data': '4ec19a7093534e7dcf7c796b889283c6cec224b1895720ba3ff43ce091dc72c61fd5ea56def418ba3f15239f73228c6c8558585311f5e6673efe57482a1f9c9fe71e921576989eace671ec543685e3ad8f976bbfa4c2dbc629fab936c227d4fd4da3a1561ea79e553bae7b758ff91762572c1448a2d18bec797e12721238ef5ba18ddf1fba8ae773a8debe1040b3b158220aec6be9c7190687139f589a30d9c8887792fd7040e3c7cf3f9999fb9dde1f9f334d17c996996d538a7e374ac93135acafdaf5fce738a1702182897b63d2cb8e308b94156473cba63dcc557d17dcbdb55fcff63d9ba5edf68c42855052e34207d6fabe94fe024c3db616b45f494da42c62224d3897e320080072cc442d4212e7b1e8d5b3d9e3c25d48f4e7c37112ef4c6b2c0c8aff0bd3ce05694370e4378701463dde26c7c0322f8a9eb5a724106039b16b35050a9a9b5717b2eec803efa962b88b9655742f5e7b180ea567449671fb5a2ce563d8b47bc25705821938192eae420391c208182a788dd06fb6448b9858a4104a14efd7717671c65cd08fd979a4da7c01712bc5d4e949a10ef1ea65caf1f07cee34b063bab01bfb7a59047fef30c3059ea652f1c92b9e72aac515ac8851756703772e1fa05384ee7f0d5c7a3c', 112 'data': '4ec19a7093534e7dcf7c796b889283c6cec224b1895720ba3ff43ce091dc72c61fd5ea56def418ba3f15239f73228c6c8558585311f5e6673efe57482a1f9c9fe71e921576989eace671ec543685e3ad8f976bbfa4c2dbc629fab936c227d4fd4da3a1561ea79e553bae7b758ff91762572c1448a2d18bec797e12721238ef5ba18ddf1fba8ae773a8debe1040b3b158220aec6be9c7190687139f589a30d9c8887792fd7040e3c7cf3f9999fb9dde1f9f334d17c996996d538a7e374ac93135acafdaf5fce738a1702182897b63d2cb8e308b94156473cba63dcc557d17dcbdb55fcff63d9ba5edf68c42855052e34207d6fabe94fe024c3db616b45f494da42c62224d3897e320080072cc442d4212e7b1e8d5b3d9e3c25d48f4e7c37112ef4c6b2c0c8aff0bd3ce05694370e4378701463dde26c7c0322f8a9eb5a724106039b16b35050a9a9b5717b2eec803efa962b88b9655742f5e7b180ea567449671fb5a2ce563d8b47bc25705821938192eae420391c208182a788dd06fb6448b9858a4104a14efd7717671c65cd08fd979a4da7c01712bc5d4e949a10ef1ea65caf1f07cee34b063bab01bfb7a59047fef30c3059ea652f1c92b9e72aac515ac8851756703772e1fa05384ee7f0d5c7a3c',
113 'version': '0.1' 113 'version': '0.1'
114 } 114 }
115 115
116 }), 116 }),
117 117
118 'retrieveIndexDataFunction':MochiKit.Base.partial(MochiKit.Async.succeed, { 118 'retrieveIndexDataFunction':MochiKit.Base.partial(MochiKit.Async.succeed, {
119 // 'key': 'e038652297f981d5ca917d88fa2c4c3251a12c0fa41bf7313a4d24a9738fe6c6', 119 // 'key': 'e038652297f981d5ca917d88fa2c4c3251a12c0fa41bf7313a4d24a9738fe6c6',
120 'label': '<< label >>', 120 'label': '<< label >>',
121 'notes': '<< notes >>' 121 'notes': '<< notes >>'
122 }), 122 }),
123 'updateIndexDataFunction': MochiKit.Base.noop, 123 'updateIndexDataFunction': MochiKit.Base.noop,
124 'updateDate': 'Mon Oct 02 10:01:52 CEST 2006' 124 'updateDate': 'Mon Oct 02 10:01:52 CEST 2006'
125 }); 125 });
126*/ 126*/
127 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:false, isDefault:true, readOnly:false}); 127 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:false, isDefault:true, readOnly:false});
128 user = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}}); 128 user = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}});
129 recordID = "05aad20ee399b11ddc923e601fcd1d096233634f2ad4c55db4f6435e5f9cc17a"; 129 recordID = "05aad20ee399b11ddc923e601fcd1d096233634f2ad4c55db4f6435e5f9cc17a";
130 130
131 deferredResult = new Clipperz.Async.Deferred("recordFromOldData_version_0.1_test", someTestArgs); 131 deferredResult = new Clipperz.Async.Deferred("recordFromOldData_version_0.1_test", someTestArgs);
132 132
133 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_someExtraOldData']); 133 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_someExtraOldData']);
134 deferredResult.addMethod(user, 'login'); 134 deferredResult.addMethod(user, 'login');
135 135
136 deferredResult.addMethod(user, 'getRecord', recordID); 136 deferredResult.addMethod(user, 'getRecord', recordID);
137 deferredResult.addMethodcaller('hasAnyCleanTextData'); 137 deferredResult.addMethodcaller('hasAnyCleanTextData');
138 deferredResult.addTest(false, "When first loaded, the record has no clean text data"); 138 deferredResult.addTest(false, "When first loaded, the record has no clean text data");
139 139
140 deferredResult.addMethod(user, 'getRecord', recordID); 140 deferredResult.addMethod(user, 'getRecord', recordID);
141 deferredResult.addMethodcaller('label'); 141 deferredResult.addMethodcaller('label');
142 deferredResult.addTest("Card encoded with an old algorithm", "Record returns the right value for label"); 142 deferredResult.addTest("Card encoded with an old algorithm", "Record returns the right value for label");
143 143
144 deferredResult.addMethod(user, 'getRecord', recordID); 144 deferredResult.addMethod(user, 'getRecord', recordID);
145 deferredResult.addMethodcaller('notes'); 145 deferredResult.addMethodcaller('notes');
146 deferredResult.addTest("", "Record returns the right value for notes - even the legacy one, stored on the header"); 146 deferredResult.addTest("", "Record returns the right value for notes - even the legacy one, stored on the header");
147 147
148 deferredResult.addMethod(user, 'getRecord', recordID); 148 deferredResult.addMethod(user, 'getRecord', recordID);
149 deferredResult.addMethodcaller('hasAnyCleanTextData'); 149 deferredResult.addMethodcaller('hasAnyCleanTextData');
150 deferredResult.addTest(true, "After reading some values, the record has some clean text data"); 150 deferredResult.addTest(true, "After reading some values, the record has some clean text data");
151 151
152 deferredResult.addMethod(user, 'getRecord', recordID); 152 deferredResult.addMethod(user, 'getRecord', recordID);
153 deferredResult.addMethodcaller('fields'); 153 deferredResult.addMethodcaller('fields');
154 deferredResult.addCallback(function (someFields) { 154 deferredResult.addCallback(function (someFields) {
155 SimpleTest.is(MochiKit.Base.values(someFields).length, 6, "the card has 6 fields"); 155 SimpleTest.is(MochiKit.Base.values(someFields).length, 6, "the card has 6 fields");
156 }); 156 });
157 deferredResult.callback(); 157 deferredResult.callback();
158 158
159 return deferredResult; 159 return deferredResult;
160 160
161 }, 161 },
162 162
163 //------------------------------------------------------------------------- 163 //-------------------------------------------------------------------------
164 164
165 'removeDirectLogin': function (someTestArgs) { 165 'removeDirectLogin': function (someTestArgs) {
166 var deferredResult; 166 var deferredResult;
167 var proxy; 167 var proxy;
168 var user; 168 var user;
169 169
170 var recordID = 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d'; //YAHOO (4) 170 var recordID = 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d'; //YAHOO (4)
171 var directLoginID ='dba0db679802f0e6aa6d0b7a6aaf42350aabc5f057409edd99a268a92ebb6496'; 171 var directLoginID ='dba0db679802f0e6aa6d0b7a6aaf42350aabc5f057409edd99a268a92ebb6496';
172 172
173 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:false, isDefault:true, readOnly:false}); 173 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:false, isDefault:true, readOnly:false});
174 user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}}); 174 user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
175 user2 = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}}); 175 user2 = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
176 176
177 deferredResult = new Clipperz.Async.Deferred("Record.test.removeDirectLogin", someTestArgs); 177 deferredResult = new Clipperz.Async.Deferred("Record.test.removeDirectLogin", someTestArgs);
178 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']); 178 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
179 deferredResult.addMethod(user, 'login'); 179 deferredResult.addMethod(user, 'login');
180
181 deferredResult.addMethod(user, 'getRecord', recordID);
182 deferredResult.addMethodcaller('directLogins');
183 deferredResult.addCallback(MochiKit.Base.keys);
184 deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
185 deferredResult.addTest(4, "The record initially has 4 direct logins");
186
180 deferredResult.addMethod(user, 'getRecord', recordID); 187 deferredResult.addMethod(user, 'getRecord', recordID);
181 deferredResult.addMethodcaller('directLogins'); 188 deferredResult.addMethodcaller('directLogins');
182 deferredResult.addCallback(MochiKit.Base.itemgetter(directLoginID)); 189 deferredResult.addCallback(MochiKit.Base.itemgetter(directLoginID));
183 deferredResult.addMethodcaller('remove'); 190 deferredResult.addMethodcaller('remove');
184 191
185 deferredResult.addMethod(user, 'getRecord', recordID); 192 deferredResult.addMethod(user, 'getRecord', recordID);
186 deferredResult.addMethodcaller('hasPendingChanges'); 193 deferredResult.addMethodcaller('hasPendingChanges');
187 deferredResult.addTest(true, "removing a direct login to a record should result in pending changes on the record"); 194 deferredResult.addTest(true, "removing a direct login to a record should result in pending changes on the record");
188 195
189 deferredResult.addMethod(user, 'saveChanges'); 196 deferredResult.addMethod(user, 'saveChanges');
197
190 deferredResult.addMethod(user, 'hasPendingChanges'); 198 deferredResult.addMethod(user, 'hasPendingChanges');
191 deferredResult.addTest(false, "after saving there should be not any pending changes"); 199 deferredResult.addTest(false, "after saving there should be not any pending changes");
192 200
193 deferredResult.addMethod(user, 'getRecord', recordID); 201 deferredResult.addMethod(user, 'getRecord', recordID);
194 deferredResult.addMethodcaller('directLogins'); 202 deferredResult.addMethodcaller('directLogins');
195 deferredResult.addCallback(MochiKit.Base.keys); 203 deferredResult.addCallback(MochiKit.Base.keys);
196 deferredResult.addCallback(MochiKit.Base.itemgetter('length')); 204 deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
197 deferredResult.addTest(3, "after saving changes, the record should have only 3 direct logins"); 205 deferredResult.addTest(3, "after saving changes, the record should have only 3 direct logins");
198 206
199 deferredResult.addMethod(user2, 'login'); 207 deferredResult.addMethod(user2, 'login');
200 deferredResult.addMethod(user2, 'getRecord', recordID); 208 deferredResult.addMethod(user2, 'getRecord', recordID);
201 deferredResult.addMethodcaller('directLogins'); 209 deferredResult.addMethodcaller('directLogins');
202 deferredResult.addCallback(MochiKit.Base.keys); 210 deferredResult.addCallback(MochiKit.Base.keys);
203 deferredResult.addCallback(MochiKit.Base.itemgetter('length')); 211 deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
204 deferredResult.addTest(3, "also reloading all the data with a new user, the direct logins should always be 3"); 212 deferredResult.addTest(3, "also reloading all the data with a new user, the direct logins should always be 3");
205 213
206 deferredResult.callback(); 214 deferredResult.callback();
207 215
208 return deferredResult; 216 return deferredResult;
209 }, 217 },
210 218
211 //------------------------------------------------------------------------- 219 //-------------------------------------------------------------------------
212 220
213 'removeDirectLoginAndRevertChanges': function (someTestArgs) { 221 'removeDirectLoginAndRevertChanges': function (someTestArgs) {
214 var deferredResult; 222 var deferredResult;
215 var proxy; 223 var proxy;
216 var user; 224 var user;
217 225
218 var recordID = 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d'; 226 var recordID = 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d';
219 var directLoginID ='dba0db679802f0e6aa6d0b7a6aaf42350aabc5f057409edd99a268a92ebb6496'; 227 var directLoginID ='dba0db679802f0e6aa6d0b7a6aaf42350aabc5f057409edd99a268a92ebb6496';
220 228
221 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:false, isDefault:true, readOnly:false}); 229 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:false, isDefault:true, readOnly:false});
222 user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}}); 230 user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
223 231
224 deferredResult = new Clipperz.Async.Deferred("Record.test.removeDirectLoginAndRevertChanges", someTestArgs); 232 deferredResult = new Clipperz.Async.Deferred("Record.test.removeDirectLoginAndRevertChanges", someTestArgs);
225 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']); 233 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
226 deferredResult.addMethod(user, 'login'); 234 deferredResult.addMethod(user, 'login');
227 235
228 deferredResult.addMethod(user, 'getDirectLogins'); 236 deferredResult.addMethod(user, 'getDirectLogins');
229 deferredResult.addCallback(MochiKit.Base.itemgetter('length')); 237 deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
230 deferredResult.addTest(22, "the user has 22 initially"); 238 deferredResult.addTest(22, "the user has 22 initially");
231 239
232 deferredResult.addMethod(user, 'getRecord', recordID); 240 deferredResult.addMethod(user, 'getRecord', recordID);
233 deferredResult.addMethodcaller('directLogins'); 241 deferredResult.addMethodcaller('directLogins');
234 deferredResult.addCallback(MochiKit.Base.keys); 242 deferredResult.addCallback(MochiKit.Base.keys);
235 deferredResult.addCallback(MochiKit.Base.itemgetter('length')); 243 deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
236 deferredResult.addTest(4, "the selected record has 4 direct logins"); 244 deferredResult.addTest(4, "the selected record has 4 direct logins");
237 245
238 deferredResult.addMethod(user, 'getRecord', recordID); 246 deferredResult.addMethod(user, 'getRecord', recordID);
239 deferredResult.addMethodcaller('directLogins'); 247 deferredResult.addMethodcaller('directLogins');
240 deferredResult.addCallback(MochiKit.Base.itemgetter(directLoginID)); 248 deferredResult.addCallback(MochiKit.Base.itemgetter(directLoginID));
241 deferredResult.addMethodcaller('remove'); 249 deferredResult.addMethodcaller('remove');
242 250
243 deferredResult.addMethod(user, 'getRecord', recordID); 251 deferredResult.addMethod(user, 'getRecord', recordID);
244 deferredResult.addMethodcaller('hasPendingChanges'); 252 deferredResult.addMethodcaller('hasPendingChanges');
245 deferredResult.addTest(true, "removing a direct login to a record should result in pending changes on the record"); 253 deferredResult.addTest(true, "removing a direct login to a record should result in pending changes on the record");
246 254
247 deferredResult.addMethod(user, 'revertChanges'); 255 deferredResult.addMethod(user, 'revertChanges');
248 deferredResult.addMethod(user, 'hasPendingChanges'); 256 deferredResult.addMethod(user, 'hasPendingChanges');
249 deferredResult.addTest(false, "after reverting the changes, the user should not have pending changes"); 257 deferredResult.addTest(false, "after reverting the changes, the user should not have pending changes");
250 258
251 deferredResult.addMethod(user, 'getDirectLogins'); 259 deferredResult.addMethod(user, 'getDirectLogins');
252 deferredResult.addCallback(MochiKit.Base.itemgetter('length')); 260 deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
253 deferredResult.addTest(22, "after reverting the changes, the user should still have 22 direct logins"); 261 deferredResult.addTest(22, "after reverting the changes, the user should still have 22 direct logins");
254 262
255 deferredResult.addMethod(user, 'getRecord', recordID); 263 deferredResult.addMethod(user, 'getRecord', recordID);
256 deferredResult.addMethodcaller('directLogins'); 264 deferredResult.addMethodcaller('directLogins');
257 deferredResult.addCallback(MochiKit.Base.keys); 265 deferredResult.addCallback(MochiKit.Base.keys);
258 deferredResult.addCallback(MochiKit.Base.itemgetter('length')); 266 deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
259 deferredResult.addTest(4, "after reverting the changes, the record should still have 4 direct logins"); 267 deferredResult.addTest(4, "after reverting the changes, the record should still have 4 direct logins");
260 268
261 deferredResult.callback(); 269 deferredResult.callback();
262 270
263 return deferredResult; 271 return deferredResult;
264 }, 272 },
265 273
266 //------------------------------------------------------------------------- 274 //-------------------------------------------------------------------------
267 275
268 'addDirectLoginAndRevertChanges': function (someTestArgs) { 276 'addDirectLoginAndRevertChanges': function (someTestArgs) {
269 var deferredResult; 277 var deferredResult;
270 var proxy; 278 var proxy;
271 var user, user2; 279 var user, user2;
272 var recordID = 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d'; //YAHOO (4) 280 var recordID = 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d'; //YAHOO (4)
273 var directLoginReference; 281 var directLoginReference;
274 282
275 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:false, isDefault:true, readOnly:false}); 283 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:false, isDefault:true, readOnly:false});
276 user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}}); 284 user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
277 user2 = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}}); 285 user2 = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
278 286
279 deferredResult = new Clipperz.Async.Deferred("Record.test.addDirectLoginAndRevertChanges", someTestArgs); 287 deferredResult = new Clipperz.Async.Deferred("Record.test.addDirectLoginAndRevertChanges", someTestArgs);
280 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']); 288 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
281 deferredResult.addMethod(user, 'login'); 289 deferredResult.addMethod(user, 'login');
282 290
283 deferredResult.addMethod(user, 'getRecord', recordID); 291 deferredResult.addMethod(user, 'getRecord', recordID);
284 deferredResult.setValue('record'); 292 deferredResult.setValue('record');
285 deferredResult.addMethodcaller('directLogins'); 293 deferredResult.addMethodcaller('directLogins');
286 deferredResult.addCallback(MochiKit.Base.keys); 294 deferredResult.addCallback(MochiKit.Base.keys);
287 deferredResult.addCallback(MochiKit.Base.itemgetter('length')); 295 deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
288 deferredResult.addTest(4, "the record, when initially loaded, has 4 direct logins"); 296 deferredResult.addTest(4, "the record, when initially loaded, has 4 direct logins");
289 297
290 deferredResult.getValue('record'); 298 deferredResult.getValue('record');
291 deferredResult.addMethodcaller('createNewDirectLogin'); 299 deferredResult.addMethodcaller('createNewDirectLogin');
292 deferredResult.setValue('directLogin'); 300 deferredResult.setValue('directLogin');
293 301
294 deferredResult.getValue('directLogin'); 302 deferredResult.getValue('directLogin');
295 deferredResult.addMethodcaller('setLabel', "New direct login"); 303 deferredResult.addMethodcaller('setLabel', "New direct login");
296 304
297 deferredResult.getValue('directLogin'); 305 deferredResult.getValue('directLogin');
298 deferredResult.addMethodcaller('setBookmarkletConfiguration', '{"page": {"title": "Parallels Account"}, "form": {"attributes": {"action": "https://www.parallels.com/account/", "method": "post"}, "inputs": [{"type": "text", "name": "Email", "value": ""}, {"type": "password", "name": "Password", "value": ""}]}, "version": "0.2.3"}'); 306 deferredResult.addMethodcaller('setBookmarkletConfiguration', '{"page": {"title": "Parallels Account"}, "form": {"attributes": {"action": "https://www.parallels.com/account/", "method": "post"}, "inputs": [{"type": "text", "name": "Email", "value": ""}, {"type": "password", "name": "Password", "value": ""}]}, "version": "0.2.3"}');
299 307
300 deferredResult.addMethod(user, 'revertChanges'); 308 deferredResult.addMethod(user, 'revertChanges');
301//deferredResult.addCallback(function () { console.log("###################################"); }); 309//deferredResult.addCallback(function () { console.log("###################################"); });
302 deferredResult.addMethod(user, 'hasPendingChanges'); 310 deferredResult.addMethod(user, 'hasPendingChanges');
303 deferredResult.addTest(false, "after reverting the changes, the user should NOT have pending changes"); 311 deferredResult.addTest(false, "after reverting the changes, the user should NOT have pending changes");
304 312
305 deferredResult.getValue('record'); 313 deferredResult.getValue('record');
306 deferredResult.addMethodcaller('hasPendingChanges'); 314 deferredResult.addMethodcaller('hasPendingChanges');
307 deferredResult.addTest(false, "after reverting the changes, the record should NOT have pending changes"); 315 deferredResult.addTest(false, "after reverting the changes, the record should NOT have pending changes");
308 316
309 deferredResult.addMethod(user2, 'login'); 317 deferredResult.addMethod(user2, 'login');
310 318
311 deferredResult.addMethod(user2, 'getRecord', recordID); 319 deferredResult.addMethod(user2, 'getRecord', recordID);
312 deferredResult.setValue('record_2'); 320 deferredResult.setValue('record_2');
313 deferredResult.addMethodcaller('directLogins'); 321 deferredResult.addMethodcaller('directLogins');
314 deferredResult.addCallback(MochiKit.Base.keys); 322 deferredResult.addCallback(MochiKit.Base.keys);
315 deferredResult.addCallback(MochiKit.Base.itemgetter('length')); 323 deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
316 deferredResult.addTest(4, "the record, when reloaded from scratch, has still 4 direct logins"); 324 deferredResult.addTest(4, "the record, when reloaded from scratch, has still 4 direct logins");
317 325
318 deferredResult.callback(); 326 deferredResult.callback();
319 327
320 return deferredResult; 328 return deferredResult;
321 }, 329 },
322 330
323 //------------------------------------------------------------------------- 331 //-------------------------------------------------------------------------
324 332
325 'addDirectLoginAndSaveChanges': function (someTestArgs) { 333 'addDirectLoginAndSaveChanges': function (someTestArgs) {
326 var deferredResult; 334 var deferredResult;
327 var proxy; 335 var proxy;
328 var user, user2; 336 var user, user2;
329 var recordID = 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d'; //YAHOO (4) 337 var recordID = 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d'; //YAHOO (4)
330 var directLoginReference; 338 var directLoginReference;
331 339
332 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:false, isDefault:true, readOnly:false}); 340 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:false, isDefault:true, readOnly:false});
333 user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}}); 341 user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
334 user2 = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}}); 342 user2 = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
335 343
336 deferredResult = new Clipperz.Async.Deferred("Record.test.addDirectLoginAndSaveChanges", someTestArgs); 344 deferredResult = new Clipperz.Async.Deferred("Record.test.addDirectLoginAndSaveChanges", someTestArgs);
337 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']); 345 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
338 deferredResult.addMethod(user, 'login'); 346 deferredResult.addMethod(user, 'login');
339 347
340 deferredResult.addMethod(user, 'getRecord', recordID); 348 deferredResult.addMethod(user, 'getRecord', recordID);
341 deferredResult.addMethodcaller('hasAnyCleanTextData'); 349 deferredResult.addMethodcaller('hasAnyCleanTextData');
342 deferredResult.addTest(false, "When first loaded, the record has no clean text data [2]"); 350 deferredResult.addTest(false, "When first loaded, the record has no clean text data [2]");
343 351
344 deferredResult.addMethod(user, 'getRecord', recordID); 352 deferredResult.addMethod(user, 'getRecord', recordID);
345 deferredResult.setValue('record'); 353 deferredResult.setValue('record');
346 deferredResult.addMethodcaller('directLogins'); 354 deferredResult.addMethodcaller('directLogins');
347 deferredResult.addCallback(MochiKit.Base.keys); 355 deferredResult.addCallback(MochiKit.Base.keys);
348 deferredResult.addCallback(MochiKit.Base.itemgetter('length')); 356 deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
349 deferredResult.addTest(4, "the selected record has 4 direct logins"); 357 deferredResult.addTest(4, "the selected record has 4 direct logins");
350 358
351 deferredResult.addMethod(user, 'getRecord', recordID); 359 deferredResult.addMethod(user, 'getRecord', recordID);
352 deferredResult.addMethodcaller('hasAnyCleanTextData'); 360 deferredResult.addMethodcaller('hasAnyCleanTextData');
353 deferredResult.addTest(false, "Still no clean text data is stored on the record, as all accessed data are stored on the index"); 361 deferredResult.addTest(false, "Still no clean text data is stored on the record, as all accessed data are stored on the index");
354 362
355 deferredResult.addMethod(user, 'hasAnyCleanTextData'); 363 deferredResult.addMethod(user, 'hasAnyCleanTextData');
356 deferredResult.addTest(true, "the user has some clean text data"); 364 deferredResult.addTest(true, "the user has some clean text data");
357 365
358 deferredResult.getValue('record'); 366 deferredResult.getValue('record');
359 deferredResult.addMethodcaller('createNewDirectLogin'); 367 deferredResult.addMethodcaller('createNewDirectLogin');
360 deferredResult.setValue('directLogin'); 368 deferredResult.setValue('directLogin');
361 369
362 deferredResult.getValue('directLogin'); 370 deferredResult.getValue('directLogin');
363 deferredResult.addMethodcaller('label'); 371 deferredResult.addMethodcaller('label');
364 deferredResult.addTest(null, "The label of a initially created direct login is empty"); 372 deferredResult.addTest(null, "The label of a initially created direct login is empty");
365 373
366 deferredResult.getValue('directLogin'); 374 deferredResult.getValue('directLogin');
367 deferredResult.addMethodcaller('bookmarkletConfiguration'); 375 deferredResult.addMethodcaller('bookmarkletConfiguration');
368 deferredResult.addTest('', "The bookmaraklet configuration of a initially created direct login is empty"); 376 deferredResult.addTest('', "The bookmaraklet configuration of a initially created direct login is empty");
369 377
370 deferredResult.getValue('directLogin'); 378 deferredResult.getValue('directLogin');
371 deferredResult.addMethodcaller('bindings'); 379 deferredResult.addMethodcaller('bindings');
372 deferredResult.addCallback(Clipperz.Async.Test.isDeeply({}, "The bindings of a initially created direct login is empty")); 380 deferredResult.addCallback(Clipperz.Async.Test.isDeeply({}, "The bindings of a initially created direct login is empty"));
373 381
374 deferredResult.getValue('directLogin'); 382 deferredResult.getValue('directLogin');
375 deferredResult.addMethodcaller('setLabel', "New direct login"); 383 deferredResult.addMethodcaller('setLabel', "New direct login");
376 384
377 deferredResult.getValue('directLogin'); 385 deferredResult.getValue('directLogin');
378 deferredResult.addMethodcaller('setBookmarkletConfiguration', directLoginConfigurations['Parallels']); 386 deferredResult.addMethodcaller('setBookmarkletConfiguration', directLoginConfigurations['Parallels']);
379 387
380 deferredResult.getValue('directLogin'); 388 deferredResult.getValue('directLogin');
381 deferredResult.addMethodcaller('bindings'); 389 deferredResult.addMethodcaller('bindings');
382 deferredResult.addCallback(MochiKit.Base.itemgetter('Email')); 390 deferredResult.addCallback(MochiKit.Base.itemgetter('Email'));
383 deferredResult.addMethodcaller('setFieldKey', '4cfaf1e782086e7527bd0e0cc82b67eb773e8157ad0c5babe516f7bc945a02a9'); //"userID" 391 deferredResult.addMethodcaller('setFieldKey', '4cfaf1e782086e7527bd0e0cc82b67eb773e8157ad0c5babe516f7bc945a02a9'); //"userID"
384 392
385 deferredResult.getValue('directLogin'); 393 deferredResult.getValue('directLogin');
386 deferredResult.addMethodcaller('bindings'); 394 deferredResult.addMethodcaller('bindings');
387 deferredResult.addCallback(MochiKit.Base.itemgetter('Password')); 395 deferredResult.addCallback(MochiKit.Base.itemgetter('Password'));
388 deferredResult.addMethodcaller('setFieldKey', 'ef2dee54322bf401540657d469e158a50e9228bc0a192a31d2e3ee56a77e565b'); //"password" 396 deferredResult.addMethodcaller('setFieldKey', 'ef2dee54322bf401540657d469e158a50e9228bc0a192a31d2e3ee56a77e565b'); //"password"
389 397
390 deferredResult.getValue('directLogin'); 398 deferredResult.getValue('directLogin');
391 deferredResult.addMethodcaller('favicon'), 399 deferredResult.addMethodcaller('favicon'),
392 deferredResult.addTest('http://www.parallels.com/favicon.ico', "the original favicon is the expected one"), 400 deferredResult.addTest('http://www.parallels.com/favicon.ico', "the original favicon is the expected one"),
393 401
394 deferredResult.getValue('directLogin'); 402 deferredResult.getValue('directLogin');
395 deferredResult.addMethodcaller('reference'); 403 deferredResult.addMethodcaller('reference');
396 deferredResult.addCallback(function (aReference) { 404 deferredResult.addCallback(function (aReference) {
397 directLoginReference = aReference; 405 directLoginReference = aReference;
398 }); 406 });
399 407
400 deferredResult.addMethod(user, 'hasPendingChanges'); 408 deferredResult.addMethod(user, 'hasPendingChanges');
401 deferredResult.addTest(true, "after adding a new direct login, the user should have pending changes"); 409 deferredResult.addTest(true, "after adding a new direct login, the user should have pending changes");
402 410
403 deferredResult.getValue('record'); 411 deferredResult.getValue('record');
404 deferredResult.addMethodcaller('hasPendingChanges'); 412 deferredResult.addMethodcaller('hasPendingChanges');
405 deferredResult.addTest(true, "after adding a new direct login, the record should have pending changes"); 413 deferredResult.addTest(true, "after adding a new direct login, the record should have pending changes");
406 414
407 deferredResult.getValue('record'); 415 deferredResult.getValue('record');
408 deferredResult.addMethodcaller('directLogins'); 416 deferredResult.addMethodcaller('directLogins');
409 deferredResult.addCallback(MochiKit.Base.keys); 417 deferredResult.addCallback(MochiKit.Base.keys);
410 deferredResult.addCallback(MochiKit.Base.itemgetter('length')); 418 deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
411 deferredResult.addTest(5, "after adding a new direct login, the record has now 5 direct logins"); 419 deferredResult.addTest(5, "after adding a new direct login, the record has now 5 direct logins");
412 420
413 421
414 deferredResult.addMethod(user, 'saveChanges'); 422 deferredResult.addMethod(user, 'saveChanges');
415 deferredResult.addMethod(user, 'hasPendingChanges'); 423 deferredResult.addMethod(user, 'hasPendingChanges');
416 deferredResult.addTest(false, "after saving the changes, the user should NOT have pending changes"); 424 deferredResult.addTest(false, "after saving the changes, the user should NOT have pending changes");
417 425
418 426
419 deferredResult.addMethod(user2, 'login'); 427 deferredResult.addMethod(user2, 'login');
420 428
421 deferredResult.addMethod(user2, 'getRecord', recordID); 429 deferredResult.addMethod(user2, 'getRecord', recordID);
422 deferredResult.setValue('record_2'); 430 deferredResult.setValue('record_2');
423 deferredResult.addMethodcaller('directLogins'); 431 deferredResult.addMethodcaller('directLogins');
424 deferredResult.addCallback(MochiKit.Base.keys); 432 deferredResult.addCallback(MochiKit.Base.keys);
425 deferredResult.addCallback(MochiKit.Base.itemgetter('length')); 433 deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
426 deferredResult.addTest(5, "the record, when reloaded from scratch, has still 5 direct logins"); 434 deferredResult.addTest(5, "the record, when reloaded from scratch, has still 5 direct logins");
427 435
428 deferredResult.getValue('record_2'); 436 deferredResult.getValue('record_2');
429 deferredResult.addMethodcaller('directLogins'); 437 deferredResult.addMethodcaller('directLogins');
430 deferredResult.addCallback(MochiKit.Base.values); 438 deferredResult.addCallback(MochiKit.Base.values);
431 deferredResult.addCallback(MochiKit.Base.itemgetter('4')); //TODO: accessing directLogins by index is not really nice 439 deferredResult.addCallback(MochiKit.Base.itemgetter('4')); //TODO: accessing directLogins by index is not really nice
432 deferredResult.setValue('directLogin_2'); 440 deferredResult.setValue('directLogin_2');
433 deferredResult.addMethodcaller('label'); 441 deferredResult.addMethodcaller('label');
434 deferredResult.addTest('New direct login', "The label of the direct login has been correctly saved"); 442 deferredResult.addTest('New direct login', "The label of the direct login has been correctly saved");
435 443
436 deferredResult.getValue('directLogin_2'); 444 deferredResult.getValue('directLogin_2');
437 deferredResult.addMethodcaller('bindings'); 445 deferredResult.addMethodcaller('bindings');
438 deferredResult.addCallback(MochiKit.Base.itemgetter('Email')); 446 deferredResult.addCallback(MochiKit.Base.itemgetter('Email'));
439 deferredResult.addMethodcaller('field'); 447 deferredResult.addMethodcaller('field');
440 deferredResult.addMethodcaller('value'); 448 deferredResult.addMethodcaller('value');
441 deferredResult.addTest('joe.clipperz', "The value bound to the direct login 'Email' field is correct"); 449 deferredResult.addTest('joe.clipperz', "The value bound to the direct login 'Email' field is correct");
442 450
443 deferredResult.getValue('directLogin_2'); 451 deferredResult.getValue('directLogin_2');
444 deferredResult.addMethodcaller('bindings'); 452 deferredResult.addMethodcaller('bindings');
445 deferredResult.addCallback(MochiKit.Base.itemgetter('Password')); 453 deferredResult.addCallback(MochiKit.Base.itemgetter('Password'));
446 deferredResult.addMethodcaller('field'); 454 deferredResult.addMethodcaller('field');
447 deferredResult.addMethodcaller('value'); 455 deferredResult.addMethodcaller('value');
448 deferredResult.addTest('enfvDG1RxAsl', "The value bound to the direct login 'Password' field is correct"); 456 deferredResult.addTest('enfvDG1RxAsl', "The value bound to the direct login 'Password' field is correct");
449 457
450 deferredResult.callback(); 458 deferredResult.callback();
451 459
452 return deferredResult; 460 return deferredResult;
453 }, 461 },
454 462
455 //------------------------------------------------------------------------- 463 //-------------------------------------------------------------------------
456 464
457 'readDirectLoginAttributes': function (someTestArgs) { 465 'readDirectLoginAttributes': function (someTestArgs) {
458 var deferredResult; 466 var deferredResult;
459 var proxy; 467 var proxy;
460 var user; 468 var user;
461 469
462 var recordID = '2977aa5f99a9f6e5596c1bd7871e82d7328c3716c9ef8ba349ae65f10d97924e'; 470 var recordID = '2977aa5f99a9f6e5596c1bd7871e82d7328c3716c9ef8ba349ae65f10d97924e';
463 var directLoginID ='03251dc1cbc5398789e4c4b45c52cfac3fcd8c1a4f19a81fa68fc6feae31d55c'; 471 var directLoginID ='03251dc1cbc5398789e4c4b45c52cfac3fcd8c1a4f19a81fa68fc6feae31d55c';
464 472
465 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:false, isDefault:true, readOnly:false}); 473 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:false, isDefault:true, readOnly:false});
466 user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}}); 474 user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
467 475
468 deferredResult = new Clipperz.Async.Deferred("Record.test.readDirectLoginAttributes", someTestArgs); 476 deferredResult = new Clipperz.Async.Deferred("Record.test.readDirectLoginAttributes", someTestArgs);
469 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_with_multipleRecordVersions_data']); 477 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_with_multipleRecordVersions_data']);
470 deferredResult.addMethod(user, 'login'); 478 deferredResult.addMethod(user, 'login');
471 479
472 deferredResult.addMethod(user, 'getRecord', recordID); 480 deferredResult.addMethod(user, 'getRecord', recordID);
473 deferredResult.addMethodcaller('directLogins'); 481 deferredResult.addMethodcaller('directLogins');
474 deferredResult.addCallback(MochiKit.Base.itemgetter('03251dc1cbc5398789e4c4b45c52cfac3fcd8c1a4f19a81fa68fc6feae31d55c')); 482 deferredResult.addCallback(MochiKit.Base.itemgetter('03251dc1cbc5398789e4c4b45c52cfac3fcd8c1a4f19a81fa68fc6feae31d55c'));
475 deferredResult.setValue('directLogin'); 483 deferredResult.setValue('directLogin');
476 484
477 deferredResult.getValue('directLogin'); 485 deferredResult.getValue('directLogin');
478 deferredResult.addMethodcaller('inputs'); 486 deferredResult.addMethodcaller('inputs');
479 deferredResult.addCallback(MochiKit.Base.keys); 487 deferredResult.addCallback(MochiKit.Base.keys);
480 deferredResult.addCallback(MochiKit.Base.itemgetter('length')); 488 deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
481 deferredResult.addTest(13, "Amazon direct login has 13 inputs"); 489 deferredResult.addTest(13, "Amazon direct login has 13 inputs");
482 490
483 deferredResult.getValue('directLogin'); 491 deferredResult.getValue('directLogin');
484 deferredResult.addMethodcaller('inputs'); 492 deferredResult.addMethodcaller('inputs');
485 deferredResult.addCallback(MochiKit.Base.values); 493 deferredResult.addCallback(MochiKit.Base.values);
486 deferredResult.addCallback(MochiKit.Base.filter, MochiKit.Base.methodcaller('needsFormValue')); 494 deferredResult.addCallback(MochiKit.Base.filter, MochiKit.Base.methodcaller('needsFormValue'));
487 deferredResult.addCallback(MochiKit.Base.itemgetter('length')); 495 deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
488 deferredResult.addTest(1, "Amazon direct login has 1 field needing a form value"); 496 deferredResult.addTest(1, "Amazon direct login has 1 field needing a form value");
489 497
490 deferredResult.getValue('directLogin'); 498 deferredResult.getValue('directLogin');
491 deferredResult.addMethodcaller('inputs'); 499 deferredResult.addMethodcaller('inputs');
492 deferredResult.addCallback(MochiKit.Base.values); 500 deferredResult.addCallback(MochiKit.Base.values);
493 deferredResult.addCallback(MochiKit.Base.filter, MochiKit.Base.methodcaller('needsBinding')); 501 deferredResult.addCallback(MochiKit.Base.filter, MochiKit.Base.methodcaller('needsBinding'));
494 deferredResult.addCallback(MochiKit.Base.itemgetter('length')); 502 deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
495 deferredResult.addTest(2, "Amazon direct login has 2 field needing a binding"); 503 deferredResult.addTest(2, "Amazon direct login has 2 field needing a binding");
496 504
497 505
498 deferredResult.getValue('directLogin'); 506 deferredResult.getValue('directLogin');
499 deferredResult.addMethodcaller('bindings'); 507 deferredResult.addMethodcaller('bindings');
500 deferredResult.addCallback(MochiKit.Base.keys); 508 deferredResult.addCallback(MochiKit.Base.keys);
501 deferredResult.addCallback(MochiKit.Base.itemgetter('length')); 509 deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
502 deferredResult.addTest(2, "Amazon direct login has just two bindings"); 510 deferredResult.addTest(2, "Amazon direct login has just two bindings");
503 511
504 deferredResult.getValue('directLogin'); 512 deferredResult.getValue('directLogin');
505 deferredResult.addMethodcaller('bindings'); 513 deferredResult.addMethodcaller('bindings');
506 deferredResult.addCallback(MochiKit.Base.itemgetter('email')); 514 deferredResult.addCallback(MochiKit.Base.itemgetter('email'));
507 deferredResult.addMethodcaller('fieldKey'); 515 deferredResult.addMethodcaller('fieldKey');
508 deferredResult.addTest('5e822c34aaf1a9fbc0b52585c1915f3a3758abd51923a4d35ae85373bbb839c2', "Amazon direct login 'email' binding points to the correct field"); 516 deferredResult.addTest('5e822c34aaf1a9fbc0b52585c1915f3a3758abd51923a4d35ae85373bbb839c2', "Amazon direct login 'email' binding points to the correct field");
509 517
510 deferredResult.getValue('directLogin'); 518 deferredResult.getValue('directLogin');
511 deferredResult.addMethodcaller('bindings'); 519 deferredResult.addMethodcaller('bindings');
512 deferredResult.addCallback(MochiKit.Base.itemgetter('password')); 520 deferredResult.addCallback(MochiKit.Base.itemgetter('password'));
513 deferredResult.setValue('passwordBinding'); 521 deferredResult.setValue('passwordBinding');
514 deferredResult.addMethodcaller('fieldKey'); 522 deferredResult.addMethodcaller('fieldKey');
515 deferredResult.addTest('01e4bb6dcf054f312c535de8160bcf50bdccd664bdc05721b10d4e69583765f7', "Amazon direct login 'password' binding points to the correct field"); 523 deferredResult.addTest('01e4bb6dcf054f312c535de8160bcf50bdccd664bdc05721b10d4e69583765f7', "Amazon direct login 'password' binding points to the correct field");
516 524
517 deferredResult.getValue('passwordBinding'); 525 deferredResult.getValue('passwordBinding');
518 deferredResult.addMethodcaller('field'); 526 deferredResult.addMethodcaller('field');
519 deferredResult.addMethodcaller('label'); 527 deferredResult.addMethodcaller('label');
520 deferredResult.addTest('password', "Amazon direct login 'password' binding points to the 'password' field"); 528 deferredResult.addTest('password', "Amazon direct login 'password' binding points to the 'password' field");
521 529
522 530
523 deferredResult.getValue('directLogin'); 531 deferredResult.getValue('directLogin');
524 deferredResult.addMethodcaller('formValues'); 532 deferredResult.addMethodcaller('formValues');
525 deferredResult.addCallback(MochiKit.Base.keys); 533 deferredResult.addCallback(MochiKit.Base.keys);
526 deferredResult.addCallback(MochiKit.Base.itemgetter('length')); 534 deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
527 deferredResult.addTest(1, "Amazon direct login has just one formValue"); 535 deferredResult.addTest(1, "Amazon direct login has just one formValue");
528 536
529 deferredResult.getValue('directLogin'); 537 deferredResult.getValue('directLogin');
530 deferredResult.addMethodcaller('formValues'); 538 deferredResult.addMethodcaller('formValues');
531 deferredResult.addCallback(MochiKit.Base.itemgetter('action')); 539 deferredResult.addCallback(MochiKit.Base.itemgetter('action'));
532 deferredResult.addMethodcaller('value'); 540 deferredResult.addMethodcaller('value');
533 deferredResult.addTest('sign-in', "Amazon direct 'action' formValue is set to 'sign-in'"); 541 deferredResult.addTest('sign-in', "Amazon direct 'action' formValue is set to 'sign-in'");
534 542
535 543
536 deferredResult.callback(); 544 deferredResult.callback();
537 545
538 return deferredResult; 546 return deferredResult;
539 }, 547 },
540 548
541 //------------------------------------------------------------------------- 549 //-------------------------------------------------------------------------
542 550
543 'editDirectLoginLabel': function (someTestArgs) { 551 'editDirectLoginLabel': function (someTestArgs) {
544 var deferredResult; 552 var deferredResult;
545 var proxy; 553 var proxy;
546 var user; 554 var user;
547 var oldLabel; 555 var oldLabel;
548 var newLabel; 556 var newLabel;
549 557
550 var recordID = 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d'; 558 var recordID = 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d';
551 var directLoginID ='dba0db679802f0e6aa6d0b7a6aaf42350aabc5f057409edd99a268a92ebb6496'; 559 var directLoginID ='dba0db679802f0e6aa6d0b7a6aaf42350aabc5f057409edd99a268a92ebb6496';
552 560
553 oldLabel = "Yahoo! Mail"; 561 oldLabel = "Yahoo! Mail";
554 newLabel = "YAHOO! Mail"; 562 newLabel = "YAHOO! Mail";
555 563
556 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:false, isDefault:true, readOnly:false}); 564 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:false, isDefault:true, readOnly:false});
557 user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}}); 565 user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
558 566
559 deferredResult = new Clipperz.Async.Deferred("Record.test.editDirectLoginLabel", someTestArgs); 567 deferredResult = new Clipperz.Async.Deferred("Record.test.editDirectLoginLabel", someTestArgs);
560 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']); 568 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
561 deferredResult.addMethod(user, 'login'); 569 deferredResult.addMethod(user, 'login');
562 570
563 deferredResult.addMethod(user, 'getRecord', recordID); 571 deferredResult.addMethod(user, 'getRecord', recordID);
564 deferredResult.addMethodcaller('directLogins'); 572 deferredResult.addMethodcaller('directLogins');
565 deferredResult.addCallback(MochiKit.Base.itemgetter(directLoginID)); 573 deferredResult.addCallback(MochiKit.Base.itemgetter(directLoginID));
566 deferredResult.addMethodcaller('label'); 574 deferredResult.addMethodcaller('label');
567 deferredResult.addTest(oldLabel, "the current label of the direct login"); 575 deferredResult.addTest(oldLabel, "the current label of the direct login");
568 576
569 deferredResult.addMethod(user, 'getRecord', recordID); 577 deferredResult.addMethod(user, 'getRecord', recordID);
570 deferredResult.addMethodcaller('directLogins'); 578 deferredResult.addMethodcaller('directLogins');
571 deferredResult.addCallback(MochiKit.Base.itemgetter(directLoginID)); 579 deferredResult.addCallback(MochiKit.Base.itemgetter(directLoginID));
572 deferredResult.addMethodcaller('setLabel', newLabel); 580 deferredResult.addMethodcaller('setLabel', newLabel);
573 581
574 deferredResult.addMethod(user, 'hasPendingChanges'); 582 deferredResult.addMethod(user, 'hasPendingChanges');
575 deferredResult.addTest(true, "changing the label of a direct login should trigger some changes"); 583 deferredResult.addTest(true, "changing the label of a direct login should trigger some changes");
576 584
577 deferredResult.addMethod(user, 'getRecord', recordID); 585 deferredResult.addMethod(user, 'getRecord', recordID);
578 deferredResult.addMethodcaller('hasPendingChanges'); 586 deferredResult.addMethodcaller('hasPendingChanges');
579 deferredResult.addTest(true, "changing the label of a direct login should trigger some changes also on the record itself"); 587 deferredResult.addTest(true, "changing the label of a direct login should trigger some changes also on the record itself");
580 588
581 deferredResult.addMethod(user, 'getRecord', recordID); 589 deferredResult.addMethod(user, 'getRecord', recordID);
582 deferredResult.addMethodcaller('directLogins'); 590 deferredResult.addMethodcaller('directLogins');
583 deferredResult.addCallback(MochiKit.Base.itemgetter(directLoginID)); 591 deferredResult.addCallback(MochiKit.Base.itemgetter(directLoginID));
584 deferredResult.addMethodcaller('hasPendingChanges'); 592 deferredResult.addMethodcaller('hasPendingChanges');
585 deferredResult.addTest(true, "changing the label of a direct login should trigger some changes also on the directLogin itself"); 593 deferredResult.addTest(true, "changing the label of a direct login should trigger some changes also on the directLogin itself");
586 594
587 deferredResult.callback(); 595 deferredResult.callback();
588 596
589 return deferredResult; 597 return deferredResult;
590 }, 598 },
591 599
592 //------------------------------------------------------------------------- 600 //-------------------------------------------------------------------------
593 601
594 'editDirectLoginFormValueAndRestoreChanges': function (someTestArgs) { 602 'editDirectLoginFormValueAndRestoreChanges': function (someTestArgs) {
595 var deferredResult; 603 var deferredResult;
596 var proxy; 604 var proxy;
597 var user; 605 var user;
598 606
599 var recordID = 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d'; 607 var recordID = 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d';
600 var directLoginID ='dba0db679802f0e6aa6d0b7a6aaf42350aabc5f057409edd99a268a92ebb6496'; 608 var directLoginID ='dba0db679802f0e6aa6d0b7a6aaf42350aabc5f057409edd99a268a92ebb6496';
601 609
602 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:false, isDefault:true, readOnly:false}); 610 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:false, isDefault:true, readOnly:false});
603 user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}}); 611 user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
604 612
605 deferredResult = new Clipperz.Async.Deferred("Record.test.editDirectLoginFormValueAndRestoreChanges", someTestArgs); 613 deferredResult = new Clipperz.Async.Deferred("Record.test.editDirectLoginFormValueAndRestoreChanges", someTestArgs);
606 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']); 614 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
607 deferredResult.addMethod(user, 'login'); 615 deferredResult.addMethod(user, 'login');
608 616
609 deferredResult.addMethod(user, 'getRecord', recordID); 617 deferredResult.addMethod(user, 'getRecord', recordID);
610 deferredResult.addMethodcaller('directLogins'); 618 deferredResult.addMethodcaller('directLogins');
611 deferredResult.addCallback(MochiKit.Base.itemgetter(directLoginID)); 619 deferredResult.addCallback(MochiKit.Base.itemgetter(directLoginID));
612 deferredResult.setValue('directLogin'); 620 deferredResult.setValue('directLogin');
613 deferredResult.addMethodcaller('formValues'); 621 deferredResult.addMethodcaller('formValues');
614 deferredResult.addCallback(MochiKit.Base.itemgetter('.persistent')); 622 deferredResult.addCallback(MochiKit.Base.itemgetter('.persistent'));
615 deferredResult.addMethodcaller('value'); 623 deferredResult.addMethodcaller('value');
616 deferredResult.addTest(null, "original formValue value matches"); 624 deferredResult.addTest(null, "original formValue value matches");
617 625
618 deferredResult.getValue('directLogin'); 626 deferredResult.getValue('directLogin');
619 deferredResult.addMethodcaller('formValues'); 627 deferredResult.addMethodcaller('formValues');
620 deferredResult.addCallback(MochiKit.Base.itemgetter('.persistent')) 628 deferredResult.addCallback(MochiKit.Base.itemgetter('.persistent'))
621 deferredResult.addMethodcaller('setValue', 'y'); 629 deferredResult.addMethodcaller('setValue', 'y');
622 630
623 deferredResult.getValue('directLogin'); 631 deferredResult.getValue('directLogin');
624 deferredResult.addMethodcaller('formValues'); 632 deferredResult.addMethodcaller('formValues');
625 deferredResult.addCallback(MochiKit.Base.itemgetter('.persistent')) 633 deferredResult.addCallback(MochiKit.Base.itemgetter('.persistent'))
626 deferredResult.addMethodcaller('value'); 634 deferredResult.addMethodcaller('value');
627 deferredResult.addTest('y', "the newly set value is retained"); 635 deferredResult.addTest('y', "the newly set value is retained");
628 636
629 637
630 deferredResult.addMethod(user, 'hasPendingChanges'); 638 deferredResult.addMethod(user, 'hasPendingChanges');
631 deferredResult.addTest(true, "changing the label of a direct login should trigger some changes"); 639 deferredResult.addTest(true, "changing the label of a direct login should trigger some changes");
632 640
633 deferredResult.addMethod(user, 'getRecord', recordID); 641 deferredResult.addMethod(user, 'getRecord', recordID);
634 deferredResult.addMethodcaller('hasPendingChanges'); 642 deferredResult.addMethodcaller('hasPendingChanges');
635 deferredResult.addTest(true, "changing the label of a direct login should trigger some changes also on the record itself"); 643 deferredResult.addTest(true, "changing the label of a direct login should trigger some changes also on the record itself");
636 644
637 deferredResult.addMethod(user, 'getRecord', recordID); 645 deferredResult.addMethod(user, 'getRecord', recordID);
638 deferredResult.addMethodcaller('directLogins'); 646 deferredResult.addMethodcaller('directLogins');
639 deferredResult.addCallback(MochiKit.Base.itemgetter(directLoginID)); 647 deferredResult.addCallback(MochiKit.Base.itemgetter(directLoginID));
640 deferredResult.addMethodcaller('hasPendingChanges'); 648 deferredResult.addMethodcaller('hasPendingChanges');
641 deferredResult.addTest(true, "changing the label of a direct login should trigger some changes also on the directLogin itself"); 649 deferredResult.addTest(true, "changing the label of a direct login should trigger some changes also on the directLogin itself");
642 650
643 deferredResult.addMethod(user, 'revertChanges'); 651 deferredResult.addMethod(user, 'revertChanges');
644 652
645 deferredResult.getValue('directLogin'); 653 deferredResult.getValue('directLogin');
646 deferredResult.addMethodcaller('formValues'); 654 deferredResult.addMethodcaller('formValues');
647 deferredResult.addCallback(MochiKit.Base.itemgetter('.persistent')) 655 deferredResult.addCallback(MochiKit.Base.itemgetter('.persistent'))
648 deferredResult.addMethodcaller('value'); 656 deferredResult.addMethodcaller('value');
649 deferredResult.addTest(null, "the old formValue value is correctly restored"); 657 deferredResult.addTest(null, "the old formValue value is correctly restored");
650 658
651 deferredResult.callback(); 659 deferredResult.callback();
652 660
653 return deferredResult; 661 return deferredResult;
654 }, 662 },
655 663
656 //------------------------------------------------------------------------- 664 //-------------------------------------------------------------------------
657 665
658 'editDirectLoginConfigurationAndRevertChanges': function (someTestArgs) { 666 'editDirectLoginConfigurationAndRevertChanges': function (someTestArgs) {
659 var deferredResult; 667 var deferredResult;
660 var proxy; 668 var proxy;
661 var user; 669 var user;
662 670
663 var recordID = 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d'; 671 var recordID = 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d';
664 var directLoginID ='dba0db679802f0e6aa6d0b7a6aaf42350aabc5f057409edd99a268a92ebb6496'; 672 var directLoginID ='dba0db679802f0e6aa6d0b7a6aaf42350aabc5f057409edd99a268a92ebb6496';
665 673
666 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:false, isDefault:true, readOnly:false}); 674 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:false, isDefault:true, readOnly:false});
667 user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}}); 675 user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
668 676
669 deferredResult = new Clipperz.Async.Deferred("Record.test.editDirectLoginConfigurationAndRevertChanges", someTestArgs); 677 deferredResult = new Clipperz.Async.Deferred("Record.test.editDirectLoginConfigurationAndRevertChanges", someTestArgs);
670 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']); 678 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
671 deferredResult.addMethod(user, 'login'); 679 deferredResult.addMethod(user, 'login');
672 680
673 deferredResult.addMethod(user, 'getRecord', recordID); 681 deferredResult.addMethod(user, 'getRecord', recordID);
674 deferredResult.addMethodcaller('directLogins'); 682 deferredResult.addMethodcaller('directLogins');
675 deferredResult.addCallback(MochiKit.Base.itemgetter(directLoginID)); 683 deferredResult.addCallback(MochiKit.Base.itemgetter(directLoginID));
676 684
677 deferredResult.addCallback(function (aDirectLogin) { 685 deferredResult.addCallback(function (aDirectLogin) {
678 // var newBookmarkletConfiguration; 686 // var newBookmarkletConfiguration;
679 687
680 // newBookmarkletConfiguration = '{\n \"page\": {\n \"title\": \"Yahoo! Mail\"\n },\n \"form\": {\n \"attributes\": {\n \"action\": \"https://login.yahoo.com/config/login?\",\n \"method\": \"post\"\n },\n \"inputs\": [\n {\n \"type\": \"text\",\n \"name\": \"login\",\n \"value\": \"\"\n },\n {\n \"type\": \"password\",\n \"name\": \"passwd\",\n \"value\": \"\"\n },\n {\n \"type\": \"checkbox\",\n \"name\": \".persistent\",\n \"value\": \"y\"\n }\n ]\n },\n \"version\": \"0.2\"\n}'; 688 // newBookmarkletConfiguration = '{\n \"page\": {\n \"title\": \"Yahoo! Mail\"\n },\n \"form\": {\n \"attributes\": {\n \"action\": \"https://login.yahoo.com/config/login?\",\n \"method\": \"post\"\n },\n \"inputs\": [\n {\n \"type\": \"text\",\n \"name\": \"login\",\n \"value\": \"\"\n },\n {\n \"type\": \"password\",\n \"name\": \"passwd\",\n \"value\": \"\"\n },\n {\n \"type\": \"checkbox\",\n \"name\": \".persistent\",\n \"value\": \"y\"\n }\n ]\n },\n \"version\": \"0.2\"\n}';
681 return Clipperz.Async.callbacks("Record.test.editDirectLoginConfiguration [inner call]", [ 689 return Clipperz.Async.callbacks("Record.test.editDirectLoginConfiguration [inner call]", [
682 MochiKit.Base.method(aDirectLogin, 'bookmarkletConfiguration'), 690 MochiKit.Base.method(aDirectLogin, 'bookmarkletConfiguration'),
683 Clipperz.Async.Test.is(directLoginConfigurations['Yahoo! Mail'], "the current bookmarkletConfiguration"), 691 Clipperz.Async.Test.is(directLoginConfigurations['Yahoo! Mail'], "the current bookmarkletConfiguration"),
684 692
685 MochiKit.Base.method(aDirectLogin, 'favicon'), 693 MochiKit.Base.method(aDirectLogin, 'favicon'),
686 Clipperz.Async.Test.is('http://login.yahoo.com/favicon.ico', "the original favicon is the expected one"), 694 Clipperz.Async.Test.is('http://login.yahoo.com/favicon.ico', "the original favicon is the expected one"),
687 695
688 MochiKit.Base.method(aDirectLogin, 'setBookmarkletConfiguration', directLoginConfigurations['Parallels']), 696 MochiKit.Base.method(aDirectLogin, 'setBookmarkletConfiguration', directLoginConfigurations['Parallels']),
689 697
690 MochiKit.Base.method(aDirectLogin, 'favicon'), 698 MochiKit.Base.method(aDirectLogin, 'favicon'),
691 Clipperz.Async.Test.is('http://login.yahoo.com/favicon.ico', "the original favicon is the expected one"), 699 Clipperz.Async.Test.is('http://login.yahoo.com/favicon.ico', "the original favicon is the expected one"),
692 700
693 MochiKit.Base.method(aDirectLogin, 'hasPendingChanges'), 701 MochiKit.Base.method(aDirectLogin, 'hasPendingChanges'),
694 Clipperz.Async.Test.ok("changing the configuration should trigger the pending changes on the direct login"), 702 Clipperz.Async.Test.ok("changing the configuration should trigger the pending changes on the direct login"),
695 MochiKit.Base.method(aDirectLogin.record(), 'hasPendingChanges'), 703 MochiKit.Base.method(aDirectLogin.record(), 'hasPendingChanges'),
696 Clipperz.Async.Test.ok("changing the configuration should trigger the pending changes also on the record"), 704 Clipperz.Async.Test.ok("changing the configuration should trigger the pending changes also on the record"),
697 MochiKit.Base.method(user, 'hasPendingChanges'), 705 MochiKit.Base.method(user, 'hasPendingChanges'),
698 Clipperz.Async.Test.ok("changing the configuration should trigger the pending changes also on the user"), 706 Clipperz.Async.Test.ok("changing the configuration should trigger the pending changes also on the user"),
699 707
700 MochiKit.Base.method(aDirectLogin, 'revertChanges'), 708 MochiKit.Base.method(aDirectLogin, 'revertChanges'),
701 709
702 MochiKit.Base.method(aDirectLogin, 'hasPendingChanges'), 710 MochiKit.Base.method(aDirectLogin, 'hasPendingChanges'),
703 Clipperz.Async.Test.fail("reverting changes should reset pending changes on the direct login"), 711 Clipperz.Async.Test.fail("reverting changes should reset pending changes on the direct login"),
704 MochiKit.Base.method(aDirectLogin.record(), 'hasPendingChanges'), 712 MochiKit.Base.method(aDirectLogin.record(), 'hasPendingChanges'),
705 Clipperz.Async.Test.fail("reverting changes should reset pending changes also on the record"), 713 Clipperz.Async.Test.fail("reverting changes should reset pending changes also on the record"),
706 MochiKit.Base.method(user, 'hasPendingChanges'), 714 MochiKit.Base.method(user, 'hasPendingChanges'),
707 Clipperz.Async.Test.fail("reverting changes should reset pending changes also on the user"), 715 Clipperz.Async.Test.fail("reverting changes should reset pending changes also on the user"),
708 716
709 MochiKit.Base.noop 717 MochiKit.Base.noop
710 ], someTestArgs); 718 ], someTestArgs);
711 }) 719 })
712 720
713 deferredResult.callback(); 721 deferredResult.callback();
714 722
715 return deferredResult; 723 return deferredResult;
716 }, 724 },
717 725
718 //------------------------------------------------------------------------- 726 //-------------------------------------------------------------------------
719 727
720 'editDirectLoginConfiguration_keepingTheSameStructure_AndSaveChanges': function (someTestArgs) { 728 'editDirectLoginConfiguration_keepingTheSameStructure_AndSaveChanges': function (someTestArgs) {
721 var deferredResult; 729 var deferredResult;
722 var proxy; 730 var proxy;
723 var user; 731 var user;
724 var user2; 732 var user2;
725 var newBookmarkletConfiguration; 733 var newBookmarkletConfiguration;
726 734
727 var recordID = 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d'; 735 var recordID = 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d';
728 var directLoginID ='dba0db679802f0e6aa6d0b7a6aaf42350aabc5f057409edd99a268a92ebb6496'; 736 var directLoginID ='dba0db679802f0e6aa6d0b7a6aaf42350aabc5f057409edd99a268a92ebb6496';
729 737
730 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:false, isDefault:true, readOnly:false}); 738 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:false, isDefault:true, readOnly:false});
731 user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}}); 739 user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
732 user2 = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}}); 740 user2 = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
733 741
734 newBookmarkletConfiguration = '{\n \"page\": {\n \"title\": \"Yahoo! Mail\"\n },\n \"form\": {\n \"attributes\": {\n \"action\": \"https://login.yahoo.com/config/login?\",\n \"method\": \"post\"\n },\n \"inputs\": [\n {\n \"type\": \"text\",\n \"name\": \"login\",\n \"value\": \"\"\n },\n {\n \"type\": \"password\",\n \"name\": \"passwd\",\n \"value\": \"\"\n },\n {\n \"type\": \"checkbox\",\n \"name\": \".persistent\",\n \"value\": \"y\"\n }\n ]\n },\n \"version\": \"0.2\"\n}'; 742 newBookmarkletConfiguration = '{\n \"page\": {\n \"title\": \"Yahoo! Mail\"\n },\n \"form\": {\n \"attributes\": {\n \"action\": \"https://login.yahoo.com/config/login?\",\n \"method\": \"post\"\n },\n \"inputs\": [\n {\n \"type\": \"text\",\n \"name\": \"login\",\n \"value\": \"\"\n },\n {\n \"type\": \"password\",\n \"name\": \"passwd\",\n \"value\": \"\"\n },\n {\n \"type\": \"checkbox\",\n \"name\": \".persistent\",\n \"value\": \"y\"\n }\n ]\n },\n \"version\": \"0.2\"\n}';
735 743
736 deferredResult = new Clipperz.Async.Deferred("Record.test.editDirectLoginConfiguration_keepingTheSameStructure_AndSaveChanges", someTestArgs); 744 deferredResult = new Clipperz.Async.Deferred("Record.test.editDirectLoginConfiguration_keepingTheSameStructure_AndSaveChanges", someTestArgs);
737 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']); 745 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
738 deferredResult.addMethod(user, 'login'); 746 deferredResult.addMethod(user, 'login');
739 747
740 deferredResult.addMethod(user, 'getRecord', recordID); 748 deferredResult.addMethod(user, 'getRecord', recordID);
741 deferredResult.addMethodcaller('directLogins'); 749 deferredResult.addMethodcaller('directLogins');
742 deferredResult.addCallback(MochiKit.Base.itemgetter(directLoginID)); 750 deferredResult.addCallback(MochiKit.Base.itemgetter(directLoginID));
743 deferredResult.addCallback(function (aDirectLogin) { 751 deferredResult.addCallback(function (aDirectLogin) {
744 return Clipperz.Async.callbacks("Record.test.editDirectLoginConfiguration_keepingTheSameStructure_AndSaveChanges [inner call 1]", [ 752 return Clipperz.Async.callbacks("Record.test.editDirectLoginConfiguration_keepingTheSameStructure_AndSaveChanges [inner call 1]", [
745 MochiKit.Base.method(aDirectLogin, 'bookmarkletConfiguration'), 753 MochiKit.Base.method(aDirectLogin, 'bookmarkletConfiguration'),
746 Clipperz.Async.Test.is(directLoginConfigurations['Yahoo! Mail'], "the current bookmarkletConfiguration (1)"), 754 Clipperz.Async.Test.is(directLoginConfigurations['Yahoo! Mail'], "the current bookmarkletConfiguration (1)"),
747 755
748 MochiKit.Base.method(aDirectLogin, 'inputs'), 756 MochiKit.Base.method(aDirectLogin, 'inputs'),
749 MochiKit.Base.keys, 757 MochiKit.Base.keys,
750 MochiKit.Base.itemgetter('length'), 758 MochiKit.Base.itemgetter('length'),
751 Clipperz.Async.Test.is(26, "The original direct login had 26 inputs"), 759 Clipperz.Async.Test.is(26, "The original direct login had 26 inputs"),
752 760
753 MochiKit.Base.method(aDirectLogin, 'bindings'), 761 MochiKit.Base.method(aDirectLogin, 'bindings'),
754 MochiKit.Base.keys, 762 MochiKit.Base.keys,
755 MochiKit.Base.itemgetter('length'), 763 MochiKit.Base.itemgetter('length'),
756 Clipperz.Async.Test.is(2, "The original direct login had 2 inputs"), 764 Clipperz.Async.Test.is(2, "The original direct login had 2 inputs"),
757 765
758 MochiKit.Base.method(aDirectLogin, 'bindings'), 766 MochiKit.Base.method(aDirectLogin, 'bindings'),
759 MochiKit.Base.itemgetter('login'), 767 MochiKit.Base.itemgetter('login'),
760 MochiKit.Base.methodcaller('field'), 768 MochiKit.Base.methodcaller('field'),
761 MochiKit.Base.methodcaller('reference'), 769 MochiKit.Base.methodcaller('reference'),
762 Clipperz.Async.Test.is('4cfaf1e782086e7527bd0e0cc82b67eb773e8157ad0c5babe516f7bc945a02a9', "the original 'login' direct login binding points to the correct field"), 770 Clipperz.Async.Test.is('4cfaf1e782086e7527bd0e0cc82b67eb773e8157ad0c5babe516f7bc945a02a9', "the original 'login' direct login binding points to the correct field"),
763 771
764 MochiKit.Base.method(aDirectLogin, 'formValues'), 772 MochiKit.Base.method(aDirectLogin, 'formValues'),
765 MochiKit.Base.keys, 773 MochiKit.Base.keys,
766 MochiKit.Base.itemgetter('length'), 774 MochiKit.Base.itemgetter('length'),
767 Clipperz.Async.Test.is(1, "The original direct login had 1 form values"), 775 Clipperz.Async.Test.is(1, "The original direct login had 1 form values"),
768 776
769 MochiKit.Base.method(aDirectLogin, 'formValues'), 777 MochiKit.Base.method(aDirectLogin, 'formValues'),
770 MochiKit.Base.itemgetter('.persistent'), 778 MochiKit.Base.itemgetter('.persistent'),
771 MochiKit.Base.methodcaller('type'), 779 MochiKit.Base.methodcaller('type'),
772 Clipperz.Async.Test.is('checkbox', "the original formValue has the expected type"), 780 Clipperz.Async.Test.is('checkbox', "the original formValue has the expected type"),
773 781
774 MochiKit.Base.method(aDirectLogin, 'formValues'), 782 MochiKit.Base.method(aDirectLogin, 'formValues'),
775 MochiKit.Base.itemgetter('.persistent'), 783 MochiKit.Base.itemgetter('.persistent'),
776 MochiKit.Base.methodcaller('value'), 784 MochiKit.Base.methodcaller('value'),
777 Clipperz.Async.Test.is(null, "the original formValue is correct (1)"), 785 Clipperz.Async.Test.is(null, "the original formValue is correct (1)"),
778 786
779 MochiKit.Base.method(aDirectLogin, 'formValues'), 787 MochiKit.Base.method(aDirectLogin, 'formValues'),
780 MochiKit.Base.itemgetter('.persistent'), 788 MochiKit.Base.itemgetter('.persistent'),
781 MochiKit.Base.methodcaller('setValue', 'y'), 789 MochiKit.Base.methodcaller('setValue', 'y'),
782 790
783 791
784 MochiKit.Base.method(aDirectLogin, 'setBookmarkletConfiguration', newBookmarkletConfiguration), 792 MochiKit.Base.method(aDirectLogin, 'setBookmarkletConfiguration', newBookmarkletConfiguration),
785 MochiKit.Base.method(user, 'saveChanges'), 793 MochiKit.Base.method(user, 'saveChanges'),
786 794
787 MochiKit.Base.method(aDirectLogin, 'bindings'), 795 MochiKit.Base.method(aDirectLogin, 'bindings'),
788 MochiKit.Base.itemgetter('login'), 796 MochiKit.Base.itemgetter('login'),
789 MochiKit.Base.methodcaller('field'), 797 MochiKit.Base.methodcaller('field'),
790 MochiKit.Base.methodcaller('reference'), 798 MochiKit.Base.methodcaller('reference'),
791 Clipperz.Async.Test.is('4cfaf1e782086e7527bd0e0cc82b67eb773e8157ad0c5babe516f7bc945a02a9', "the 'login' binding is still valid after the new configuration is set"), 799 Clipperz.Async.Test.is('4cfaf1e782086e7527bd0e0cc82b67eb773e8157ad0c5babe516f7bc945a02a9', "the 'login' binding is still valid after the new configuration is set"),
792 800
793 MochiKit.Base.method(aDirectLogin, 'hasPendingChanges'), 801 MochiKit.Base.method(aDirectLogin, 'hasPendingChanges'),
794 Clipperz.Async.Test.fail("reverting changes should reset pending changes on the direct login (2)"), 802 Clipperz.Async.Test.fail("reverting changes should reset pending changes on the direct login (2)"),
795 MochiKit.Base.method(aDirectLogin.record(), 'hasPendingChanges'), 803 MochiKit.Base.method(aDirectLogin.record(), 'hasPendingChanges'),
796 Clipperz.Async.Test.fail("reverting changes should reset pending changes also on the record (2)"), 804 Clipperz.Async.Test.fail("reverting changes should reset pending changes also on the record (2)"),
797 MochiKit.Base.method(user, 'hasPendingChanges'), 805 MochiKit.Base.method(user, 'hasPendingChanges'),
798 Clipperz.Async.Test.fail("reverting changes should reset pending changes also on the user (2)"), 806 Clipperz.Async.Test.fail("reverting changes should reset pending changes also on the user (2)"),
799 807
800 MochiKit.Base.noop 808 MochiKit.Base.noop
801 ], someTestArgs); 809 ], someTestArgs);
802 }) 810 })
803 811
804 deferredResult.addMethod(user2, 'login'); 812 deferredResult.addMethod(user2, 'login');
805 813
806 deferredResult.addMethod(user2, 'getRecord', recordID); 814 deferredResult.addMethod(user2, 'getRecord', recordID);
807 deferredResult.addMethodcaller('directLogins'); 815 deferredResult.addMethodcaller('directLogins');
808 deferredResult.addCallback(MochiKit.Base.itemgetter(directLoginID)); 816 deferredResult.addCallback(MochiKit.Base.itemgetter(directLoginID));
809 deferredResult.addCallback(function (aDirectLogin) { 817 deferredResult.addCallback(function (aDirectLogin) {
810 return Clipperz.Async.callbacks("Record.test.editDirectLoginConfiguration_keepingTheSameStructure_AndSaveChanges [inner call 2]", [ 818 return Clipperz.Async.callbacks("Record.test.editDirectLoginConfiguration_keepingTheSameStructure_AndSaveChanges [inner call 2]", [
811 MochiKit.Base.method(aDirectLogin, 'bookmarkletConfiguration'), 819 MochiKit.Base.method(aDirectLogin, 'bookmarkletConfiguration'),
812 Clipperz.Async.Test.is(newBookmarkletConfiguration, "the direct login has the new bookmarkletConfiguration even after being reloaded"), 820 Clipperz.Async.Test.is(newBookmarkletConfiguration, "the direct login has the new bookmarkletConfiguration even after being reloaded"),
813 821
814 MochiKit.Base.method(aDirectLogin, 'inputs'), 822 MochiKit.Base.method(aDirectLogin, 'inputs'),
815 MochiKit.Base.keys, 823 MochiKit.Base.keys,
816 MochiKit.Base.itemgetter('length'), 824 MochiKit.Base.itemgetter('length'),
817 Clipperz.Async.Test.is(3, "The new direct login has 3 inputs"), 825 Clipperz.Async.Test.is(3, "The new direct login has 3 inputs"),
818 826
819 MochiKit.Base.method(aDirectLogin, 'bindings'), 827 MochiKit.Base.method(aDirectLogin, 'bindings'),
820 MochiKit.Base.keys, 828 MochiKit.Base.keys,
821 MochiKit.Base.itemgetter('length'), 829 MochiKit.Base.itemgetter('length'),
822 Clipperz.Async.Test.is(2, "The new direct login had 2 inputs"), 830 Clipperz.Async.Test.is(2, "The new direct login had 2 inputs"),
823 831
824 MochiKit.Base.method(aDirectLogin, 'bindings'), 832 MochiKit.Base.method(aDirectLogin, 'bindings'),
825 MochiKit.Base.itemgetter('login'), 833 MochiKit.Base.itemgetter('login'),
826 MochiKit.Base.methodcaller('field'), 834 MochiKit.Base.methodcaller('field'),
827 MochiKit.Base.methodcaller('reference'), 835 MochiKit.Base.methodcaller('reference'),
828 Clipperz.Async.Test.is('4cfaf1e782086e7527bd0e0cc82b67eb773e8157ad0c5babe516f7bc945a02a9', "the new 'login' direct login binding still points to the correct field"), 836 Clipperz.Async.Test.is('4cfaf1e782086e7527bd0e0cc82b67eb773e8157ad0c5babe516f7bc945a02a9', "the new 'login' direct login binding still points to the correct field"),
829 837
830 MochiKit.Base.method(aDirectLogin, 'formValues'), 838 MochiKit.Base.method(aDirectLogin, 'formValues'),
831 MochiKit.Base.keys, 839 MochiKit.Base.keys,
832 MochiKit.Base.itemgetter('length'), 840 MochiKit.Base.itemgetter('length'),
833 Clipperz.Async.Test.is(1, "The new direct login had 1 form values (1)"), 841 Clipperz.Async.Test.is(1, "The new direct login had 1 form values (1)"),
834 842
835 MochiKit.Base.method(aDirectLogin, 'formValues'), 843 MochiKit.Base.method(aDirectLogin, 'formValues'),
836 MochiKit.Base.itemgetter('.persistent'), 844 MochiKit.Base.itemgetter('.persistent'),
837 MochiKit.Base.methodcaller('value'), 845 MochiKit.Base.methodcaller('value'),
838 Clipperz.Async.Test.is(null, "the formValue is still correctly set"), 846 Clipperz.Async.Test.is(null, "the formValue is still correctly set"),
839 847
840 MochiKit.Base.noop 848 MochiKit.Base.noop
841 ], someTestArgs); 849 ], someTestArgs);
842 }); 850 });
843 851
844 deferredResult.callback(); 852 deferredResult.callback();
845 853
846 return deferredResult; 854 return deferredResult;
847 }, 855 },
848 856
849 //------------------------------------------------------------------------- 857 //-------------------------------------------------------------------------
850 858
851 'editDirectLoginConfiguration_changingTheStructure_AndSaveChanges': function (someTestArgs) { 859 'editDirectLoginConfiguration_changingTheStructure_AndSaveChanges': function (someTestArgs) {
852 var deferredResult; 860 var deferredResult;
853 var proxy; 861 var proxy;
854 var user; 862 var user;
855 var user2; 863 var user2;
856 864
857 var recordID = 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d'; 865 var recordID = 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d';
858 var directLoginID ='dba0db679802f0e6aa6d0b7a6aaf42350aabc5f057409edd99a268a92ebb6496'; 866 var directLoginID ='dba0db679802f0e6aa6d0b7a6aaf42350aabc5f057409edd99a268a92ebb6496';
859 867
860 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:false, isDefault:true, readOnly:false}); 868 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:false, isDefault:true, readOnly:false});
861 user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}}); 869 user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
862 user2 = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}}); 870 user2 = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
863 871
864 deferredResult = new Clipperz.Async.Deferred("Record.test.editDirectLoginConfiguration_changingTheStructure_AndSaveChanges", someTestArgs); 872 deferredResult = new Clipperz.Async.Deferred("Record.test.editDirectLoginConfiguration_changingTheStructure_AndSaveChanges", someTestArgs);
865 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']); 873 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
866 deferredResult.addMethod(user, 'login'); 874 deferredResult.addMethod(user, 'login');
867 875
868 deferredResult.addMethod(user, 'getRecord', recordID); 876 deferredResult.addMethod(user, 'getRecord', recordID);
869 deferredResult.addMethodcaller('directLogins'); 877 deferredResult.addMethodcaller('directLogins');
870 deferredResult.addCallback(MochiKit.Base.itemgetter(directLoginID)); 878 deferredResult.addCallback(MochiKit.Base.itemgetter(directLoginID));
871 deferredResult.addCallback(function (aDirectLogin) { 879 deferredResult.addCallback(function (aDirectLogin) {
872 return Clipperz.Async.callbacks("Record.test.editDirectLoginConfiguration_changingTheStructure_AndSaveChanges [inner call 1]", [ 880 return Clipperz.Async.callbacks("Record.test.editDirectLoginConfiguration_changingTheStructure_AndSaveChanges [inner call 1]", [
873 MochiKit.Base.method(aDirectLogin, 'bookmarkletConfiguration'), 881 MochiKit.Base.method(aDirectLogin, 'bookmarkletConfiguration'),
874 Clipperz.Async.Test.is(directLoginConfigurations['Yahoo! Mail'], "the current bookmarkletConfiguration (2)"), 882 Clipperz.Async.Test.is(directLoginConfigurations['Yahoo! Mail'], "the current bookmarkletConfiguration (2)"),
875 883
876 MochiKit.Base.method(aDirectLogin, 'inputs'), 884 MochiKit.Base.method(aDirectLogin, 'inputs'),
877 MochiKit.Base.keys, 885 MochiKit.Base.keys,
878 MochiKit.Base.itemgetter('length'), 886 MochiKit.Base.itemgetter('length'),
879 Clipperz.Async.Test.is(26, "The original direct login had 26 inputs"), 887 Clipperz.Async.Test.is(26, "The original direct login had 26 inputs"),
880 888
881 MochiKit.Base.method(aDirectLogin, 'bindings'), 889 MochiKit.Base.method(aDirectLogin, 'bindings'),
882 MochiKit.Base.keys, 890 MochiKit.Base.keys,
883 MochiKit.Base.itemgetter('length'), 891 MochiKit.Base.itemgetter('length'),
884 Clipperz.Async.Test.is(2, "The original direct login had 2 inputs"), 892 Clipperz.Async.Test.is(2, "The original direct login had 2 inputs"),
885 893
886 MochiKit.Base.method(aDirectLogin, 'bindings'), 894 MochiKit.Base.method(aDirectLogin, 'bindings'),
887 MochiKit.Base.itemgetter('login'), 895 MochiKit.Base.itemgetter('login'),
888 MochiKit.Base.methodcaller('field'), 896 MochiKit.Base.methodcaller('field'),
889 MochiKit.Base.methodcaller('reference'), 897 MochiKit.Base.methodcaller('reference'),
890 Clipperz.Async.Test.is('4cfaf1e782086e7527bd0e0cc82b67eb773e8157ad0c5babe516f7bc945a02a9', "the original 'login' direct login binding points to the correct field"), 898 Clipperz.Async.Test.is('4cfaf1e782086e7527bd0e0cc82b67eb773e8157ad0c5babe516f7bc945a02a9', "the original 'login' direct login binding points to the correct field"),
891 899
892 MochiKit.Base.method(aDirectLogin, 'formValues'), 900 MochiKit.Base.method(aDirectLogin, 'formValues'),
893 MochiKit.Base.keys, 901 MochiKit.Base.keys,
894 MochiKit.Base.itemgetter('length'), 902 MochiKit.Base.itemgetter('length'),
895 Clipperz.Async.Test.is(1, "The original direct login had 1 form values"), 903 Clipperz.Async.Test.is(1, "The original direct login had 1 form values"),
896 904
897 MochiKit.Base.method(aDirectLogin, 'formValues'), 905 MochiKit.Base.method(aDirectLogin, 'formValues'),
898 MochiKit.Base.itemgetter('.persistent'), 906 MochiKit.Base.itemgetter('.persistent'),
899 MochiKit.Base.methodcaller('value'), 907 MochiKit.Base.methodcaller('value'),
900 Clipperz.Async.Test.is(null, "the original formValue is correct (2)"), 908 Clipperz.Async.Test.is(null, "the original formValue is correct (2)"),
901 909
902 910
903 MochiKit.Base.method(aDirectLogin, 'setBookmarkletConfiguration', directLoginConfigurations['Parallels']), 911 MochiKit.Base.method(aDirectLogin, 'setBookmarkletConfiguration', directLoginConfigurations['Parallels']),
904 MochiKit.Base.method(user, 'saveChanges'), 912 MochiKit.Base.method(user, 'saveChanges'),
905 913
906 MochiKit.Base.method(aDirectLogin, 'inputs'), 914 MochiKit.Base.method(aDirectLogin, 'inputs'),
907 MochiKit.Base.keys, 915 MochiKit.Base.keys,
908 MochiKit.Base.itemgetter('length'), 916 MochiKit.Base.itemgetter('length'),
909 Clipperz.Async.Test.is(2, "The new direct login has 2 inputs"), 917 Clipperz.Async.Test.is(2, "The new direct login has 2 inputs"),
910 918
911 MochiKit.Base.method(aDirectLogin, 'formValues'), 919 MochiKit.Base.method(aDirectLogin, 'formValues'),
912 MochiKit.Base.keys, 920 MochiKit.Base.keys,
913 MochiKit.Base.itemgetter('length'), 921 MochiKit.Base.itemgetter('length'),
914 Clipperz.Async.Test.is(0, "The new direct login has no form values"), 922 Clipperz.Async.Test.is(0, "The new direct login has no form values"),
915 923
916 MochiKit.Base.method(aDirectLogin, 'bindings'), 924 MochiKit.Base.method(aDirectLogin, 'bindings'),
917 MochiKit.Base.keys, 925 MochiKit.Base.keys,
918 MochiKit.Base.itemgetter('length'), 926 MochiKit.Base.itemgetter('length'),
919 Clipperz.Async.Test.is(2, "The new direct login has 2 inputs"), 927 Clipperz.Async.Test.is(2, "The new direct login has 2 inputs"),
920 928
921 MochiKit.Base.method(aDirectLogin, 'bindings'), 929 MochiKit.Base.method(aDirectLogin, 'bindings'),
922 MochiKit.Base.itemgetter('login'), 930 MochiKit.Base.itemgetter('login'),
923 Clipperz.Async.Test.is(null, "the 'login' binding should not exist within the new configuration"), 931 Clipperz.Async.Test.is(null, "the 'login' binding should not exist within the new configuration"),
924 932
925 MochiKit.Base.method(aDirectLogin, 'bindings'), 933 MochiKit.Base.method(aDirectLogin, 'bindings'),
926 MochiKit.Base.itemgetter('passwd'), 934 MochiKit.Base.itemgetter('passwd'),
927 Clipperz.Async.Test.is(null, "the 'passwd' binding should not exist within the new configuration"), 935 Clipperz.Async.Test.is(null, "the 'passwd' binding should not exist within the new configuration"),
928 936
929 MochiKit.Base.method(aDirectLogin, 'bindings'), 937 MochiKit.Base.method(aDirectLogin, 'bindings'),
930 MochiKit.Base.itemgetter('Email'), 938 MochiKit.Base.itemgetter('Email'),
931 Clipperz.Async.Test.ok("the 'Email' binding should exist within the new configuration"), 939 Clipperz.Async.Test.ok("the 'Email' binding should exist within the new configuration"),
932 940
933 MochiKit.Base.method(aDirectLogin, 'bindings'), 941 MochiKit.Base.method(aDirectLogin, 'bindings'),
934 MochiKit.Base.itemgetter('Password'), 942 MochiKit.Base.itemgetter('Password'),
935 Clipperz.Async.Test.ok("the 'Password' binding should exist within the new configuration"), 943 Clipperz.Async.Test.ok("the 'Password' binding should exist within the new configuration"),
936 944
937 945
938 MochiKit.Base.method(aDirectLogin, 'bindings'), 946 MochiKit.Base.method(aDirectLogin, 'bindings'),
939 MochiKit.Base.itemgetter('Email'), 947 MochiKit.Base.itemgetter('Email'),
940 MochiKit.Base.methodcaller('field'), 948 MochiKit.Base.methodcaller('field'),
941 Clipperz.Async.Test.is(null, "the 'Email' binding should not point to any field, yet"), 949 Clipperz.Async.Test.is(null, "the 'Email' binding should not point to any field, yet"),
942 950
943 951
944 MochiKit.Base.method(aDirectLogin, 'hasPendingChanges'), 952 MochiKit.Base.method(aDirectLogin, 'hasPendingChanges'),
945 Clipperz.Async.Test.fail("reverting changes should reset pending changes on the direct login (2)"), 953 Clipperz.Async.Test.fail("reverting changes should reset pending changes on the direct login (2)"),
946 MochiKit.Base.method(aDirectLogin.record(), 'hasPendingChanges'), 954 MochiKit.Base.method(aDirectLogin.record(), 'hasPendingChanges'),
947 Clipperz.Async.Test.fail("reverting changes should reset pending changes also on the record (2)"), 955 Clipperz.Async.Test.fail("reverting changes should reset pending changes also on the record (2)"),
948 MochiKit.Base.method(user, 'hasPendingChanges'), 956 MochiKit.Base.method(user, 'hasPendingChanges'),
949 Clipperz.Async.Test.fail("reverting changes should reset pending changes also on the user (2)"), 957 Clipperz.Async.Test.fail("reverting changes should reset pending changes also on the user (2)"),
950 958
951 MochiKit.Base.noop 959 MochiKit.Base.noop
952 ], someTestArgs); 960 ], someTestArgs);
953 }) 961 })
954 962
955 deferredResult.addMethod(user2, 'login'); 963 deferredResult.addMethod(user2, 'login');
956 964
957 deferredResult.addMethod(user2, 'getRecord', recordID); 965 deferredResult.addMethod(user2, 'getRecord', recordID);
diff --git a/frontend/gamma/tests/tests/Clipperz/PM/DataModel/User.html b/frontend/gamma/tests/tests/Clipperz/PM/DataModel/User.html
index 793f763..3a0eda8 100644
--- a/frontend/gamma/tests/tests/Clipperz/PM/DataModel/User.html
+++ b/frontend/gamma/tests/tests/Clipperz/PM/DataModel/User.html
@@ -1,101 +1,102 @@
1<!-- 1<!--
2 2
3Copyright 2008-2013 Clipperz Srl 3Copyright 2008-2013 Clipperz Srl
4 4
5This file is part of Clipperz, the online password manager. 5This file is part of Clipperz, the online password manager.
6For further information about its features and functionalities please 6For further information about its features and functionalities please
7refer to http://www.clipperz.com. 7refer to http://www.clipperz.com.
8 8
9* Clipperz is free software: you can redistribute it and/or modify it 9* Clipperz is free software: you can redistribute it and/or modify it
10 under the terms of the GNU Affero General Public License as published 10 under the terms of the GNU Affero General Public License as published
11 by the Free Software Foundation, either version 3 of the License, or 11 by the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version. 12 (at your option) any later version.
13 13
14* Clipperz is distributed in the hope that it will be useful, but 14* Clipperz is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of 15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU Affero General Public License for more details. 17 See the GNU Affero General Public License for more details.
18 18
19* You should have received a copy of the GNU Affero General Public 19* You should have received a copy of the GNU Affero General Public
20 License along with Clipperz. If not, see http://www.gnu.org/licenses/. 20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
21 21
22--> 22-->
23 23
24<html> 24<html>
25<head> 25<head>
26 <title>Clipperz.PM.DataModel.User - test</title> 26 <title>Clipperz.PM.DataModel.User - test</title>
27 27
28 <script type="text/javascript" src="../../../../../js/MochiKit/MochiKit.js"></script> 28 <script type="text/javascript" src="../../../../../js/MochiKit/MochiKit.js"></script>
29 <script type="text/javascript" src="../../../../SimpleTest/SimpleTest.js"></script> 29 <script type="text/javascript" src="../../../../SimpleTest/SimpleTest.js"></script>
30 <link rel="stylesheet" type="text/css" href="../../../../SimpleTest/test.css"> 30 <link rel="stylesheet" type="text/css" href="../../../../SimpleTest/test.css">
31 31
32 <script type='text/javascript' src='../../../../../js/JSON/json2.js'></script> 32 <script type='text/javascript' src='../../../../../js/JSON/json2.js'></script>
33 33
34 <script type='text/javascript' src='../../../../../js/Clipperz/YUI/Utils.js'></script> 34 <script type='text/javascript' src='../../../../../js/Clipperz/YUI/Utils.js'></script>
35 <script type='text/javascript' src='../../../../../js/Clipperz/Base.js'></script> 35 <script type='text/javascript' src='../../../../../js/Clipperz/Base.js'></script>
36 <script type='text/javascript' src='../../../../../js/Clipperz/Date.js'></script> 36 <script type='text/javascript' src='../../../../../js/Clipperz/Date.js'></script>
37 <script type='text/javascript' src='../../../../../js/Clipperz/ByteArray.js'></script> 37 <script type='text/javascript' src='../../../../../js/Clipperz/ByteArray.js'></script>
38 <script type='text/javascript' src='../../../../../js/Clipperz/Logging.js'></script> 38 <script type='text/javascript' src='../../../../../js/Clipperz/Logging.js'></script>
39 <script type='text/javascript' src='../../../../../js/Clipperz/Async.js'></script> 39 <script type='text/javascript' src='../../../../../js/Clipperz/Async.js'></script>
40 <script type='text/javascript' src='../../../../../js/Clipperz/Signal.js'></script> 40 <script type='text/javascript' src='../../../../../js/Clipperz/Signal.js'></script>
41 <script type='text/javascript' src='../../../../../js/Clipperz/KeyValueObjectStore.js'></script> 41 <script type='text/javascript' src='../../../../../js/Clipperz/KeyValueObjectStore.js'></script>
42 42
43 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/Base.js'></script> 43 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/Base.js'></script>
44 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/BigInt.js'></script> 44 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/BigInt.js'></script>
45 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/AES.js'></script> 45 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/AES.js'></script>
46 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/AES_2.js'></script>
46 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/SHA.js'></script> 47 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/SHA.js'></script>
47 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/PRNG.js'></script> 48 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/PRNG.js'></script>
48 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/SRP.js'></script> 49 <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/SRP.js'></script>
49 50
50 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Toll.js'></script> 51 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Toll.js'></script>
51 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy.js'></script> 52 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy.js'></script>
52 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy/Proxy.Offline.js'></script> 53 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy/Proxy.Offline.js'></script>
53 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy/Proxy.Test.js'></script> 54 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy/Proxy.Test.js'></script>
54 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js'></script> 55 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js'></script>
55 56
56 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Connection.js'></script> 57 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Connection.js'></script>
57 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Crypto.js'></script> 58 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Crypto.js'></script>
58 59
59 <script type='text/javascript' src='../../../../../js/Clipperz/PM/UI/Common/Controllers/DirectLoginRunner.js'></script> 60 <script type='text/javascript' src='../../../../../js/Clipperz/PM/UI/Common/Controllers/DirectLoginRunner.js'></script>
60 61
61 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Strings.js'></script> 62 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Strings.js'></script>
62 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Strings/Strings_en-US.js'></script> 63 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Strings/Strings_en-US.js'></script>
63 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Date.js'></script> 64 <script type='text/javascript' src='../../../../../js/Clipperz/PM/Date.js'></script>
64 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/EncryptedRemoteObject.js'></script> 65 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/EncryptedRemoteObject.js'></script>
65 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/Record.js'></script> 66 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/Record.js'></script>
66 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/Record.Version.js'></script> 67 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/Record.Version.js'></script>
67 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/Record.Version.Field.js'></script> 68 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/Record.Version.Field.js'></script>
68 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLogin.js'></script> 69 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLogin.js'></script>
69 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLoginInput.js'></script> 70 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLoginInput.js'></script>
70 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLoginBinding.js'></script> 71 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLoginBinding.js'></script>
71 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLoginFormValue.js'></script> 72 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLoginFormValue.js'></script>
72 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.js'></script> 73 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.js'></script>
73 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.Legacy.js'></script> 74 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.Legacy.js'></script>
74 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.RecordIndex.js'></script> 75 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.RecordIndex.js'></script>
75 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.Preferences.js'></script> 76 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.Preferences.js'></script>
76 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.OneTimePasswords.js'></script> 77 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.OneTimePasswords.js'></script>
77 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/OneTimePassword.js'></script> 78 <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/OneTimePassword.js'></script>
78 79
79 <script type="text/javascript" src="../../../../SimpleTest/SimpleTest.Async.js"></script> 80 <script type="text/javascript" src="../../../../SimpleTest/SimpleTest.Async.js"></script>
80<script> 81<script>
81 Clipperz_IEisBroken = false; 82 Clipperz_IEisBroken = false;
82</script> 83</script>
83 84
84<!--[if IE]><script> 85<!--[if IE]><script>
85Clipperz_IEisBroken = true; 86Clipperz_IEisBroken = true;
86Clipperz_normalizedNewLine = '\x0d\x0a'; 87Clipperz_normalizedNewLine = '\x0d\x0a';
87</script><![endif]--> 88</script><![endif]-->
88 89
89</head> 90</head>
90<body> 91<body>
91 92
92<pre id="test"> 93<pre id="test">
93<script> 94<script>
94 Clipperz.PM.Strings.Languages.setSelectedLanguage('en-us'); 95 Clipperz.PM.Strings.Languages.setSelectedLanguage('en-us');
95</script> 96</script>
96<script type="text/javascript" src="User.data.js"></script> 97<script type="text/javascript" src="User.data.js"></script>
97<script type="text/javascript" src="User.data.old.js"></script> 98<script type="text/javascript" src="User.data.old.js"></script>
98<script type="text/javascript" src="User.test.js"></script> 99<script type="text/javascript" src="User.test.js"></script>
99</pre> 100</pre>
100</body> 101</body>
101</html> 102</html>
diff --git a/frontend/gamma/tests/tests/Clipperz/PM/DataModel/User.test.js b/frontend/gamma/tests/tests/Clipperz/PM/DataModel/User.test.js
index 45f3297..545580f 100644
--- a/frontend/gamma/tests/tests/Clipperz/PM/DataModel/User.test.js
+++ b/frontend/gamma/tests/tests/Clipperz/PM/DataModel/User.test.js
@@ -1157,921 +1157,921 @@ var tests = {
1157 deferredResult.addMethodcaller('hasLoadedRemoteData'); 1157 deferredResult.addMethodcaller('hasLoadedRemoteData');
1158 deferredResult.addTest(false, "After saving, record_2 should still be NOT loaded"); 1158 deferredResult.addTest(false, "After saving, record_2 should still be NOT loaded");
1159 1159
1160 1160
1161 deferredResult.callback(); 1161 deferredResult.callback();
1162 1162
1163 return deferredResult; 1163 return deferredResult;
1164 }, 1164 },
1165 1165
1166 //------------------------------------------------------------------------- 1166 //-------------------------------------------------------------------------
1167 1167
1168 'addNewRecordFieldAndSave_test': function (someTestArgs) { 1168 'addNewRecordFieldAndSave_test': function (someTestArgs) {
1169 var deferredResult; 1169 var deferredResult;
1170 var proxy; 1170 var proxy;
1171 var user; 1171 var user;
1172 1172
1173 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false}); 1173 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
1174 user = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}}); 1174 user = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}});
1175 1175
1176 deferredResult = new Clipperz.Async.Deferred("simpleSaveChanges_test", someTestArgs); 1176 deferredResult = new Clipperz.Async.Deferred("simpleSaveChanges_test", someTestArgs);
1177 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_offline_copy_data']); 1177 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_offline_copy_data']);
1178 deferredResult.addMethod(user, 'login'); 1178 deferredResult.addMethod(user, 'login');
1179 1179
1180 deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13'); 1180 deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
1181 deferredResult.addMethodcaller('fields'); 1181 deferredResult.addMethodcaller('fields');
1182 deferredResult.addCallback(function (someFields) { 1182 deferredResult.addCallback(function (someFields) {
1183 SimpleTest.is(MochiKit.Base.values(someFields).length, 3, "The record has initially 3 fields"); 1183 SimpleTest.is(MochiKit.Base.values(someFields).length, 3, "The record has initially 3 fields");
1184 }); 1184 });
1185 1185
1186 deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13'); 1186 deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
1187 deferredResult.addCallback(MochiKit.Base.methodcaller('addField', {'label':"New field label", 'value':"New field value", 'isHidden':false})); 1187 deferredResult.addCallback(MochiKit.Base.methodcaller('addField', {'label':"New field label", 'value':"New field value", 'isHidden':false}));
1188 1188
1189 deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13'); 1189 deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
1190 deferredResult.addMethodcaller('hasPendingChanges'); 1190 deferredResult.addMethodcaller('hasPendingChanges');
1191 deferredResult.addTest(true, "adding a field should mark the record as having pending changes"); 1191 deferredResult.addTest(true, "adding a field should mark the record as having pending changes");
1192 1192
1193 deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13'); 1193 deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
1194 deferredResult.addMethodcaller('fields'); 1194 deferredResult.addMethodcaller('fields');
1195 deferredResult.addCallback(function (someFields) { 1195 deferredResult.addCallback(function (someFields) {
1196 SimpleTest.is(MochiKit.Base.values(someFields).length, 4, "The record has now 4 fields"); 1196 SimpleTest.is(MochiKit.Base.values(someFields).length, 4, "The record has now 4 fields");
1197 }); 1197 });
1198 1198
1199 deferredResult.addMethod(user, 'saveChanges'); 1199 deferredResult.addMethod(user, 'saveChanges');
1200 deferredResult.addMethod(user, 'hasPendingChanges'); 1200 deferredResult.addMethod(user, 'hasPendingChanges');
1201 deferredResult.addTest(false, "saving changes should return the user to a state with not changes pending - 4"); 1201 deferredResult.addTest(false, "saving changes should return the user to a state with not changes pending - 4");
1202 1202
1203 deferredResult.addMethod(user, 'hasAnyCleanTextData'); 1203 deferredResult.addMethod(user, 'hasAnyCleanTextData');
1204 deferredResult.addTest(true, "after saving changes, hasAnyCleanTextData should be true"); 1204 deferredResult.addTest(true, "after saving changes, hasAnyCleanTextData should be true");
1205 1205
1206//deferredResult.addCallback(function (aValue) { console.log(">>> #################################################"); return aValue}); 1206//deferredResult.addCallback(function (aValue) { console.log(">>> #################################################"); return aValue});
1207 deferredResult.addMethod(user, 'deleteAllCleanTextData'); 1207 deferredResult.addMethod(user, 'deleteAllCleanTextData');
1208//deferredResult.addCallback(function (aValue) { console.log("<<< #################################################"); return aValue}); 1208//deferredResult.addCallback(function (aValue) { console.log("<<< #################################################"); return aValue});
1209 1209
1210 deferredResult.addMethod(user, 'hasAnyCleanTextData'); 1210 deferredResult.addMethod(user, 'hasAnyCleanTextData');
1211 deferredResult.addTest(false, "after deleting all clean text, hasAnyCleanTextData should be false"); 1211 deferredResult.addTest(false, "after deleting all clean text, hasAnyCleanTextData should be false");
1212 1212
1213 deferredResult.callback(); 1213 deferredResult.callback();
1214 1214
1215 return deferredResult; 1215 return deferredResult;
1216 }, 1216 },
1217 1217
1218 //------------------------------------------------------------------------- 1218 //-------------------------------------------------------------------------
1219 1219
1220 'deleteRecordFieldAndSave_test': function (someTestArgs) { 1220 'deleteRecordFieldAndSave_test': function (someTestArgs) {
1221 var deferredResult; 1221 var deferredResult;
1222 var proxy; 1222 var proxy;
1223 var user; 1223 var user;
1224 var user2; 1224 var user2;
1225 1225
1226 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false}); 1226 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
1227 user = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}}); 1227 user = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}});
1228 user2 = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}}); 1228 user2 = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}});
1229 1229
1230 deferredResult = new Clipperz.Async.Deferred("simpleSaveChanges_test", someTestArgs); 1230 deferredResult = new Clipperz.Async.Deferred("simpleSaveChanges_test", someTestArgs);
1231 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_offline_copy_data']); 1231 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_offline_copy_data']);
1232 deferredResult.addMethod(user, 'login'); 1232 deferredResult.addMethod(user, 'login');
1233 1233
1234 deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13'); 1234 deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
1235 deferredResult.addMethodcaller('fields'); 1235 deferredResult.addMethodcaller('fields');
1236 deferredResult.addCallback(function (someFields) { 1236 deferredResult.addCallback(function (someFields) {
1237 SimpleTest.is(MochiKit.Base.values(someFields).length, 3, "The record has initially 3 fields"); 1237 SimpleTest.is(MochiKit.Base.values(someFields).length, 3, "The record has initially 3 fields");
1238 }); 1238 });
1239 1239
1240 deferredResult.collectResults({ 1240 deferredResult.collectResults({
1241 'record': MochiKit.Base.method(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13'), 1241 'record': MochiKit.Base.method(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13'),
1242 'field': [ 1242 'field': [
1243 MochiKit.Base.method(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13'), 1243 MochiKit.Base.method(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13'),
1244 MochiKit.Base.methodcaller('fields'), 1244 MochiKit.Base.methodcaller('fields'),
1245 MochiKit.Base.values, 1245 MochiKit.Base.values,
1246 MochiKit.Base.itemgetter('0') 1246 MochiKit.Base.itemgetter('0')
1247 ] 1247 ]
1248 }) 1248 })
1249 deferredResult.addCallback(function (someValues) { 1249 deferredResult.addCallback(function (someValues) {
1250 someValues['record'].removeField(someValues['field']); 1250 someValues['record'].removeField(someValues['field']);
1251 }); 1251 });
1252 1252
1253 deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13'); 1253 deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
1254 deferredResult.addMethodcaller('hasPendingChanges'); 1254 deferredResult.addMethodcaller('hasPendingChanges');
1255 deferredResult.addTest(true, "removing a field should mark the record as having pending changes"); 1255 deferredResult.addTest(true, "removing a field should mark the record as having pending changes");
1256 1256
1257 deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13'); 1257 deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
1258 deferredResult.addMethodcaller('fields'); 1258 deferredResult.addMethodcaller('fields');
1259 deferredResult.addCallback(function (someFields) { 1259 deferredResult.addCallback(function (someFields) {
1260 SimpleTest.is(MochiKit.Base.values(someFields).length, 2, "The record has now 2 fields"); 1260 SimpleTest.is(MochiKit.Base.values(someFields).length, 2, "The record has now 2 fields");
1261 }); 1261 });
1262 1262
1263 deferredResult.addMethod(user, 'saveChanges'); 1263 deferredResult.addMethod(user, 'saveChanges');
1264 deferredResult.addMethod(user, 'hasPendingChanges'); 1264 deferredResult.addMethod(user, 'hasPendingChanges');
1265 deferredResult.addTest(false, "saving changes should return the user to a state with not changes pending - 5"); 1265 deferredResult.addTest(false, "saving changes should return the user to a state with not changes pending - 5");
1266 1266
1267 //. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1267 //. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1268 1268
1269 deferredResult.addMethod(user2, 'login'); 1269 deferredResult.addMethod(user2, 'login');
1270 deferredResult.addMethod(user2, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13'); 1270 deferredResult.addMethod(user2, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
1271 deferredResult.addMethodcaller('fields'); 1271 deferredResult.addMethodcaller('fields');
1272 deferredResult.addCallback(function (someFields) { 1272 deferredResult.addCallback(function (someFields) {
1273 SimpleTest.is(MochiKit.Base.values(someFields).length, 2, "Once saved, the record is left with just two fields"); 1273 SimpleTest.is(MochiKit.Base.values(someFields).length, 2, "Once saved, the record is left with just two fields");
1274 }); 1274 });
1275 1275
1276 deferredResult.callback(); 1276 deferredResult.callback();
1277 1277
1278 return deferredResult; 1278 return deferredResult;
1279 }, 1279 },
1280 1280
1281 //------------------------------------------------------------------------- 1281 //-------------------------------------------------------------------------
1282 1282
1283 'loadDirectLogin_test': function (someTestArgs) { 1283 'loadDirectLogin_test': function (someTestArgs) {
1284 var deferredResult; 1284 var deferredResult;
1285 var proxy; 1285 var proxy;
1286 var user; 1286 var user;
1287 1287
1288 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true}); 1288 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true});
1289 user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}}); 1289 user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
1290 1290
1291 deferredResult = new Clipperz.Async.Deferred("loadDirectLogin_test", someTestArgs); 1291 deferredResult = new Clipperz.Async.Deferred("loadDirectLogin_test", someTestArgs);
1292 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']); 1292 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
1293 deferredResult.addMethod(user, 'login'); 1293 deferredResult.addMethod(user, 'login');
1294 1294
1295 deferredResult.addMethod(user, 'getRecord', '13a5e52976337ab210903cd04872588e1b21fb72bc183e91aa25c494b8138551'); 1295 deferredResult.addMethod(user, 'getRecord', '13a5e52976337ab210903cd04872588e1b21fb72bc183e91aa25c494b8138551');
1296 deferredResult.addCallback(MochiKit.Base.methodcaller('directLogins')); 1296 deferredResult.addCallback(MochiKit.Base.methodcaller('directLogins'));
1297 deferredResult.addCallback(function (someDirectLogins) { 1297 deferredResult.addCallback(function (someDirectLogins) {
1298 SimpleTest.is(1, MochiKit.Base.keys(someDirectLogins).length, "the Amazon.com card has just one direct login"); 1298 SimpleTest.is(1, MochiKit.Base.keys(someDirectLogins).length, "the Amazon.com card has just one direct login");
1299 }); 1299 });
1300 1300
1301 deferredResult.addMethod(user, 'getRecord', '13a5e52976337ab210903cd04872588e1b21fb72bc183e91aa25c494b8138551'); 1301 deferredResult.addMethod(user, 'getRecord', '13a5e52976337ab210903cd04872588e1b21fb72bc183e91aa25c494b8138551');
1302 deferredResult.addCallback(MochiKit.Base.methodcaller('hasPendingChanges')); 1302 deferredResult.addCallback(MochiKit.Base.methodcaller('hasPendingChanges'));
1303 deferredResult.addTest(false, "initially the record does not have any pending changes"); 1303 deferredResult.addTest(false, "initially the record does not have any pending changes");
1304 1304
1305 deferredResult.addMethod(user, 'getRecord', '13a5e52976337ab210903cd04872588e1b21fb72bc183e91aa25c494b8138551'); 1305 deferredResult.addMethod(user, 'getRecord', '13a5e52976337ab210903cd04872588e1b21fb72bc183e91aa25c494b8138551');
1306 deferredResult.addCallback(MochiKit.Base.methodcaller('directLogins')); 1306 deferredResult.addCallback(MochiKit.Base.methodcaller('directLogins'));
1307 deferredResult.addCallback(MochiKit.Base.itemgetter('03251dc1cbc5398789e4c4b45c52cfac3fcd8c1a4f19a81fa68fc6feae31d55c')); 1307 deferredResult.addCallback(MochiKit.Base.itemgetter('03251dc1cbc5398789e4c4b45c52cfac3fcd8c1a4f19a81fa68fc6feae31d55c'));
1308 // deferredResult.addCallback(MochiKit.Base.methodcaller('runDirectLogin', true)); 1308 // deferredResult.addCallback(MochiKit.Base.methodcaller('runDirectLogin', true));
1309 deferredResult.addCallback(Clipperz.PM.UI.Common.Controllers.DirectLoginRunner.testDirectLogin); 1309 deferredResult.addCallback(Clipperz.PM.UI.Common.Controllers.DirectLoginRunner.testDirectLogin);
1310 1310
1311 deferredResult.addMethod(user, 'getRecord', '13a5e52976337ab210903cd04872588e1b21fb72bc183e91aa25c494b8138551'); 1311 deferredResult.addMethod(user, 'getRecord', '13a5e52976337ab210903cd04872588e1b21fb72bc183e91aa25c494b8138551');
1312 deferredResult.addCallback(MochiKit.Base.methodcaller('getFieldsValues')); 1312 deferredResult.addCallback(MochiKit.Base.methodcaller('getFieldsValues'));
1313 deferredResult.addCallback(function (someFieldsValues) { 1313 deferredResult.addCallback(function (someFieldsValues) {
1314 SimpleTest.is(MochiKit.Base.keys(someFieldsValues).length, 2, "the Amazon.com card has just two fields"); 1314 SimpleTest.is(MochiKit.Base.keys(someFieldsValues).length, 2, "the Amazon.com card has just two fields");
1315 }); 1315 });
1316 1316
1317 deferredResult.addMethod(user, 'getRecord', '13a5e52976337ab210903cd04872588e1b21fb72bc183e91aa25c494b8138551'); 1317 deferredResult.addMethod(user, 'getRecord', '13a5e52976337ab210903cd04872588e1b21fb72bc183e91aa25c494b8138551');
1318 deferredResult.addCallback(MochiKit.Base.methodcaller('hasPendingChanges')); 1318 deferredResult.addCallback(MochiKit.Base.methodcaller('hasPendingChanges'));
1319 deferredResult.addTest(false, "accessing fields values should not trigger the 'hasPendingChanges' flag"); 1319 deferredResult.addTest(false, "accessing fields values should not trigger the 'hasPendingChanges' flag");
1320 1320
1321 deferredResult.callback(); 1321 deferredResult.callback();
1322 1322
1323 return deferredResult; 1323 return deferredResult;
1324 }, 1324 },
1325 1325
1326 //------------------------------------------------------------------------- 1326 //-------------------------------------------------------------------------
1327 1327
1328 'readingVeryOldCards_test': function (someTestArgs) { 1328 'readingVeryOldCards_test': function (someTestArgs) {
1329 var deferredResult; 1329 var deferredResult;
1330 var proxy; 1330 var proxy;
1331 var user; 1331 var user;
1332 1332
1333 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true}); 1333 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true});
1334 user = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}}); 1334 user = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}});
1335 1335
1336 deferredResult = new Clipperz.Async.Deferred("readingVeryOldCards_test", someTestArgs); 1336 deferredResult = new Clipperz.Async.Deferred("readingVeryOldCards_test", someTestArgs);
1337 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_someExtraOldData']); 1337 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_someExtraOldData']);
1338 deferredResult.addMethod(user, 'login'); 1338 deferredResult.addMethod(user, 'login');
1339 1339
1340 deferredResult.addMethod(user, 'getRecord', '05aad20ee399b11ddc923e601fcd1d096233634f2ad4c55db4f6435e5f9cc17a'); 1340 deferredResult.addMethod(user, 'getRecord', '05aad20ee399b11ddc923e601fcd1d096233634f2ad4c55db4f6435e5f9cc17a');
1341 deferredResult.addMethodcaller('label'); 1341 deferredResult.addMethodcaller('label');
1342 deferredResult.addTest('Card encoded with an old algorithm', 'the label of the selected record is the expected one'); 1342 deferredResult.addTest('Card encoded with an old algorithm', 'the label of the selected record is the expected one');
1343 1343
1344 deferredResult.addMethod(user, 'getRecord', '05aad20ee399b11ddc923e601fcd1d096233634f2ad4c55db4f6435e5f9cc17a'); 1344 deferredResult.addMethod(user, 'getRecord', '05aad20ee399b11ddc923e601fcd1d096233634f2ad4c55db4f6435e5f9cc17a');
1345 deferredResult.addCallback(MochiKit.Base.methodcaller('fields')); 1345 deferredResult.addCallback(MochiKit.Base.methodcaller('fields'));
1346 deferredResult.addCallback(function (someFields) { 1346 deferredResult.addCallback(function (someFields) {
1347 SimpleTest.is(6, MochiKit.Base.keys(someFields).length, "the 'Card encoded with an old algorithm' card has six fields"); 1347 SimpleTest.is(6, MochiKit.Base.keys(someFields).length, "the 'Card encoded with an old algorithm' card has six fields");
1348 }); 1348 });
1349 1349
1350 deferredResult.addMethod(user, 'getRecord', '05aad20ee399b11ddc923e601fcd1d096233634f2ad4c55db4f6435e5f9cc17a'); 1350 deferredResult.addMethod(user, 'getRecord', '05aad20ee399b11ddc923e601fcd1d096233634f2ad4c55db4f6435e5f9cc17a');
1351 deferredResult.addMethodcaller('hasPendingChanges'); 1351 deferredResult.addMethodcaller('hasPendingChanges');
1352 deferredResult.addTest(false, "accessing the card fields should not trigger the hasPendingChanges flag"); 1352 deferredResult.addTest(false, "accessing the card fields should not trigger the hasPendingChanges flag");
1353 1353
1354 deferredResult.addMethod(user, 'getRecord', '05aad20ee399b11ddc923e601fcd1d096233634f2ad4c55db4f6435e5f9cc17a'); 1354 deferredResult.addMethod(user, 'getRecord', '05aad20ee399b11ddc923e601fcd1d096233634f2ad4c55db4f6435e5f9cc17a');
1355 deferredResult.addCallback(MochiKit.Base.methodcaller('addField', {'label':"New field label", 'value':"New field value", 'isHidden':false})); 1355 deferredResult.addCallback(MochiKit.Base.methodcaller('addField', {'label':"New field label", 'value':"New field value", 'isHidden':false}));
1356 1356
1357 deferredResult.addMethod(user, 'getRecord', '05aad20ee399b11ddc923e601fcd1d096233634f2ad4c55db4f6435e5f9cc17a'); 1357 deferredResult.addMethod(user, 'getRecord', '05aad20ee399b11ddc923e601fcd1d096233634f2ad4c55db4f6435e5f9cc17a');
1358 deferredResult.addCallback(MochiKit.Base.methodcaller('fields')); 1358 deferredResult.addCallback(MochiKit.Base.methodcaller('fields'));
1359 deferredResult.addCallback(function (someFields) { 1359 deferredResult.addCallback(function (someFields) {
1360 SimpleTest.is(7, MochiKit.Base.keys(someFields).length, "adding a field shoult bring the total field count to 7"); 1360 SimpleTest.is(7, MochiKit.Base.keys(someFields).length, "adding a field shoult bring the total field count to 7");
1361 }); 1361 });
1362 1362
1363 deferredResult.addMethod(user, 'getRecord', '05aad20ee399b11ddc923e601fcd1d096233634f2ad4c55db4f6435e5f9cc17a'); 1363 deferredResult.addMethod(user, 'getRecord', '05aad20ee399b11ddc923e601fcd1d096233634f2ad4c55db4f6435e5f9cc17a');
1364 deferredResult.addMethodcaller('hasPendingChanges'); 1364 deferredResult.addMethodcaller('hasPendingChanges');
1365 deferredResult.addTest(true, "adding a field should mark the record as having pending changes - 2"); 1365 deferredResult.addTest(true, "adding a field should mark the record as having pending changes - 2");
1366 1366
1367 deferredResult.callback(); 1367 deferredResult.callback();
1368 1368
1369 return deferredResult; 1369 return deferredResult;
1370 }, 1370 },
1371 1371
1372 //------------------------------------------------------------------------- 1372 //-------------------------------------------------------------------------
1373 1373
1374 'addingNewEmptyRecordAndSaveChanges_test': function (someTestArgs) { 1374 'addingNewEmptyRecordAndSaveChanges_test': function (someTestArgs) {
1375 var deferredResult; 1375 var deferredResult;
1376 var proxy; 1376 var proxy;
1377 var user; 1377 var user;
1378 var newRecordReference; 1378 var newRecordReference;
1379 1379
1380 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false}); 1380 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
1381 user = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}}); 1381 user = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}});
1382 user2 = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}}); 1382 user2 = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}});
1383 1383
1384 deferredResult = new Clipperz.Async.Deferred("addingNewEmptyRecordAndSaveChanges_test", someTestArgs); 1384 deferredResult = new Clipperz.Async.Deferred("addingNewEmptyRecordAndSaveChanges_test", someTestArgs);
1385 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_someExtraOldData']); 1385 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_someExtraOldData']);
1386 deferredResult.addMethod(user, 'login'); 1386 deferredResult.addMethod(user, 'login');
1387 1387
1388 deferredResult.addMethod(user, 'getRecords'); 1388 deferredResult.addMethod(user, 'getRecords');
1389 deferredResult.addCallback(function (someRecords) { 1389 deferredResult.addCallback(function (someRecords) {
1390 SimpleTest.is(MochiKit.Base.keys(someRecords).length, 1, "The user has initially just one record"); 1390 SimpleTest.is(MochiKit.Base.keys(someRecords).length, 1, "The user has initially just one record");
1391 }); 1391 });
1392 1392
1393 deferredResult.addMethod(user, 'createNewRecord'); 1393 deferredResult.addMethod(user, 'createNewRecord');
1394 deferredResult.addMethodcaller('reference'); 1394 deferredResult.addMethodcaller('reference');
1395 deferredResult.addCallback(function (aNewRecordReference) { 1395 deferredResult.addCallback(function (aNewRecordReference) {
1396 newRecordReference = aNewRecordReference; 1396 newRecordReference = aNewRecordReference;
1397 }) 1397 })
1398 1398
1399 deferredResult.addMethod(user, 'getRecords'); 1399 deferredResult.addMethod(user, 'getRecords');
1400 deferredResult.addCallback(function (someRecords) { 1400 deferredResult.addCallback(function (someRecords) {
1401 SimpleTest.is(MochiKit.Base.keys(someRecords).length, 2, "After having created a new record, the total should be updated accordingly"); 1401 SimpleTest.is(MochiKit.Base.keys(someRecords).length, 2, "After having created a new record, the total should be updated accordingly");
1402 }); 1402 });
1403 1403
1404 deferredResult.addMethod(user, 'getRecord', '05aad20ee399b11ddc923e601fcd1d096233634f2ad4c55db4f6435e5f9cc17a'); 1404 deferredResult.addMethod(user, 'getRecord', '05aad20ee399b11ddc923e601fcd1d096233634f2ad4c55db4f6435e5f9cc17a');
1405 deferredResult.addMethodcaller('hasPendingChanges'); 1405 deferredResult.addMethodcaller('hasPendingChanges');
1406 deferredResult.addTest(false, "adding a new record should not trigger any changes on a sibling record"); 1406 deferredResult.addTest(false, "adding a new record should not trigger any changes on a sibling record");
1407 1407
1408 deferredResult.addMethod(user, 'hasPendingChanges'); 1408 deferredResult.addMethod(user, 'hasPendingChanges');
1409 deferredResult.addTest(true, "adding a new record should trigger the 'has pending changes' flag on the user"); 1409 deferredResult.addTest(true, "adding a new record should trigger the 'has pending changes' flag on the user");
1410 1410
1411 deferredResult.addMethod(user, 'saveChanges'); 1411 deferredResult.addMethod(user, 'saveChanges');
1412 1412
1413 deferredResult.addMethod(user2, 'login'); 1413 deferredResult.addMethod(user2, 'login');
1414 deferredResult.addMethod(user2, 'getRecords'); 1414 deferredResult.addMethod(user2, 'getRecords');
1415 deferredResult.addCallback(function (someRecords) { 1415 deferredResult.addCallback(function (someRecords) {
1416 SimpleTest.is(MochiKit.Base.keys(someRecords).length, 1, "Reloading the data, just one record is available, as a brand new record without any changes should not be saved"); 1416 SimpleTest.is(MochiKit.Base.keys(someRecords).length, 1, "Reloading the data, just one record is available, as a brand new record without any changes should not be saved");
1417 }); 1417 });
1418 1418
1419 deferredResult.callback(); 1419 deferredResult.callback();
1420 1420
1421 return deferredResult; 1421 return deferredResult;
1422 }, 1422 },
1423 1423
1424 //------------------------------------------------------------------------- 1424 //-------------------------------------------------------------------------
1425 1425
1426 'addNewRecordAndSaveChanges_test': function (someTestArgs) { 1426 'addNewRecordAndSaveChanges_test': function (someTestArgs) {
1427 var deferredResult; 1427 var deferredResult;
1428 var proxy; 1428 var proxy;
1429 var user; 1429 var user;
1430 1430
1431 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false}); 1431 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
1432 user = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}}); 1432 user = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}});
1433 user2 = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}}); 1433 user2 = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}});
1434 1434
1435 deferredResult = new Clipperz.Async.Deferred("addNewRecordAndSaveChanges_test", someTestArgs); 1435 deferredResult = new Clipperz.Async.Deferred("addNewRecordAndSaveChanges_test", someTestArgs);
1436 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_someExtraOldData']); 1436 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_someExtraOldData']);
1437 deferredResult.addMethod(user, 'login'); 1437 deferredResult.addMethod(user, 'login');
1438 1438
1439 deferredResult.addMethod(user, 'getRecords'); 1439 deferredResult.addMethod(user, 'getRecords');
1440 deferredResult.addCallback(function (someRecords) { 1440 deferredResult.addCallback(function (someRecords) {
1441 SimpleTest.is(MochiKit.Base.keys(someRecords).length, 1, "The user has initially just one record"); 1441 SimpleTest.is(MochiKit.Base.keys(someRecords).length, 1, "The user has initially just one record");
1442 }); 1442 });
1443 1443
1444 deferredResult.addMethod(user, 'createNewRecord'); 1444 deferredResult.addMethod(user, 'createNewRecord');
1445 deferredResult.addCallback(function (aNewRecord) { 1445 deferredResult.addCallback(function (aNewRecord) {
1446 var innerDeferredResult; 1446 var innerDeferredResult;
1447 1447
1448 innerDeferredResult = new Clipperz.Async.Deferred("addNewRecordAndSaveChanges_test <internal>", {trace:false}); 1448 innerDeferredResult = new Clipperz.Async.Deferred("addNewRecordAndSaveChanges_test <internal>", {trace:false});
1449 1449
1450 innerDeferredResult.addMethod(aNewRecord, 'label'); 1450 innerDeferredResult.addMethod(aNewRecord, 'label');
1451 innerDeferredResult.addTest('', "The label of a brand new record should be the empty string"); 1451 innerDeferredResult.addTest('', "The label of a brand new record should be the empty string");
1452 1452
1453 innerDeferredResult.addMethod(aNewRecord, 'setLabel', "New record label"); 1453 innerDeferredResult.addMethod(aNewRecord, 'setLabel', "New record label");
1454 innerDeferredResult.addMethod(aNewRecord, 'setNotes', "New record notes"); 1454 innerDeferredResult.addMethod(aNewRecord, 'setNotes', "New record notes");
1455 innerDeferredResult.addMethod(aNewRecord, 'addField', {'label':"Label 1", 'value':"Value 1", 'isHidden':false}); 1455 innerDeferredResult.addMethod(aNewRecord, 'addField', {'label':"Label 1", 'value':"Value 1", 'isHidden':false});
1456 innerDeferredResult.addMethod(aNewRecord, 'addField', {'label':"Label 2", 'value':"Value 2", 'isHidden':false}); 1456 innerDeferredResult.addMethod(aNewRecord, 'addField', {'label':"Label 2", 'value':"Value 2", 'isHidden':false});
1457 innerDeferredResult.addMethod(aNewRecord, 'addField', {'label':"Label 3", 'value':"Value 3", 'isHidden':true}); 1457 innerDeferredResult.addMethod(aNewRecord, 'addField', {'label':"Label 3", 'value':"Value 3", 'isHidden':true});
1458 innerDeferredResult.addMethod(aNewRecord, 'addField', {'label':"Label 4", 'value':"Value 4", 'isHidden':false}); 1458 innerDeferredResult.addMethod(aNewRecord, 'addField', {'label':"Label 4", 'value':"Value 4", 'isHidden':false});
1459 innerDeferredResult.callback(); 1459 innerDeferredResult.callback();
1460 1460
1461 return innerDeferredResult; 1461 return innerDeferredResult;
1462 }) 1462 })
1463 1463
1464 deferredResult.addMethod(user, 'getRecords'); 1464 deferredResult.addMethod(user, 'getRecords');
1465 deferredResult.addCallback(function (someRecords) { 1465 deferredResult.addCallback(function (someRecords) {
1466 SimpleTest.is(MochiKit.Base.keys(someRecords).length, 2, "After having created a new record, the total should be updated accordingly"); 1466 SimpleTest.is(MochiKit.Base.keys(someRecords).length, 2, "After having created a new record, the total should be updated accordingly");
1467 }); 1467 });
1468 1468
1469 deferredResult.addMethod(user, 'getRecord', '05aad20ee399b11ddc923e601fcd1d096233634f2ad4c55db4f6435e5f9cc17a'); 1469 deferredResult.addMethod(user, 'getRecord', '05aad20ee399b11ddc923e601fcd1d096233634f2ad4c55db4f6435e5f9cc17a');
1470 deferredResult.addMethodcaller('hasPendingChanges'); 1470 deferredResult.addMethodcaller('hasPendingChanges');
1471 deferredResult.addTest(false, "adding a new record should not trigger any changes on a sibling record"); 1471 deferredResult.addTest(false, "adding a new record should not trigger any changes on a sibling record");
1472 1472
1473 deferredResult.addMethod(user, 'hasPendingChanges'); 1473 deferredResult.addMethod(user, 'hasPendingChanges');
1474 deferredResult.addTest(true, "adding a new record should trigger the 'has pending changes' flag on the user"); 1474 deferredResult.addTest(true, "adding a new record should trigger the 'has pending changes' flag on the user");
1475 1475
1476 deferredResult.addMethod(user, 'saveChanges'); 1476 deferredResult.addMethod(user, 'saveChanges');
1477 1477
1478 deferredResult.addCallback(function () { 1478 deferredResult.addCallback(function () {
1479 var recordData 1479 var recordData
1480 var recordVersionData; 1480 var recordVersionData;
1481 1481
1482 recordData = MochiKit.Base.values(proxy.dataStore().data()['users']['9a984e219b07f9b645ef35f4de938b4741abe2e0b4adc88b40e9367170c91cc8']['records'])[1]; 1482 recordData = MochiKit.Base.values(proxy.dataStore().data()['users']['9a984e219b07f9b645ef35f4de938b4741abe2e0b4adc88b40e9367170c91cc8']['records'])[1];
1483 recordVersionData = MochiKit.Base.values(recordData['versions'])[0]; 1483 recordVersionData = MochiKit.Base.values(recordData['versions'])[0];
1484 1484
1485 SimpleTest.is(recordVersionData['previousVersionKey'], Clipperz.PM.Crypto.nullValue, "The previous version key on the first version of a newly created record is equal to Clipperz.PM.Crypto.nullValue"); 1485 SimpleTest.is(recordVersionData['previousVersionKey'], Clipperz.PM.Crypto.nullValue, "The previous version key on the first version of a newly created record is equal to Clipperz.PM.Crypto.nullValue");
1486 }); 1486 });
1487 1487
1488 deferredResult.addMethod(user2, 'login'); 1488 deferredResult.addMethod(user2, 'login');
1489 deferredResult.addMethod(user2, 'getRecords'); 1489 deferredResult.addMethod(user2, 'getRecords');
1490 deferredResult.addCallback(function (someRecords) { 1490 deferredResult.addCallback(function (someRecords) {
1491 SimpleTest.is(someRecords.length, 2, "Reloading the data, two records are available."); 1491 SimpleTest.is(someRecords.length, 2, "Reloading the data, two records are available.");
1492 return someRecords; 1492 return someRecords;
1493 }); 1493 });
1494 deferredResult.addCallback(MochiKit.Base.itemgetter('1')); 1494 deferredResult.addCallback(MochiKit.Base.itemgetter('1'));
1495 deferredResult.collectResults({ 1495 deferredResult.collectResults({
1496 'label':[ 1496 'label':[
1497 MochiKit.Base.methodcaller('label'), 1497 MochiKit.Base.methodcaller('label'),
1498 Clipperz.Async.Test.is("New record label", "The label is correct") 1498 Clipperz.Async.Test.is("New record label", "The label is correct")
1499 ], 1499 ],
1500 'notes':[ 1500 'notes':[
1501 MochiKit.Base.methodcaller('notes'), 1501 MochiKit.Base.methodcaller('notes'),
1502 Clipperz.Async.Test.is("New record notes", "The note is correct") 1502 Clipperz.Async.Test.is("New record notes", "The note is correct")
1503 ], 1503 ],
1504 'fields':[ 1504 'fields':[
1505 MochiKit.Base.methodcaller('fields'), 1505 MochiKit.Base.methodcaller('fields'),
1506 function (someFields) { 1506 function (someFields) {
1507 SimpleTest.is(MochiKit.Base.values(someFields).length, 4, "The fields are 4, as expected"); 1507 SimpleTest.is(MochiKit.Base.values(someFields).length, 4, "The fields are 4, as expected");
1508 return someFields; 1508 return someFields;
1509 } 1509 }
1510 ] 1510 ]
1511 }) 1511 })
1512 1512
1513 deferredResult.callback(); 1513 deferredResult.callback();
1514 1514
1515 return deferredResult; 1515 return deferredResult;
1516 }, 1516 },
1517 1517
1518 //------------------------------------------------------------------------- 1518 //-------------------------------------------------------------------------
1519 1519
1520 'addNewRecordAndTestNewRecordIndex_test': function (someTestArgs) { 1520 'addNewRecordAndTestNewRecordIndex_test': function (someTestArgs) {
1521 var deferredResult; 1521 var deferredResult;
1522 var proxy; 1522 var proxy;
1523 var user; 1523 var user;
1524 1524
1525 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false}); 1525 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
1526 user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}}); 1526 user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
1527 1527
1528 deferredResult = new Clipperz.Async.Deferred("addNewRecordAndTestNewRecordIndex_test", someTestArgs); 1528 deferredResult = new Clipperz.Async.Deferred("addNewRecordAndTestNewRecordIndex_test", someTestArgs);
1529 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']); 1529 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
1530 deferredResult.addMethod(user, 'login'); 1530 deferredResult.addMethod(user, 'login');
1531 1531
1532 deferredResult.addMethod(user, 'getRecords'); 1532 deferredResult.addMethod(user, 'getRecords');
1533 deferredResult.addCallback(function (someRecords) { 1533 deferredResult.addCallback(function (someRecords) {
1534 SimpleTest.is(MochiKit.Base.keys(someRecords).length, 20, "The user has initially 20 records"); 1534 SimpleTest.is(MochiKit.Base.keys(someRecords).length, 20, "The user has initially 20 records");
1535 }); 1535 });
1536 1536
1537 deferredResult.addMethod(user, 'createNewRecord'); 1537 deferredResult.addMethod(user, 'createNewRecord');
1538 deferredResult.addCallback(function (aNewRecord) { 1538 deferredResult.addCallback(function (aNewRecord) {
1539 var innerDeferredResult; 1539 var innerDeferredResult;
1540 1540
1541 innerDeferredResult = new Clipperz.Async.Deferred("addNewRecordAndTestNewRecordIndex_test <internal>", {trace:false}); 1541 innerDeferredResult = new Clipperz.Async.Deferred("addNewRecordAndTestNewRecordIndex_test <internal>", {trace:false});
1542 1542
1543 innerDeferredResult.addMethod(user, 'getHeaderIndex', 'recordsIndex'); 1543 innerDeferredResult.addMethod(user, 'getHeaderIndex', 'recordsIndex');
1544 innerDeferredResult.addMethodcaller('recordsIndex'); 1544 innerDeferredResult.addMethodcaller('recordsIndex');
1545 innerDeferredResult.addCallback(MochiKit.Base.itemgetter(aNewRecord.reference())); 1545 innerDeferredResult.addCallback(MochiKit.Base.itemgetter(aNewRecord.reference()));
1546 innerDeferredResult.addTest(20, "The index of the new record should be 20"); 1546 innerDeferredResult.addTest(20, "The index of the new record should be 20");
1547 1547
1548 innerDeferredResult.callback(); 1548 innerDeferredResult.callback();
1549 1549
1550 return innerDeferredResult; 1550 return innerDeferredResult;
1551 }) 1551 })
1552 1552
1553 deferredResult.callback(); 1553 deferredResult.callback();
1554 1554
1555 return deferredResult; 1555 return deferredResult;
1556 }, 1556 },
1557 1557
1558 //------------------------------------------------------------------------- 1558 //-------------------------------------------------------------------------
1559 1559
1560 'editRecordAndTestForChangesInPreferencesAndOTP_test': function (someTestArgs) { 1560 'editRecordAndTestForChangesInPreferencesAndOTP_test': function (someTestArgs) {
1561 var deferredResult; 1561 var deferredResult;
1562 var proxy; 1562 var proxy;
1563 var user; 1563 var user;
1564 var user_2; 1564 var user_2;
1565 var originalPreferences; 1565 var originalPreferences;
1566 var originalOTPs; 1566 var originalOTPs;
1567 1567
1568 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false}); 1568 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
1569 user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}}); 1569 user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
1570 user_2 = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}}); 1570 user_2 = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
1571 1571
1572 deferredResult = new Clipperz.Async.Deferred("editRecordAndTestForChangesInPreferencesAndOTP_test", someTestArgs); 1572 deferredResult = new Clipperz.Async.Deferred("editRecordAndTestForChangesInPreferencesAndOTP_test", someTestArgs);
1573 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_with_preferences_and_OTPs_data']); 1573 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_with_preferences_and_OTPs_data']);
1574 deferredResult.addMethod(user, 'login'); 1574 deferredResult.addMethod(user, 'login');
1575 deferredResult.addMethod(user, 'getServerData'); 1575 deferredResult.addMethod(user, 'getServerData');
1576 1576
1577 deferredResult.collectResults({ 1577 deferredResult.collectResults({
1578 'preferences': [ 1578 'preferences': [
1579 MochiKit.Base.method(user, 'getHeaderIndex', 'preferences'), 1579 MochiKit.Base.method(user, 'getHeaderIndex', 'preferences'),
1580 MochiKit.Base.methodcaller('getDecryptedData') 1580 MochiKit.Base.methodcaller('getDecryptedData')
1581 ], 1581 ],
1582 'oneTimePasswords': [ 1582 'oneTimePasswords': [
1583 MochiKit.Base.method(user, 'getHeaderIndex', 'oneTimePasswords'), 1583 MochiKit.Base.method(user, 'getHeaderIndex', 'oneTimePasswords'),
1584 MochiKit.Base.methodcaller('getDecryptedData') 1584 MochiKit.Base.methodcaller('getDecryptedData')
1585 ] 1585 ]
1586 }); 1586 });
1587 1587
1588 deferredResult.addCallback(function (someValues) { 1588 deferredResult.addCallback(function (someValues) {
1589//console.log("SOME VALUES", someValues); 1589//console.log("SOME VALUES", someValues);
1590 originalPreferences = Clipperz.Base.deepClone(someValues['preferences']); 1590 originalPreferences = Clipperz.Base.deepClone(someValues['preferences']);
1591 originalOTPs = Clipperz.Base.deepClone(someValues['oneTimePasswords']); 1591 originalOTPs = Clipperz.Base.deepClone(someValues['oneTimePasswords']);
1592 1592
1593 SimpleTest.is(originalPreferences['preferredLanguage'], 'en-US', "Preference.language is ok"); 1593 SimpleTest.is(originalPreferences['preferredLanguage'], 'en-US', "Preference.language is ok");
1594 SimpleTest.is(originalPreferences['shouldShowDonationPanel'], false, "Preference.shouldShowDonationPanel is ok"); 1594 SimpleTest.is(originalPreferences['shouldShowDonationPanel'], false, "Preference.shouldShowDonationPanel is ok");
1595 1595
1596 SimpleTest.is(MochiKit.Base.keys(originalOTPs).length, 6, "the number of OTPs is as expected"); 1596 SimpleTest.is(MochiKit.Base.keys(originalOTPs).length, 6, "the number of OTPs is as expected");
1597 }); 1597 });
1598 1598
1599 deferredResult.addMethod(user, 'getRecord', '35b30f9e923ce913365815d44cf344ce66cb71b636093b8ec55b8245d13df82b'); 1599 deferredResult.addMethod(user, 'getRecord', '35b30f9e923ce913365815d44cf344ce66cb71b636093b8ec55b8245d13df82b');
1600 deferredResult.addCallback(MochiKit.Base.methodcaller('setLabel', "NEW LABEL")); 1600 deferredResult.addCallback(MochiKit.Base.methodcaller('setLabel', "NEW LABEL"));
1601 deferredResult.addMethod(user, 'saveChanges'); 1601 deferredResult.addMethod(user, 'saveChanges');
1602 1602
1603 deferredResult.addMethod(user_2, 'login'); 1603 deferredResult.addMethod(user_2, 'login');
1604 deferredResult.addMethod(user_2, 'getServerData'); 1604 deferredResult.addMethod(user_2, 'getServerData');
1605 1605
1606 deferredResult.collectResults({ 1606 deferredResult.collectResults({
1607 'preferences': [ 1607 'preferences': [
1608 MochiKit.Base.method(user_2, 'getHeaderIndex', 'preferences'), 1608 MochiKit.Base.method(user_2, 'getHeaderIndex', 'preferences'),
1609 MochiKit.Base.methodcaller('getDecryptedData') 1609 MochiKit.Base.methodcaller('getDecryptedData')
1610 ], 1610 ],
1611 'oneTimePasswords': [ 1611 'oneTimePasswords': [
1612 MochiKit.Base.method(user_2, 'getHeaderIndex', 'oneTimePasswords'), 1612 MochiKit.Base.method(user_2, 'getHeaderIndex', 'oneTimePasswords'),
1613 MochiKit.Base.methodcaller('getDecryptedData') 1613 MochiKit.Base.methodcaller('getDecryptedData')
1614 ] 1614 ]
1615 }); 1615 });
1616 1616
1617 deferredResult.addCallback(function (someValues) { 1617 deferredResult.addCallback(function (someValues) {
1618//console.log("SOME VALUES", someValues); 1618//console.log("SOME VALUES", someValues);
1619 // originalPreferences = Clipperz.Base.deepClone(someValues['preferences']); 1619 // originalPreferences = Clipperz.Base.deepClone(someValues['preferences']);
1620 // originalOTPs = Clipperz.Base.deepClone(someValues['oneTimePasswords']); 1620 // originalOTPs = Clipperz.Base.deepClone(someValues['oneTimePasswords']);
1621 1621
1622 SimpleTest.is(someValues['preferences']['preferredLanguage'], originalPreferences['preferredLanguage'], "Preference.language is preserved"); 1622 SimpleTest.is(someValues['preferences']['preferredLanguage'], originalPreferences['preferredLanguage'], "Preference.language is preserved");
1623 SimpleTest.is(someValues['preferences']['shouldShowDonationPanel'], originalPreferences['shouldShowDonationPanel'], "Preference.shouldShowDonationPanel is preserved"); 1623 SimpleTest.is(someValues['preferences']['shouldShowDonationPanel'], originalPreferences['shouldShowDonationPanel'], "Preference.shouldShowDonationPanel is preserved");
1624 1624
1625 SimpleTest.is(MochiKit.Base.keys(someValues['oneTimePasswords']).length, MochiKit.Base.keys(originalOTPs).length, "the number of OTPs is preserved"); 1625 SimpleTest.is(MochiKit.Base.keys(someValues['oneTimePasswords']).length, MochiKit.Base.keys(originalOTPs).length, "the number of OTPs is preserved");
1626 }); 1626 });
1627 1627
1628 deferredResult.callback(); 1628 deferredResult.callback();
1629 1629
1630 return deferredResult; 1630 return deferredResult;
1631 }, 1631 },
1632 1632
1633 //------------------------------------------------------------------------- 1633 //-------------------------------------------------------------------------
1634 1634
1635 'addRecordAndSaveChangesMultipleTimes_test': function (someTestArgs) { 1635 'addRecordAndSaveChangesMultipleTimes_test': function (someTestArgs) {
1636 var deferredResult; 1636 var deferredResult;
1637 var proxy; 1637 var proxy;
1638 var user; 1638 var user;
1639 1639
1640 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false}); 1640 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
1641 user = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}}); 1641 user = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}});
1642 user2 = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}}); 1642 user2 = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}});
1643 1643
1644 deferredResult = new Clipperz.Async.Deferred("addRecordAndSaveChangesMultipleTimes_test", someTestArgs); 1644 deferredResult = new Clipperz.Async.Deferred("addRecordAndSaveChangesMultipleTimes_test", someTestArgs);
1645 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_someExtraOldData']); 1645 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_someExtraOldData']);
1646 deferredResult.addMethod(user, 'login'); 1646 deferredResult.addMethod(user, 'login');
1647 1647
1648 deferredResult.addMethod(user, 'getRecords'); 1648 deferredResult.addMethod(user, 'getRecords');
1649 deferredResult.addCallback(MochiKit.Base.itemgetter('length')); 1649 deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
1650 deferredResult.addTest(1, "The user has one record stored in its account"); 1650 deferredResult.addTest(1, "The user has one record stored in its account");
1651 1651
1652 deferredResult.addMethod(user, 'hasPendingChanges'); 1652 deferredResult.addMethod(user, 'hasPendingChanges');
1653 deferredResult.addTest(false, "After loading records, the user should have no pending changes"); 1653 deferredResult.addTest(false, "After loading records, the user should have no pending changes");
1654 1654
1655 deferredResult.addMethod(user, 'createNewRecord'); 1655 deferredResult.addMethod(user, 'createNewRecord');
1656 deferredResult.addCallback(function (aNewRecord) { 1656 deferredResult.addCallback(function (aNewRecord) {
1657 var innerDeferredResult; 1657 var innerDeferredResult;
1658 1658
1659 innerDeferredResult = new Clipperz.Async.Deferred("addRecordAndSaveChangesMultipleTimes_test <internal [1]>", {trace:false}); 1659 innerDeferredResult = new Clipperz.Async.Deferred("addRecordAndSaveChangesMultipleTimes_test <internal [1]>", {trace:false});
1660 1660
1661 innerDeferredResult.addMethod(aNewRecord, 'setLabel', "New record 1"); 1661 innerDeferredResult.addMethod(aNewRecord, 'setLabel', "New record 1");
1662 innerDeferredResult.addMethod(aNewRecord, 'addField', {'label':'record number', 'value':"1", 'isHidden':false}); 1662 innerDeferredResult.addMethod(aNewRecord, 'addField', {'label':'record number', 'value':"1", 'isHidden':false});
1663 innerDeferredResult.addMethod(aNewRecord, 'addField', {'label':'field count', 'value':"2", 'isHidden':false}); 1663 innerDeferredResult.addMethod(aNewRecord, 'addField', {'label':'field count', 'value':"2", 'isHidden':false});
1664 innerDeferredResult.callback(); 1664 innerDeferredResult.callback();
1665 1665
1666 return innerDeferredResult; 1666 return innerDeferredResult;
1667 }) 1667 })
1668 1668
1669 deferredResult.addMethod(user, 'hasPendingChanges'); 1669 deferredResult.addMethod(user, 'hasPendingChanges');
1670 deferredResult.addTest(true, "Before saving, the user has pending changes"); 1670 deferredResult.addTest(true, "Before saving, the user has pending changes");
1671 1671
1672 deferredResult.addMethod(user, 'saveChanges'); 1672 deferredResult.addMethod(user, 'saveChanges');
1673 deferredResult.addCallback(SimpleTest.ok, true, "Saving worked (apparently) fine"); 1673 deferredResult.addCallback(SimpleTest.ok, true, "Saving worked (apparently) fine");
1674 1674
1675 deferredResult.addMethod(user, 'hasPendingChanges'); 1675 deferredResult.addMethod(user, 'hasPendingChanges');
1676 deferredResult.addTest(false, "After saving, the user has no pending changes"); 1676 deferredResult.addTest(false, "After saving, the user has no pending changes");
1677 1677
1678 deferredResult.addMethod(user, 'createNewRecord'); 1678 deferredResult.addMethod(user, 'createNewRecord');
1679 deferredResult.addCallback(function (aNewRecord) { 1679 deferredResult.addCallback(function (aNewRecord) {
1680 var innerDeferredResult; 1680 var innerDeferredResult;
1681 1681
1682 innerDeferredResult = new Clipperz.Async.Deferred("addRecordAndSaveChangesMultipleTimes_test <internal [2]>", {trace:false}); 1682 innerDeferredResult = new Clipperz.Async.Deferred("addRecordAndSaveChangesMultipleTimes_test <internal [2]>", {trace:false});
1683 1683
1684 innerDeferredResult.addMethod(aNewRecord, 'setLabel', "New record 2"); 1684 innerDeferredResult.addMethod(aNewRecord, 'setLabel', "New record 2");
1685 innerDeferredResult.addMethod(aNewRecord, 'addField', {'label':"record number", 'value':"2", 'isHidden':false}); 1685 innerDeferredResult.addMethod(aNewRecord, 'addField', {'label':"record number", 'value':"2", 'isHidden':false});
1686 innerDeferredResult.callback(); 1686 innerDeferredResult.callback();
1687 1687
1688 return innerDeferredResult; 1688 return innerDeferredResult;
1689 }) 1689 })
1690 deferredResult.addMethod(user, 'saveChanges'); 1690 deferredResult.addMethod(user, 'saveChanges');
1691 1691
1692 deferredResult.addMethod(user, 'getRecords'); 1692 deferredResult.addMethod(user, 'getRecords');
1693 deferredResult.addCallback(MochiKit.Base.itemgetter('length')); 1693 deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
1694 deferredResult.addTest(3, "After having created two new records, the total should be updated accordingly"); 1694 deferredResult.addTest(3, "After having created two new records, the total should be updated accordingly");
1695 1695
1696 1696
1697 deferredResult.addMethod(user2, 'login'); 1697 deferredResult.addMethod(user2, 'login');
1698 deferredResult.addMethod(user2, 'getRecords'); 1698 deferredResult.addMethod(user2, 'getRecords');
1699 deferredResult.addCallback(MochiKit.Base.itemgetter('length')); 1699 deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
1700 deferredResult.addTest(3, "Reloading the data, three records are available"); 1700 deferredResult.addTest(3, "Reloading the data, three records are available");
1701 1701
1702 deferredResult.addMethod(user2, 'recordWithLabel', 'New record 1'); 1702 deferredResult.addMethod(user2, 'recordWithLabel', 'New record 1');
1703//deferredResult.addCallback(function (aValue) { console.log("RECORD with Label", aValue); return aValue; }); 1703//deferredResult.addCallback(function (aValue) { console.log("RECORD with Label", aValue); return aValue; });
1704 deferredResult.collectResults({ 1704 deferredResult.collectResults({
1705 'label':[ 1705 'label':[
1706 MochiKit.Base.methodcaller('label'), 1706 MochiKit.Base.methodcaller('label'),
1707 MochiKit.Base.partial(Clipperz.Async.Test.is, 'New record label', "The label is correct") 1707 MochiKit.Base.partial(Clipperz.Async.Test.is, 'New record label', "The label is correct")
1708 ], 1708 ],
1709 'notes':[ 1709 'notes':[
1710 MochiKit.Base.methodcaller('notes'), 1710 MochiKit.Base.methodcaller('notes'),
1711 Clipperz.Async.Test.is('', "The note of the new created record is empty") 1711 Clipperz.Async.Test.is('', "The note of the new created record is empty")
1712 ], 1712 ],
1713 'fields':[ 1713 'fields':[
1714 MochiKit.Base.methodcaller('fields'), 1714 MochiKit.Base.methodcaller('fields'),
1715 MochiKit.Base.values, 1715 MochiKit.Base.values,
1716 MochiKit.Base.itemgetter('length'), 1716 MochiKit.Base.itemgetter('length'),
1717 Clipperz.Async.Test.is(2, "The new record has just one field, as expected") 1717 Clipperz.Async.Test.is(2, "The new record has just one field, as expected")
1718 ], 1718 ],
1719 'fieldValues_1': [ 1719 'fieldValues_1': [
1720 MochiKit.Base.methodcaller('fieldWithLabel', 'record number'), 1720 MochiKit.Base.methodcaller('fieldWithLabel', 'record number'),
1721 MochiKit.Base.methodcaller('value'), 1721 MochiKit.Base.methodcaller('value'),
1722 Clipperz.Async.Test.is('1', "The field value is as expected") 1722 Clipperz.Async.Test.is('1', "The field value is as expected")
1723 ], 1723 ],
1724 'fieldValues_2': [ 1724 'fieldValues_2': [
1725 MochiKit.Base.methodcaller('fieldWithLabel', 'field count'), 1725 MochiKit.Base.methodcaller('fieldWithLabel', 'field count'),
1726 MochiKit.Base.methodcaller('value'), 1726 MochiKit.Base.methodcaller('value'),
1727 Clipperz.Async.Test.is('2', "Also the second field value is as expected") 1727 Clipperz.Async.Test.is('2', "Also the second field value is as expected")
1728 ] 1728 ]
1729 }) 1729 })
1730 1730
1731 deferredResult.callback(); 1731 deferredResult.callback();
1732 1732
1733 return deferredResult; 1733 return deferredResult;
1734 }, 1734 },
1735 1735
1736 //------------------------------------------------------------------------- 1736 //-------------------------------------------------------------------------
1737 1737
1738 'addNewRecordAndRevertChanges_test': function (someTestArgs) { 1738 'addNewRecordAndRevertChanges_test': function (someTestArgs) {
1739 var deferredResult; 1739 var deferredResult;
1740 var proxy; 1740 var proxy;
1741 var user, user2; 1741 var user, user2;
1742 1742
1743 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false}); 1743 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
1744 user = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}}); 1744 user = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}});
1745 user2 = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}}); 1745 user2 = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}});
1746 1746
1747 deferredResult = new Clipperz.Async.Deferred("addNewRecordAndRevertChanges_test", someTestArgs); 1747 deferredResult = new Clipperz.Async.Deferred("addNewRecordAndRevertChanges_test", someTestArgs);
1748 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_someExtraOldData']); 1748 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_someExtraOldData']);
1749 deferredResult.addMethod(user, 'login'); 1749 deferredResult.addMethod(user, 'login');
1750 1750
1751 deferredResult.addMethod(user, 'getRecords'); 1751 deferredResult.addMethod(user, 'getRecords');
1752 deferredResult.addCallback(function (someRecords) { 1752 deferredResult.addCallback(function (someRecords) {
1753 SimpleTest.is(MochiKit.Base.keys(someRecords).length, 1, "The user has initially just one record"); 1753 SimpleTest.is(MochiKit.Base.keys(someRecords).length, 1, "The user has initially just one record");
1754 }); 1754 });
1755 1755
1756 deferredResult.addMethod(user, 'createNewRecord'); 1756 deferredResult.addMethod(user, 'createNewRecord');
1757 deferredResult.addCallback(function (aNewRecord) { 1757 deferredResult.addCallback(function (aNewRecord) {
1758 returnClipperz.Async.callbacks("addNewRecordAndRevertChanges_test <internal>", [ 1758 returnClipperz.Async.callbacks("addNewRecordAndRevertChanges_test <internal>", [
1759 MochiKit.Base.method(aNewRecord, 'setLabel', "New record label"), 1759 MochiKit.Base.method(aNewRecord, 'setLabel', "New record label"),
1760 MochiKit.Base.method(aNewRecord, 'setNotes', "New record notes"), 1760 MochiKit.Base.method(aNewRecord, 'setNotes', "New record notes"),
1761 MochiKit.Base.method(aNewRecord, 'addField', {'label':"Label 1", 'value':"Value 1", 'isHidden':false}), 1761 MochiKit.Base.method(aNewRecord, 'addField', {'label':"Label 1", 'value':"Value 1", 'isHidden':false}),
1762 MochiKit.Base.method(aNewRecord, 'addField', {'label':"Label 2", 'value':"Value 2", 'isHidden':false}), 1762 MochiKit.Base.method(aNewRecord, 'addField', {'label':"Label 2", 'value':"Value 2", 'isHidden':false}),
1763 MochiKit.Base.method(aNewRecord, 'addField', {'label':"Label 3", 'value':"Value 3", 'isHidden':true}), 1763 MochiKit.Base.method(aNewRecord, 'addField', {'label':"Label 3", 'value':"Value 3", 'isHidden':true}),
1764 MochiKit.Base.method(aNewRecord, 'addField', {'label':"Label 4", 'value':"Value 4", 'isHidden':false}) 1764 MochiKit.Base.method(aNewRecord, 'addField', {'label':"Label 4", 'value':"Value 4", 'isHidden':false})
1765 ], {trace:false}); 1765 ], {trace:false});
1766 }) 1766 })
1767 1767
1768 deferredResult.addMethod(user, 'getRecords'); 1768 deferredResult.addMethod(user, 'getRecords');
1769 deferredResult.addCallback(function (someRecords) { 1769 deferredResult.addCallback(function (someRecords) {
1770 SimpleTest.is(MochiKit.Base.keys(someRecords).length, 2, "After having created a new record, the total should be updated accordingly"); 1770 SimpleTest.is(MochiKit.Base.keys(someRecords).length, 2, "After having created a new record, the total should be updated accordingly");
1771 }); 1771 });
1772 1772
1773 deferredResult.addMethod(user, 'getRecord', '05aad20ee399b11ddc923e601fcd1d096233634f2ad4c55db4f6435e5f9cc17a'); 1773 deferredResult.addMethod(user, 'getRecord', '05aad20ee399b11ddc923e601fcd1d096233634f2ad4c55db4f6435e5f9cc17a');
1774 deferredResult.addMethodcaller('hasPendingChanges'); 1774 deferredResult.addMethodcaller('hasPendingChanges');
1775 deferredResult.addTest(false, "adding a new record should not trigger any changes on a sibling record"); 1775 deferredResult.addTest(false, "adding a new record should not trigger any changes on a sibling record");
1776 1776
1777 deferredResult.addMethod(user, 'hasPendingChanges'); 1777 deferredResult.addMethod(user, 'hasPendingChanges');
1778 deferredResult.addTest(true, "adding a new record should trigger the 'has pending changes' flag on the user"); 1778 deferredResult.addTest(true, "adding a new record should trigger the 'has pending changes' flag on the user");
1779 1779
1780 deferredResult.addMethod(user, 'revertChanges'); 1780 deferredResult.addMethod(user, 'revertChanges');
1781 deferredResult.addMethod(user, 'hasPendingChanges'); 1781 deferredResult.addMethod(user, 'hasPendingChanges');
1782 deferredResult.addTest(false, "reverting changes shoud restore the previous state on the user"); 1782 deferredResult.addTest(false, "reverting changes shoud restore the previous state on the user");
1783 1783
1784 deferredResult.addMethod(user2, 'login'); 1784 deferredResult.addMethod(user2, 'login');
1785 deferredResult.addMethod(user2, 'getRecords'); 1785 deferredResult.addMethod(user2, 'getRecords');
1786 deferredResult.addCallback(function (someRecords) { 1786 deferredResult.addCallback(function (someRecords) {
1787 SimpleTest.is(someRecords.length, 1, "Reloading the data, just one record is available."); 1787 SimpleTest.is(someRecords.length, 1, "Reloading the data, just one record is available.");
1788 return someRecords; 1788 return someRecords;
1789 }); 1789 });
1790 1790
1791 deferredResult.callback(); 1791 deferredResult.callback();
1792 1792
1793 return deferredResult; 1793 return deferredResult;
1794 }, 1794 },
1795 1795
1796 //------------------------------------------------------------------------- 1796 //-------------------------------------------------------------------------
1797 1797
1798 'logout_test': function (someTestArgs) { 1798 'logout_test': function (someTestArgs) {
1799 var deferredResult; 1799 var deferredResult;
1800 var proxy; 1800 var proxy;
1801 var user; 1801 var user;
1802 1802
1803 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false}); 1803 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
1804 user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}}); 1804 user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
1805 1805
1806 deferredResult = new Clipperz.Async.Deferred("logout_test", someTestArgs); 1806 deferredResult = new Clipperz.Async.Deferred("logout_test", someTestArgs);
1807 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_with_preferences_and_OTPs_data']); 1807 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_with_preferences_and_OTPs_data']);
1808 deferredResult.addMethod(user, 'login'); 1808 deferredResult.addMethod(user, 'login');
1809 1809
1810 deferredResult.addMethod(user, 'getRecords'); 1810 deferredResult.addMethod(user, 'getRecords');
1811 deferredResult.addCallback(function (someRecords) { 1811 deferredResult.addCallback(function (someRecords) {
1812 SimpleTest.is(MochiKit.Base.keys(someRecords).length, 18, "The user has 18 records"); 1812 SimpleTest.is(MochiKit.Base.keys(someRecords).length, 18, "The user has 18 records");
1813 }); 1813 });
1814 1814
1815 deferredResult.addMethod(user, 'logout'); 1815 deferredResult.addMethod(user, 'logout');
1816 deferredResult.shouldSucceed("Logging out should not trigger an exception"); 1816 deferredResult.shouldSucceed("Logging out should not trigger an exception");
1817 1817
1818 deferredResult.callback(); 1818 deferredResult.callback();
1819 1819
1820 return deferredResult; 1820 return deferredResult;
1821 }, 1821 },
1822 1822
1823 //------------------------------------------------------------------------- 1823 //-------------------------------------------------------------------------
1824 1824
1825 'lock_test': function (someTestArgs) { 1825 'lock_test': function (someTestArgs) {
1826 var deferredResult; 1826 var deferredResult;
1827 var proxy; 1827 var proxy;
1828 var user; 1828 var user;
1829 var returnPassword= function () { return MochiKit.Async.succeed('clipperz'); }; 1829 var returnPassword= function () { return MochiKit.Async.succeed('clipperz'); };
1830 var failPassword= function () { throw "Unexpected access to the password"; }; 1830 var failPassword= function () { throw "Unexpected access to the password"; };
1831 var currentPasswordFunction = returnPassword; 1831 var currentPasswordFunction = returnPassword;
1832 var passwordFunction = function () { return currentPasswordFunction(); }; 1832 var passwordFunction = function () { return currentPasswordFunction(); };
1833 1833
1834 1834
1835 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false}); 1835 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
1836 user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:passwordFunction}); 1836 user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:passwordFunction});
1837 1837
1838 deferredResult = new Clipperz.Async.Deferred("lock_test", someTestArgs); 1838 deferredResult = new Clipperz.Async.Deferred("lock_test", someTestArgs);
1839 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_with_preferences_and_OTPs_data']); 1839 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_with_preferences_and_OTPs_data']);
1840 1840
1841 deferredResult.addMethod(user, 'login'); 1841 deferredResult.addMethod(user, 'login');
1842 1842
1843 deferredResult.addMethod(user, 'getRecords'); 1843 deferredResult.addMethod(user, 'getRecords');
1844 deferredResult.addCallback(function (someRecords) { 1844 deferredResult.addCallback(function (someRecords) {
1845 SimpleTest.is(MochiKit.Base.keys(someRecords).length, 18, "The user has 18 records"); 1845 SimpleTest.is(MochiKit.Base.keys(someRecords).length, 18, "The user has 18 records");
1846 }); 1846 });
1847 1847
1848 deferredResult.addMethod(user, 'getDirectLogins'); 1848 deferredResult.addMethod(user, 'getDirectLogins');
1849 deferredResult.addCallback(function (someDirectLogins) { 1849 deferredResult.addCallback(function (someDirectLogins) {
1850 SimpleTest.is(MochiKit.Base.keys(someDirectLogins).length, 22, "The user has 22 direct logins"); 1850 SimpleTest.is(MochiKit.Base.keys(someDirectLogins).length, 22, "The user has 22 direct logins");
1851 }); 1851 });
1852 1852
1853 deferredResult.addMethod(proxy, 'shouldNotReceiveAnyFurtherRequest'); 1853 deferredResult.addMethod(proxy, 'shouldNotReceiveAnyFurtherRequest');
1854 deferredResult.addCallback(function () { currentPasswordFunction = failPassword; }); 1854 deferredResult.addCallback(function () { currentPasswordFunction = failPassword; });
1855 1855
1856 deferredResult.addMethod(user, 'lock'); 1856 deferredResult.addMethod(user, 'lock');
1857 deferredResult.shouldSucceed("Locking out should not trigger an exception"); 1857 deferredResult.shouldSucceed("Locking out should not trigger an exception");
1858 1858
1859 deferredResult.addMethod(proxy, 'unexpectedRequests'); 1859 deferredResult.addMethod(proxy, 'unexpectedRequests');
1860 deferredResult.addCallback(MochiKit.Base.itemgetter('length')); 1860 deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
1861 deferredResult.addTest(0, "The proxy should have not received any extra request"); 1861 deferredResult.addTest(0, "The proxy should have not received any extra request");
1862//deferredResult.addCallback(function (aValue) { console.log("PROXY.unexpectedRequests", Clipperz.Base.serializeJSON(proxy.unexpectedRequests())); return aValue; }); 1862//deferredResult.addCallback(function (aValue) { console.log("PROXY.unexpectedRequests", Clipperz.Base.serializeJSON(proxy.unexpectedRequests())); return aValue; });
1863 deferredResult.addMethod(proxy, 'mayReceiveMoreRequests'); 1863 deferredResult.addMethod(proxy, 'mayReceiveMoreRequests');
1864 deferredResult.addCallback(function () { currentPasswordFunction = returnPassword; }); 1864 deferredResult.addCallback(function () { currentPasswordFunction = returnPassword; });
1865 1865
1866 deferredResult.callback(); 1866 deferredResult.callback();
1867 1867
1868 return deferredResult; 1868 return deferredResult;
1869 }, 1869 },
1870 1870
1871 //------------------------------------------------------------------------- 1871 //-------------------------------------------------------------------------
1872 1872
1873 'registerNewUser_test': function (someTestArgs) { 1873 'registerNewUser_test': function (someTestArgs) {
1874 var deferredResult; 1874 var deferredResult;
1875 var proxy; 1875 var proxy;
1876 var user, user2; 1876 var user, user2;
1877 var username; 1877 var username;
1878 var passphrase; 1878 var passphrase;
1879 1879
1880 username = "new"; 1880 username = "new";
1881 passphrase = "user"; 1881 passphrase = "user";
1882 1882
1883 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false}); 1883 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
1884 // user2 = new Clipperz.PM.DataModel.User({username:username, getPassphraseFunction:function () { return MochiKit.Async.succeed(passphrase);}}); 1884 // user2 = new Clipperz.PM.DataModel.User({username:username, getPassphraseFunction:function () { return MochiKit.Async.succeed(passphrase);}});
1885 user2 = new Clipperz.PM.DataModel.User({username:username, getPassphraseFunction:function () { return passphrase;}}); 1885 user2 = new Clipperz.PM.DataModel.User({username:username, getPassphraseFunction:function () { return passphrase;}});
1886 1886
1887 deferredResult = new Clipperz.Async.Deferred("registerNewUser_test", someTestArgs); 1887 deferredResult = new Clipperz.Async.Deferred("registerNewUser_test", someTestArgs);
1888 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_with_preferences_and_OTPs_data']); 1888 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_with_preferences_and_OTPs_data']);
1889 1889
1890 deferredResult.addCallback(Clipperz.PM.DataModel.User.registerNewAccount, username, function () { return MochiKit.Async.succeed(passphrase);}); 1890 deferredResult.addCallback(Clipperz.PM.DataModel.User.registerNewAccount, username, function () { return MochiKit.Async.succeed(passphrase);});
1891 deferredResult.setValue('user'); 1891 deferredResult.setValue('user');
1892 1892
1893 deferredResult.addMethodcaller('getRecords'); 1893 deferredResult.addMethodcaller('getRecords');
1894 deferredResult.addCallback(function (someRecords) { 1894 deferredResult.addCallback(function (someRecords) {
1895 SimpleTest.is(MochiKit.Base.keys(someRecords).length, 0, "The newly created user has no records"); 1895 SimpleTest.is(MochiKit.Base.keys(someRecords).length, 0, "The newly created user has no records");
1896 }); 1896 });
1897 deferredResult.getValue('user'); 1897 deferredResult.getValue('user');
1898 deferredResult.addMethodcaller('logout'); 1898 deferredResult.addMethodcaller('logout');
1899 1899
1900 deferredResult.addMethod(user2, 'login'); 1900 deferredResult.addMethod(user2, 'login');
1901 deferredResult.addMethod(user2, 'getDirectLogins'); 1901 deferredResult.addMethod(user2, 'getDirectLogins');
1902 deferredResult.addCallback(function (someDirectLogins) { 1902 deferredResult.addCallback(function (someDirectLogins) {
1903 SimpleTest.is(MochiKit.Base.keys(someDirectLogins).length, 0, "The user has no direct logins"); 1903 SimpleTest.is(MochiKit.Base.keys(someDirectLogins).length, 0, "The user has no direct logins");
1904 }); 1904 });
1905 1905
1906 deferredResult.callback(); 1906 deferredResult.callback();
1907 1907
1908 return deferredResult; 1908 return deferredResult;
1909 }, 1909 },
1910 1910
1911 //------------------------------------------------------------------------- 1911 //-------------------------------------------------------------------------
1912 1912
1913 'registerNewUserAndAddARecord_test': function (someTestArgs) { 1913 'registerNewUserAndAddARecord_test': function (someTestArgs) {
1914 var deferredResult; 1914 var deferredResult;
1915 var proxy; 1915 var proxy;
1916 var user, user2; 1916 var user, user2;
1917 var username; 1917 var username;
1918 var passphrase; 1918 var passphrase;
1919 1919
1920 username = "new"; 1920 username = "new";
1921 passphrase = "user"; 1921 passphrase = "user";
1922 1922
1923 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false}); 1923 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
1924 user2 = new Clipperz.PM.DataModel.User({username:username, getPassphraseFunction:function () { return passphrase;}}); 1924 user2 = new Clipperz.PM.DataModel.User({username:username, getPassphraseFunction:function () { return passphrase;}});
1925 1925console.log("PROXY", proxy);
1926 deferredResult = new Clipperz.Async.Deferred("registerNewUserAndAddARecord_test", someTestArgs); 1926 deferredResult = new Clipperz.Async.Deferred("registerNewUserAndAddARecord_test", someTestArgs);
1927 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_with_preferences_and_OTPs_data']); 1927 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_with_preferences_and_OTPs_data']);
1928 1928
1929 deferredResult.addCallback(Clipperz.PM.DataModel.User.registerNewAccount, username, function () { return MochiKit.Async.succeed(passphrase);}); 1929 deferredResult.addCallback(Clipperz.PM.DataModel.User.registerNewAccount, username, function () { return MochiKit.Async.succeed(passphrase);});
1930 deferredResult.setValue('user'); 1930 deferredResult.setValue('user');
1931 1931
1932 deferredResult.addMethodcaller('getRecords'); 1932 deferredResult.addMethodcaller('getRecords');
1933 deferredResult.addCallback(function (someRecords) { 1933 deferredResult.addCallback(function (someRecords) {
1934 SimpleTest.is(MochiKit.Base.keys(someRecords).length, 0, "The newly created user has no records"); 1934 SimpleTest.is(MochiKit.Base.keys(someRecords).length, 0, "The newly created user has no records");
1935 }); 1935 });
1936 1936
1937 deferredResult.getValue('user'); 1937 deferredResult.getValue('user');
1938 deferredResult.addMethodcaller('createNewRecord'); 1938 deferredResult.addMethodcaller('createNewRecord');
1939 deferredResult.addCallback(function (aNewRecord) { 1939 deferredResult.addCallback(function (aNewRecord) {
1940 var innerDeferredResult; 1940 var innerDeferredResult;
1941 1941
1942 innerDeferredResult = new Clipperz.Async.Deferred("addRecordAndSaveChangesMultipleTimes_test <internal [1]>", {trace:false}); 1942 innerDeferredResult = new Clipperz.Async.Deferred("addRecordAndSaveChangesMultipleTimes_test <internal [1]>", {trace:false});
1943 1943
1944 innerDeferredResult.addMethod(aNewRecord, 'setLabel', "New record 1"); 1944 innerDeferredResult.addMethod(aNewRecord, 'setLabel', "New record 1");
1945 innerDeferredResult.addMethod(aNewRecord, 'addField', {'label':'record number', 'value':"1", 'isHidden':false}); 1945 innerDeferredResult.addMethod(aNewRecord, 'addField', {'label':'record number', 'value':"1", 'isHidden':false});
1946 innerDeferredResult.addMethod(aNewRecord, 'addField', {'label':'field count', 'value':"2", 'isHidden':false}); 1946 innerDeferredResult.addMethod(aNewRecord, 'addField', {'label':'field count', 'value':"2", 'isHidden':false});
1947 innerDeferredResult.callback(); 1947 innerDeferredResult.callback();
1948 1948
1949 return innerDeferredResult; 1949 return innerDeferredResult;
1950 }) 1950 })
1951 1951
1952 deferredResult.getValue('user'); 1952 deferredResult.getValue('user');
1953 deferredResult.addMethodcaller('saveChanges'); 1953 deferredResult.addMethodcaller('saveChanges');
1954 deferredResult.addCallback(SimpleTest.ok, true, "Saving worked (apparently) fine"); 1954 deferredResult.addCallback(SimpleTest.ok, true, "Saving worked (apparently) fine");
1955 1955
1956 1956
1957 deferredResult.getValue('user'); 1957 deferredResult.getValue('user');
1958 deferredResult.addMethodcaller('logout'); 1958 deferredResult.addMethodcaller('logout');
1959 1959
1960 deferredResult.addMethod(user2, 'login'); 1960 deferredResult.addMethod(user2, 'login');
1961 deferredResult.addMethod(user2, 'getRecords'); 1961 deferredResult.addMethod(user2, 'getRecords');
1962 deferredResult.addCallback(function (someDirectLogins) { 1962 deferredResult.addCallback(function (someDirectLogins) {
1963 SimpleTest.is(MochiKit.Base.keys(someDirectLogins).length, 1, "The user - even after a brand new login - has the newly created record"); 1963 SimpleTest.is(MochiKit.Base.keys(someDirectLogins).length, 1, "The user - even after a brand new login - has the newly created record");
1964 }); 1964 });
1965 1965
1966 deferredResult.callback(); 1966 deferredResult.callback();
1967 1967
1968 return deferredResult; 1968 return deferredResult;
1969 }, 1969 },
1970 1970
1971 //------------------------------------------------------------------------- 1971 //-------------------------------------------------------------------------
1972 1972
1973 'changePassphrase_test': function (someTestArgs) { 1973 'changePassphrase_test': function (someTestArgs) {
1974 var deferredResult; 1974 var deferredResult;
1975 var proxy; 1975 var proxy;
1976 var user; 1976 var user;
1977 var user2; 1977 var user2;
1978 var newPassphrase; 1978 var newPassphrase;
1979 1979
1980 newPassphrase = 'zreppilc'; 1980 newPassphrase = 'zreppilc';
1981 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false}); 1981 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
1982 user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}}); 1982 user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
1983 user2 = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return newPassphrase;}}); 1983 user2 = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return newPassphrase;}});
1984 1984
1985 deferredResult = new Clipperz.Async.Deferred("changePassphrase_test", someTestArgs); 1985 deferredResult = new Clipperz.Async.Deferred("changePassphrase_test", someTestArgs);
1986 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']); 1986 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
1987 1987
1988 deferredResult.addMethod(user, 'login'); 1988 deferredResult.addMethod(user, 'login');
1989 1989
1990 deferredResult.addMethod(user, 'getRecords'); 1990 deferredResult.addMethod(user, 'getRecords');
1991 deferredResult.addCallback(MochiKit.Base.itemgetter('length')); 1991 deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
1992 deferredResult.addTest(20, "This account has oly a single card"); 1992 deferredResult.addTest(20, "This account has oly a single card");
1993 1993
1994 deferredResult.addMethod(user, 'changePassphrase', newPassphrase); 1994 deferredResult.addMethod(user, 'changePassphrase', newPassphrase);
1995 deferredResult.addMethod(user, 'logout'); 1995 deferredResult.addMethod(user, 'logout');
1996 1996
1997 deferredResult.addMethod(user2, 'login'); 1997 deferredResult.addMethod(user2, 'login');
1998 deferredResult.addMethod(user2, 'getRecords'); 1998 deferredResult.addMethod(user2, 'getRecords');
1999 deferredResult.addCallback(MochiKit.Base.itemgetter('length')); 1999 deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
2000 deferredResult.addTest(20, "This account has oly a single card"); 2000 deferredResult.addTest(20, "This account has oly a single card");
2001 2001
2002 deferredResult.callback(); 2002 deferredResult.callback();
2003 2003
2004 return deferredResult; 2004 return deferredResult;
2005 }, 2005 },
2006 2006
2007 //------------------------------------------------------------------------- 2007 //-------------------------------------------------------------------------
2008/* 2008/*
2009 'rearrangeRecordFieldOrderAndSave_test': function (someTestArgs) { 2009 'rearrangeRecordFieldOrderAndSave_test': function (someTestArgs) {
2010 var deferredResult; 2010 var deferredResult;
2011 var proxy; 2011 var proxy;
2012 var user; 2012 var user;
2013 2013
2014 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false}); 2014 proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
2015 user = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}}); 2015 user = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}});
2016 2016
2017 deferredResult = new Clipperz.Async.Deferred("simpleSaveChanges_test", someTestArgs); 2017 deferredResult = new Clipperz.Async.Deferred("simpleSaveChanges_test", someTestArgs);
2018 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_offline_copy_data']); 2018 deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_offline_copy_data']);
2019 deferredResult.addMethod(user, 'login'); 2019 deferredResult.addMethod(user, 'login');
2020 2020
2021 deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13'); 2021 deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
2022 deferredResult.addMethodcaller('fields'); 2022 deferredResult.addMethodcaller('fields');
2023 deferredResult.addCallback(function (someFields) { 2023 deferredResult.addCallback(function (someFields) {
2024 var fields; 2024 var fields;
2025 2025
2026 fields = MochiKit.Base.values(someFields); 2026 fields = MochiKit.Base.values(someFields);
2027 SimpleTest.is(fields.length, 3, "The record has initially 3 fields"); 2027 SimpleTest.is(fields.length, 3, "The record has initially 3 fields");
2028 SimpleTest.is(fields[0].reference(), '6a84c414866dd6d266186f0255a595e9330fb34973c085a81a6e4906876c721b', "the first field is the expected one"); 2028 SimpleTest.is(fields[0].reference(), '6a84c414866dd6d266186f0255a595e9330fb34973c085a81a6e4906876c721b', "the first field is the expected one");
2029 SimpleTest.is(fields[1].reference(), 'fde88847cdbae6f7ee7e38aca1a242492888ff430a79c997bc6ba4afd0540ca2', "the second field is the expected one"); 2029 SimpleTest.is(fields[1].reference(), 'fde88847cdbae6f7ee7e38aca1a242492888ff430a79c997bc6ba4afd0540ca2', "the second field is the expected one");
2030 SimpleTest.is(fields[2].reference(), 'bd4e3bb9d3497f63c4c3a507d4b80f489fdb57deb9d1b342a5e1cff65936a410', "the third field is the expected one"); 2030 SimpleTest.is(fields[2].reference(), 'bd4e3bb9d3497f63c4c3a507d4b80f489fdb57deb9d1b342a5e1cff65936a410', "the third field is the expected one");
2031 }); 2031 });
2032 2032
2033 // "6a84c414866dd6d266186f0255a595e9330fb34973c085a81a6e4906876c721b": { 2033 // "6a84c414866dd6d266186f0255a595e9330fb34973c085a81a6e4906876c721b": {
2034 // "label":"Label 1","value":"Value 1","type":"TXT","hidden":false 2034 // "label":"Label 1","value":"Value 1","type":"TXT","hidden":false
2035 // }, 2035 // },
2036 // "fde88847cdbae6f7ee7e38aca1a242492888ff430a79c997bc6ba4afd0540ca2": { 2036 // "fde88847cdbae6f7ee7e38aca1a242492888ff430a79c997bc6ba4afd0540ca2": {
2037 // "label":"Label 2","value":"Value 2","type":"PWD","hidden":true 2037 // "label":"Label 2","value":"Value 2","type":"PWD","hidden":true
2038 // }, 2038 // },
2039 // "bd4e3bb9d3497f63c4c3a507d4b80f489fdb57deb9d1b342a5e1cff65936a410": { 2039 // "bd4e3bb9d3497f63c4c3a507d4b80f489fdb57deb9d1b342a5e1cff65936a410": {
2040 // "label":"Label 3","value":"http://www.example.com","type":"URL","hidden":false 2040 // "label":"Label 3","value":"http://www.example.com","type":"URL","hidden":false
2041 // } 2041 // }
2042 2042
2043 deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13'); 2043 deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
2044 deferredResult.addCallback(MochiKit.Base.methodcaller('sortFieldReference', [ 2044 deferredResult.addCallback(MochiKit.Base.methodcaller('sortFieldReference', [
2045 'bd4e3bb9d3497f63c4c3a507d4b80f489fdb57deb9d1b342a5e1cff65936a410', 2045 'bd4e3bb9d3497f63c4c3a507d4b80f489fdb57deb9d1b342a5e1cff65936a410',
2046 '6a84c414866dd6d266186f0255a595e9330fb34973c085a81a6e4906876c721b', 2046 '6a84c414866dd6d266186f0255a595e9330fb34973c085a81a6e4906876c721b',
2047 'bd4e3bb9d3497f63c4c3a507d4b80f489fdb57deb9d1b342a5e1cff65936a410' 2047 'bd4e3bb9d3497f63c4c3a507d4b80f489fdb57deb9d1b342a5e1cff65936a410'
2048 ])); 2048 ]));
2049 2049
2050 deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13'); 2050 deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
2051 deferredResult.addMethodcaller('hasPendingChanges'); 2051 deferredResult.addMethodcaller('hasPendingChanges');
2052 deferredResult.addTest(true, "adding a field should mark the record as having pending changes"); 2052 deferredResult.addTest(true, "adding a field should mark the record as having pending changes");
2053 2053
2054 deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13'); 2054 deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
2055 deferredResult.addMethodcaller('fields'); 2055 deferredResult.addMethodcaller('fields');
2056 deferredResult.addCallback(function (someFields) { 2056 deferredResult.addCallback(function (someFields) {
2057 SimpleTest.is(MochiKit.Base.values(someFields).length, 4, "The record has now 4 fields"); 2057 SimpleTest.is(MochiKit.Base.values(someFields).length, 4, "The record has now 4 fields");
2058 }); 2058 });
2059 2059
2060 deferredResult.addMethod(user, 'saveChanges'); 2060 deferredResult.addMethod(user, 'saveChanges');
2061 deferredResult.addMethod(user, 'hasPendingChanges'); 2061 deferredResult.addMethod(user, 'hasPendingChanges');
2062 deferredResult.addTest(false, "saving changes should return the user to a state with not changes pending - 4"); 2062 deferredResult.addTest(false, "saving changes should return the user to a state with not changes pending - 4");
2063 2063
2064 deferredResult.callback(); 2064 deferredResult.callback();
2065 2065
2066 return deferredResult; 2066 return deferredResult;
2067 }, 2067 },
2068*/ 2068*/
2069 //------------------------------------------------------------------------- 2069 //-------------------------------------------------------------------------
2070 'syntaxFix': MochiKit.Base.noop 2070 'syntaxFix': MochiKit.Base.noop
2071}; 2071};
2072 2072
2073 2073
2074 2074
2075//############################################################################# 2075//#############################################################################
2076 2076
2077SimpleTest.runDeferredTests("Clipperz.PM.DataModel.User", tests, {trace:false}); 2077SimpleTest.runDeferredTests("Clipperz.PM.DataModel.User", tests, {trace:false});
diff --git a/frontend/gamma/tests/tests/Clipperz/PM/index.html b/frontend/gamma/tests/tests/Clipperz/PM/index.html
index eeda692..6eb6622 100644
--- a/frontend/gamma/tests/tests/Clipperz/PM/index.html
+++ b/frontend/gamma/tests/tests/Clipperz/PM/index.html
@@ -1,52 +1,53 @@
1<!-- 1<!--
2 2
3Copyright 2008-2013 Clipperz Srl 3Copyright 2008-2013 Clipperz Srl
4 4
5This file is part of Clipperz, the online password manager. 5This file is part of Clipperz, the online password manager.
6For further information about its features and functionalities please 6For further information about its features and functionalities please
7refer to http://www.clipperz.com. 7refer to http://www.clipperz.com.
8 8
9* Clipperz is free software: you can redistribute it and/or modify it 9* Clipperz is free software: you can redistribute it and/or modify it
10 under the terms of the GNU Affero General Public License as published 10 under the terms of the GNU Affero General Public License as published
11 by the Free Software Foundation, either version 3 of the License, or 11 by the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version. 12 (at your option) any later version.
13 13
14* Clipperz is distributed in the hope that it will be useful, but 14* Clipperz is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of 15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU Affero General Public License for more details. 17 See the GNU Affero General Public License for more details.
18 18
19* You should have received a copy of the GNU Affero General Public 19* You should have received a copy of the GNU Affero General Public
20 License along with Clipperz. If not, see http://www.gnu.org/licenses/. 20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
21 21
22--> 22-->
23 23
24<html> 24<html>
25<head> 25<head>
26 <title>Clipperz.PM.* - tests</title> 26 <title>Clipperz.PM.* - tests</title>
27 27
28 <script type="text/javascript" src="../../../../js/MochiKit/MochiKit.js"></script> 28 <script type="text/javascript" src="../../../../js/MochiKit/MochiKit.js"></script>
29 <script type="text/javascript" src="../../../SimpleTest/TestRunner.js"></script> 29 <script type="text/javascript" src="../../../SimpleTest/TestRunner.js"></script>
30</head> 30</head>
31<body> 31<body>
32<script> 32<script>
33TestRunner.runTests( 33TestRunner.runTests(
34// 34//
35 //This is still a complete mess. 35 //This is still a complete mess.
36// 36//
37 //'BookmarkletProcessor.html', 37 //'BookmarkletProcessor.html',
38 'Connection.html', 38 'Connection.html',
39 'Crypto.html', 39 'Crypto.html',
40 'Crypto_v0_4.html',
40 //'Crypto_other_implementation_comparison.html', 41 //'Crypto_other_implementation_comparison.html',
41 'Crypto_performanceEvaluation.html', 42 'Crypto_performanceEvaluation.html',
42 //'CryptoPerformance_ByteArrayArray.html', 43 //'CryptoPerformance_ByteArrayArray.html',
43 //'CryptoPerformance_ByteArrayHex.html', 44 //'CryptoPerformance_ByteArrayHex.html',
44 //'CryptoPerformance_ByteArrayString.html', 45 //'CryptoPerformance_ByteArrayString.html',
45 'Date.html', 46 'Date.html',
46 'PIN.html', 47 'PIN.html',
47 'Proxy.html', 48 'Proxy.html',
48 'Toll.html' 49 'Toll.html'
49); 50);
50</script> 51</script>
51</body> 52</body>
52</html> \ No newline at end of file 53</html> \ No newline at end of file