// $Header: /cvs/cvs_archive/univ/java/src/com/lawson/lawsec/authen/ssowebapp/Attic/sso.js,v 1.1.2.46.8.5 2007/01/05 14:00:14 jayeshn Exp $
//-----------------------------------------------------------------------------
//	Proprietary Program Material
//	This material is proprietary to Lawson Software, and is not to be
//	reproduced or disclosed except in accordance with software contract
//	provisions, or upon written authorization from Lawson Software.
//
//	Copyright (C) 2002 by Lawson Software. All Rights Reserved.
//	Saint Paul, Minnesota
//-----------------------------------------------------------------------------

var ssoFileInstance = findSSO();

/*	searchOpener - Boolean flag to represent whether to search the opener for 
 *				   a copy of the sso.js file.  Defaulted to false because if you
 *				   point to the opener and the opener is closed, you get errors.
 *				   BlackBoxes need to tell the opener about authentication though.
 *	ref - Used for passing starting points for recursive calls.
 */
function findSSO(searchOpener, ref)
{
	if (!ref)
		ref = self;

	try
	{
		// is there a parent?
		if (ref != ref.parent)
		{
			if (typeof(ref.parent.ssoFileInstance) != "undefined")
			{
				// found a copy...
				if (ref.parent.ssoFileInstance != null)
					return ref.parent.ssoFileInstance;
				else
					return ref.parent;
			}
			else if (typeof(ref.parent.winOpener) != "undefined" && ref.parent.winOpener != null)
			{
				// found a copy...
				if (ref.parent.winOpener.ssoFileInstance != null)
					return ref.parent.winOpener.ssoFileInstance;
				else
					return ref.parent.winOpener;
			}
			else if (searchOpener && ref.parent.opener)
			{
				if (typeof(ref.parent.opener.ssoFileInstance) != "undefined")
				{
					// found a copy...
					if (ref.parent.opener.ssoFileInstance != null)
						return ref.parent.opener.ssoFileInstance;
					else
						return ref.parent.opener;
				}
				else
				{
					// didn't find it... try higher on the opener
					var ssoFile = findSSO(searchOpener, ref.parent.opener);
					if (ssoFile)
						return ssoFile;
				}
			}
			else
			{
				// didn't find it... try higher
				var ssoFile = findSSO(searchOpener, ref.parent);
				if (ssoFile)
					return ssoFile;
			}
		}
		else if (searchOpener && ref.opener)
		{
			if (typeof(ref.opener.ssoFileInstance) != "undefined")
			{
				// found a copy...
				if (ref.opener.ssoFileInstance != null)
					return ref.opener.ssoFileInstance;
				else
					return ref.opener;
			}
			else
			{
				// didn't find it... try higher on the opener
				var ssoFile = findSSO(searchOpener, ref.opener);
				if (ssoFile)
					return ssoFile;
			}
		}
		else if (typeof(winOpener) != "undefined")
			return winOpener;
	}
	catch (e)
	{
		// error occured, give up...
	}

	return null;
}

