22 files changed, 1501 insertions, 803 deletions
diff --git a/frontend/gamma/js/Clipperz/Async.js b/frontend/gamma/js/Clipperz/Async.js index 97d8ecf..f7a9517 100644 --- a/frontend/gamma/js/Clipperz/Async.js +++ b/frontend/gamma/js/Clipperz/Async.js @@ -468,99 +468,99 @@ MochiKit.Base.update(Clipperz.Async, { methods = MochiKit.Base.values(someRequests); deferredResult = new Clipperz.Async.Deferred(aName, args); deferredResult.addCallback(Clipperz.Async.forkAndJoin(aName + " [inner forkAndJoin]", methods, args)); deferredResult.addBoth(function(someResults) { var returnFunction; var results; var i,c; var result; if (someResults instanceof MochiKit.Async.CancelledError) { returnFunction = MochiKit.Async.fail; result = someResults; } else { if (someResults instanceof Error) { returnFunction = MochiKit.Async.fail; results = someResults['message']; } else { returnFunction = MochiKit.Async.succeed; results = someResults; } result = {}; c = requestKeys.length; for (i=0; i<c; i++) { result[requestKeys[i]] = results[i]; } } return returnFunction.call(null, result); }); deferredResult.callback(aValue); return deferredResult; }, aName, someRequests, args); }, //------------------------------------------------------------------------- 'collectAll': function (someDeferredObjects) { var deferredResult; deferredResult = new MochiKit.Async.DeferredList(someDeferredObjects, false, false, false); deferredResult.addCallback(function (aResultList) { return MochiKit.Base.map(function (aResult) { if (aResult[0]) { return aResult[1]; - } else { + } else { throw aResult[1]; - } + } }, aResultList); }); return deferredResult; }, //------------------------------------------------------------------------- 'setItem': function (anObject, aKey, aValue) { anObject[aKey] = aValue; return anObject; }, 'setItemOnObject': function (aKey, aValue, anObject) { anObject[aKey] = aValue; return anObject; }, 'setDeferredItemOnObject': function (aKey, aDeferredFunction, anObject) { return Clipperz.Async.callbacks("Clipperz.Async.setDeferredItemOnObject", [ aDeferredFunction, MochiKit.Base.partial(Clipperz.Async.setItem, anObject, aKey) ], {trace:false}, anObject); }, //------------------------------------------------------------------------- 'deferredIf': function (aName, aThenBlock, anElseBlock) { return function (aValue) { var deferredResult; if (!MochiKit.Base.isUndefinedOrNull(aValue) && aValue) { deferredResult = Clipperz.Async.callbacks(aName + " <then>", aThenBlock, null, aValue); } else { deferredResult = Clipperz.Async.callbacks(aName + " <else>", anElseBlock, null, aValue); } return deferredResult; } }, //------------------------------------------------------------------------- 'log': function(aMessage, aResult) { if (CLIPPERZ_DEFERRED_LOGGING_ENABLED) { Clipperz.log(aMessage + " ", aResult); diff --git a/frontend/gamma/js/Clipperz/Base.js b/frontend/gamma/js/Clipperz/Base.js index 76b2c3f..9d399d9 100644 --- a/frontend/gamma/js/Clipperz/Base.js +++ b/frontend/gamma/js/Clipperz/Base.js @@ -32,96 +32,101 @@ Clipperz.Base.NAME = "Clipperz.Base"; MochiKit.Base.update(Clipperz.Base, { //------------------------------------------------------------------------- '__repr__': function () { return "[" + this.NAME + " " + this.VERSION + "]"; }, //------------------------------------------------------------------------- 'toString': function () { return this.__repr__(); }, //------------------------------------------------------------------------- 'itemgetter': function (aKeyPath) { // return MochiKit.Base.compose.apply(null, [MochiKit.Base.itemgetter('key3')]); return MochiKit.Base.compose.apply(null, MochiKit.Base.map( MochiKit.Base.itemgetter, MochiKit.Iter.reversed( aKeyPath.split('.') ) ) ); }, //------------------------------------------------------------------------- 'isUrl': function (aValue) { return (MochiKit.Base.urlRegExp.test(aValue)); }, 'isEmail': function (aValue) { return (MochiKit.Base.emailRegExp.test(aValue)); }, //------------------------------------------------------------------------- 'caseInsensitiveCompare': function (a, b) { return MochiKit.Base.compare(a.toLowerCase(), b.toLowerCase()); }, 'reverseComparator': function (aComparator) { return MochiKit.Base.compose(function(aResult) { return -aResult; }, aComparator); }, + 'caseInsensitiveKeyComparator': function (aKey) { + return function (a, b) { + return MochiKit.Base.compare(a[aKey].toLowerCase(), b[aKey].toLowerCase()); + } + }, //------------------------------------------------------------------------- /* 'dependsOn': function(module, deps) { if (!(module in Clipperz)) { MochiKit[module] = {}; } if (typeof(dojo) != 'undefined') { dojo.provide('Clipperz.' + module); } for (var i = 0; i < deps.length; i++) { if (typeof(dojo) != 'undefined') { dojo.require('Clipperz.' + deps[i]); } if (typeof(JSAN) != 'undefined') { JSAN.use('Clipperz.' + deps[i], []); } if (!(deps[i] in Clipperz)) { throw 'Clipperz.' + module + ' depends on Clipperz.' + deps[i] + '!' } } }, */ //------------------------------------------------------------------------- 'trim': function (aValue) { return aValue.replace(/^\s+|\s+$/g, ""); }, //------------------------------------------------------------------------- 'stringToByteArray': function (aValue) { var result; var i, c; result = []; c = aValue.length; for (i=0; i<c; i++) { result[i] = aValue.charCodeAt(i); } return result; }, //......................................................................... 'byteArrayToString': function (anArrayOfBytes) { diff --git a/frontend/gamma/js/Clipperz/PM/Connection.js b/frontend/gamma/js/Clipperz/PM/Connection.js index b4e8aaa..a05a310 100644 --- a/frontend/gamma/js/Clipperz/PM/Connection.js +++ b/frontend/gamma/js/Clipperz/PM/Connection.js @@ -1,91 +1,92 @@ /* Copyright 2008-2011 Clipperz Srl This file is part of Clipperz Community Edition. Clipperz Community Edition is an online password manager. For further information about its features and functionalities please refer to http://www.clipperz.com. * Clipperz Community Edition 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. * Clipperz Community Edition 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 Clipperz Community Edition. If not, see <http://www.gnu.org/licenses/>. */ if (typeof(Clipperz) == 'undefined') { Clipperz = {}; } if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; } //----------------------------------------------------------------------------- // // Abstract C O N N E C T I O N class // //----------------------------------------------------------------------------- Clipperz.PM.Connection = function (args) { args = args || {}; this._proxy = args.proxy || Clipperz.PM.Proxy.defaultProxy; this._getCredentialsFunction = args.getCredentialsFunction; this._clipperz_pm_crypto_version = null; this._connectionId = null; this._sharedSecret = null; + this._serverLockValue = null; return this; } Clipperz.PM.Connection.prototype = MochiKit.Base.update(null, { 'toString': function() { return "Connection [" + this.version() + "]"; }, //========================================================================= 'version': function() { throw Clipperz.Base.exception.AbstractMethod; }, 'clipperz_pm_crypto_version': function() { if (this._clipperz_pm_crypto_version == null) { var connectionVersions; var versions; var version; var i, c; version = null; connectionVersions = Clipperz.PM.Connection.communicationProtocol.versions; versions = MochiKit.Base.keys(connectionVersions); c = versions.length; for (i=0; i<c; i++) { if (! (versions[i] == 'current')) { if (this instanceof connectionVersions[versions[i]]) { version = versions[i]; }; } } this._clipperz_pm_crypto_version = version; } return this._clipperz_pm_crypto_version; }, //------------------------------------------------------------------------- 'defaultErrorHandler': function(anErrorString, anException) { MochiKit.Logging.logError("### Connection.defaultErrorHandler: " + anErrorString + " (" + anException + ")"); }, //------------------------------------------------------------------------- @@ -101,96 +102,106 @@ MochiKit.Logging.logError("### Connection.defaultErrorHandler: " + anErrorString //========================================================================= 'proxy': function () { return this._proxy; }, //========================================================================= 'register': function () { throw Clipperz.Base.exception.AbstractMethod; }, 'login': function() { throw Clipperz.Base.exception.AbstractMethod; }, //------------------------------------------------------------------------- 'message': function(someArguments, aCallback) { throw Clipperz.Base.exception.AbstractMethod; }, //------------------------------------------------------------------------- 'serverSideUserCredentials': function() { throw Clipperz.Base.exception.AbstractMethod; }, //========================================================================= 'sharedSecret': function () { return this._sharedSecret; }, 'setSharedSecret': function (aValue) { this._sharedSecret = aValue; }, //------------------------------------------------------------------------- 'connectionId': function() { return this._connectionId; }, 'setConnectionId': function(aValue) { this._connectionId = aValue; }, + //------------------------------------------------------------------------- + + 'serverLockValue': function () { + return this._serverLockValue; + }, + + 'setServerLockValue': function (aValue) { + this._serverLockValue = aValue; + }, + //========================================================================= /* // TODO: ????? 'oneTimePassword': function() { return this._oneTimePassword; }, 'setOneTimePassword': function(aValue) { this._oneTimePassword = aValue; }, */ //========================================================================= 'reset': function() { this.setSharedSecret(null); this.setConnectionId(null); }, //========================================================================= __syntaxFix__: "syntax fix" } ); if (typeof(Clipperz.PM.Connection.SRP) == 'undefined') { Clipperz.PM.Connection.SRP = {}; } //----------------------------------------------------------------------------- // // S R P [ 1 . 0 ] C O N N E C T I O N class // //----------------------------------------------------------------------------- Clipperz.PM.Connection.SRP['1.0'] = function (args) { Clipperz.PM.Connection.call(this, args); return this; } Clipperz.PM.Connection.SRP['1.0'].prototype = MochiKit.Base.update(new Clipperz.PM.Connection(), { 'version': function() { return '1.0'; }, //========================================================================= 'register': function (someUserData) { var deferredResult; @@ -275,227 +286,239 @@ Clipperz.PM.Connection.SRP['1.0'].prototype = MochiKit.Base.update(new Clipperz. 'parameters': { 'oneTimePasswordKey': Clipperz.PM.DataModel.OneTimePassword.computeKeyWithUsernameAndPassword(anUsername, aOneTimePassword), 'oneTimePasswordKeyChecksum': Clipperz.PM.DataModel.OneTimePassword.computeKeyChecksumWithUsernameAndPassword(anUsername, aOneTimePassword) } } return args; }, anUsername, oneTimePassword); deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'OTP_login_loadingOTP'); deferredResult.addCallback(MochiKit.Base.method(Clipperz.PM.Proxy.defaultProxy, 'handshake')); deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'OTP_login_extractingPassphrase'); deferredResult.addCallback(function(aResult) { return Clipperz.PM.Crypto.deferredDecrypt(oneTimePassword, aResult['data'], aResult['version']); }); deferredResult.addCallback(function(aResult) { return (new Clipperz.ByteArray().appendBase64String(aResult['passphrase'])).asString(); }); deferredResult.addMethod(this, 'doLoginWithUsernameAndPassphrase', anUsername), */ var args; var normalizedOTP; normalizedOTP = Clipperz.PM.DataModel.OneTimePassword.normalizedOneTimePassword(someParameters['password']); args = { 'message': 'oneTimePassword', 'version': Clipperz.PM.Connection.communicationProtocol.currentVersion, 'parameters': { 'oneTimePasswordKey': Clipperz.PM.DataModel.OneTimePassword.computeKeyWithUsernameAndPassword(someParameters['username'], normalizedOTP), 'oneTimePasswordKeyChecksum': Clipperz.PM.DataModel.OneTimePassword.computeKeyChecksumWithUsernameAndPassword(someParameters['username'], normalizedOTP) } } return Clipperz.Async.callbacks("Connction.redeemOTP", [ MochiKit.Base.method(this.proxy(), 'handshake', args), function(aResult) { return Clipperz.PM.Crypto.deferredDecrypt({ value: aResult['data'], key: normalizedOTP, version:aResult['version'] }); }, function(aResult) { return (new Clipperz.ByteArray().appendBase64String(aResult['passphrase'])).asString(); } ], {trace:false}) }, - 'login': function(/*anUsername, aPassphrase*/) { + 'login': function(isReconnecting) { var deferredResult; var cryptoVersion; var srpConnection; cryptoVersion = this.clipperz_pm_crypto_version(); - deferredResult = new Clipperz.Async.Deferred("Connection.login", {trace:false}); deferredResult.addCallback(this.getCredentialsFunction()); deferredResult.addMethod(this, 'normalizedCredentials'); // deferredResult.addCallbackPass(MochiKit.Signal.signal, this, 'updatedProgressState', 'connection_sendingCredentials'); deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress'); deferredResult.addCallback(MochiKit.Base.bind(function(someCredentials) { srpConnection = new Clipperz.Crypto.SRP.Connection({ C:someCredentials['username'], P:someCredentials['password'], hash:this.hash() }); }, this)); deferredResult.addCallback(function() { var result; result = { message: 'connect', version: cryptoVersion, parameters: { C: srpConnection.C(), A: srpConnection.A().asString(16) // reconnecting: this.connectionId() } }; // TODO: ????? // if (isReconnecting == true) { // args.parameters['reconnecting'] = aConnection.connectionId(); // } return result; }); deferredResult.addMethod(this.proxy(), 'handshake'); // deferredResult.addCallbackPass(MochiKit.Signal.signal, this, 'updatedProgressState', 'connection_credentialVerification'); deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress'); deferredResult.addCallback(function(someParameters) { var result; srpConnection.set_s(new Clipperz.Crypto.BigInt(someParameters['s'], 16)); srpConnection.set_B(new Clipperz.Crypto.BigInt(someParameters['B'], 16)); // TODO: ????? // if (typeof(someParameters['oneTimePassword']) != 'undefined') { // this.setOneTimePassword(someParameters['oneTimePassword']); // } result = { message: 'credentialCheck', version: cryptoVersion, parameters: { M1: srpConnection.M1() } }; return result; }); deferredResult.addMethod(this.proxy(), 'handshake'); deferredResult.addCallback(function(someParameters) { var result; if (someParameters['M2'] == srpConnection.M2()) { result = MochiKit.Async.succeed(someParameters); } else { result = MochiKit.Async.fail(Clipperz.PM.Connection.exception.WrongChecksum); } return result; }); deferredResult.addCallback(MochiKit.Base.bind(function(someParameters) { this.setConnectionId(someParameters['connectionId']); this.setSharedSecret(srpConnection.K()); // TODO: ????? // if (this.oneTimePassword() != null) { /// ?? result = this.user().oneTimePasswordManager().archiveOneTimePassword(this.oneTimePassword())); // } + + if ((isReconnecting == true) && (this.serverLockValue() != someParameters['lock'])) { + throw Clipperz.PM.Connection.exception.StaleData; + } else { + this.setServerLockValue(someParameters['lock']); + } + return someParameters; }, this)); // deferredResult.addCallbackPass(MochiKit.Signal.signal, this, 'updatedProgressState', 'connection_loggedIn'); deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress'); deferredResult.addCallback(MochiKit.Async.succeed, {result:"done"}); deferredResult.callback(); return deferredResult; }, //========================================================================= 'logout': function() { return Clipperz.Async.callbacks("Connection.logout", [ MochiKit.Base.method(this, 'setSharedSecret'), MochiKit.Base.method(this.proxy(), 'logout', {}) ], {trace:false}); }, //========================================================================= 'ping': function () { // TODO: ping the server in order to have a valid session }, //========================================================================= 'message': function(aMessageName, someParameters) { var args; + var parameters; + + parameters = someParameters || {}; + if (typeof(parameters['user']) != 'undefined') { + parameters['user']['lock'] = this.serverLockValue(); + } //console.log(">>> Connection.message", aMessageName, someParameters); args = { message: aMessageName, srpSharedSecret: this.sharedSecret(), - parameters: (someParameters || {}) +// parameters: (someParameters || {}) + parameters: parameters } return this.sendMessage(args); }, //------------------------------------------------------------------------- 'sendMessage': function(someArguments) { var deferredResult; deferredResult = new Clipperz.Async.Deferred("Connection.sendMessage", {trace:false}); deferredResult.addMethod(this.proxy(), 'message', someArguments); deferredResult.addCallback(MochiKit.Base.bind(function(res) { if (typeof(res['lock']) != 'undefined') { -// TODO: ????? -// ?? this.user().setLock(res['lock']); + this.setServerLockValue(res['lock']); } return res; }, this)); deferredResult.addErrback(MochiKit.Base.method(this, 'messageExceptionHandler'), someArguments); deferredResult.callback(); return deferredResult }, //------------------------------------------------------------------------- 'messageExceptionHandler': function(anOriginalMessageArguments, anError) { var result; console.log(">>> Connection.messageExceptionHandler", anError, anError.message); if (anError instanceof MochiKit.Async.CancelledError) { result = anError; } else { if ((anError.message == 'Trying to communicate without an active connection') || (anError.message == 'No tollManager available for current session') ) { result = this.reestablishConnection(anOriginalMessageArguments); } else if (anError.message == 'Session with stale data') { MochiKit.Signal.signal(this, 'EXCEPTION'); } else { result = anError; } } console.log("<<< Connection.messageExceptionHandler", anError) return result;; }, //========================================================================= 'reestablishConnection': function(anOriginalMessageArguments) { var deferredResult; deferredResult = new Clipperz.Async.Deferred("Connection.reestablishConnection"); deferredResult.addMethod(this, 'reset'); deferredResult.addMethod(this, 'login', true); deferredResult.addCallback(MochiKit.Base.bind(function(aMessage) { aMessage['srpSharedSecret'] = this.sharedSecret(); return aMessage; }, this), anOriginalMessageArguments); deferredResult.addMethod(this, 'sendMessage'); deferredResult.addErrback(MochiKit.Signal.signal, this, 'EXCEPTION', null); @@ -542,75 +565,76 @@ console.log("<<< Connection.messageExceptionHandler", anError) }); //----------------------------------------------------------------------------- // // S R P [ 1 . 1 ] C O N N E C T I O N class // //----------------------------------------------------------------------------- Clipperz.PM.Connection.SRP['1.1'] = function (args) { Clipperz.PM.Connection.SRP['1.0'].call(this, args); return this; } Clipperz.PM.Connection.SRP['1.1'].prototype = MochiKit.Base.update(new Clipperz.PM.Connection.SRP['1.0'](), { 'version': function() { return '1.1'; }, //----------------------------------------------------------------------------- 'normalizedCredentials': function(someValues) { var result; result = {} result['username'] = this.hash()(new Clipperz.ByteArray(someValues['username'] + someValues['password'])).toHexString().substring(2); result['password'] = this.hash()(new Clipperz.ByteArray(someValues['password'] + someValues['username'])).toHexString().substring(2); return result; }, //----------------------------------------------------------------------------- 'hash': function() { return Clipperz.PM.Crypto.encryptingFunctions.versions['0.2'].hash; }, //----------------------------------------------------------------------------- __syntaxFix__: "syntax fix" }); Clipperz.PM.Connection.exception = { WrongChecksum: new MochiKit.Base.NamedError("Clipperz.ByteArray.exception.InvalidValue"), + StaleData: new MochiKit.Base.NamedError("Stale data"), UnexpectedRequest: new MochiKit.Base.NamedError("Clipperz.ByteArray.exception.UnexpectedRequest") }; Clipperz.PM.Connection.communicationProtocol = { 'currentVersion': '0.2', 'versions': { '0.1': Clipperz.PM.Connection.SRP['1.0'], //Clipperz.Crypto.SRP.versions['1.0'].Connection, '0.2': Clipperz.PM.Connection.SRP['1.1'] //Clipperz.Crypto.SRP.versions['1.1'].Connection }, 'fallbackVersions': { // 'current': '0.1', '0.2': '0.1', '0.1': null } }; MochiKit.Base.update(Clipperz.PM.Connection.communicationProtocol.versions, { 'current': Clipperz.PM.Connection.communicationProtocol.versions[Clipperz.PM.Connection.communicationProtocol.currentVersion] }); MochiKit.Base.update(Clipperz.PM.Connection.communicationProtocol.fallbackVersions, { 'current': Clipperz.PM.Connection.communicationProtocol.fallbackVersions[Clipperz.PM.Connection.communicationProtocol.currentVersion] }); diff --git a/frontend/gamma/js/Clipperz/PM/DataModel/User.js b/frontend/gamma/js/Clipperz/PM/DataModel/User.js index 72d4006..646ce21 100644 --- a/frontend/gamma/js/Clipperz/PM/DataModel/User.js +++ b/frontend/gamma/js/Clipperz/PM/DataModel/User.js @@ -1,152 +1,152 @@ /* Copyright 2008-2011 Clipperz Srl This file is part of Clipperz Community Edition. Clipperz Community Edition is an online password manager. For further information about its features and functionalities please refer to http://www.clipperz.com. * Clipperz Community Edition 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. * Clipperz Community Edition 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 Clipperz Community Edition. 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) { args = args || {}; Clipperz.PM.DataModel.User.superclass.constructor.apply(this, arguments); this._username = args.username || null; this._getPassphraseFunction = args.getPassphraseFunction || null; this._data = null; this._connection = null; this._connectionVersion = 'current'; this._serverData = null; - this._serverLockValue = null; +// this._serverLockValue = null; this._transientState = null; this._deferredLocks = { 'passphrase': new MochiKit.Async.DeferredLock(), 'serverData': new MochiKit.Async.DeferredLock(), // 'recordsIndex': new MochiKit.Async.DeferredLock(), // 'directLoginsIndex': new MochiKit.Async.DeferredLock() // 'preferences': new MochiKit.Async.DeferredLock() // 'oneTimePasswords': new MochiKit.Async.DeferredLock() '__syntaxFix__': 'syntax fix' }; return this; } Clipperz.Base.extend(Clipperz.PM.DataModel.User, Object, { 'toString': function () { return "Clipperz.PM.DataModel.User - " + this.username(); }, //------------------------------------------------------------------------- 'username': function () { return this._username; }, 'setUsername': function (aValue) { this._username = aValue; }, //------------------------------------------------------------------------- 'displayName': function() { return "" + this.username() + ""; }, //------------------------------------------------------------------------- 'data': function () { if (this._data == null) { this._data = new Clipperz.KeyValueObjectStore(/*{'name':'User.data [1]'}*/); }; return this._data; }, //------------------------------------------------------------------------- - +/* 'serverLockValue': function () { return this._serverLockValue; }, 'setServerLockValue': function (aValue) { this._serverLockValue = aValue; }, - +*/ //------------------------------------------------------------------------- 'transientState': function () { if (this._transientState == null) { this._transientState = {} } return this._transientState; }, 'resetTransientState': function (isCommitting) { this._transientState = null; }, //------------------------------------------------------------------------- 'deferredLockForSection': function(aSectionName) { return this._deferredLocks[aSectionName]; }, //------------------------------------------------------------------------- '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; }, 'getPassphraseFunction': function () { return this._getPassphraseFunction; }, //------------------------------------------------------------------------- 'getCredentials': function () { return Clipperz.Async.collectResults("User; get username and passphrase", { 'username': MochiKit.Base.method(this, 'username'), 'password': MochiKit.Base.method(this, 'getPassphrase') }, {trace:false})(); }, //------------------------------------------------------------------------- @@ -175,206 +175,206 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User, Object, { return deferredResult; }, //------------------------------------------------------------------------- 'initialSetupWithNoData': function () { this._serverData = { 'version': '0.1', 'statistics': "", 'header': { 'data': null, 'version': Clipperz.PM.Crypto.encryptingFunctions.currentVersion, 'recordsIndex': new Clipperz.PM.DataModel.User.Header.RecordIndex({ 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase'), 'recordsData': {'data':null, 'index':{}}, 'recordsStats': null, 'directLoginsData': {'data':null, 'index':{}}, 'encryptedDataVersion': Clipperz.PM.Crypto.encryptingFunctions.currentVersion, 'retrieveRecordDetailFunction': MochiKit.Base.method(this, 'getRecordDetail') }), 'preferences': new Clipperz.PM.DataModel.User.Header.Preferences({ 'name': 'preferences', 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase') }), 'oneTimePasswords': new Clipperz.PM.DataModel.User.Header.OneTimePasswords({ 'name': 'preferences', 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase') }) } }; // this._serverLockValue = Clipperz.PM.Crypto.randomKey(); }, //......................................................................... 'registerAsNewAccount': function () { 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.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; }, //------------------------------------------------------------------------- 'login': function () { var deferredResult; deferredResult = new Clipperz.Async.Deferred("User.login", {trace:false}); deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'updateProgress', {'extraSteps':3}); deferredResult.addMethod(this, 'getPassphrase'); deferredResult.addCallback(Clipperz.PM.DataModel.OneTimePassword.isValidOneTimePasswordValue); deferredResult.addCallback(Clipperz.Async.deferredIf("Is the passphrase an OTP", [ MochiKit.Base.partial(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'updateProgress', {'extraSteps':1}), MochiKit.Base.method(this, 'getCredentials'), MochiKit.Base.method(this.connection(), 'redeemOneTimePassword'), MochiKit.Base.method(this.data(), 'setValue', 'passphrase') ], [])); deferredResult.addErrback(MochiKit.Base.method(this, 'getPassphrase')); - deferredResult.addMethod(this.connection(), 'login'); + deferredResult.addMethod(this.connection(), 'login', false); deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'userSuccessfullyLoggedIn'); deferredResult.addErrback (MochiKit.Base.method(this, 'handleConnectionFallback')); deferredResult.callback(); return deferredResult; }, //......................................................................... 'handleConnectionFallback': function(aValue) { var result; if (aValue instanceof MochiKit.Async.CancelledError) { result = aValue; } else { this.setConnectionVersion(Clipperz.PM.Connection.communicationProtocol.fallbackVersions[this.connectionVersion()]); if (this.connectionVersion() != null) { result = new Clipperz.Async.Deferred("User.handleConnectionFallback - retry"); result.addMethod(this, 'login'); result.callback(); } else { 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) ], {trace:false}); } } return result; }, //------------------------------------------------------------------------- 'lock': function () { return Clipperz.Async.callbacks("User.lock", [ MochiKit.Base.method(this, 'deleteAllCleanTextData') ], {trace:false}); }, //------------------------------------------------------------------------- 'logout': function () { return Clipperz.Async.callbacks("User.logout", [ MochiKit.Base.method(this, 'deleteAllCleanTextData'), MochiKit.Base.method(this.connection(), 'logout') ], {trace:false}); }, //------------------------------------------------------------------------- 'headerFormatVersion': function(anHeader) { var result; if (anHeader.charAt(0) == '{') { var headerData; headerData = Clipperz.Base.evalJSON(anHeader); result = headerData['version']; } else { result = 'LEGACY'; } return result; }, //------------------------------------------------------------------------- 'unpackServerData': function (someServerData) { var unpackedData; var headerVersion; var recordsIndex; var preferences; var oneTimePasswords; //console.log(">>> ***************** user.unpackServerData", someServerData); - this.setServerLockValue(someServerData['lock']); +// this.setServerLockValue(someServerData['lock']); headerVersion = this.headerFormatVersion(someServerData['header']); switch (headerVersion) { case 'LEGACY': var legacyHeader; legacyHeader = new Clipperz.PM.DataModel.User.Header.Legacy({ 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase'), 'remoteData': { 'data': someServerData['header'], 'version': someServerData['version'], 'recordsStats': someServerData['recordsStats'] }, // 'encryptedDataKeypath': 'data', // 'encryptedVersionKeypath': 'version', 'retrieveRecordDetailFunction': MochiKit.Base.method(this, 'getRecordDetail') }); recordsIndex = legacyHeader; preferences = legacyHeader; oneTimePasswords = legacyHeader; break; case '0.1': var headerData; headerData = Clipperz.Base.evalJSON(someServerData['header']); recordsIndex = new Clipperz.PM.DataModel.User.Header.RecordIndex({ 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase'), 'recordsData': headerData['records'], 'recordsStats': someServerData['recordsStats'], 'directLoginsData': headerData['directLogins'], 'encryptedDataVersion': someServerData['version'], 'retrieveRecordDetailFunction': MochiKit.Base.method(this, 'getRecordDetail') }); // Still missing a test case that actually fais with the old version of the code, where the check for undefined was missing if (typeof(headerData['preferences']) != 'undefined') { preferences = new Clipperz.PM.DataModel.User.Header.Preferences({ 'name': 'preferences', 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase'), 'remoteData': { 'data': headerData['preferences']['data'], 'version': someServerData['version'] } }); } else { @@ -617,175 +617,175 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User, Object, { ]//, // 'statistics': [ // MochiKit.Base.method(this, 'getStatistics'), // MochiKit.Base.methodcaller(aMethodName, aValue) // ] }, {trace:false})(); }, //------------------------------------------------------------------------- 'invokeMethodNamedOnRecords': function (aMethodName, aValue) { return Clipperz.Async.callbacks("User.invokeMethodNamedOnRecords[" + aMethodName + "]", [ MochiKit.Base.method(this, 'getRecords'), MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.methodcaller(aMethodName, aValue)), Clipperz.Async.collectAll ], {trace:false}); }, //========================================================================= 'hasPendingChanges': function () { var deferredResult; deferredResult = new Clipperz.Async.Deferred("User.hasPendingChanges", {trace:false}); deferredResult.collectResults({ 'header': [ MochiKit.Base.method(this, 'invokeMethodNamedOnHeader', 'hasPendingChanges'), MochiKit.Base.values ], 'records': MochiKit.Base.method(this, 'invokeMethodNamedOnRecords', 'hasPendingChanges') }); deferredResult.addCallback(Clipperz.Async.or); deferredResult.callback(); // recordsIndex = legacyHeader; // preferences = legacyHeader; // oneTimePasswords = legacyHeader; return deferredResult; }, //========================================================================= 'commitTransientState': function () { return Clipperz.Async.callbacks("User.commitTransientState", [ MochiKit.Base.method(this, 'invokeMethodNamedOnHeader', 'commitTransientState'), MochiKit.Base.method(this, 'invokeMethodNamedOnRecords', 'commitTransientState'), MochiKit.Base.method(this, 'transientState'), - MochiKit.Base.itemgetter('lock'), - MochiKit.Base.method(this, 'setServerLockValue'), +// MochiKit.Base.itemgetter('lock'), +// MochiKit.Base.method(this, 'setServerLockValue'), MochiKit.Base.method(this, 'resetTransientState', true) ], {trace:false}); }, //------------------------------------------------------------------------- 'revertChanges': function () { return Clipperz.Async.callbacks("User.revertChanges", [ MochiKit.Base.method(this, 'invokeMethodNamedOnHeader', 'revertChanges'), MochiKit.Base.method(this, 'invokeMethodNamedOnRecords', 'revertChanges'), MochiKit.Base.method(this, 'resetTransientState', false) ], {trace:false}); }, //========================================================================= 'deleteAllCleanTextData': function () { return Clipperz.Async.callbacks("User.deleteAllCleanTextData", [ MochiKit.Base.method(this, 'invokeMethodNamedOnRecords', 'deleteAllCleanTextData'), MochiKit.Base.method(this, 'invokeMethodNamedOnHeader', 'deleteAllCleanTextData'), MochiKit.Base.method(this.data(), 'removeAllData'), MochiKit.Base.method(this, 'resetTransientState', false) ], {trace:false}); }, //------------------------------------------------------------------------- 'hasAnyCleanTextData': function () { var deferredResult; deferredResult = new Clipperz.Async.Deferred("User.hasAnyCleanTextData", {trace:false}); deferredResult.collectResults({ 'header': [ MochiKit.Base.method(this, 'invokeMethodNamedOnHeader', 'hasAnyCleanTextData'), MochiKit.Base.values ], 'records': MochiKit.Base.method(this, 'invokeMethodNamedOnRecords', 'hasAnyCleanTextData'), 'data': MochiKit.Base.bind(function () { return MochiKit.Async.succeed(! this.data().isEmpty()); }, this), 'transientState': MochiKit.Base.bind(function () { return MochiKit.Async.succeed(MochiKit.Base.keys(this.transientState()).length != 0); }, this) }); deferredResult.addCallback(Clipperz.Async.or); deferredResult.callback(); return deferredResult; }, //========================================================================= 'prepareRemoteDataWithKey': function (aKey /*, aCurrentKey*/) { var deferredResult; var result; result = {}; deferredResult = new Clipperz.Async.Deferred("User.prepareRemoteDataWithKey", {trace:false}); deferredResult.addMethod(this, 'invokeMethodNamedOnHeader', 'prepareRemoteDataWithKey', aKey /*, aCurrentKey*/); deferredResult.addCallback(MochiKit.Base.bind(function (aResult, someHeaderPackedData) { var header; header = {}; header['records'] = someHeaderPackedData['recordIndex']['records']; header['directLogins'] = someHeaderPackedData['recordIndex']['directLogins']; header['preferences'] = {'data': someHeaderPackedData['preferences']['data']}; // this._serverData['header']['preferences']; // Clipperz.Base.evalJSON(this._serverData['header']['data'])['preferences']; // ??????????? header['oneTimePasswords'] = {'data': someHeaderPackedData['oneTimePasswords']['data']}; // this._serverData['header']['oneTimePasswords']; // Clipperz.Base.evalJSON(this._serverData['header']['data'])['oneTimePasswords']; // ??????????? header['version'] = '0.1'; aResult['header'] = Clipperz.Base.serializeJSON(header); aResult['statistics'] = this._serverData['statistics']; // "someHeaderPackedData['statistics']['data']"; return aResult; }, this), result); deferredResult.addCallback(Clipperz.Async.setItem, result, 'version', Clipperz.PM.Crypto.encryptingFunctions.currentVersion); - deferredResult.addCallback(Clipperz.Async.setItem, result, 'lock', this.serverLockValue()); +// deferredResult.addCallback(Clipperz.Async.setItem, result, 'lock', this.serverLockValue()); deferredResult.callback(); return deferredResult; }, //========================================================================= 'saveChanges': function () { var deferredResult; var messageParameters; messageParameters = {}; deferredResult = new Clipperz.Async.Deferred("User.saveChangaes", {trace:false}); 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(); return deferredResult; }, //========================================================================= __syntaxFix__: "syntax fix" }); //----------------------------------------------------------------------------- diff --git a/frontend/gamma/js/Clipperz/PM/PIN.js b/frontend/gamma/js/Clipperz/PM/PIN.js new file mode 100644 index 0000000..bc932b2 --- a/dev/null +++ b/frontend/gamma/js/Clipperz/PM/PIN.js @@ -0,0 +1,134 @@ +/* + +Copyright 2008-2011 Clipperz Srl + +This file is part of Clipperz Community Edition. +Clipperz Community Edition is an online password manager. +For further information about its features and functionalities please +refer to http://www.clipperz.com. + +* Clipperz Community Edition 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. + +* Clipperz Community Edition 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 Clipperz Community Edition. If not, see + <http://www.gnu.org/licenses/>. + +*/ + +if (typeof(Clipperz) == 'undefined') { Clipperz = {}; } +if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; } +if (typeof(Clipperz.PM.PIN) == 'undefined') { Clipperz.PM.PIN = {}; } + +MochiKit.Base.update(Clipperz.PM.PIN, { + + //------------------------------------------------------------------------- + + '__repr__': function () { + return "[" + this.NAME + " " + this.VERSION + "]"; + }, + + //------------------------------------------------------------------------- + + 'toString': function () { + return this.__repr__(); + }, + + 'CREDENTIALS': 'CLIPPERZ.CREDENTIALS', + 'FAILURE_COUNT': 'CLIPPERZ.FAILED_LOGIN_COUNT', + 'ALLOWED_RETRY': 3, + + //------------------------------------------------------------------------- + + 'isSet': function () { + return (this.storedCredentials() != null); + }, + + 'storedCredentials': function () { + return localStorage[this.CREDENTIALS]; + }, + + //------------------------------------------------------------------------- + + 'recordFailedAttempt': function () { + var failureCount; + var result; + + failureCount = localStorage[this.FAILURE_COUNT]; + + if (failureCount == null) { + failureCount = 0 + } + + failureCount ++; + + if (failureCount < this.ALLOWED_RETRY) { + localStorage[this.FAILURE_COUNT] = failureCount; + result = failureCount; + } else { + this.removeLocalCredentials(); + result = -1; + } + + return result; + }, + + 'resetFailedAttemptCount': function () { + localStorage.removeItem(this.FAILURE_COUNT); + }, + + 'failureCount': function () { + return localStorage[this.FAILURE_COUNT]; + }, + + //------------------------------------------------------------------------- + + 'deriveKeyFromPin': function (aPIN) { + return Clipperz.Crypto.SHA.sha256(new Clipperz.ByteArray(aPIN)); + }, + + 'credentialsWithPIN': function (aPIN) { + var byteArrayValue; + var decryptedValue; + var result; + + byteArrayValue = (new Clipperz.ByteArray()).appendBase64String(localStorage[this.CREDENTIALS]); + decryptedValue = Clipperz.Crypto.AES.decrypt(this.deriveKeyFromPin(aPIN), byteArrayValue).asString(); + try { + result = Clipperz.Base.evalJSON(decryptedValue); + } catch (error) { + result = {'username':'fakeusername', 'passphrase':'fakepassphrase'}; + } + + return result; + }, + + 'setCredentialsWithPIN': function (aPIN, someCredentials) { + var encodedValue; + var byteArrayValue; + var encryptedValue; + + encodedValue = Clipperz.Base.serializeJSON(someCredentials); + byteArrayValue = new Clipperz.ByteArray(encodedValue); + encryptedValue = Clipperz.Crypto.AES.encrypt(this.deriveKeyFromPin(aPIN), byteArrayValue).toBase64String(); + + localStorage[this.CREDENTIALS] = encryptedValue; + }, + + 'removeLocalCredentials': function () { + localStorage.removeItem(this.CREDENTIALS); + localStorage.removeItem(this.FAILURE_COUNT); + }, + + //------------------------------------------------------------------------- + __syntaxFix__: "syntax fix" + +}); + diff --git a/frontend/gamma/js/Clipperz/PM/Proxy/Proxy.OfflineCache.js b/frontend/gamma/js/Clipperz/PM/Proxy/Proxy.OfflineCache.js new file mode 100644 index 0000000..803c590 --- a/dev/null +++ b/frontend/gamma/js/Clipperz/PM/Proxy/Proxy.OfflineCache.js @@ -0,0 +1,65 @@ +/* + +Copyright 2008-2011 Clipperz Srl + +This file is part of Clipperz Community Edition. +Clipperz Community Edition is an online password manager. +For further information about its features and functionalities please +refer to http://www.clipperz.com. + +* Clipperz Community Edition 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. + +* Clipperz Community Edition 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 Clipperz Community Edition. If not, see + <http://www.gnu.org/licenses/>. + +*/ + +if (typeof(Clipperz) == 'undefined') { Clipperz = {}; } +if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; } + +//============================================================================= + +Clipperz.PM.Proxy.OfflineCache = function(args) { + args = args || {}; + + Clipperz.PM.Proxy.Offline.superclass.constructor.call(this, args); + +// this._dataStore = args.dataStore || new Clipperz.PM.Proxy.Offline.DataStore(args); + + return this; +} + +Clipperz.Base.extend(Clipperz.PM.Proxy.OfflineCache, Clipperz.PM.Proxy, { + + 'toString': function () { + return "Clipperz.PM.Proxy.OfflineCache"; + }, + + //------------------------------------------------------------------------- + +// 'dataStore': function () { +// return this._dataStore; +// }, + + //------------------------------------------------------------------------- + + 'sendMessage': function(aFunctionName, someParameters) { + throw Clipperz.Base.exception.MethodNotImplementedYet; +// return this.dataStore().processMessage(aFunctionName, someParameters); + }, + + //------------------------------------------------------------------------- + + __syntaxFix__: "syntax fix" + +}); + diff --git a/frontend/gamma/js/Clipperz/PM/UI/Common/Components/BaseComponent.js b/frontend/gamma/js/Clipperz/PM/UI/Common/Components/BaseComponent.js index 2a03fdf..b9d7adf 100644 --- a/frontend/gamma/js/Clipperz/PM/UI/Common/Components/BaseComponent.js +++ b/frontend/gamma/js/Clipperz/PM/UI/Common/Components/BaseComponent.js @@ -361,96 +361,100 @@ Clipperz.Base.extend(Clipperz.PM.UI.Common.Components.BaseComponent, /*Ext.Compo for (slotName in this.slotComponents()) { this.slotComponents()[slotName].remove(); delete this.slotComponents()[slotName]; } for (componentId in this.components()) { this.components()[componentId].remove(); delete this.components()[componentId]; } this.clear(); MochiKit.Signal.disconnectAll(this); }, 'append': function(aNode, aValue) { return Clipperz.DOM.Helper.append(aNode, aValue); }, 'insertBefore': function (aNode, aValue) { return Clipperz.DOM.Helper.insertBefore(aNode, aValue); }, 'insertAfter': function (aNode, aValue) { return Clipperz.DOM.Helper.insertAfter(aNode, aValue); }, //------------------------------------------------------------------------- 'getId': function(aValue) { var result; if (typeof(aValue) != 'undefined') { result = this._ids[aValue]; if (typeof(result) == 'undefined') { _Clipperz_PM_Components_base_id_ ++; result = "Clipperz_PM_Components_" + aValue + "_" + _Clipperz_PM_Components_base_id_; this._ids[aValue] = result; } } else { // result = Clipperz.PM.UI.Common.Components.BaseComponent.superclass.getId.call(this); throw "call to BaseComponent.getId with an undefined value"; } return result; }, + 'getAnchor': function (aValue) { + return '#' + this.getId(aValue); + }, + //------------------------------------------------------------------------- 'getElement': function(aValue) { return Clipperz.DOM.get(this.getId(aValue)); }, //------------------------------------------------------------------------- 'hideElement': function(anElementName) { MochiKit.Style.hideElement(this.getElement(anElementName)); }, 'showElement': function(anElementName) { MochiKit.Style.showElement(this.getElement(anElementName)); }, //------------------------------------------------------------------------- 'activate': function () { this._isActive = true; }, 'deactivate': function () { this._isActive = false; }, 'isActive': function () { return this._isActive; }, //------------------------------------------------------------------------- 'hideSlot': function(aSlotName) { if (this.componentForSlotNamed(aSlotName)) { this.componentForSlotNamed(aSlotName).deactivate(); } MochiKit.Style.hideElement(this.elementForSlotNamed(aSlotName)); }, 'showSlot': function(aSlotName) { if (this.componentForSlotNamed(aSlotName)) { this.componentForSlotNamed(aSlotName).activate(); } MochiKit.Style.showElement(this.elementForSlotNamed(aSlotName)); }, //------------------------------------------------------------------------- diff --git a/frontend/gamma/js/Clipperz/PM/UI/Common/Components/Button.js b/frontend/gamma/js/Clipperz/PM/UI/Common/Components/Button.js index 716d851..1010c9d 100644 --- a/frontend/gamma/js/Clipperz/PM/UI/Common/Components/Button.js +++ b/frontend/gamma/js/Clipperz/PM/UI/Common/Components/Button.js @@ -17,89 +17,97 @@ refer to http://www.clipperz.com. 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 Clipperz Community Edition. If not, see <http://www.gnu.org/licenses/>. */ Clipperz.Base.module('Clipperz.PM.UI.Common.Components'); Clipperz.PM.UI.Common.Components.Button = function(args) { args = args || {}; Clipperz.PM.UI.Common.Components.Button.superclass.constructor.apply(this, arguments); this._element = args.element || Clipperz.Base.exception.raise('MandatoryParameter'); this._text = args.text || Clipperz.Base.exception.raise('MandatoryParameter'); this._isDefault = args.isDefault || false; this.render(); return this; } //============================================================================= Clipperz.Base.extend(Clipperz.PM.UI.Common.Components.Button, Clipperz.PM.UI.Common.Components.BaseComponent, { //------------------------------------------------------------------------- 'toString': function () { return "Clipperz.PM.UI.Common.Components.Button component"; }, //------------------------------------------------------------------------- 'text': function () { return this._text; }, 'isDefault': function () { return this._isDefault; }, //------------------------------------------------------------------------- 'renderSelf': function () { - this.append(this.element(), {tag:'div', id:this.getId('wrapper'), cls:'button_wrapper', children:[ +/* + this.append(this.element(), {tag:'div', id:this.getId('button'), cls:'button_wrapper', children:[ {tag:'div', id:this.getId('bodyWrapper'), cls:'button_bodyWrapper', children:[ {tag:'div', id:this.getId('body'), cls:'button_body', children:[ {tag:'span', html:this.text()} ]}, {tag:'div', id:this.getId('footer'), cls:'button_footer'} ]} ]}); +*/ +/* + this.append(this.element(), {tag:'div', id:this.getId('button'), cls:'button', children:[ + {tag:'span', html:this.text()} + ]}); +*/ + this.append(this.element(), {tag:'a', id:this.getId('button'), cls:'button', html:this.text()}); if (this.isDefault()) { - MochiKit.DOM.addElementClass(this.getId('wrapper'), 'default'); + MochiKit.DOM.addElementClass(this.getId('button'), 'default'); } - MochiKit.Signal.connect(this.getId('wrapper'), 'onmouseenter', this, 'handleOnMouseEnter'); - MochiKit.Signal.connect(this.getId('wrapper'), 'onmouseleave', this, 'handleOnMouseLeave'); - MochiKit.Signal.connect(this.getId('wrapper'), 'onmousedown', this, 'handleOnMouseDown'); - MochiKit.Signal.connect(this.getId('wrapper'), 'onclick', this, 'handleOnClick'); +// MochiKit.Signal.connect(this.getId('button'), 'onmouseenter', this, 'handleOnMouseEnter'); +// MochiKit.Signal.connect(this.getId('button'), 'onmouseleave', this, 'handleOnMouseLeave'); +// MochiKit.Signal.connect(this.getId('button'), 'onmousedown', this, 'handleOnMouseDown'); + MochiKit.Signal.connect(this.getId('button'), 'onclick', this, 'handleOnClick'); }, //------------------------------------------------------------------------- - +/* 'handleOnMouseEnter': function (anEvent) { - MochiKit.DOM.addElementClass(this.getId('wrapper'), 'hover'); + MochiKit.DOM.addElementClass(this.getId('button'), 'hover'); }, 'handleOnMouseLeave': function (anEvent) { - MochiKit.DOM.removeElementClass(this.getId('wrapper'), 'hover'); - MochiKit.DOM.removeElementClass(this.getId('wrapper'), 'clicked'); + MochiKit.DOM.removeElementClass(this.getId('button'), 'hover'); + MochiKit.DOM.removeElementClass(this.getId('button'), 'clicked'); }, 'handleOnMouseDown': function (anEvent) { - MochiKit.DOM.addElementClass(this.getId('wrapper'), 'clicked'); + MochiKit.DOM.addElementClass(this.getId('button'), 'clicked'); }, - +*/ 'handleOnClick': function (anEvent) { MochiKit.Signal.signal(this, 'onclick', anEvent); }, - + //------------------------------------------------------------------------- __syntaxFix__: "syntax fix" }); diff --git a/frontend/gamma/js/Clipperz/PM/UI/Common/Components/SimpleMessagePanel.js b/frontend/gamma/js/Clipperz/PM/UI/Common/Components/SimpleMessagePanel.js index 1992154..1d816a9 100644 --- a/frontend/gamma/js/Clipperz/PM/UI/Common/Components/SimpleMessagePanel.js +++ b/frontend/gamma/js/Clipperz/PM/UI/Common/Components/SimpleMessagePanel.js @@ -53,141 +53,159 @@ Clipperz.Base.extend(Clipperz.PM.UI.Common.Components.SimpleMessagePanel, Clippe return "Clipperz.PM.UI.Common.Components.SimpleMessagePanel component"; }, //------------------------------------------------------------------------- 'deferred': function() { if (this._deferred == null) { this._deferred = new Clipperz.Async.Deferred("SimpleMessagePanel.deferred", {trace:false}); } return this._deferred; }, //------------------------------------------------------------------------- 'title': function () { return this._title; }, 'setTitle': function (aValue) { this._title = aValue; if (this.getElement('title') != null) { this.getElement('title').innerHTML = aValue; } }, //------------------------------------------------------------------------- 'text': function () { return this._text; }, 'setText': function (aValue) { this._text = aValue; if (this.getElement('text') != null) { this.getElement('text').innerHTML = aValue; } }, //------------------------------------------------------------------------- 'type': function () { return this._type; }, 'setType': function (aValue) { - if (this.getElement('icon') != null) { - MochiKit.DOM.removeElementClass(this.getId('icon'), this._type); - MochiKit.DOM.addElementClass(this.getId('icon'), aValue); - } +// if (this.getElement('icon') != null) { +// MochiKit.DOM.removeElementClass(this.getId('icon'), this._type); +// MochiKit.DOM.addElementClass(this.getId('icon'), aValue); +// } this._type = aValue; }, + 'icon': function () { + var type = this.type(); + var result; + + if (type == 'ALERT') { + result = '!'; + } else if (type == 'INFO') { + result = 'i'; + } else if (type == 'ERROR') { + result = '!'; + } + + return result; + }, + //------------------------------------------------------------------------- 'buttons': function () { return this._buttons; }, 'setButtons': function (someValues) { MochiKit.Iter.forEach(this.buttonComponents(), MochiKit.Base.methodcaller('clear')); this._buttons = someValues; if (this.getElement('buttonArea') != null) { this.renderButtons(); } }, //......................................................................... 'buttonComponents': function () { return this._buttonComponents; }, //------------------------------------------------------------------------- 'renderSelf': function() { this.append(this.element(), {tag:'div', cls:'SimpleMessagePanel', id:this.getId('panel'), children: [ - {tag:'div', cls:'header', children:[]}, +// {tag:'div', cls:'header', children:[]}, {tag:'div', cls:'body', children:[ - {tag:'div', id:this.getId('icon'), cls:'img ' + this.type(), children:[{tag:'div'}]}, +// {tag:'div', id:this.getId('icon'), cls:'img ' + this.type(), children:[{tag:'div'}]}, + {tag:'div', /*id:this.getId('icon'),*/ cls:'img ' + this.type(), children:[{tag:'canvas', id:this.getId('icon')}]}, {tag:'h3', id:this.getId('title'), html:this.title()}, {tag:'p', id:this.getId('text'), html:this.text()}, {tag:'div', id:this.getId('container')}, {tag:'div', id:this.getId('buttonArea'), cls:'buttonArea', children:[]} - ]}, - {tag:'div', cls:'footer', children:[]} + ]} +// {tag:'div', cls:'footer', children:[]} ]}); + Clipperz.PM.UI.Canvas.marks[this.icon()](this.getElement('icon'), "#ffffff"); + MochiKit.Signal.connect(this.getId('panel'), 'onkeydown', this, 'keyDownHandler'); this.renderButtons(); }, //------------------------------------------------------------------------- 'renderButtons': function () { this.getElement('buttonArea').innerHTML = ''; MochiKit.Base.map(MochiKit.Base.bind(function (aButton) { var buttonElement; var buttonComponent; // element = this.append(this.getElement('buttonArea'), {tag:'div', cls:'button' + (aButton['isDefault'] === true ? ' default' : ''), children:[ // {tag:'a', href:'#'/*, id:this.getId('buttonLink')*/, html:aButton['text']} // ]}); buttonElement = this.append(this.getElement('buttonArea'), {tag:'div'}); buttonComponent = new Clipperz.PM.UI.Common.Components.Button({'element':buttonElement, 'text':aButton['text'], 'isDefault':aButton['isDefault']}); this.buttonComponents().push(buttonComponent); MochiKit.Signal.connect(buttonComponent, 'onclick', MochiKit.Base.method(this, 'buttonEventHandler', aButton)); }, this), MochiKit.Iter.reversed(this.buttons())); }, //------------------------------------------------------------------------- 'displayElement': function() { return this.getElement('panel'); }, //------------------------------------------------------------------------- 'closeOk': function () { this.deferred().callback(); this._deferred = null; }, 'closeCancel': function () { this.deferred().cancel(); this._deferred = null; }, 'closeError': function () { this.deferred().errback(); this._deferred = null; }, diff --git a/frontend/gamma/js/Clipperz/PM/UI/Mobile/Components/CardDetail.js b/frontend/gamma/js/Clipperz/PM/UI/Mobile/Components/CardDetail.js new file mode 100644 index 0000000..32dfa63 --- a/dev/null +++ b/frontend/gamma/js/Clipperz/PM/UI/Mobile/Components/CardDetail.js @@ -0,0 +1,299 @@ +/* + +Copyright 2008-2011 Clipperz Srl + +This file is part of Clipperz Community Edition. +Clipperz Community Edition is an online password manager. +For further information about its features and functionalities please +refer to http://www.clipperz.com. + +* Clipperz Community Edition 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. + +* Clipperz Community Edition 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 Clipperz Community Edition. If not, see + <http://www.gnu.org/licenses/>. + +*/ + +Clipperz.Base.module('Clipperz.PM.UI.Mobile.Components'); + +Clipperz.PM.UI.Mobile.Components.CardDetail = function(args) { + args = args || {}; + + Clipperz.PM.UI.Mobile.Components.CardDetail.superclass.constructor.apply(this, arguments); + +// this._cardReference = null; + + return this; +} + +//============================================================================= + +Clipperz.Base.extend(Clipperz.PM.UI.Mobile.Components.CardDetail, Clipperz.PM.UI.Common.Components.BaseComponent, { + + //------------------------------------------------------------------------- + + 'toString': function () { + return "Clipperz.PM.UI.Mobile.Components.CardDetail component"; + }, + + //------------------------------------------------------------------------- +/* + 'cardReference': function () { + return this._cardReference; + }, + + 'setCardReference': function (aValue) { + this._cardReference = aValue; + }, +*/ + //------------------------------------------------------------------------- + + 'renderSelf': function () { +console.log("CardDetail.renderSelf"); + this.append(this.element(), {tag:'div', cls:'cardDetail', children:[ + {tag:'div', cls:'toolbar', children:[ + {tag:'a', href:'#', cls:'back', html:"List"}, + {tag:'h1', id:this.getId('cardTitle'), html:"…"} + ]}, + {tag:'div', cls:'scroll', id:this.getId('cardDetails'), children:[ + ]} + ]}); + }, +/* + 'renderSelf': function() { + this.append(this.element(), [ + {tag:'div', cls:'cardDetail', id:this.getId('cardDetail'), children:[ + {tag:'div', id:this.getId('progressBar')} //, + ]} + ]); + + this.addComponent(new Clipperz.PM.UI.Common.Components.ProgressBar({'element':this.getElement('progressBar')})); + MochiKit.Signal.signal(Clipperz.PM.UI.Common.Controllers.ProgressBarController.defaultController, 'updateProgress', 0); + }, +*/ + + 'setTitle': function (aValue) { + this.getElement('cardTitle').innerHTML = aValue; + }, + + 'fieldListElement': function () { + var result; + + result = this.getElement('fieldList'); + if (result == null) { + result = this.append(this.getElement('cardDetails'), {tag:'ul', cls:'rounded', id:this.getId('fieldList')}); + } + + return result; + }, + + 'renderFieldValues': function (someFieldValues) { + var fieldClass; + + if ((someFieldValues['actionType'] != 'NONE') || (someFieldValues['label'] != '') && (someFieldValues['value'] != '')) { + if (someFieldValues['isHidden'] == true) { + fieldClass = 'password'; + } else { + fieldClass = ''; + } + + this.append(this.fieldListElement(), {tag:'li', cls:'cardField', children:[ + {tag:'a', href:'#', cls:fieldClass, html:someFieldValues['value'], children:[ + {tag:'small', cls:'label', html:someFieldValues['label']} + ]} + ]}) + } + }, + + 'addField': function (aField) { + var deferredResult; + var fieldValues; + + fieldValues = {}; + deferredResult = new Clipperz.Async.Deferred("CardDetail.addField", {trace:false}); + deferredResult.addMethod(aField, 'label'); + deferredResult.addCallback(function (aValue) { fieldValues['label'] = aValue; }); + deferredResult.addMethod(aField, 'value'); + deferredResult.addCallback(function (aValue) { fieldValues['value'] = aValue; }); + deferredResult.addMethod(aField, 'actionType'); + deferredResult.addCallback(function (aValue) { fieldValues['actionType'] = aValue; }); + deferredResult.addMethod(aField, 'isHidden'); + deferredResult.addCallback(function (aValue) { fieldValues['isHidden'] = aValue; }); + deferredResult.addMethod(this, 'renderFieldValues', fieldValues); + deferredResult.callback(); + + return deferredResult; + }, + + //------------------------------------------------------------------------- + + 'directLoginElement': function () { + var result; + + result = this.getElement('directLoginList'); + if (result == null) { + this.append(this.getElement('cardDetails'), {tag:'h2', html:"Direct login"}); + result = this.append(this.getElement('cardDetails'), {tag:'ul', cls:'rounded', id:this.getId('directLoginList')}); + } + + return result; + }, + + 'addDirectLogin': function (aDirectLogin) { + this.append(this.directLoginElement(), {tag:'li', cls:'directLogin forward', children:[ + {tag:'a', href:'#', html:"direct login", children:[ + {tag:'small', cls:'favicon', children:[{tag:'img', cls:'favicon', src:'http://www.clipperz.com/favicon.ico'}]} + ]} + ]}) + +console.log("ADD DIRECT LOGIN", aDirectLogin); + }, + + //========================================================================= + + 'showCard': function (aCard) { + var deferredResult; + +// this.render(); + +console.log("CardDetail.showCard", aCard); + deferredResult = new Clipperz.Async.Deferred("CardDetail.showCard", {trace:false}); + deferredResult.addMethod(aCard, 'label'); + deferredResult.addMethod(this, 'setTitle'); + + deferredResult.addMethod(aCard, 'fields'); + deferredResult.addCallback(MochiKit.Base.values); + deferredResult.addCallback(MochiKit.Base.map, MochiKit.Base.method(this, 'addField')); + + deferredResult.addMethod(aCard, 'directLogins'); + deferredResult.addCallback(MochiKit.Base.values); + deferredResult.addCallback(MochiKit.Base.map, MochiKit.Base.method(this, 'addDirectLogin')); + + + deferredResult.callback(); + + return deferredResult; +// return Clipperz.Async.callbacks("CardDialogController.updateComponentState", [ +// MochiKit.Base.method(this.record(), 'hasPendingChanges'), +// MochiKit.Base.method(this.cardDialogComponent(), 'setShouldEnableSaving'), +// +// MochiKit.Base.method(this.record(), 'label'), +// MochiKit.Base.method(this.cardDialogComponent(), 'setTitle'), +// MochiKit.Base.method(this.record(), 'notes'), +// MochiKit.Base.method(this.cardDialogComponent(), 'setNotes'), +// +// MochiKit.Base.method(this.record(), 'fields'), +// MochiKit.Base.values, +// MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.method(this, 'addCardDialogComponentWithField')), +// +// MochiKit.Base.method(this.record(), 'directLogins'), +// MochiKit.Base.values, +// MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.method(this, 'addCardDialogComponentWithDirectLogin')), +// +// MochiKit.Base.method(this.cardDialogComponent(), 'resetNewFieldInputs'), +// MochiKit.Base.noop +// ], {trace:false}); + + }, + + //========================================================================= + + 'showCardDetails': function (someData) { + this.element().innerHTML = ''; + this.append(this.element(), [ + {tag:'fieldset', id:this.getId('fields'), children:MochiKit.Base.map(function (aFieldData) { + return {tag:'div', cls:'row', children:[ + {tag:'label', html:aFieldData['label']}, +// {tag:'span', cls:('fieldValue ' + (aFieldData['isHidden'] ? 'password' : 'text')), html:aFieldData['value']} + {tag:'div', cls:('fieldValue ' + (aFieldData['isHidden'] ? 'password' : 'text')), children:[ + {tag:'div', children:[{tag:'p', html:aFieldData['value']}]} + ]} +// {tag:'input', type:'text', cls:('fieldValue ' + (aFieldData['isHidden'] ? 'password' : 'text')), value:aFieldData['value'], disabled:true} + + ]} + }, someData['fields'])} + ]); + + MochiKit.Iter.forEach(MochiKit.Selector.findChildElements(this.element(), ['span.password']), MochiKit.Base.bind(function (aPasswordElement) { + MochiKit.Signal.connect(aPasswordElement, 'onclick', function (anEvent) { alert(MochiKit.DOM.scrapeText(anEvent.src())); }) + }, this)); + + if (someData['directLogins'].length > 0) { + this.append(this.element(), [ + {tag:'h2', html:"Direct logins"}, + {tag:'fieldset', id:this.getId('directLogins'), children:MochiKit.Base.map(function (aDirectLoginData) { + return {tag:'div', cls:'row', id:('directLogin_' + aDirectLoginData['_reference']), children:[ + {tag:'img', cls:'favicon', src:aDirectLoginData['favicon']}, +// {tag:'input', cls:'directLogin', disabled:'disabled', type:'text', name:aDirectLoginData['label'], value:aDirectLoginData['label']} + {tag:'span', cls:'directLogin', html:aDirectLoginData['label']} + ]} + }, someData['directLogins'])} + ]); + + MochiKit.Base.map(MochiKit.Base.bind(function (aRowNode) { + MochiKit.Signal.connect(aRowNode, 'onclick', this, 'directLoginClickHandler'); + }, this), + MochiKit.Selector.findChildElements(this.getElement('directLogins'), ['div.row']) + ) + }; + + if (someData['notes'] != '') { + this.append(this.element(), [ + {tag:'h2', html:"Notes"}, + {tag:'fieldset', id:this.getId('fieldset'), children:[ + {tag:'div', cls:'row notes', children:[ + {tag:'span', html:someData['notes']} + ]} + ]} + ]); + }; + + return true; + }, + + //------------------------------------------------------------------------- +/* + 'toggleClickHandler': function (anEvent) { + var nextState; + var fieldValue; + +//console.log("TOGGLE"); + anEvent.preventDefault; + fieldValue = MochiKit.Selector.findChildElements(anEvent.src().parentNode.parentNode, ['span.password'])[0]; + + nextState = (MochiKit.DOM.getNodeAttribute(anEvent.src(), 'toggled') != 'true'); + if (nextState) { + MochiKit.DOM.removeElementClass(fieldValue, 'clear'); + } else { + MochiKit.DOM.addElementClass(fieldValue, 'clear'); + } + + MochiKit.DOM.setNodeAttribute(anEvent.src(), 'toggled', nextState); + }, +* / + //========================================================================= +/* + 'directLoginClickHandler': function (anEvent) { + anEvent.preventDefault(); + + if (/(directLogin_)/.test(anEvent.src().id)) { + var directLoginReference; + + directLoginReference = anEvent.src().id.match(/(directLogin_)(.*)/)[2]; + MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'selectedDirectLogin', {cardReference:this.cardReference(), directLoginReference:directLoginReference}); + } + }, +*/ + //========================================================================= + + __syntaxFix__: "syntax fix" +}); diff --git a/frontend/gamma/js/Clipperz/PM/UI/iPhone/Components/CardList.js b/frontend/gamma/js/Clipperz/PM/UI/Mobile/Components/CardList.js index c3f2701..a4aa212 100644 --- a/frontend/gamma/js/Clipperz/PM/UI/iPhone/Components/CardList.js +++ b/frontend/gamma/js/Clipperz/PM/UI/Mobile/Components/CardList.js @@ -1,201 +1,254 @@ /* Copyright 2008-2011 Clipperz Srl This file is part of Clipperz Community Edition. Clipperz Community Edition is an online password manager. For further information about its features and functionalities please refer to http://www.clipperz.com. * Clipperz Community Edition 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. * Clipperz Community Edition 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 Clipperz Community Edition. If not, see <http://www.gnu.org/licenses/>. */ -Clipperz.Base.module('Clipperz.PM.UI.iPhone.Components'); +Clipperz.Base.module('Clipperz.PM.UI.Mobile.Components'); -Clipperz.PM.UI.iPhone.Components.CardList = function(args) { +Clipperz.PM.UI.Mobile.Components.CardList = function(args) { args = args || {}; - Clipperz.PM.UI.iPhone.Components.CardList.superclass.constructor.apply(this, arguments); + Clipperz.PM.UI.Mobile.Components.CardList.superclass.constructor.apply(this, arguments); this._cardDetail = null; return this; } //============================================================================= -Clipperz.Base.extend(Clipperz.PM.UI.iPhone.Components.CardList, Clipperz.PM.UI.Common.Components.BaseComponent, { +Clipperz.Base.extend(Clipperz.PM.UI.Mobile.Components.CardList, Clipperz.PM.UI.Common.Components.BaseComponent, { //------------------------------------------------------------------------- 'toString': function () { - return "Clipperz.PM.UI.iPhone.Components.CardList component"; + return "Clipperz.PM.UI.Mobile.Components.CardList component"; }, //------------------------------------------------------------------------- - 'renderSelf': function(/*aContainer, aPosition*/) { - this.append(this.element(), [ - {tag:'div', cls:'toolbar', id:'toolbar', children:[ - {tag:'h1', id:'pageTitle', html:"cards"}, - {tag:'a', id:'backButton', cls:'button', href:'#', html:"cards"} + 'renderSelf': function () { + this.append(this.element(), {tag:'div', cls:'cardList', children:[ + {tag:'div', cls:'toolbar', children:[ + {tag:'h1', html:"clipperz"}, +// {tag:'input', name:'search', type:'search', autocomplete:'off', placeholder:"search", id:this.getId('search')}, + {tag:'a', href:'#', id:'settings', cls:'button', html:"*"} ]}, - {tag:'div', cls:'cardList', id:this.getId('cardList'), children:[ - {tag:'form', title:'search', cls:'panel cardListSearchForm', id:this.getId('cardListSearchForm'), children:[ - {tag:'input', type:'search', name:'search', value:"", placeholder:"search", id:this.getId('searchField')} - ]}, - {tag:'ul', cls:'panel cardListPanel', id:this.getId('cardListPanel'), children:[]} - ]}, - {tag:'div', cls:'panel cardDetailPanel', id:this.getId('cardDetail')} - ]); - - MochiKit.Signal.connect(this.getElement('cardListSearchForm'), 'onsubmit', this, 'searchHandler'); - MochiKit.Signal.connect(this.getElement('cardListSearchForm'), 'onkeydown', this, 'searchHandler'); - MochiKit.Signal.connect(this.getElement('cardListSearchForm'), 'onkeyup', this, 'searchHandler'); + {tag:'div', cls:'scroll', id:this.getId('listBox'), children:[ + {tag:'ul', cls:'rounded', id:this.getId('list'), children:[ + {tag:'li', html:'loading'} + ]} + ]} + ]}); + + MochiKit.Signal.connect(this.getElement('list'), 'onclick', this, 'cardSelectionHandler'); + MochiKit.Signal.connect(this.getElement('list'), 'ontouchstart', this, 'cardSelectionHandler'); +// MochiKit.Signal.connect(this.getElement('cardListSearchForm'), 'onsubmit', this, 'searchHandler'); +// MochiKit.Signal.connect(this.getElement('cardListSearchForm'), 'onkeydown', this, 'searchHandler'); +// MochiKit.Signal.connect(this.getElement('cardListSearchForm'), 'onkeyup', this, 'searchHandler'); - MochiKit.Signal.connect(this.getElement('cardListPanel'), 'onclick', this, 'cardListClickHandler'); - MochiKit.Signal.connect('backButton', 'onclick', this, 'backButtonClickHandler'); +// MochiKit.Signal.connect(this.getElement('cardListPanel'), 'onclick', this, 'cardListClickHandler'); +// MochiKit.Signal.connect('backButton', 'onclick', this, 'backButtonClickHandler'); - MochiKit.Style.hideElement('backButton'); - MochiKit.Style.hideElement(this.getElement('cardDetail')); +// MochiKit.Style.hideElement('backButton'); +// MochiKit.Style.hideElement(this.getElement('cardDetail')); }, - //------------------------------------------------------------------------- + 'showCards': function (someCards) { + var cardListElement; + if (this.isFullyRendered() == false) { + this.render(); + }; + + cardListElement = this.getElement('list') + + cardInfo = { + '_rowObject': MochiKit.Async.succeed, + '_reference': MochiKit.Base.methodcaller('reference'), + '_searchableContent': MochiKit.Base.methodcaller('searchableContent'), + 'label': MochiKit.Base.methodcaller('label'), + 'favicon': MochiKit.Base.methodcaller('favicon') + }; + +//console.log("someCards", someCards); + deferredResult = new Clipperz.Async.Deferred("CardList.showCards", {trace:false}); + deferredResult.addCallback(MochiKit.Base.map, Clipperz.Async.collectResults("CardList.value - collectResults", cardInfo, {trace:false})); + deferredResult.addCallback(Clipperz.Async.collectAll); + deferredResult.addCallback(MochiKit.Base.methodcaller('sort', Clipperz.Base.caseInsensitiveKeyComparator('label'))); + deferredResult.addCallbackPass(MochiKit.DOM.replaceChildNodes, cardListElement); +// deferredResult.addCallbackPass(MochiKit.DOM.removeElementClass, cardListElement, 'loading'); + deferredResult.addCallback(MochiKit.Base.map, MochiKit.Base.method(this, 'appendCardToList', cardListElement)); + deferredResult.callback(someCards); + }, + + 'appendCardToList': function (aCardListElement, aCardInfo) { +//console.log("appendCardToList", aCardInfo); + this.append(aCardListElement, {tag:'li', cls:'cardListItem arrow', cardreference:aCardInfo['_reference'], children:[ + {tag:'a', href:'#', html:aCardInfo['label'], children:[ + {tag:'small', cls:'favicon', children:[{tag:'img', cls:'favicon', src:aCardInfo['favicon']}]} + ]} + ]}); + }, + + 'cardSelectionHandler': function (anEvent) { + var listElement; + var cardReference; + + anEvent.preventDefault(); + + listElement = anEvent.target(); + if (MochiKit.DOM.getNodeAttribute(listElement, 'cardreference') == null) { + listElement = MochiKit.DOM.getFirstParentByTagAndClassName(anEvent.target(), tagName='li', className='cardListItem'); + } + cardReference = MochiKit.DOM.getNodeAttribute(listElement, 'cardreference'); +console.log("###", listElement, cardReference); + // TODO: Notify card with reference MochiKit.DOM.getNodeAttribute(listElement, 'cardreference') has been selected + MochiKit.Signal.signal(this, 'selectedCard', cardReference); + }, + //------------------------------------------------------------------------- +/* 'searchHandler': function (anEvent) { if ((typeof(anEvent.key()) != 'undefined') && (anEvent.key().string == 'KEY_ENTER')) { // RETURN anEvent.preventDefault(); } else { if ((typeof(anEvent.key()) != 'undefined') && (anEvent.key().string == 'KEY_ESCAPE')) { anEvent.target().value = ""; } if (anEvent.type() == 'keyup') { MochiKit.Signal.signal(this, 'searchEvent', anEvent.target().value); } } }, //------------------------------------------------------------------------- 'update': function (someObjects) { var cardListPanel; var i,c; cardListPanel = this.getElement('cardListPanel'); cardListPanel.innerHTML = ''; c = someObjects.length; for (i=0; i<c; i++) { this.append(cardListPanel, {tag:'li', cls:'cardListItem', id:('cardListItem_' + someObjects[i]['_reference']), children:[ {tag:'img', src:(someObjects[i]['favicon'] ? someObjects[i]['favicon'] : 'data:application/octet-stream;charset=utf-8;base64,AAABAAEAFxcAAAEAGAD8BgAAFgAAACgAAAAXAAAALgAAAAEAGAAAAAAAAAAAABIXAAASFwAAAAAAAAAAAAD///////////////////////////////////////////////////////////////////////////////////////////9zAC////////////////////////////////////////////////////////////////////////////////////////////9pAG////////////////////////////////////////////////////////////////////////////////////////////9rAC////////////////////////////////////////////////////////////////////////////////////////////9yAHP////////////////////////IyMizs7O6urrq6ur////////////Ozs6zs7Ozs7Pq6ur///////////////////////8AAAD////////////////////V1dWXl5eXl5eXl5elpaX4+Pj////Ozs6Xl5eXl5eXl5eenp7///////////////////////8AAAD////////////////////Ozs6Xl5eXl5eXl5eXl5fBwcHq6uqenp6Xl5eXl5eXl5eXl5f///////////////////////8AAAD////////////////////j4+OXl5eXl5eXl5eXl5eXl5elpaWXl5eXl5eXl5eXl5ezs7P///////////////////////8AAAD////////////////////////IyMiXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eenp7x8fH////////////////////////////////////////////////////4+PilpaWXl5eXl5eXl5eXl5eXl5eXl5eXl5fOzs7////////////////////////////////////////////////////////q6uq6urqXl5eXl5eXl5eXl5eXl5eXl5eenp7V1dX4+Pj///////////////////////8AAAD////////////4+PjOzs6lpaWXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5e6urrj4+P///////////////8AAAD////////////BwcGXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5fx8fH///////////8AAAD///////////+zs7OXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5fj4+P///////////8AAAD////////////IyMiXl5eXl5eXl5eXl5e6urqXl5eXl5eXl5eXl5esrKylpaWXl5eXl5eXl5eenp7x8fH///////////8AAAD////////////////Ozs7Ozs7V1dX4+Pj///+Xl5eXl5eXl5eXl5fOzs7////q6urOzs7Ozs7q6ur///////////////8AAAD///////////////////////////////////+Xl5eXl5eXl5eXl5fOzs7///////////////////////////////////8AAAD///////////////////////////////////+Xl5eXl5eXl5eXl5fOzs7///////////////////////////////////8AAAD///////////////////////////////////+Xl5eXl5eXl5eXl5fOzs7///////////////////////////////////8AAAD////////////////////////////////////IyMiXl5eXl5eenp7x8fH///////////////////////////////////8AAAD////////////////////////////////////////j4+Pj4+Px8fH///////////////////////////////////////8AAAD///////////////////////////////////////////////////////////////////////////////////////////8AAAD///////////////////////////////////////////////////////////////////////////////////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAo=')}, {tag:'a', id:('cardListReference_' + someObjects[i]['_reference']), href:'#', html:someObjects[i]['label']} ]}) MochiKit.Signal.connect('cardListItem_' + someObjects[i]['_reference'], 'onclick', this, 'cardListClickHandler'); } }, 'cardListClickHandler': function (anEvent) { anEvent.preventDefault(); if (/(cardListReference_|cardListItem_)/.test(anEvent.target().id)) { var cardListReference; cardListReference = anEvent.target().id.match(/(cardListReference_|cardListItem_)(.*)/)[2]; //console.log("Showing detail for card named", cardListReference); MochiKit.Signal.signal(this, 'selectedCard', cardListReference); } }, //========================================================================= 'cardDetail': function (someData) { if (this._cardDetail == null) { - this._cardDetail = new Clipperz.PM.UI.iPhone.Components.CardDetail({element:this.getElement('cardDetail')}); + this._cardDetail = new Clipperz.PM.UI.Mobile.Components.CardDetail({element:this.getElement('cardDetail')}); } return this._cardDetail; }, //------------------------------------------------------------------------- 'removeCardDetail': function () { if (this._cardDetail != null) { this._cardDetail.remove(); this._cardDetail = null; } }, //========================================================================= 'showCard': function (someData) { var deferredResult; var offset; offset = ((MochiKit.DOM.getNodeAttribute(MochiKit.DOM.currentDocument().body, 'orientation') == 'portrait') ? 320 : 480); this.cardDetail().render(); this.cardDetail().setCardReference(someData['_reference']); MochiKit.Style.setElementPosition(this.cardDetail().element(), {x:offset}); new MochiKit.Visual.Sequence([ // new MochiKit.Visual.Move(this.cardDetail().element(), {x:offset, y:45, mode:'absolute', duration:0, sync:true}), new MochiKit.Visual.Parallel([ new MochiKit.Visual.Move(this.getElement('cardList'), {x:-offset, y:0, mode:'relative', transition:MochiKit.Visual.Transitions.linear, sync:true}), new MochiKit.Visual.Move(this.getElement('cardDetail'), {x:0, y:45, mode:'absolute', transition:MochiKit.Visual.Transitions.linear, sync:true}), // new MochiKit.Visual.ScrollTo('toolbar', {sync:true}), MochiKit.Visual.appear ('backButton', { transition:MochiKit.Visual.Transitions.linear, sync:true}) ], {duration:1, sync:true}), MochiKit.Visual.fade(this.getElement('cardList'), {duration:0, sync:true}) ], {}) MochiKit.DOM.getElement('pageTitle').innerHTML = someData['title']; return true; }, //------------------------------------------------------------------------- 'showCardDetails': function (someData) { return this.cardDetail().showCardDetails(someData); }, //========================================================================= 'backButtonClickHandler': function (anEvent) { var offset; anEvent.preventDefault(); MochiKit.DOM.getElement('pageTitle').innerHTML = "cards"; offset = ((MochiKit.DOM.getNodeAttribute(MochiKit.DOM.currentDocument().body, 'orientation') == 'portrait') ? 320 : 480); MochiKit.Style.setElementPosition(this.getElement('cardList'), {x:-offset}); MochiKit.DOM.showElement(this.getElement('cardList')); new MochiKit.Visual.Parallel([ new MochiKit.Visual.Move(this.getElement('cardList'), {x:offset, y:0, mode:'relative', transition:MochiKit.Visual.Transitions.linear, sync:true}), new MochiKit.Visual.Move(this.getElement('cardDetail'), {x:offset, y:0, mode:'relative', transition:MochiKit.Visual.Transitions.linear, sync:true}), MochiKit.Visual.fade (this.getElement('cardDetail'), { transition:MochiKit.Visual.Transitions.linear, sync:true}), MochiKit.Visual.fade ('backButton', { transition:MochiKit.Visual.Transitions.linear, sync:true}) ], {duration:1, afterFinish:MochiKit.Base.method(this, 'removeCardDetail')}) }, - +*/ //========================================================================= __syntaxFix__: "syntax fix" }); diff --git a/frontend/gamma/js/Clipperz/PM/UI/Mobile/Components/LoginForm.js b/frontend/gamma/js/Clipperz/PM/UI/Mobile/Components/LoginForm.js new file mode 100644 index 0000000..eafcdbc --- a/dev/null +++ b/frontend/gamma/js/Clipperz/PM/UI/Mobile/Components/LoginForm.js @@ -0,0 +1,356 @@ +/* + +Copyright 2008-2011 Clipperz Srl + +This file is part of Clipperz Community Edition. +Clipperz Community Edition is an online password manager. +For further information about its features and functionalities please +refer to http://www.clipperz.com. + +* Clipperz Community Edition 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. + +* Clipperz Community Edition 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 Clipperz Community Edition. If not, see + <http://www.gnu.org/licenses/>. + +*/ + +Clipperz.Base.module('Clipperz.PM.UI.Mobile.Components'); + +Clipperz.PM.UI.Mobile.Components.LoginForm = function(args) { + args = args || {}; + + this._pin = ''; + + this._message = null; + this._steps = 0; + this._actualSteps = 0; + + this._callback = null; + this._errorCallback = null; + + this._mode = 'CREDENTIALS'; + + Clipperz.PM.UI.Mobile.Components.LoginForm.superclass.constructor.apply(this, arguments); + + return this; +} + +//============================================================================= + +Clipperz.Base.extend(Clipperz.PM.UI.Mobile.Components.LoginForm, Clipperz.PM.UI.Common.Components.BaseComponent, { + + //------------------------------------------------------------------------- + + 'toString': function () { + return "Clipperz.PM.UI.Mobile.Components.LoginForm component"; + }, + + //------------------------------------------------------------------------- + + 'callback': function () { + return this._callback; + }, + + 'errorCallback': function () { + return this._errorCallback; + }, + + //------------------------------------------------------------------------- + + 'mode': function () { + return this._mode; + }, + + 'setMode': function (aValue) { + this._mode = aValue; + }, + + //.......................................................................... + + 'pin': function () { + return this._pin; + }, + + 'setPin': function (aValue) { + this._pin = aValue; + }, + + //.......................................................................... + + 'username': function () { + return this._username; + }, + + 'setUsername': function (aValue) { + this._username = aValue; + }, + + //.......................................................................... + + 'passphrase': function () { + return this._passphrase; + }, + + 'setPassphrase': function (aValue) { + this._passphrase = aValue; + }, + + //------------------------------------------------------------------------- + + 'message': function () { + return this._message; + }, + + '_setMessage': function (aValue) { + this._message = aValue; + + if (aValue == null) { + MochiKit.Style.hideElement(this.getElement('credentialsMessage')); + } else { + this.getElement('message').innerHTML = aValue; + MochiKit.Style.showElement(this.getElement('credentialsMessage')); + } + }, + + 'setMessage': function (aValue) { + this._setMessage(aValue); + MochiKit.DOM.removeElementClass(this.getElement('credentialsMessage'), 'error'); + }, + + 'setErrorMessage': function (aValue) { + this._setMessage(aValue); + MochiKit.DOM.addElementClass(this.getElement('credentialsMessage'), 'error'); + }, + + //------------------------------------------------------------------------- + + 'setCallbacks': function (args) { + this._callback = args['callback']; + this._errorCallback = args['errorCallback']; + }, + + 'showErrors': function (args) { +//console.log("LoginForm.showErrors", args); + if (args['previousFailedAttempt'] == 'LOGIN') { + this.setErrorMessage("Wrong credentials"); + } else if (args['previousFailedAttempt'] == 'PIN') { + if (args['failedAttempts'] == -1) { + this.setErrorMessage("Wrong PIN - Resetted"); + } else { + this.setErrorMessage("Wrong PIN"); + } + } else { + this.setMessage(null); + } + }, + + 'updateWithArgs': function (args) { + this.renderIfNeeded(); + this.setCallbacks(args); + this.showErrors(args); + this.updateRendering(); + }, + + 'showPinLogin': function (args) { + this.setPin(''); + this.setMode('PIN'); + this.updateWithArgs(args); + +// $(this.getAnchor('PIN')).focus(); + this.getElement('PIN').focus(); + }, + + 'showCredentialsLogin': function (args) { + this.setMode('CREDENTIALS'); + this.updateWithArgs(args); + + if (this.getElement('usernameField').value.length == 0) { +// $(this.getAnchor('usernameField')).focus(); + this.getElement('usernameField').focus(); + } else { +// $(this.getAnchor('passphraseField')).focus(); + this.getElement('passphraseField').focus(); + this.getElement('passphraseField').select(); + } + }, + + //------------------------------------------------------------------------- + + 'renderIfNeeded': function () { + if (this.isFullyRendered() == false) { + this.render(); + }; + this.updateRendering(); + }, + + 'updateRendering': function () { + MochiKit.Style.showElement(this.getElement('credentialsBody')); + MochiKit.Style.hideElement(this.getElement('validating')); + +// this.hideAllPanes(); + MochiKit.Base.map(function (aNode) { MochiKit.Style.hideElement(aNode); }, MochiKit.Selector.findDocElements('div.credentialsBody > div')); + if (this.mode() == 'CREDENTIALS') { + selectedPanel = this.getElement('credentials') + } else if (this.mode() == 'PIN') { + selectedPanel = this.getElement('pin') +// this.updatePinDisplay(); + } else { + throw 'Unhandled login form mode'; + } + MochiKit.Style.showElement(selectedPanel); + + MochiKit.Style.hideElement(this.getElement('validating')); + }, + + 'renderSelf': function() { + var selectedPanel; + this.append(this.element(), {tag:'div', id:'login', children:[ + {tag:'div', cls:'toolbar', children:[ + {tag:'h1', html:"clipperz"} + ]}, + {tag:'div', cls:'scroll', children:[ + //================================================================== + {tag:'div', cls:'credentialsMessage', id:this.getId('credentialsMessage'), children:[ + {tag:'h1', cls:'message', id:this.getId('message'), html:"Message"} + ]}, + //================================================================== + {tag:'div', cls:'credentialsBody', id:this.getId('credentialsBody'), children:[ + //-------------------------------------------------------------- + {tag:'div', cls:'pin', id:this.getId('pin'), children:[ + {tag:'form', cls:'scroll', id:this.getId('pinForm'), children:[ + {tag:'ul', cls:'edit rounded', children:[ + {tag:'li', children:[{tag:'input', type:'number', name:'PIN', placeholder:"PIN", id:this.getId('PIN') }]}, + ]}, + {tag:'a', href:'#', cls:'greenButton', id:this.getId('pinSubmitButton'), html:"Login"} + ]} + ]}, + //-------------------------------------------------------------- + {tag:'div', cls:'credentials', id:this.getId('credentials'), children:[ + {tag:'form', cls:'scroll', id:this.getId('credentialsForm'), children:[ + {tag:'ul', cls:'edit rounded', children:[ + {tag:'li', children:[{tag:'input', type:'email', name:'name', /*value:'joe',*/ placeholder:"username", id:this.getId('usernameField') }]}, + {tag:'li', children:[{tag:'input', type:'password', name:'passphrase', /*value:'clipperz',*/ placeholder:"passphrase", id:this.getId('passphraseField') }]} + ]}, + {tag:'a', href:'#', cls:'greenButton', id:this.getId('credentialsSubmitButton'), html:"Login"} +// {tag:'input', type:'submit', cls:'greenButton', id:this.getId('credentialsSubmitButton'), value:"Login"} + + ]} + ]}, + //-------------------------------------------------------------- + ]}, + //================================================================== + {tag:'div', cls:'validating', id:this.getId('validating'), children:[ + {tag:'div', cls:'loading', children:[ + {tag:'div', cls:'spinner', children:[ + {tag:'div', cls:'bar01'}, + {tag:'div', cls:'bar02'}, + {tag:'div', cls:'bar03'}, + {tag:'div', cls:'bar04'}, + {tag:'div', cls:'bar05'}, + {tag:'div', cls:'bar06'}, + {tag:'div', cls:'bar07'}, + {tag:'div', cls:'bar08'}, + {tag:'div', cls:'bar09'}, + {tag:'div', cls:'bar10'}, + {tag:'div', cls:'bar11'}, + {tag:'div', cls:'bar12'} + ]} + ]}, + {tag:'div', id:this.getId('loadingMessage')}, + {tag:'a', href:'#', cls:'grayButton', id:this.getId('loginCancelButton'), html:"Cancel"} + ]} + //================================================================== + ]} + ]}); + + MochiKit.Signal.connect(this.getElement('credentialsForm'), 'onsubmit', this, 'submitCredentialsHandler'); + MochiKit.Signal.connect(this.getElement('credentialsSubmitButton'), 'onclick', this, 'submitCredentialsHandler'); + + MochiKit.Signal.connect(this.getElement('pinForm'), 'onsubmit', this, 'submitPinHandler'); + MochiKit.Signal.connect(this.getElement('pinSubmitButton'), 'onclick', this, 'submitPinHandler'); + + MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, 'initProgress', this, 'initProgressHandle'); + MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, 'updateProgress', this, 'updateProgressHandle'); + MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, 'advanceProgress', this, 'advanceProgressHandle'); + MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, 'progressDone', this, 'progressDoneHandle'); + }, + + //------------------------------------------------------------------------- + + 'submitPinHandler': function (anEvent) { + var pin; + + this.setMessage(null); + pin = this.getElement('PIN').value; +// $(this.getAnchor('PIN')).blur(); + this.getElement('PIN').blur(); + + credentials = Clipperz.PM.PIN.credentialsWithPIN(pin); + this.loginWithCredentials(credentials); + }, + + 'submitCredentialsHandler': function (anEvent) { +//console.log("submitCredentialsHandler"); + var credentials; + + this.setMessage(null); + + credentials = {}; + credentials['username'] = this.getElement('usernameField').value; + credentials['passphrase'] = this.getElement('passphraseField').value; +// $(this.getAnchor('passphraseField')).blur(); + this.getElement('passphraseField').blur(); + + this.loginWithCredentials(credentials); + }, + + //------------------------------------------------------------------------- + + 'loginWithCredentials': function (someCredentials) { + var args; + + args = {}; + args['credentials'] = someCredentials; + args['errorCallback'] = this.errorCallback(); + + MochiKit.Style.hideElement(this.getElement('credentialsBody')); + MochiKit.Style.showElement(this.getElement('validating')); + + MochiKit.Async.callLater(0.1, this.callback(), args); + }, + + //------------------------------------------------------------------------- + + 'initProgressHandle': function (anEvent) { +//console.log("** initProgressHandle", anEvent); + this._steps = anEvent['steps']; + this._actualSteps = 0; + }, + + 'updateProgressHandle': function (anEvent) { +//console.log("** updateProgressHandle", anEvent); + this._steps += anEvent['extraSteps']; + }, + + 'advanceProgressHandle': function (anEvent) { +//console.log("** advanceProgressHandle", anEvent); + this._actualSteps ++; +//console.log("STEPS: " + this._actualSteps + "/" + this._steps); + }, + + 'progressDoneHandle': function (anEvent) { +//console.log("** progressDoneHandle", anEvent); + }, + + //------------------------------------------------------------------------- + __syntaxFix__: "syntax fix" +}); diff --git a/frontend/gamma/js/Clipperz/PM/UI/Mobile/Controllers/MainController.js b/frontend/gamma/js/Clipperz/PM/UI/Mobile/Controllers/MainController.js new file mode 100644 index 0000000..12a61f7 --- a/dev/null +++ b/frontend/gamma/js/Clipperz/PM/UI/Mobile/Controllers/MainController.js @@ -0,0 +1,393 @@ +/* + +Copyright 2008-2011 Clipperz Srl + +This file is part of Clipperz Community Edition. +Clipperz Community Edition is an online password manager. +For further information about its features and functionalities please +refer to http://www.clipperz.com. + +* Clipperz Community Edition 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. + +* Clipperz Community Edition 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 Clipperz Community Edition. If not, see + <http://www.gnu.org/licenses/>. + +*/ + +Clipperz.Base.module('Clipperz.PM.UI.Mobile.Controllers'); + +Clipperz.PM.UI.Mobile.Controllers.MainController = function() { + this._jQTouch = null; + this._user = null; + this._proxy = null; + this._loginForm = null; + this._cardList = null; + this._cardDetail = null; + + return this; +} + +MochiKit.Base.update(Clipperz.PM.UI.Mobile.Controllers.MainController.prototype, { + + 'toString': function () { + return "Clipperz.PM.UI.Mobile.Controllers.MainController"; + }, + + //------------------------------------------------------------------------- + + 'user': function () { + return this._user; + }, + + 'setUser': function (aValue) { + this._user = aValue; + }, + + //------------------------------------------------------------------------- + + 'jQTouch': function () { + return this._jQTouch; + }, + + 'setJQTouch': function (aValue) { + this._jQTouch = aValue; + }, + + //========================================================================= + + 'run': function () { + console.log("MainController.run"); + + MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, 'doLogin', MochiKit.Base.method(this, 'doLogin')); + Clipperz.DOM.Helper.overwrite(MochiKit.DOM.currentDocument().body, {tag:'div', id:'jqt', children:[ + {tag:'div', id:'loginForm'}, + {tag:'div', id:'cardList'}, + {tag:'div', id:'cardDetail'}, + {tag:'div', id:'preferences'} + ]}); + + this.showLoginForm(); + + this.initjQTouch(); + + +// this.showAddToHomeScreenBaloon(); +// this.selectInitialProxy(); + }, + + 'initjQTouch': function () { + var jqt; + + jqt = new $.jQTouch({ + icon: 'data:image/png;charset=utf-8;base64,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', +// icon4: 'jqtouch4.png', +// startupScreen: null, // Pass a string path to a 320px x 460px startup screen for full screen apps. + statusBar: 'black-translucent', // Styles the status bar when running as a fullscreen app. Other options are `default`, `black`, and `black-translucent`. +// addGlossToIcon: true, // Set to 'false' to prevent automatic glossy button effect on icon. + preloadImages: false, // Pass an array of image paths to load them before page loads. Ex: `['images/link_over.png', 'images/link_select.png']` + fixedViewport: true, // Removes the user's ability to scale the page. Ensures the site behaves more like an application. +// fullScreen: true, // The website will become a fullscreen application when saved to a user's home screen. Set to `false` to disable. +// fullScreenClass: 'fullscreen' // Adds a class to the `<body>` when running in full-screen mode, to allow for easy detection and styling. Set to `false` to disable. +// themeSelectionSelector: '#jqt #themes ul', // ??? + +// useAnimations: true, // Set to `false` to disable all animations. +// useFastTouch: true, // Removes ~350ms onClick delay when tapping a link (use in conjunction with the .tap() event) **Experimental** +// useTouchScroll: true, // Adds support for iOS5 scrolling. Set to false to disable. **Experimental** + + cacheGetRequests: false, // Automatically caches GET requests, so subsequent taps reference the pre-loaded views. (default: true) + +// backSelector: '.back, .cancel, .goback', // A CSS selector for back links/buttons. When clicked, the page history goes back one, automatically reversing whichever entrance animation was used. + +// cubeSelector: '.cube', // Link selector for a cube animation. +// dissolveSelector: '.dissolve', // Link selector for a dissolve animation. +// fadeSelector: '.fade', // Link selector for a fade animation. +// flipSelector: '.flip', // Link selector for a 3d flip animation. + formSelector: null, // Sets which forms are automatically submitted via Ajax. (default: 'form') +// popSelector: '.pop', // Link selector for a pop animation. (default: '.pop') +// slideSelector: 'body > * > ul li a', // Link selector for the default slide-left transition. By default applies to all links within an unordered list. Accepts any jQuery-capable selector `'li > a, a:not(.dontslide)'`, etc. (default: 'body > * > ul li a') +// slideupSelector: '.slideup', // Link selector for a slide up animation. (default: '.slideup') +// submitSelector: '.submit', // Selector which, when clicked, will submit its parent form (and close keyboard if open). (default: '.submit') +// swapSelector: '.swap', // Link selector for 3d swap animation. (default: '.swap') +// touchSelector: 'a, .touch', // Selector for items which are automatically given expanded touch events. This makes ordinary links more responsive and provides trigger events like `swipe` (default: 'a, .touch') + + debug: false + }); + + this.setJQTouch(jqt); + }, + + //========================================================================= + + 'showAddToHomeScreenBaloon': function () { +console.log(">>> showAddToHomeScreenBaloon"); + }, + + //------------------------------------------------------------------------- + + 'selectInitialProxy': function () { +//console.log(">>> selectInitialProxy"); + if (this.isOnline()) { +//console.log("--- selectInitialProxy: using default proxy"); + this._proxy = Clipperz.PM.Proxy.defaultProxy; + } else { + if (this.hasLocalData()) { +//console.log("--- selectInitialProxy: using local cache proxy"); + this._proxy = new Clipperz.PM.Proxy.OfflineCache({'shouldPayTolls':false}); + } else { + this.showOfflineError(); + } + } + }, + + //------------------------------------------------------------------------- + + 'showLoginForm': function (args) { + args = args || {}; + + args['callback'] = MochiKit.Base.method(this, 'doLogin'); + + if (Clipperz.PM.PIN.isSet()) { + args['errorCallback'] = MochiKit.Base.method(this, 'handleFailedPinLogin'); + this.loginForm().showPinLogin(args); + } else { + args['errorCallback'] = MochiKit.Base.method(this, 'handleFailedCredentialsLogin'); + this.loginForm().showCredentialsLogin(args); + } + }, + + //......................................................................... + + 'handleFailedCredentialsLogin': function () { +console.log("LOGIN FAILED"); + this.showLoginForm({'previousFailedAttempt':'LOGIN'}); + }, + + //......................................................................... + + 'handleFailedPinLogin': function () { + var failedAttempts; + var status; + + failedAttempts = Clipperz.PM.PIN.recordFailedAttempt(); + this.showLoginForm({'previousFailedAttempt':'PIN', 'failedAttempts': failedAttempts}); + }, + + //------------------------------------------------------------------------- + + 'doLogin': function (someArgs) { + var deferredResult; + var credentials; + var errorCallback; + var user; + var getPassphraseDelegate; + +//console.log(">>> MainController.doLogin", someArgs); + credentials = someArgs['credentials']; + errorCallback = someArgs['errorCallback'] || MochiKit.Base.noop; + + getPassphraseDelegate = MochiKit.Base.partial(MochiKit.Async.succeed, credentials.passphrase); + user = new Clipperz.PM.DataModel.User({'username':credentials.username, 'getPassphraseFunction':getPassphraseDelegate}); + + deferredResult = new Clipperz.Async.Deferred('MainController.doLogin', {trace:false}); + deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'initProgress', {'steps':4}); + deferredResult.addCallback(MochiKit.Async.wait, 0.1); + deferredResult.addMethod(Clipperz.Crypto.PRNG.defaultRandomGenerator(), 'deferredEntropyCollection'); + deferredResult.addMethod(user, 'login'); + deferredResult.addCallbacks( + MochiKit.Base.method(this, 'processSuccessfulLogin', user), + errorCallback + ); + deferredResult.callback(); + + return deferredResult; + }, + + //.......................................................................... + + 'processSuccessfulLogin': function (aUser) { + var deferredResult; + + deferredResult = new Clipperz.Async.Deferred('MainController.processSuccessfulLogin', {trace:false}); + deferredResult.addMethod(Clipperz.PM.PIN, 'resetFailedAttemptCount'); +// deferredResult.addMethod(this, 'removeLoginForm'); + deferredResult.addMethod(this, 'setUser', aUser); + deferredResult.addMethod(this, 'setupApplication'); + deferredResult.addMethod(this, 'runApplication'); + deferredResult.callback(); + + return deferredResult; + }, + + //------------------------------------------------------------------------- + + 'setupApplication': function () { + var deferredResult; + +console.log(">>> setupApplication"); + deferredResult = new Clipperz.Async.Deferred("MainController.setupApplication", {trace:false}); + deferredResult.addMethod(this, 'welcomeFirstTimeUser'); + deferredResult.addMethod(this, 'showPaymentReminder'); + deferredResult.addMethod(this, 'copyDataLocally'); + deferredResult.callback(arguments); + + return deferredResult; + }, + + + //.......................................................................... + + 'isFirstTimeUser': function () { + return false; + }, + + 'welcomeFirstTimeUser': function () { + var deferredResult; + + deferredResult = new Clipperz.Async.Deferred('MainController.welcomeFirstTimeUser', {trace:false}); + + if (this.isFirstTimeUser()) { + deferredResult.addCallback(function () { console.log("--> welcome"); }); + } + deferredResult.callback(); + + return deferredResult; + }, + + //.......................................................................... + + 'shouldShowPaymentReminder': function () { + return true; + }, + + 'showPaymentReminder': function () { + var deferredResult; + + deferredResult = new Clipperz.Async.Deferred('MainController.showPaymentReminder', {trace:false}); + + if (this.shouldShowPaymentReminder()) { + deferredResult.addCallback(function () { console.log("--> payment reminder"); }); + } + deferredResult.callback(); + + return deferredResult; + }, + + //.......................................................................... + + 'canCopyDataLocally': function () { + return false; + }, + + 'copyDataLocally': function () { + var deferredResult; + + deferredResult = new Clipperz.Async.Deferred('MainController.copyDataLocally', {trace:false}); + + if (this.canCopyDataLocally()) { + deferredResult.addCallback(function () { console.log("--> copy data locally"); }); + } + deferredResult.callback(); + + return deferredResult; + + }, + + //------------------------------------------------------------------------- + + 'runApplication': function () { + var deferredResult; + +//console.log(">>> runApplication"); + deferredResult = new Clipperz.Async.Deferred('MainController.runApplication', {trace:true}); + deferredResult.addMethod(this.user(), 'getRecords'); + deferredResult.addMethod(this, 'showCards'); + deferredResult.callback(); + + return deferredResult; + }, + + //========================================================================= + + 'showOfflineError': function (anException) { + alert("Error: " + anException); + throw anException; + }, + + //========================================================================= + + 'isOnline': function() { + return navigator.onLine; + }, + + 'hasLocalData': function() { + return false; + }, + + //========================================================================= + + 'loginForm': function() { + if (this._loginForm == null) { + this._loginForm = new Clipperz.PM.UI.Mobile.Components.LoginForm({element:MochiKit.DOM.getElement('loginForm')}); + } + + return this._loginForm; + }, + + 'removeLoginForm': function () { + if (this._loginForm != null) { + this._loginForm.remove(); + this._loginForm = null; + } + }, + + //------------------------------------------------------------------------- + + 'cardList': function () { + if (this._cardList == null) { + this._cardList = new Clipperz.PM.UI.Mobile.Components.CardList({element:MochiKit.DOM.getElement('cardList')}); + MochiKit.Signal.connect(this._cardList, 'selectedCard', this, 'selectCardHandler'); + } + + return this._cardList; + }, + + 'showCards': function (someCards) { + this.cardList().showCards(someCards); + this.jQTouch().goTo('#cardList', 'slideleft'); + }, + + //------------------------------------------------------------------------- + + 'cardDetail': function () { + if (this._cardDetail == null) { + this._cardDetail = new Clipperz.PM.UI.Mobile.Components.CardDetail({element:MochiKit.DOM.getElement('cardDetail')}); + } + + return this._cardDetail; + }, + + 'selectCardHandler': function (aCardReference) { + var deferredResult; + + deferredResult = new Clipperz.Async.Deferred("MainController.selectCardHandler", {trace:true}); + deferredResult.addMethod(this.cardDetail(), 'render'); + deferredResult.addMethod(this.jQTouch(), 'goTo', '#cardDetail', 'slideleft'); + deferredResult.addMethod(this.user(), 'getRecord', aCardReference); + deferredResult.addMethod(this.cardDetail(), 'showCard'); + deferredResult.callback(); + + return deferredResult; + }, + + //========================================================================= + __syntaxFix__: "syntax fix" +}); diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/AccountPanel.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/AccountPanel.js index ee6d7a3..d6b0574 100644 --- a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/AccountPanel.js +++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/AccountPanel.js @@ -1,145 +1,150 @@ /* Copyright 2008-2011 Clipperz Srl This file is part of Clipperz Community Edition. Clipperz Community Edition is an online password manager. For further information about its features and functionalities please refer to http://www.clipperz.com. * Clipperz Community Edition 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. * Clipperz Community Edition 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 Clipperz Community Edition. If not, see <http://www.gnu.org/licenses/>. */ Clipperz.Base.module('Clipperz.PM.UI.Web.Components'); Clipperz.PM.UI.Web.Components.AccountPanel = function(args) { args = args || {}; Clipperz.PM.UI.Web.Components.AccountPanel.superclass.constructor.apply(this, arguments); // this._initiallySelectedTab = args.selected || 'ACCOUNT'; this._initiallySelectedTab = args.selected || 'PASSPHRASE'; this._tabPanelControllerConfiguration = { // 'ACCOUNT': { // tab: 'accountTab', // panel: 'accountPanel' // }, 'PASSPHRASE': { tab: 'passphraseTab', panel: 'passphrasePanel' }, + 'OTP': { + tab: 'OTPTab', + panel: 'OTPPanel' + }, 'PREFERENCES': { tab: 'preferencesTab', panel: 'preferencesPanel' }, 'LOGIN_HISTORY': { tab: 'loginHistoryTab', panel: 'loginHistoryPanel' } }; return this; } //============================================================================= Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.AccountPanel, Clipperz.PM.UI.Common.Components.TabPanelComponent, { //------------------------------------------------------------------------- 'toString': function () { return "Clipperz.PM.UI.Web.Components.AccountPanel component"; }, //------------------------------------------------------------------------- 'renderSelf': function(/*aContainer, aPosition*/) { //Clipperz.log("AccountPanel.renderSelf element", this.element()); this.append(this.element(), [ {tag:'div', cls:'header', children:[ {tag:'div', cls:'subPanelTabs', children:[ {tag:'ul', children:[ // {tag:'li', id:this.getId('accountTab'), children:[{tag:'a', href:'#', html:'Account'}], cls:'first'}, {tag:'li', id:this.getId('passphraseTab'), children:[{tag:'a', href:'#', html:'Passphrase'}], cls:'first'}, + {tag:'li', id:this.getId('OTPTab'), children:[{tag:'a', href:'#', html:'One Time Passwords'}]}, {tag:'li', id:this.getId('preferencesTab'), children:[{tag:'a', href:'#', html:'Preferences'}]}, {tag:'li', id:this.getId('loginHistoryTab'), children:[{tag:'a', href:'#', html:'Login history'}]} ]} ]} ]}, {tag:'div', cls:'body', children:[ {tag:'div', cls:'accountPanel', children:[ {tag:'div', cls:'subPanelContent', children:[ {tag:'ul', children:[ // {tag:'li', id:this.getId('accountPanel'), children:[ // {tag:'h3', html:"-- Account --"} // ]}, {tag:'li', id:this.getId('passphrasePanel'), children:[ {tag:'h3', cls:'changePassphrase', html:"Change passphrase"}, {tag:'form', id:this.getId('changePassphrase'), cls:'changePassphrase', children:[ {tag:'div', cls:'currentCredentials', children:[ {tag:'div', cls:'field username', children:[ {tag:'label', html:"username", 'for':this.getId('currentUsername')}, {tag:'input', id:this.getId('currentUsername')} ]}, {tag:'div', cls:'field passphrase', children:[ {tag:'label', html:"passphrase", 'for':this.getId('currentPassphrase')}, {tag:'input', id:this.getId('currentPassphrase')} ]} ]}, {tag:'div', cls:'newPassphrase', children:[ {tag:'div', cls:'field', children:[ {tag:'label', html:"new passphrase", 'for':this.getId('newPassphrase')}, {tag:'input', id:this.getId('newPassphrase')} ]}, {tag:'div', cls:'field', children:[ {tag:'label', html:"re-new passphrase", 'for':this.getId('reNewPassphrase')}, {tag:'input', id:this.getId('reNewPassphrase')} ]} ]}, {tag:'div', cls:'confirm', children:[ {tag:'input', type:'checkbox', id:this.getId('confirm')}, {tag:'label', html:"I understand that Clipperz will not be able to recover a lost passphrase", 'for':this.getId('confirm')} ]} ]}, {tag:'div', cls:'clear'}, {tag:'div', cls:'confirmButton', id:this.getId('confirmationButton'), children:[ {tag:'span', html:"change passphrase"} - ]}, - - {tag:'h3', cls:'manageOTP', html:"Manage One-Time Passphrases"}, - {} + ]} + ]}, + {tag:'li', id:this.getId('OTPPanel'), children:[ +// {tag:'h3', html:"Manage One-Time Passphrases"} ]}, {tag:'li', id:this.getId('preferencesPanel'), children:[ - {tag:'h3', html:"-- Preferences --"} +// {tag:'h3', html:"-- Preferences --"} ]}, {tag:'li', id:this.getId('loginHistoryPanel'), children:[ - {tag:'h3', html:"-- Login History --"} +// {tag:'h3', html:"-- Login History --"} ]} ]} ]} ]} ]}, {tag:'div', cls:'footer'} ]); this.tabPanelController().setup({selected:this.initiallySelectedTab()}); }, //------------------------------------------------------------------------- __syntaxFix__: "syntax fix" }); diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DataPanel.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DataPanel.js index d2f1045..462d864 100644 --- a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DataPanel.js +++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DataPanel.js @@ -37,72 +37,80 @@ Clipperz.PM.UI.Web.Components.DataPanel = function(args) { panel: 'offlineCopyPanel' }, 'SHARING': { tab: 'sharingTab', panel: 'sharingPanel' }, 'IMPORT': { tab: 'importTab', panel: 'importPanel' }, 'EXPORT': { tab: 'exportTab', panel: 'exportPanel' } }; return this; } //============================================================================= Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.DataPanel, Clipperz.PM.UI.Common.Components.TabPanelComponent, { //------------------------------------------------------------------------- 'toString': function () { return "Clipperz.PM.UI.Web.Components.DataPanel component"; }, //------------------------------------------------------------------------- 'renderSelf': function(/*aContainer, aPosition*/) { this.append(this.element(), [ {tag:'div', cls:'header', children:[ {tag:'div', cls:'subPanelTabs', children:[ {tag:'ul', children:[ {tag:'li', id:this.getId('offlineCopyTab'), children:[{tag:'a', href:'#', html:'Offline copy'}], cls:'first'}, {tag:'li', id:this.getId('sharingTab'), children:[{tag:'a', href:'#', html:'Sharing'}]}, {tag:'li', id:this.getId('importTab'), children:[{tag:'a', href:'#', html:'Import'}]}, {tag:'li', id:this.getId('exportTab'), children:[{tag:'a', href:'#', html:'Export'}]} ]} ]} ]}, {tag:'div', cls:'body', children:[ {tag:'div', cls:'accountPanel', children:[ {tag:'div', cls:'subPanelContent', children:[ {tag:'ul', children:[ {tag:'li', id:this.getId('offlineCopyPanel'), children:[ - {tag:'h3', html:"Offline copy"} +// {tag:'h3', html:"Offline copy"}, + {tag:'p', html:"With just one click you can dump all your encrypted data from Clipperz servers to your hard disk and create a read-only offline version of Clipperz to be used when you are not connected to the Internet."}, + {tag:'a', id:this.getId('offlineCopyDownloadLink'), href:'#', html:"Download", cls:'downloadOfflineCopy'} ]}, {tag:'li', id:this.getId('sharingPanel'), children:[ - {tag:'h3', html:"Sharing"} +// {tag:'h3', html:"Sharing"} ]}, {tag:'li', id:this.getId('importPanel'), children:[ - {tag:'h3', html:"Import"} +// {tag:'h3', html:"Import"} ]}, {tag:'li', id:this.getId('exportPanel'), children:[ - {tag:'h3', html:"Export"} +// {tag:'h3', html:"Export"} ]} ]} ]} ]} ]}, {tag:'div', cls:'footer'} ]); this.tabPanelController().setup({selected:this.initiallySelectedTab()}); + MochiKit.Signal.connect(this.getId('offlineCopyDownloadLink'), 'onclick', this, 'downloadOfflineCopy'); }, - + + 'downloadOfflineCopy': function (anEvent) { + anEvent.preventDefault(); + MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'downloadOfflineCopy', anEvent.src()); + }, + //------------------------------------------------------------------------- __syntaxFix__: "syntax fix" }); diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/LoginProgress.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/LoginProgress.js index 5d082b5..26506e7 100644 --- a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/LoginProgress.js +++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/LoginProgress.js @@ -37,116 +37,120 @@ Clipperz.PM.UI.Web.Components.LoginProgress = function(args) { //============================================================================= Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.LoginProgress, Clipperz.PM.UI.Common.Components.BaseComponent, { //------------------------------------------------------------------------- 'toString': function () { return "Clipperz.PM.UI.Web.Components.LoginProgress component"; }, //------------------------------------------------------------------------- 'deferred': function() { return this._deferred; }, 'setDeferred': function(aValue) { this._deferred = aValue; }, //------------------------------------------------------------------------- 'renderSelf': function() { // var loginProgressElement; // // loginProgressElement = MochiKit.DOM.getElement('loginProgress'); // // if (loginProgressElement == null) { // loginProgressElement = this.append(this.element(), {tag:'div', id:'loginProgress', cls:'LoginProgress'}, true); // } //console.log(">> LoginProgress.renderSelf", this.element()); this.append(this.element(), {tag:'div', id:'loginProgress', cls:'LoginProgress', children: [ // this.append(loginProgressElement, [ {tag:'div', cls:'header', children:[ {tag:'h3', id:this.getId('title'), html:"login progress"} ]}, {tag:'div', cls:'body', children:[ {tag:'div', id:this.getId('progressBar')}, {tag:'div', id:this.getId('errorBox'), cls:'errorBox', children:[ // {tag:'div', cls:'img ALERT', children:[{tag:'div'}]}, {tag:'div', cls:'img ALERT', children:[{tag:'canvas', id:this.getId('canvas')}]}, {tag:'p', html:"Login failed"} ]} ]}, {tag:'div', cls:'footer', children:[ {tag:'div', cls:'buttonArea', id:this.getId('buttonArea'), children:[ - {tag:'div', cls:'button', id:this.getId('button'), children:[ - {tag:'a', href:'#', id:this.getId('buttonLink'), html:"cancel"} - ]} +// {tag:'div', cls:'button', id:this.getId('button'), children:[ +// {tag:'a', href:'#', id:this.getId('buttonLink'), html:"cancel"} +// ]} + {tag:'a', cls:'button', id:this.getId('button'), html:"cancel"} ]} ]} ]}); // ]); Clipperz.PM.UI.Canvas.marks['!'](this.getElement('canvas'), "#ffffff"); this.addComponent(new Clipperz.PM.UI.Common.Components.ProgressBar({'element':this.getElement('progressBar')})); MochiKit.Style.hideElement(this.getElement('errorBox')); - MochiKit.Signal.connect(this.getId('buttonLink'), 'onclick', this, 'cancelEventHandler'); +// MochiKit.Signal.connect(this.getId('buttonLink'), 'onclick', this, 'cancelEventHandler'); + MochiKit.Signal.connect(this.getId('button'), 'onclick', this, 'cancelEventHandler'); }, //------------------------------------------------------------------------- 'displayElement': function() { return MochiKit.DOM.getElement('loginProgress'); }, //------------------------------------------------------------------------- 'cancelEventHandler': function(anEvent) { anEvent.preventDefault(); MochiKit.Signal.signal(this, 'cancelEvent'); }, //------------------------------------------------------------------------- 'disableCancel': function() { MochiKit.Style.hideElement(this.getElement('buttonArea')); }, //------------------------------------------------------------------------- 'showErrorMessage': function() { - this.getElement('buttonLink').innerHTML = "close"; +// this.getElement('buttonLink').innerHTML = "close"; + this.getElement('button').innerHTML = "close"; + MochiKit.DOM.addElementClass(this.getElement('button'), 'default'); MochiKit.Style.hideElement(this.getElement('progressBar')); this.getElement('title').innerHTML = "Error"; MochiKit.Style.showElement(this.getElement('errorBox')); MochiKit.Style.showElement(this.getElement('buttonArea')); }, //------------------------------------------------------------------------- 'deferredHideModalAndRemove': function(someParameters, aResult) { var deferredResult; deferredResult = new Clipperz.Async.Deferred("LoginProgress.deferredHideModalAndRemove", {trace:false}); deferredResult.addMethod(this, 'deferredHideModal'); deferredResult.addMethod(this, 'remove'); deferredResult.addCallback(function () { return aResult; }); deferredResult.callback(someParameters); return deferredResult; }, //------------------------------------------------------------------------- __syntaxFix__: "syntax fix" }); diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/ToolsPanel.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/ToolsPanel.js index 3ee6189..0fa369f 100644 --- a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/ToolsPanel.js +++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/ToolsPanel.js @@ -37,74 +37,74 @@ Clipperz.PM.UI.Web.Components.ToolsPanel = function(args) { panel: 'passwordGeneratorPanel' }, 'BOOKMARKLET': { tab: 'bookmarkletTab', panel: 'bookmarkletPanel' }, 'COMPACT_EDITION': { tab: 'compactEditionTab', panel: 'compactEditionPanel' }, 'HTTP_AUTH': { tab: 'httpAuthTab', panel: 'httpAuthPanel' } }; return this; } //============================================================================= Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.ToolsPanel, Clipperz.PM.UI.Common.Components.TabPanelComponent, { //------------------------------------------------------------------------- 'toString': function () { return "Clipperz.PM.UI.Web.Components.ToolsPanel component"; }, //------------------------------------------------------------------------- 'renderSelf': function(/*aContainer, aPosition*/) { this.append(this.element(), [ {tag:'div', cls:'header', children:[ {tag:'div', cls:'subPanelTabs', children:[ {tag:'ul', children:[ {tag:'li', id:this.getId('passwordGeneratorTab'), children:[{tag:'a', href:'#', html:'Password generator'}], cls:'first'}, {tag:'li', id:this.getId('bookmarkletTab'), children:[{tag:'a', href:'#', html:'Bookmarklet'}]}, {tag:'li', id:this.getId('compactEditionTab'), children:[{tag:'a', href:'#', html:'Compact edition'}]}, {tag:'li', id:this.getId('httpAuthTab'), children:[{tag:'a', href:'#', html:'HTTP Auth'}]} ]} ]} ]}, {tag:'div', cls:'body', children:[ {tag:'div', cls:'accountPanel', children:[ {tag:'div', cls:'subPanelContent', children:[ {tag:'ul', children:[ {tag:'li', id:this.getId('passwordGeneratorPanel'), children:[ - {tag:'h3', html:"Password generator"} +// {tag:'h3', html:"Password generator"} ]}, {tag:'li', id:this.getId('bookmarkletPanel'), children:[ - {tag:'h3', html:"Bookmarklet"} +// {tag:'h3', html:"Bookmarklet"} ]}, {tag:'li', id:this.getId('compactEditionPanel'), children:[ - {tag:'h3', html:"Compact edition"} +// {tag:'h3', html:"Compact edition"} ]}, {tag:'li', id:this.getId('httpAuthPanel'), children:[ - {tag:'h3', html:"HTTP Auth"} +// {tag:'h3', html:"HTTP Auth"} ]} ]} ]} ]} ]}, {tag:'div', cls:'footer'} ]); this.tabPanelController().setup({selected:this.initiallySelectedTab()}); }, //------------------------------------------------------------------------- __syntaxFix__: "syntax fix" }); diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/AppController.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/AppController.js index 9a0e744..1ab2e69 100644 --- a/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/AppController.js +++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/AppController.js @@ -186,141 +186,166 @@ MochiKit.Base.update(Clipperz.PM.UI.Web.Controllers.AppController.prototype, { //----------------------------------------------------------------------------- 'populateUserInfo': function() { var deferredResult; deferredResult = new Clipperz.Async.Deferred("AppController.populateUserInfo", {trace:false}); deferredResult.collectResults({ 'username': MochiKit.Base.methodcaller('displayName'), 'cardsNumber': [ MochiKit.Base.methodcaller('getRecords'), function (someResults) { return someResults.length; } ], 'directLoginsNumber': [ MochiKit.Base.methodcaller('getDirectLogins'), function (someResults) { return someResults.length; } ] }) deferredResult.addMethod(this.userInfoBox(), 'updateUserDetails'); deferredResult.callback(this.user()); return deferredResult; }, //----------------------------------------------------------------------------- 'run': function(args) { var deferredResult; var slot; var page; var user; slot = args.slot; user = args.user; this.setUser(user); slot.setContent(this.appPage()); this.appPage().slotNamed('userInfoBox').setContent(this.userInfoBox()); this.appPage().slotNamed('tabSidePanel').setContent(this.tabSidePanel()); this.appPage().slotNamed('accountPanel').setContent(this.accountPanel()); this.appPage().slotNamed('dataPanel').setContent(this.dataPanel()); this.appPage().slotNamed('toolsPanel').setContent(this.toolsPanel()); this.hideAllAppPageTabSlots(); this.appPage().showSlot(this.slotNameForTab('cards')); - MochiKit.Signal.connect(this.tabSidePanel(), 'tabSelected', this, 'handleTabSelected'); - MochiKit.Signal.connect(this.tabSidePanel(), 'addCard', this, 'handleAddCard'); - MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, 'addCard', this, 'handleAddCard'); + MochiKit.Signal.connect(this.tabSidePanel(), 'tabSelected', this, 'handleTabSelected'); + MochiKit.Signal.connect(this.tabSidePanel(), 'addCard', this, 'handleAddCard'); + MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, 'addCard', this, 'handleAddCard'); + + MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, 'downloadOfflineCopy', this, 'handleDownloadOfflineCopy'); deferredResult = new Clipperz.Async.Deferred("AppController.run", {trace:false}); deferredResult.addMethod(this.cardsController(), 'run', {slot:this.appPage().slotNamed('cardGrid'), user:user}); // deferredResult.addMethod(this.directLoginsController(), 'run', {slot:this.appPage().slotNamed('directLoginGrid'), user:user}); deferredResult.addMethod(this, 'populateUserInfo'); deferredResult.addCallback(MochiKit.Visual.ScrollTo, 'miscLinks', {duration:0}); deferredResult.addCallback(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'CARDS_CONTROLLER_DID_RUN'); deferredResult.addMethod(this.tabSidePanel(), 'selectTab', 'cards'); deferredResult.callback(); }, //----------------------------------------------------------------------------- 'handleTabSelected': function (selectedTabName) { var aTabName; var aSlotName; //Clipperz.log(">>> AppController.handleTabSelected", selectedTabName); this.hideAllAppPageTabSlots(); this.appPage().showSlot(this.slotNameForTab(selectedTabName)); switch (selectedTabName) { case 'cards': this.cardsController().focus(); break; // case 'directLogins': // this.directLoginsController().focus(); // break; case 'data': break; case 'account': break; case 'tools': break; } //Clipperz.log("<-- AppController.handleTabSelected", aTabName); }, //============================================================================= 'handleAddCard': function (aSourceElement) { //Clipperz.log("=== AppController.addCard", aSourceElement); this.cardsController().addCard(aSourceElement); }, //============================================================================= 'userDataSuccessfullySavedHandler': function (anEvent) { this.populateUserInfo(); }, //============================================================================= 'handleLogout': function(anEvent) { var deferredResult; deferredResult = new Clipperz.Async.Deferred("AppController.handleLogout", {trace:false}); deferredResult.addMethod(this.user(), 'logout'); deferredResult.addCallback(MochiKit.Signal.signal, this, 'logout'); deferredResult.callback(); return deferredResult; }, //----------------------------------------------------------------------------- 'handleLock': function (anEvent) { return Clipperz.Async.callbacks("AppController.handleLock", [ MochiKit.Base.method(this.cardsController(), 'deleteAllCleanTextData'), MochiKit.Base.method(this.user(), 'lock') ], {trace:false}); }, //............................................................................. 'handleUnlock': function (anEvent) { return Clipperz.Async.callbacks("AppController.handleUnock", [ MochiKit.Base.partial(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'initProgress'), MochiKit.Base.method(this.user(), 'login'), MochiKit.Base.method(this.cardsController(), 'focus'), MochiKit.Base.partial(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'progressDone'), MochiKit.Base.method(this.userInfoBox(), 'unlock') ], {trace:false}); }, + 'handleDownloadOfflineCopy': function (anEvent) { +console.log("AppController.handleDownloadOfflineCopy"); + var downloadHref; + + downloadHref = window.location.href.replace(/\/[^\/]*$/,'') + Clipperz_dumpUrl; + + if (Clipperz_IEisBroken == true) { + window.open(downloadHref, ""); + } else { + var deferredResult; + var newWindow; + + newWindow = window.open("", ""); + + deferredResult = new Clipperz.Async.Deferred("AppController.handleDownloadOfflineCopy", {trace:true}); + deferredResult.addCallback(MochiKit.Base.method(this.user().connection(), 'message'), 'echo', {'echo':"echo"}); + deferredResult.addCallback(function(aWindow) { + aWindow.location.href = downloadHref; + }, newWindow); + deferredResult.callback(); + } + }, + //============================================================================= __syntaxFix__: "syntax fix" }); diff --git a/frontend/gamma/js/Clipperz/PM/UI/iPhone/Components/CardDetail.js b/frontend/gamma/js/Clipperz/PM/UI/iPhone/Components/CardDetail.js deleted file mode 100644 index 5380aa1..0000000 --- a/frontend/gamma/js/Clipperz/PM/UI/iPhone/Components/CardDetail.js +++ b/dev/null @@ -1,163 +0,0 @@ -/* - -Copyright 2008-2011 Clipperz Srl - -This file is part of Clipperz Community Edition. -Clipperz Community Edition is an online password manager. -For further information about its features and functionalities please -refer to http://www.clipperz.com. - -* Clipperz Community Edition 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. - -* Clipperz Community Edition 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 Clipperz Community Edition. If not, see - <http://www.gnu.org/licenses/>. - -*/ - -Clipperz.Base.module('Clipperz.PM.UI.iPhone.Components'); - -Clipperz.PM.UI.iPhone.Components.CardDetail = function(args) { - args = args || {}; - - Clipperz.PM.UI.iPhone.Components.CardDetail.superclass.constructor.apply(this, arguments); - - this._cardReference = null; - - return this; -} - -//============================================================================= - -Clipperz.Base.extend(Clipperz.PM.UI.iPhone.Components.CardDetail, Clipperz.PM.UI.Common.Components.BaseComponent, { - - //------------------------------------------------------------------------- - - 'toString': function () { - return "Clipperz.PM.UI.iPhone.Components.CardDetail component"; - }, - - //------------------------------------------------------------------------- - - 'cardReference': function () { - return this._cardReference; - }, - - 'setCardReference': function (aValue) { - this._cardReference = aValue; - }, - - //------------------------------------------------------------------------- - - 'renderSelf': function(/*aContainer, aPosition*/) { - this.append(this.element(), [ - {tag:'div', cls:'cardDetail', id:this.getId('cardDetail'), children:[ - {tag:'div', id:this.getId('progressBar')} //, -// {tag:'h1', cls:'loading', html:"loading"} - ]} - ]); - - this.addComponent(new Clipperz.PM.UI.Common.Components.ProgressBar({'element':this.getElement('progressBar')})); - MochiKit.Signal.signal(Clipperz.PM.UI.Common.Controllers.ProgressBarController.defaultController, 'updateProgress', 0); - }, - - //========================================================================= - - 'showCardDetails': function (someData) { - this.element().innerHTML = ''; - this.append(this.element(), [ - {tag:'fieldset', id:this.getId('fields'), children:MochiKit.Base.map(function (aFieldData) { - return {tag:'div', cls:'row', children:[ - {tag:'label', html:aFieldData['label']}, -// {tag:'span', cls:('fieldValue ' + (aFieldData['isHidden'] ? 'password' : 'text')), html:aFieldData['value']} - {tag:'div', cls:('fieldValue ' + (aFieldData['isHidden'] ? 'password' : 'text')), children:[ - {tag:'div', children:[{tag:'p', html:aFieldData['value']}]} - ]} -// {tag:'input', type:'text', cls:('fieldValue ' + (aFieldData['isHidden'] ? 'password' : 'text')), value:aFieldData['value'], disabled:true} - - ]} - }, someData['fields'])} - ]); - - MochiKit.Iter.forEach(MochiKit.Selector.findChildElements(this.element(), ['span.password']), MochiKit.Base.bind(function (aPasswordElement) { - MochiKit.Signal.connect(aPasswordElement, 'onclick', function (anEvent) { alert(MochiKit.DOM.scrapeText(anEvent.src())); }) - }, this)); - - if (someData['directLogins'].length > 0) { - this.append(this.element(), [ - {tag:'h2', html:"Direct logins"}, - {tag:'fieldset', id:this.getId('directLogins'), children:MochiKit.Base.map(function (aDirectLoginData) { - return {tag:'div', cls:'row', id:('directLogin_' + aDirectLoginData['_reference']), children:[ - {tag:'img', cls:'favicon', src:aDirectLoginData['favicon']}, -// {tag:'input', cls:'directLogin', disabled:'disabled', type:'text', name:aDirectLoginData['label'], value:aDirectLoginData['label']} - {tag:'span', cls:'directLogin', html:aDirectLoginData['label']} - ]} - }, someData['directLogins'])} - ]); - - MochiKit.Base.map(MochiKit.Base.bind(function (aRowNode) { - MochiKit.Signal.connect(aRowNode, 'onclick', this, 'directLoginClickHandler'); - }, this), - MochiKit.Selector.findChildElements(this.getElement('directLogins'), ['div.row']) - ) - }; - - if (someData['notes'] != '') { - this.append(this.element(), [ - {tag:'h2', html:"Notes"}, - {tag:'fieldset', id:this.getId('fieldset'), children:[ - {tag:'div', cls:'row notes', children:[ - {tag:'span', html:someData['notes']} - ]} - ]} - ]); - }; - - return true; - }, - - //------------------------------------------------------------------------- -/* - 'toggleClickHandler': function (anEvent) { - var nextState; - var fieldValue; - -//console.log("TOGGLE"); - anEvent.preventDefault; - fieldValue = MochiKit.Selector.findChildElements(anEvent.src().parentNode.parentNode, ['span.password'])[0]; - - nextState = (MochiKit.DOM.getNodeAttribute(anEvent.src(), 'toggled') != 'true'); - if (nextState) { - MochiKit.DOM.removeElementClass(fieldValue, 'clear'); - } else { - MochiKit.DOM.addElementClass(fieldValue, 'clear'); - } - - MochiKit.DOM.setNodeAttribute(anEvent.src(), 'toggled', nextState); - }, -*/ - //========================================================================= - - 'directLoginClickHandler': function (anEvent) { - anEvent.preventDefault(); - - if (/(directLogin_)/.test(anEvent.src().id)) { - var directLoginReference; - - directLoginReference = anEvent.src().id.match(/(directLogin_)(.*)/)[2]; - MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'selectedDirectLogin', {cardReference:this.cardReference(), directLoginReference:directLoginReference}); - } - }, - - //========================================================================= - - __syntaxFix__: "syntax fix" -}); diff --git a/frontend/gamma/js/Clipperz/PM/UI/iPhone/Components/LoginForm.js b/frontend/gamma/js/Clipperz/PM/UI/iPhone/Components/LoginForm.js deleted file mode 100644 index 5341878..0000000 --- a/frontend/gamma/js/Clipperz/PM/UI/iPhone/Components/LoginForm.js +++ b/dev/null @@ -1,178 +0,0 @@ -/* - -Copyright 2008-2011 Clipperz Srl - -This file is part of Clipperz Community Edition. -Clipperz Community Edition is an online password manager. -For further information about its features and functionalities please -refer to http://www.clipperz.com. - -* Clipperz Community Edition 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. - -* Clipperz Community Edition 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 Clipperz Community Edition. If not, see - <http://www.gnu.org/licenses/>. - -*/ - -Clipperz.Base.module('Clipperz.PM.UI.iPhone.Components'); - -Clipperz.PM.UI.iPhone.Components.LoginForm = function(args) { - args = args || {}; - - Clipperz.PM.UI.iPhone.Components.LoginForm.superclass.constructor.apply(this, arguments); - - return this; -} - -//============================================================================= - -Clipperz.Base.extend(Clipperz.PM.UI.iPhone.Components.LoginForm, Clipperz.PM.UI.Common.Components.BaseComponent, { - - //------------------------------------------------------------------------- - - 'toString': function () { - return "Clipperz.PM.UI.iPhone.Components.LoginForm component"; - }, - - //------------------------------------------------------------------------- - - 'focusOnUsername': function () { - this.getElement('username').focus(); - }, - - //------------------------------------------------------------------------- - - 'username': function () { - return this.getElement('username').value; - }, - - 'passphrase': function () { - return this.getElement('passphrase').value; - }, - - //------------------------------------------------------------------------- - - 'renderSelf': function(/*aContainer, aPosition*/) { - this.append(this.element(), [ - {tag:'div', cls:'toolbar iPhoneClipperzToolbar', children:[ - {tag:'h1', id:'pageTitle', html:'Clipperz'}, - {tag:'a', id:'backButton', cls:'button', href:'#', html:"back"} - ]}, - {tag:'form', title:'Theaters', cls:'panel toolbarlessPanel loginForm', id:this.getId('loginFormPanel'), children:[ - {tag:'fieldset', id:this.getId('fieldset'), children:[ - {tag:'div', cls:'row', children:[ - {tag:'label', html:"username"}, - {tag:'input', type:'text', name:'username', value:"", autocorrect:'off', autocapitalize:'off', id:this.getId('username')} - ]}, - {tag:'div', cls:'row', children:[ - {tag:'label', html:"passphrase"}, - {tag:'input', type:'password', name:'passphrase', value:"", id:this.getId('passphrase')} - ]} - ]}, - {tag:'a', cls:'whiteButton', type:'submit', href:'#', html:"Login", id:this.getId('submit')} - ]}, - {tag:'div', cls:'panel toolbarlessPanel loginProgressPanel', id:this.getId('loginProgressPanel'), children:[ - {tag:'div', id:this.getId('progressBar')} //, -// {tag:'a', cls:'whiteButton', type:'submit', href:'#', html:"Cancel", id:this.getId('cancel')} - ]}, - {tag:'div', cls:'panel loginErrorPanel', id:this.getId('loginErrorPanel'), children:[ - {tag:'div', cls:'errorMessage', id:this.getId('errorMessageBox'), children:[ - {tag:'h2', id:this.getId('errorMessage'), html:"Login failed"} - ]} - ]} - ]); - - MochiKit.Signal.connect(this.getElement('submit'), 'onclick', this, 'submitHandler'); - MochiKit.Signal.connect(this.getElement('loginFormPanel'), 'onsubmit', this, 'submitHandler'); - -// MochiKit.Signal.connect(this.getElement('cancel'), 'onclick', this, 'cancelHandler'); - MochiKit.Signal.connect('backButton', 'onclick', this, 'backHandler'); - - this.addComponent(new Clipperz.PM.UI.Common.Components.ProgressBar({'element':this.getElement('progressBar')})); - -// MochiKit.Style.hideElement(this.getElement('errorMessage')); - - this.showLoginForm(); -// MochiKit.Async.callLater(0.2, MochiKit.Base.method(this, 'focusOnUsername')); - }, - - //------------------------------------------------------------------------- - - 'showLoginForm': function () { - MochiKit.Style.showElement(this.getElement('loginFormPanel')); - MochiKit.Style.hideElement(this.getElement('loginProgressPanel')); - MochiKit.Style.hideElement(this.getElement('loginErrorPanel')); - MochiKit.Style.hideElement('backButton'); - }, - - 'slideInLoginForm': function () { - var offset; - - offset = ((MochiKit.DOM.getNodeAttribute(MochiKit.DOM.currentDocument().body, 'orientation') == 'portrait') ? 320 : 480); - - MochiKit.Style.showElement(this.getElement('loginFormPanel')); - MochiKit.Style.setElementPosition(this.getElement('loginFormPanel'), {x:-offset, y:0}); - - new MochiKit.Visual.Sequence([ - new MochiKit.Visual.Parallel([ - new MochiKit.Visual.Move(this.getElement('loginErrorPanel'), {x:offset, y:0, mode:'relative', transition:MochiKit.Visual.Transitions.linear, sync:true}), - new MochiKit.Visual.Move(this.getElement('loginFormPanel'), {x:0, y:0, mode:'absolute', transition:MochiKit.Visual.Transitions.linear, sync:true}), - MochiKit.Visual.fade ('backButton', { transition:MochiKit.Visual.Transitions.linear, sync:true}) - ], {duration:0.5, sync:true}), - MochiKit.Visual.fade(this.getElement('loginErrorPanel'), {duration:0, sync:true}) - ], {}) - }, - - 'showLoginProgress': function () { - MochiKit.Style.hideElement(this.getElement('loginFormPanel')); - MochiKit.Style.showElement(this.getElement('loginProgressPanel')); - }, - - 'showLoginError': function (anError) { - this.getElement('errorMessage').innerHTML = "Login error"; - - MochiKit.Style.showElement('backButton'); - MochiKit.Style.hideElement(this.getElement('loginProgressPanel')); - MochiKit.Style.showElement(this.getElement('loginErrorPanel')); - MochiKit.Style.setElementPosition(this.getElement('loginErrorPanel'), {x:0, y:45}); - }, - - //------------------------------------------------------------------------- -/* - 'disableCancelButton': function () { - MochiKit.DOM.hideElement(this.getElement('cancel')); - }, -*/ - //------------------------------------------------------------------------- - - 'submitHandler': function (anEvent) { - anEvent.preventDefault(); - - MochiKit.Signal.signal(this, 'doLogin', {'username':this.username(), 'passphrase':this.passphrase()}); - }, - - 'cancelHandler': function (anEvent) { - anEvent.preventDefault(); - -//console.log("CANCEL"); - }, - - 'backHandler': function (anEvent) { - anEvent.preventDefault(); - - this.slideInLoginForm(); - }, - - //------------------------------------------------------------------------- - - __syntaxFix__: "syntax fix" -}); diff --git a/frontend/gamma/js/Clipperz/PM/UI/iPhone/Controllers/MainController.js b/frontend/gamma/js/Clipperz/PM/UI/iPhone/Controllers/MainController.js deleted file mode 100644 index 3fcaae1..0000000 --- a/frontend/gamma/js/Clipperz/PM/UI/iPhone/Controllers/MainController.js +++ b/dev/null @@ -1,369 +0,0 @@ -/* - -Copyright 2008-2011 Clipperz Srl - -This file is part of Clipperz Community Edition. -Clipperz Community Edition is an online password manager. -For further information about its features and functionalities please -refer to http://www.clipperz.com. - -* Clipperz Community Edition 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. - -* Clipperz Community Edition 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 Clipperz Community Edition. If not, see - <http://www.gnu.org/licenses/>. - -*/ - -Clipperz.Base.module('Clipperz.PM.UI.iPhone.Controllers'); - -// Some parts of this controller have been derived from the iUI library. - -Clipperz.PM.UI.iPhone.Controllers.MainController = function() { - this._loginForm = null; - this._cardList = null; - this._cachedValues = null; - this._user = null; - - if (typeof window.onorientationchange == 'object') { - MochiKit.Signal.connect(window, 'onorientationchange', this, 'orientationChangeHandler'); - MochiKit.Async.callLater(0, MochiKit.Base.method(this, 'orientationChangeHandler')); - } else { - this.setOrientation('portrait'); -// this.setOrientation('landscape'); - } - - this.addMetaTag('viewport', 'width=devicewidth; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;'); - this.addMetaTag('apple-mobile-web-app-capable', 'yes'); - this.addMetaTag('apple-mobile-web-app-status-bar-style', 'black'); - - this.addLinkTag('apple-touch-icon', 'data:image/png;charset=utf-8;base64,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'); -// this.addLinkTag('apple-touch-startup-image', 'default.png'); - -// if (!window.navigator.standalone) // not running as an installed app - - MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, 'selectedDirectLogin', this, 'selectedDirectLoginHandler'); - - MochiKit.DOM.addElementClass(document.body, 'iPhone'); - return this; -} - -MochiKit.Base.update(Clipperz.PM.UI.iPhone.Controllers.MainController.prototype, { - - 'toString': function () { - return "Clipperz.PM.UI.iPhone.Controllers.MainController"; - }, - - //========================================================================= - - 'user': function () { - return this._user; - }, - - 'setUser': function (aValue) { - this._user = aValue; - }, - - //========================================================================= - - 'loginForm': function() { - if (this._loginForm == null) { - MochiKit.DOM.removeElement('mainDiv'); - this._loginForm = new Clipperz.PM.UI.iPhone.Components.LoginForm({element:MochiKit.DOM.currentDocument().body}); - MochiKit.Signal.connect(this._loginForm, 'doLogin', this, 'doLoginHandler') - } - - return this._loginForm; - }, - - 'removeLoginForm': function () { - if (this._loginForm != null) { - this._loginForm.remove(); - this._loginForm = null; - } - }, - - //----------------------------------------------------------------------------- - - 'cardList': function () { - if (this._cardList == null) { - this._cardList = new Clipperz.PM.UI.iPhone.Components.CardList({element:MochiKit.DOM.currentDocument().body}); - MochiKit.Signal.connect(this._cardList, 'searchEvent', this, 'searchEventHandler') - MochiKit.Signal.connect(this._cardList, 'selectedCard', this, 'selecetedCardHandler') - } - - return this._cardList; - }, - - //========================================================================= - - 'currentWidth': function () { - return this._currentWidth; - }, - - 'setCurrentWidth': function (aValue) { - this._currentWidth = aValue; - }, - - //========================================================================= - - 'orientationChangeHandler': function () { - switch(window.orientation) { - case 0: - this.setOrientation('portrait'); - break; - case 90: - case -90: - this.setOrientation('landscape'); - break; - } - }, - - //------------------------------------------------------------------------- - - 'setOrientation': function (anOrientation) { - document.body.setAttribute('orientation', anOrientation); - setTimeout(scrollTo, 100, 0, 1); - }, - - //------------------------------------------------------------------------- - - 'slidePages': function (fromPage, toPage, backwards) { - var axis; - var slideDone; - - slideDone = function () { - // console.log("slideDone"); - if (!hasClass(toPage, "dialog")) { - fromPage.removeAttribute("selected"); - } - checkTimer = setInterval(checkOrientAndLocation, 300); - setTimeout(updatePage, 0, toPage, fromPage); - fromPage.removeEventListener('webkitTransitionEnd', slideDone, false); - } - - axis = (backwards ? fromPage : toPage).getAttribute("axis"); - - clearInterval(checkTimer); - - if (canDoSlideAnim() && axis != 'y') { - slide2(fromPage, toPage, backwards, slideDone); - } else { - slide1(fromPage, toPage, backwards, axis, slideDone); - } - }, - - //------------------------------------------------------------------------- - - 'getCachedValues': function () { - var deferredResult; - - if (this._cachedObjects != null) { - deferredResult = MochiKit.Async.succeed(this._cachedObjects); - } else { - deferredResult = new Clipperz.Async.Deferred("MainController.getCachedValues", {trace:false}); - deferredResult.addMethod(this.user(), 'getRecords'); - deferredResult.addCallback(MochiKit.Base.map, Clipperz.Async.collectResults("MainController.getCachedValues - collectResults", { - '_rowObject': MochiKit.Async.succeed, - '_reference': MochiKit.Base.methodcaller('reference'), - 'label': MochiKit.Base.methodcaller('label'), - 'favicon': MochiKit.Base.methodcaller('favicon'), - '_searchableContent': MochiKit.Base.methodcaller('searchableContent') - }, {trace:false})); - deferredResult.addCallback(Clipperz.Async.collectAll); - deferredResult.addCallback(MochiKit.Base.bind(function (someRows) { - this._cachedObjects = someRows; - return this._cachedObjects; - }, this)); - deferredResult.callback(); - } - - return deferredResult; - }, - //========================================================================= - - 'run': function(shouldShowRegistrationForm) { - this.loginForm().render(); - MochiKit.Async.callLater(1, MochiKit.Base.method(this.loginForm(), 'focusOnUsername')); - }, - - //========================================================================= - - 'doLoginHandler': function (someArgs) { - var deferredResult; - var parameters; - var shouldUseOTP; -// var loginProgress; - var user; - var getPassphraseDelegate; - - parameters = someArgs; - shouldUseOTP = (typeof(parameters.passphrase) == 'undefined'); - - getPassphraseDelegate = MochiKit.Base.partial(MochiKit.Async.succeed, parameters.passphrase); - user = new Clipperz.PM.DataModel.User({'username':parameters.username, 'getPassphraseFunction':getPassphraseDelegate}); - - deferredResult = new Clipperz.Async.Deferred("MainController.doLogin", {trace:false}); - deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'initProgress', {'steps':4}); - deferredResult.addMethod(this.loginForm(), 'showLoginProgress'); - deferredResult.addCallback(MochiKit.Async.wait, 0.1); - deferredResult.addMethod(Clipperz.Crypto.PRNG.defaultRandomGenerator(), 'deferredEntropyCollection'); - deferredResult.addMethod(user, 'login'); - deferredResult.addMethod(this, 'setUser', user); - deferredResult.addMethod(user, 'getRecords'); - deferredResult.addMethod(this, 'removeLoginForm'); - deferredResult.addMethod(this.cardList(), 'render'); - deferredResult.addMethod(this, 'displaySelectedRecords', ''); - deferredResult.addErrback(MochiKit.Base.method(this.loginForm(), 'showLoginError')); - deferredResult.callback(); - - return deferredResult; - }, - - //========================================================================= - - 'searchEventHandler': function (aValue) { -//console.log("searching for ... " + aValue); - return this.displaySelectedRecords(aValue); - }, - - //========================================================================= - - '_displaySelectedRows': function (aFilter, someRows) { - var result; - - result = someRows; - - if (aFilter != null) { - var filter; - var filterRegExp; - - filter = aFilter.replace(/[^A-Za-z0-9]/g, "\\$&"); - filterRegExp = new RegExp(filter, "i"); - result = MochiKit.Base.filter(function (aCachedResult) { return filterRegExp.test(aCachedResult['_searchableContent'])}, result); - } - - - result.sort(MochiKit.Base.partial(function (aKey, aComparator, aObject, bObject) { - return aComparator(aObject[aKey], bObject[aKey]); - }, 'label', Clipperz.Base.caseInsensitiveCompare)); - - this.cardList().update(result); - }, - - //------------------------------------------------------------------------- - - 'displaySelectedRecords': function (aFilter) { - return Clipperz.Async.callbacks("MainController.displaySelectedrows", [ - MochiKit.Base.method(this, 'getCachedValues'), - MochiKit.Base.method(this, '_displaySelectedRows', aFilter) - ], {trace:false}); - }, - - //========================================================================= - - 'selecetedCardHandler': function (aRecordReference) { - var deferredResult; - var recordData; - - recordData = {}; -//console.log("Showing detail for card with reference", aRecordReference); - deferredResult = new Clipperz.Async.Deferred("MainController.selectedCardHandler", {trace:false}); - deferredResult.addMethod(this.user(), 'getRecord', aRecordReference); - deferredResult.collectResults({ - '_reference': MochiKit.Base.methodcaller('reference'), - 'title': MochiKit.Base.methodcaller('label'), - 'favicon': MochiKit.Base.methodcaller('favicon') - }); - deferredResult.addCallback(function (someData) { - MochiKit.Base.update(recordData, someData); - }) - deferredResult.addMethod(this.cardList(), 'showCard', recordData); - - deferredResult.addMethod(this.user(), 'getRecord', aRecordReference); - deferredResult.addMethodcaller('notes'); - deferredResult.addCallback(function (someNotes) { - recordData['notes'] = someNotes; - }) - - deferredResult.addMethod(this.user(), 'getRecord', aRecordReference); - deferredResult.addMethodcaller('getCurrentRecordVersion'); - deferredResult.addMethodcaller('fields'); - deferredResult.addCallback(MochiKit.Base.values); - deferredResult.addCallback(MochiKit.Base.map, Clipperz.Async.collectResults("MainController.selectedCardHandler - fields", { - 'label': MochiKit.Base.methodcaller('label'), - 'value': MochiKit.Base.methodcaller('value'), - 'isHidden': MochiKit.Base.methodcaller('isHidden') - }, {trace:false})); - deferredResult.addCallback(Clipperz.Async.collectAll); - deferredResult.addCallback(function (someData) { - recordData['fields'] = someData; - }); - - deferredResult.addMethod(this.user(), 'getRecord', aRecordReference); - deferredResult.addMethodcaller('directLogins'); - deferredResult.addCallback(MochiKit.Base.values); - deferredResult.addCallback(MochiKit.Base.map, Clipperz.Async.collectResults("MainController.selectedCardHandler - directLogins", { - 'label': MochiKit.Base.methodcaller('label'), - 'favicon': MochiKit.Base.methodcaller('favicon'), - '_reference': MochiKit.Base.methodcaller('reference') - }, {trace:false})); - deferredResult.addCallback(Clipperz.Async.collectAll); - deferredResult.addCallback(function (someData) { - recordData['directLogins'] = someData; - }); - - deferredResult.addMethod(this.cardList(), 'showCardDetails', recordData); - deferredResult.callback(); - - return deferredResult; - }, - - //========================================================================= - - 'selectedDirectLoginHandler': function (someData) { - var deferredResult; - -//console.log("<<< signal - directLogin"); - deferredResult = new Clipperz.Async.Deferred("MainController.selectedDirectLoginHandler", {trace:false}); - deferredResult.addMethod(this.user(), 'getRecord', someData['cardReference']); - deferredResult.addMethodcaller('directLogins'); - deferredResult.addCallback(MochiKit.Base.itemgetter(someData['directLoginReference'])); -// deferredResult.addMethodcaller('runDirectLogin'); - deferredResult.addCallback(Clipperz.PM.UI.Common.Controllers.DirectLoginRunner.openDirectLogin); - deferredResult.callback(); - - return deferredResult; - }, - - //========================================================================= - - 'addMetaTag': function (aName, aContent) { - var metaTag; - - metaTag = document.createElement('meta'); - metaTag.name = aName; - metaTag.content = aContent; - document.getElementsByTagName('head')[0].appendChild(metaTag); - }, - - 'addLinkTag': function (aRel, anHref) { - var linkTag; - - linkTag = document.createElement('link'); - linkTag.rel = aRel; - linkTag.href = anHref; - document.getElementsByTagName('head')[0].appendChild(linkTag); - }, - - //========================================================================= - __syntaxFix__: "syntax fix" -});
\ No newline at end of file diff --git a/frontend/gamma/js/main_iPhone.js b/frontend/gamma/js/main.mobile.js index 0644f68..60a32fa 100644 --- a/frontend/gamma/js/main_iPhone.js +++ b/frontend/gamma/js/main.mobile.js @@ -2,56 +2,63 @@ Copyright 2008-2011 Clipperz Srl This file is part of Clipperz Community Edition. Clipperz Community Edition is an online password manager. For further information about its features and functionalities please refer to http://www.clipperz.com. * Clipperz Community Edition 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. * Clipperz Community Edition 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 Clipperz Community Edition. If not, see <http://www.gnu.org/licenses/>. */ function _pm_logEvent(anEvent) { // console.log("####", anEvent); anEvent.preventDefault(); } function handleGenericDeferredError(anError) { var result; if (anError instanceof MochiKit.Async.CancelledError) { result = anError; } else { MochiKit.Logging.logError("## MainController - GENERIC ERROR" + "\n" + "==>> " + anError + " <<==\n" + anError.stack); result = new MochiKit.Async.CancelledError(anError); } return result; } Clipperz.PM.RunTime = {}; function run() { - MochiKit.DOM.removeElement('javaScriptAlert'); Clipperz.PM.Strings.Languages.initSetup(); - Clipperz.PM.RunTime.mainController = new Clipperz.PM.UI.iPhone.Controllers.MainController(); - Clipperz.PM.RunTime.mainController.run(false); + Clipperz.PM.RunTime.mainController = new Clipperz.PM.UI.Mobile.Controllers.MainController(); + Clipperz.PM.RunTime.mainController.run(); } +// if (navigator.standalone == false) { +// window.localStorage.setItem('PIN', '1234'); +// alert("Saved PIN"); +// } else { +// alert (window.localStorage.getItem('PIN')); +// } + + MochiKit.DOM.addLoadEvent(run); |