Commits

watermelon committed 79ab512

major refactoring:
moved validation into a separate file
cleanup of controller, uiController, communicator
added more solid type checking
BUG: regexp for public key validation does not do what it's supposed to

  • Participants
  • Parent commits 26877ad

Comments (0)

Files changed (12)

File src/main/client/comm/Communicator.js

  *
  * The Communicator constructor.
  * 
- * **_login** so that the server can determine which users files to access
+ * **_login** so that the server can determine which users files to access<br/>
  * **_server_url** the url of the server
  **/
 bookmaak.comm.Communicator = function Communicator(_login, _server_url) {
 	 * ************************/
 	
 	//the user's login
-	if(typeof _login == 'undefined')
-		throw "_login is undefined.";
-	else if(Object.prototype.toString.call(_login) == "[object String]")
-			var login = _login;
-	else
-		throw "illegal argument _login.";
+	var login = _login;
 	
 	//the server url
-	if(typeof _server_url == 'undefined')
-		throw "_server_url is undefined.";
-	else if(Object.prototype.toString.call(_server_url) == "[object String]")
-			var server_url = _server_url;
-	else
-		throw "illegal argument _server_url.";
-	
+	var server_url = _server_url;
 	
 	
 	/* ************************
 	/**
 	 * Communicator#retrieveFile(String, Function)
 	 * 
-	 * **_file_type** the file to retrieve BOOKMARK or USER
-	 * **callback** callback, passsing result and File
+	 * **file_type** the file to retrieve BOOKMARK or USER<br/>
+	 * **callback** callback, passsing result and File<br/>
 	 * returns	calls callback with a result as
-	 * 		{	
-	 * 			success: Boolean, true on success, else false
+	 * 		{	success: Boolean, true on success, else false
 	 * 			type: String, error type
 	 * 			msg: String, textual message, describing the error or success.
 	 * 		}
 	 **/
-	this.retrieveFile = function(_file_type, callback) {
-		
-		if(typeof callback != typeof Function)
-			throw "callback is undefined or not a function.";
-		
-		//check file_type
-		if(typeof _file_type == 'undefined')
-			throw "_file_type is undefined.";
-		else if(Object.prototype.toString.call(_file_type) == "[object String]")
-			var file_type = _file_type;
-		else
-			throw "illegal argument _file_type.";
+	this.retrieveFile = function(file_type, callback) {
 		
 		switch(file_type) {
 			case bookmaak.controller.FILE_TYPE.USER:
 				var mime_type = "text/bookmaak."+file_type+".crypt";
 				break;
 			default:
-				throw "unknown _file_type.";
+				throw "unknown file_type.";
 		}
 		
+		console.debug("Trying to retrieve "+file_type+" file of '"+login+"'");
+		console.debug("MIME-Type: "+mime_type);
 		jQuery.ajax({
-			url: server_url + '/' + login + '/' + file_type,
+			url: server_url + login + '/' + file_type,
 			type: "GET",
 			crossDomain: true,
 			mimeType: mime_type,
-			success: function(data, textStatus, jqXHR) {
+			complete: function(jqXHR, textStatus) {
 				
+				//TODO check response mime type...
 				switch(jqXHR.status) {
 					case 404://NOT FOUND
-						callback({
-							success: false,
-							type: textStatus,
-							msg: file_type+" file of "+login+" not found."
-							}, null);
+						console.info("Status: "+jqXHR.status+" - Failed to retrieved "+file_type+" file of '"+login+"', it odes not exist!");
+						callback({	success: false,
+									type: textStatus,
+									msg: file_type+" file of "+login+" not found."
+								}, null);
 						break;
 					case 200://OK
-						callback({
-							success: true,
-							type: textStatus,
-							msg: "Successfully retrieved "+file_type+" file of "+login+"."
-							}, new bookmaak.domain.File(file_type, data));
+						console.info("Status: "+jqXHR.status+" - Successfully retrieved "+file_type+" file of '"+login+"'!");
+						callback({	success: true,
+									type: textStatus,
+									msg: "Successfully retrieved "+file_type+" file of "+login+"."
+								}, new bookmaak.domain.File(file_type, jqXHR.responseText));
 						break;
 					default:
-						callback({
-							success: false,
-							type: "unhandled",
-							msg: "unhandled status: "+jqXHR.status
-							}, null);
+						console.error("Status: "+jqXHR.status+" - Unexpected error!");
+						callback({	success: false,
+									type: textStatus,
+									msg: "Failed to retrieve "+file_type+" file of "+login
+								}, null);
 				}
-				return;
-			},
-			error: function(jqXHR, textStatus, errorThrown) {
-				
-				callback({
-					success: false,
-					type: "request failed",
-					msg: "Failed to retrieve "+file_type+" file of "+login
-				}, null);
-				return;
 			}
 		});
 	};
 	/**
 	 * Communicator#sendFile(File, Function)
 	 * 
-	 * **_file** the file to be sent
-	 * **callback** callback, passsing result
+	 * **file** the file to be sent<br/>
+	 * **callback** callback, passsing result<br/>
 	 * returns	calls callback with a result as
-	 * 		{	
-	 * 			success: Boolean, true on success, else false
+	 * 		{	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.
 	 * 		}
 	 **/
-	this.sendFile = function(_file, callback) {
-		
-		if(typeof callback != typeof Function)
-			throw "callback is undefined or not a function.";
-		
-		//check file
-		if(typeof _file == 'undefined')
-			throw "_file is undefined.";
-		else if(Object.prototype.toString.call(_file) == "[object Object]")
-			var file = _file;
-		else
-			throw "illegal argument _file.";
+	this.sendFile = function(file, callback) {
 		
 		switch(file.type) {
 			case bookmaak.controller.FILE_TYPE.USER:
 				var mime_type = "text/bookmaak."+file.type+".crypt";
 				break;
 			default:
-				callback({
-					success: false,
-					type: "unknown type",
-					msg: "The specified file is of an unknown type."
-				});
+				throw "unknown file.type.";
 		}
 		
+		console.debug("Trying to send "+file.type+" file of '"+login+"'");
+		console.debug("MIME-Type: "+mime_type);
 		jQuery.ajax({
-			url: server_url + '/' + login + '/' + file.type,
+			url: server_url + login + '/' + file.type,
 			type: "PUT",
+			processData: false,//XXX that does not change anything.... on put we get options request too..
 			data: file.data,
 			crossDomain: true,
-			success: function(data, textStatus, jqXHR) {
+			complete: function(jqXHR, textStatus) {
 				
 				switch(jqXHR.status) {
 					case 201://CREATED
-						callback({
-							success: true,
-							type: textStatus,
-							msg: "Successfully sent "+file.type+" file of "+login+"."
-						});
+						console.info("Status: "+jqXHR.status+" - Successfully sent "+file.type+" file of '"+login+"'!");
+						callback({	success: true,
+									type: textStatus,
+									msg: "Successfully sent "+file.type+" file of "+login+"."
+								});
 						break;
 					case 406://NOT ACCEPTABLE because of mime-type
-						callback({
-							success: false,
-							type: textStatus,
-							msg: "The server did not accept the file because of a wrong mime-type."
-						});
+						console.info("Status: "+jqXHR.status+" - Failed to send "+file.type+" file of '"+login+"', invalid MIME-Type!");
+						callback({	success: false,
+									type: textStatus,
+									msg: "The server did not accept the file because of a wrong mime-type."
+								});
 						break;
 					case 507://INSUFFICIENT STORAGE
-						callback({
-							success: false,
-							type: textStatus,
-							msg: "The server did not accept the file because of insufficient storage."
-						});
+						console.info("Status: "+jqXHR.status+" - Failed to send "+file.type+" file of '"+login+"', insufficient storage!");
+						callback({	success: false,
+									type: textStatus,
+									msg: "The server did not accept the file because of insufficient storage."
+								});
 						break;
 					default:
-						callback({
-							success: false,
-							type: "unhandled",
-							msg: "unhandled status: "+jqXHR.status
-						});
-					return;
+						console.error("Status: "+jqXHR.status+" - Unexpected error!");
+						callback({	success: false,
+									type: "request failed",
+									msg: "Failed to send "+file.type+" file of "+login
+								});
 				}
-			},
-			error: function(jqXHR, textStatus, errorThrown) {
-				
-				callback({
-					success: false,
-					type: "request failed",
-					msg: "Failed to send "+file.type+" file of "+login
-				});
-				return;
 			}
 		});
 	};

File src/main/client/constants.js

+//
+//  Copyright (C) 2011
+//    Mario Gastegger <mario DOT gastegger AT gmx DOT net>, uniqx
+//    Metalab, 1010 Vienna, Austria
+//
+//  This program 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.
+//
+//  This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+
+
+//TODO needs documentation
+bookmaak.ERROR_PREFIX = "BOOKMAAK: ";
+
+bookmaak.SYM_KEY_LENGTH = 128;

File src/main/client/controller/Controller.js

 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 //
 
-//TODO MOVE ARGUMENT VALIDATION TO THOSE WHO CALL THE CONTROLLER
-//(keeps controller/the actual application logic code simple and readable)
-
 /**
  * bookmaak.controller.Controller
  *
 
 
 /**
- * bookmaak.controller.Controller.login -> String
+ * bookmaak.controller.Controller.login_name -> String
  * 
  * the user that is logged in.
  **/
-bookmaak.controller.Controller.login = "";
+bookmaak.controller.Controller.login_name = "";
 
+/**
+ * bookmaak.controller.Controller.communicator -> Communicator
+ * 
+ * the logged in user's communicator to the server
+ **/
+bookmaak.controller.Controller.communicator = "";
 
 /**
  * bookmaak.controller.Controller.rng -> SecureRandom
 
 
 /**
- * bookmaak.controller.Controller.probeServer([String], Function) -> Object
+ * bookmaak.controller.Controller.probeServer(Function)
  * 
  * TODO maybe we should replace that by a real login
  * 
- * **_server_url**	The (new) url to the server.
- * 					If non is specified, the previous will be used.
- * 					If it was never set, an exception is thrown.<br/>
  * **callback**		Is called passing the result as argument.<br/>
  * returns	calls callback with a result as
  * 			{	
  * 				msg: String, textual error message
  * 			};
  **/
-bookmaak.controller.Controller.probeServer = function(_server_url, callback) {
-	
-	if(typeof callback != typeof Function)
-		throw "callback is undefined or not a function.";
-	
-	//if a new url should be set
-	if(typeof _server_url != 'undefined') {
-		
-		if(Object.prototype.toString.call(_server_url) == "[object String]") {
-			
-			console.log("server url inupt:"+_server_url);
-			re_fix_url = /^(?:http:\/\/){0,1}(.+)(?:\/){0,1}$/;
-			bookmaak.controller.Controller.server_url = _server_url.replace(re_fix_url, "http://$1/");
-			console.log("server url fixed:"+bookmaak.controller.Controller.server_url);
-		}
-		else
-			throw "illegal argument _server_url.";
-	}
-	else if(//typeof _server_url == 'undefined' && not neccessary
-			typeof bookmaak.controller.Controller.server_url == 'undefined') {
-		
-		throw "no sever url specified.";
-//		callback(function() {
-//			this.success = false;
-//			this.type = "no server url";
-//			this.msg = "There is no sever url specified.";
-//		});
-	}
-	//else bookmaak.controller.Controller.server_url == defined...
+bookmaak.controller.Controller.probeServer = function(callback) {
 	
 	//work around for problem with opera... :(((((( about:config#UserPrefs|AllowFileXHTTPRequest does not work
 	if(jQuery.browser.opera) {
-		
 		callback({
 			success: true,
 			type: "no transfer",
 		aync: false,//we want to probe the server before proceeding TODO maybe we change the wohle process and make the login a real login...
 		type: "HEAD",
 		crossDomain: true,
-		success: function(data, textStatus, jqXHR) {
+		complete: function(jqXHR, textStatus) {
 			
 			//TODO for debuging
-//			console.log(obj.probe_result);
-//			console.log(jqXHR);
-//			console.log(textStatus);
+//			console.debug(jqXHR);
 			
 			var server_name = jqXHR.getResponseHeader("Server");
-			alert("wenn hier["+server_name+"] Bookmaak steht ist alles gut");
+			console.debug("wenn hier["+server_name+"] Bookmaak steht ist alles gut");
+			
 			//TODO for now we decide only on status
+			console.debug("jqXHR.status: "+jqXHR.status);
 			if(jqXHR.status == 200 /*&& server_name == "Bookmaak"*/) {
-				
+				console.info("Server is up!");
 				callback({
 					success: true,
 					type: "",
 					msg: ""
 				});
-				return;
+			}
+			else if(jqXHR.status == 0) {
+				console.error("Server is down!");
+				callback({
+					success: false,
+					type: "network error",
+					msg: "Server is not reachable!"
+				});
 			}
 			else {
-				
+				console.error("Server is down or broken!");
 				callback({
 					success: false,
 					type: textStatus,
-					msg: "Status "+jqXHR.status
+					msg: "Status "+jqXHR.status+" - Server is down or broken!"
 				});
-				return;
-			}
-		},
-		error: function(jqXHR, textStatus, errorThrown) {
-			
-			//TODO for debuging
-//			console.log(obj.probe_result);
-//			console.log(textStatus);
-//			console.log(jqXHR);
-			
-			switch(textStatus) {
-				case "abort":
-				case "parsererror":
-				case "timeout":
-					callback({
-						success: false,
-						type: textStatus,
-						msg: ""
-					});
-					break;
-				case "error":
-					if(jqXHR.status == 0) {//XXX thats the case at least for ff8 and ch16.0.912.63
-						callback({
-							success: false,
-							type: textStatus,
-							msg: "Server did not respond."
-						});
-						return;
-					}
-					else {
-						callback({
-							success: false,
-							type: textStatus,
-							msg: errorThrown
-						});
-						return;
-					}
-					break;
-				default:
-					callback({
-						success: false,
-						type: textStatus,
-						msg: "unhandled response status"
-					});
-					return;
 			}
 		}
 	});
 
 
 /**
- * bookmaak.controller.userExists(String, Function) -> Boolean
+ * bookmaak.controller.userExists(String, Function)
  * 
- * **_login** the user name/login
- * **callback** called passing the result
+ * **login** the user name/login<br/>
+ * **callback** called passing the result<br/>
  * returns calls callback with the result as 
  * {
  * 		exists: Boolean, true on success, else false, undefined on error
  * 		msg: String, textual message, describing the error.
  * 	}
  **/
-bookmaak.controller.userExists = function(_login, callback) {
-	
-	if(typeof callback != typeof Function)
-		throw "callback is undefined or not a function.";
-	
-	
-	if(typeof _login == 'undefined')
-		throw "_login is undefined.";
-	else if(Object.prototype.toString.call(_login) == "[object String]")
-			var login = _login;
-	else
-		throw "illegal argument _login.";
+bookmaak.controller.userExists = function(login, callback) {
 	
 	jQuery.ajax({
 		url: bookmaak.controller.Controller.server_url + login,
-		aync: false,
+		aync: false,//TODO does not work for crossdomain requests... damn
 		type: "HEAD",
 		crossDomain: true,
 		complete: function(jqXHR, textStatus) {
 			console.debug("userExists request complete. status: "+jqXHR.status+" textStatus: "+textStatus);
 			
 			switch(jqXHR.status) {
-				
 				case 302:
 					console.info("Status: "+jqXHR.status+" - User '"+login+"' exists!");
-					callback({
-						exists: true,
-						type: "",
-						msg: "User \'"+login+"\' exists."
+					callback({	exists: true,
+								type: "",
+								msg: "User \'"+login+"\' exists."
 					});
 					break;
-				
 				case 404:
 					console.info("Status: "+jqXHR.status+" - User '"+login+"' does not exist!");
-					callback({
-						exists: false,
-						type: "",
-						msg: "User \'"+login+"\' does not exist."
+					callback({	exists: false,
+								type: "",
+								msg: "User \'"+login+"\' does not exist."
 					});
 					break;
-					
 				default:
 					console.error("Status: "+jqXHR.status+" - Unexpected error!");
-					callback({
-						exists: undefined,
-						type: textStatus,
-						msg: "An error occured during user existance request."
+					callback({	exists: undefined,
+								type: textStatus,
+								msg: "An error occured during user existance request."
 					});
 			}
-			return;
 		}
 	});
 };
 
 
 /**
- * bookmaak.controller.Controller.register(Object) -> Boolean
+ * bookmaak.controller.Controller.register(Object, Function)
  *
  * To register a new "account".
  * 
  **/
 bookmaak.controller.Controller.register = function(registrationData, callback) {
 	
-	if(typeof callback != typeof Function)
-		throw "callback is undefined or not a function.";
-	
-	
-	//generate symm key byte array
-	var key_length = 128;
-	var symm_key_bytes = new Array(key_length);
-	
+	//generate random sym key bytes
+	var symm_key_bytes = new Array(bookmaak.SYM_KEY_LENGTH);
 	bookmaak.controller.Controller.rng.nextBytes(symm_key_bytes);
 	
 	var symm_key = pidCryptUtil.byteArray2String(symm_key_bytes);
 	
-	//create user file with symm key + filename (what will be the file name for this one... maybe the rsa encrypted user identification)
+	//create user file with sym key + filename (what will be the file name for this one... maybe the rsa encrypted user identification)
 	var user_file_plain = new bookmaak.domain.File(
 			bookmaak.controller.FILE_TYPE.USER,
 			symm_key);
 	
 	var user_file_encrypted = usrCrypto.encryptUserFile(user_file_plain);
 	
-	//send it to the server
+	//send it to the server...we discard the communicator, on login we keep it
 	(new bookmaak.comm.Communicator(
-			registrationData.login,
-			bookmaak.controller.Controller.server_url)).sendFile(
-					user_file_encrypted,
-					function(result) {
-//						{	
-//							success: Boolean, true on success, else false
+		registrationData.login,
+		bookmaak.controller.Controller.server_url)).sendFile(
+			user_file_encrypted,
+			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.
 //						}
-						if(result.success) {
-							
-							//save params to localstore TODO check results
-							bookmaak.util.addSetting(
-									registrationData.login,
-									bookmaak.util.SETTING_KEY.LOGIN,
-									registrationData.login,
-									bookmaak.util.SETTING_TYPE.USER);
-							
-							bookmaak.util.addSetting(
-									registrationData.login,
-									bookmaak.util.SETTING_KEY.PRIVATE_KEY,
-									registrationData.rsa_private_key_pem,
-									bookmaak.util.SETTING_TYPE.USER);
-							
-							bookmaak.util.addSetting(
-									registrationData.login,
-									bookmaak.util.SETTING_KEY.PUBLIC_KEY,
-									registrationData.rsa_public_key_pem,
-									bookmaak.util.SETTING_TYPE.USER);
-							
-							callback(result);
-						}
-						else {
-							
-							//TODO clean up server_url in case of a connection error
-							callback(result);
-						}
-						
-					});
+				if(result.success) {
+					//save params to localstore TODO check results
+					bookmaak.util.addSetting(
+							registrationData.login,
+							bookmaak.util.SETTING_KEY.LOGIN,
+							registrationData.login,
+							bookmaak.util.SETTING_TYPE.USER);
+					
+					bookmaak.util.addSetting(
+							registrationData.login,
+							bookmaak.util.SETTING_KEY.PRIVATE_KEY,
+							registrationData.rsa_private_key_pem,
+							bookmaak.util.SETTING_TYPE.USER);
+					
+					bookmaak.util.addSetting(
+							registrationData.login,
+							bookmaak.util.SETTING_KEY.PUBLIC_KEY,
+							registrationData.rsa_public_key_pem,
+							bookmaak.util.SETTING_TYPE.USER);
+					
+					callback(result);
+				}
+				else {
+					
+					//TODO clean up server_url in case of a connection error
+					//usw....
+					callback(result);
+				}
+				
+			});
 };
 
 
 
 
 /**
- * bookmaak.controller.Controller.login(String, Function) -> Boolean
+ * bookmaak.controller.Controller.login(String, Function)
  *
  * To log into an "account"
  * 
  **/
 bookmaak.controller.Controller.login = function(login, callback) {
 	
-	if(typeof callback != typeof Function)
-		throw "callback is undefined or not a function.";
-	
-	if(typeof login == 'undefined'
-		|| Object.prototype.toString.call(login) != "[object String]")
-		return callback({
-			success: false,
-			type: "invalid login",
-			msg: "login is undefined or not a string"
-		});
-	
+	//init user's communicator
+	console.debug("Initializing user's communicator...");
+	bookmaak.controller.Controller.
+	communicator = new bookmaak.comm.
+						Communicator(
+							login,
+							bookmaak.controller.Controller.server_url);
 	
 	//retrieve user file
-	var comm = new bookmaak.comm.Communicator(login, bookmaak.controller.Controller.server_url);
-	//TODO just for testing
-	comm.retrieveFile(bookmaak.controller.FILE_TYPE.USER, function(result, file) {
-		
+	console.debug("Trying to retrieve the user file...");
+	bookmaak.controller.Controller.
+	communicator.retrieveFile(
+		bookmaak.controller.FILE_TYPE.USER,
+		function(result, file) {
+//		{	success: Boolean, true on success, else false
+//			type: String, error type
+//			msg: String, textual message, describing the error or success.
+//		}
 		if(result.success) {
-			
-			bookmaak.controller.Controller.login = login;
-			callback(result);
+			console.log("Successfully retrieved user file!");
+			bookmaak.controller.Controller.login_name = login;
 		}
 		else {
-			
-			callback(result);
+			console.error("Failed to retrieved user file!");
+			console.error("Error type: "+result.type+" Msg:"+result.msg);
+			//TODO maybe disconnect... if servers fault
 		}
+		callback(result.success);
 	});
-	
-	//decrypt the file and extract the symkey and the name of the bookmark file
-	
-	
-	
-	//retrieve the bookmark files and decrypt it
-	
-	//extract the bookmarks into memory
-	
-	//show the management site
-	
-	//on error: return false;
-	
-//	comm.sendFile(new bookmaak.domain.File(bookmaak.controller.FILE_TYPE.USER, "ich bin ein user file :D"), function(result) {
-//		
-//		if(result.success) {
-//			alert("jo");
-//		}
-//		else {
-//			alert("na");
-//		}
-//	});
 };
 

File src/main/client/crypto/CryptoUtils.js

 bookmaak.crypto.CryptoUtils = bookmaak.crypto.CryptoUtils || {};
 
 
-/**
- * bookmaak.crypto.CryptoUtils.validate_rsa_private_key_pem(String) -> Boolean
- * 
- * Validates the pem formated private key.
- * 
- * **rsa_private_key_pem** the private key in pem format
- * returns true if valid, otherwise false.
- **/
-bookmaak.crypto.CryptoUtils.validate_rsa_private_key_pem = function(rsa_private_key_pem) {
-	
-	var rsa_params = {};
-	
-	rsa_params = bookmaak.crypto.CryptoUtils.parseCert(rsa_private_key_pem);
-
-	if(rsa_params.iv
-	&& rsa_params.salt
-	&& rsa_params.mode == 'CBC'
-	&& rsa_params.aes
-	&& rsa_params.bits
-	&& rsa_params.b64) {
-		
-		return true;
-	}
-	else {
-		
-		return false;
-	}
-};
-
-
 
 /**
  * bookmaak.crypto.CryptoUtils.decryptPrivateKey(Object) -> ASN1

File src/main/client/namespaces.js

  * Contains helper functions.
  **/
 bookmaak.util = bookmaak.util || {};
+
+/**
+ * bookmaak.util.validation
+ * 
+ * Provides methods for validation of all sort of things.
+ **/
+bookmaak.util.validation = bookmaak.util.validation || {};
+
+

File src/main/client/ui/UiController.js

 /**
  * bookmaak.ui.UiController
  * 
- * UiController provides some helper functions to simplify ui tasks
+ * UiController provides some helper functions to simplify ui tasks.<br/>
+ * **UiController MUST do all input validation,
+ * it won't be done on the layers blow!**
  **/
 bookmaak.ui.UiController = bookmaak.ui.UiController || {};
 
 
 
 /**
- * bookmaak.ui.UiController.printMessage(String[, MESSAGE_TYPE])
+ * bookmaak.ui.UiController.printMessage(String, MESSAGE_TYPE)
  * 
  * Shows the message and fades it out again.
  * 
  * **_message** the message<br/>
  * **type** enum bookmaak.ui.UiController.MESSAGE_TYPE
  **/
-bookmaak.ui.UiController.printMessage = function(_message, _type) {
+bookmaak.ui.UiController.printMessage = function(_message, type) {
 	
-	if(typeof _message == 'undefined')
-		var message = "";
-	else if(Object.prototype.toString.call(_message) != '[object String]')
-		var message = "";
-	else
-		var message = _message;
+	//TODO apply whitelist to _message
 	
-	if(typeof _type == 'undefined')
-		var type = bookmaak.ui.MESSAGE_TYPE.NOTICE;
-	else if(Object.prototype.toString.call(_type) != '[object String]')
-		var type = bookmaak.ui.MESSAGE_TYPE.NOTICE;
-	else
-		var type = _type;
 	switch(type) {
 		case bookmaak.ui.MESSAGE_TYPE.SUCCESS:
 			elem = ".successbox";
 		case bookmaak.ui.MESSAGE_TYPE.ERROR:
 			elem = ".errorbox";
 			break;
-		default:
 		case bookmaak.ui.MESSAGE_TYPE.NOTICE:
 			elem = ".noticebox";
 			break;
+		default: throw new Error("BOOKMAAK: Semantic error in bookmaak.ui.UiController.printMessage");
 	}
 	
 	//set message
-	jQuery(elem).html(message);
+	jQuery(elem).html(_message);
 	
 	//show message
 	jQuery(elem).fadeIn(500);
 	
 	//fade it out again
-	setTimeout(function(){
+	setTimeout(function() {
 		
 		jQuery(elem).fadeOut();
-//		"slow", function () {
-//			
-//			jQuery(elem).hide();
-//		}
 	}, 2000);
 };
 
 
 
 
+/**
+ * bookmaak.ui.UiController.printSuccessMessage(String)
+ * 
+ * Shows a success message.
+ * 
+ * **_message** the message<br/>
+ **/
+bookmaak.ui.UiController.printSuccessMessage = function(_message) {
+	
+	bookmaak.ui.UiController.
+	printMessage(_message, bookmaak.ui.MESSAGE_TYPE.SUCCESS);
+};
+
+/**
+ * bookmaak.ui.UiController.printNoticeMessage(String)
+ * 
+ * Shows a notice message.
+ * 
+ * **_message** the message<br/>
+ **/
+bookmaak.ui.UiController.printNoticeMessage = function(_message) {
+	
+	bookmaak.ui.UiController.
+	printMessage(_message, bookmaak.ui.MESSAGE_TYPE.NOTICE);
+};
+
+/**
+ * bookmaak.ui.UiController.printWarningMessage(String)
+ * 
+ * Shows a warning message.
+ * 
+ * **_message** the message<br/>
+ **/
+bookmaak.ui.UiController.printWarningMessage = function(_message) {
+	
+	bookmaak.ui.UiController.
+	printMessage(_message, bookmaak.ui.MESSAGE_TYPE.WARNING);
+};
+
+/**
+ * bookmaak.ui.UiController.printErrorMessage(String)
+ * 
+ * Shows an error message.
+ * 
+ * **_message** the message<br/>
+ **/
+bookmaak.ui.UiController.printErrorMessage = function(_message) {
+	
+	bookmaak.ui.UiController.
+	printMessage(_message, bookmaak.ui.MESSAGE_TYPE.ERROR);
+};
+
+
 
 
 /**
  **/
 bookmaak.ui.UiController.onClickConnect = function() {
 	
-	var server_url = jQuery("#connect_to_url").val();
-
-	bookmaak.controller.Controller.probeServer(server_url, function(probe) {
+	var _server_url = jQuery("#connect_to_url").val();
+	console.log("server url inupt:"+_server_url);
+	
+	
+	//validate server url
+	var server_url_is_valid = bookmaak.util.validation.validateServerUrl(_server_url);
+	if(server_url_is_valid) {//fix it if necessary
 		
-		//TODO for debungin
-//		console.log(probe);
+		//TODO make a constant and merge with the bookmaak.util.validation.validateServerUrl definition
+		var re_fix_url = /^(?:http:\/\/){0,1}([A-Za-z0-9\.\:\-]+)(?:\/){0,1}$/;
 		
-		if(probe.success){
+		//set the server url in Controller.
+		bookmaak.controller.Controller.
+		server_url = _server_url.replace(re_fix_url, "http://$1/");
+		
+		console.log("server url fixed:"+bookmaak.controller.Controller.server_url);
+	}
+	else {
+		
+		bookmaak.ui.UiController.printErrorMessage("Invalid server url");
+	}
+	
+	//try to contact server
+	if(server_url_is_valid) {
+		
+		bookmaak.controller.Controller.probeServer(function(probe) {
 			
-			var success_text = "Connection successful! ";
-			if(probe.msg != "")
-				success_text += "("+probe.msg+")";
+			if(probe.success){
 				
-			bookmaak.ui.UiController.printMessage(success_text,
-					bookmaak.ui.MESSAGE_TYPE.SUCCESS);
-			
-			showConnectViewConnected(server_url);
-			
-			showLoginView();
-		}
-		else {
-			
-			var error_text = "Connection failed! ";
-			if(probe.error_type != "")
-				error_text += "<br/>Error type: "+probe.error_type;
-				if(probe.msg)
-					error_text += " - "+probe.msg;
+				var success_text = "Connection successful! "
+					+(probe.msg != "" ? "("+probe.msg+")" : "");
 					
-			bookmaak.ui.UiController.printMessage(error_text,
-					bookmaak.ui.MESSAGE_TYPE.ERROR);
-		}
-	});
-	
-	
+				bookmaak.ui.UiController.printSuccessMessage(success_text);
+				
+				
+				showConnectViewConnected(_server_url);
+				
+				//TODO we skip connection view for development
+				showLoginView();
+			}
+			else {
+				
+				var error_text = "Connection failed! "
+					+(probe.type != "" ? "<br/>Error type: "+probe.type : "")
+					+(probe.msg ? " - "+probe.msg : "");
+					
+				bookmaak.ui.UiController.printErrorMessage(error_text);
+			}
+		});
+	}
 };
 
 /**
 
 function showConnectViewConnected(server_url) {
 	
+	if(!bookmaak.util.isDefined(server_url)
+	|| !bookmaak.util.isType(server_url, bookmaak.util.TYPE.STRING)) {
+		console.error("invalid server_url: "+server_url);
+		server_url = "";
+	}
+	
 	//hide all
 	jQuery(".view").hide();
 	
  **/
 bookmaak.ui.UiController.onClickLogin = function() {
 	
-	var re_login = /^\w+$/;
-	
 	var _login = jQuery("#login").val();
 	
-	if(typeof _login == 'undefined'
-		|| Object.prototype.toString.call(_login) != "[object String]"
-		|| !re_login.test(_login)) {
-		
-		bookmaak.ui.UiController.printMessage(
-				"Login is invalid.",
-				bookmaak.ui.MESSAGE_TYPE.ERROR);
-	}
-	else {
+	if(bookmaak.util.validation.validateLogin(_login)) {
 		
 		var login = _login;
 		
-		bookmaak.controller.Controller.login(login, function(login) {
+		bookmaak.controller.Controller.
+		login(login, function(success) {
 			
-			if(login.success) {
+			if(success) {
 				
-				bookmaak.ui.UiController.printMessage(
-						"Login successful, you may proceed!",
-						bookmaak.ui.MESSAGE_TYPE.SUCCESS);
+				bookmaak.ui.UiController.
+				printSuccessMessage("Login successful, you may proceed!");
 				
 				showManageAccountView();
 			}
 			else {
 				
-				bookmaak.ui.UiController.printMessage(
-						"Login failed, maybe register first?",
-						bookmaak.ui.MESSAGE_TYPE.WARNING);
+				bookmaak.ui.UiController.
+				printWarningMessage("Login failed, maybe register first?");
 				
-				showLoginView();
+				showLoginView(_login);
 			}
 		});
 	}
+	else {
+		
+		bookmaak.ui.UiController.
+		printErrorMessage("Login is invalid.");
+	}
 };
 
 function showLoginView(login) {
 	
-	if(typeof login == 'undefined') {
+	if(!bookmaak.util.isDefined(login))
 		login = "";
-	}
-	else if(Object.prototype.toString.call(login) != '[object String]') {
-		
-		alert("bookmaak.ui.UiController.showLoginView: "
-				+ "da ging was schief, aber keine panic, nix schlimmes");
+	else if(!bookmaak.util.isType(login, bookmaak.util.TYPE.STRING)) {
+		console.error("invalid login: "+login);
 		login = "";
 	}
 	
  **/
 bookmaak.ui.UiController.onClickDoRegister = function() {
 	
+	//error markers
+	var error = false;
+	var login_is_valid = false;
+	var private_key_is_valid = false;
+	var public_key_is_valid = false;
+	var login_exists = true;
+	
 	//get the fields
 	var _login = jQuery('#register_login').val();
 	var _private_key = jQuery('#register_private_key').val();
 	var _public_key = jQuery('#register_public_key').val();
 	
-	//predefine reg data
-	var registrationData = {
-		login: _login,
-		rsa_private_key_pem: _private_key,
-		rsa_public_key_pem: _public_key
-	};
-	
-	//error markers
-	var error = false;
-	
-	var login_is_valid = false;
-	var login_exists = true;
-	
-	var private_key_is_valid = false;
-	
-	var public_key_is_valid = false;
-	
-	
-	//validate login
-	var re_login = /^\w+$/;
-	
-	if(Object.prototype.toString.call(_login) == "[object String]"
-	&& re_login.test(_login)
-	&& _login.length > 4) {
+	try {
+		//validate login pub key and priv key
+		login_is_valid = bookmaak.util.validation.validateLogin(_login);
+		private_key_is_valid = bookmaak.util.validation.validateRSAPrivateKeyPEM(_private_key);
+		public_key_is_valid = bookmaak.util.validation.validateRSAPublicKeyPEM(_public_key);
 		
-		var login_is_valid = true;
+		//check if usernamen yet exists
+		if(login_is_valid) {
+			console.log("bookmaak.controller.userExists("+_login+")");
+			bookmaak.controller.userExists(_login, function(result) {
+				
+				console.debug("result:");console.debug(result);
+				
+				if(!bookmaak.util.isDefined(result.exists))	//error occurred
+					error = true;
+				else if(result.exists)						//exists
+					login_exists = true;
+				else										//does not exist
+					login_exists = false;
+				
+				console.log("login exists: "+login_exists);
+				
+				//do register
+				if(login_is_valid && !login_exists
+				&& private_key_is_valid
+				&& public_key_is_valid) {
+					
+					//fill in the validated data
+					registrationData = {	login: _login,
+											rsa_private_key_pem: _private_key,
+											rsa_public_key_pem: _public_key};
+					if(error) {//serious errors
+						bookmaak.ui.UiController.printWarningMessage(
+							"Registration failed, try again later.<br/>"
+							+"If the problem persists, contact the servers administrator.");
+						//back again
+						showRegisterView(registrationData);
+					}
+					else {//everything is alright
+						bookmaak.controller.Controller.
+						register(registrationData, function(result) {
+							if(result.success) {
+								bookmaak.ui.UiController.printSuccessMessage(
+									"Registration successful, you may login now!");
+								//show the login site
+								showLoginView(registrationData.login);
+							}
+							else {
+								bookmaak.ui.UiController.printWarningMessage(
+									"Registration failed, try again later.<br/>"
+									+"If the problem persists, contact the servers administrator.");
+								//back again
+								showRegisterView(registrationData);
+							}
+						});
+					}
+				}
+				else {
+					//validation errors
+					bookmaak.ui.UiController.printErrorMessage(
+						(!login_is_valid ?			"Login is invalid<br/>" : "")
+						+(login_exists ? 			"Login already exists<br/>" : "")
+						+(!private_key_is_valid ?	"Private key is invalid<br/>" : "")
+						+(!public_key_is_valid ?	"Public key is invalid<br/>" : ""));
+				}
+			});
+		}
+		else {
+			//validation errors
+			bookmaak.ui.UiController.printErrorMessage(
+				(!login_is_valid ?			"Login is invalid<br/>" : "")
+				+(!private_key_is_valid ?	"Private key is invalid<br/>" : "")
+				+(!public_key_is_valid ?	"Public key is invalid<br/>" : ""));
+		}
 	}
-	
-	//check if usernamen yet exists
-	bookmaak.controller.userExists(_login, function(result) {
-		
-		if(typeof result.exists == undefined) {//error occurred
-			
-			error = true;
-		}
-		else if(result.exists){//exists
-			
-			login_exists = true;
-		}
-		else {//does not exist
-			
-			login_exists = false;
-		}
-	});
-	
-	//here the login validation is complete
-	if(!login_exists
-	&& login_is_valid) {
-		
-		var login = _login;
+	catch(err) {
+		console.error(err);
+		throw new Error("BOOKMAAK: There is something wrong with the input fields...");
 	}
-	
-	console.log("login does not exist: "+!login_exists);
-	console.log("login is valid: "+login_is_valid);
-	
-	
-	//validate private key
-	if(bookmaak.crypto.CryptoUtils.validate_rsa_private_key_pem(_private_key)) {
-		
-		var rsa_private_key_pem = _private_key;
-		private_key_is_valid = true;
-	}
-	
-	console.log("private key is valid: "+private_key_is_valid);
-	
-	//validate public key TODO make a more sophisticated regex
-	var re_public_key = /.*/;
-	if(re_public_key.test(_public_key)) {
-		
-		var public_key = _public_key;
-		public_key_is_valid = true;
-	}
-	
-	console.log("public key is valid: "+private_key_is_valid);
-	
-	
-	//do register
-	if(login_is_valid
-	&& !login_exists
-	&& private_key_is_valid
-	&& public_key_is_valid) {
-		
-		//fill in the validated data
-		registrationData = {
-			login: login,
-			rsa_private_key_pem: rsa_private_key_pem,
-			rsa_public_key_pem: public_key
-		};
-		
-		bookmaak.controller.Controller.register(registrationData, function(result) {
-			
-			if(result.success) {
-				
-				bookmaak.ui.UiController.printMessage(
-						"Registration successful, you may login now!",
-						bookmaak.ui.MESSAGE_TYPE.SUCCESS);
-				
-				//show the login site
-				showLoginView(registrationData.login);
-			}
-			else {
-				
-				//TODO check if this is only on network errors the case
-//				bookmaak.ui.UiController.printMessage(
-//						"Registration failed, try again later.<br/>"
-//						+"If the problem persists, contact the servers administrator.",
-//						bookmaak.ui.MESSAGE_TYPE.WARNING);
-				error = true;
-			}
-		});
-	}
-	
-	//serious errors
-	if(error) {
-		
-		bookmaak.ui.UiController.printMessage(
-				"Registration failed, try again later.<br/>"
-				+"If the problem persists, contact the servers administrator.",
-				bookmaak.ui.MESSAGE_TYPE.WARNING);
-		
-		//back again
-		showRegisterView(registrationData);
-	}
-	else if(!login_is_valid
-	|| login_exists
-	|| !private_key_is_valid
-	|| !public_key_is_valid) {
-		
-		//validation errors
-		bookmaak.ui.UiController.printMessage(
-				(!login_is_valid ?			"Login is invalid<br/>" : "")
-				+(login_exists ? 			"Login already exists<br/>" : "")
-				+(!private_key_is_valid ?	"Private key is invalid<br/>" : "")
-				+(!public_key_is_valid ?	"Public key is invalid<br/>" : ""),
-				bookmaak.ui.MESSAGE_TYPE.ERROR);
-		
-		showRegisterView(registrationData);
-	}
-	
-	return;
 };
 
 function showRegisterView(values) {
 	//hide all
 	jQuery(".view").hide();
 	
-	//and re-init register-view
-	//TODO check if defined, if not assign ""
-	var values = {//for testing
-			login: "new_login",
-			private_key: "private_key",
-			public_key: "public_key"
-	};
+	//re-init register-view if neccessary
+	if(!bookmaak.util.isDefined(values)
+	|| !bookmaak.util.isType(values, bookmaak.util.TYPE.OBJECT)) {
+		
+		values = {	login: "new_login",
+					private_key: "private_key",
+					public_key: "public_key"
+		};
+	}
 	
 	jQuery("#register_login").val(values.login);
 	jQuery("#register_private_key").val(values.private_key);
  **/
 bookmaak.ui.UiController.onClickImportExport = function() {
 	
-	//TODO implement option "partial"
 	showManageAccountView("#man_opt_import_export");
 };
 
  **/
 bookmaak.ui.UiController.onClickChangeAccount = function() {
 	
-	//TODO implement option "partial"
 	showManageAccountView("#man_opt_change_account");
 };
 
  **/
 bookmaak.ui.UiController.onClickDeleteAccount = function() {
 	
-	//TODO implement option "partial"
 	showManageAccountView("#man_opt_delete_account");
 };
 
  **/
 bookmaak.ui.UiController.onClickLogout = function() {
 	
-	//TODO implement option "partial"
 	showManageAccountView("#man_opt_logout");
 };
 
 function showManageAccountView(option_to_show) {
 	
-	if(typeof option_to_show == 'undefined') {
-		option_to_show = "";
-	}
-	else if(Object.prototype.toString.call(option_to_show) != '[object String]') {
-		
-		alert("bookmaak.ui.UiController.showManageAccountView: "
-				+"da ging was schief, aber keine panic, nix schlimmes");
+	if(!bookmaak.util.isDefined(option_to_show)
+	|| !bookmaak.util.isType(option_to_show, bookmaak.util.TYPE.STRING)) {
 		option_to_show = "";
 	}
 	
 	//hide all
 	jQuery(".view").hide();
 	
-	//show none or only the correct option
-//	jQuery("#manage").hide();
-	
-	//hide all options by default
-	jQuery(".man_opt_option").hide();
 	switch(option_to_show) {
-	
 		case "#man_opt_import_export":
 		case "#man_opt_change_account":
 		case "#man_opt_delete_account":
 		case "#man_opt_logout":
 			jQuery(option_to_show).show();
 			break;
-			
-//		default://not necessary since they are already hidden
-//			//hide all options
-//			jQuery(".man_opt_option").hide();
+		default:
+			//hide all options by default
+			jQuery(".man_opt_option").hide();
 	}
 	
 	//show view
 	
 	//TODO call the controller to get the result
 	
-	bookmaak.ui.UiController.printMessage("(debug) searching...");
+	bookmaak.ui.UiController.printNoticeMessage("(debug) searching...");
 	
 	jQuery("#search_result").show();
 };

File src/main/client/ui/register_view.jade

   label(for='register_private_key')
     | Paste your private encrypted rsa key:
   br
-  textarea#register_private_key(rows=30 , cols=63)
+  textarea#register_private_key(rows=30 , cols=64)
   br
   br
   label(for='register_public_key')
     | Paste your public rsa key:
   br
-  textarea#register_public_key(rows=10 , cols=63)
+  textarea#register_public_key(rows=10 , cols=64)
   br
   br
   input(value='Register', type='button',

File src/main/client/util/Settings.js

 	PUBLIC_KEY:		"public_key"
 };
 
+
+
+//TODO allow add, get and remove for userData objects
+//
+//
+//
+//
+
+
+
 /**
  * bookmaak.util.addSetting(String, SETTING_KEY, ANY, SETTING_TYPE) -> Boolean
  * 
 };
 
 
+
+
+
+
 function addSetting(key_prefix, key, value) {
 	
 	var prefixed_key = key_prefix + "_" + key;

File src/main/client/util/types.js

+//
+//  Copyright (C) 2011
+//    Mario Gastegger <mario DOT gastegger AT gmx DOT net>, uniqx
+//    Metalab, 1010 Vienna, Austria
+//
+//  This program 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.
+//
+//  This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+
+
+/**
+ * $bookmaak.util.TYPE = NULL | UNDEFINED | OBJECT | FUNCTION | REGEXP
+ * 						| ARRAY | BOOLEAN | NUMBER | STRING
+ * 
+ * Enumeration of all by check* supported types.
+ **/
+bookmaak.util.TYPE = {
+	
+	NULL:		Object.prototype.toString.call(null),
+	UNDEFINED:	Object.prototype.toString.call(undefined),
+	
+	OBJECT:		Object.prototype.toString.call({}),
+	
+	FUNCTION:	Object.prototype.toString.call(function(){}),
+	
+	REGEXP:		Object.prototype.toString.call(/regex/),
+	
+	ARRAY:		Object.prototype.toString.call([]),
+	
+	BOOLEAN:	Object.prototype.toString.call(true || false),
+	NUMBER:		Object.prototype.toString.call(0815),
+	STRING:		Object.prototype.toString.call('l33t')
+	
+	//TODO extend to own classes... at least the builtin and custom errors
+};
+
+/**
+ * $bookmaak.util.getType(Any) -> String
+ * 
+ * returns the human readable type.
+ **/
+bookmaak.util.getType = function(type) {
+	
+	return Object.prototype.toString.call(type).match(/^\[object\s(.+)\]$/)[1];
+};
+
+
+/**
+ * $bookmaak.util.checkDefined(Any, String)
+ * 
+ * Checks a if **parameter** is defined.<br/>
+ * 
+ * **parameter**	the parameter to be checked<br/>
+ * **parameterName**name the **parameter**<br/>
+ * Throws:<br/>
+ * ReferenceError	if **parameterName** or **parameter** is not defined<br/>
+ * TypeError		if **parameterName** is not a string<br/>
+ **/
+bookmaak.util.checkDefined = function(parameter, parameterName) {
+	
+	if(Object.prototype.toString.call(parameterName)
+			=== bookmaak.util.TYPE.UNDEFINED)
+		throw new ReferenceError(bookmaak.ERROR_PREFIX
+								+"parameterName is undefined");
+	if(Object.prototype.toString.call(parameterName)
+			!== bookmaak.util.TYPE.STRING)
+		throw new TypeError(bookmaak.ERROR_PREFIX
+							+"parameterName is not a string");
+	
+	
+	if(Object.prototype.toString.call(parameter) 
+			=== bookmaak.util.TYPE.UNDEFINED)
+		throw new ReferenceError(bookmaak.ERROR_PREFIX
+								+parameterName+" is undefined");
+};
+
+/**
+ * $bookmaak.util.isDefined(Any)
+ * 
+ * Checks a if **parameter** is defined.<br/>
+ * 
+ * **parameter**	the parameter to be checked<br/>
+ * returns			true if **parameter** is defined, otherwise false.
+ **/
+bookmaak.util.isDefined = function(parameter) {
+	
+	if(Object.prototype.toString.call(parameter) 
+			=== bookmaak.util.TYPE.UNDEFINED)
+		return false;
+	else
+		return true;
+};
+
+
+/**
+ * $bookmaak.util.isNull(Any)
+ * 
+ * Checks a if **parameter** is null.<br/>
+ * 
+ * **parameter**	the parameter to be checked<br/>
+ * returns			true if **parameter** is null, otherwise false.
+ * Throws:<br/>
+ * ReferenceError	if **parameter** is not defined<br/>
+ **/
+bookmaak.util.isNull = function(parameter) {
+	
+	bookmaak.util.checkDefined(parameter, "parameter");
+	
+	if(Object.prototype.toString.call(parameter) === bookmaak.util.TYPE.NULL)
+		return true;
+	else
+		return false;
+};
+
+
+
+/**
+ * $bookmaak.util.checkType(Any, String, TYPE)
+ * 
+ * Checks if **parameter** is of type **expectedType**<br/><br/>
+ * **Can be used for String, Number, Boolean, Object, Array, Function, Null and RegExp.**<br/>
+ * **Must not be used to check for type undefined!
+ * Use bookmaak.util.checkDefined() instead.**<br/>
+ * 
+ * **parameter**	the parameter to check<br/>
+ * **parameterName**the name of the **parameter**<br/>
+ * **expectedType**	the expected type of the **parameter**<br/>
+ * Throws:<br/>
+ * ReferenceError	if **parameterName**
+ * 					or **parameter**
+ * 					or **expectedType** is not defined<br/>
+ * TypeError		if **parameterName** is not a string
+ * 					or **parameter** is not of **expectedType**<br/>
+ **/
+bookmaak.util.checkType = function(parameter, parameterName, expectedType) {
+	
+	bookmaak.util.checkDefined(parameter, parameterName);
+	bookmaak.util.checkDefined(expectedType, "expectedType");
+	
+	if(Object.prototype.toString.call(parameter) !== expectedType)
+		throw new TypeError(bookmaak.ERROR_PREFIX
+				+"type of "+parameterName
+				+" is not "+expectedType
+				+"(it is "+bookmaak.util.getType(parameter)+")");
+};
+
+/**
+ * $bookmaak.util.isType(Any, TYPE)
+ * 
+ * Checks if **parameter** is of type **expectedType**<br/><br/>
+ * **Can be used for String, Number, Boolean, Object, Array, Function, Null and RegExp.**<br/>
+ * **Must not be used to check for type undefined!
+ * Use bookmaak.util.isDefined() instead.**<br/>
+ * 
+ * **parameter**	the parameter to check<br/>
+ * **expectedType**	the expected type of the **parameter**<br/>
+ * returns			true if **parameter** is of **expectedType**<br/>
+ * Throws:<br/>
+ * ReferenceError	if **parameter** or **expectedType** is not defined<br/>
+ **/
+bookmaak.util.isType = function(parameter, expectedType) {
+	
+	bookmaak.util.checkDefined(parameter, "parameter");
+	bookmaak.util.checkDefined(expectedType, "expectedType");
+	
+	if(Object.prototype.toString.call(parameter) === expectedType)
+		return true;
+	else
+		return false;
+};
+
+
+/**
+ * class bookmaak.util.AssertionException
+ * 
+ * Thrown if an assertion fails.
+ **/
+/**
+ * new bookmaak.util.AssertionException(String)
+ **/
+bookmaak.util.AssertionException = function AssertionException(message) {
+	
+	/**
+	 * bookmaak.util.AssertionException#message -> String
+	 **/
+	this.message = message;
+	
+	/**
+	 * bookmaak.util.AssertionException#toString() -> String
+	 **/
+	this.toString = function() {
+		
+		return this.message;
+	};
+};
+
+/**
+ * class bookmaak.util.ValidationException
+ * 
+ * Thrown if an assertion fails.
+ **/
+/**
+ * new bookmaak.util.ValidationException(String)
+ **/
+bookmaak.util.ValidationException = function ValidationException(message) {
+	
+	/**
+	 * bookmaak.util.ValidationException#message -> String
+	 **/
+	this.message = message;
+	
+	/**
+	 * bookmaak.util.ValidationException#toString() -> String
+	 **/
+	this.toString = function() {
+		
+		return this.message;
+	};
+};
+
+/**
+ * $bookmaak.util.assert(Boolean, String)
+ * 
+ * Throws an AssertionException if **exp** is false.
+ * 
+ * **exp** the expression which is asserted to be true<br/>
+ * **message** the message
+ **/
+bookmaak.util.assert = function(exp, message) {
+
+	if(exp !== true)
+		throw new AssertionException(message);
+};

File src/main/client/util/validation.js

+//
+//  Copyright (C) 2011
+//    Mario Gastegger <mario DOT gastegger AT gmx DOT net>, uniqx
+//    Metalab, 1010 Vienna, Austria
+//
+//  This program 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.
+//
+//  This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+
+
+/**
+ * bookmaak.util.validation.validateUserData(Object) -> Object
+ * 
+ * Validates **userData**...<br/>
+ * 
+ * **userData** {	login:				String
+ * 					rsa_private_key_pem:String
+ * 					rsa_public_key_pem:	String
+ * 				}<br/>
+ * returns {	login_is_valid:				Boolean, true if valid, otherwise false
+ * 				rsa_private_key_pem_is_valid:Boolean, true if valid, otherwise false 
+ * 				rsa_public_key_pem_is_valid:Boolean, true if valid, otherwise false
+ * 				}
+ **/
+bookmaak.util.validation.validateUserData = function(userData) {
+	
+	if(!bookmaak.util.isType(userData, bookmaak.util.TYPE.OBJECT))
+		return false;
+
+	//check if every property is defined
+	for(var property in userData) {
+		if(!bookmaak.util.isType(userData[property], bookmaak.util.STRING))
+			return false;
+	}
+	
+	var result = {
+		login_is_valid:				 bookmaak.util.validation.validateLogin(userData.login),
+		rsa_private_key_pem_is_valid:bookmaak.util.validation.validateRSAPrivateKeyPEM(userData.rsa_private_key_pem),
+		rsa_public_key_pem_is_valid: bookmaak.util.validation.validateRSAPublicKeyPEM(userData.rsa_public_key_pem)
+	};
+	
+	return result;
+};
+
+
+/**
+ * bookmaak.util.validation.validateLogin(String) -> Boolean
+ * 
+ * Validates **login**...<br/>
+ * 
+ * **login** the login
+ **/
+bookmaak.util.validation.validateLogin = function(login) {
+	
+	if(!bookmaak.util.isType(login, bookmaak.util.TYPE.STRING))
+		return false;
+	
+	console.debug("validateLogin("+login+")");
+	
+	//validate login
+	//begins with a alphachar, followed by at least 3 alphanumeric chars
+	var re_login = /^[A-Za-z]+[A-Za-z0-9]{3,}$/;
+	
+	console.log(login.match(re_login) || "no match");
+	
+	if(re_login.test(login))
+		return true;
+	else
+		return false;
+};
+
+
+
+/**
+ * bookmaak.util.validation.validateRSAPrivateKeyPEM(String) -> Boolean
+ * 
+ * Validates the pem formated private key.
+ * 
+ * **rsa_private_key_pem** the private key in pem format
+ * returns true if valid, otherwise false.
+ **/
+bookmaak.util.validation.validateRSAPrivateKeyPEM = function(rsa_private_key_pem) {
+	
+	if(!bookmaak.util.isType(rsa_private_key_pem, bookmaak.util.TYPE.STRING))
+		return false;
+	
+	console.debug("validateRSAPrivateKeyPEM("+rsa_private_key_pem+")");
+	
+	var rsa_params = {};
+	
+	rsa_params = bookmaak.crypto.CryptoUtils.parseCert(rsa_private_key_pem);
+	
+	console.log(rsa_private_key_pem);
+	
+	if(rsa_params.iv
+	&& rsa_params.salt
+	&& rsa_params.mode == 'CBC'
+	&& rsa_params.aes
+	&& rsa_params.bits
+	&& rsa_params.b64) {
+		
+		return true;
+	}
+	else {
+		
+		return false;
+	}
+};
+
+
+/**
+ * bookmaak.util.validation.validateRSAPublicKeyPEM(String) -> Boolean
+ * 
+ * Validates the pem formated public key.
+ * 
+ * **rsa_public_key_pem** the public key in pem format
+ * returns true if valid, otherwise false.
+ **/
+bookmaak.util.validation.validateRSAPublicKeyPEM = function(rsa_public_key_pem) {
+	
+	if(!bookmaak.util.isType(rsa_public_key_pem, bookmaak.util.TYPE.STRING))
+		return false;
+	
+	console.debug("validateRSAPublicKeyPEM("+rsa_public_key_pem+")");
+	
+	//validate public key
+	//TODO make a more sophisticated regexp
+	var re_public_key = /.*/;
+	//TODO here seems to be a bug
+	console.log(rsa_public_key_pem.match(re_public_key) || "no match");
+	
+	if(re_public_key.test(rsa_public_key_pem))
+		return true;
+	else
+		return false;
+};
+
+
+
+/**
+ * bookmaak.util.validation.validateServerUrl(String) -> Boolean
+ * 
+ * Validates the server url.
+ * 
+ * **server_url** the server url
+ * returns true if valid, otherwise false.
+ **/
+bookmaak.util.validation.validateServerUrl = function(server_url) {
+	
+	if(!bookmaak.util.isType(server_url, bookmaak.util.TYPE.STRING))
+		return false;
+	
+	console.debug("validateServerUrl("+server_url+")");
+	
+	//validate the server url anything, with or without leading http:// and trailing /
+	var re_server_url = /^(?:http:\/\/){0,1}([A-Za-z0-9\.\:\-]+)(?:\/){0,1}$/;
+	
+	console.debug(server_url.match(re_server_url) || "no match");
+	
+	if(re_server_url.test(server_url))
+		return true;
+	else
+		return false;
+};
+
+
+
+

File src/main/server/srv.js

 						
 						throw "it seems you have a single file '"+username+"' in your .boomarks";
 					}
-
 				}
 			});
 }

File util/js-build

 echo '## js source ##'
 
 add src/main/client/namespaces.js
+add src/main/client/constants.js
 
 add src/main/client/domain/Bookmark.js
 add src/main/client/domain/File.js
 
 add src/main/client/util/FTS.js
 add src/main/client/util/Settings.js
+add src/main/client/util/types.js
+add src/main/client/util/validation.js
 
 add src/main/client/dao/BookmarkDao.js