//-----------------------------------------------------------------------------
//-- start browser object code
function SSOBrowser()
{
	// only allow 1 instance of this object
	if (SSOBrowser._singleton)
		return SSOBrowser._singleton;
	else
	{
		// try to get objects from 1 instance of this file
		if (ssoFileInstance)
		{
			SSOBrowser._singleton = ssoFileInstance.SSOBrowser._singleton;
			return SSOBrowser._singleton;
		}
		SSOBrowser._singleton = this;
	}

	// browsers
	this.isIE    = false;
	this.isNS    = false;
	this.isSAF	 = false;
	this.version = null;
	this.language = "en-us";

	// operating systems
	this.isMAC   = false;
	this.isWIN   = false;
	this.osVersion = 0;
	this.isXP = false;

	var ua = navigator.userAgent;
	var an = navigator.appName;

	// BROWSER
	if (an == "Microsoft Internet Explorer")
	{
		var key = "MSIE ";
		this.isIE = true;
		this.version = parseFloat(ua.substr(ua.indexOf(key) + key.length));
	}
	else if (an == "Netscape")
	{
		// Safari lies and says it's Netscape
		if (ua.indexOf("Safari") != -1)
		{
			var key = "Safari/";
			this.isNS = true;	// temporary
			this.isSAF = true;
			this.version = parseFloat(ua.substr(ua.indexOf(key) + key.length));
		}
		else
		{
			this.isNS = true;
			this.version = parseFloat(navigator.vendorSub);
		}
	}

	// language
	this.language = ((this.isIE) ? navigator.userLanguage : navigator.language).toLowerCase();

	// OPERATING SYSTEM
	if (ua.indexOf("Windows") >= 0)
	{
		this.isWIN = true;
		var idx = ua.indexOf("Windows NT ");
		if (idx != -1)
		{
			this.osVersion = parseFloat(ua.substring(idx+11), 10);
			if (this.osVersion >= 5.1)
				this.isXP = true;
		}
	}
	else if (ua.indexOf("Macintosh") >= 0)
		this.isMAC = true;
}
SSOBrowser.prototype._singleton = null;
SSOBrowser.prototype.cookiesEnabled = function()
{
	if (navigator.cookieEnabled)
	{
		var cName = "TestCookie";
		var cValue = "Cookie Saved!";
		this.setCookie(cName, cValue, new Date(new Date().getTime()+25000)); // a 25-second cookie
		if (this.getCookie(cName) == cValue)
			return true;
	}
	return false;
}
SSOBrowser.prototype.getCookie = function(name)
{
	var re = new RegExp(name + "=([^;]+)");
	var value = re.exec(document.cookie);
	return (value != null) ? unescape(value[1]) : null;
}
SSOBrowser.prototype.setCookie = function(name, value, expires, path, domain, secure)
{
	if (!name || !value)
		return;

	var c = name + "=" + escape(value);
	if (expires)
		c += "; expires=" + expires.toGMTString();
	if (path)
		c += "; path=" + path;
	if (domain)
		c += "; domain=" + domain;
	if (secure && typeof(secure) == "boolean")
		c += "; secure";
	document.cookie = c;
}
//-- end browser object code
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
//-- start url object code
function URLObject(url)
{
	if (typeof(url) != "string" || url.substring(0,4).toLowerCase() != "http")
		url = null;

	this.url = url;
	// private variables, use methods
	this.protocol = null;
	this.host = null;
	this.port = null;
}
URLObject.prototype.getProtocol = function()
{
	if (this.protocol == null && this.url != null)
		this.protocol = (this.url.indexOf("https:") == 0) ? "https:" : "http:" ;
	return this.protocol;
}
URLObject.prototype.getHost = function()
{
	if (this.host == null && this.url != null)
	{
		this.host = this.url.substring(this.getProtocol().length + 2);
		this.host = (this.host.indexOf("/") != -1) ? this.host.substring(0, this.host.indexOf("/")) : this.host ;
		if (this.getProtocol()== "http:" && this.host.substring(this.host.length-3) == ":80")
			this.host = this.host.substring(0, this.host.length-3);
		else if(this.getProtocol()== "https:" && this.host.substring(this.host.length-4) == ":443")
			this.host = this.host.substring(0, this.host.length-4);
	}
	return this.host;
}
URLObject.prototype.getPort = function()
{
	if (this.port == null && this.url != null)
	{
		this.port = this.getHost();
		if (this.port.indexOf(":") == -1)
			this.port = "";
		else
		{
			var tmpAry = this.port.split(":");
			this.port = tmpAry[tmpAry.length-1];
		}
		if ((this.getProtocol() == "http:" && this.port == "80")
			|| (this.getProtocol() == "https:" && this.port == "443"))
			this.port = "";
	}
	return this.port;
}
URLObject.prototype.isSameProtocol = function()
{
	return (this.getProtocol() == document.location.protocol) ? true : false ;
}
URLObject.prototype.isSameHost = function()
{
	var thisHost = this.getHost();
	var isSame = (thisHost != null && thisHost.toLowerCase() == document.location.host.toLowerCase()) ? true : false ;
	if (!isSame && document.location.protocol == "http:" && document.location.port == "80")
	{
		var locHost = document.location.host.substring(0, document.location.host.length-3);
		if (this.getHost().toLowerCase() == locHost.toLowerCase())
			isSame = true;
	}
	else if(!isSame && document.location.protocol == "https:" && document.location.port == "443")
	{
		var locHost = document.location.host.substring(0, document.location.host.length-4);
		if (this.getHost().toLowerCase() == locHost.toLowerCase())
			isSame = true;
	}
	return isSame;
}
URLObject.prototype.isSamePort = function()
{
	var isSame = (this.getPort() == document.location.port) ? true : false ;
	if (!isSame)
	{
		if(document.location.protocol == "http:" && document.location.port == "80" && this.getPort() == "")
			isSame = true;
		else if(document.location.protocol == "https:" && document.location.port == "443" && this.getPort() == "")
			isSame = true;
	}
	return isSame;
}
//-- end url object code
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
//-- start object factory code
function SSOObjectFactory()
{
	// only allow 1 instance of this object
	if (SSOObjectFactory._singleton)
		return SSOObjectFactory._singleton;

	// PT 145923 - singleton is OK, but not a reference to ssoFileInstance, it messes up relative path calls
	SSOObjectFactory._singleton = this;

	// default to minimal XML support
	this.browser = new SSOBrowser();
	this.errorObj = new SSOErrorObject();
	this.xmlVersion = (this.browser.isIE ? "2.0" : "");
	this.xmlDOMProgId = (this.browser.isIE ? "Microsoft.XMLDOM" : "");
	this.xmlHTTPProgId = (this.browser.isIE ? "Microsoft.XMLHTTP" : "NSMTTPReqest");
	this.xmlFTDOMProgId = "";
	this.xmlXSLTProgId = "";

	if (!this.browser.isIE)
		return;

	var domObj = null;
	var ver = "";
	try
	{
		domObj = new ActiveXObject("Msxml2.DOMDocument.4.0");
		ver = "4.0";
	}
	catch (e)
	{
		try
		{
			domObj = new ActiveXObject("Msxml2.DOMDocument.3.0");
			ver = "3.0";
		}
		catch (e)
		{
			try
			{
				// 'basic' DOM Documents only
				domObj = new ActiveXObject(this.xmlDOMProgId);
			}
			catch (e)
			{
				this.xmlDOMProgId = "";
				this.xmlHTTPProgId = "";
			}
			return;
		}
	}
	this.xmlVersion  = ver;
	this.xmlDOMProgId = "Msxml2.DOMDocument." + ver;
	this.xmlHTTPProgId = "Msxml2.XMLHTTP." + ver;
	this.xmlFTDOMProgId = "Msxml2.FreeThreadedDOMDocument." + ver;
	this.xmlXSLTProgId = "Msxml2.XSLTemplate." + ver;
}
SSOObjectFactory.prototype._singleton = null;
SSOObjectFactory.prototype.getMSXMLVersion = function()
{
	return this.xmlVersion;
}
SSOObjectFactory.prototype.createInstance = function(type)
{
	var retObj = null;
	try
	{
		switch(type.toUpperCase())
		{
			case "DOM":  // DOM document
				retObj = this.browser.isNS
					? null
					: new ActiveXObject(this.xmlDOMProgId);
				break;
			case "HTTP": // HTTP request object
				retObj = this.browser.isNS
					? new XMLHttpRequest()
					: new ActiveXObject(this.xmlHTTPProgId);
				break;
			case "FTDOM": // FreeThreaded DOM document
				retObj = this.browser.isNS
					? null
					: new ActiveXObject(this.xmlFTDOMProgId);
				break;
			case "XSLT": // XSLT Template object
				retObj = this.browser.isNS
					? null
					: new ActiveXObject(this.xmlXSLTProgId);
				break;
		}
	}
	catch (e)
	{ // do nothing
	}
	return retObj;
}
SSOObjectFactory.prototype.getDomFromString = function(xmlStr)
{
	if (typeof(xmlStr) != "string")
		xmlStr = "";

	var retDom = null;
	var errorMsg = "Invalid XML String";
	var errorDtl = "SSOObjectFactory.getDomFromString() - sso.js";

	if (this.browser.isIE)
	{
		retDom = this.createInstance("DOM");
		retDom.async = false;
		retDom.loadXML(xmlStr);
		var pErr = retDom.parseError;
		if (pErr.errorCode != 0)
		{
			errorDtl = "Reason: " + pErr.reason + "\n"
					 + ((pErr.url != "") ? "URL: " + pErr.url + "\n" : "")
					 + "Source: " + pErr.srcText + "\n"
					 + "Line: " + pErr.line + "\n"
					 + "Line Position: " + pErr.linepos + "\n"
					 + "File Position: " + pErr.filepos + "\n"
					 + errorDtl;

			// add debugging to the Portal's trace window
			portalTraceMsg(errorMsg, errorDtl);
			portalTraceResponseObj("SSOObjectFactory.getDomFromString(...)", xmlStr);

			return this.errorObj.getErrorDom(errorMsg, errorDtl);
		}
	}
	else
	{
		var parser = new DOMParser();
		retDom = parser.parseFromString(xmlStr, "text/xml");

		if (retDom.documentElement.nodeName == "parsererror")
		{
			if (retDom.documentElement.firstChild)
				errorDtl = retDom.documentElement.firstChild.nodeValue + "\n\n" + errorDtl;

			// add debugging to the Portal's trace window
			portalTraceMsg(errorMsg, errorDtl);
			portalTraceResponseObj("SSOObjectFactory.getDomFromString(...)", xmlStr);

			return this.errorObj.getErrorDom(errorMsg, errorDtl);
		}
	}
	return retDom;
}
SSOObjectFactory.prototype.getStringFromDom = function(xmlDom, bFormat)
{
	if (typeof(bFormat) != "boolean")
		bFormat = false;

	if (this.browser.isIE)
	{
		if (!bFormat)
			return xmlDom.xml;

		try
		{
			var str = xmlDom.replace(/\>\</gi,">\n<");
			var dom = this.createInstance("DOM");
			dom.async = false;
			dom.loadXML(str);
			str = dom.xml;
			return str;
		}
		catch (e)
		{}

		return xmlDom.xml;
	}

	// non IE
	var ser = new XMLSerializer();
	var str = ser.serializeToString(xmlDom);
	if (bFormat)
	{
		str = str.replace(/\>\</gi,">\n<");
		str = str.replace(/\>\t/g,">\n\t");
	}
	return str;
}
//-- end object factory code
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
//-- start sso error object code
function SSOErrorObject()
{
	this.browser = new SSOBrowser();
	this.objFactory = new SSOObjectFactory();
}
SSOErrorObject.prototype.getErrorDom = function(msg, details, errorNbr, levelNbr)
{
	if (typeof(msg) == "undefined")
		msg = "Error";
	if (typeof(details) == "undefined")
		details = "No additional details to provide.\n\nSSOErrorObject.getErrorDom() - sso.js";
	if (typeof(errorNbr) == "undefined")
		errorNbr = 1;
	if (typeof(levelNbr) == "undefined")
		levelNbr = 1;

	var xmlStr = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>"
			   + "<ERROR key=\"" + errorNbr + "\" level=\"" + levelNbr + "\">"
			   + "<MSG><![CDATA[" + msg + "]]></MSG>"
			   + "<DETAILS><![CDATA[" + details + "]]></DETAILS>"
			   + "</ERROR>";

	return this.objFactory.getDomFromString(xmlStr);
}
SSOErrorObject.prototype.getExceptionMsg = function(e)
{
	var errorMsg = "";
	if (this.browser.isIE)
	{
		errorMsg = "ERROR: " + e.name + "\n"
				 + "Number: " + (e.number & 0xFFFF) + "\n"
				 + "Message: " + e.message + "\n"
				 + "Description: " + e.description
	}
	else
	{
		errorMsg += "ERROR:\n";
		var isCharAry = null;
		var ctr = 0;
		for (var i in e)
		{
			if (isCharAry == null)
				isCharAry = (e[i].length > 1) ? false : true ;
			if (isCharAry)
			{
				errorMsg += e[i];
				if (++ctr % 70 == 0)
					errorMsg += "\n"
			}
			else
				errorMsg += e[i] + "\n";
		}
	}
	return errorMsg;
}
//-- end sso error object code
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
//-- start authentication object code
function SSOAuthObject()
{
	// only allow 1 instance of this object
	if (SSOAuthObject._singleton)
		return SSOAuthObject._singleton;
	else
	{
		// try to get objects from 1 instance of this file
		if (ssoFileInstance)
		{
			SSOAuthObject._singleton = ssoFileInstance.SSOAuthObject._singleton;
			return SSOAuthObject._singleton;
		}
		SSOAuthObject._singleton = this;
	}

	// PUBLIC
	this.browser		= new SSOBrowser();
	this.configUrl		= "/ssoconfig/SSOCfgInfoServlet";
	this.modalPageRet	= null;
	this.modalPageUrl	= null;
	this.modalPageSrc	= null;
	this.logoutUrl		= "/sso/logout.htm";
	this.useSSO			= true; // whether to check reponses for login page and call SSOCfgInfoServlet, etc...

	// PRIVATE
	this.alertErrMsgs = false;		// whether to have the object alert errors
	this.configDom = null;			// XML returned by this.configUrl
	this.version = "";				// Version of the SSOCfgInfoServlet
	this.primaryUrl = "";			// HTTPS Url
	this.HTTPUrl = "";				// HTTP Url
	this.isPrimary = null;			// will be boolean
	this.timeoutVal = -1;			// minutes
	this.configAry = new Array();	// values to look for in a login page
	this.canChgPwd = null;			// will be boolean
	this.userName = "";				// will be set when calling PING.. and cached until logout
	this.language = "";				// will be set when calling PING.. and cached until logout
	this.bBoxAry = new Array();		// used by Black Box Object ONLY!
	this.bBoxIfrm = null;			// used by Black Box Object ONLY if not provided to constructor
	this.HomePage = "";             // HomePage Url
	this.RelyingSvcURL = "";        // SSO service on the current endpoint
}
SSOAuthObject.prototype._singleton = null;
SSOAuthObject.prototype.getAlertErrors = function()
{
	return this.alertErrMsgs;
}
SSOAuthObject.prototype.setAlertErrors = function(bErrors)
{
	if (typeof(bErrors) == "boolean")
		this.alertErrMsgs = bErrors;
}
SSOAuthObject.prototype.isSSOOn = function()
{
	return this.useSSO;
}
SSOAuthObject.prototype.turnSSOOff = function()
{
	this.useSSO = false;
}
SSOAuthObject.prototype.turnSSOOn = function()
{
	this.useSSO = true;

	// reset some need variables
	this.configDom = null;
	this.version = "";
	this.primaryUrl = "";
	this.HTTPUrl = "";
	this.isPrimary = null;
	this.timeoutVal = -1;
	this.configAry = new Array();
	this.canChgPwd = null;
	this.userName = "";
	this.language = "";
}
SSOAuthObject.prototype.getConfigDom = function()
{
	if (this.configDom == null && this.isSSOOn())
	{
		this.configDom = SSORequest(this.configUrl, null, null, null, this.getAlertErrors());
		if (this.configDom.status > 400)
		{
			this.configDom = null;
			if (this.getAlertErrors())
				alert(this.configUrl + " did not return valid XML\n\nSSOAuthObject.getConfigDom() - sso.js");
		}
	}
	return this.configDom;
}
SSOAuthObject.prototype.getVersion = function()
{
	if (this.version == "")
	{
		var cDom = this.getConfigDom();
		if (cDom == null)
			return null;

		var propNodes = cDom.getElementsByTagName("SSOCONFIG");
		if (propNodes.length > 0)
			this.version = propNodes[0].getAttribute("version");
		else if (this.getAlertErrors())
			alert("The version was not found in " + this.configUrl + "\n\nSSOAuthObject.getVersion() - sso.js");
	}
	return this.version;
}

