Diffstat (limited to 'frontend/beta/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js') (more/less context) (ignore whitespace changes)
-rw-r--r-- | frontend/beta/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js | 804 |
1 files changed, 804 insertions, 0 deletions
diff --git a/frontend/beta/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js b/frontend/beta/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js new file mode 100644 index 0000000..4d3ba08 --- a/dev/null +++ b/frontend/beta/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js | |||
@@ -0,0 +1,804 @@ | |||
1 | /* | ||
2 | |||
3 | Copyright 2008-2011 Clipperz Srl | ||
4 | |||
5 | This file is part of Clipperz's Javascript Crypto Library. | ||
6 | Javascript Crypto Library provides web developers with an extensive | ||
7 | and efficient set of cryptographic functions. The library aims to | ||
8 | obtain maximum execution speed while preserving modularity and | ||
9 | reusability. | ||
10 | For further information about its features and functionalities please | ||
11 | refer to http://www.clipperz.com | ||
12 | |||
13 | * Javascript Crypto Library is free software: you can redistribute | ||
14 | it and/or modify it under the terms of the GNU Affero General Public | ||
15 | License as published by the Free Software Foundation, either version | ||
16 | 3 of the License, or (at your option) any later version. | ||
17 | |||
18 | * Javascript Crypto Library is distributed in the hope that it will | ||
19 | be useful, but WITHOUT ANY WARRANTY; without even the implied | ||
20 | warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
21 | See the GNU Affero General Public License for more details. | ||
22 | |||
23 | * You should have received a copy of the GNU Affero General Public | ||
24 | License along with Javascript Crypto Library. If not, see | ||
25 | <http://www.gnu.org/licenses/>. | ||
26 | |||
27 | */ | ||
28 | |||
29 | try { if (typeof(Clipperz.PM.Proxy.Offline) == 'undefined') { throw ""; }} catch (e) { | ||
30 | throw "Clipperz.PM.Proxy.Offline.DataStore depends on Clipperz.PM.Proxy.Offline!"; | ||
31 | } | ||
32 | |||
33 | //============================================================================= | ||
34 | |||
35 | Clipperz.PM.Proxy.Offline.DataStore = function(args) { | ||
36 | args = args || {}; | ||
37 | |||
38 | this._data = args.data || (typeof(_clipperz_dump_data_) != 'undefined' ? _clipperz_dump_data_ : null); | ||
39 | this._isReadOnly = (typeof(args.readOnly) == 'undefined' ? true : args.readOnly); | ||
40 | this._shouldPayTolls = args.shouldPayTolls || false; | ||
41 | |||
42 | this._tolls = {}; | ||
43 | this._connections = {}; | ||
44 | |||
45 | this._b = null; | ||
46 | this._B = null; | ||
47 | this._A = null; | ||
48 | this._userData = null; | ||
49 | |||
50 | return this; | ||
51 | } | ||
52 | |||
53 | //Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.DataStore, Object, { | ||
54 | Clipperz.PM.Proxy.Offline.DataStore.prototype = MochiKit.Base.update(null, { | ||
55 | |||
56 | //------------------------------------------------------------------------- | ||
57 | |||
58 | 'isReadOnly': function () { | ||
59 | return this._isReadOnly; | ||
60 | }, | ||
61 | |||
62 | //------------------------------------------------------------------------- | ||
63 | |||
64 | 'shouldPayTolls': function() { | ||
65 | return this._shouldPayTolls; | ||
66 | }, | ||
67 | |||
68 | //------------------------------------------------------------------------- | ||
69 | |||
70 | 'data': function () { | ||
71 | return this._data; | ||
72 | }, | ||
73 | |||
74 | //------------------------------------------------------------------------- | ||
75 | |||
76 | 'tolls': function () { | ||
77 | return this._tolls; | ||
78 | }, | ||
79 | |||
80 | //------------------------------------------------------------------------- | ||
81 | |||
82 | 'connections': function () { | ||
83 | return this._connections; | ||
84 | }, | ||
85 | |||
86 | //========================================================================= | ||
87 | |||
88 | 'resetData': function() { | ||
89 | this._data = { | ||
90 | 'users': { | ||
91 | 'catchAllUser': { | ||
92 | __masterkey_test_value__: 'masterkey', | ||
93 | s: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00', | ||
94 | v: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00' | ||
95 | } | ||
96 | } | ||
97 | }; | ||
98 | }, | ||
99 | |||
100 | //------------------------------------------------------------------------- | ||
101 | |||
102 | 'setupWithEncryptedData': function(someData) { | ||
103 | this._data = Clipperz.Base.deepClone(someData); | ||
104 | }, | ||
105 | |||
106 | //------------------------------------------------------------------------- | ||
107 | |||
108 | 'setupWithData': function(someData) { | ||
109 | var deferredResult; | ||
110 | var resultData; | ||
111 | var i, c; | ||
112 | |||
113 | //Clipperz.log(">>> Proxy.Test.setupWithData"); | ||
114 | resultData = this._data; | ||
115 | |||
116 | deferredResult = new MochiKit.Async.Deferred(); | ||
117 | c = someData['users'].length; | ||
118 | |||
119 | for (i=0; i<c; i++) { | ||
120 | varnewConnection; | ||
121 | varrecordConfiguration; | ||
122 | |||
123 | deferredResult.addCallback(MochiKit.Base.method(this, 'userSerializedEncryptedData', someData['users'][i])); | ||
124 | deferredResult.addCallback(MochiKit.Base.bind(function(aUserSerializationContext) { | ||
125 | //console.log("SERIALIZED USER", aUserSerializationContext); | ||
126 | resultData['users'][aUserSerializationContext['credentials']['C']] = { | ||
127 | 's': aUserSerializationContext['credentials']['s'], | ||
128 | 'v': aUserSerializationContext['credentials']['v'], | ||
129 | 'version': aUserSerializationContext['data']['connectionVersion'], | ||
130 | 'userDetails': aUserSerializationContext['encryptedData']['user']['header'], | ||
131 | 'userDetailsVersion':aUserSerializationContext['encryptedData']['user']['version'], | ||
132 | 'statistics': aUserSerializationContext['encryptedData']['user']['statistics'], | ||
133 | 'lock': aUserSerializationContext['encryptedData']['user']['lock'], | ||
134 | 'records': this.rearrangeRecordsData(aUserSerializationContext['encryptedData']['records']) | ||
135 | } | ||
136 | }, this)); | ||
137 | } | ||
138 | |||
139 | deferredResult.addCallback(MochiKit.Base.bind(function() { | ||
140 | //console.log("this._data", resultData); | ||
141 | this._data = resultData; | ||
142 | }, this)); | ||
143 | |||
144 | deferredResult.callback(); | ||
145 | //Clipperz.log("<<< Proxy.Test.setupWithData"); | ||
146 | |||
147 | return deferredResult; | ||
148 | }, | ||
149 | |||
150 | //========================================================================= | ||
151 | |||
152 | 'b': function() { | ||
153 | return this._b; | ||
154 | }, | ||
155 | |||
156 | 'set_b': function(aValue) { | ||
157 | this._b = aValue; | ||
158 | }, | ||
159 | |||
160 | //------------------------------------------------------------------------- | ||
161 | |||
162 | 'B': function() { | ||
163 | return this._B; | ||
164 | }, | ||
165 | |||
166 | 'set_B': function(aValue) { | ||
167 | this._B = aValue; | ||
168 | }, | ||
169 | |||
170 | //------------------------------------------------------------------------- | ||
171 | |||
172 | 'A': function() { | ||
173 | return this._A; | ||
174 | }, | ||
175 | |||
176 | 'set_A': function(aValue) { | ||
177 | this._A = aValue; | ||
178 | }, | ||
179 | |||
180 | //------------------------------------------------------------------------- | ||
181 | |||
182 | 'userData': function() { | ||
183 | return this._userData; | ||
184 | }, | ||
185 | |||
186 | 'setUserData': function(aValue) { | ||
187 | this._userData = aValue; | ||
188 | }, | ||
189 | |||
190 | //========================================================================= | ||
191 | |||
192 | 'getTollForRequestType': function (aRequestType) { | ||
193 | varresult; | ||
194 | vartargetValue; | ||
195 | var cost; | ||
196 | |||
197 | targetValue = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2); | ||
198 | switch (aRequestType) { | ||
199 | case 'REGISTER': | ||
200 | cost = 5; | ||
201 | break; | ||
202 | case 'CONNECT': | ||
203 | cost = 5; | ||
204 | break; | ||
205 | case 'MESSAGE': | ||
206 | cost = 2; | ||
207 | break; | ||
208 | } | ||
209 | |||
210 | result = { | ||
211 | requestType: aRequestType, | ||
212 | targetValue: targetValue, | ||
213 | cost: cost | ||
214 | } | ||
215 | |||
216 | if (this.shouldPayTolls()) { | ||
217 | this.tolls()[targetValue] = result; | ||
218 | } | ||
219 | |||
220 | return result; | ||
221 | }, | ||
222 | |||
223 | //------------------------------------------------------------------------- | ||
224 | |||
225 | 'checkToll': function (aFunctionName, someParameters) { | ||
226 | if (this.shouldPayTolls()) { | ||
227 | var localToll; | ||
228 | vartollParameters; | ||
229 | |||
230 | tollParameters = someParameters['toll']; | ||
231 | localToll = this.tolls()[tollParameters['targetValue']]; | ||
232 | |||
233 | if (localToll != null) { | ||
234 | if (! Clipperz.PM.Toll.validate(tollParameters['targetValue'], tollParameters['toll'], localToll['cost'])) { | ||
235 | throw "Toll value too low."; | ||
236 | }; | ||
237 | } else { | ||
238 | throw "Missing toll"; | ||
239 | } | ||
240 | } | ||
241 | }, | ||
242 | |||
243 | //========================================================================= | ||
244 | |||
245 | 'processMessage': function(aFunctionName, someParameters) { | ||
246 | var result; | ||
247 | |||
248 | switch(aFunctionName) { | ||
249 | case 'knock': | ||
250 | result = this._knock(someParameters); | ||
251 | break; | ||
252 | case 'registration': | ||
253 | this.checkToll(aFunctionName, someParameters); | ||
254 | result = this._registration(someParameters.parameters); | ||
255 | break; | ||
256 | case 'handshake': | ||
257 | this.checkToll(aFunctionName, someParameters); | ||
258 | result = this._handshake(someParameters.parameters); | ||
259 | break; | ||
260 | case 'message': | ||
261 | this.checkToll(aFunctionName, someParameters); | ||
262 | result = this._message(someParameters.parameters); | ||
263 | break; | ||
264 | case 'logout': | ||
265 | result = this._logout(someParameters.parameters); | ||
266 | break; | ||
267 | } | ||
268 | |||
269 | return result; | ||
270 | }, | ||
271 | |||
272 | //========================================================================= | ||
273 | |||
274 | '_knock': function(someParameters) { | ||
275 | var result; | ||
276 | |||
277 | result = { | ||
278 | toll: this.getTollForRequestType(someParameters['requestType']) | ||
279 | // toll: { | ||
280 | // requestType: someParameters['requestType'], | ||
281 | // targetValue: "3a1ba0be23580f902885c6c8a6b035e228ed1ca74d77de5f9bb0e0c899f07cfe", | ||
282 | // cost: | ||
283 | // } | ||
284 | } | ||
285 | |||
286 | return result; | ||
287 | }, | ||
288 | |||
289 | //------------------------------------------------------------------------- | ||
290 | |||
291 | '_registration': function(someParameters) { | ||
292 | //console.log("_registration", someParameters); | ||
293 | if (this.isReadOnly() == false) { | ||
294 | if (typeof(this.data()['users'][someParameters['credentials']['C']]) == 'undefined') { | ||
295 | this.data()['users'][someParameters['credentials']['C']] = { | ||
296 | 's': someParameters['credentials']['s'], | ||
297 | 'v': someParameters['credentials']['v'], | ||
298 | 'version':someParameters['credentials']['version'], | ||
299 | // 'lock': someParameters['user']['lock'], | ||
300 | 'lock': Clipperz.Crypto.Base.generateRandomSeed(), | ||
301 | // 'maxNumberOfRecords':'100', | ||
302 | 'userDetails': someParameters['user']['header'], | ||
303 | 'statistics': someParameters['user']['statistics'], | ||
304 | 'userDetailsVersion':someParameters['user']['version'], | ||
305 | 'records':{} | ||
306 | } | ||
307 | } else { | ||
308 | throw "user already exists"; | ||
309 | } | ||
310 | } else { | ||
311 | throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly; | ||
312 | } | ||
313 | |||
314 | result = { | ||
315 | result: { | ||
316 | 'lock': this.data()['users'][someParameters['credentials']['C']]['lock'], | ||
317 | 'result':'done' | ||
318 | }, | ||
319 | toll: this.getTollForRequestType('CONNECT') | ||
320 | } | ||
321 | |||
322 | return MochiKit.Async.succeed(result); | ||
323 | }, | ||
324 | |||
325 | //------------------------------------------------------------------------- | ||
326 | |||
327 | '_handshake': function(someParameters) { | ||
328 | var result; | ||
329 | varnextTollRequestType; | ||
330 | |||
331 | //Clipperz.log(">>> Proxy.Offline.DataStore._handshake"); | ||
332 | result = {}; | ||
333 | if (someParameters.message == "connect") { | ||
334 | var userData; | ||
335 | var randomBytes; | ||
336 | var b, B, v; | ||
337 | |||
338 | //console.log(">>> Proxy.Offline.DataStore._handshake.connect", someParameters); | ||
339 | userData = this.data()['users'][someParameters.parameters.C]; | ||
340 | |||
341 | if ((typeof(userData) != 'undefined') && (userData['version'] == someParameters.version)) { | ||
342 | this.setUserData(userData); | ||
343 | } else { | ||
344 | this.setUserData(this.data()['users']['catchAllUser']); | ||
345 | } | ||
346 | |||
347 | randomBytes = Clipperz.Crypto.Base.generateRandomSeed(); | ||
348 | this.set_b(new Clipperz.Crypto.BigInt(randomBytes, 16)); | ||
349 | v = new Clipperz.Crypto.BigInt(this.userData()['v'], 16); | ||
350 | this.set_B(v.add(Clipperz.Crypto.SRP.g().powerModule(this.b(), Clipperz.Crypto.SRP.n()))); | ||
351 | |||
352 | this.set_A(someParameters.parameters.A); | ||
353 | |||
354 | result['s'] = this.userData()['s']; | ||
355 | result['B'] = this.B().asString(16); | ||
356 | |||
357 | nextTollRequestType = 'CONNECT'; | ||
358 | } else if (someParameters.message == "credentialCheck") { | ||
359 | var v, u, S, A, K, M1; | ||
360 | |||
361 | //console.log(">>> Proxy.Offline.DataStore._handshake.credentialCheck", someParameters); | ||
362 | v = new Clipperz.Crypto.BigInt(this.userData()['v'], 16); | ||
363 | u = new Clipperz.Crypto.BigInt(Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(this.B().asString(10))).toHexString(), 16); | ||
364 | A = new Clipperz.Crypto.BigInt(this.A(), 16); | ||
365 | S = (A.multiply(v.powerModule(u, Clipperz.Crypto.SRP.n()))).powerModule(this.b(), Clipperz.Crypto.SRP.n()); | ||
366 | |||
367 | K = Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(S.asString(10))).toHexString().slice(2); | ||
368 | |||
369 | M1 = Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(A.asString(10) + this.B().asString(10) + K)).toHexString().slice(2); | ||
370 | if (someParameters.parameters.M1 == M1) { | ||
371 | var M2; | ||
372 | |||
373 | M2 = Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(A.asString(10) + someParameters.parameters.M1 + K)).toHexString().slice(2); | ||
374 | result['M2'] = M2; | ||
375 | } else { | ||
376 | throw new Error("Client checksum verification failed! Expected <" + M1 + ">, received <" + someParameters.parameters.M1 + ">.", "Error"); | ||
377 | } | ||
378 | |||
379 | nextTollRequestType = 'MESSAGE'; | ||
380 | } else if (someParameters.message == "oneTimePassword") { | ||
381 | var otpData; | ||
382 | |||
383 | //console.log("HANDSHAKE WITH OTP", someParameters.parameters.oneTimePasswordKey); | ||
384 | //console.log("someParameters", someParameters); | ||
385 | //console.log("data.OTP", Clipperz.Base.serializeJSON(this.data()['onetimePasswords'])); | ||
386 | otpData = this.data()['onetimePasswords'][someParameters.parameters.oneTimePasswordKey]; | ||
387 | |||
388 | try { | ||
389 | if (typeof(otpData) != 'undefined') { | ||
390 | if (otpData['status'] == 'ACTIVE') { | ||
391 | if (otpData['key_checksum'] == someParameters.parameters.oneTimePasswordKeyChecksum) { | ||
392 | result = { | ||
393 | 'data': otpData['data'], | ||
394 | 'version':otpData['version'] | ||
395 | } | ||
396 | |||
397 | otpData['status'] = 'REQUESTED'; | ||
398 | } else { | ||
399 | otpData['status'] = 'DISABLED'; | ||
400 | throw "The requested One Time Password has been disabled, due to a wrong keyChecksum"; | ||
401 | } | ||
402 | } else { | ||
403 | throw "The requested One Time Password was not active"; | ||
404 | } | ||
405 | } else { | ||
406 | throw "The requested One Time Password has not been found" | ||
407 | } | ||
408 | } catch (exception) { | ||
409 | result = { | ||
410 | 'data': Clipperz.PM.Crypto.randomKey(), | ||
411 | 'version':Clipperz.PM.Connection.communicationProtocol.currentVersion | ||
412 | } | ||
413 | } | ||
414 | nextTollRequestType = 'CONNECT'; | ||
415 | } else { | ||
416 | MochiKit.Logging.logError("Clipperz.PM.Proxy.Test.handshake - unhandled message: " + someParameters.message); | ||
417 | } | ||
418 | //console.log("<<< Proxy.Offline._handshake", result); | ||
419 | |||
420 | result = { | ||
421 | result: result, | ||
422 | toll: this.getTollForRequestType(nextTollRequestType) | ||
423 | } | ||
424 | |||
425 | return MochiKit.Async.succeed(result); | ||
426 | }, | ||
427 | |||
428 | //------------------------------------------------------------------------- | ||
429 | |||
430 | '_message': function(someParameters) { | ||
431 | var result; | ||
432 | |||
433 | result = {}; | ||
434 | |||
435 | //===================================================================== | ||
436 | // | ||
437 | // R E A D - O N L Y M e t h o d s | ||
438 | // | ||
439 | //===================================================================== | ||
440 | if (someParameters.message == 'getUserDetails') { | ||
441 | var recordsStats; | ||
442 | var recordReference; | ||
443 | |||
444 | //try { | ||
445 | recordsStats = {}; | ||
446 | for (recordReference in this.userData()['records']) { | ||
447 | recordsStats[recordReference] = { | ||
448 | 'updateDate': this.userData()['records'][recordReference]['updateDate'] | ||
449 | } | ||
450 | } | ||
451 | |||
452 | result['header'] = this.userDetails(); | ||
453 | result['statistics'] = this.statistics(); | ||
454 | result['maxNumberOfRecords'] = this.userData()['maxNumberOfRecords']; | ||
455 | result['version'] = this.userData()['userDetailsVersion']; | ||
456 | result['recordsStats'] = recordsStats; | ||
457 | |||
458 | if (this.isReadOnly() == false) { | ||
459 | varlock; | ||
460 | |||
461 | if (typeof(this.userData()['lock']) == 'undefined') { | ||
462 | this.userData()['lock'] = "<<LOCK>>"; | ||
463 | } | ||
464 | |||
465 | result['lock'] = this.userData()['lock']; | ||
466 | } | ||
467 | //} catch (exception) { | ||
468 | //console.log("*#*#*#*#*#*#*", exception); | ||
469 | //throw exception; | ||
470 | //} | ||
471 | //===================================================================== | ||
472 | } else if (someParameters.message == 'getRecordDetail') { | ||
473 | recordData = this.userData()['records'][someParameters['parameters']['reference']]; | ||
474 | |||
475 | result['reference'] = someParameters['parameters']['reference']; | ||
476 | result['data'] = recordData['data']; | ||
477 | result['version'] = recordData['version']; | ||
478 | result['creationData'] = recordData['creationDate']; | ||
479 | result['updateDate'] = recordData['updateDate']; | ||
480 | result['accessDate'] = recordData['accessDate']; | ||
481 | |||
482 | currentVersionData = recordData['versions'][recordData['currentVersion']]; | ||
483 | |||
484 | result['currentVersion'] = {}; | ||
485 | result['currentVersion']['reference'] = recordData['currentVersion']; | ||
486 | result['currentVersion']['version'] = currentVersionData['version']; | ||
487 | result['currentVersion']['header'] = currentVersionData['header']; | ||
488 | result['currentVersion']['data'] = currentVersionData['data']; | ||
489 | result['currentVersion']['creationData'] = currentVersionData['creationDate']; | ||
490 | result['currentVersion']['updateDate'] = currentVersionData['updateDate']; | ||
491 | result['currentVersion']['accessDate'] = currentVersionData['accessDate']; | ||
492 | if (typeof(currentVersionData['previousVersion']) != 'undefined') { | ||
493 | result['currentVersion']['previousVersionKey'] = currentVersionData['previousVersionKey']; | ||
494 | result['currentVersion']['previousVersion'] = currentVersionData['previousVersion']; | ||
495 | } | ||
496 | |||
497 | //===================================================================== | ||
498 | // | ||
499 | // R E A D - W R I T E M e t h o d s | ||
500 | // | ||
501 | //===================================================================== | ||
502 | } else if (someParameters.message == 'upgradeUserCredentials') { | ||
503 | if (this.isReadOnly() == false) { | ||
504 | var parameters; | ||
505 | parameters = someParameters.parameters; | ||
506 | |||
507 | if (parameters['C'] == null) { | ||
508 | result = Clipperz.PM.DataModel.User.exception.CredentialUpgradeFailed; | ||
509 | } else if (parameters['s'] == null) { | ||
510 | result = Clipperz.PM.DataModel.User.exception.CredentialUpgradeFailed; | ||
511 | } else if (parameters['v'] == null) { | ||
512 | result = Clipperz.PM.DataModel.User.exception.CredentialUpgradeFailed; | ||
513 | } else if (parameters['version'] != Clipperz.PM.Connection.communicationProtocol.currentVersion) { | ||
514 | result = Clipperz.PM.DataModel.User.exception.CredentialUpgradeFailed; | ||
515 | } else { | ||
516 | result = {result:"done", parameters:parameters}; | ||
517 | } | ||
518 | } else { | ||
519 | throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly; | ||
520 | } | ||
521 | //===================================================================== | ||
522 | /* } else if (someParameters.message == 'updateData') { | ||
523 | if (this.isReadOnly() == false) { | ||
524 | var i, c; | ||
525 | |||
526 | //console.log("###==============================================================="); | ||
527 | //console.log("###>>>", Clipperz.Base.serializeJSON(someParameters)); | ||
528 | //console.log("###--- userData", Clipperz.Base.serializeJSON(this.userData())); | ||
529 | if (this.userData()['lock']!= someParameters['parameters']['user']['lock']) { | ||
530 | throw "the lock attribute is not processed correctly" | ||
531 | } | ||
532 | |||
533 | this.userData()['userDetails'] = someParameters['parameters']['user']['header']; | ||
534 | this.userData()['statistics'] = someParameters['parameters']['user']['statistics']; | ||
535 | this.userData()['userDetailsVersions']= someParameters['parameters']['user']['version']; | ||
536 | |||
537 | c = someParameters['parameters']['records'].length; | ||
538 | for (i=0; i<c; i++) { | ||
539 | var currentRecord; | ||
540 | var currentRecordData; | ||
541 | |||
542 | currentRecordData = someParameters['parameters']['records'][i]; | ||
543 | currentRecord = this.userData()['records'][currentRecordData['record']['reference']]; | ||
544 | |||
545 | if (currentRecord == null) { | ||
546 | } | ||
547 | |||
548 | currentRecord['data'] = currentRecordData['record']['data']; | ||
549 | currentRecord['version'] = currentRecordData['record']['version']; | ||
550 | currentRecord['currentVersion'] = currentRecordData['currentRecordVersion']['reference']; | ||
551 | |||
552 | currentRecord['versions'][currentRecordData['currentRecordVersion']['reference']] = { | ||
553 | 'data': currentRecordData['currentRecordVersion']['data'], | ||
554 | 'version': currentRecordData['currentRecordVersion']['version'], | ||
555 | 'previousVersion': currentRecordData['currentRecordVersion']['previousVersion'], | ||
556 | 'previousVersionKey':currentRecordData['currentRecordVersion']['previousVersionKey'] | ||
557 | } | ||
558 | } | ||
559 | |||
560 | this.userData()['lock'] = Clipperz.PM.Crypto.randomKey(); | ||
561 | result['lock'] = this.userData()['lock']; | ||
562 | result['result'] = 'done'; | ||
563 | //console.log("###<<< userData", Clipperz.Base.serializeJSON(this.userData())); | ||
564 | } else { | ||
565 | throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly; | ||
566 | } | ||
567 | */ //===================================================================== | ||
568 | } else if (someParameters.message == 'saveChanges') { | ||
569 | if (this.isReadOnly() == false) { | ||
570 | var i, c; | ||
571 | |||
572 | //console.log("###==============================================================="); | ||
573 | //console.log("###>>>", someParameters); | ||
574 | //console.log("###>>>", Clipperz.Base.serializeJSON(someParameters)); | ||
575 | //console.log("###--- userData", Clipperz.Base.serializeJSON(this.userData())); | ||
576 | //console.log("###==============================================================="); | ||
577 | //console.log("--- userData.lock ", this.userData()['lock']); | ||
578 | //console.log("--- parameters.lock", someParameters['parameters']['user']['lock']); | ||
579 | if (this.userData()['lock']!= someParameters['parameters']['user']['lock']) { | ||
580 | throw "the lock attribute is not processed correctly" | ||
581 | } | ||
582 | |||
583 | this.userData()['userDetails'] = someParameters['parameters']['user']['header']; | ||
584 | this.userData()['statistics'] = someParameters['parameters']['user']['statistics']; | ||
585 | this.userData()['userDetailsVersions']= someParameters['parameters']['user']['version']; | ||
586 | |||
587 | c = someParameters['parameters']['records']['updated'].length; | ||
588 | for (i=0; i<c; i++) { | ||
589 | var currentRecord; | ||
590 | var currentRecordData; | ||
591 | |||
592 | currentRecordData = someParameters['parameters']['records']['updated'][i]; | ||
593 | currentRecord = this.userData()['records'][currentRecordData['record']['reference']]; | ||
594 | |||
595 | if ( | ||
596 | (typeof(this.userData()['records'][currentRecordData['record']['reference']]) == 'undefined') | ||
597 | && | ||
598 | (typeof(currentRecordData['currentRecordVersion']) == 'undefined') | ||
599 | ) { | ||
600 | //console.log("######## SHIT HAPPENS"); | ||
601 | throw "Record added without a recordVersion"; | ||
602 | } | ||
603 | |||
604 | if (currentRecord == null) { | ||
605 | currentRecord = {}; | ||
606 | currentRecord['versions'] = {}; | ||
607 | currentRecord['creationDate']= Clipperz.PM.Date.formatDateWithUTCFormat(new Date()); | ||
608 | currentRecord['accessDate'] = Clipperz.PM.Date.formatDateWithUTCFormat(new Date()); | ||
609 | |||
610 | this.userData()['records'][currentRecordData['record']['reference']] = currentRecord; | ||
611 | } | ||
612 | |||
613 | currentRecord['data'] = currentRecordData['record']['data']; | ||
614 | currentRecord['version']= currentRecordData['record']['version']; | ||
615 | currentRecord['updateDate']= Clipperz.PM.Date.formatDateWithUTCFormat(new Date()); | ||
616 | |||
617 | if (typeof(currentRecordData['currentRecordVersion']) != 'undefined') { | ||
618 | currentRecord['currentVersion'] = currentRecordData['currentRecordVersion']['reference']; | ||
619 | currentRecord['versions'][currentRecordData['currentRecordVersion']['reference']] = { | ||
620 | 'data': currentRecordData['currentRecordVersion']['data'], | ||
621 | 'version': currentRecordData['currentRecordVersion']['version'], | ||
622 | 'previousVersion': currentRecordData['currentRecordVersion']['previousVersion'], | ||
623 | 'previousVersionKey':currentRecordData['currentRecordVersion']['previousVersionKey'], | ||
624 | 'creationDate':Clipperz.PM.Date.formatDateWithUTCFormat(new Date()), | ||
625 | 'updateDate':Clipperz.PM.Date.formatDateWithUTCFormat(new Date()), | ||
626 | 'accessDate':Clipperz.PM.Date.formatDateWithUTCFormat(new Date()) | ||
627 | } | ||
628 | } | ||
629 | } | ||
630 | |||
631 | c = someParameters['parameters']['records']['deleted'].length; | ||
632 | for (i=0; i<c; i++) { | ||
633 | var currentRecordReference; | ||
634 | |||
635 | currentRecordReference = someParameters['parameters']['records']['deleted'][i]; | ||
636 | //console.log("DELETING records", currentRecordReference); | ||
637 | delete this.userData()['records'][currentRecordReference]; | ||
638 | } | ||
639 | |||
640 | this.userData()['lock'] = Clipperz.PM.Crypto.randomKey(); | ||
641 | result['lock'] = this.userData()['lock']; | ||
642 | result['result'] = 'done'; | ||
643 | //console.log("###<<< userData", Clipperz.Base.serializeJSON(this.userData())); | ||
644 | } else { | ||
645 | throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly; | ||
646 | } | ||
647 | |||
648 | //===================================================================== | ||
649 | // | ||
650 | // U N H A N D L E D M e t h o d | ||
651 | // | ||
652 | //===================================================================== | ||
653 | } else { | ||
654 | MochiKit.Logging.logError("Clipperz.PM.Proxy.Test.message - unhandled message: " + someParameters.message); | ||
655 | } | ||
656 | |||
657 | result = { | ||
658 | result: result, | ||
659 | toll: this.getTollForRequestType('MESSAGE') | ||
660 | } | ||
661 | |||
662 | return MochiKit.Async.succeed(result); | ||
663 | }, | ||
664 | |||
665 | //------------------------------------------------------------------------- | ||
666 | |||
667 | '_logout': function(someParameters) { | ||
668 | return MochiKit.Async.succeed({result: 'done'}); | ||
669 | }, | ||
670 | |||
671 | //========================================================================= | ||
672 | //######################################################################### | ||
673 | |||
674 | 'isTestData': function() { | ||
675 | return (typeof(this.userData()['__masterkey_test_value__']) != 'undefined'); | ||
676 | }, | ||
677 | |||
678 | 'userDetails': function() { | ||
679 | var result; | ||
680 | |||
681 | if (this.isTestData()) { | ||
682 | var serializedHeader; | ||
683 | var version; | ||
684 | |||
685 | //MochiKit.Logging.logDebug("### test data"); | ||
686 | version = this.userData()['userDetailsVersion']; | ||
687 | serializedHeader = Clipperz.Base.serializeJSON(this.userData()['userDetails']); | ||
688 | result = Clipperz.PM.Crypto.encryptingFunctions.versions[version].encrypt(this.userData()['__masterkey_test_value__'], serializedHeader); | ||
689 | } else { | ||
690 | //MochiKit.Logging.logDebug("### NOT test data"); | ||
691 | result = this.userData()['userDetails']; | ||
692 | } | ||
693 | |||
694 | return result; | ||
695 | }, | ||
696 | |||
697 | 'statistics': function() { | ||
698 | var result; | ||
699 | |||
700 | if (this.userData()['statistics'] != null) { | ||
701 | if (this.isTestData()) { | ||
702 | var serializedStatistics; | ||
703 | var version; | ||
704 | |||
705 | version = this.userData()['userDetailsVersion']; | ||
706 | serializedStatistics = Clipperz.Base.serializeJSON(this.userData()['statistics']); | ||
707 | result = Clipperz.PM.Crypto.encryptingFunctions.versions[version].encrypt(this.userData()['__masterkey_test_value__'], serializedStatistics); | ||
708 | } else { | ||
709 | result = this.userData()['statistics']; | ||
710 | } | ||
711 | } else { | ||
712 | result = null; | ||
713 | } | ||
714 | |||
715 | return result; | ||
716 | }, | ||
717 | |||
718 | /* | ||
719 | 'userSerializedEncryptedData': function(someData) { | ||
720 | var deferredResult; | ||
721 | var deferredContext; | ||
722 | |||
723 | deferredContext = { 'data': someData }; | ||
724 | |||
725 | deferredResult = new Clipperz.Async.Deferred('Proxy.Test.serializeUserEncryptedData', {trace:false}); | ||
726 | deferredResult.addCallback(MochiKit.Base.bind(function(aDeferredContext) { | ||
727 | aDeferredContext['user'] = this.createUserUsingConfigurationData(aDeferredContext['data']); | ||
728 | return aDeferredContext; | ||
729 | }, this)); | ||
730 | deferredResult.addCallback(function(aDeferredContext) { | ||
731 | // return aDeferredContext['user'].encryptedDataUsingVersion(aDeferredContext['data']['version']); | ||
732 | return aDeferredContext['user'].serializedDataUsingVersion(MochiKit.Base.values(aDeferredContext['user'].records()), aDeferredContext['data']['version']); | ||
733 | }); | ||
734 | deferredResult.addCallback(function(aUserEncryptedData) { | ||
735 | deferredContext['encryptedData'] = aUserEncryptedData; | ||
736 | return deferredContext; | ||
737 | }); | ||
738 | deferredResult.addCallback(function(aDeferredContext) { | ||
739 | var connection; | ||
740 | |||
741 | connection = new Clipperz.PM.Connection.communicationProtocol.versions[aDeferredContext['data']['connectionVersion']]() | ||
742 | aDeferredContext['credentials'] = connection.serverSideUserCredentials(aDeferredContext['user'].username(),aDeferredContext['user'].passphrase()); | ||
743 | |||
744 | return aDeferredContext; | ||
745 | }); | ||
746 | |||
747 | // deferredResult.addCallback(function(aDeferredContext) { | ||
748 | //console.log("#-#-#-#-#", aDeferredContext); | ||
749 | // return aDeferredContext['user'].serializedDataUsingVersion(MochiKit.Base.values(aDeferredContext['user'].records()), aDeferredContext['data']['version']); | ||
750 | // }, deferredContext); | ||
751 | // deferredResult.addCallback(function(aUserSerializedData) { | ||
752 | //console.log("USER SERIALIZED DATA", aUserSerializedData); | ||
753 | // }); | ||
754 | // | ||
755 | // deferredResult.addCallback(MochiKit.Async.succeed, deferredContext); | ||
756 | deferredResult.callback(deferredContext); | ||
757 | |||
758 | return deferredResult; | ||
759 | }, | ||
760 | |||
761 | 'createUserUsingConfigurationData': function(someData) { | ||
762 | var result; | ||
763 | var user; | ||
764 | var recordLabel; | ||
765 | |||
766 | user = new Clipperz.PM.DataModel.User(); | ||
767 | user.initForTests(); | ||
768 | user.setUsername(someData['username']); | ||
769 | user.setPassphrase(someData['passphrase']); | ||
770 | |||
771 | for (recordLabel in someData['records']) { | ||
772 | var recordData; | ||
773 | var record; | ||
774 | var i, c; | ||
775 | |||
776 | recordData = someData['records'][recordLabel]; | ||
777 | record = new Clipperz.PM.DataModel.Record({user:user, label:recordLabel}); | ||
778 | record.setNotes(recordData['notes']); | ||
779 | |||
780 | c = recordData['fields'].length; | ||
781 | for (i=0; i<c; i++) { | ||
782 | var recordField; | ||
783 | |||
784 | recordField = new Clipperz.PM.DataModel.RecordField(); | ||
785 | recordField.setLabel(recordData['fields'][i]['name']); | ||
786 | recordField.setValue(recordData['fields'][i]['value']); | ||
787 | recordField.setType(recordData['fields'][i]['type']); | ||
788 | record.addField(recordField); | ||
789 | } | ||
790 | user.addRecord(record, true); | ||
791 | } | ||
792 | |||
793 | result = user; | ||
794 | |||
795 | return result; | ||
796 | }, | ||
797 | */ | ||
798 | //========================================================================= | ||
799 | __syntaxFix__: "syntax fix" | ||
800 | }); | ||
801 | |||
802 | Clipperz.PM.Proxy.Offline.DataStore['exception'] = { | ||
803 | 'ReadOnly': new MochiKit.Base.NamedError("Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly") | ||
804 | }; \ No newline at end of file | ||