mirror of
http://git.whoc.org.uk/git/password-manager.git
synced 2024-11-01 13:27:16 +01:00
905 lines
36 KiB
JavaScript
905 lines
36 KiB
JavaScript
|
/*
|
||
|
|
||
|
Copyright 2008-2011 Clipperz Srl
|
||
|
|
||
|
This file is part of Clipperz's Javascript Crypto Library.
|
||
|
Javascript Crypto Library provides web developers with an extensive
|
||
|
and efficient set of cryptographic functions. The library aims to
|
||
|
obtain maximum execution speed while preserving modularity and
|
||
|
reusability.
|
||
|
For further information about its features and functionalities please
|
||
|
refer to http://www.clipperz.com
|
||
|
|
||
|
* Javascript Crypto Library is free software: you can redistribute
|
||
|
it and/or modify it under the terms of the GNU Affero General Public
|
||
|
License as published by the Free Software Foundation, either version
|
||
|
3 of the License, or (at your option) any later version.
|
||
|
|
||
|
* Javascript Crypto Library is distributed in the hope that it will
|
||
|
be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||
|
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||
|
See the GNU Affero General Public License for more details.
|
||
|
|
||
|
* You should have received a copy of the GNU Affero General Public
|
||
|
License along with Javascript Crypto Library. If not, see
|
||
|
<http://www.gnu.org/licenses/>.
|
||
|
|
||
|
*/
|
||
|
|
||
|
if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
|
||
|
if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; }
|
||
|
if (typeof(Clipperz.PM.DataModel) == 'undefined') { Clipperz.PM.DataModel = {}; }
|
||
|
|
||
|
|
||
|
//#############################################################################
|
||
|
|
||
|
Clipperz.PM.DataModel.User = function(args) {
|
||
|
//MochiKit.Logging.logDebug(">>> new User");
|
||
|
args = args || {};
|
||
|
|
||
|
this._username = args.username || null;
|
||
|
this._passphrase = args.passphrase || null;
|
||
|
|
||
|
this._connection = null;
|
||
|
this._connectionVersion = 'current';
|
||
|
|
||
|
this._header = null;
|
||
|
this._statistics = null;
|
||
|
this._lock = 'new lock';
|
||
|
|
||
|
this._preferences = null;
|
||
|
this._records = {};
|
||
|
this._directLoginReferences = {};
|
||
|
this._oneTimePasswordManager = null;
|
||
|
|
||
|
this._isLoadingUserDetails = false;
|
||
|
this._loadingUserDetailsPendingQueue = [];
|
||
|
|
||
|
this._maxNumberOfRecords = Number.MAX_VALUE;
|
||
|
|
||
|
this._shouldDownloadOfflineCopy = false;
|
||
|
|
||
|
this._loginInfo = null;
|
||
|
this._loginHistory = null;
|
||
|
|
||
|
this._serverData = null;
|
||
|
//MochiKit.Logging.logDebug("<<< new User");
|
||
|
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
Clipperz.PM.DataModel.User.prototype = MochiKit.Base.update(null, {
|
||
|
|
||
|
'toString': function() {
|
||
|
return "Clipperz.PM.DataModel.User - " + this.username();
|
||
|
},
|
||
|
|
||
|
//-------------------------------------------------------------------------
|
||
|
|
||
|
'username': function() {
|
||
|
return this._username;
|
||
|
},
|
||
|
|
||
|
'setUsername': function(aValue) {
|
||
|
this._username = aValue;
|
||
|
},
|
||
|
|
||
|
//-------------------------------------------------------------------------
|
||
|
|
||
|
'passphrase': function() {
|
||
|
return this._passphrase;
|
||
|
},
|
||
|
|
||
|
'setPassphrase': function(aValue) {
|
||
|
this._passphrase = aValue;
|
||
|
},
|
||
|
|
||
|
//-------------------------------------------------------------------------
|
||
|
|
||
|
'maxNumberOfRecords': function() {
|
||
|
return this._maxNumberOfRecords;
|
||
|
},
|
||
|
|
||
|
'setMaxNumberOfRecords': function(aValue) {
|
||
|
this._maxNumberOfRecords = aValue;
|
||
|
},
|
||
|
|
||
|
//-------------------------------------------------------------------------
|
||
|
|
||
|
'errorHandler': function(anErrorString, anException) {
|
||
|
MochiKit.Logging.logError("- User.errorHandler: " + anErrorString + " (" + anException + ")");
|
||
|
},
|
||
|
|
||
|
//-------------------------------------------------------------------------
|
||
|
|
||
|
'connectionVersion': function() {
|
||
|
return this._connectionVersion;
|
||
|
},
|
||
|
|
||
|
'setConnectionVersion': function(aValue) {
|
||
|
this._connectionVersion = aValue;
|
||
|
},
|
||
|
|
||
|
//-------------------------------------------------------------------------
|
||
|
|
||
|
'connection': function() {
|
||
|
if ((this._connection == null) && (this.connectionVersion() != null) ){
|
||
|
this._connection = new Clipperz.PM.Crypto.communicationProtocol.versions[this.connectionVersion()]({user:this});
|
||
|
}
|
||
|
|
||
|
return this._connection;
|
||
|
},
|
||
|
|
||
|
'resetConnection': function(aValue) {
|
||
|
this._connection = null;
|
||
|
},
|
||
|
|
||
|
//=========================================================================
|
||
|
|
||
|
'register': function(anInvitationCode) {
|
||
|
var deferredResult;
|
||
|
var prng;
|
||
|
|
||
|
//MochiKit.Logging.logError(">>> User.register: " + this);
|
||
|
prng = Clipperz.Crypto.PRNG.defaultRandomGenerator();
|
||
|
|
||
|
deferredResult = new MochiKit.Async.Deferred()
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.register - 1: " + res); return res;});
|
||
|
deferredResult.addCallback(MochiKit.Base.method(prng, 'deferredEntropyCollection'));
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.register - 2: " + res); return res;});
|
||
|
deferredResult.addCallback(MochiKit.Base.method(this.header(), 'updateAllSections'), anInvitationCode);
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.register - 2.1: " + res); return res;});
|
||
|
deferredResult.addCallback(MochiKit.Base.method(this.connection(), 'register'), anInvitationCode);
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.register - 3: " + res); return res;});
|
||
|
deferredResult.callback();
|
||
|
//MochiKit.Logging.logError("<<< User.register");
|
||
|
|
||
|
return deferredResult;
|
||
|
},
|
||
|
|
||
|
//=========================================================================
|
||
|
|
||
|
'connect': function(aValue) {
|
||
|
var deferredResult;
|
||
|
var prng;
|
||
|
|
||
|
prng = Clipperz.Crypto.PRNG.defaultRandomGenerator();
|
||
|
|
||
|
//MochiKit.Logging.logDebug(">>> User.connect");
|
||
|
deferredResult = new MochiKit.Async.Deferred();
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("1.2.1 - User.connect - 1: "/* + res*/); return res;});
|
||
|
//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
|
||
|
deferredResult.addCallback(MochiKit.Base.method(prng, 'deferredEntropyCollection'));
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("1.2.2 - User.connect - 2: "/* + res*/); return res;});
|
||
|
//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
|
||
|
deferredResult.addCallback(MochiKit.Base.method(this.connection(), 'login'));
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("1.2.3 - User.connect - 3: "/* + res*/); return res;});
|
||
|
//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
|
||
|
|
||
|
// TODO: add an addErrback call here to manage a wrong login. Any error after this point is due to some other causes.
|
||
|
// possibly the same exact 'handleConnectionFallback use at the end of this same method.
|
||
|
|
||
|
if (this.connectionVersion() != 'current') {
|
||
|
var currentConnection;
|
||
|
|
||
|
currentVersionConnection = new Clipperz.PM.Crypto.communicationProtocol.versions['current']({user:this});
|
||
|
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("1.2.4 - User.connect - 4: "/* + res*/); return res;});
|
||
|
//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
|
||
|
deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'connection_upgrading');
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("1.2.5 - User.connect - 5: "/* + res*/); return res;});
|
||
|
//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
|
||
|
deferredResult.addCallback(MochiKit.Base.method(this.connection(), 'message'), 'upgradeUserCredentials', currentVersionConnection.serverSideUserCredentials());
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("1.2.6 - User.connect - 6: "/* + res*/); return res;});
|
||
|
//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
|
||
|
}
|
||
|
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("1.2.7 - User.connect - 7: "/* + res*/); return res;});
|
||
|
//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
|
||
|
deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'userConnected', null);
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("1.2.8 - User.connect - 8: "/* + res*/); return res;});
|
||
|
//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
|
||
|
deferredResult.addErrback(MochiKit.Base.method(this, 'handleConnectionFallback'));
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("1.2.9 - User.connect - 9: "/* + res*/); return res;});
|
||
|
//deferredResult.addErrback(function(res) {MochiKit.Logging.logDebug("ERROR: " + res); return res;});
|
||
|
|
||
|
deferredResult.callback(aValue);
|
||
|
//MochiKit.Logging.logDebug("<<< User.connect");
|
||
|
|
||
|
return deferredResult;
|
||
|
},
|
||
|
|
||
|
//.........................................................................
|
||
|
|
||
|
'handleConnectionFallback': function(aValue) {
|
||
|
var result;
|
||
|
//MochiKit.Logging.logDebug(">>> User.handleConnectionFallback");
|
||
|
if (aValue instanceof MochiKit.Async.CancelledError) {
|
||
|
//MochiKit.Logging.logDebug("--- User.handleConnectionFallback - operation cancelled");
|
||
|
result = aValue;
|
||
|
} else {
|
||
|
|
||
|
//MochiKit.Logging.logDebug("--- User.handleConnectionFallback - an ERROR has occurred - " + aValue);
|
||
|
this.resetConnection();
|
||
|
this.setConnectionVersion(Clipperz.PM.Crypto.communicationProtocol.fallbackVersions[this.connectionVersion()]);
|
||
|
|
||
|
if (this.connectionVersion() != null) {
|
||
|
result = new MochiKit.Async.Deferred();
|
||
|
|
||
|
result.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'connection_tryOlderSchema');
|
||
|
result.addCallback(MochiKit.Base.method(this, 'connect'));
|
||
|
result.callback();
|
||
|
} else {
|
||
|
result = MochiKit.Async.fail(Clipperz.PM.DataModel.User.exception.LoginFailed);
|
||
|
}
|
||
|
}
|
||
|
//MochiKit.Logging.logDebug("<<< User.handleConnectionFallback");
|
||
|
return result;
|
||
|
},
|
||
|
|
||
|
//=========================================================================
|
||
|
|
||
|
'header': function() {
|
||
|
if (this._header == null) {
|
||
|
this._header = new Clipperz.PM.DataModel.Header({user:this});
|
||
|
}
|
||
|
return this._header;
|
||
|
},
|
||
|
|
||
|
//-------------------------------------------------------------------------
|
||
|
|
||
|
'statistics': function() {
|
||
|
if (this._statistics == null) {
|
||
|
this._statistics = new Clipperz.PM.DataModel.Statistics({user:this});
|
||
|
}
|
||
|
return this._statistics;
|
||
|
},
|
||
|
|
||
|
//-------------------------------------------------------------------------
|
||
|
|
||
|
'records': function() {
|
||
|
return this._records;
|
||
|
},
|
||
|
|
||
|
//.........................................................................
|
||
|
|
||
|
'addRecord': function(aValue, isBatchUpdate) {
|
||
|
this.records()[aValue.reference()] = aValue;
|
||
|
|
||
|
if (isBatchUpdate != true) {
|
||
|
Clipperz.NotificationCenter.notify(aValue, 'recordAdded', null, true);
|
||
|
Clipperz.NotificationCenter.notify(this, 'updatedSection', 'records', true);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
'addNewRecord': function() {
|
||
|
var record;
|
||
|
|
||
|
//MochiKit.Logging.logDebug(">>> User.addNewRecord");
|
||
|
record = new Clipperz.PM.DataModel.Record({user:this});
|
||
|
this.addRecord(record);
|
||
|
Clipperz.NotificationCenter.notify(this, 'updatedSection', 'records', true);
|
||
|
//MochiKit.Logging.logDebug("<<< User.addNewRecord");
|
||
|
|
||
|
return record;
|
||
|
},
|
||
|
|
||
|
//-------------------------------------------------------------------------
|
||
|
|
||
|
'saveRecords': function(someRecords, aMethodName) {
|
||
|
var deferredResult;
|
||
|
var methodName;
|
||
|
var result;
|
||
|
var i,c;
|
||
|
|
||
|
//console.log("User.saveRecords - someRecords", someRecords);
|
||
|
methodName = aMethodName || 'addNewRecords';
|
||
|
|
||
|
Clipperz.NotificationCenter.notify(this, 'updatedSection', 'records', true);
|
||
|
//MochiKit.Logging.logDebug(">>> User.saveRecords");
|
||
|
//MochiKit.Logging.logDebug(">>> [" + (new Date()).valueOf() + "] User.saveRecords");
|
||
|
/*
|
||
|
MochiKit.Logging.logDebug("--- User.saveRecords - 1");
|
||
|
MochiKit.Iter.forEach(someRecords, function(aRecord) {
|
||
|
if (aRecord.headerNotes() != null) {
|
||
|
aRecord.setNotes(aRecord.headerNotes());
|
||
|
}
|
||
|
aRecord.syncDirectLoginReferenceValues();
|
||
|
aRecord.currentVersion().createNewVersion();
|
||
|
aRecord.updateKey();
|
||
|
});
|
||
|
MochiKit.Logging.logDebug("--- User.saveRecords - 2");
|
||
|
*/
|
||
|
|
||
|
result = {'records': []};
|
||
|
|
||
|
deferredResult = new MochiKit.Async.Deferred();
|
||
|
c = someRecords.length;
|
||
|
for (i=0; i<c; i++) {
|
||
|
deferredResult.addCallback(function(aRecord) {
|
||
|
if (aRecord.headerNotes() != null) {
|
||
|
aRecord.setNotes(aRecord.headerNotes());
|
||
|
}
|
||
|
aRecord.syncDirectLoginReferenceValues();
|
||
|
aRecord.currentVersion().createNewVersion();
|
||
|
aRecord.updateKey();
|
||
|
}, someRecords[i]);
|
||
|
deferredResult.addCallback(MochiKit.Async.wait, 0.1);
|
||
|
}
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.saveRecords - 1 " + res); return res;});
|
||
|
deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'saveCard_collectRecordInfo');
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.saveRecords - 2 " + res); return res;});
|
||
|
|
||
|
deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'saveCard_encryptUserData');
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.saveRecords - 3 " + res); return res;});
|
||
|
deferredResult.addCallback(MochiKit.Base.method(this, 'encryptedData'));
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.saveRecords - 4 " + res); return res;});
|
||
|
deferredResult.addCallback(function(aResult, res) {
|
||
|
aResult['user'] = res;
|
||
|
return aResult;
|
||
|
}, result);
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.saveRecords - 5 " + res); return res;});
|
||
|
|
||
|
c = someRecords.length;
|
||
|
for (i=0; i<c; i++) {
|
||
|
var recordData;
|
||
|
|
||
|
recordData = {};
|
||
|
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.saveRecords - 6.1 " + res); return res;});
|
||
|
deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'saveCard_encryptRecordData');
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.saveRecords - 6.2 " + res); return res;});
|
||
|
deferredResult.addCallback(MochiKit.Base.method(someRecords[i], 'encryptedData'));
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.saveRecords - 6.3 " + res); return res;});
|
||
|
deferredResult.addCallback(function(aResult, res) {
|
||
|
aResult['record'] = res;
|
||
|
return aResult;
|
||
|
}, recordData);
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.saveRecords - 6.4 " + res); return res;});
|
||
|
|
||
|
deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', {} /*'saveCard_encryptRecordVersions'*/);
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.saveRecords - 6.5 " + res); return res;});
|
||
|
deferredResult.addCallback(MochiKit.Base.method(someRecords[i].currentVersion(), 'encryptedData'));
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.saveRecords - 6.6 " + res); return res;});
|
||
|
deferredResult.addCallback(function(aResult, res) {
|
||
|
aResult['currentRecordVersion'] = res;
|
||
|
return aResult;
|
||
|
}, recordData);
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.saveRecords - 6.7 " + res); return res;});
|
||
|
|
||
|
deferredResult.addCallback(function(aResult, res) {
|
||
|
aResult['records'].push(res);
|
||
|
return aResult;
|
||
|
}, result);
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.saveRecords - 6.8 " + res); return res;});
|
||
|
}
|
||
|
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.saveRecords - 7 " + res); return res;});
|
||
|
deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'saveCard_sendingData');
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.saveRecords - 8 " + res); return res;});
|
||
|
deferredResult.addCallback(MochiKit.Base.method(this.connection(), 'message'), methodName);
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.saveRecords - 9 " + res); return res;});
|
||
|
|
||
|
for (i=0; i<c; i++) {
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.saveRecords - 9.1 " + res); return res;});
|
||
|
deferredResult.addCallback(MochiKit.Base.method(someRecords[i], 'takeSnapshotOfCurrentData'));
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.saveRecords - 9.2 " + res); return res;});
|
||
|
deferredResult.addCallback(MochiKit.Base.method(someRecords[i], 'setIsBrandNew'), false);
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.saveRecords - 9.3 " + res); return res;});
|
||
|
}
|
||
|
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.saveRecords - 10 " + res); return res;});
|
||
|
deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'notify', 'recordUpdated');
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.saveRecords - 11 " + res); return res;});
|
||
|
deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'notify', 'directLoginUpdated');
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.saveRecords - 12 " + res); return res;});
|
||
|
deferredResult.callback();
|
||
|
|
||
|
return deferredResult;
|
||
|
},
|
||
|
|
||
|
//-------------------------------------------------------------------------
|
||
|
|
||
|
'removeRecord': function(aRecord) {
|
||
|
//MochiKit.Logging.logDebug(">>> User.removeRecord");
|
||
|
delete this.records()[aRecord.reference()];
|
||
|
//MochiKit.Logging.logDebug("--- User.removeRecord - 1");
|
||
|
Clipperz.NotificationCenter.notify(aRecord, 'recordRemoved', null, false);
|
||
|
Clipperz.NotificationCenter.notify(this, 'updatedSection', 'records', true);
|
||
|
//MochiKit.Logging.logDebug("<<< User.removeRecord");
|
||
|
},
|
||
|
|
||
|
//-------------------------------------------------------------------------
|
||
|
|
||
|
'deleteRecordsAction': function(someRecords) {
|
||
|
var deferredResult;
|
||
|
var parameters;
|
||
|
|
||
|
//MochiKit.Logging.logDebug(">>> User.deleteRecordsAction - someRecords.length: " + someRecords.length);
|
||
|
parameters = {};
|
||
|
deferredResult = new MochiKit.Async.Deferred();
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.deleteRecordsAction - 1 " + res); return res;});
|
||
|
deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'deleteRecord_collectData');
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.deleteRecordsAction - 2 " + res); return res;});
|
||
|
deferredResult.addCallback(function(someParameters, someRecords) {
|
||
|
var recordReferences;
|
||
|
|
||
|
recordReferences = MochiKit.Base.map(function(aRecord) {
|
||
|
var result;
|
||
|
|
||
|
result = aRecord.reference();
|
||
|
aRecord.remove();
|
||
|
|
||
|
return result;
|
||
|
}, someRecords);
|
||
|
someParameters.recordReferences = recordReferences;
|
||
|
|
||
|
return someParameters;
|
||
|
}, parameters);
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.deleteRecordsAction - 3 " + res); return res;});
|
||
|
deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'deleteRecord_encryptData');
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.deleteRecordsAction - 4 " + res); return res;});
|
||
|
deferredResult.addCallback(MochiKit.Base.method(this, 'encryptedData'));
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.deleteRecordsAction - 5 " + res); return res;});
|
||
|
deferredResult.addCallback(function(someParameters, anUserEncryptedData) {
|
||
|
someParameters.user = anUserEncryptedData;
|
||
|
return someParameters;
|
||
|
}, parameters);
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.deleteRecordsAction - 6 " + res); return res;});
|
||
|
deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'deleteRecord_sendingData');
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.deleteRecords parameters: " + Clipperz.Base.serializeJSON(res)); return res;});
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.deleteRecordsAction - 7 " + res); return res;});
|
||
|
deferredResult.addCallback(MochiKit.Base.method(this.connection(), 'message'), 'deleteRecords');
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.deleteRecordsAction - 8 " + res); return res;});
|
||
|
deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'deleteRecord_updatingInterface');
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.deleteRecordsAction - 9 " + res); return res;});
|
||
|
deferredResult.callback(someRecords);
|
||
|
//MochiKit.Logging.logDebug("<<< User.deleteRecordsAction");
|
||
|
|
||
|
return deferredResult;
|
||
|
},
|
||
|
|
||
|
//-------------------------------------------------------------------------
|
||
|
|
||
|
'resetAllLocalData': function() {
|
||
|
this.resetConnection();
|
||
|
|
||
|
this.setUsername("");
|
||
|
this.setPassphrase("");
|
||
|
|
||
|
this._header = null;
|
||
|
this._statistics = null;
|
||
|
this._preferences = null;
|
||
|
this._records = {};
|
||
|
this._directLoginReferences = {};
|
||
|
},
|
||
|
|
||
|
//-------------------------------------------------------------------------
|
||
|
|
||
|
'deleteAccountAction': function() {
|
||
|
var deferredResult;
|
||
|
|
||
|
//MochiKit.Logging.logDebug(">>> user.deleteAccountAction - " + this);
|
||
|
deferredResult = new MochiKit.Async.Deferred();
|
||
|
deferredResult.addCallback(MochiKit.Base.method(this.connection(), 'message'), 'deleteUser');
|
||
|
deferredResult.addCallback(MochiKit.Base.method(this, 'resetAllLocalData'));
|
||
|
deferredResult.callback();
|
||
|
//MochiKit.Logging.logDebug("<<< user.deleteAccountAction - " + this);
|
||
|
|
||
|
return deferredResult;
|
||
|
},
|
||
|
|
||
|
//-------------------------------------------------------------------------
|
||
|
|
||
|
'encryptedData': function() {
|
||
|
var deferredResult;
|
||
|
var result;
|
||
|
|
||
|
result = {};
|
||
|
|
||
|
deferredResult = new MochiKit.Async.Deferred();
|
||
|
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.encryptedData - 0: " + res); return res;});
|
||
|
deferredResult.addCallback(MochiKit.Base.method(this.header(), 'encryptedData'));
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.encryptedData - 1: " + res); return res;});
|
||
|
deferredResult.addCallback(function(aResult, aValue) {
|
||
|
aResult['header'] = aValue;
|
||
|
}, result);
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.encryptedData - 2: " + res); return res;});
|
||
|
|
||
|
deferredResult.addCallback(MochiKit.Base.method(this.statistics(), 'encryptedData'));
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.encryptedData - 3: " + res); return res;});
|
||
|
deferredResult.addCallback(function(aResult, aValue) {
|
||
|
aResult['statistics'] = aValue;
|
||
|
}, result);
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.encryptedData - 4: " + res); return res;});
|
||
|
|
||
|
deferredResult.addCallback(MochiKit.Base.bind(function(aResult, aValue) {
|
||
|
aResult['version'] = Clipperz.PM.Crypto.encryptingFunctions.currentVersion;
|
||
|
aResult['lock'] = this.lock();
|
||
|
|
||
|
return aResult;
|
||
|
}, this), result);
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.encryptedData - 5: " + res); return res;});
|
||
|
deferredResult.callback();
|
||
|
|
||
|
return deferredResult;
|
||
|
},
|
||
|
|
||
|
//-------------------------------------------------------------------------
|
||
|
|
||
|
'preferences': function() {
|
||
|
if (this._preferences == null) {
|
||
|
this._preferences = new Clipperz.PM.DataModel.UserPreferences({user:this});
|
||
|
}
|
||
|
|
||
|
return this._preferences;
|
||
|
},
|
||
|
/*
|
||
|
'setPreferences': function(aValue) {
|
||
|
this._preferences = aValue;
|
||
|
|
||
|
if (this._preferences.preferredLanguage() != null) {
|
||
|
Clipperz.PM.Strings.Languages.setSelectedLanguage(this._preferences.preferredLanguage());
|
||
|
} else {
|
||
|
//MochiKit.Logging.logDebug("### keepping the browser selected language: " + Clipperz.PM.Strings.selectedLanguage);
|
||
|
}
|
||
|
},
|
||
|
*/
|
||
|
//-------------------------------------------------------------------------
|
||
|
|
||
|
'oneTimePasswordManager': function() {
|
||
|
if (this._oneTimePasswordManager == null) {
|
||
|
this._oneTimePasswordManager = new Clipperz.PM.DataModel.OneTimePasswordManager(this, null);
|
||
|
}
|
||
|
|
||
|
return this._oneTimePasswordManager;
|
||
|
},
|
||
|
|
||
|
//-------------------------------------------------------------------------
|
||
|
|
||
|
'directLoginReferences': function() {
|
||
|
return this._directLoginReferences;
|
||
|
},
|
||
|
|
||
|
'addDirectLoginReference': function(aDirectLoginReference, isBatchUpdate) {
|
||
|
//MochiKit.Logging.logDebug(">>> User.addDirectLoginReference");
|
||
|
this.directLoginReferences()[aDirectLoginReference.reference()] = aDirectLoginReference;
|
||
|
|
||
|
if (isBatchUpdate != true) {
|
||
|
Clipperz.NotificationCenter.notify(aDirectLoginReference, 'directLoginAdded');
|
||
|
Clipperz.NotificationCenter.notify(this, 'updatedSection', 'directLogins', true);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
'removeDirectLoginReference': function(aDirectLoginReference) {
|
||
|
delete this.directLoginReferences()[aDirectLoginReference.reference()];
|
||
|
Clipperz.NotificationCenter.notify(aDirectLoginReference, 'directLoginRemoved');
|
||
|
Clipperz.NotificationCenter.notify(this, 'updatedSection', 'directLogins', true);
|
||
|
},
|
||
|
|
||
|
//.........................................................................
|
||
|
|
||
|
'addDirectLogin': function(aDirectLogin) {
|
||
|
var newDirectLoginReference;
|
||
|
|
||
|
newDirectLoginReference = new Clipperz.PM.DataModel.DirectLoginReference({user:this, directLogin:aDirectLogin})
|
||
|
this.addDirectLoginReference(newDirectLoginReference);
|
||
|
},
|
||
|
|
||
|
'synchronizeDirectLogin': function(aDirectLogin) {
|
||
|
var directLoginReference;
|
||
|
|
||
|
directLoginReference = this.directLoginReferences()[aDirectLogin.reference()];
|
||
|
if (typeof(directLoginReference) != 'undefined') {
|
||
|
directLoginReference.synchronizeValues(aDirectLogin);
|
||
|
} else {
|
||
|
this.addDirectLogin(aDirectLogin);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
'removeDirectLogin': function(aDirectLogin) {
|
||
|
this.removeDirectLoginReference(aDirectLogin);
|
||
|
},
|
||
|
|
||
|
//-------------------------------------------------------------------------
|
||
|
|
||
|
'changeCredentials': function(aUsername, aPassphrase) {
|
||
|
var deferredResult;
|
||
|
var result;
|
||
|
|
||
|
result = {};
|
||
|
|
||
|
deferredResult = new MochiKit.Async.Deferred();
|
||
|
|
||
|
deferredResult.addCallback(MochiKit.Base.method(this.header(), 'loadAllSections'));
|
||
|
deferredResult.addCallback(MochiKit.Base.method(this.header(), 'updateAllSections'));
|
||
|
|
||
|
deferredResult.addCallback(MochiKit.Base.bind(function(aUsername, aPssphrase) {
|
||
|
this.setUsername(aUsername);
|
||
|
this.setPassphrase(aPassphrase);
|
||
|
}, this), aUsername, aPassphrase)
|
||
|
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.changeCredentials - 1: " + res); return res;});
|
||
|
deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'changeCredentials_encryptingData');
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.changeCredentials - 2: " + res); return res;});
|
||
|
deferredResult.addCallback(MochiKit.Base.method(this, 'encryptedData'));
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.changeCredentials - 3: " + res); return res;});
|
||
|
deferredResult.addCallback(function(aResult, anEncryptedData) {
|
||
|
aResult['user'] = anEncryptedData;
|
||
|
|
||
|
return aResult;
|
||
|
}, result);
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.changeCredentials - 4: " + res); return res;});
|
||
|
deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'changeCredentials_creatingNewCredentials');
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.changeCredentials - 5: " + res); return res;});
|
||
|
deferredResult.addCallback(function(aResult, anUser) {
|
||
|
var newConnection;
|
||
|
|
||
|
newConnection = new Clipperz.PM.Crypto.communicationProtocol.versions[Clipperz.PM.Crypto.communicationProtocol.currentVersion]({user:anUser})
|
||
|
aResult['credentials'] = newConnection.serverSideUserCredentials();
|
||
|
|
||
|
return aResult;
|
||
|
}, result, this);
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.changeCredentials - 6: " + res); return res;});
|
||
|
deferredResult.addCallback(MochiKit.Base.method(this.oneTimePasswordManager(), 'encryptedData'));
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.changeCredentials - 7: " + res); return res;});
|
||
|
deferredResult.addCallback(function(aResult, anEncryptedData) {
|
||
|
aResult['oneTimePasswords'] = anEncryptedData;
|
||
|
|
||
|
return aResult;
|
||
|
}, result);
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.changeCredentials - 8: " + res); return res;});
|
||
|
deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'changeCredentials_sendingCredentials');
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.changeCredentials - 9: " + res); return res;});
|
||
|
deferredResult.addCallback(MochiKit.Base.method(this.connection(), 'message'), 'upgradeUserCredentials');
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.changeCredentials - 10: " + res); return res;});
|
||
|
deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'changeCredentials_done');
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.changeCredentials - 11: " + res); return res;});
|
||
|
deferredResult.callback();
|
||
|
|
||
|
return deferredResult;
|
||
|
},
|
||
|
|
||
|
//-------------------------------------------------------------------------
|
||
|
|
||
|
'doLogout': function() {
|
||
|
var deferredResult;
|
||
|
|
||
|
deferredResult = new MochiKit.Async.Deferred();
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.doLogout - 1: " + res); return res;});
|
||
|
deferredResult.addCallback(MochiKit.Base.method(this.connection(), 'logout'));
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.doLogout - 2: " + res); return res;});
|
||
|
deferredResult.addCallback(MochiKit.Base.method(this, 'resetAllLocalData'));
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.doLogout - 3: " + res); return res;});
|
||
|
|
||
|
deferredResult.callback();
|
||
|
|
||
|
return deferredResult;
|
||
|
},
|
||
|
|
||
|
//-------------------------------------------------------------------------
|
||
|
|
||
|
'lock': function() {
|
||
|
this.setPassphrase("")
|
||
|
this.connection().logout();
|
||
|
this.connection().resetSrpConnection();
|
||
|
},
|
||
|
|
||
|
'unlockWithPassphrase': function(aValue) {
|
||
|
var deferredResult;
|
||
|
// var connection;
|
||
|
|
||
|
// connection = this.connection();
|
||
|
|
||
|
deferredResult = new MochiKit.Async.Deferred();
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.unlockWithPassphrase 1: " + res); return res;});
|
||
|
deferredResult.addCallback(MochiKit.Base.method(this, 'setPassphrase'));
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.unlockWithPassphrase 2: " + res); return res;});
|
||
|
// deferredResult.addCallback(MochiKit.Base.method(connection, 'message'), 'echo', {'echo':"echo"});
|
||
|
deferredResult.addCallback(MochiKit.Base.method(this.connection(), 'reestablishConnection'));
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.unlockWithPassphrase 3: " + res); return res;});
|
||
|
// deferredResult.addErrback(MochiKit.Base.method(this, 'setPassphrase', ""));
|
||
|
deferredResult.addErrback(MochiKit.Base.bind(function(anError) {
|
||
|
this.setPassphrase("");
|
||
|
this.connection().resetSrpConnection();
|
||
|
|
||
|
return anError;
|
||
|
}, this));
|
||
|
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("User.unlockWithPassphrase 4: " + res); return res;});
|
||
|
deferredResult.callback(aValue);
|
||
|
|
||
|
return deferredResult;
|
||
|
},
|
||
|
|
||
|
//-------------------------------------------------------------------------
|
||
|
//-------------------------------------------------------------------------
|
||
|
//-------------------------------------------------------------------------
|
||
|
//-------------------------------------------------------------------------
|
||
|
//-------------------------------------------------------------------------
|
||
|
//-------------------------------------------------------------------------
|
||
|
//-------------------------------------------------------------------------
|
||
|
//-------------------------------------------------------------------------
|
||
|
//-------------------------------------------------------------------------
|
||
|
//-------------------------------------------------------------------------
|
||
|
//-------------------------------------------------------------------------
|
||
|
//-------------------------------------------------------------------------
|
||
|
|
||
|
'serverData': function() {
|
||
|
return this._serverData;
|
||
|
},
|
||
|
|
||
|
'setServerData': function(aValue) {
|
||
|
//MochiKit.Logging.logDebug(">>> User.setServerData");
|
||
|
this._serverData = aValue;
|
||
|
|
||
|
if (typeof(aValue.maxNumberOfRecords) != 'undefined') {
|
||
|
this.setMaxNumberOfRecords(aValue.maxNumberOfRecords);
|
||
|
}
|
||
|
//MochiKit.Logging.logDebug("<<< User.setServerData");
|
||
|
},
|
||
|
|
||
|
//-------------------------------------------------------------------------
|
||
|
|
||
|
'isLoadingUserDetails': function() {
|
||
|
return this._isLoadingUserDetails;
|
||
|
},
|
||
|
|
||
|
'setIsLoadingUserDetails': function(aValue) {
|
||
|
this._isLoadingUserDetails = aValue;
|
||
|
},
|
||
|
|
||
|
//-------------------------------------------------------------------------
|
||
|
|
||
|
'loadingUserDetailsPendingQueue': function() {
|
||
|
return this._loadingUserDetailsPendingQueue;
|
||
|
},
|
||
|
|
||
|
'flushLoadingUserDetailsPendingQueue': function() {
|
||
|
var queue;
|
||
|
|
||
|
//MochiKit.Logging.logDebug(">>> User.flushLoadingUserDetailsPendingQueue");
|
||
|
queue = this.loadingUserDetailsPendingQueue();
|
||
|
|
||
|
while(queue.length > 0) {
|
||
|
//MochiKit.Logging.logDebug("--- User.flushLoadingUserDetailsPendingQueue - pop");
|
||
|
queue.pop().callback();
|
||
|
}
|
||
|
//MochiKit.Logging.logDebug("<<< User.flushLoadingUserDetailsPendingQueue");
|
||
|
},
|
||
|
|
||
|
//-------------------------------------------------------------------------
|
||
|
|
||
|
'getUserDetails': function() {
|
||
|
var deferredResult;
|
||
|
|
||
|
//MochiKit.Logging.logDebug(">>> User.getUserDetails");
|
||
|
deferredResult = new MochiKit.Async.Deferred();
|
||
|
if ((this.serverData() == null) && (this.isLoadingUserDetails() == false)) {
|
||
|
deferredResult.addCallback(MochiKit.Base.method(this, 'setIsLoadingUserDetails', true));
|
||
|
deferredResult.addCallback(MochiKit.Base.method(this.connection(), 'message'), 'getUserDetails');
|
||
|
deferredResult.addCallback(MochiKit.Base.method(this, 'setServerData'));
|
||
|
deferredResult.addCallback(MochiKit.Base.method(this, 'flushLoadingUserDetailsPendingQueue'));
|
||
|
deferredResult.addCallback(MochiKit.Base.method(this, 'setIsLoadingUserDetails', false));
|
||
|
}
|
||
|
|
||
|
deferredResult.addCallback(MochiKit.Base.method(this, 'serverData'));
|
||
|
|
||
|
if (this.isLoadingUserDetails() == false) {
|
||
|
deferredResult.callback();
|
||
|
} else {
|
||
|
this.loadingUserDetailsPendingQueue().push(deferredResult);
|
||
|
}
|
||
|
//MochiKit.Logging.logDebug("<<< User.getUserDetails");
|
||
|
|
||
|
return deferredResult;
|
||
|
},
|
||
|
|
||
|
//-------------------------------------------------------------------------
|
||
|
|
||
|
'loadRecords': function() {
|
||
|
return this.header().loadRecords();
|
||
|
},
|
||
|
|
||
|
'loadDirectLogins': function() {
|
||
|
return this.header().loadDirectLogins();
|
||
|
},
|
||
|
|
||
|
'loadPreferences': function() {
|
||
|
return this.header().loadPreferences();
|
||
|
},
|
||
|
|
||
|
'loadOneTimePasswords': function() {
|
||
|
return this.header().loadOneTimePasswords();
|
||
|
},
|
||
|
|
||
|
//-------------------------------------------------------------------------
|
||
|
|
||
|
'loadLoginHistory': function() {
|
||
|
var deferredResult;
|
||
|
|
||
|
deferredResult = new MochiKit.Async.Deferred();
|
||
|
deferredResult.addCallback(MochiKit.Base.method(this.connection(), 'message'), 'getLoginHistory');
|
||
|
deferredResult.addCallback(function(aResult) {
|
||
|
return aResult['result'];
|
||
|
});
|
||
|
deferredResult.addCallback(MochiKit.Base.method(this, 'setLoginHistory'));
|
||
|
deferredResult.addCallback(MochiKit.Base.method(this, 'loginHistory'));
|
||
|
deferredResult.callback();
|
||
|
|
||
|
return deferredResult;
|
||
|
},
|
||
|
|
||
|
//-------------------------------------------------------------------------
|
||
|
|
||
|
'shouldDownloadOfflineCopy': function() {
|
||
|
return this._shouldDownloadOfflineCopy;
|
||
|
},
|
||
|
|
||
|
'setShouldDownloadOfflineCopy': function(aValue) {
|
||
|
this._shouldDownloadOfflineCopy = aValue;
|
||
|
},
|
||
|
|
||
|
//-------------------------------------------------------------------------
|
||
|
|
||
|
'loginInfo': function() {
|
||
|
return this._loginInfo;
|
||
|
},
|
||
|
|
||
|
'setLoginInfo': function(aValue) {
|
||
|
this._loginInfo = aValue;
|
||
|
//MochiKit.Logging.logDebug("### LoginInfo: " + Clipperz.Base.serializeJSON(aValue));
|
||
|
},
|
||
|
|
||
|
//-------------------------------------------------------------------------
|
||
|
|
||
|
'loginHistory': function() {
|
||
|
return this._loginHistory;
|
||
|
},
|
||
|
|
||
|
'setLoginHistory': function(aValue) {
|
||
|
this._loginHistory = aValue;
|
||
|
},
|
||
|
/*
|
||
|
'loginInfoWithOneTimePasswordReference': function(aOneTimePasswordReference) {
|
||
|
var result;
|
||
|
var i,c;
|
||
|
|
||
|
result = null;
|
||
|
c = this.loginHistory().length;
|
||
|
for (i=0; (i<c) && (result == null); i++) {
|
||
|
var currentLoginInfo;
|
||
|
|
||
|
currentLoginInfo = this.loginHistory()[i];
|
||
|
if (currentLoginInfo['oneTimePasswordReference'] == aOneTimePasswordReference) {
|
||
|
result = currentLoginInfo;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return result;
|
||
|
},
|
||
|
*/
|
||
|
//-------------------------------------------------------------------------
|
||
|
|
||
|
'lock': function() {
|
||
|
return this._lock;
|
||
|
},
|
||
|
|
||
|
'setLock': function(aValue) {
|
||
|
//MochiKit.Logging.logDebug("=== User.setLock: " + aValue);
|
||
|
this._lock = aValue;
|
||
|
},
|
||
|
|
||
|
//-------------------------------------------------------------------------
|
||
|
__syntaxFix__: "syntax fix"
|
||
|
|
||
|
});
|
||
|
|
||
|
|
||
|
Clipperz.PM.DataModel.User.exception = {
|
||
|
LoginFailed: new MochiKit.Base.NamedError("Clipperz.PM.DataModel.User.exception.LoginFailed")
|
||
|
};
|
||
|
|