summaryrefslogtreecommitdiff
path: root/frontend/gamma/js/Clipperz/PM/DataModel/User.js
Unidiff
Diffstat (limited to 'frontend/gamma/js/Clipperz/PM/DataModel/User.js') (more/less context) (ignore whitespace changes)
-rw-r--r--frontend/gamma/js/Clipperz/PM/DataModel/User.js24
1 files changed, 10 insertions, 14 deletions
diff --git a/frontend/gamma/js/Clipperz/PM/DataModel/User.js b/frontend/gamma/js/Clipperz/PM/DataModel/User.js
index 646ce21..fd18faf 100644
--- a/frontend/gamma/js/Clipperz/PM/DataModel/User.js
+++ b/frontend/gamma/js/Clipperz/PM/DataModel/User.js
@@ -1,612 +1,608 @@
1/* 1/*
2 2
3Copyright 2008-2011 Clipperz Srl 3Copyright 2008-2013 Clipperz Srl
4 4
5This file is part of Clipperz Community Edition. 5This file is part of Clipperz, the online password manager.
6Clipperz Community Edition is an online password manager.
7For further information about its features and functionalities please 6For further information about its features and functionalities please
8refer to http://www.clipperz.com. 7refer to http://www.clipperz.com.
9 8
10* Clipperz Community Edition is free software: you can redistribute 9* Clipperz is free software: you can redistribute it and/or modify it
11 it and/or modify it under the terms of the GNU Affero General Public 10 under the terms of the GNU Affero General Public License as published
12 License as published by the Free Software Foundation, either version 11 by the Free Software Foundation, either version 3 of the License, or
13 3 of the License, or (at your option) any later version. 12 (at your option) any later version.
14 13
15* Clipperz Community Edition is distributed in the hope that it will 14* Clipperz is distributed in the hope that it will be useful, but
16 be useful, but WITHOUT ANY WARRANTY; without even the implied 15 WITHOUT ANY WARRANTY; without even the implied warranty of
17 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18 See the GNU Affero General Public License for more details. 17 See the GNU Affero General Public License for more details.
19 18
20* 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
21 License along with Clipperz Community Edition. If not, see 20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
22 <http://www.gnu.org/licenses/>.
23 21
24*/ 22*/
25 23
26if (typeof(Clipperz) == 'undefined') { Clipperz = {}; } 24if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
27if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; } 25if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; }
28if (typeof(Clipperz.PM.DataModel) == 'undefined') { Clipperz.PM.DataModel = {}; } 26if (typeof(Clipperz.PM.DataModel) == 'undefined') { Clipperz.PM.DataModel = {}; }
29 27
30 28
31//############################################################################# 29//#############################################################################
32 30
33Clipperz.PM.DataModel.User = function (args) { 31Clipperz.PM.DataModel.User = function (args) {
34 args = args || {}; 32 args = args || {};
35 33
36 Clipperz.PM.DataModel.User.superclass.constructor.apply(this, arguments); 34 Clipperz.PM.DataModel.User.superclass.constructor.apply(this, arguments);
37 35
38 this._username = args.username || null; 36 this._username = args.username || null;
39 this._getPassphraseFunction = args.getPassphraseFunction || null; 37 this._getPassphraseFunction = args.getPassphraseFunction || null;
40 38
41 this._data = null; 39 this._data = null;
42 40
43 this._connection = null; 41 this._connection = null;
44 this._connectionVersion = 'current'; 42 this._connectionVersion = 'current';
45 43
46 this._serverData = null; 44 this._serverData = null;
47 //this._serverLockValue = null; 45 //this._serverLockValue = null;
48 this._transientState = null; 46 this._transientState = null;
49 47
50 this._deferredLocks = { 48 this._deferredLocks = {
51 'passphrase': new MochiKit.Async.DeferredLock(), 49 'passphrase': new MochiKit.Async.DeferredLock(),
52 'serverData': new MochiKit.Async.DeferredLock(), 50 'serverData': new MochiKit.Async.DeferredLock(),
53 // 'recordsIndex': new MochiKit.Async.DeferredLock(), 51 // 'recordsIndex': new MochiKit.Async.DeferredLock(),
54 // 'directLoginsIndex':new MochiKit.Async.DeferredLock() 52 // 'directLoginsIndex':new MochiKit.Async.DeferredLock()
55 // 'preferences': new MochiKit.Async.DeferredLock() 53 // 'preferences': new MochiKit.Async.DeferredLock()
56 // 'oneTimePasswords': new MochiKit.Async.DeferredLock() 54 // 'oneTimePasswords': new MochiKit.Async.DeferredLock()
57 '__syntaxFix__': 'syntax fix' 55 '__syntaxFix__': 'syntax fix'
58 }; 56 };
59 57
60 return this; 58 return this;
61} 59}
62 60
63Clipperz.Base.extend(Clipperz.PM.DataModel.User, Object, { 61Clipperz.Base.extend(Clipperz.PM.DataModel.User, Object, {
64 62
65 'toString': function () { 63 'toString': function () {
66 return "Clipperz.PM.DataModel.User - " + this.username(); 64 return "Clipperz.PM.DataModel.User - " + this.username();
67 }, 65 },
68 66
69 //------------------------------------------------------------------------- 67 //-------------------------------------------------------------------------
70 68
71 'username': function () { 69 'username': function () {
72 return this._username; 70 return this._username;
73 }, 71 },
74 72
75 'setUsername': function (aValue) { 73 'setUsername': function (aValue) {
76 this._username = aValue; 74 this._username = aValue;
77 }, 75 },
78 76
79 //------------------------------------------------------------------------- 77 //-------------------------------------------------------------------------
80 78
81 'displayName': function() { 79 'displayName': function() {
82 return "" + this.username() + ""; 80 return "" + this.username() + "";
83 }, 81 },
84 82
85 //------------------------------------------------------------------------- 83 //-------------------------------------------------------------------------
86 84
87 'data': function () { 85 'data': function () {
88 if (this._data == null) { 86 if (this._data == null) {
89 this._data = new Clipperz.KeyValueObjectStore(/*{'name':'User.data [1]'}*/); 87 this._data = new Clipperz.KeyValueObjectStore(/*{'name':'User.data [1]'}*/);
90 }; 88 };
91 89
92 return this._data; 90 return this._data;
93 }, 91 },
94 92
95 //------------------------------------------------------------------------- 93 //-------------------------------------------------------------------------
96/* 94/*
97 'serverLockValue': function () { 95 'serverLockValue': function () {
98 return this._serverLockValue; 96 return this._serverLockValue;
99 }, 97 },
100 98
101 'setServerLockValue': function (aValue) { 99 'setServerLockValue': function (aValue) {
102 this._serverLockValue = aValue; 100 this._serverLockValue = aValue;
103 }, 101 },
104*/ 102*/
105 //------------------------------------------------------------------------- 103 //-------------------------------------------------------------------------
106 104
107 'transientState': function () { 105 'transientState': function () {
108 if (this._transientState == null) { 106 if (this._transientState == null) {
109 this._transientState = {} 107 this._transientState = {}
110 } 108 }
111 109
112 return this._transientState; 110 return this._transientState;
113 }, 111 },
114 112
115 'resetTransientState': function (isCommitting) { 113 'resetTransientState': function (isCommitting) {
116 this._transientState = null; 114 this._transientState = null;
117 }, 115 },
118 116
119 //------------------------------------------------------------------------- 117 //-------------------------------------------------------------------------
120 118
121 'deferredLockForSection': function(aSectionName) { 119 'deferredLockForSection': function(aSectionName) {
122 return this._deferredLocks[aSectionName]; 120 return this._deferredLocks[aSectionName];
123 }, 121 },
124 122
125 //------------------------------------------------------------------------- 123 //-------------------------------------------------------------------------
126 124
127 'getPassphrase': function() { 125 'getPassphrase': function() {
128 var deferredResult; 126 var deferredResult;
129 127
130 deferredResult = new Clipperz.Async.Deferred("User.getPassphrase", {trace:false}); 128 deferredResult = new Clipperz.Async.Deferred("User.getPassphrase", {trace:false});
131 deferredResult.acquireLock(this.deferredLockForSection('passphrase')); 129 deferredResult.acquireLock(this.deferredLockForSection('passphrase'));
132 deferredResult.addMethod(this.data(), 'deferredGetOrSet', 'passphrase', this.getPassphraseFunction()); 130 deferredResult.addMethod(this.data(), 'deferredGetOrSet', 'passphrase', this.getPassphraseFunction());
133 deferredResult.releaseLock(this.deferredLockForSection('passphrase')); 131 deferredResult.releaseLock(this.deferredLockForSection('passphrase'));
134 deferredResult.callback(); 132 deferredResult.callback();
135 133
136 return deferredResult; 134 return deferredResult;
137 }, 135 },
138 136
139 'getPassphraseFunction': function () { 137 'getPassphraseFunction': function () {
140 return this._getPassphraseFunction; 138 return this._getPassphraseFunction;
141 }, 139 },
142 140
143 //------------------------------------------------------------------------- 141 //-------------------------------------------------------------------------
144 142
145 'getCredentials': function () { 143 'getCredentials': function () {
146 return Clipperz.Async.collectResults("User; get username and passphrase", { 144 return Clipperz.Async.collectResults("User; get username and passphrase", {
147 'username': MochiKit.Base.method(this, 'username'), 145 'username': MochiKit.Base.method(this, 'username'),
148 'password': MochiKit.Base.method(this, 'getPassphrase') 146 'password': MochiKit.Base.method(this, 'getPassphrase')
149 }, {trace:false})(); 147 }, {trace:false})();
150 }, 148 },
151 149
152 //------------------------------------------------------------------------- 150 //-------------------------------------------------------------------------
153 151
154 'changePassphrase': function (aNewValue) { 152 'changePassphrase': function (aNewValue) {
155 return this.updateCredentials(this.username(), aNewValue); 153 return this.updateCredentials(this.username(), aNewValue);
156 }, 154 },
157 155
158 //......................................................................... 156 //.........................................................................
159 157
160 'updateCredentials': function (aUsername, aPassphrase) { 158 'updateCredentials': function (aUsername, aPassphrase) {
161 vardeferredResult; 159 vardeferredResult;
162 160
163 deferredResult = new Clipperz.Async.Deferred("User.updateCredentials", {trace:false}); 161 deferredResult = new Clipperz.Async.Deferred("User.updateCredentials", {trace:false});
164 // deferredResult.addMethod(this, 'getPassphrase'); 162 // deferredResult.addMethod(this, 'getPassphrase');
165 // deferredResult.setValue('currentPassphrase'); 163 // deferredResult.setValue('currentPassphrase');
166 deferredResult.addMethod(this.connection(), 'ping'); 164 deferredResult.addMethod(this.connection(), 'ping');
167 deferredResult.addMethod(this, 'setUsername', aUsername) 165 deferredResult.addMethod(this, 'setUsername', aUsername)
168 deferredResult.acquireLock(this.deferredLockForSection('passphrase')); 166 deferredResult.acquireLock(this.deferredLockForSection('passphrase'));
169 deferredResult.addMethod(this.data(), 'deferredGetOrSet', 'passphrase', aPassphrase); 167 deferredResult.addMethod(this.data(), 'deferredGetOrSet', 'passphrase', aPassphrase);
170 deferredResult.releaseLock(this.deferredLockForSection('passphrase')); 168 deferredResult.releaseLock(this.deferredLockForSection('passphrase'));
171 // deferredResult.getValue('currentPassphrase'); 169 // deferredResult.getValue('currentPassphrase');
172 deferredResult.addMethod(this, 'prepareRemoteDataWithKey', aPassphrase); 170 deferredResult.addMethod(this, 'prepareRemoteDataWithKey', aPassphrase);
173 deferredResult.addMethod(this.connection(), 'updateCredentials', aUsername, aPassphrase); 171 deferredResult.addMethod(this.connection(), 'updateCredentials', aUsername, aPassphrase);
174 deferredResult.callback(); 172 deferredResult.callback();
175 173
176 return deferredResult; 174 return deferredResult;
177 }, 175 },
178 176
179 //------------------------------------------------------------------------- 177 //-------------------------------------------------------------------------
180 178
181 'initialSetupWithNoData': function () { 179 'initialSetupWithNoData': function () {
182 this._serverData = { 180 this._serverData = {
183 'version': '0.1', 181 'version': '0.1',
184 'statistics': "", 182 'statistics': "",
185 'header': { 183 'header': {
186 'data': null, 184 'data': null,
187 'version': Clipperz.PM.Crypto.encryptingFunctions.currentVersion, 185 'version': Clipperz.PM.Crypto.encryptingFunctions.currentVersion,
188 186
189 'recordsIndex': new Clipperz.PM.DataModel.User.Header.RecordIndex({ 187 'recordsIndex': new Clipperz.PM.DataModel.User.Header.RecordIndex({
190 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase'), 188 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase'),
191 'recordsData': {'data':null, 'index':{}}, 189 'recordsData': {'data':null, 'index':{}},
192 'recordsStats': null, 190 'recordsStats': null,
193 'directLoginsData': {'data':null, 'index':{}}, 191 'directLoginsData': {'data':null, 'index':{}},
194 'encryptedDataVersion': Clipperz.PM.Crypto.encryptingFunctions.currentVersion, 192 'encryptedDataVersion': Clipperz.PM.Crypto.encryptingFunctions.currentVersion,
195 'retrieveRecordDetailFunction':MochiKit.Base.method(this, 'getRecordDetail') 193 'retrieveRecordDetailFunction':MochiKit.Base.method(this, 'getRecordDetail')
196 }), 194 }),
197 'preferences': new Clipperz.PM.DataModel.User.Header.Preferences({ 195 'preferences': new Clipperz.PM.DataModel.User.Header.Preferences({
198 'name':'preferences', 196 'name':'preferences',
199 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase') 197 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase')
200 }), 198 }),
201 'oneTimePasswords': new Clipperz.PM.DataModel.User.Header.OneTimePasswords({ 199 'oneTimePasswords': new Clipperz.PM.DataModel.User.Header.OneTimePasswords({
202 'name':'preferences', 200 'name':'preferences',
203 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase') 201 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase')
204 }) 202 })
205 } 203 }
206 }; 204 };
207 205
208 // this._serverLockValue = Clipperz.PM.Crypto.randomKey(); 206 // this._serverLockValue = Clipperz.PM.Crypto.randomKey();
209 }, 207 },
210 208
211 //......................................................................... 209 //.........................................................................
212 210
213 'registerAsNewAccount': function () { 211 'registerAsNewAccount': function () {
214 var deferredResult; 212 var deferredResult;
215 213
216 deferredResult = new Clipperz.Async.Deferred("User.registerAsNewAccount", {trace:false}); 214 deferredResult = new Clipperz.Async.Deferred("User.registerAsNewAccount", {trace:false});
217 deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'updateProgress', {'extraSteps':3}); 215 deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'updateProgress', {'extraSteps':3});
218 deferredResult.addMethod(this, 'initialSetupWithNoData') 216 deferredResult.addMethod(this, 'initialSetupWithNoData')
219 deferredResult.addMethod(this, 'getPassphrase'); 217 deferredResult.addMethod(this, 'getPassphrase');
220 deferredResult.addMethod(this, 'prepareRemoteDataWithKey'); 218 deferredResult.addMethod(this, 'prepareRemoteDataWithKey');
221 deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress'); 219 deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress');
222 deferredResult.addMethod(this.connection(), 'register'); 220 deferredResult.addMethod(this.connection(), 'register');
223 // deferredResult.addCallback(MochiKit.Base.itemgetter('lock')); 221 // deferredResult.addCallback(MochiKit.Base.itemgetter('lock'));
224 // deferredResult.addMethod(this, 'setServerLockValue'); 222 // deferredResult.addMethod(this, 'setServerLockValue');
225 deferredResult.addCallbackPass(MochiKit.Signal.signal,Clipperz.Signal.NotificationCenter, 'userSuccessfullyRegistered'); 223 deferredResult.addCallbackPass(MochiKit.Signal.signal,Clipperz.Signal.NotificationCenter, 'userSuccessfullyRegistered');
226 224
227 // deferredResult.addErrback (MochiKit.Base.method(this, 'handleRegistrationFailure')); 225 // deferredResult.addErrback (MochiKit.Base.method(this, 'handleRegistrationFailure'));
228 226
229 deferredResult.callback(); 227 deferredResult.callback();
230 228
231 return deferredResult; 229 return deferredResult;
232 }, 230 },
233 231
234 //------------------------------------------------------------------------- 232 //-------------------------------------------------------------------------
235 233
236 'login': function () { 234 'login': function () {
237 var deferredResult; 235 var deferredResult;
238 236
239 deferredResult = new Clipperz.Async.Deferred("User.login", {trace:false}); 237 deferredResult = new Clipperz.Async.Deferred("User.login", {trace:false});
240 deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'updateProgress', {'extraSteps':3}); 238 deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'updateProgress', {'extraSteps':3});
241 deferredResult.addMethod(this, 'getPassphrase'); 239 deferredResult.addMethod(this, 'getPassphrase');
242 deferredResult.addCallback(Clipperz.PM.DataModel.OneTimePassword.isValidOneTimePasswordValue); 240 deferredResult.addCallback(Clipperz.PM.DataModel.OneTimePassword.isValidOneTimePasswordValue);
243 deferredResult.addCallback(Clipperz.Async.deferredIf("Is the passphrase an OTP", [ 241 deferredResult.addCallback(Clipperz.Async.deferredIf("Is the passphrase an OTP", [
244 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}),
245 MochiKit.Base.method(this, 'getCredentials'), 243 MochiKit.Base.method(this, 'getCredentials'),
246 MochiKit.Base.method(this.connection(), 'redeemOneTimePassword'), 244 MochiKit.Base.method(this.connection(), 'redeemOneTimePassword'),
247 MochiKit.Base.method(this.data(), 'setValue', 'passphrase') 245 MochiKit.Base.method(this.data(), 'setValue', 'passphrase')
248 ], [])); 246 ], []));
249 deferredResult.addErrback(MochiKit.Base.method(this, 'getPassphrase')); 247 deferredResult.addErrback(MochiKit.Base.method(this, 'getPassphrase'));
250 deferredResult.addMethod(this.connection(), 'login', false); 248 deferredResult.addMethod(this.connection(), 'login', false);
251 deferredResult.addCallbackPass(MochiKit.Signal.signal,Clipperz.Signal.NotificationCenter, 'userSuccessfullyLoggedIn'); 249 deferredResult.addCallbackPass(MochiKit.Signal.signal,Clipperz.Signal.NotificationCenter, 'userSuccessfullyLoggedIn');
252 deferredResult.addErrback (MochiKit.Base.method(this, 'handleConnectionFallback')); 250 deferredResult.addErrback (MochiKit.Base.method(this, 'handleConnectionFallback'));
253 251
254 deferredResult.callback(); 252 deferredResult.callback();
255 253
256 return deferredResult; 254 return deferredResult;
257 }, 255 },
258 256
259 //......................................................................... 257 //.........................................................................
260 258
261 'handleConnectionFallback': function(aValue) { 259 'handleConnectionFallback': function(aValue) {
262 var result; 260 var result;
263 261
264 if (aValue instanceof MochiKit.Async.CancelledError) { 262 if (aValue instanceof MochiKit.Async.CancelledError) {
265 result = aValue; 263 result = aValue;
266 } else { 264 } else {
267 this.setConnectionVersion(Clipperz.PM.Connection.communicationProtocol.fallbackVersions[this.connectionVersion()]); 265 this.setConnectionVersion(Clipperz.PM.Connection.communicationProtocol.fallbackVersions[this.connectionVersion()]);
268 266
269 if (this.connectionVersion() != null) { 267 if (this.connectionVersion() != null) {
270 result = new Clipperz.Async.Deferred("User.handleConnectionFallback - retry"); 268 result = new Clipperz.Async.Deferred("User.handleConnectionFallback - retry");
271 269
272 result.addMethod(this, 'login'); 270 result.addMethod(this, 'login');
273 result.callback(); 271 result.callback();
274 } else { 272 } else {
275 result = Clipperz.Async.callbacks("User.handleConnectionFallback - failed", [ 273 result = Clipperz.Async.callbacks("User.handleConnectionFallback - failed", [
276 MochiKit.Base.method(this.data(), 'removeValue', 'passphrase'), 274 MochiKit.Base.method(this.data(), 'removeValue', 'passphrase'),
277 MochiKit.Base.method(this, 'setConnectionVersion', 'current'), 275 MochiKit.Base.method(this, 'setConnectionVersion', 'current'),
278 MochiKit.Base.partial(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'userLoginFailed'), 276 MochiKit.Base.partial(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'userLoginFailed'),
279 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)
280 ], {trace:false}); 278 ], {trace:false});
281 } 279 }
282 } 280 }
283 281
284 return result; 282 return result;
285 }, 283 },
286 284
287 //------------------------------------------------------------------------- 285 //-------------------------------------------------------------------------
288 286
289 'lock': function () { 287 'lock': function () {
290 return Clipperz.Async.callbacks("User.lock", [ 288 return Clipperz.Async.callbacks("User.lock", [
291 MochiKit.Base.method(this, 'deleteAllCleanTextData') 289 MochiKit.Base.method(this, 'deleteAllCleanTextData')
292 ], {trace:false}); 290 ], {trace:false});
293 }, 291 },
294 292
295 //------------------------------------------------------------------------- 293 //-------------------------------------------------------------------------
296 294
297 'logout': function () { 295 'logout': function () {
298 return Clipperz.Async.callbacks("User.logout", [ 296 return Clipperz.Async.callbacks("User.logout", [
299 MochiKit.Base.method(this, 'deleteAllCleanTextData'), 297 MochiKit.Base.method(this, 'deleteAllCleanTextData'),
300 MochiKit.Base.method(this.connection(), 'logout') 298 MochiKit.Base.method(this.connection(), 'logout')
301 ], {trace:false}); 299 ], {trace:false});
302 }, 300 },
303 301
304 //------------------------------------------------------------------------- 302 //-------------------------------------------------------------------------
305 303
306 'headerFormatVersion': function(anHeader) { 304 'headerFormatVersion': function(anHeader) {
307 var result; 305 var result;
308 306
309 if (anHeader.charAt(0) == '{') { 307 if (anHeader.charAt(0) == '{') {
310 varheaderData; 308 varheaderData;
311 309
312 headerData = Clipperz.Base.evalJSON(anHeader); 310 headerData = Clipperz.Base.evalJSON(anHeader);
313 result = headerData['version']; 311 result = headerData['version'];
314 } else { 312 } else {
315 result = 'LEGACY'; 313 result = 'LEGACY';
316 } 314 }
317 315
318 return result; 316 return result;
319 }, 317 },
320 318
321 //------------------------------------------------------------------------- 319 //-------------------------------------------------------------------------
322 320
323 'unpackServerData': function (someServerData) { 321 'unpackServerData': function (someServerData) {
324 var unpackedData; 322 var unpackedData;
325 var headerVersion; 323 var headerVersion;
326 324
327 varrecordsIndex; 325 varrecordsIndex;
328 var preferences; 326 var preferences;
329 var oneTimePasswords; 327 var oneTimePasswords;
330 328
331//console.log(">>> ***************** user.unpackServerData", someServerData);
332 // this.setServerLockValue(someServerData['lock']); 329 // this.setServerLockValue(someServerData['lock']);
333 330
334 headerVersion = this.headerFormatVersion(someServerData['header']); 331 headerVersion = this.headerFormatVersion(someServerData['header']);
335 332
336 switch (headerVersion) { 333 switch (headerVersion) {
337 case 'LEGACY': 334 case 'LEGACY':
338 varlegacyHeader; 335 varlegacyHeader;
339 336
340 legacyHeader = new Clipperz.PM.DataModel.User.Header.Legacy({ 337 legacyHeader = new Clipperz.PM.DataModel.User.Header.Legacy({
341 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase'), 338 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase'),
342 'remoteData': { 339 'remoteData': {
343 'data': someServerData['header'], 340 'data': someServerData['header'],
344 'version': someServerData['version'], 341 'version': someServerData['version'],
345 'recordsStats': someServerData['recordsStats'] 342 'recordsStats': someServerData['recordsStats']
346 }, 343 },
347 // 'encryptedDataKeypath': 'data', 344 // 'encryptedDataKeypath': 'data',
348 // 'encryptedVersionKeypath': 'version', 345 // 'encryptedVersionKeypath': 'version',
349 'retrieveRecordDetailFunction':MochiKit.Base.method(this, 'getRecordDetail') 346 'retrieveRecordDetailFunction':MochiKit.Base.method(this, 'getRecordDetail')
350 }); 347 });
351 348
352 recordsIndex = legacyHeader; 349 recordsIndex = legacyHeader;
353 preferences = legacyHeader; 350 preferences = legacyHeader;
354 oneTimePasswords= legacyHeader; 351 oneTimePasswords= legacyHeader;
355 break; 352 break;
356 case '0.1': 353 case '0.1':
357 varheaderData; 354 varheaderData;
358 355
359 headerData = Clipperz.Base.evalJSON(someServerData['header']); 356 headerData = Clipperz.Base.evalJSON(someServerData['header']);
360 357
361 recordsIndex = new Clipperz.PM.DataModel.User.Header.RecordIndex({ 358 recordsIndex = new Clipperz.PM.DataModel.User.Header.RecordIndex({
362 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase'), 359 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase'),
363 'recordsData': headerData['records'], 360 'recordsData': headerData['records'],
364 'recordsStats': someServerData['recordsStats'], 361 'recordsStats': someServerData['recordsStats'],
365 'directLoginsData': headerData['directLogins'], 362 'directLoginsData': headerData['directLogins'],
366 'encryptedDataVersion': someServerData['version'], 363 'encryptedDataVersion': someServerData['version'],
367 'retrieveRecordDetailFunction':MochiKit.Base.method(this, 'getRecordDetail') 364 'retrieveRecordDetailFunction':MochiKit.Base.method(this, 'getRecordDetail')
368 }); 365 });
369 366
370 //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
371 if (typeof(headerData['preferences']) != 'undefined') { 368 if (typeof(headerData['preferences']) != 'undefined') {
372 preferences= new Clipperz.PM.DataModel.User.Header.Preferences({ 369 preferences= new Clipperz.PM.DataModel.User.Header.Preferences({
373 'name':'preferences', 370 'name':'preferences',
374 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase'), 371 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase'),
375 'remoteData': { 372 'remoteData': {
376 'data': headerData['preferences']['data'], 373 'data': headerData['preferences']['data'],
377 'version': someServerData['version'] 374 'version': someServerData['version']
378 } 375 }
379 }); 376 });
380 } else { 377 } else {
381 preferences= new Clipperz.PM.DataModel.User.Header.Preferences({ 378 preferences= new Clipperz.PM.DataModel.User.Header.Preferences({
382 'name':'preferences', 379 'name':'preferences',
383 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase') 380 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase')
384 }); 381 });
385 } 382 }
386 383
387 if (typeof(headerData['oneTimePasswords']) != 'undefined') { 384 if (typeof(headerData['oneTimePasswords']) != 'undefined') {
388 oneTimePasswords = new Clipperz.PM.DataModel.User.Header.OneTimePasswords({ 385 oneTimePasswords = new Clipperz.PM.DataModel.User.Header.OneTimePasswords({
389 'name':'preferences', 386 'name':'preferences',
390 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase'), 387 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase'),
391 'remoteData': { 388 'remoteData': {
392 'data': headerData['oneTimePasswords']['data'], 389 'data': headerData['oneTimePasswords']['data'],
393 'version': someServerData['version'] 390 'version': someServerData['version']
394 } 391 }
395 }); 392 });
396 } else { 393 } else {
397 oneTimePasswords = new Clipperz.PM.DataModel.User.Header.OneTimePasswords({ 394 oneTimePasswords = new Clipperz.PM.DataModel.User.Header.OneTimePasswords({
398 'name':'preferences', 395 'name':'preferences',
399 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase') 396 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase')
400 }); 397 });
401 } 398 }
402 399
403 break; 400 break;
404 } 401 }
405 402
406 unpackedData = { 403 unpackedData = {
407 'version': someServerData['version'], 404 'version': someServerData['version'],
408 'statistics': someServerData['statistics'], 405 'statistics': someServerData['statistics'],
409 'header': { 406 'header': {
410 'data': someServerData['header'], 407 'data': someServerData['header'],
411 'version': headerVersion, 408 'version': headerVersion,
412 409
413 'recordsIndex': recordsIndex, 410 'recordsIndex': recordsIndex,
414 'preferences': preferences, 411 'preferences': preferences,
415 'oneTimePasswords': oneTimePasswords 412 'oneTimePasswords': oneTimePasswords
416 } 413 }
417 }; 414 };
418 415
419 this._serverData = unpackedData; 416 this._serverData = unpackedData;
420//console.log("<<< ***************** user.unpackServerData", this._serverData);
421 417
422 return this._serverData; 418 return this._serverData;
423 }, 419 },
424 420
425 //------------------------------------------------------------------------- 421 //-------------------------------------------------------------------------
426 422
427 'getServerData': function() { 423 'getServerData': function() {
428 var deferredResult; 424 var deferredResult;
429 425
430 deferredResult = new Clipperz.Async.Deferred("User.getServerData", {trace:false}); 426 deferredResult = new Clipperz.Async.Deferred("User.getServerData", {trace:false});
431 deferredResult.acquireLock(this.deferredLockForSection('serverData')); 427 deferredResult.acquireLock(this.deferredLockForSection('serverData'));
432 deferredResult.addCallback(MochiKit.Base.bind(function(aResult) { 428 deferredResult.addCallback(MochiKit.Base.bind(function(aResult) {
433 var innerDeferredResult; 429 var innerDeferredResult;
434 430
435 innerDeferredResult = new Clipperz.Async.Deferred("User.getUserDetails.innerDeferred", {trace:false}); 431 innerDeferredResult = new Clipperz.Async.Deferred("User.getUserDetails.innerDeferred", {trace:false});
436 if (this._serverData == null) { 432 if (this._serverData == null) {
437 innerDeferredResult.addCallbackPass(MochiKit.Signal.signal, this, 'loadingUserDetails'); 433 innerDeferredResult.addCallbackPass(MochiKit.Signal.signal, this, 'loadingUserDetails');
438 innerDeferredResult.addMethod(this.connection(), 'message', 'getUserDetails'); 434 innerDeferredResult.addMethod(this.connection(), 'message', 'getUserDetails');
439 innerDeferredResult.addMethod(this, 'unpackServerData'); 435 innerDeferredResult.addMethod(this, 'unpackServerData');
440 innerDeferredResult.addCallbackPass(MochiKit.Signal.signal, this, 'loadedUserDetails'); 436 innerDeferredResult.addCallbackPass(MochiKit.Signal.signal, this, 'loadedUserDetails');
441 } 437 }
442 438
443 innerDeferredResult.addCallback(MochiKit.Base.bind(function () { 439 innerDeferredResult.addCallback(MochiKit.Base.bind(function () {
444 return this._serverData; 440 return this._serverData;
445 },this)); 441 },this));
446 innerDeferredResult.callback(); 442 innerDeferredResult.callback();
447 443
448 return innerDeferredResult; 444 return innerDeferredResult;
449 }, this)); 445 }, this));
450 deferredResult.releaseLock(this.deferredLockForSection('serverData')); 446 deferredResult.releaseLock(this.deferredLockForSection('serverData'));
451 deferredResult.callback(); 447 deferredResult.callback();
452 448
453 return deferredResult; 449 return deferredResult;
454 }, 450 },
455 451
456 //------------------------------------------------------------------------- 452 //-------------------------------------------------------------------------
457 453
458 'connectionVersion': function() { 454 'connectionVersion': function() {
459 return this._connectionVersion; 455 return this._connectionVersion;
460 }, 456 },
461 457
462 'setConnectionVersion': function(aValue) { 458 'setConnectionVersion': function(aValue) {
463 if (this._connectionVersion != aValue) { 459 if (this._connectionVersion != aValue) {
464 this.resetConnection(); 460 this.resetConnection();
465 } 461 }
466 this._connectionVersion = aValue; 462 this._connectionVersion = aValue;
467 }, 463 },
468 464
469 //------------------------------------------------------------------------- 465 //-------------------------------------------------------------------------
470 466
471 'connection': function() { 467 'connection': function() {
472 if ((this._connection == null) && (this.connectionVersion() != null) ){ 468 if ((this._connection == null) && (this.connectionVersion() != null) ){
473 this._connection = new Clipperz.PM.Connection.communicationProtocol.versions[this.connectionVersion()]({ 469 this._connection = new Clipperz.PM.Connection.communicationProtocol.versions[this.connectionVersion()]({
474 getCredentialsFunction: MochiKit.Base.method(this, 'getCredentials') 470 getCredentialsFunction: MochiKit.Base.method(this, 'getCredentials')
475 }); 471 });
476 } 472 }
477 473
478 return this._connection; 474 return this._connection;
479 }, 475 },
480 476
481 'resetConnection': function(aValue) { 477 'resetConnection': function(aValue) {
482 if (this._connection != null) { 478 if (this._connection != null) {
483 this._connection.reset(); 479 this._connection.reset();
484 } 480 }
485 481
486 this._connection = null; 482 this._connection = null;
487 }, 483 },
488 484
489 //========================================================================= 485 //=========================================================================
490 486
491 'getHeaderIndex': function (aKey) { 487 'getHeaderIndex': function (aKey) {
492 return Clipperz.Async.callbacks("User.getHeaderIndex", [ 488 return Clipperz.Async.callbacks("User.getHeaderIndex", [
493 MochiKit.Base.method(this, 'getServerData'), 489 MochiKit.Base.method(this, 'getServerData'),
494 MochiKit.Base.itemgetter('header'), 490 MochiKit.Base.itemgetter('header'),
495 MochiKit.Base.itemgetter(aKey) 491 MochiKit.Base.itemgetter(aKey)
496 ], {trace:false}) 492 ], {trace:false})
497 }, 493 },
498 494
499 //========================================================================= 495 //=========================================================================
500 496
501 'getRecords': function () { 497 'getRecords': function () {
502 return Clipperz.Async.callbacks("User.getRecords", [ 498 return Clipperz.Async.callbacks("User.getRecords", [
503 MochiKit.Base.method(this, 'getHeaderIndex', 'recordsIndex'), 499 MochiKit.Base.method(this, 'getHeaderIndex', 'recordsIndex'),
504 MochiKit.Base.methodcaller('records'), 500 MochiKit.Base.methodcaller('records'),
505 MochiKit.Base.values 501 MochiKit.Base.values
506 ], {trace:false}); 502 ], {trace:false});
507 }, 503 },
508 504
509 'recordWithLabel': function (aLabel) { 505 'recordWithLabel': function (aLabel) {
510 return Clipperz.Async.callbacks("User.recordWithLabel", [ 506 return Clipperz.Async.callbacks("User.recordWithLabel", [
511 MochiKit.Base.method(this, 'getRecords'), 507 MochiKit.Base.method(this, 'getRecords'),
512 MochiKit.Base.partial(Clipperz.Async.deferredFilter, function (aRecord) { 508 MochiKit.Base.partial(Clipperz.Async.deferredFilter, function (aRecord) {
513 return Clipperz.Async.callbacks("User.recordWithLabel - check record label", [ 509 return Clipperz.Async.callbacks("User.recordWithLabel - check record label", [
514 MochiKit.Base.methodcaller('label'), 510 MochiKit.Base.methodcaller('label'),
515 MochiKit.Base.partial(MochiKit.Base.operator.eq, aLabel) 511 MochiKit.Base.partial(MochiKit.Base.operator.eq, aLabel)
516 ], {trace:false}, aRecord); 512 ], {trace:false}, aRecord);
517 }), 513 }),
518 function (someFilteredResults) { 514 function (someFilteredResults) {
519 var result; 515 var result;
520 516
521 switch (someFilteredResults.length) { 517 switch (someFilteredResults.length) {
522 case 0: 518 case 0:
523 result = null; 519 result = null;
524 break; 520 break;
525 case 1: 521 case 1:
526 result = someFilteredResults[0]; 522 result = someFilteredResults[0];
527 break; 523 break;
528 default: 524 default:
529 WTF = TODO; 525 WTF = TODO;
530 break; 526 break;
531 } 527 }
532 528
533 return result; 529 return result;
534 } 530 }
535 ], {trace:false}); 531 ], {trace:false});
536 }, 532 },
537 533
538 //------------------------------------------------------------------------- 534 //-------------------------------------------------------------------------
539 535
540 'getRecord': function (aRecordReference) { 536 'getRecord': function (aRecordReference) {
541 return Clipperz.Async.callbacks("User.getRecord", [ 537 return Clipperz.Async.callbacks("User.getRecord", [
542 MochiKit.Base.method(this, 'getHeaderIndex', 'recordsIndex'), 538 MochiKit.Base.method(this, 'getHeaderIndex', 'recordsIndex'),
543 MochiKit.Base.methodcaller('records'), 539 MochiKit.Base.methodcaller('records'),
544 MochiKit.Base.itemgetter(aRecordReference), 540 MochiKit.Base.itemgetter(aRecordReference),
545 541
546 Clipperz.Async.deferredIf("record != null", [ 542 Clipperz.Async.deferredIf("record != null", [
547 MochiKit.Base.operator.identity 543 MochiKit.Base.operator.identity
548 ], [ 544 ], [
549 function () { throw "Record does not exists"} 545 function () { throw "Record does not exists"}
550 ]) 546 ])
551 ], {trace:false}); 547 ], {trace:false});
552 }, 548 },
553 549
554 //------------------------------------------------------------------------- 550 //-------------------------------------------------------------------------
555 551
556 'getRecordDetail': function (aRecordReference) { 552 'getRecordDetail': function (aRecordReference) {
557 return this.connection().message('getRecordDetail', {reference: aRecordReference}); 553 return this.connection().message('getRecordDetail', {reference: aRecordReference});
558 }, 554 },
559 555
560 //------------------------------------------------------------------------- 556 //-------------------------------------------------------------------------
561 557
562 'deleteRecord': function (aRecord) { 558 'deleteRecord': function (aRecord) {
563 return Clipperz.Async.callbacks("User.deleteRecord", [ 559 return Clipperz.Async.callbacks("User.deleteRecord", [
564 MochiKit.Base.method(this, 'getHeaderIndex', 'recordsIndex'), 560 MochiKit.Base.method(this, 'getHeaderIndex', 'recordsIndex'),
565 MochiKit.Base.methodcaller('deleteRecord', aRecord) 561 MochiKit.Base.methodcaller('deleteRecord', aRecord)
566 ], {trace:false}); 562 ], {trace:false});
567 }, 563 },
568 564
569 //------------------------------------------------------------------------- 565 //-------------------------------------------------------------------------
570 566
571 'createNewRecord': function () { 567 'createNewRecord': function () {
572 return Clipperz.Async.callbacks("User.createNewRecord", [ 568 return Clipperz.Async.callbacks("User.createNewRecord", [
573 MochiKit.Base.method(this, 'getHeaderIndex', 'recordsIndex'), 569 MochiKit.Base.method(this, 'getHeaderIndex', 'recordsIndex'),
574 MochiKit.Base.methodcaller('createNewRecord') 570 MochiKit.Base.methodcaller('createNewRecord')
575 ], {trace:false}); 571 ], {trace:false});
576 }, 572 },
577 573
578 //========================================================================= 574 //=========================================================================
579 575
580 'getDirectLogins': function() { 576 'getDirectLogins': function() {
581 var deferredResult; 577 var deferredResult;
582 578
583 deferredResult = new Clipperz.Async.Deferred("User.getDirectLogins", {trace:false}); 579 deferredResult = new Clipperz.Async.Deferred("User.getDirectLogins", {trace:false});
584 deferredResult.addMethod(this, 'getRecords'); 580 deferredResult.addMethod(this, 'getRecords');
585 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')));
586 deferredResult.addCallback(MochiKit.Base.flattenArray); 582 deferredResult.addCallback(MochiKit.Base.flattenArray);
587 deferredResult.callback(); 583 deferredResult.callback();
588 584
589 return deferredResult; 585 return deferredResult;
590 }, 586 },
591 587
592 //========================================================================= 588 //=========================================================================
593 589
594 'getOneTimePasswords': function () { 590 'getOneTimePasswords': function () {
595 return Clipperz.Async.callbacks("User.getOneTimePasswords", [ 591 return Clipperz.Async.callbacks("User.getOneTimePasswords", [
596 MochiKit.Base.method(this, 'getHeaderIndex', 'oneTimePasswords'), 592 MochiKit.Base.method(this, 'getHeaderIndex', 'oneTimePasswords'),
597 MochiKit.Base.methodcaller('oneTimePasswords'), 593 MochiKit.Base.methodcaller('oneTimePasswords'),
598 MochiKit.Base.values 594 MochiKit.Base.values
599 ], {trace:false}); 595 ], {trace:false});
600 }, 596 },
601 597
602 //========================================================================= 598 //=========================================================================
603 599
604 'invokeMethodNamedOnHeader': function (aMethodName, aValue) { 600 'invokeMethodNamedOnHeader': function (aMethodName, aValue) {
605 return Clipperz.Async.collectResults("User.invokeMethodNamedOnHeader [" + aMethodName + "]", { 601 return Clipperz.Async.collectResults("User.invokeMethodNamedOnHeader [" + aMethodName + "]", {
606 'recordIndex': [ 602 'recordIndex': [
607 MochiKit.Base.method(this, 'getHeaderIndex', 'recordsIndex'), 603 MochiKit.Base.method(this, 'getHeaderIndex', 'recordsIndex'),
608 MochiKit.Base.methodcaller(aMethodName, aValue) 604 MochiKit.Base.methodcaller(aMethodName, aValue)
609 ], 605 ],
610 'preferences': [ 606 'preferences': [
611 MochiKit.Base.method(this, 'getHeaderIndex', 'preferences'), 607 MochiKit.Base.method(this, 'getHeaderIndex', 'preferences'),
612 MochiKit.Base.methodcaller(aMethodName, aValue) 608 MochiKit.Base.methodcaller(aMethodName, aValue)