mirror of
http://git.whoc.org.uk/git/password-manager.git
synced 2025-10-25 17:47:34 +02:00
Merged all pending work done on the private repository
This commit is contained in:
@@ -120,7 +120,8 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.DirectLogin, Object, {
|
||||
'setLabelKeepingBackwardCompatibilityWithBeta': function (aValue) {
|
||||
return Clipperz.Async.callbacks("DirectLogin.setLabelKeepingBackwardCompatibilityWithBeta", [
|
||||
MochiKit.Base.method(this, 'setIndexDataForKey', 'label', aValue),
|
||||
MochiKit.Base.method(this, 'setValue', 'label', aValue)
|
||||
MochiKit.Base.method(this, 'setValue', 'label', aValue),
|
||||
MochiKit.Base.partial(MochiKit.Async.succeed, this),
|
||||
], {trace:false});
|
||||
},
|
||||
|
||||
@@ -497,7 +498,8 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.DirectLogin, Object, {
|
||||
MochiKit.Base.method(this, 'updateFormValuesAfterChangingBookmarkletConfiguration'),
|
||||
MochiKit.Base.method(this, 'updateBindingsAfterChangingBookmarkletConfiguration'),
|
||||
|
||||
MochiKit.Base.noop
|
||||
// MochiKit.Base.noop
|
||||
MochiKit.Base.partial(MochiKit.Async.succeed, this),
|
||||
], {trace:false});
|
||||
},
|
||||
|
||||
@@ -607,6 +609,20 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.DirectLogin, Object, {
|
||||
], {trace:false});
|
||||
},
|
||||
|
||||
'setBindings': function (someBindings, originalFields) {
|
||||
var self = this;
|
||||
|
||||
return Clipperz.Async.callbacks("DirectLogin.setBindings", [
|
||||
function () {
|
||||
return MochiKit.Base.map(function (aBindingInfo) {
|
||||
return self.bindFormFieldWithLabelToRecordFieldWithLabel(aBindingInfo[0], originalFields[aBindingInfo[1]]['label']);
|
||||
}, MochiKit.Base.zip(MochiKit.Base.keys(someBindings), MochiKit.Base.values(someBindings)));
|
||||
},
|
||||
Clipperz.Async.collectAll,
|
||||
MochiKit.Base.partial(MochiKit.Async.succeed, this),
|
||||
], {trace:false});
|
||||
},
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
'bindingValues': function () {
|
||||
|
||||
@@ -72,7 +72,7 @@ Clipperz.PM.DataModel.EncryptedRemoteObject = function(args) {
|
||||
//
|
||||
// getRemoteData
|
||||
// unpackRemoteData
|
||||
// getDecryptData [encryptedDataKeypath, encryptedVersionKeypath]
|
||||
// getDecryptedData [encryptedDataKeypath, encryptedVersionKeypath]
|
||||
// unpackData
|
||||
//
|
||||
//
|
||||
|
||||
@@ -31,18 +31,13 @@ if (typeof(Clipperz.PM.DataModel) == 'undefined') { Clipperz.PM.DataModel = {};
|
||||
Clipperz.PM.DataModel.OneTimePassword = function(args) {
|
||||
args = args || {};
|
||||
|
||||
// this._user = args['user'];
|
||||
this._username = args['username'];
|
||||
this._passphraseCallback = args['passphraseCallback'];
|
||||
this._reference = args['reference'] || Clipperz.PM.Crypto.randomKey();
|
||||
this._password = args['password'];
|
||||
this._passwordValue = Clipperz.PM.DataModel.OneTimePassword.normalizedOneTimePassword(args['password']);
|
||||
this._creationDate = args['created'] ? Clipperz.PM.Date.parseDateWithUTCFormat(args['created']) : new Date();
|
||||
this._usageDate = args['used'] ? Clipperz.PM.Date.parseDateWithUTCFormat(args['used']) : null;
|
||||
|
||||
this._status = args['status'] || 'ACTIVE'; // 'REQUESTED', 'USED', 'DISABLED'
|
||||
this._connectionInfo= null;
|
||||
|
||||
this._key = null;
|
||||
this._keyChecksum = null;
|
||||
this._label = args['label'] || "";
|
||||
this._usageDate = args['usageDate'] || null; // Usage date is stored when the client is sure that the otp was used
|
||||
|
||||
return this;
|
||||
}
|
||||
@@ -52,19 +47,35 @@ Clipperz.PM.DataModel.OneTimePassword.prototype = MochiKit.Base.update(null, {
|
||||
'toString': function() {
|
||||
return "Clipperz.PM.DataModel.OneTimePassword";
|
||||
},
|
||||
/*
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
'user': function() {
|
||||
return this._user;
|
||||
'username': function() {
|
||||
return this._username;
|
||||
},
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
'passphraseCallback': function () {
|
||||
return this._passphraseCallback;
|
||||
},
|
||||
|
||||
'setPassphraseCallback': function(aPassphraseCallback) {
|
||||
this._passphraseCallback = aPassphraseCallback;
|
||||
},
|
||||
|
||||
'password': function() {
|
||||
return this._password;
|
||||
},
|
||||
|
||||
'label': function() {
|
||||
return this._label;
|
||||
},
|
||||
|
||||
'usageDate': function() {
|
||||
return this._usageDate;
|
||||
},
|
||||
|
||||
'setUsageDate': function(aDate) {
|
||||
this._usageDate = aDate;
|
||||
},
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
'passwordValue': function() {
|
||||
@@ -73,12 +84,6 @@ Clipperz.PM.DataModel.OneTimePassword.prototype = MochiKit.Base.update(null, {
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
'creationDate': function() {
|
||||
return this._creationDate;
|
||||
},
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
'reference': function() {
|
||||
return this._reference;
|
||||
},
|
||||
@@ -86,51 +91,18 @@ Clipperz.PM.DataModel.OneTimePassword.prototype = MochiKit.Base.update(null, {
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
'key': function() {
|
||||
if (this._key == null) {
|
||||
this._key = Clipperz.PM.DataModel.OneTimePassword.computeKeyWithUsernameAndPassword(this.user().username(), this.passwordValue());
|
||||
}
|
||||
|
||||
return this._key;
|
||||
return Clipperz.PM.DataModel.OneTimePassword.computeKeyWithPassword(this.passwordValue());
|
||||
},
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
'keyChecksum': function() {
|
||||
if (this._keyChecksum == null) {
|
||||
this._keyChecksum = Clipperz.PM.DataModel.OneTimePassword.computeKeyChecksumWithUsernameAndPassword(this.user().username(), this.passwordValue());
|
||||
}
|
||||
|
||||
return this._keyChecksum;
|
||||
},
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
'status': function() {
|
||||
return this._status;
|
||||
},
|
||||
|
||||
'setStatus': function(aValue) {
|
||||
this._status = aValue;
|
||||
},
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
'serializedData': function() {
|
||||
var result;
|
||||
|
||||
result = {
|
||||
'password': this.password(),
|
||||
'created': this.creationDate() ? Clipperz.PM.Date.formatDateWithUTCFormat(this.creationDate()) : null,
|
||||
'used': this.usageDate() ? Clipperz.PM.Date.formatDateWithUTCFormat(this.usageDate()) : null,
|
||||
'status': this.status()
|
||||
};
|
||||
|
||||
return result;
|
||||
return Clipperz.PM.DataModel.OneTimePassword.computeKeyChecksumWithUsernameAndPassword(this.username(), this.passwordValue());
|
||||
},
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
'packedPassphrase': function() {
|
||||
'packedPassphrase': function(aPassphrase) {
|
||||
var result;
|
||||
var packedPassphrase;
|
||||
var encodedPassphrase;
|
||||
@@ -140,32 +112,29 @@ Clipperz.PM.DataModel.OneTimePassword.prototype = MochiKit.Base.update(null, {
|
||||
|
||||
getRandomBytes = MochiKit.Base.method(Clipperz.Crypto.PRNG.defaultRandomGenerator(), 'getRandomBytes');
|
||||
|
||||
encodedPassphrase = new Clipperz.ByteArray(this.user().passphrase()).toBase64String();
|
||||
//Clipperz.logDebug("--- encodedPassphrase.length: " + encodedPassphrase.length);
|
||||
encodedPassphrase = new Clipperz.ByteArray(aPassphrase).toBase64String();
|
||||
prefixPadding = getRandomBytes(getRandomBytes(1).byteAtIndex(0)).toBase64String();
|
||||
//Clipperz.logDebug("--- prefixPadding.length: " + prefixPadding.length);
|
||||
suffixPadding = getRandomBytes((500 - prefixPadding.length - encodedPassphrase.length) * 6 / 8).toBase64String();
|
||||
//Clipperz.logDebug("--- suffixPadding.length: " + suffixPadding.length);
|
||||
//Clipperz.logDebug("--- total.length: " + (prefixPadding.length + encodedPassphrase.length + suffixPadding.length));
|
||||
|
||||
|
||||
packedPassphrase = {
|
||||
'prefix': prefixPadding,
|
||||
'passphrase': encodedPassphrase,
|
||||
'suffix': suffixPadding
|
||||
};
|
||||
|
||||
// result = Clipperz.Base.serializeJSON(packedPassphrase);
|
||||
result = packedPassphrase;
|
||||
//Clipperz.logDebug("===== OTP packedPassprase: [" + result.length + "]" + result);
|
||||
//Clipperz.logDebug("<<< OneTimePassword.packedPassphrase");
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
'encryptedPackedPassphrase': function() {
|
||||
return Clipperz.PM.Crypto.deferredEncryptWithCurrentVersion(this.passwordValue(), this.packedPassphrase())
|
||||
'encryptedPackedPassphrase': function(aPassphrase) {
|
||||
return Clipperz.PM.Crypto.deferredEncrypt({
|
||||
'key': this.passwordValue(),
|
||||
'value': this.packedPassphrase(aPassphrase),
|
||||
'version': Clipperz.PM.Crypto.encryptingFunctions.currentVersion
|
||||
})
|
||||
},
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
@@ -174,8 +143,6 @@ Clipperz.PM.DataModel.OneTimePassword.prototype = MochiKit.Base.update(null, {
|
||||
var deferredResult;
|
||||
var result;
|
||||
|
||||
//Clipperz.logDebug(">>> OneTimePassword.encryptedData");
|
||||
//Clipperz.logDebug("--- OneTimePassword.encryptedData - id: " + this.reference());
|
||||
result = {
|
||||
'reference': this.reference(),
|
||||
'key': this.key(),
|
||||
@@ -183,116 +150,26 @@ Clipperz.PM.DataModel.OneTimePassword.prototype = MochiKit.Base.update(null, {
|
||||
'data': "",
|
||||
'version': Clipperz.PM.Crypto.encryptingFunctions.currentVersion
|
||||
}
|
||||
//Clipperz.logDebug("--- OneTimePassword.encryptedData - 2: " + Clipperz.Base.serializeJSON(result));
|
||||
deferredResult = new MochiKit.Async.Deferred();
|
||||
//Clipperz.logDebug("--- OneTimePassword.encryptedData - 3");
|
||||
//deferredResult.addBoth(function(res) {Clipperz.logDebug("OneTimePassword.encryptedData - 1: " + res); return res;});
|
||||
//# deferredResult.addCallback(Clipperz.PM.Crypto.deferredEncryptWithCurrentVersion, this.passwordValue(), this.packedPassphrase());
|
||||
deferredResult = new Clipperz.Async.Deferred("OneTimePassword.encryptedData", {trace: false});
|
||||
deferredResult.addCallback(this.passphraseCallback());
|
||||
deferredResult.addCallback(MochiKit.Base.method(this, 'encryptedPackedPassphrase'));
|
||||
//Clipperz.logDebug("--- OneTimePassword.encryptedData - 4");
|
||||
//deferredResult.addBoth(function(res) {Clipperz.logDebug("OneTimePassword.encryptedData - 2: [" + res.length + "]" + res); return res;});
|
||||
deferredResult.addCallback(function(aResult, res) {
|
||||
aResult['data'] = res;
|
||||
return aResult;
|
||||
}, result);
|
||||
//Clipperz.logDebug("--- OneTimePassword.encryptedData - 5");
|
||||
//deferredResult.addBoth(function(res) {Clipperz.logDebug("OneTimePassword.encryptedData - 3: " + Clipperz.Base.serializeJSON(res)); return res;});
|
||||
|
||||
deferredResult.callback();
|
||||
//Clipperz.logDebug("--- OneTimePassword.encryptedData - 6");
|
||||
|
||||
return deferredResult;
|
||||
},
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
'saveChanges': function() {
|
||||
var deferredResult;
|
||||
var result;
|
||||
|
||||
//Clipperz.logDebug(">>> OneTimePassword.saveChanges");
|
||||
result = {};
|
||||
deferredResult = new MochiKit.Async.Deferred();
|
||||
|
||||
deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'saveOTP_encryptUserData');
|
||||
deferredResult.addCallback(MochiKit.Base.method(this.user(), 'encryptedData'));
|
||||
deferredResult.addCallback(function(aResult, res) {
|
||||
aResult['user'] = res;
|
||||
return aResult;
|
||||
}, result);
|
||||
|
||||
deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'saveOTP_encryptOTPData');
|
||||
deferredResult.addCallback(MochiKit.Base.method(this, 'encryptedData'));
|
||||
deferredResult.addCallback(function(aResult, res) {
|
||||
aResult['oneTimePassword'] = res;
|
||||
return aResult;
|
||||
}, result);
|
||||
|
||||
deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'saveOTP_sendingData');
|
||||
//deferredResult.addBoth(function(res) {Clipperz.logDebug("OneTimePassword.saveChanges - 1: " + Clipperz.Base.serializeJSON(res)); return res;});
|
||||
deferredResult.addCallback(MochiKit.Base.method(this.user().connection(), 'message'), 'addNewOneTimePassword');
|
||||
|
||||
deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'saveOTP_updatingInterface');
|
||||
//deferredResult.addBoth(function(res) {Clipperz.logDebug("OneTimePassword.saveChanges - 2: " + res); return res;});
|
||||
deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'notify', 'OTPUpdated');
|
||||
deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'oneTimePassword_saveChanges_done', null);
|
||||
//deferredResult.addBoth(function(res) {Clipperz.logDebug("OneTimePassword.saveChanges - 2: " + res); return res;});
|
||||
deferredResult.callback();
|
||||
//Clipperz.logDebug("<<< OneTimePassword.saveChanges");
|
||||
|
||||
return deferredResult;
|
||||
},
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
'usageDate': function() {
|
||||
return this._usageDate;
|
||||
},
|
||||
|
||||
'setUsageDate': function(aValue) {
|
||||
this._usageDate = aValue;
|
||||
},
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
'connectionInfo': function() {
|
||||
return this._connectionInfo;
|
||||
},
|
||||
|
||||
'setConnectionInfo': function(aValue) {
|
||||
this._connectionInfo = aValue;
|
||||
},
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
'isExpired': function() {
|
||||
return (this.usageDate() != null);
|
||||
},
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
'updateStatusWithValues': function(someValues) {
|
||||
var result;
|
||||
|
||||
result = false;
|
||||
|
||||
if (someValues['status'] != this.status()) {
|
||||
result = true;
|
||||
}
|
||||
|
||||
this.setStatus(someValues['status']);
|
||||
this.setUsageDate(Clipperz.PM.Date.parseDateWithUTCFormat(someValues['requestDate']));
|
||||
this.setConnectionInfo(someValues['connection']);
|
||||
|
||||
return result;
|
||||
},
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
__syntaxFix__: "syntax fix"
|
||||
});
|
||||
|
||||
//#############################################################################
|
||||
|
||||
Clipperz.PM.DataModel.OneTimePassword.computeKeyWithUsernameAndPassword = function(anUsername, aPassword) {
|
||||
Clipperz.PM.DataModel.OneTimePassword.computeKeyWithPassword = function(aPassword) {
|
||||
return Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aPassword)).toHexString().substring(2);
|
||||
}
|
||||
|
||||
@@ -348,3 +225,32 @@ Clipperz.PM.DataModel.OneTimePassword.normalizedOneTimePassword = function(aPass
|
||||
};
|
||||
|
||||
//#############################################################################
|
||||
|
||||
Clipperz.PM.DataModel.OneTimePassword.generateRandomBase32OTPValue = function() {
|
||||
var randomValue;
|
||||
var result;
|
||||
|
||||
randomValue = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(160/8);
|
||||
result = randomValue.toBase32String();
|
||||
result = result.replace(/.{4}\B/g, '$&' + ' ');
|
||||
result = result.replace(/(.{4} ){2}/g, '$&' + '- ');
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
//#############################################################################
|
||||
|
||||
Clipperz.PM.DataModel.OneTimePassword.createNewOneTimePassword = function(aUsername, aPassphraseCallback) {
|
||||
var result;
|
||||
var password;
|
||||
|
||||
password = Clipperz.PM.DataModel.OneTimePassword.generateRandomBase32OTPValue();
|
||||
result = new Clipperz.PM.DataModel.OneTimePassword({
|
||||
'username': aUsername,
|
||||
'passphraseCallback': aPassphraseCallback,
|
||||
'password': password,
|
||||
'label': ""
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -175,7 +175,7 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.Record.Version.Field, Object, {
|
||||
deferredResult.addMethod(this, 'actionType');
|
||||
deferredResult.addCallback(function (aValue) { fieldValues['actionType'] = aValue; });
|
||||
deferredResult.addMethod(this, 'isHidden');
|
||||
deferredResult.addCallback(function (aValue) { fieldValues['isHidden'] = aValue; });
|
||||
deferredResult.addCallback(function (aValue) { fieldValues['hidden'] = aValue; });
|
||||
deferredResult.addCallback(function () { return fieldValues; });
|
||||
deferredResult.callback();
|
||||
|
||||
|
||||
@@ -327,16 +327,15 @@ console.log("Record.Version.hasPendingChanges");
|
||||
deferredResult = new Clipperz.Async.Deferred('Record.Version.export', {trace:false});
|
||||
deferredResult.addMethod(this,'fields');
|
||||
deferredResult.addCallback(MochiKit.Base.values);
|
||||
deferredResult.addCallback(MochiKit.Base.map, function(fieldIn) {
|
||||
deferredResult.addCallback(MochiKit.Base.map, function (fieldIn) {
|
||||
return fieldIn.content();
|
||||
});
|
||||
deferredResult.addCallback(Clipperz.Async.collectAll);
|
||||
deferredResult.addCallback(function(listIn) {
|
||||
// return listIn.reduce(function(result, field) {
|
||||
return MochiKit.Iter.reduce(function(result, field) {
|
||||
var ref = field.reference;
|
||||
var ref = field['reference'];
|
||||
result[ref] = field;
|
||||
delete result[ref].reference;
|
||||
delete result[ref]['reference'];
|
||||
return result;
|
||||
}, listIn, {});
|
||||
});
|
||||
|
||||
@@ -170,7 +170,7 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.Record, Clipperz.PM.DataModel.Encrypt
|
||||
},
|
||||
|
||||
//............................................................................
|
||||
|
||||
|
||||
'label': function () {
|
||||
return Clipperz.Async.callbacks("Record.label", [
|
||||
MochiKit.Base.method(this, 'fullLabel'),
|
||||
@@ -1128,7 +1128,8 @@ console.log("Record.hasPendingChanges RESULT", result);
|
||||
Clipperz.Async.collectAll,
|
||||
|
||||
MochiKit.Base.method(aRecord, 'directLogins'), MochiKit.Base.values,
|
||||
//function (aValue) { console.log("-> DirectLogin Values", aValue); return aValue; },
|
||||
//function (aValue) { console.log("-> SETUP WITH RECORD: DirectLogin Values", aValue); return aValue; },
|
||||
// TODO: possibly broken implementation of direct login cloning
|
||||
MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.method(this, 'addDirectLogin')),
|
||||
//function (aValue) { console.log("-> DirectLogin Values", aValue); return aValue; },
|
||||
// Clipperz.Async.collectAll,
|
||||
@@ -1136,16 +1137,25 @@ console.log("Record.hasPendingChanges RESULT", result);
|
||||
MochiKit.Base.bind(function () { return this; }, this)
|
||||
], {trace:false});
|
||||
},
|
||||
|
||||
'directLoginWithJsonData': function (someData) {
|
||||
var result;
|
||||
|
||||
'setUpWithJSON': function(data) {
|
||||
result = new Clipperz.PM.DataModel.DirectLogin({'record': this});
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
'setUpWithJSON': function(data, labelPostfix) {
|
||||
return Clipperz.Async.callbacks("Record.setUpWithJSON", [
|
||||
// TODO: proper tag handling
|
||||
MochiKit.Base.method(this,'setLabel',data.label),
|
||||
MochiKit.Base.method(this,'setNotes',data.data.notes),
|
||||
MochiKit.Base.method(this,'setLabel', data['label'] + ((labelPostfix) ? labelPostfix : '')),
|
||||
MochiKit.Base.method(this,'setNotes', data['data']['notes']),
|
||||
// TODO: check whether fields' order is kept or not
|
||||
function(){ return MochiKit.Base.values(data.currentVersion.fields); },
|
||||
MochiKit.Base.partial(MochiKit.Base.map,MochiKit.Base.method(this, 'addField')),
|
||||
Clipperz.Async.collectAll
|
||||
MochiKit.Base.partial(MochiKit.Base.values, data['currentVersion']['fields']),
|
||||
MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.method(this, 'addField')),
|
||||
Clipperz.Async.collectAll,
|
||||
MochiKit.Base.partial(MochiKit.Async.succeed, this),
|
||||
], {trace:false});
|
||||
},
|
||||
|
||||
@@ -1174,12 +1184,12 @@ console.log("Record.hasPendingChanges RESULT", result);
|
||||
var label;
|
||||
var data;
|
||||
var currentVersion;
|
||||
var directLogins;
|
||||
// var directLogins;
|
||||
var currentVersionObject;
|
||||
|
||||
data = {};
|
||||
currentVersion = {};
|
||||
directLogins = {};
|
||||
// directLogins = {};
|
||||
deferredResult = new Clipperz.Async.Deferred('Record.export', {trace:false});
|
||||
deferredResult.addMethod(this, 'getCurrentRecordVersion');
|
||||
deferredResult.addCallback(function(recordVersionIn) { currentVersionObject = recordVersionIn; })
|
||||
@@ -1211,7 +1221,6 @@ console.log("Record.hasPendingChanges RESULT", result);
|
||||
__syntaxFix__: "syntax fix"
|
||||
});
|
||||
|
||||
|
||||
Clipperz.PM.DataModel.Record.defaultCardInfo = {
|
||||
'_rowObject': MochiKit.Async.succeed,
|
||||
'_reference': MochiKit.Base.methodcaller('reference'),
|
||||
@@ -1277,3 +1286,14 @@ Clipperz.PM.DataModel.Record.extractTagsFromFullLabel = function (aLabel) {
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
Clipperz.PM.DataModel.Record.labelContainsTag = function (aLabel, aTag) {
|
||||
return MochiKit.Iter.some(
|
||||
MochiKit.Base.keys(Clipperz.PM.DataModel.Record.extractTagsFromFullLabel(aLabel)),
|
||||
MochiKit.Base.partial(MochiKit.Base.operator.eq, aTag)
|
||||
);
|
||||
}
|
||||
|
||||
Clipperz.PM.DataModel.Record.labelContainsArchiveTag = function (aLabel) {
|
||||
return Clipperz.PM.DataModel.Record.labelContainsTag(aLabel, Clipperz.PM.DataModel.Record.archivedTag);
|
||||
}
|
||||
@@ -31,7 +31,13 @@ if (typeof(Clipperz.PM.DataModel.User.Header) == 'undefined') { Clipperz.PM.Data
|
||||
Clipperz.PM.DataModel.User.Header.OneTimePasswords = function(args) {
|
||||
Clipperz.PM.DataModel.User.Header.OneTimePasswords.superclass.constructor.apply(this, arguments);
|
||||
|
||||
// TODO: there are still method calls around passing these values: should be cleared...
|
||||
this._connection = args['connection'];
|
||||
this._username = args['username'];
|
||||
this._passphraseCallback = args['retrieveKeyFunction'];
|
||||
|
||||
this._oneTimePasswords = null;
|
||||
this._oneTimePasswordsDetails = null;
|
||||
|
||||
return this;
|
||||
}
|
||||
@@ -45,55 +51,45 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User.Header.OneTimePasswords, Clipper
|
||||
},
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
'packData': function (someData) { // ++
|
||||
var result;
|
||||
|
||||
result = Clipperz.PM.DataModel.User.Header.OneTimePasswords.superclass.packData.apply(this, arguments);
|
||||
|
||||
return result;
|
||||
'connection': function() {
|
||||
return this._connection;
|
||||
},
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
'packRemoteData': function (someData) {
|
||||
var result;
|
||||
|
||||
result = Clipperz.PM.DataModel.User.Header.OneTimePasswords.superclass.packRemoteData.apply(this, arguments);
|
||||
|
||||
return result;
|
||||
'username': function() {
|
||||
return this._username;
|
||||
},
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
'prepareRemoteDataWithKey': function (aKey) {
|
||||
var result;
|
||||
|
||||
result = Clipperz.PM.DataModel.User.Header.OneTimePasswords.superclass.prepareRemoteDataWithKey.apply(this, arguments);
|
||||
|
||||
return result;
|
||||
'passphraseCallback': function() {
|
||||
return this._passphraseCallback;
|
||||
},
|
||||
*/
|
||||
|
||||
//=========================================================================
|
||||
|
||||
'oneTimePasswords': function () {
|
||||
var deferredResult;
|
||||
|
||||
deferredResult = new Clipperz.Async.Deferred("User.Header.OneTimePasswords.oneTimePasswords", {trace:false});
|
||||
|
||||
// TODO: change with transient state
|
||||
// Also, OTPs created here don't store username, making it impossible to generate the key checksum (shouldn't be used anywhere, but probably the design should be changed)
|
||||
if (this._oneTimePasswords == null) {
|
||||
deferredResult.addMethod(this, 'values')
|
||||
deferredResult.addMethod(this, 'values');
|
||||
deferredResult.addCallback(MochiKit.Base.bind(function (someData) {
|
||||
var otpKey;
|
||||
|
||||
this._oneTimePasswords = {};
|
||||
|
||||
|
||||
for (otpKey in someData) {
|
||||
var otp;
|
||||
var otpParameters;
|
||||
|
||||
otpParameters = Clipperz.Base.deepClone(someData[otpKey]);
|
||||
otpParameters['reference'] = otpKey;
|
||||
|
||||
otpParameters['username'] = this.username();
|
||||
otpParameters['passphraseCallback'] = this.passphraseCallback();
|
||||
otpParameters['usageDate'] = someData[otpKey]['usageDate'] || null;
|
||||
|
||||
otp = new Clipperz.PM.DataModel.OneTimePassword(otpParameters);
|
||||
this._oneTimePasswords[otpKey] = otp;
|
||||
}
|
||||
@@ -109,6 +105,182 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User.Header.OneTimePasswords, Clipper
|
||||
return deferredResult;
|
||||
},
|
||||
|
||||
'oneTimePasswordsDetails': function() {
|
||||
if (this._oneTimePasswordsDetails) {
|
||||
return MochiKit.Async.succeed(this._oneTimePasswordsDetails);
|
||||
} else {
|
||||
return Clipperz.Async.callbacks("User.oneTimePasswordsDetails", [
|
||||
MochiKit.Base.method(this.connection(), 'message', 'getOneTimePasswordsDetails'),
|
||||
MochiKit.Base.bind(function(someData) {
|
||||
this._oneTimePasswordsDetails = someData;
|
||||
|
||||
return someData;
|
||||
}, this)
|
||||
], {trace:false});
|
||||
}
|
||||
},
|
||||
|
||||
//=========================================================================
|
||||
|
||||
'getReferenceFromKey': function(aKey) {
|
||||
return Clipperz.Async.callbacks("User.Header.OneTimePasswords.getReferenceFromKey", [
|
||||
MochiKit.Base.method(this, 'values'),
|
||||
function(someValues) {
|
||||
var result;
|
||||
var normalizedOTP;
|
||||
var i;
|
||||
|
||||
result = null;
|
||||
for (i in someValues) {
|
||||
normalizedOTP = Clipperz.PM.DataModel.OneTimePassword.normalizedOneTimePassword(someValues[i]['password']);
|
||||
|
||||
if (Clipperz.PM.DataModel.OneTimePassword.computeKeyWithPassword(normalizedOTP) == aKey) {
|
||||
result = i;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
], {trace:false});
|
||||
},
|
||||
|
||||
//=========================================================================
|
||||
|
||||
'createNewOTP': function (aUsername, aPassphraseCallback) {
|
||||
var newOneTimePassword;
|
||||
|
||||
newOneTimePassword = Clipperz.PM.DataModel.OneTimePassword.createNewOneTimePassword(aUsername, aPassphraseCallback);
|
||||
|
||||
// TODO: this is deferred --> change everything to deferred
|
||||
// TestData include 'created' and 'status'
|
||||
this.setValue(newOneTimePassword.reference(), {
|
||||
// 'created': newOneTimePassword.creationDate().toString(), // won't work: creation date is no more stored in OTP
|
||||
'password': newOneTimePassword.password(),
|
||||
'label': newOneTimePassword.label()
|
||||
// 'status': newOneTimePassword.status()
|
||||
});
|
||||
|
||||
this._oneTimePasswords = null;
|
||||
this._oneTimePasswordsDetails = null;
|
||||
|
||||
return newOneTimePassword;
|
||||
},
|
||||
|
||||
//.........................................................................
|
||||
|
||||
'deleteOTPs': function (aList) {
|
||||
this._oneTimePasswords = null;
|
||||
this._oneTimePasswordsDetails = null;
|
||||
|
||||
return Clipperz.Async.callbacks("User.Header.OneTimePasswords.deleteOTPs", [
|
||||
MochiKit.Base.method(this, 'values'),
|
||||
MochiKit.Base.keys,
|
||||
MochiKit.Base.bind(function(someKeys) {
|
||||
var result;
|
||||
|
||||
result = [];
|
||||
MochiKit.Base.map(MochiKit.Base.bind(function(aList, aKey) {
|
||||
if (aList.indexOf(aKey) >= 0) {
|
||||
this.removeValue(aKey);
|
||||
} else {
|
||||
result.push(aKey);
|
||||
}
|
||||
}, this, aList), someKeys);
|
||||
|
||||
return result; // Return a list of references of the remaining OTPs, needed for the 'updateOneTimePasswords' message
|
||||
// Maybe this logic should be moved to another method
|
||||
}, this),
|
||||
], {trace:false});
|
||||
},
|
||||
|
||||
//.........................................................................
|
||||
|
||||
'changeOTPLabel': function (aReference, aLabel) {
|
||||
this._oneTimePasswords = null;
|
||||
|
||||
return Clipperz.Async.callbacks("User.Header.OneTimePasswords.changeOTPLabel", [
|
||||
MochiKit.Base.method(this, 'getValue', aReference),
|
||||
function(aValue) {
|
||||
aValue['label'] = aLabel;
|
||||
return aValue;
|
||||
},
|
||||
MochiKit.Base.method(this, 'setValue', aReference)
|
||||
], {trace:false});
|
||||
},
|
||||
|
||||
//.........................................................................
|
||||
|
||||
'markOTPAsUsed': function(aKey) {
|
||||
var reference;
|
||||
|
||||
this._oneTimePasswords = null;
|
||||
|
||||
return Clipperz.Async.callbacks("User.Header.OneTimePasswords.markOTPAsUsed", [
|
||||
MochiKit.Base.method(this, 'getReferenceFromKey', aKey),
|
||||
function(aReference) {
|
||||
reference = aReference;
|
||||
return aReference;
|
||||
},
|
||||
MochiKit.Base.method(this, 'getValue'),
|
||||
MochiKit.Base.bind(function(aValue) {
|
||||
if (aValue) {
|
||||
aValue['usageDate'] = new Date().toString();
|
||||
this.setValue(reference, aValue);
|
||||
}
|
||||
}, this)
|
||||
], {trace:false});
|
||||
},
|
||||
|
||||
//=========================================================================
|
||||
|
||||
'getEncryptedOTPData': function(aPassphraseCallback) {
|
||||
var deferredResult;
|
||||
|
||||
deferredResult = new Clipperz.Async.Deferred("User.Header.OneTimePasswords.getEncryptedOTPData", {trace:false});
|
||||
|
||||
deferredResult.collectResults({
|
||||
'oneTimePasswords': MochiKit.Base.method(this, 'oneTimePasswords'),
|
||||
'oneTimePasswordsDetails': MochiKit.Base.method(this, 'oneTimePasswordsDetails')
|
||||
});
|
||||
deferredResult.addCallback(function (someData) {
|
||||
var result;
|
||||
var otpFilteredList;
|
||||
var i;
|
||||
|
||||
var otpList = MochiKit.Base.values(someData['oneTimePasswords']);
|
||||
|
||||
otpFilteredList = MochiKit.Base.filter(function (aOTP) {
|
||||
return (someData['oneTimePasswordsDetails'][aOTP.reference()]
|
||||
&& someData['oneTimePasswordsDetails'][aOTP.reference()]['status'] == 'ACTIVE'
|
||||
&& ! someData['oneTimePasswords'][aOTP.reference()].usageDate()
|
||||
);
|
||||
}, otpList);
|
||||
|
||||
result = MochiKit.Base.map(function (aOTP) {
|
||||
aOTP.setPassphraseCallback(aPassphraseCallback);
|
||||
return aOTP.encryptedData();
|
||||
}, otpFilteredList);
|
||||
|
||||
return result;
|
||||
});
|
||||
deferredResult.addCallback(Clipperz.Async.collectAll);
|
||||
deferredResult.addCallback(function (someData) {
|
||||
var result;
|
||||
var i;
|
||||
|
||||
result = {};
|
||||
for (i in someData) {
|
||||
result[someData[i].reference] = someData[i];
|
||||
}
|
||||
|
||||
return result;
|
||||
});
|
||||
|
||||
deferredResult.callback();
|
||||
|
||||
return deferredResult;
|
||||
},
|
||||
|
||||
//=========================================================================
|
||||
__syntaxFix__: "syntax fix"
|
||||
});
|
||||
|
||||
@@ -59,6 +59,8 @@ Clipperz.PM.DataModel.User = function (args) {
|
||||
'__syntaxFix__': 'syntax fix'
|
||||
};
|
||||
|
||||
this._usedOTP = null;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -80,6 +82,40 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User, Object, {
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
'setUsedOTP': function(aOTP) {
|
||||
this._usedOTP = aOTP;
|
||||
|
||||
return aOTP;
|
||||
},
|
||||
|
||||
'resetUsedOTP': function(aOTP) {
|
||||
this._usedOTP = null;
|
||||
},
|
||||
|
||||
'markUsedOTP': function(aOTP) {
|
||||
var result;
|
||||
var oneTimePasswordKey;
|
||||
|
||||
if (this._usedOTP) {
|
||||
oneTimePasswordKey = Clipperz.PM.DataModel.OneTimePassword.computeKeyWithPassword(
|
||||
Clipperz.PM.DataModel.OneTimePassword.normalizedOneTimePassword(this._usedOTP)
|
||||
);
|
||||
|
||||
result = Clipperz.Async.callbacks("User.markUsedOTP", [ // NOTE: fired also when passphrase looks exactly like OTP
|
||||
MochiKit.Base.method(this, 'getHeaderIndex', 'oneTimePasswords'),
|
||||
MochiKit.Base.methodcaller('markOTPAsUsed', oneTimePasswordKey),
|
||||
MochiKit.Base.method(this,'saveChanges'), // Too 'heavy'?
|
||||
MochiKit.Base.method(this, 'resetUsedOTP')
|
||||
], {'trace': false});
|
||||
} else {
|
||||
result = MochiKit.Async.succeed();
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// this.setSubscription(new Clipperz.PM.DataModel.User.Subscription(someServerData['subscription']));
|
||||
'accountInfo': function () {
|
||||
return this._accountInfo;
|
||||
@@ -138,21 +174,17 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User, Object, {
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
'getPassphrase': function() {
|
||||
var deferredResult;
|
||||
|
||||
deferredResult = new Clipperz.Async.Deferred("User.getPassphrase", {trace:false});
|
||||
deferredResult.acquireLock(this.deferredLockForSection('passphrase'));
|
||||
deferredResult.addMethod(this.data(), 'deferredGetOrSet', 'passphrase', this.getPassphraseFunction());
|
||||
deferredResult.releaseLock(this.deferredLockForSection('passphrase'));
|
||||
deferredResult.callback();
|
||||
|
||||
return deferredResult;
|
||||
return this._getPassphraseFunction();
|
||||
},
|
||||
|
||||
'getPassphraseFunction': function () {
|
||||
return this._getPassphraseFunction;
|
||||
},
|
||||
|
||||
'setPassphraseFunction': function(aFunction) {
|
||||
this._getPassphraseFunction = aFunction;
|
||||
},
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
'getCredentials': function () {
|
||||
@@ -164,26 +196,44 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User, Object, {
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
'changePassphrase': function (aNewValue) {
|
||||
return this.updateCredentials(this.username(), aNewValue);
|
||||
'changePassphrase': function (aNewValueCallback) {
|
||||
return this.updateCredentials(this.username(), aNewValueCallback);
|
||||
},
|
||||
|
||||
//.........................................................................
|
||||
|
||||
'updateCredentials': function (aUsername, aPassphrase) {
|
||||
'updateCredentials': function (aUsername, aPassphraseCallback) {
|
||||
var deferredResult;
|
||||
|
||||
deferredResult = new Clipperz.Async.Deferred("User.updateCredentials", {trace:false});
|
||||
// deferredResult.addMethod(this, 'getPassphrase');
|
||||
// deferredResult.setValue('currentPassphrase');
|
||||
deferredResult.addMethod(this.connection(), 'ping');
|
||||
deferredResult.addMethod(this, 'setUsername', aUsername)
|
||||
deferredResult.acquireLock(this.deferredLockForSection('passphrase'));
|
||||
deferredResult.addMethod(this.data(), 'deferredGetOrSet', 'passphrase', aPassphrase);
|
||||
deferredResult.releaseLock(this.deferredLockForSection('passphrase'));
|
||||
// deferredResult.getValue('currentPassphrase');
|
||||
deferredResult.addMethod(this, 'prepareRemoteDataWithKey', aPassphrase);
|
||||
deferredResult.addMethod(this.connection(), 'updateCredentials', aUsername, aPassphrase);
|
||||
deferredResult.collectResults({
|
||||
'newUsername': MochiKit.Base.partial(MochiKit.Async.succeed, aUsername),
|
||||
'newPassphrase': aPassphraseCallback,
|
||||
'user': MochiKit.Base.method(this, 'prepareRemoteDataWithKeyFunction', aPassphraseCallback),
|
||||
'oneTimePasswords': [
|
||||
MochiKit.Base.method(this, 'getHeaderIndex', 'oneTimePasswords'),
|
||||
MochiKit.Base.methodcaller('getEncryptedOTPData', aPassphraseCallback),
|
||||
function (otps) {
|
||||
var result;
|
||||
var otpRefs;
|
||||
var i, c;
|
||||
|
||||
result = {};
|
||||
otpRefs = MochiKit.Base.keys(otps);
|
||||
c = otpRefs.length;
|
||||
for (i=0; i<c; i++) {
|
||||
result[otpRefs[i]] = {}
|
||||
result[otpRefs[i]]['data'] = otps[otpRefs[i]]['data'];
|
||||
result[otpRefs[i]]['version'] = otps[otpRefs[i]]['version'];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
deferredResult.addMethod(this.connection(), 'updateCredentials');
|
||||
deferredResult.callback();
|
||||
|
||||
return deferredResult;
|
||||
@@ -212,8 +262,10 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User, Object, {
|
||||
'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase')
|
||||
}),
|
||||
'oneTimePasswords': new Clipperz.PM.DataModel.User.Header.OneTimePasswords({
|
||||
'name': 'preferences',
|
||||
'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase')
|
||||
'connection': this.connection(),
|
||||
'name': 'oneTimePasswords',
|
||||
'username': this.username(),
|
||||
'passphraseCallback': MochiKit.Base.method(this, 'getPassphrase')
|
||||
})
|
||||
}
|
||||
};
|
||||
@@ -227,18 +279,10 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User, Object, {
|
||||
var deferredResult;
|
||||
|
||||
deferredResult = new Clipperz.Async.Deferred("User.registerAsNewAccount", {trace:false});
|
||||
// deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'updateProgress', {'extraSteps':3});
|
||||
deferredResult.addMethod(this, 'initialSetupWithNoData')
|
||||
deferredResult.addMethod(this, 'getPassphrase');
|
||||
deferredResult.addMethod(this, 'prepareRemoteDataWithKey');
|
||||
// deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress');
|
||||
deferredResult.addMethod(this.connection(), 'register');
|
||||
// deferredResult.addCallback(MochiKit.Base.itemgetter('lock'));
|
||||
// deferredResult.addMethod(this, 'setServerLockValue');
|
||||
// deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'userSuccessfullyRegistered');
|
||||
|
||||
// deferredResult.addErrback (MochiKit.Base.method(this, 'handleRegistrationFailure'));
|
||||
|
||||
deferredResult.callback();
|
||||
|
||||
return deferredResult;
|
||||
@@ -276,22 +320,44 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User, Object, {
|
||||
|
||||
'login': function () {
|
||||
var deferredResult;
|
||||
var oneTimePasswordReference;
|
||||
|
||||
deferredResult = new Clipperz.Async.Deferred("User.login", {trace:false});
|
||||
deferredResult.addMethod(this, 'getPassphrase');
|
||||
deferredResult.addCallback(Clipperz.PM.DataModel.OneTimePassword.isValidOneTimePasswordValue);
|
||||
|
||||
deferredResult.addCallback(Clipperz.Async.deferredIf("Is the passphrase an OTP", [
|
||||
MochiKit.Base.method(this,'getPassphrase'),
|
||||
MochiKit.Base.method(this,'setUsedOTP'),
|
||||
MochiKit.Base.method(this, 'getCredentials'),
|
||||
MochiKit.Base.method(this.connection(), 'redeemOneTimePassword'),
|
||||
MochiKit.Base.method(this.data(), 'setValue', 'passphrase')
|
||||
function (aPassphrase) {
|
||||
return MochiKit.Base.partial(MochiKit.Async.succeed, aPassphrase);
|
||||
},
|
||||
MochiKit.Base.method(this, 'setPassphraseFunction')
|
||||
], []));
|
||||
deferredResult.addErrback(MochiKit.Base.method(this, 'getPassphrase'));
|
||||
|
||||
deferredResult.addBoth(MochiKit.Base.method(this, 'loginWithPassphrase'));
|
||||
deferredResult.addBoth(MochiKit.Base.method(this, 'resetUsedOTP'));
|
||||
|
||||
deferredResult.callback();
|
||||
|
||||
return deferredResult;
|
||||
},
|
||||
|
||||
'loginWithPassphrase': function () {
|
||||
var deferredResult;
|
||||
|
||||
deferredResult = new Clipperz.Async.Deferred("User.loginWithPassphrase", {trace:false});
|
||||
|
||||
deferredResult.addMethod(this, 'getPassphrase');
|
||||
deferredResult.addMethod(this.connection(), 'login', false);
|
||||
deferredResult.addMethod(this, 'setupAccountInfo');
|
||||
deferredResult.addMethod(this, 'markUsedOTP');
|
||||
deferredResult.addErrback (MochiKit.Base.method(this, 'handleConnectionFallback'));
|
||||
|
||||
deferredResult.callback();
|
||||
|
||||
|
||||
return deferredResult;
|
||||
},
|
||||
|
||||
@@ -300,21 +366,18 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User, Object, {
|
||||
'handleConnectionFallback': function(aValue) {
|
||||
var result;
|
||||
|
||||
//console.log("USER - handleConnectionFallback", aValue, aValue['isPermanent']);
|
||||
if (aValue instanceof MochiKit.Async.CancelledError) {
|
||||
result = aValue;
|
||||
} else if ((aValue['isPermanent'] === true) || (Clipperz.PM.Connection.communicationProtocol.fallbackVersions[this.connectionVersion()] == null)) {
|
||||
result = Clipperz.Async.callbacks("User.handleConnectionFallback - failed", [
|
||||
MochiKit.Base.method(this.data(), 'removeValue', 'passphrase'),
|
||||
MochiKit.Base.method(this, 'setConnectionVersion', 'current'),
|
||||
// MochiKit.Base.partial(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'userLoginFailed'),
|
||||
// MochiKit.Base.partial(MochiKit.Async.fail, Clipperz.PM.DataModel.User.exception.LoginFailed)
|
||||
MochiKit.Base.partial(MochiKit.Async.fail, aValue)
|
||||
], {trace:false});
|
||||
} else {
|
||||
this.setConnectionVersion(Clipperz.PM.Connection.communicationProtocol.fallbackVersions[this.connectionVersion()]);
|
||||
result = new Clipperz.Async.Deferred("User.handleConnectionFallback - retry");
|
||||
result.addMethod(this, 'login');
|
||||
result.addMethod(this, 'loginWithPassphrase');
|
||||
result.callback();
|
||||
}
|
||||
|
||||
@@ -324,8 +387,6 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User, Object, {
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
'setupAccountInfo': function (aValue) {
|
||||
//console.log("User.setupAccountInfo", aValue, aValue['accountInfo']);
|
||||
// this.setLoginInfo(aValue['loginInfo']);
|
||||
this.setAccountInfo(new Clipperz.PM.DataModel.User.AccountInfo(aValue['accountInfo']));
|
||||
},
|
||||
|
||||
@@ -373,8 +434,6 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User, Object, {
|
||||
var preferences;
|
||||
var oneTimePasswords;
|
||||
|
||||
// this.setServerLockValue(someServerData['lock']);
|
||||
|
||||
headerVersion = this.headerFormatVersion(someServerData['header']);
|
||||
switch (headerVersion) {
|
||||
case 'LEGACY':
|
||||
@@ -429,7 +488,9 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User, Object, {
|
||||
|
||||
if (typeof(headerData['oneTimePasswords']) != 'undefined') {
|
||||
oneTimePasswords = new Clipperz.PM.DataModel.User.Header.OneTimePasswords({
|
||||
'name': 'preferences',
|
||||
'name': 'oneTimePasswords',
|
||||
'connection': this.connection(),
|
||||
'username': this.username(),
|
||||
'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase'),
|
||||
'remoteData': {
|
||||
'data': headerData['oneTimePasswords']['data'],
|
||||
@@ -438,7 +499,9 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User, Object, {
|
||||
});
|
||||
} else {
|
||||
oneTimePasswords = new Clipperz.PM.DataModel.User.Header.OneTimePasswords({
|
||||
'name': 'preferences',
|
||||
'name': 'OneTimePasswords',
|
||||
'connection': this.connection(),
|
||||
'username': this.username(),
|
||||
'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase')
|
||||
});
|
||||
}
|
||||
@@ -595,7 +658,6 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User, Object, {
|
||||
*/
|
||||
], {trace:false});
|
||||
},
|
||||
|
||||
/*
|
||||
'filterRecordsInfo': function (someArgs) {
|
||||
var info = (someArgs.info ? someArgs.info : Clipperz.PM.DataModel.Record.defaultCardInfo);
|
||||
@@ -688,8 +750,47 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User, Object, {
|
||||
], {trace:false});
|
||||
},
|
||||
|
||||
//.........................................................................
|
||||
|
||||
'createNewRecordFromJSON': function(someJSON) {
|
||||
var deferredResult;
|
||||
|
||||
deferredResult = new Clipperz.Async.Deferred("User.createNewRecordFromJSON", {trace:false});
|
||||
deferredResult.collectResults({
|
||||
'recordIndex': MochiKit.Base.method(this, 'getHeaderIndex', 'recordsIndex'),
|
||||
'newRecord': [
|
||||
MochiKit.Base.method(this, 'createNewRecord'),
|
||||
MochiKit.Base.methodcaller('setUpWithJSON', someJSON),
|
||||
]
|
||||
});
|
||||
deferredResult.addCallback(function (someInfo) {
|
||||
var record = someInfo['newRecord'];
|
||||
var recordIndex = someInfo['recordIndex'];
|
||||
|
||||
return MochiKit.Base.map(function (aDirectLogin) {
|
||||
var configuration = JSON.stringify({
|
||||
'page': {'title': aDirectLogin['label']},
|
||||
'form': aDirectLogin['formData'],
|
||||
'version': '0.2' // correct?
|
||||
});
|
||||
|
||||
return Clipperz.Async.callbacks("User.createNewRecordFromJSON__inner", [
|
||||
MochiKit.Base.method(recordIndex, 'createNewDirectLogin', record),
|
||||
MochiKit.Base.methodcaller('setLabel', aDirectLogin['label']),
|
||||
MochiKit.Base.methodcaller('setBookmarkletConfiguration', configuration),
|
||||
MochiKit.Base.methodcaller('setBindings', aDirectLogin['bindingData'], someJSON['currentVersion']['fields']),
|
||||
], {'trace': false});
|
||||
}, MochiKit.Base.values(someJSON.data.directLogins));
|
||||
});
|
||||
deferredResult.addCallback(Clipperz.Async.collectAll);
|
||||
deferredResult.callback();
|
||||
|
||||
return deferredResult;
|
||||
},
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
'cloneRecord': function (aRecord) {
|
||||
//console.log("USER.cloneRecord", aRecord);
|
||||
var result;
|
||||
var user = this;
|
||||
|
||||
@@ -700,9 +801,6 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User, Object, {
|
||||
], [
|
||||
MochiKit.Base.method(user, 'createNewRecord'),
|
||||
MochiKit.Base.methodcaller('setUpWithRecord', aRecord),
|
||||
// function (aValue) { result = aValue; return aValue; },
|
||||
// MochiKit.Base.method(user, 'saveChanges'),
|
||||
// function () { return result; }
|
||||
])
|
||||
], {trace:false});
|
||||
},
|
||||
@@ -731,6 +829,62 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User, Object, {
|
||||
], {trace:false});
|
||||
},
|
||||
|
||||
'getOneTimePasswordsDetails': function() {
|
||||
return Clipperz.Async.callbacks("User.getOneTimePasswords", [
|
||||
MochiKit.Base.method(this, 'getHeaderIndex', 'oneTimePasswords'),
|
||||
MochiKit.Base.methodcaller('oneTimePasswordsDetails', this.connection()),
|
||||
], {trace:false});
|
||||
},
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
'createNewOTP': function () {
|
||||
var messageParameters;
|
||||
|
||||
messageParameters = {};
|
||||
return Clipperz.Async.callbacks("User.createNewOTP", [
|
||||
MochiKit.Base.method(this, 'getHeaderIndex', 'oneTimePasswords'),
|
||||
MochiKit.Base.methodcaller('createNewOTP', this.username(), MochiKit.Base.method(this, 'getPassphrase')),
|
||||
MochiKit.Base.methodcaller('encryptedData'),
|
||||
MochiKit.Base.partial(function(someParameters, someOTPEncryptedData) {
|
||||
someParameters['oneTimePassword'] = someOTPEncryptedData;
|
||||
}, messageParameters),
|
||||
MochiKit.Base.method(this, 'getPassphrase'),
|
||||
MochiKit.Base.method(this, 'prepareRemoteDataWithKey'),
|
||||
MochiKit.Base.partial(function(someParameters, someEncryptedRemoteData) {
|
||||
someParameters['user'] = someEncryptedRemoteData;
|
||||
}, messageParameters),
|
||||
MochiKit.Base.method(this.connection(), 'message', 'addNewOneTimePassword', messageParameters)
|
||||
], {trace:false});
|
||||
},
|
||||
|
||||
'deleteOTPs': function (aList) {
|
||||
var messageParameters;
|
||||
|
||||
messageParameters = {};
|
||||
return Clipperz.Async.callbacks("User.deleteOTPs", [
|
||||
MochiKit.Base.method(this, 'getHeaderIndex', 'oneTimePasswords'),
|
||||
MochiKit.Base.methodcaller('deleteOTPs', aList),
|
||||
MochiKit.Base.partial(function(someParameters, aList) {
|
||||
someParameters['oneTimePasswords'] = aList
|
||||
}, messageParameters),
|
||||
MochiKit.Base.method(this, 'getPassphrase'),
|
||||
MochiKit.Base.method(this, 'prepareRemoteDataWithKey'),
|
||||
MochiKit.Base.partial(function(someParameters, someEncryptedRemoteData) {
|
||||
someParameters['user'] = someEncryptedRemoteData;
|
||||
}, messageParameters),
|
||||
MochiKit.Base.method(this.connection(), 'message', 'updateOneTimePasswords', messageParameters)
|
||||
], {trace:false});
|
||||
},
|
||||
|
||||
'changeOTPLabel': function (aReference, aLabel) {
|
||||
return Clipperz.Async.callbacks("User.changeOTPLabel", [
|
||||
MochiKit.Base.method(this, 'getHeaderIndex', 'oneTimePasswords'),
|
||||
MochiKit.Base.methodcaller('changeOTPLabel', aReference, aLabel),
|
||||
MochiKit.Base.method(this,'saveChanges') // Too 'heavy'? Should be moved to MainController to prevent glitch in the UI?
|
||||
], {trace:false});
|
||||
},
|
||||
|
||||
//=========================================================================
|
||||
|
||||
'invokeMethodNamedOnHeader': function (aMethodName, aValue) {
|
||||
@@ -804,13 +958,9 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User, Object, {
|
||||
|
||||
'revertChanges': function () {
|
||||
return Clipperz.Async.callbacks("User.revertChanges", [
|
||||
//function (aValue) { console.log("User.revertChanges - 1"); return aValue; },
|
||||
MochiKit.Base.method(this, 'invokeMethodNamedOnHeader', 'revertChanges'),
|
||||
//function (aValue) { console.log("User.revertChanges - 2"); return aValue; },
|
||||
MochiKit.Base.method(this, 'invokeMethodNamedOnRecords', 'revertChanges'),
|
||||
//function (aValue) { console.log("User.revertChanges - 3"); return aValue; },
|
||||
MochiKit.Base.method(this, 'resetTransientState', false),
|
||||
//function (aValue) { console.log("User.revertChanges - 4"); return aValue; },
|
||||
], {trace:false});
|
||||
},
|
||||
|
||||
@@ -882,6 +1032,13 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User, Object, {
|
||||
return deferredResult;
|
||||
},
|
||||
|
||||
'prepareRemoteDataWithKeyFunction': function(aKeyFunction) {
|
||||
return new Clipperz.Async.callbacks("User.prepareRemoteDataWithKeyFunction", [
|
||||
aKeyFunction,
|
||||
MochiKit.Base.method(this, 'prepareRemoteDataWithKey')
|
||||
], {'trace': false})
|
||||
},
|
||||
|
||||
//=========================================================================
|
||||
|
||||
'saveChanges': function () {
|
||||
@@ -895,24 +1052,17 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User, Object, {
|
||||
deferredResult.addMethod(this, 'getHeaderIndex', 'recordsIndex');
|
||||
deferredResult.addCallback(MochiKit.Base.methodcaller('prepareRemoteDataForChangedRecords'));
|
||||
deferredResult.addCallback(Clipperz.Async.setItem, messageParameters, 'records');
|
||||
// deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress');
|
||||
|
||||
deferredResult.addMethod(this, 'getPassphrase');
|
||||
deferredResult.addMethod(this, 'prepareRemoteDataWithKey');
|
||||
deferredResult.addCallback(Clipperz.Async.setItem, messageParameters, 'user');
|
||||
// deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress');
|
||||
|
||||
deferredResult.addCallback(MochiKit.Async.succeed, messageParameters);
|
||||
deferredResult.addMethod(this.connection(), 'message', 'saveChanges');
|
||||
deferredResult.addCallback(MochiKit.Base.update, this.transientState())
|
||||
// deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress');
|
||||
|
||||
deferredResult.addMethod(this, 'commitTransientState');
|
||||
// deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress');
|
||||
// deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'userDataSuccessfullySaved');
|
||||
|
||||
deferredResult.addErrbackPass(MochiKit.Base.method(this, 'revertChanges'));
|
||||
// deferredResult.addErrbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'failureWhileSavingUserData');
|
||||
|
||||
deferredResult.callback();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user