SSOAuthObject.prototype.getPrimaryUrl = function()
{
	if (this.primaryUrl == "")
	{
		var cDom = this.getConfigDom();
		if (cDom == null)
			return null;

		var propNodes = cDom.getElementsByTagName("PROPERTY");
		for (var i=0; i<propNodes.length; i++)
		{
			if (propNodes[i].getAttribute("name") == "loginurl")
			{
				this.primaryUrl = propNodes[i].getAttribute("value");
				break;
			}
		}

		if (this.primaryUrl == null && this.getAlertErrors())
			alert("The Primary URL was not found from " + this.configUrl + "\n\nSSOAuthObject.getPrimaryUrl() - sso.js");
	}
	return this.primaryUrl;
}

SSOAuthObject.prototype.getHomePage = function()
{
       if (this.HomePage == "")
       {
               var cDom = this.getConfigDom();
               if (cDom == null)
                       return null;

               var propNodes = cDom.getElementsByTagName("PROPERTY");
               for (var i=0; i<propNodes.length; i++)
               {
                       if (propNodes[i].getAttribute("name") == "serviceurl")
                       {
                               this.HomePage = propNodes[i].getAttribute("value");
                               break;
                       }
               }

               if (this.HomePage == "")
                       this.HomePage = "NOTFOUND";
       }
       if(this.HomePage == "NOTFOUND")
               return null;
       else
               return this.HomePage;
}

