summaryrefslogtreecommitdiff
path: root/frontend/delta/js/Clipperz/PM/Proxy/Proxy.Offline.LocalStorageDataStore.js
Unidiff
Diffstat (limited to 'frontend/delta/js/Clipperz/PM/Proxy/Proxy.Offline.LocalStorageDataStore.js') (more/less context) (ignore whitespace changes)
-rw-r--r--frontend/delta/js/Clipperz/PM/Proxy/Proxy.Offline.LocalStorageDataStore.js420
1 files changed, 420 insertions, 0 deletions
diff --git a/frontend/delta/js/Clipperz/PM/Proxy/Proxy.Offline.LocalStorageDataStore.js b/frontend/delta/js/Clipperz/PM/Proxy/Proxy.Offline.LocalStorageDataStore.js
new file mode 100644
index 0000000..a3c238c
--- a/dev/null
+++ b/frontend/delta/js/Clipperz/PM/Proxy/Proxy.Offline.LocalStorageDataStore.js
@@ -0,0 +1,420 @@
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.PM.Proxy.Offline.DataStore) == 'undefined') { throw ""; }} catch (e) {
25 throw "Clipperz.PM.Proxy.Offline.LocalStorageDataStore depends on Clipperz.PM.Proxy.Offline.DataStore!";
26}
27
28//=============================================================================
29
30Clipperz.PM.Proxy.Offline.LocalStorageDataStore = function(args) {
31 args = args || {};
32
33 this._data = args.data || (typeof(_clipperz_dump_data_) != 'undefined' ? _clipperz_dump_data_ : null);
34 this._isReadOnly = (typeof(args.readOnly) == 'undefined' ? true : args.readOnly);
35 this._shouldPayTolls = args.shouldPayTolls || false;
36
37 this._tolls = {};
38 this._currentStaticConnection = null;
39
40 //Clipperz.PM.Proxy.Offline.LocalStorageDataStore.superclass.constructor.apply(this, arguments);
41
42 return this;
43}
44
45Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.LocalStorageDataStore, Clipperz.PM.Proxy.Offline.DataStore, {
46
47 //=========================================================================
48
49 '_knock': function(aConnection, someParameters) {
50 var result;
51
52 result = {
53 toll: this.getTollForRequestType(someParameters['requestType'])
54 }
55
56 return result;
57 },
58
59 //-------------------------------------------------------------------------
60
61 '_registration': function(aConnection, someParameters) {
62 throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly;
63 },
64
65 //-------------------------------------------------------------------------
66
67 '_handshake': function(aConnection, someParameters) {
68 var result;
69 varnextTollRequestType;
70
71 result = {};
72 if (someParameters.message == "connect") {
73 var userData;
74 var randomBytes;
75 var v;
76
77 userData = this.data()['users'][someParameters.parameters.C];
78
79 if ((typeof(userData) != 'undefined') && (userData['version'] == someParameters.version)) {
80 aConnection['userData'] = userData;
81 aConnection['C'] = someParameters.parameters.C;
82 } else {
83 aConnection['userData'] = this.data()['users']['catchAllUser'];
84 }
85
86 randomBytes = Clipperz.Crypto.Base.generateRandomSeed();
87 aConnection['b'] = new Clipperz.Crypto.BigInt(randomBytes, 16);
88 v = new Clipperz.Crypto.BigInt(aConnection['userData']['v'], 16);
89 aConnection['B'] = v.add(Clipperz.Crypto.SRP.g().powerModule(aConnection['b'], Clipperz.Crypto.SRP.n()));
90
91 aConnection['A'] = someParameters.parameters.A;
92
93 result['s'] = aConnection['userData']['s'];
94 result['B'] = aConnection['B'].asString(16);
95
96 nextTollRequestType = 'CONNECT';
97 } else if (someParameters.message == "credentialCheck") {
98 var v, u, S, A, K, M1;
99
100 v = new Clipperz.Crypto.BigInt(aConnection['userData']['v'], 16);
101 u = new Clipperz.Crypto.BigInt(Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(aConnection['B'].asString(10))).toHexString(), 16);
102 A = new Clipperz.Crypto.BigInt(aConnection['A'], 16);
103 S = (A.multiply(v.powerModule(u, Clipperz.Crypto.SRP.n()))).powerModule(aConnection['b'], Clipperz.Crypto.SRP.n());
104
105 K = Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(S.asString(10))).toHexString().slice(2);
106
107 M1 = Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(A.asString(10) + aConnection['B'].asString(10) + K)).toHexString().slice(2);
108 if (someParameters.parameters.M1 == M1) {
109 var M2;
110
111 M2 = Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(A.asString(10) + someParameters.parameters.M1 + K)).toHexString().slice(2);
112 result['M2'] = M2;
113 } else {
114 throw new Error("Client checksum verification failed! Expected <" + M1 + ">, received <" + someParameters.parameters.M1 + ">.", "Error");
115 }
116
117 nextTollRequestType = 'MESSAGE';
118 } else if (someParameters.message == "oneTimePassword") {
119 var otpData;
120
121 otpData = this.data()['onetimePasswords'][someParameters.parameters.oneTimePasswordKey];
122
123 try {
124 if (typeof(otpData) != 'undefined') {
125 if (otpData['status'] == 'ACTIVE') {
126 if (otpData['key_checksum'] == someParameters.parameters.oneTimePasswordKeyChecksum) {
127 result = {
128 'data': otpData['data'],
129 'version':otpData['version']
130 }
131
132 otpData['status'] = 'REQUESTED';
133 } else {
134 otpData['status'] = 'DISABLED';
135 throw "The requested One Time Password has been disabled, due to a wrong keyChecksum";
136 }
137 } else {
138 throw "The requested One Time Password was not active";
139 }
140 } else {
141 throw "The requested One Time Password has not been found"
142 }
143 } catch (exception) {
144 result = {
145 'data': Clipperz.PM.Crypto.randomKey(),
146 'version':Clipperz.PM.Connection.communicationProtocol.currentVersion
147 }
148 }
149 nextTollRequestType = 'CONNECT';
150 } else {
151 Clipperz.logError("Clipperz.PM.Proxy.Test.handshake - unhandled message: " + someParameters.message);
152 }
153
154 result = {
155 result: result,
156 toll: this.getTollForRequestType(nextTollRequestType)
157 }
158
159 return result;
160 },
161
162 //-------------------------------------------------------------------------
163
164 '_message': function(aConnection, someParameters) {
165 var result;
166
167 result = {};
168
169 //=====================================================================
170 //
171 // R E A D - O N L Y M e t h o d s
172 //
173 //=====================================================================
174 if (someParameters.message == 'getUserDetails') {
175 var recordsStats;
176 var recordReference;
177
178 recordsStats = {};
179 for (recordReference in aConnection['userData']['records']) {
180 recordsStats[recordReference] = {
181 'updateDate': aConnection['userData']['records'][recordReference]['updateDate']
182 }
183 }
184
185 result['header'] = this.userDetails(aConnection);
186 result['statistics'] = this.statistics(aConnection);
187 result['maxNumberOfRecords'] = aConnection['userData']['maxNumberOfRecords'];
188 result['version'] = aConnection['userData']['userDetailsVersion'];
189 result['recordsStats'] = recordsStats;
190
191 if (this.isReadOnly() == false) {
192 varlock;
193
194 if (typeof(aConnection['userData']['lock']) == 'undefined') {
195 aConnection['userData']['lock'] = "<<LOCK>>";
196 }
197
198 result['lock'] = aConnection['userData']['lock'];
199 }
200
201 //=====================================================================
202 } else if (someParameters.message == 'getRecordDetail') {
203/*
204 varrecordData;
205 var currentVersionData;
206
207 recordData = this.userData()['records'][someParameters['parameters']['reference']];
208 result['reference'] = someParameters['parameters']['reference'];
209 result['data'] = recordData['data'];
210 result['version'] = recordData['version'];
211 result['creationData'] = recordData['creationDate'];
212 result['updateDate'] = recordData['updateDate'];
213 result['accessDate'] = recordData['accessDate'];
214
215 currentVersionData = recordData['versions'][recordData['currentVersion']];
216
217 result['currentVersion'] = {};
218 result['currentVersion']['reference'] = recordData['currentVersion'];
219 result['currentVersion']['version'] = currentVersionData['version'];
220 result['currentVersion']['header'] = currentVersionData['header'];
221 result['currentVersion']['data'] = currentVersionData['data'];
222 result['currentVersion']['creationData'] = currentVersionData['creationDate'];
223 result['currentVersion']['updateDate'] = currentVersionData['updateDate'];
224 result['currentVersion']['accessDate'] = currentVersionData['accessDate'];
225 if (typeof(currentVersionData['previousVersion']) != 'undefined') {
226 result['currentVersion']['previousVersionKey'] = currentVersionData['previousVersionKey'];
227 result['currentVersion']['previousVersion'] = currentVersionData['previousVersion'];
228 }
229*/
230 MochiKit.Base.update(result, aConnection['userData']['records'][someParameters['parameters']['reference']]);
231 result['reference'] = someParameters['parameters']['reference'];
232
233 //=====================================================================
234 //
235 // R E A D - W R I T E M e t h o d s
236 //
237 //=====================================================================
238 } else if (someParameters.message == 'upgradeUserCredentials') {
239 if (this.isReadOnly() == false) {
240 var parameters;
241 var credentials;
242
243 parameters = someParameters['parameters'];
244 credentials = parameters['credentials'];
245
246 if ((credentials['C'] == null)
247 ||(credentials['s'] == null)
248 ||(credentials['v'] == null)
249 ||(credentials['version'] != Clipperz.PM.Connection.communicationProtocol.currentVersion)
250 ) {
251 result = Clipperz.PM.DataModel.User.exception.CredentialUpgradeFailed;
252 } else {
253 varoldCValue;
254 oldCValue = aConnection['C'];
255
256 this.data()['users'][credentials['C']] = aConnection['userData'];
257 aConnection['C'] = credentials['C'];
258
259 aConnection['userData']['s'] = credentials['s'];
260 aConnection['userData']['v'] = credentials['v'];
261 aConnection['userData']['version'] = credentials['version'];
262
263 aConnection['userData']['userDetails'] = parameters['user']['header'];
264 aConnection['userData']['userDetailsVersion'] = parameters['user']['version'];
265 aConnection['userData']['statistics'] = parameters['user']['statistics'];
266
267 aConnection['userData']['lock'] = parameters['user']['lock'];
268
269 delete this.data()['users'][oldCValue];
270
271 result = {result:"done", parameters:parameters};
272 }
273 } else {
274 throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly;
275 }
276
277 //=====================================================================
278
279 } else if (someParameters.message == 'saveChanges') {
280 if (this.isReadOnly() == false) {
281 var i, c;
282
283 if (aConnection['userData']['lock']!= someParameters['parameters']['user']['lock']) {
284 throw "the lock attribute is not processed correctly"
285 }
286
287 aConnection['userData']['userDetails'] = someParameters['parameters']['user']['header'];
288 aConnection['userData']['statistics'] = someParameters['parameters']['user']['statistics'];
289 aConnection['userData']['userDetailsVersion']= someParameters['parameters']['user']['version'];
290
291 c = someParameters['parameters']['records']['updated'].length;
292 for (i=0; i<c; i++) {
293 var currentRecord;
294 var currentRecordData;
295
296 currentRecordData = someParameters['parameters']['records']['updated'][i];
297 currentRecord = aConnection['userData']['records'][currentRecordData['record']['reference']];
298
299 if (
300 (typeof(aConnection['userData']['records'][currentRecordData['record']['reference']]) == 'undefined')
301 &&
302 (typeof(currentRecordData['currentRecordVersion']) == 'undefined')
303 ) {
304 throw "Record added without a recordVersion";
305 }
306
307 if (currentRecord == null) {
308 currentRecord = {};
309 currentRecord['versions'] = {};
310 currentRecord['creationDate']= Clipperz.PM.Date.formatDateWithUTCFormat(new Date());
311 currentRecord['accessDate'] = Clipperz.PM.Date.formatDateWithUTCFormat(new Date());
312
313 aConnection['userData']['records'][currentRecordData['record']['reference']] = currentRecord;
314 }
315
316 currentRecord['data'] = currentRecordData['record']['data'];
317 currentRecord['version']= currentRecordData['record']['version'];
318 currentRecord['updateDate']= Clipperz.PM.Date.formatDateWithUTCFormat(new Date());
319
320 if (typeof(currentRecordData['currentRecordVersion']) != 'undefined') {
321 currentRecord['currentVersion'] = currentRecordData['currentRecordVersion']['reference'];
322 currentRecord['versions'][currentRecordData['currentRecordVersion']['reference']] = {
323 'data': currentRecordData['currentRecordVersion']['data'],
324 'version': currentRecordData['currentRecordVersion']['version'],
325 'previousVersion': currentRecordData['currentRecordVersion']['previousVersion'],
326 'previousVersionKey':currentRecordData['currentRecordVersion']['previousVersionKey'],
327 'creationDate':Clipperz.PM.Date.formatDateWithUTCFormat(new Date()),
328 'updateDate':Clipperz.PM.Date.formatDateWithUTCFormat(new Date()),
329 'accessDate':Clipperz.PM.Date.formatDateWithUTCFormat(new Date())
330 }
331 }
332 }
333
334 c = someParameters['parameters']['records']['deleted'].length;
335 for (i=0; i<c; i++) {
336 var currentRecordReference;
337
338 currentRecordReference = someParameters['parameters']['records']['deleted'][i];
339 delete aConnection['userData']['records'][currentRecordReference];
340 }
341
342 aConnection['userData']['lock'] = Clipperz.PM.Crypto.randomKey();
343 result['lock'] = aConnection['userData']['lock'];
344 result['result'] = 'done';
345 } else {
346 throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly;
347 }
348
349 //=====================================================================
350 //
351 // U N H A N D L E D M e t h o d
352 //
353 //=====================================================================
354 } else {
355 Clipperz.logError("Clipperz.PM.Proxy.Test.message - unhandled message: " + someParameters.message);
356 }
357
358 result = {
359 result: result,
360 toll: this.getTollForRequestType('MESSAGE')
361 }
362
363 // return MochiKit.Async.succeed(result);
364 return result;
365 },
366
367 //-------------------------------------------------------------------------
368
369 '_logout': function(someParameters) {
370 // return MochiKit.Async.succeed({result: 'done'});
371 return {result: 'done'};
372 },
373
374 //=========================================================================
375 //#########################################################################
376/*
377 'userDetails': function(aConnection) {
378 var result;
379
380 if (this.isTestData(aConnection)) {
381 var serializedHeader;
382 var version;
383
384//Clipperz.logDebug("### test data");
385 version = aConnection['userData']['userDetailsVersion'];
386 serializedHeader = Clipperz.Base.serializeJSON(aConnection['userData']['userDetails']);
387 result = Clipperz.PM.Crypto.encryptingFunctions.versions[version].encrypt(aConnection['userData']['__masterkey_test_value__'], serializedHeader);
388 } else {
389//Clipperz.logDebug("### NOT test data");
390 result = aConnection['userData']['userDetails'];
391 }
392
393 return result;
394 },
395
396 'statistics': function(aConnection) {
397 var result;
398
399 if (aConnection['userData']['statistics'] != null) {
400 if (this.isTestData(aConnection)) {
401 var serializedStatistics;
402 var version;
403
404 version = aConnection['userData']['userDetailsVersion'];
405 serializedStatistics = Clipperz.Base.serializeJSON(aConnection['userData']['statistics']);
406 result = Clipperz.PM.Crypto.encryptingFunctions.versions[version].encrypt(aConnection['userData']['__masterkey_test_value__'], serializedStatistics);
407 } else {
408 result = aConnection['userData']['statistics'];
409 }
410 } else {
411 result = null;
412 }
413
414 return result;
415 },
416*/
417 //=========================================================================
418 __syntaxFix__: "syntax fix"
419});
420