Commits

watermelon committed e08a5b5

sending end receiving bookmarks works but the de/encryption does not

Comments (0)

Files changed (11)

src/main/client/comm/Communicator.js

 	 * 		{	success: Boolean, true on success, else false
 	 * 			type: String, error type
 	 * 			msg: String, textual message, describing the error or success.
-	 * 		}
+	 * 		}, file || null
 	 **/
 	this.retrieveFile = function(file_type, callback) {
 		
 						break;
 					case 200://OK
 						console.info("bookmaak.comm.Communicator.retrieveFile: Status: "+jqXHR.status+" - Successfully retrieved "+file_type+" file of '"+login+"'!");
+						console.debug("bookmaak.comm.Communicator.retrieveFile: content: "+jqXHR.responseText);
 						callback({	success: true,
 									type: textStatus,
 									msg: "Successfully retrieved "+file_type+" file of "+login+"."

src/main/client/controller/Controller.js

  **/
 bookmaak.controller.Controller.communicator = null;
 
+/**
+ * bookmaak.controller.Controller.user_crypto -> BookmarkDao
+ * 
+ * to work on the encrypted user file... it is only set when a user is logged in
+ **/
+bookmaak.controller.Controller.user_crypto = null;
 
+/**
+ * bookmaak.controller.Controller.bookmark_dao -> BookmarkDao
+ * 
+ * the data access object for bookmarks... it is only set when a user is logged in
+ **/
+bookmaak.controller.Controller.bookmark_dao = null;
 
 
 
 	console.debug("bookmaak.controller.Controller.login: Trying to retrieve the user file...");
 	bookmaak.controller.Controller.communicator.retrieveFile(
 		bookmaak.controller.FILE_TYPE.USER,
-		function(result, file) {
+		function(result, user_file) {
 //		{	success: Boolean, true on success, else false
 //			type: String, error type
 //			msg: String, textual message, describing the error or success.
 //		}
 		if(result.success) {
+			
 			console.log("bookmaak.controller.Controller.login: Successfully retrieved user file!");
-			bookmaak.controller.Controller.login_name = login;
+			
+			//error markers
+			var have_private_key = false;
+			var have_public_key = false;
+			var have_bookmarks_file = false;
+			
+			//retrieve private and publik key from local store
+			var private_key = bookmaak.util.getSetting(
+										login,
+										bookmaak.util.SETTING_KEY.PRIVATE_KEY,
+										bookmaak.util.SETTING_TYPE.USER);
+			if(private_key != null)
+				have_private_key = true;
+			
+			var public_key = bookmaak.util.getSetting(
+										login,
+										bookmaak.util.SETTING_KEY.PUBLIC_KEY,
+										bookmaak.util.SETTING_TYPE.USER);
+			if(public_key != null)
+				have_public_key = true;
+			
+			if(have_private_key && have_public_key) {
+				
+				//in callback on success:
+				//XXX improve that code
+				bookmaak.controller.Controller.
+						user_crypto = new bookmaak.crypto.
+								UserCrypto(private_key, public_key);
+				
+				var sym_key_b64 = bookmaak.controller.Controller.
+						user_crypto.getSymmKeyFrom(user_file);
+				var bookmark_crypto = new bookmaak.crypto.BookmarkCrypto(sym_key_b64);
+				
+				
+				//remove and dereference sym_key
+				sym_key_b64 = "";
+				delete sym_key_b64;
+				
+				//get bookmarks
+				bookmaak.controller.Controller.
+						bookmark_dao = new bookmaak.dao.
+								BookmarkDao(login,
+								bookmaak.controller.Controller.communicator,
+								bookmark_crypto);
+				
+				bookmaak.controller.Controller.login_name = login;
+				
+				//TODO for testing we send some first...
+				bookmaak.controller.Controller.bookmark_dao.
+				addBookmark(new bookmaak.domain.Bookmark(
+						1,
+						'Wikipedia - Universal Software Radio Peripheral',
+						'http://en.wikipedia.org/wiki/Universal_Software_Radio_Peripheral',
+						['hardware','gnu','radio','usrp','universal','software','radio','periferal'],
+						['radio', 'gnu', 'wiki', 'wikipedia']));
+
+				bookmaak.controller.Controller.bookmark_dao.
+				addBookmark(new bookmaak.domain.Bookmark(
+						2,
+						'Wikipedia - Universal Software Radio Peripheral',
+						'http://en.wikipedia.org/wiki/Universal_Software_Radio_Peripheral',
+						['hardware','gnu','radio','usrp','universal','software','radio','periferal'],
+						['radio', 'gnu', 'wiki', 'wikipedia']));
+				
+				
+				bookmaak.controller.Controller.bookmark_dao.commit();
+
+				
+				//TODO on server error disconnect... in some clever way....
+			}
+			
+			
+			
 		}
 		else {
 			console.error("bookmaak.controller.Controller.login: Failed to retrieved user file!");

src/main/client/crypto/BookmarkCrypto.js

  * 
  * The constructor takes the symmKey.
  * 
- * **_symmKey** the symmetric key
+ * **_symm_Key** the symmetric key
  **/
-bookmaak.crypto.BookmarkCrypto = function BookmarkCrypto( _symmeKey) {
+bookmaak.crypto.BookmarkCrypto = function BookmarkCrypto( _symm_Key) {
 	
 	var that = this;
 	
 	 * ************************/
 	
 	//the key for the symmetrical de/encryption.
-	var symmKey = _symmKey;
+//	var symm_Key = _symm_Key;
+	
+	
+	//new instance
+	var aes = new pidCrypt.AES.CTR();
+	aes.init(_symm_Key, { nBits: bookmaak.SYM_KEY_LENGTH });//TODO that makes the whole sym key generation nonsense ?!
 	
 	
 	/* ************************
-     * * Functions
-     * ************************/
-     
+	 * * Functions
+	 * ************************/
+	
 	/**
 	 * bookmaak.crypto.BookmarkCrypto#encrypt(File) -> File
 	 * 
 	 * Encrypts a plain file.
 	 * 
-	 * **_plainFile** a plain file
+	 * **plain_file** a plain file<br/>
 	 * returns the encrypted file
 	 **/
-	this.encrypt = function(_plainFile) {
+	this.encrypt = function(plain_file) {
 		
-		//encrypt bm file with the symmKey
+		var type = plain_file.type;
 		
-		//return the encrypted file
+		if(type != bookmaak.controller.FILE_TYPE.BOOKMARKS)
+			throw "bookmaak.crypto.BookmarkCrypto.encrypt: plain_file is undefined or of wrong type";
+		
+		var data_plain = plain_file.data;
+		
+		//encrypt
+		var data_encrypted = aes.encrypt(data_plain);
+		
+		var cipher_file = new bookmaak.domain.File(type, data_encrypted);
+		var plain_again_file = this.decrypt(cipher_file);
+		console.log("DAS FUCKING VER/ENTSCHLÜSSEÖN HAUT NIXHT HIN::::::plain again file content");
+		console.log(plain_again_file.data);
+		return cipher_file;
 	};
 	
 	
 	 * 
 	 * Decrypts an encrypted file.
 	 * 
-	 * **_cipherFile** an encrypted file
+	 * **cipher_file** an encrypted file</br>
 	 * returns the plain file
 	 **/
-	this.decrypt = function(_cipherFile) {
-			
-		//decrypt bm file with the symmKey
+	this.decrypt = function(cipher_file) {
+		
+		var type = cipher_file.type;
+		
+		if(type != bookmaak.controller.FILE_TYPE.BOOKMARKS)
+			throw "bookmaak.crypto.BookmarkCrypto.decrypt: cipher_file is undefined or of wrong type";
+		
+		var data_encrypted = cipher_file.data;
+		
+		//decrypt
+		var data_plain = aes.decrypt(data_encrypted);
 	
-		//return the plain file
+		return new bookmaak.domain.File(type, data_plain);
 	};
 };

src/main/client/crypto/UserCrypto.js

  * users file.
  *
  * **_rsa_private_key_pem_encrypted** the pem formated encrypted private key
- * **_privateKey** the pem formated public key
+ * **_rsa_public_key_pem** the pem formated public key
  **/
 bookmaak.crypto.UserCrypto = function UserCrypto(_rsa_private_key_pem_encrypted, _rsa_public_key_pem) {
 	
 	/**
 	 * bookmaak.crypto.UserCrypto#getSymmKeyFrom(File) -> String
 	 *
-	 * **cipherFile** the encrypted users file.
+	 * **cipher_file** the encrypted users file.
 	 * returns the base64 encoded aes key
 	 **/
-	this.getSymmKeyFrom = function(cipherFile) {
+	this.getSymmKeyFrom = function(cipher_file) {
 		
-		var file_type = cipherFile.type;
-		var data_encrypted_b64 = cipherFile.data();
+		var file_type = cipher_file.type;
+		var data_encrypted_b64 = cipher_file.data;
 		
 		var data_encrypted = pidCryptUtil.decodeBase64(data_encrypted_b64);
 		
 		//var userData = "";//find the only valid text, which is the users sym
 		//key, guard by [symKey] and [/symKey]
 		
-		var user_symm_key = decrypted_data;
+		var user_symm_key = data_decrypted;
 		
 		return user_symm_key;
 	};

src/main/client/dao/BookmarkDao.js

  *
  * Setter for the communication layer.
  *
- * **_fileName** the name of the bookmark store file
+ * **_login** the name of the bookmark store file
  * **_comm** the communication object
- * **_bookmarkCrypto** the crypto layer object
+ * **_bookmark_crypto** the crypto layer object
  **/
-bookmaak.dao.BookmarkDao = function BookmarkDao(_fileName, _comm, _bookmarkCrypto) {
+bookmaak.dao.BookmarkDao = function BookmarkDao(_login, _comm, _bookmark_crypto) {
 //here we can allow other types like sql or harddisc access providers
 //TODO change communicator to provider	
 	var that = this;
 	 * ************************/
 	
 	//the file name of the bookmark store
-	var fileName = _fileName;
+	var login = _login;
 	
 	//the communicator to the actual bookmark store.
 	var comm = _comm;
 	
 	//the crypto layer object to en/decrypt the bookmark file.
-	var bookmarkCrypto = _bookmarkCrypto;
+	var bookmark_crypto = _bookmark_crypto;
 	
 	//the in-memory bookmark store
 	var bookmarks = new Array();
 		
 		//TODO do cleanup if necessary
 		
-		sendBookmarks(bookmarks);
+		sendBookmarks();
 		
 		return true;
 	};
 	 **/
 	this.addBookmark = function(bm) {
 		
-		return true;
+		return bookmarks.push(bm);
 	};
 	
 	
 	 **/
 	this.getAllBookmark = function() {
 		
-		return new Array();
+
+//		return new Array();
 	};
 	
 	
 	
 	
 	/* ************************
-     * * Private functions
-     * ************************/
-     
+	 * * Private functions
+	 * ************************/
+	
 	/**
 	 * bookmaak.dao.BookmarkDao#fetchBookmarks()
 	 * 
 	function fetchBookmarks() {
 		
 		//retrieve the bookmarks as file
-		//comm.get(filename)
-		
-		//decrypt it
-		//bookmarkCrypto.decrpyt...
-		
-		//dump all of them into bookmarks
-		//...
+		comm.retrieveFile(
+			bookmaak.controller.FILE_TYPE.BOOKMARKS,
+			function(result, bookmarks_file_cipher) {
+				
+				if(result.success) {
+					
+					console.log("bookmaak.dao.BookmarkDao.fetchBookmarks: File content cipher: v");
+					console.log(bookmarks_file_cipher.data);
+					
+					//decrypt it
+					var bookmarks_file_plain = bookmark_crypto.decrypt(bookmarks_file_cipher);
+					
+					console.log("bookmaak.dao.BookmarkDao.fetchBookmarks: File content plain: v");
+					console.log(bookmarks_file_plain.data);
+					
+					if(bookmarks_file_plain.data != "") {
+						var bookmarks_file_plain_data = JSON.parse(bookmarks_file_plain.data);
+						console.log("bookmaak.dao.BookmarkDao.fetchBookmarks: File content plain: "+bookmarks_file_plain_data);
+						
+						//TODO fill in to array...
+					}
+					else
+						console.log("bookmaak.dao.BookmarkDao.fetchBookmarks: You have no bookmarks yet!");
+					
+				}
+				else {
+	//				result.type: String, error type
+	//				result.msg: String, textual message, describing the error or success.
+				}
+		});
 	}
 	
 	
 	function sendBookmarks() {
 		
 		//make a file of the bookmarks
+		var bookmarks_file_plain = new bookmaak.domain.File();
+		bookmarks_file_plain.type = bookmaak.controller.FILE_TYPE.BOOKMARKS;
+		
+		console.log("bookmaak.dao.BookmarkDao.sendBookmarks: bookmarks to be sent: v");
+		console.log(bookmarks);
+		
+		for(var i = 0; i < bookmarks.length; i++){
+			
+			var bm = JSON.stringify(
+					{
+						id: bookmarks[i].getId(),
+						title: bookmarks[i].getTitle(),
+						url: bookmarks[i].getUrl(),
+						tags: bookmarks[i].getTags(),
+						metas: bookmarks[i].getMetas()
+			});
+			bookmarks_file_plain.data += bm;
+		}
+		
+		console.log("bookmaak.dao.BookmarkDao.sendBookmarks: all bookmarks in json: v");
+		console.log(bookmarks_file_plain.data);
+		
+		console.log("bookmaak.dao.BookmarkDao.sendBookmarks: all bookmarks in file content: v");
+		console.log(bookmarks_file_plain.data);
 		
 		//encrypt it
+		var bookmarks_file_cipher = bookmark_crypto.encrypt(bookmarks_file_plain);
+		
+		console.log("bookmaak.dao.BookmarkDao.sendBookmarks: all bookmarks in encrypted file: v");
+		console.log(bookmarks_file_cipher.data);
 		
 		//send it to the server
+		comm.sendFile(bookmarks_file_cipher, function(result) {
+			
+//			{	success: Boolean, true on success, else false
+//				type: String, type of the error or the textStatus on success
+//				msg: String, textual message, describing the error or success.
+//			}
+			console.log("bookmaak.dao.BookmarkDao.sendBookmarks: send report: v");
+			console.log(result);
+			
+			//TODO for debugging
+			fetchBookmarks();
+		});
 	}
-	
-	
-	
-	/* ************************
-     * * Setters
-     * ************************/
-	
-	/**
-	 * bookmaak.dao.BookmarkDao#setFileName(String)
-	 *
-	 * Sets the (file) name of the bookmark store.
-	 * To retrieve the bookmark store via the communicator,
-	 * a (file) name is necessary
-	 *
-	 * **_fileName** the new name of the bookmark store
-	 **/
-	this.setFileName = function(_fileName) {
-		
-		fileName = _fileName;
-	};
-	
-	
-	/**
-	 * bookmaak.dao.BookmarkDao#setComm(Communicator)
-	 *
-	 * Sets the communicator to the bookmark store.
-	 * Bookmark files are accessed via the communicator.
-	 *
-	 * **_comm** the new communicator to the bookmark store
-	 **/
-	this.setComm = function(_comm) {
-		
-		comm = _comm;
-	};
-	
-	
-	/**
-	 * bookmaak.dao.BookmarkDao#setBookmarkCrypto(BookmarkCrypto)
-	 *
-	 * Sets the bookmark crypto object.
-	 * Bookmark files are encrypted symmetraically.
-	 *
-	 * **_bookmarkCrypto** the new crypto layer object to decrypt the bookmarks
-	 **/
-	this.setBookmarkCrypto = function(_bookmarkCrypto) {
-		
-		bookmarkCrypto = _bookmarkCrypto;
-	};
 };

src/main/client/domain/Bookmark.js

 /**
  * class bookmaak.domain.Bookmark
  *
- * This file contains the class of the Bookmark domain object.
+ * The Bookmark domain object.
  **/
 
 
 /**
  * new bookmaak.domain.Bookmark(String, String[, Array[, Array]])
  *
- * **_title** the title of the bookmark (i.e. the page's title)
- * **_url** the page url
- * **_tags (optional)** a list of tags
+ * **_id** the id of the bookmark (to identify it for updating/deleting)<br/>
+ * **_title** the title of the bookmark (i.e. the page's title)<br/>
+ * **_url** the page url<br/>
+ * **_tags (optional)** a list of tags<br/>
  * **_metas (optional)** a list of meta tags retrieved from the page's header
  **/
-bookmaak.domain.Bookmark = function Bookmark(_title, _url, _tags, _metas) {
+bookmaak.domain.Bookmark = function Bookmark(_id, _title, _url, _tags, _metas) {
 	
 	var that = this;
 	
 	 * * Members
 	 * ************************/
 	
+	//the id of the bookmark
+	var id = _id;
+	
 	//title of the link, i.e. the page title
 	var title = _title;
 	
 	//the webpage's meta tags
 	var metas = _metas;
 	
+	//the revisions of the bookmark
+	var local_revisions = new Array();
+	
 	
 	/* ************************
 	 * * Functions
 	 * ************************/
 	
 	/**
+	 * bookmaak.domain.Bookmark#changeTitle(String)
+	 *
+	 * TODO needs testing
+	 *
+	 * **_title** changes the title of the bookmark
+	 **/
+	this.changeTitle = function(_title) {
+		
+		title = _title;
+		
+		local_revisions.push(new bookmaak.domain.
+				BookmarkRevision(
+					id, 
+					bookmaak.domain.REV_OPERATION.UPDATE,
+					{new_title: title}));
+	};
+	
+	/**
+	 * bookmaak.domain.Bookmark#changeUrl(String)
+	 *
+	 * TODO needs testing
+	 *
+	 * **_url** changes the url of the bookmark
+	 **/
+	this.changeUrl = function(_url) {
+		
+		url = _url;
+		
+		local_revisions.push(new bookmaak.domain.
+			BookmarkRevision(
+				id, 
+				bookmaak.domain.REV_OPERATION.UPDATE,
+				{new_url: url}));
+	};
+	
+	/**
 	 * bookmaak.domain.Bookmark#addTag(String)
 	 *
 	 * TODO needs testing
 	 *
-	 * **_tag** the tag to be added to the Bookmark#
+	 * **_tag** the tag to be added to the bookmark
 	 **/
 	this.addTag = function(_tag) {
+		
+		tags.push(_tag);
+		
+		local_revisions.push(new bookmaak.domain.
+				BookmarkRevision(
+						id, 
+						bookmaak.domain.REV_OPERATION.UPDATE,
+						{new_tags: tags}));
+	};
 	
-		tags.push(_tag);
-	};
-
 	/**
 	 * bookmaak.domain.Bookmark#removeTag(String)
 	 *
 	 * TODO needs testing
 	 *
-	 * **_tag** the tag to be removed from the Bookmark#
+	 * **_tag** the tag to be removed from the bookmark
 	 **/
 	this.removeTag = function(_tag) {
-	
+		
 		for (var i = 0; i <= tags.length; i++) {
 			
 			if(tags[i] == _tag) {
-
+				
 				tags.slice(i, 1);
 				break;
 			}
 		}
+		
+		local_revisions.push(new bookmaak.domain.
+				BookmarkRevision(
+						id, 
+						bookmaak.domain.REV_OPERATION.UPDATE,
+						{new_tags: tags}));
 	};
-
+	
 	/**
 	 * bookmaak.domain.Bookmark#addMeta(String)
 	 *
 	 * TODO needs testing
 	 *
-	 * **_meta** the meta tag to be added to the Bookmark#
+	 * **_meta** the meta tag to be added to the bookmark
 	 **/
 	this.addMeta = function(_meta) {
+		
+		metas.push(_meta);
+		
+		local_revisions.push(new bookmaak.domain.
+				BookmarkRevision(
+					id, 
+					bookmaak.domain.REV_OPERATION.UPDATE,
+					{new_metas: metas}));
+	};
 	
-		metas.push(_meta);
-	};
-
 	/**
 	 * bookmaak.domain.Bookmark#removeMeta(String)
 	 *
 	 * TODO needs testing
 	 *
-	 * **_meta** the meta tag to be removed from the Bookmark#
+	 * **_meta** the meta tag to be removed from the bookmark
 	 **/
 	this.removeMeta = function(_meta) {
-	
+		
 		for (var i = 0; i <= metas.length; i++) {
 			
 			if(metas[i] == _meta) {
-
+				
 				metas.slice(i, 1);
 				break;
 			}
 		}
+		
+		local_revisions.push(new bookmaak.domain.
+				BookmarkRevision(
+					id, 
+					bookmaak.domain.REV_OPERATION.UPDATE,
+					{new_metas: metas}));
 	};
-
+	
 	/**
 	 * bookmaak.domain.Bookmark#getAsText() -> String
 	 *
-	 * returns a string representation of the Bookmark#
+	 * returns a string representation of the bookmark
 	 **/
 	this.getAsText = function() {
-	
+		
 		return title + ' - ' + url;
 	};
-
+	
 	/**
 	 * bookmaak.domain.Bookmark#getAsHtmlLink() -> String
 	 *
 	 * returns the bookmark as html <a href=...
 	 **/
 	this.getAsHtmlLink = function() {
-	
+		
 		return '<a href="' + url + '">' + title + '</a>';
 	};
 	
-
+	
 	
 	/* ************************
-     * * Getters
-     * ************************/
-
+	 * * Getters
+	 * ************************/
+	
+	/**
+	 * bookmaak.domain.Bookmark#getId() -> Number
+	 *
+	 * returns the id of the bookmark
+	 **/
+	this.getId = function() {
+		
+		return id;
+	};
+	
 	/**
 	 * bookmaak.domain.Bookmark#getTitle() -> String
 	 *
-	 * returns the title of the Bookmark#
+	 * returns the title of the bookmark
 	 **/
 	this.getTitle = function() {
-
+		
 		return title;
 	};
-
+	
 	/**
 	 * bookmaak.domain.Bookmark#getUrl() -> String
 	 *
-	 * returns the url of the Bookmark#
+	 * returns the url of the bookmark
 	 **/
 	this.getUrl = function() {
-
+		
 		return url;
 	};
-
+	
 	/**
 	 * bookmaak.domain.Bookmark#getTags() -> Array
 	 *
-	 * returns the tags of the Bookmark#
+	 * returns the tags of the bookmark
 	 **/
 	this.getTags = function() {
-
+		
 		return tags;
 	};
-
+	
 	/**
 	 * bookmaak.domain.Bookmark#getMetas() -> Array
 	 *
-	 * returns the meta tags of the Bookmark#
+	 * returns the meta tags of the bookmark
 	 **/
 	this.getMetas = function() {
 		
 		return metas;
 	};
-
-
-
+	
+	/**
+	 * bookmaak.domain.Bookmark#getLocalRevisions() -> Array
+	 *
+	 * returns the revisions of the bookmark(all locally made changes)
+	 **/
+	this.getLocalRevisions = function() {
+		
+		return local_revisions;
+	};
+	
+	
 	/* ************************
-     * * Setters
-     * ************************/
-
-	/**
-	 * bookmaak.domain.Bookmark#setTitle(String)
-	 *
-	 * Sets the title of the bookmark to _title.
-	 *
-	 * **_title** the new title of the bookmark
-	 **/
-	this.setTitle = function(_title) {
-		
-		title = _title;
-	};
-
-	/**
-	 * bookmaak.domain.Bookmark#setUrl(String)
-	 *
-	 * Sets the url of the bookmark to _url.
-	 *
-	 * **_url** the new url of the bookmark
-	 **/
-	this.setUrl = function(_url) {
-		
-		url = _url;
-	};
-
-	/**
-	 * bookmaak.domain.Bookmark#setTags(Array)
-	 *
-	 * Sets the tags of the bookmark to _tags.
-	 *
-	 * **_tags** array the new tags of the bookmark
-	 **/
-	this.setTags = function(_tags) {
-		
-		tags = _tags;
-	};
-
-	/**
-	 * bookmaak.domain.Bookmark#setMetas(Array)
-	 *
-	 * Sets the meta tags of the bookmark to _metas.
-	 *
-	 * **_tags** array the new meta tags of the bookmark
-	 **/
-	this.setMetas = function(_metas) {
-		
-		metas = _metas;
-	};
-
-
-	/* ************************
-     * * Overwritten functions
-     * ************************/
-
+	 * * Overwritten functions
+	 * ************************/
+	
 	/**
 	 * bookmaak.domain.Bookmark#toString() -> String
 	 *
 	 * returns A string representation of the bookmark.
 	 **/
 	this.toString = function() {
-
+		
 		return ""
 				+ "title: " + title + "\n"
 				+ "url: " + url + "\n"
 				+ "metas: " + metas + "\n";
 	};
 };
+
+
+/**
+ * bookmaak.domain.REV_OPERATION = CREATE | UPDATE | DELETE
+ * 
+ * The operations available on bookmarks
+ **/
+bookmaak.domain.REV_OPERATION = {
+	
+	CREATE: "create",
+	UPDATE: "update",
+	DELETE: "delete"
+};
+
+
+
+/**
+ * class bookmaak.domain.BookmarkRevision
+ *
+ * A revision of a bookmark domain object.<br/>
+ * It contains the new/updated data that was performed.
+ **/
+
+/**
+ * new bookmaak.domain.BookmarkRevision(Number, REV_OPERATION[, Object])
+ *
+ * **_bookmark_id** the id of the bookmark that was revised<br/>
+ * **_operation** the operation performed on the bookmark<br/>
+ * operation = CREATE | UPDATE | DELETE
+ * **_new_data** in case of update, the new data as follows:
+ * {	[new_title: String]
+ * 		[new_url: String]
+ * 		[new_tags: String]
+ * 		[new_metas: String]
+ * }
+ **/
+bookmaak.domain.BookmarkRevision = function BookmarkRevision(	_bookmark_id, 
+																_operation, 
+																_new_data) {
+	
+	/* ************************
+	 * * Members
+	 * ************************/
+	
+	//the revision time
+	var timestamp = (new Date()).getTime();
+	
+	//id of the bookmark that was revised
+	var bookmark_id = _bookmark_id;
+	
+	//the operation that was done on the bookmark
+	var operation = _operation;
+	
+	var new_data = _new_data;
+	
+	if(_operation === bookmaak.domain.REV_OPERATION.UPDATE)
+		bookmaak.util.checkType(_new_data, "_new_data", bookmaak.util.TYPE.OBJECT);
+	
+	
+//	/* ************************
+//	 * * Functions
+//	 * ************************/
+//	TODO revision merging is done by the bookmarkdao....
+//	/**
+//	 * bookmaak.domain.BookmarkRevision#equals(BookmarkRevision) -> Boolean
+//	 * 
+//	 * **other** the revision to compare with<br/>
+//	 * returns true if the revisions are equal in every matter.
+//	 **/
+//	this.equals = function(other) {
+//		
+//		if(this.bookmark_id === other.getBookmarkId()
+//		&& this.timestamp === other.getTimestamp()
+//		&& this.operation === other.getOperation()) {
+//			//the properties are the same, now we check the new_data
+//			var other_new_data = other.getNewData();
+//			
+//			for(var property in new_data) {
+//				
+//				//on the first not matching property or property value we return false
+//				if(this.new_data[property] !== other_new_data[property])
+//					return false;
+//			}
+//			
+//			return true;
+//		}
+//		else {
+//			return false;
+//		}
+//	};
+//	
+//	/**
+//	 * bookmaak.domain.BookmarkRevision#interferesWith(BookmarkRevision) -> Boolean
+//	 * 
+//	 * **other** the revision to compare with<br/>
+//	 * returns true when the chances are not compatible.<br/>
+//	 * That is if the bookmark id and timestamp are the same but the operation 
+//	 * and/or the new data is in conflict
+//	 **/
+//	this.interferesWith = function(other) {
+//		
+//		//create should not be revisioned
+//		if(this.operation === bookmaak.domain.REV_OPERATION.CREATE
+//		|| other.getOperation() === bookmaak.domain.REV_OPERATION.CREATE)
+//			throw "bookmaak.domain.BookmarkRevision.interferesWith: "
+//			+"both revs have a create op... that may not happen?!";
+//		
+//		
+//		//XXX this is not very self explanatory...
+//		if(this.bookmark_id === other.getBookmarkId()
+//		&& this.timestamp === other.getTimestamp()) {
+//			
+//			if(other.operation === bookmaak.domain.REV_OPERATION.DELETE) {
+//				
+//				if(this.operation === other.getOperation())
+//					return true;//our delete will be taken(to eliminate duplicate deletes)
+//				else//the other wants to delete, but we do not
+//					return true;
+//			}
+//			else {//if(other.operation === bookmaak.domain.REV_OPERATION.UPDATE)
+//				
+//				if(this.operation === other.getOperation()) {
+//					
+//					//the properties are the same, now we check the new_data
+//					var other_new_data = other.getNewData();
+//					
+//					for(var property in new_data) {
+//						
+//						//on the first not matching property or property value we return false
+//						if(this.new_data[property] !== other_new_data[property])
+//							return false;
+//					}
+//				}
+//				else//the other wants to update, but we do not (this means we want delete)
+//					return true;
+//			}
+//		}
+//	};
+	
+	
+	/* ************************
+	 * * Getters
+	 * ************************/
+	
+	/**
+	 * bookmaak.domain.BookmarkRevision#getTimestamp() -> Number
+	 * 
+	 * returns the time of revision
+	 **/
+	this.getTimestamp = function getTimestamp() {
+		
+		return timestamp;
+	};
+	
+	/**
+	 * bookmaak.domain.BookmarkRevision#getOperation() -> String
+	 * 
+	 * returns the operation performed
+	 **/
+	this.getOperation = function getOperation() {
+		
+		return operation;
+	};
+	
+	/**
+	 * bookmaak.domain.BookmarkRevision#getBookmarkId() -> Number
+	 * 
+	 * returns the id of the revised bookmark
+	 **/
+	this.getBookmarkId = function getBookmarkId() {
+		
+		return bookmark_id;
+	};
+	
+	/**
+	 * bookmaak.domain.BookmarkRevision#getNewData() -> Object
+	 *
+	 * returns the an object containing the new properties of the bookmark
+	 **/
+	this.getNewData = function getNewData() {
+		
+		return new_data;
+	};
+};
+

src/main/client/domain/File.js

 	 * * Members
 	 * ************************/
 	
-	this.type = _type;
+	this.type = _type || "";
 	
-	this.data = _data;
+	this.data = _data || "";
 };

src/main/client/util/Settings.js

  * **_login** the user<br/>
  * **_key** the key<br/>
  * **_type** the type<br/>
- * returns true on success, otherwise false.
+ * returns the value on success, otherwise null.
  **/
 bookmaak.util.getSetting = function(_login, _key, _type) {
 	
 	var serialized_value = localStorage.getItem(prefixed_key);
 	
 	console.log("getSetting: got value: "+serialized_value);
-	console.log("getSetting: got value: "+JSON.pares(serialized_value));
+	console.log("getSetting: got value: "+JSON.parse(serialized_value));
 	
 	if(serialized_value == null)
-		return true;
+		return null;
 	else
 		return JSON.parse(serialized_value);
 }

src/main/server/srv.js

     });
   
   fs.readFile(BASE_DIR + rel_path, function(err,data){
-    
+  
     if(!err){
+      console.log("Data to be sent: "+data);
       res.writeHead(200,default_header({'Content-Type': 'text/bookmaak.bookmark.crypt'}));
       res.end(data);
     }else{
-      respond_404(res);
+      //empty file....
+      console.log("Error, sending: nothing");
+      console.error(err);
+      res.writeHead(200,default_header({'Content-Type': 'text/bookmaak.bookmark.crypt'}));
+      res.end("");
     }
 
   });
  *
  * This function receives a bookmark file to who ever sent it.
 **/
-function receive_bookmarks(res, rel_path, content){
+function receive_bookmarks(req, res, rel_path){
 	
 	console.log('receive_bookmarks('+rel_path+')');
 	fs.realpath(BASE_DIR + rel_path, function(err, resolvedPath) {
 		console.log(resolvedPath);
 	});
 	
-	var data = "";
-	req.data = function(chunk) {
-		data += chunk;
-	};
+	var body = '';
+	req.on('data', function (data) {
+		body += data;
+		console.log("Data: "+data);
+	});
 	
-	fs.writeFile(BASE_DIR + rel_path, data, function (err) {
+	
+	//write to file
+	req.on('end', function() {
 		
-		if(!err) {
+		//check if file exists
+		fs.stat(BASE_DIR + rel_path, function(err, stats) {
 			
-			res.writeHead(201,default_header({'Content-Type': 'text/plain'}));
-			res.end();
-		}
-		else{
-			//TODO handle all errors ... also the unknown
-			respond_404(res);
-		}
+			if(err 
+			&& err.errno == 34 
+			&& err.code == 'ENOENT') {//user does not exist...
+				
+				//we overwrite it
+				fs.open(BASE_DIR + rel_path, 'w', 770, function( e, fd ) {
+					
+					fs.write( fd, body, 0, body.length, 0, function(){
+						
+						fs.close(fd, function() {
+							console.log('file closed');
+							res.writeHead(201,default_header({'Content-Type': 'text/plain'}));
+							res.end();
+							
+							console.log('It\'s saved!');
+						});
+					});
+				});
+			}
+			else if(err) {//an other error
+				
+				console.log("Unexpected error!");
+				console.log(err);
+				throw err;
+			}
+			else {//bookmark file exists
+				console.log("stats.isFile(): "+stats.isFile());
+				console.log("stats.isDirectory(): "+stats.isDirectory());
+				
+				if(stats.isFile()) {
+					
+					//we overwrite it 'a' would append...
+					fs.open(BASE_DIR + rel_path, 'w', 666, function( e, id ) {
+						
+						fs.write( id, body, null, 'utf8', function(){
+							
+							fs.close(id, function() {
+								console.log('file closed');
+								res.writeHead(201,default_header({'Content-Type': 'text/plain'}));
+								res.end();
+								
+								console.log('It\'s saved!');
+							});
+						});
+					});
+				}
+				else {
+					throw "bookmarks is not a file";
+				}
+			}
+		});
 	});
 }
 
  *                shall be created. this path is relative to BASE_DIR.
 **/
 function receive_user(req, res, rel_path){
-
+	
 	console.log('receive_users('+rel_path+')');
-
-  if( !path.existsSync(path.dirname(BASE_DIR+rel_path)) ){
-    fs.mkdirSync(path.dirname(BASE_DIR+rel_path));
-  }
-
+	
+	if( !path.existsSync(path.dirname(BASE_DIR+rel_path)) ){
+		fs.mkdirSync(path.dirname(BASE_DIR+rel_path));
+	}
+	
 	fs.realpath(BASE_DIR + rel_path, function(err, resolvedPath) {
 		console.log(resolvedPath);
 	});

src/test/client/test.bm

       tags: ['hardware','gnu','radio','usrp','universal','software','radio','periferal'],
       metas: ['radio', 'gnu', 'wiki', 'wikipedia']
     },
-    {}
+    { title: 'Wikipedia - Universal Software Radio Peripheral',
+      url: 'http://en.wikipedia.org/wiki/Universal_Software_Radio_Peripheral',
+      tags: ['hardware','gnu','radio','usrp','universal','software','radio','periferal'],
+      metas: ['radio', 'gnu', 'wiki', 'wikipedia']
+    }
   ]
 }
+
 add lib/pidCrypt_uncompressed/md5.js
 add lib/pidCrypt_uncompressed/aes_core.js
 add lib/pidCrypt_uncompressed/aes_cbc.js
+add lib/pidCrypt_uncompressed/aes_ctr.js
 add lib/pidCrypt_uncompressed/rsa.js
 add lib/pidCrypt_uncompressed/jsbn.js
 add lib/pidCrypt_uncompressed/string_extend.js