SSOAuthObject.prototype.getRelyingSvcURL = function()
{
       if (this.RelyingSvcURL == "")
       {
               var cDom = this.getConfigDom();
               if (cDom == null)
                       return null;

               var propNodes = cDom.getElementsByTagName("PROPERTY");
               for (var i=0; i<propNodes.length; i++)
               {
                       if (propNodes[i].getAttribute("name") == "relying_service_url")
                       {
                               this.RelyingSvcURL = propNodes[i].getAttribute("value");
                               break;
                       }
               }

               if (this.RelyingSvcURL == "")
                       this.RelyingSvcURL = "NOTFOUND";
       }
       if(this.RelyingSvcURL == "NOTFOUND")
               return null;
       else
               return this.RelyingSvcURL;
}
 
SSOAuthObject.prototype.getHTTPUrl = function()
{
	if (this.HTTPUrl == "")
	{
		var cDom = this.getConfigDom();
		if (cDom == null)
			return null;

		var propNodes = cDom.getElementsByTagName("PROPERTY");
		for (var i=0; i<propNodes.length; i++)
		{
			if (propNodes[i].getAttribute("name") == "httpurl")
			{
				this.HTTPUrl = propNodes[i].getAttribute("value");
				break;
			}
		}

		if (this.HTTPUrl == null && this.getAlertErrors())
			alert("The HTTP URL was not found from " + this.configUrl + "\n\nSSOAuthObject.getHTTPUrl() - sso.js");
	}
	return this.HTTPUrl;
}
SSOAuthObject.prototype.isPrimaryBox = function()
{
	if (this.isPrimary == null)
	{
		this.isPrimary = false;

		// Primary URL (HTTPS)
		var primObj = new URLObject(this.getPrimaryUrl());	
		if (primObj.isSameProtocol() && primObj.isSameHost())
			this.isPrimary = true;

		// Primary URL (HTTP)
		var httpObj = new URLObject(this.getHTTPUrl());	
		if (httpObj.isSameProtocol() && httpObj.isSameHost())
			this.isPrimary = true;
	}
	return this.isPrimary;
}
SSOAuthObject.prototype.getTimeoutValue = function()
{
	if (this.timeoutVal == -1)
	{
		var cDom = this.getConfigDom();
		if (cDom == null)
			return null;

		var propNodes = cDom.getElementsByTagName("PROPERTY");
		for (var i=0; i<propNodes.length; i++)
		{
			if (propNodes[i].getAttribute("name") == "sessionto")
			{
				this.timeoutVal = parseInt(propNodes[i].getAttribute("value"), 10);
				break;
			}
		}

		if (this.timeoutVal == -1 && this.getAlertErrors())
			alert("The timeout value was not found from " + this.configUrl + "\n\nSSOAuthObject.getTimeoutValue() - sso.js");
	}
	return this.timeoutVal;
}
SSOAuthObject.prototype.getConfigArray = function()
{
	var cDom = this.getConfigDom();
	if (this.configAry.length > 0 || cDom == null)
		return this.configAry;

	var authenType = "";
	var propNodes = cDom.getElementsByTagName("PROPERTY");
	for (var i=0; i<propNodes.length; i++)
	{
		if (propNodes[i].getAttribute("name") == "authen_type")
		{
			authenType = propNodes[i].getAttribute("value");
			break;
		}
	}

	if (authenType.toUpperCase() == "FORM")
	{
		this.configAry.length++;
		this.configAry["authen_type"] = authenType;

		for (var i=0; i<propNodes.length; i++)
		{
			var name = propNodes[i].getAttribute("name");
			var value = propNodes[i].getAttribute("value");
			switch (name)
			{
				case "usernamefield":
					this.configAry["usernamefield"] = value;
					break;
				case "passwordnamefield":
					this.configAry["passwordnamefield"] = value;
					break;
				case "loginurl":
					this.configAry["loginurl"] = value;
					break;
				case "origurl_field_name":
					this.configAry["origurl_field_name"] = value;
					break;
			}
		}
	}
	else if (this.getAlertErrors())
		alert("Login Type: '" + authenType + "' is not supported!\n\nSSOAuthObject.getConfigArray() - sso.js");

	return this.configAry;
}
SSOAuthObject.prototype.canChangePwd = function()
{
	if (this.canChgPwd == null)
	{
		this.canChgPwd = false;

		var cDom = this.getConfigDom();
		if (cDom == null)
			return this.canChgPwd;

		var propNodes = cDom.getElementsByTagName("PROPERTY");
		for (var i=0; i<propNodes.length; i++)
		{
			if (propNodes[i].getAttribute("name") == "change_password")
			{
				if ("TRUE" == propNodes[i].getAttribute("value").toUpperCase())
					this.canChgPwd = true;
				break;
			}
		}
	}
	return this.canChgPwd;
}
SSOAuthObject.prototype.login = function()
{
	if (!this.isSSOOn())
		return false;

	if (!this.isPrimaryBox())
	{
		if (this.getAlertErrors())
			alert("This method can only be called from the primary service!\n\nSSOAuthObject.login() - sso.js");
		return false;
	}

	if (this.ping(true))
		return true;

	var origUrl = document.location.protocol + "//" + document.location.host + "/sso/blank.htm";
	var blank = SSORequest("/sso/SSOServlet?_ssoOrigUrl=" + escape(origUrl), null, null, null, this.getAlertErrors());
	return (blank != null ? true : false);
}
SSOAuthObject.prototype.changePassword = function()
{
	if (!this.isSSOOn())
		return;

	if (!this.canChangePwd())
	{
		if (this.getAlertErrors())
			alert("You are not allowed to change your password!\n\nSSOAuthObject.changePassword() - sso.js");
		return;
	}

	//Use relying service url for york env
	var cpUrl = this.getRelyingSvcURL();
	//Relying service url will be null for non-york env, use primary url instead
	if (cpUrl == null)
		cpUrl = this.getPrimaryUrl();
	cpUrl = cpUrl.substring(0, cpUrl.indexOf("SSOServlet")) + "pwchange.htm";

	// prepare to open modal window
	var modWidth = 570;
	var modHeight = 526;
	var modLeft = parseInt((screen.width / 2) - (modWidth / 2), 10);
	var modTop = parseInt((screen.height / 2) - (modHeight / 2), 10);
	if (this.browser.isIE)
		window.showModalDialog(cpUrl, new Array(window), "dialogLeft:" + modLeft + "px;dialogTop:" + modTop + "px;dialogWidth:" + modWidth + "px;dialogHeight:" + modHeight + "px;status:0;help:0");
	else
		window.open(cpUrl, "redirectWindow", "left=" + modLeft + ",top=" + modTop + ",width=" + modWidth + ",height=" + modHeight + ",modal");
}
SSOAuthObject.prototype.ping = function(updateSession)
{
	if (!this.isSSOOn())
		return false;

	var bSessionActive = false;
	var ssoURL = "/sso/SSOServlet?_action=PING";
	if (typeof(updateSession) == "boolean" && updateSession)
		ssoURL += "&_updateSession=true";
	var ssoDom = SSORequest(ssoURL, null, null, null, this.getAlertErrors());

	// is active?
	var sessionStatusNodes = ssoDom.getElementsByTagName("SESSIONSTATUS");
	if (sessionStatusNodes.length > 0 && sessionStatusNodes[0].firstChild)
	{
		var sessValue = sessionStatusNodes[0].firstChild.nodeValue;
		if (sessValue.toUpperCase() == "TRUE")
			bSessionActive = true;
	}
	return bSessionActive;
}
SSOAuthObject.prototype.globalPing = function()
{
	if (!this.isSSOOn())
		return false;

	var bSessionActive = false;
	var ssoURL = "/sso/SSOServlet?_action=PING&_globalPing=true";

	var blank = SSORequest(ssoURL, null, null, null, this.getAlertErrors());
	return (blank != null ? true : false);
}
SSOAuthObject.prototype.getUserName = function()
{
	if (this.userName == "" && this.isSSOOn())
	{
		var ssoDom = SSORequest("/sso/SSOServlet?_action=PING", null, null, null, this.getAlertErrors());

		// store username
		var userNameNodes = ssoDom.getElementsByTagName("USERNAME");
		if (userNameNodes.length > 0 && userNameNodes[0].firstChild)
			this.userName = userNameNodes[0].firstChild.nodeValue;
	}
	return this.userName;
}
SSOAuthObject.prototype.getLanguage = function()
{
	if (this.language == "" && this.isSSOOn())
	{
		var ssoDom = SSORequest("/sso/SSOServlet?_action=PING", null, null, null, this.getAlertErrors());

		// store username
		var languageNodes = ssoDom.getElementsByTagName("LANGUAGE");
		if (languageNodes.length > 0 && languageNodes[0].firstChild)
			this.language = languageNodes[0].firstChild.nodeValue;
	}
	return this.language;
}
SSOAuthObject.prototype.getActiveTimeRemaining = function()
{
	if (!this.isSSOOn())
		return 0;

	var ssoDom = SSORequest("/sso/SSOServlet?_action=PING", null, null, null, this.getAlertErrors());
	var timeNodes = ssoDom.getElementsByTagName("TIME_REMAINING");
	if (timeNodes.length > 0 && timeNodes[0].firstChild)
		return parseInt(timeNodes[0].firstChild.nodeValue, 10);
}
SSOAuthObject.prototype.logout = function(postLogoutUrl, logoutWnd)
{
	if (!this.isSSOOn())
		return;

	// clear any info that is cached...
	this.userName = "";
	this.language = "";
	this.bBoxAry = new Array();

	// validate the postLogoutUrl
	if (postLogoutUrl)
	{
		var urlObj = new URLObject(postLogoutUrl);
		if (urlObj.url == null)
			postLogoutUrl = "";
		else
			postLogoutUrl = "?" + escape(postLogoutUrl);
	}
	else
	{
		postLogoutUrl = "";
		try
		{
			// where to send them? (i.e. Portal -> Portal)
			// push them back to the page they just came from
			postLogoutUrl = "?" + escape(window.location);
		}
		catch (e)
		{}
	}

	try
	{
		logoutWnd.location.replace(this.logoutUrl + postLogoutUrl);
	}
	catch (e)
	{
		try
		{
			logoutWnd.src = this.logoutUrl + postLogoutUrl;
		}
		catch (e)
		{
			window.location.replace(this.logoutUrl + postLogoutUrl);
		}
	}
}
//-- end authentication object code
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
//-- start black (grey) box object code
function BBoxObject(url, serviceName, ifrm)
{
	this.url = url;
	this.serviceName = (!serviceName) ? null : serviceName;
	this.ifrm = (!ifrm) ? null : ifrm;
	this.type = null;
	this.authObj = new SSOAuthObject();

	// try to determine box type (black or grey)
	var cDom = this.authObj.getConfigDom();
	if (cDom == null)
		return;

	var blackboxNodes = cDom.getElementsByTagName("BLACKBOXSERVICES");
	if (blackboxNodes.length == 0)
	{
		// we don't know your service.. set it to null
		this.serviceName = null;
		this.type = null;
		return;
	}

	var serviceNodes = blackboxNodes[0].getElementsByTagName("SERVICE");
	for (var i=0; i<serviceNodes.length; i++)
	{
		if (this.serviceName != null && this.serviceName == serviceNodes[i].getAttribute("name"))
			this.type = serviceNodes[i].getAttribute("type");
		else
		{
			var regExpNodes = serviceNodes[i].getElementsByTagName("REGEXP");
			for (var j=0; j<regExpNodes.length; j++)
			{
				var reVal = regExpNodes[j].getAttribute("value");
				var re = new RegExp(reVal, "i");
				if (re.test(this.url))
				{
					this.serviceName = serviceNodes[i].getAttribute("name");
					this.type = serviceNodes[i].getAttribute("type");
					this.callBackTime = serviceNodes[i].getAttribute("timeout");
					break;
				}
			}
		}
		if (this.serviceName != null && this.type != null)
			break;
	}

	// we don't know your service.. set it to null
	if (this.type == null)
		this.serviceName = null;

	if (isPortalTraceOn())
	{
		var dataStr = "serviceName = " + this.serviceName + "\n"
					+ "type = " + this.type + "\n"
					+ "callBackTime = " + this.callBackTime+ "\n"
					+ "url = " + this.url + "\n"
					+ "ifrm = " + this.ifrm;
		portalTraceMsg("BlackBox object created", dataStr);
	}
}
// login() returns a boolean - whether you should wait for login occur
BBoxObject.prototype.login = function()
{
	if (this.serviceName == null)
	{
		portalTraceMsg("Cannot login to 'null' service.");
		return false;
	}

	// check timestamp - 2 logins in less than 5 seconds ?
	if (typeof(this.authObj.bBoxLoginTimes) != "object")
		this.authObj.bBoxLoginTimes = new Array();
	else
	{
		if (this.authObj.bBoxLoginTimes[this.serviceName])
		{
			var currTime = new Date().getTime();
			var loginTime = this.authObj.bBoxLoginTimes[this.serviceName];
			if ((currTime-loginTime)/1000 < 3)
			{
				var errMsg = "There was an error authenticating to \"" + this.serviceName + "\".  Please have your administrator check your single sign-on configuration.";
				var wnd = (ssoFileInstance) ? ssoFileInstance : self;
				if ((wnd && typeof(wnd.oUserProfile) == "object"))
				{
					var portalWnd = wnd;
					var portalObj = portalWnd.lawsonPortal;
					portalTraceMsg("ERROR: User has tried to login to '" + this.serviceName + "' twice in less than three seconds!", "This usually represents an infinite loop due to bad configuration.  Please check the setup and try again.");
					portalObj.setMessage("Error with authentication to \"" + this.serviceName + "\" service.");
					portalWnd.cmnDlg.messageBox(errMsg,"ok","stop");
					portalWnd.switchContents(portalWnd.getHome());
				}
				else
					alert(errMsg);
				return true;
			}
		}
	}

	// add timestamp for future login calls
	this.authObj.bBoxLoginTimes[this.serviceName] = new Date().getTime();

	if (this.isLoggedIn())
	{
		portalTraceMsg("User already logged in to '" + this.serviceName + "' service.");
		return false;
	}

	if (this.ifrm == null)
		this.ifrm = this.getIfrm();

	var loginUrl = this.authObj.getPrimaryUrl() + "?_action=BLACKBOX&_ssoBBoxName=" + escape(this.serviceName);
	var xmlOutUrl = loginUrl + "&_out=XML";
	loginUrl += "&_out=HTML";
	portalTraceMsg("Logging in to blackbox service '" + this.serviceName + "'", "Calling '" + loginUrl + "' to return an HTML form for login.\n\nFor a list of parameters on the HTML form, call " + xmlOutUrl);
	this.ifrm.src = loginUrl;
	return true;
}
BBoxObject.prototype.getIfrm = function()
{
	if (this.authObj.bBoxIfrm == null)
	{
		this.authObj.bBoxIfrm = document.createElement("IFRAME");
		this.authObj.bBoxIfrm.id = "dynamicSSOiframe";
		this.authObj.bBoxIfrm.style.position = "absolute";
		this.authObj.bBoxIfrm.style.visibility = "hidden";
		this.authObj.bBoxIfrm.style.display = "block";
		this.authObj.bBoxIfrm.style.width = "0px";
		this.authObj.bBoxIfrm.style.height = "0px";
		this.authObj.bBoxIfrm.style.border = "0px";
		document.body.appendChild(this.authObj.bBoxIfrm);
	}
	portalTraceMsg("Getting a frame for login.", "Returning " + this.authObj.bBoxIfrm + " - id = " + this.authObj.bBoxIfrm.id);
	return this.authObj.bBoxIfrm;
}
BBoxObject.prototype.isLoggedIn = function()
{
	if (this.serviceName == null)
	{
		portalTraceMsg("Service is null, user is not logged in.");
		return false;
	}

	for (var i=0; i<this.authObj.bBoxAry.length; i++)
	{
		var svcName = this.authObj.bBoxAry[i];
		if (this.serviceName == svcName)
		{
			portalTraceMsg("User is logged in to '" + this.serviceName + "' service.");
			return true;
		}
	}

	portalTraceMsg("User is not logged in to '" + this.serviceName + "' service.");
	return false;
}
BBoxObject.prototype.addService = function()
{
	if (this.serviceName == null)
	{
		portalTraceMsg("Cannot add 'null' service to list of logged in services.");
		return;
	}

	// make sure you don't add a duplicate
	if (!this.isLoggedIn())
	{
		portalTraceMsg("Adding blackbox service '" + this.serviceName + "' to list of logged in services.");
		this.authObj.bBoxAry[this.authObj.bBoxAry.length] = this.serviceName;
	}
}
BBoxObject.prototype.removeService = function()
{
	if (this.serviceName == null)
	{
		portalTraceMsg("Cannot remove 'null' service from list of logged in services.");
		return;
	}

	for (var i=0; i<this.authObj.bBoxAry.length; i++)
	{
		var svcName = this.authObj.bBoxAry[i];
		if (this.serviceName == svcName)
		{
			portalTraceMsg("Removing blackbox service '" + this.serviceName + "' from list of logged in services.");
			for (var j=i; j<this.authObj.bBoxAry.length-1; j++)
				this.authObj.bBoxAry[j] = this.authObj.bBoxAry[j+1];
			this.authObj.bBoxAry.length--;
		}
	}
}
//-- end black (grey) box object code
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
function SSORequest(url, pkg, cntType, outType, bShowErrors)
{
	try
	{
		var objFactory = new SSOObjectFactory();
		var authObj = new SSOAuthObject();
		var browser = new SSOBrowser();
		var errorObj = new SSOErrorObject();
		var oHTTP;
		var oResponse;
		var sndDom;
		var cmd = "GET";
		var conType;

		if (typeof(cntType) == "undefined" || cntType == "" || cntType == null)
			cntType = "text/xml";	//Default to XML if undefined
		if (typeof(outType )== "undefined" || outType == "" || outType == null)
			outType = "text/xml";	//Default to XML if undefined
		if (typeof(bShowErrors) != "boolean")
			bShowErrors = true;

		// Check for an invalid URL
		if (typeof(url) == "undefined" || url == null || url == "")
		{
			var errorMsg = "Invalid URL: " + url;
			var errorDtl = "SSORequest() - sso.js";
			if (bShowErrors)
				alert(errorMsg + "\n\n" + errorDtl);

			if (outType == "text/xml")
				return errorObj.getErrorDom(errorMsg, errorDtl);
			else
				return errorMsg;
		}

		oHTTP = objFactory.createInstance("HTTP");

		switch(typeof(pkg))
		{
			case "string":
			{
				if (pkg == "")
				{
					pkg = null;
					break;
				}
				//Load into a DOM object, NS can not take a javascript string as a send parameter
				cmd = "POST";
				if (cntType == "text/xml")
				{
					pkg = objFactory.getDomFromString(pkg);
					if (pkg.documentElement.nodeName == "ERROR")
					{
						if (bShowErrors)
							alert(pkg.documentElement.firstChild.firstChild.nodeValue + "\n\n" + pkg.documentElement.firstChild.nextSibling.firstChild.nodeValue);
						return pkg;
					}
				}
				break;
			}
			case "object":
			{
				if (pkg == null)
					break;
				//Must be a DOM or some other stream type object
				cmd = "POST";
				break;
			}
			default:
			{
				//No package, request is a get
				pkg = null;
				break;
			}
		}

		oHTTP.open(cmd, url, false);
		oHTTP.setRequestHeader("content-type", cntType);
		if (authObj.isSSOOn())
			oHTTP.setRequestHeader("_ssoClientType", "MSXML");	// only works in IE
		oHTTP.send(pkg);

		// on error return http object so caller can inquire on status
		if (oHTTP.status >= 400)
		{
			portalTraceResponseObj(oHTTP, url);
			return (oHTTP);
		}

		// Check for a blank server response
		if ((browser.isIE && oHTTP.responseText == "" && oHTTP.responseXML.xml == "")
		 || (oHTTP.responseText == null && oHTTP.responseXML == null))
		{
			var errorMsg = "Server response not populated";
			var errorDtl = url + "\nSSORequest() - sso.js";
			if (bShowErrors)
				alert(errorMsg + "\n\n" + errorDtl);

			// add debugging to the Portal's trace window
			portalTraceMsg(errorMsg, errorDtl);
			portalTraceResponseObj(oHTTP, url);

			if (outType == "text/xml")
				return errorObj.getErrorDom(errorMsg, errorDtl);
			else
				return errorMsg;
		}

		// Check for login page first...
		if (authObj.isSSOOn() && url != authObj.configUrl && isLoginPage(oHTTP))
		{
			portalTraceMsg("Login page returned from " + url);
			return showLoginPage(oHTTP, cntType, outType, bShowErrors);
		}

		// if content-type is undefined (not text/xml) from the middle tier app we must use responseText
		// once all middle tier apps set response header to text/xml we will be able to use responseXML solely
		try
		{
			conType = oHTTP.getResponseHeader("content-type");
			// PT #137060 - handle content type of 'text/xml; Charset=IS0-8859-1'
			var idx = conType.indexOf(";");
			if (idx != -1)
				conType = conType.substring(0,idx);
		}
		catch (e)
		{
			conType = null;
		}

		switch (conType)
		{
			case "text/xml":
			{
				if (authObj.isSSOOn() && url != authObj.configUrl && isTimeout(oHTTP.responseXML))
					return handleTimeout(oHTTP, cntType, outType, bShowErrors);
				oResponse = oHTTP.responseXML;
				break;
			}
			case "text/html":
			case "text/plain":
			case "text/javascript":	// used to get javascript files
			default:
			{
				if (outType == "text/xml")
					oResponse = objFactory.getDomFromString(oHTTP.responseText);
				else
					oResponse = oHTTP.responseText;
				break;
			}
			/*
			default:
			{
				var errorMsg = "Invalid content type " + conType + ".\nValid content types are text/xml, text/html, text/plain, or text/javascript.";
				var errorDtl = url + "\nSSORequest() - sso.js";
				if (bShowErrors)
					alert(errorMsg + "\n\n" + errorDtl);

				if (outType == "text/xml")
					return errorObj.getErrorDom(errorMsg, errorDtl);
				else
					return errorMsg;
			}
			*/
		}

		if (conType == "text/xml" || outType == "text/xml")
		{
			// check for valid DOM
			if (!oResponse.documentElement)
			{
				var errorMsg = "Invalid XML - Root node does not exist";
				var errorDtl = url + "\nSSORequest() - sso.js";
				if (bShowErrors)
					alert(errorMsg + "\n\n" + errorDtl);

				// add debugging to the Portal's trace window
				portalTraceMsg(errorMsg, errorDtl);
				portalTraceResponseObj(oHTTP, url, conType);

				return errorObj.getErrorDom(errorMsg, errorDtl);
			}

			// check for Netscape parse error, wrap in standard error format
			if (browser.isNS && oResponse.documentElement.nodeName == "parsererror")
			{
				var errorMsg = "Invalid XML";
				var errorDtl = url + "\nSSORequest() - sso.js";
				if (oResponse.documentElement.firstChild)
					errorDtl = oResponse.documentElement.firstChild.nodeValue;
				oResponse = errorObj.getErrorDom(errorMsg, errorDtl);
			}

			// check for standard error
			if (oResponse.documentElement.nodeName == "ERROR")
			{
				if (bShowErrors)
				{
					var details = oResponse.documentElement.firstChild.nextSibling.firstChild.nodeValue;
					if (details.length > 1024)
						details = details.substring(0, 1024) + "...";
					var msg = oResponse.documentElement.firstChild.firstChild.nodeValue
							+ "\n\n" + url + "  -  SSORequest() - sso.js"
							+ "\n\n" + details;
					alert(msg);
				}
				// add debugging to the Portal's trace window
				portalTraceMsg("Root node of returned XML document is ERROR.");
				return oResponse;
			}
		}

		return oResponse;
	}
	catch (e)
	{
		var errorMsg = "Error calling " + url;
		var errorDtl = errorObj.getExceptionMsg(e) + "\n\nSSORequest() - sso.js";
		if (bShowErrors)
			alert(errorMsg + "\n\n" + errorDtl);

		// add debugging to the Portal's trace window
		portalTraceMsg(errorMsg, errorDtl);
		portalTraceResponseObj(oHTTP, url, conType);

		return errorObj.getErrorDom(errorMsg, errorDtl);
	}
}

