/******************************
 Ajax Login
 Init by A. Krywaniuk, Mar 2006
 Copyright Fortinet, inc.
 All rights reserved
 ******************************/

var my_xmlhttp = null;
var buf_request_in_progress = false;
var challenge_page = false;


// Ajax requests are always encoded in UTF-8. So, I assume, are the responses.
// We can't easily return a string from the server, so better to cache them
// all here. (This table will be overriden by the C code when the page is generated.)
function login_string_table_t()
{
	this.login_failed = "Authentication failure";
	this.lockout_msg = "User lockout";
	this.server_unreachable = "Server unreachable";
}

var str_table = new login_string_table_t();


// login_send_request - send the login request as an Ajax message.
function login_send_request(str_url, str_body) 
{ 
	my_xmlhttp = get_xmlhttp();
	my_xmlhttp.onreadystatechange = handle_buffer_statechange;
	
	my_xmlhttp.open("POST", str_url, true);
	my_xmlhttp.setRequestHeader("Pragma", "no-cache");
	my_xmlhttp.setRequestHeader("Cache-Control", "no-store, no-cache, must-revalidate");
	my_xmlhttp.setRequestHeader("If-Modified-Since", 0);
	my_xmlhttp.send(str_body);
}

// handle_buffer_statechange - onreadystatechange callback for the Ajax request.
function handle_buffer_statechange(ev)
{
	if (my_xmlhttp.readyState == 4) // 4 == complete
	{
		handle_buffer_ready();
	}
}


// try_login - begin the login process.
function try_login()
{
	if (buf_request_in_progress)
	{
		throw("Avoid sending conflicting request\n");
		return;
	}

	buf_request_in_progress = true;

	var elm_username = document.getElementById("username");
	var elm_secretkey = document.getElementById("secretkey");
	var elm_demo = document.getElementById("demomode");

	var xstr = "ajax=1&mode=login&username=" + encodeURIComponent(elm_username.value) + "&secretkey=" + encodeURIComponent(elm_secretkey.value);

	if (elm_demo && elm_demo.checked)
		xstr += "&demomode=1";

	disable_input();
	
	try
	{
		login_send_request("/loginValidation.htm", xstr);
	}
	catch (e)
	{
		buf_request_in_progress = false;
		update_error_status_line(str_table.server_unreachable);
		reenable_input();
		
		my_xmlhttp.abort();
		delete my_xmlhttp;
		my_xmlhttp = null;
	}
}


// send_chal_rsp - send a challenge response.
function send_chal_rsp()
{
        if (buf_request_in_progress)
        {
                throw("Avoid sending conflicting request\n");
                return;
        }

        buf_request_in_progress = true;

        // The challenge response is in the password field.
        var elm_chal_resp = document.getElementById("secretkey");

        var xstr = "ajax=1&mode=login&chal_resp_auth=1&secretkey=" + encodeURIComponent(elm_chal_resp.value);

        disable_input();
        
        try
        {
                login_send_request("/loginValidation.htm", xstr);
        }
        catch (e)
        {
                buf_request_in_progress = false;
                update_error_status_line(str_table.server_unreachable);
                reenable_input();
                
                my_xmlhttp.abort();
                delete my_xmlhttp;
                my_xmlhttp = null;
        }
}


// Display a message in red above the username.
// Flash the colour between black and red to draw the user's attention (in particular when
// the error message is the same as the one from the previous request).
function update_error_status_line(msg)
{
	var elem = document.getElementById("err_msg_txt");
	// [red->]black->red visual cue (in case the text doesn't change)
	elem.style.color = "black";
	
	while(elem.childNodes.length)
	{
		elem.removeChild(elem.childNodes[0]);
	}

	var txt = document.createTextNode(msg);
	elem.appendChild(txt);
	
	setTimeout("var elem = document.getElementById(\"err_msg_txt\");  elem.style.color = \"red\";", 100);
}