//-----------------------------------------------------------------------------
function isPortalTraceOn()
{
	var wnd = (ssoFileInstance) ? ssoFileInstance : self;
	return ((!wnd || typeof(wnd.lawTrace) != "object") ? false : true);
}

//-----------------------------------------------------------------------------
function portalTraceMsg(msgStr, dataStr)
{
	if (!isPortalTraceOn())
		return;

	// add debugging to the Portal's trace window
	var wnd = (ssoFileInstance) ? ssoFileInstance : self;
	var d = new Date();
	var dateStr = d.getHours() + ":" + d.getMinutes() + ":" + d.getSeconds() + ":" + d.getMilliseconds();
	wnd.lawTrace.dump("SSO (" + dateStr + ") : " + msgStr, dataStr);
}

//-----------------------------------------------------------------------------
function portalTraceResponseObj(oHTTP, urlStr, conType)
{
	if (!isPortalTraceOn())
		return;

	// add debugging to the Portal's trace window
	urlStr = (typeof(urlStr) == "undefined") ? "" : urlStr;
	conType = (typeof(conType) == "undefined") ? "" : conType;
	try
	{
		var dataStr = "Status = " + oHTTP.status + "\n"
					+ "Status Text = " + oHTTP.statusText + "\n"
					+ "Content Type = " + conType + "\n"
					+ "Response Text = \n\n" + oHTTP.responseText;
		if (conType == "text/xml" && browser.isIE)
			dataStr += "\n\nResponse XML = \n\n" + oHTTP.responseXML.xml;
		portalTraceMsg("Response Object from " + url, dataStr);
	}
	catch (e)
	{
		portalTraceMsg("Response Object Error", urlStr + "\n\nError thrown while trying to retrieve data from response object.");
	}
}

//-----------------------------------------------------------------------------
function getResponseText(res)
{
	return (typeof(res.responseText) == "function") ? res.responseText() : res.responseText ;
}

//-----------------------------------------------------------------------------
function isLoginPage(res)
{
	var authObj = new SSOAuthObject();
	if (!authObj.isSSOOn())
		return false;

	var resTxt = getResponseText(res);
	var tmpAry = authObj.getConfigArray();
	// no criteria to check for a login page
	if (tmpAry.length == 0)
		return false;
	for (var i in tmpAry)
		if (i.toLowerCase() != "authen_type" && resTxt.indexOf(tmpAry[i]) == -1)
			return false;
	return true;
}

//-----------------------------------------------------------------------------
function isTimeout(xmlDoc)
{
	var authObj = new SSOAuthObject();
	if (!authObj.isSSOOn())
		return false;

	// check for SSO directions
	var ssoNodes = xmlDoc.getElementsByTagName("SSO");
	if (ssoNodes.length > 0)
	{
		var statusNodes = ssoNodes[0].getElementsByTagName("SSO_STATUS");
		var redirectNodes = ssoNodes[0].getElementsByTagName("SSO_REDIRECTURL");
		if (statusNodes.length > 0 && redirectNodes.length > 0)
			return true;
	}
	return false;
}