// handle_buffer_ready - function to handle the Ajax response. The first
// character of the response is the status code (0 is failure, 1 is success,
// and 2 is a special case for the 1 minute lockout). If success, the
// remainder of the string contains a JS function to redirect to the main page.
function handle_buffer_ready()
{
	// Check & reset semaphore.
	if (!buf_request_in_progress)
		return;

	buf_request_in_progress = false;

	var retval = my_xmlhttp.responseText;
	
	my_xmlhttp = null;
	
	if (retval.length == 0)
	{
		update_error_status_line(str_table.server_unreachable);
		reenable_input();
		return;
	}

	var rv = retval.charAt(0); 
	var rv2 = retval.substring(1); 
	
	if (rv == "1")
	{
		// rv2 contains a page for redirection.
		eval(rv2);
	}
	else if (rv == "2") 
	{
		// rv = 2 is for 1 minute lockout
		update_error_status_line(str_table.lockout_msg);
		
		// Leave form fields during lockout period.
		setTimeout("reenable_input();", 60 * 1000);
	}
	else
	{
		// In case of error, if we are staying on the same page then all we need to
		// do is to update the status line. However, if the challenge response fails
		// then we redirect back to the regular login page.
		update_error_status_line(str_table.login_failed);
		
		if (challenge_page)
		{
			// Pause for 2 seconds so the user can read the error message.
			// Then redirect back to the regular login page.
			setTimeout("top.location='/login.htm'", 2000);
		}
		else
		{
			reenable_input();
		}
	}
}

function disable_input()
{
	var elm_username = document.getElementById("username");
	var elm_secretkey = document.getElementById("secretkey");
	var elm_button = document.getElementById("login_button");
	var elm_demo = document.getElementById("demomode");

	if (elm_username)
	{
		elm_username.value = "";
		elm_username.disabled = true;
	}
	
	if (elm_secretkey)
	{
	    elm_secretkey.value = "";
	    elm_secretkey.disabled = true;
	}
	
	elm_button.disabled = true;

	if (elm_demo)
		elm_demo.disabled = true;
}

function reenable_input()
{
	var elm_username = document.getElementById("username");
	var elm_secretkey = document.getElementById("secretkey");
	var elm_button = document.getElementById("login_button");
	var elm_demo = document.getElementById("demomode");
	
	if (elm_demo)
	{
		elm_demo.disabled = false;

		if (!elm_demo.checked)
		{
			elm_username.disabled = false;
			elm_secretkey.disabled = false;
		}
	}
	else
	{
		if (elm_username) elm_username.disabled = false;
		if (elm_secretkey) elm_secretkey.disabled = false;
	}

	elm_button.disabled = false;

	if (elm_demo && elm_demo.checked)
	{
		elm_demo.focus();
	}
	else
	{
		// Blur and set the focus on username
		if (elm_username)
		{
		    elm_username.blur();
		    elm_username.focus();
		}
	}
}

// login_get_cmd_kbd_event and login_crack_kbd_event are the copies of 
// get_cmd_kbd_event and crack_kbd_event from jsconsole.js
// login_get_cmd_kbd_event - same as get_cons_kbd_event, but uses different document object
function login_get_cmd_kbd_event(evt_p)
{
	if (evt_p)
		return evt_p;
	evt = window.event;
	if (evt) 
		return evt;
	return null;
}

// login_crack_kbd_event - Returns the keypress code associated with the event.
function login_crack_kbd_event(evt)
{
	if (evt.which)
		return evt.which;
	else if (evt.keyCode)
		return evt.keyCode;
	else if (evt.charCode)
		return evt.charCode;
	return 0;
}

function key_pressdown(evt_p)
{
	try
	{
		var evt = login_get_cmd_kbd_event(evt_p);
		if(evt == null) return;
		var key_code = login_crack_kbd_event(evt);
		if(key_code == 0) return;
		// CR: Click login button
		if (key_code == 13)
		{
			var elm_button = document.getElementById("login_button");
			elm_button.click();
			return false;
		}
	}
	catch (e)
	{
	}

	return true;
}