//-----------------------------------------------------------------------------
function showLoginPage(res, cntType, outType, bShowErrors)
{
	var authObj = new SSOAuthObject();
	if (!authObj.isSSOOn())
		return null;

	var browser = new SSOBrowser();
	if (browser.isNS)
	{
		window.location.replace(authObj.getPrimaryUrl() + "?" + authObj.configAry["origurl_field_name"] + "=" + escape(document.location));
		return;
	}

	// default the values
	cntType = (typeof(cntType) == "undefined") ? null : cntType ;
	outType = (typeof(outType) == "undefined") ? null : outType ;
	bShowErrors = (typeof(bShowErrors) == "undefined") ? true : bShowErrors ;

	if (showModal(null, getResponseText(res)) && authObj.modalPageRet != null)
	{
		var tmpUrl = authObj.modalPageRet;
		authObj.modalPageRet = null;
		return SSORequest(tmpUrl, null, cntType, outType, bShowErrors);
	}
	else
		return null;
}

//-----------------------------------------------------------------------------
function handleTimeout(res, cntType, outType, bShowErrors)
{
	var authObj = new SSOAuthObject();
	if (!authObj.isSSOOn())
		return null;

	// default the values
	cntType = (typeof(cntType) == "undefined") ? null : cntType ;
	outType = (typeof(outType) == "undefined") ? null : outType ;
	bShowErrors = (typeof(bShowErrors) == "undefined") ? true : bShowErrors ;

	var browser = new SSOBrowser();
	var xmlDoc = res.responseXML;
	var ssoStatusNodes = xmlDoc.getElementsByTagName("SSO_STATUS");
	if (ssoStatusNodes.length > 0 && ssoStatusNodes[0].firstChild)
	{
		var ssoStatus = ssoStatusNodes[0].firstChild.nodeValue;
		switch (ssoStatus)
		{
			case "Redirecting":
			{
				var ssoRedirectNodes = xmlDoc.getElementsByTagName("SSO_REDIRECTURL");
				if (ssoRedirectNodes.length > 0 && ssoRedirectNodes[0].firstChild)
				{
					var rUrl = new URLObject(ssoRedirectNodes[0].firstChild.nodeValue);
					// only use SSORequest() here if it is same protocol and same host!
					if (rUrl.isSameHost() && rUrl.isSameProtocol())
						return SSORequest(rUrl.url, null, cntType, outType, bShowErrors);
					else
					{
						var toUrl = rUrl.url;
						var origUrl = null;
						var qIdx = toUrl.indexOf("?");
						var prmsAry = toUrl.substring(qIdx+1).split("&");
						toUrl = toUrl.substring(0, qIdx+1);
						for (var i=0; i<prmsAry.length; i++)
						{
							if (prmsAry[i].indexOf("_ssoOrigUrl=") == 0)
							{
								var tmpAry = prmsAry[i].split("=");
								origUrl = unescape(tmpAry[1]);

								if (browser.isNS)
									prmsAry[i] = "_ssoOrigUrl=" + escape(document.location);
								else 
									prmsAry[i] = "_ssoOrigUrl=" + escape(document.location.protocol + "//" + document.location.host + "/sso/loadcomplete.htm");
							}
							toUrl += prmsAry[i] + ((i != prmsAry.length-1) ? "&" : "");
						}
					}

					if (browser.isNS)
					{
						window.location.replace(toUrl);
						return;
					}
					else
					{
						if (showModal(toUrl))
						    return SSORequest(origUrl, null, cntType, outType, bShowErrors);
						else
							return null;
					}
				}
				break;
			}
			case "Login":
			case "LoginFailed":
			case "LoginSuccessful":
			case "CheckTimeout":
			case "MigratingSession":
			case "ExceptionError":
			default:
			{	break;	}
		}
	}
}

//-----------------------------------------------------------------------------
// showModal has to accept either a url or html source string
function showModal(mUrl, mSrc)
{
	var authObj = new SSOAuthObject();
	var browser = new SSOBrowser();
	if (!authObj.isSSOOn() || browser.isNS)
		return;	// authentication is off or modal windows do not work

	if (mUrl)
		authObj.modalPageUrl = mUrl;
	else if (mSrc)
		authObj.modalPageSrc = mSrc;
	else
	{
		alert("This method must receive a URL or HTML source string\n\nshowModal(mUrl, mSrc) - sso.js");
		return;
	}

	// prepare to open modal window
	var modWidth = 570;
	var modHeight = 470;
	var modLeft = parseInt((screen.width / 2) - (modWidth / 2), 10);
	var modTop = parseInt((screen.height / 2) - (modHeight / 2), 10);
	if (browser.isIE)
		window.showModalDialog("/sso/modal.htm", new Array(window), "dialogLeft:" + modLeft + "px;dialogTop:" + modTop + "px;dialogWidth:" + modWidth + "px;dialogHeight:" + modHeight + "px;status:0;help:0");
	else
		window.open("/sso/modal.htm", "redirectWindow", "left=" + modLeft + ",top=" + modTop + ",width=" + modWidth + ",height=" + modHeight + ",modal");

	var retVal;
	var modalRetValue = authObj.modalPageRet;
	authObj.modalPageRet = null;
	switch (modalRetValue.toUpperCase())
	{
		case "REOPEN":
			if (mUrl)
				retVal = showModal(mUrl);
			else
				retVal = showModal(null, mSrc);
			break;
		case "QUIT":
			retVal = false;
			break;
		case "LOGGEDIN":
			retVal = true;
			break;
		case "LOGOUT":
			authObj.logout();
			retVal = false;
			break;
		case "TRUE":
			retVal = true;
			break;
		case "FALSE":
			retVal = false;
			break;
		default:
			authObj.modalPageRet = modalRetValue;
			retVal = true;
			break;
	}

	return retVal;
}

