Auth (authentication)

The Auth module is used to authenticate to compatible authentication system.

var
Auth                    = {}
Auth.Login              = Auth_Login;
Auth.Login.LocalStorage = Auth_Login_LocalStorage;
Auth.Logout             = Auth_Logout;
Auth.LogoutAndReload    = Auth_LogoutAndReload;

Login

Auth.Login( event )

It is assumed that the event passed to the Auth.Login function was caused by clicking the submit button of a form that includes 'username' and 'password' fields.

The values of the fields are passed as parameters to a request to the host returned from a call to 'Resolve()', e.g. https:api-example.com:8443, and the path specified as the value of the 'data-submit-url' attribute of the form, e.g. '/auth/login/. For example:

https://api-example.com:8443/auth/login/&username=$username&password=$password

It is expected that the reply will be JSON formatted with the following fields set: 'status', 'sessionid', 'idtype', 'group_code', and 'email'; and if an error has occurred, 'error'; e.g.:

{
    "status"     : "OK",
    "sessionid"  : "xxx",
    "idtype"     : "USER",
    "group_code" : "",
    "email"      : "joe@example.com"
}

The default handler will set the 'sessionid', 'idtype', and 'email' into cookies with the same names, and will call the 'Redirect()' function passing the idtype. This means that the 'sessionid' will be passed each time a call is made to the API server.

function Auth_Login( event )
{
    event.preventDefault();

	Submit( event, Auth.Login.Handler );
}
function Auth_Login_LocalStorage( event )
{
    event.preventDefault();

    Submit( event, Auth.Login.LocalStorageHandler );
}

Logout

Auth.Logout()

The Auth.Logout function is usually called when the user clicks a logout button or link. The call takes no parameters, and will delete the 'idtype', 'sessionid', and 'email' cookies, then call the '/auth/logout/' API endpoint.

function Auth_Logout( logout_api_url )
{
	Auth.UnsetIDTypeCookie();
	Auth.UnsetSessionIDTypeCookie();
	Auth.UnsetCookie( "email" );

    if ( "string" === typeof logout_api_url )
    {
        Call(  logout_api_url, new Array(), Auth.Logout.Handler );
    }
    else
    {
    	Call( "/api/auth/logout/", new Array(), Auth.Logout.Handler );
    }

    if ( DataStorage.Local.HasItem( "sessionid" ) )
    {
        var storage = DataStorage.Local;

        storage.RemoveItem( "idtype"        );
        storage.RemoveItem( "accessid"      );
        storage.RemoveItem( "email"         );
        storage.RemoveItem( "given"         );
        storage.RemoveItem( "group_code"    );
        storage.RemoveItem( "sessionid"     );
        storage.RemoveItem( "Authorization" );
    }

    UnsetCookie( "accessid" );
}

Logout and reload (page)

Auth.LogoutAndReload()

The Auth.LogoutAndReload function, as the name suggests, is identical to the Auth.Logout function except that the handler of the '/auth/logout/' call will also reload the page.

function Auth_LogoutAndReload( logout_api_url )
{
	Auth.UnsetIDTypeCookie();
	Auth.UnsetSessionIDTypeCookie();
    Auth.UnsetCookie( "accessid"   );
	Auth.UnsetCookie( "email"      );
    Auth.UnsetCookie( "group_code" );

    if ( logout_api_url )
    {
        Call(  logout_api_url, new Array(), Auth.LogoutAndReload.Handler );
    }
    else
    {
        Call( "/auth/logout/", new Array(), Auth.LogoutAndReload.Handler );
    }
}

Helper functions

Auth.Login.Handler
=
function ( responseText )
{
    var json = JSON.parse( responseText );

    if ( json.idtype )
    {
        Auth.Login.Handler.Orig( responseText );
    }
    else
    {
        Auth.Login.Handler.New( responseText );
    }
}

Auth.Login.Handler.Orig
=
function ( responseText )
{
	if ( "" != responseText )
	{
		var obj = JSON.parse( responseText );

		if ( obj && obj.idtype )
		{
			Auth.SetIDTypeCookie( obj.idtype );
			//Auth.SetSessionIDTypeCookie( obj.sessionid );
			Auth.SetCookie( "email", obj.email, 1 );
            Auth.SetCookie( "group_code", obj.group_code, 1 );

			Redirect( obj.idtype ); // External Call
		}
		else
		{
			if ( obj["error"] == "INVALID_CREDENTIALS" )
			{
				var errorText = "Invalid username or password.";
			}
			else
			{
				var errorText = "Error logging in, please try again.";
			}

			var loginErrorDiv = document.getElementById( 'login-error' );

            if ( loginErrorDiv )
            {
				loginErrorDiv.innerHTML = "";
				loginErrorDiv.innerHTML = errorText;
            }
            else
            {
                alert( errorText );
            }
		}
	}
	else
	{
		Auth.Logout();
	}
}

Auth.Login.Handler.New
=
function( responseText )
{
    if ( "" != responseText )
    {
        var json = JSON.parse( responseText );

        if ( "ERROR" == json.status )
        {
            switch ( json.error.split( " " )[0] )
            {
            case "INVALID_USER":
            case "INVALID_PASSWORD":
            case "INVALID_CREDENTIALS":
                alert( "Invalid username or password." );
                break;

            case "INVALID_LOGINS":
                alert( "Too many invalid logins have occurred. To reset your invalid login count, please reset your password." );
                break;

            default:
                alert( "An unexpected error occurred, please try again later." );
            }
        }
        else if ( json.results && (1 !== json.results.length) )
        {
            alert( "Session was not returned as expected, please try again later." );
        }
        else
        {
            var obj = json.results[0];

            if ( obj && obj.idtype )
            {
                Auth.SetCookie( "accessid", obj.accessid, 1 );

                //Auth.SetIDTypeCookie( obj.idtype );
                //Auth.SetCookie( "Authorization", "",             1 );
                //Auth.SetCookie( "email",         obj.email,      1 );
                //Auth.SetCookie( "given",         obj.given_name, 1 );
                //Auth.SetCookie( "group_code",    obj.group_code, 1 );

                var redirect_path = obj.redirect_path ? obj.redirect_path : "/";
                var redirect_url  = location.protocol + "//" + location.host + redirect_path;

                location.assign( redirect_url );
            }
        }
    }
}

Auth.Logout.Handler
=
function ( responseText )
{
	location.assign( location.protocol + "//" + location.hostname + "/" );
}

Auth.LogoutAndReload.Handler
=
function ( responseText )
{
	location.reload();
}

Auth.SetIDTypeCookie
=
function( idtype )
{
	Auth.SetCookie( "idtype", idtype, 1 );
}

Auth.SetSessionIDTypeCookie
=
function( sid )
{
	Auth.SetCookie( "sessionid", sid, 1 );
}

Auth.UnsetCookie
=
function ( cname )
{
	document.cookie = cname + "=; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/";
}

Auth.UnsetIDTypeCookie
=
function ()
{
	document.cookie = "idtype=; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/";
}

Auth.UnsetSessionIDTypeCookie
=
function ()
{
	document.cookie = "sessionid=; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/";
}

Auth.SetCookie
=
function( cname, cvalue, exdays )
{
    var d       = new Date(); d.setTime(d.getTime() + (exdays*24*60*60*1000));
    var expires = "expires="+d.toUTCString();
    var secure  = 'https:' == location.protocol ? ";secure" : "";

    document.cookie = cname + "=" + cvalue + "; " + ";path=/" + secure + ";SameSite=strict";
}
Auth.Login.LocalStorageHandler
=
function ( responseText )
{
    if ( "" != responseText )
    {
        var json = JSON.parse( responseText );

        if ( "ERROR" == json.status )
        {
            switch ( json.error.split( " " )[0] )
            {
            case "INVALID_USER":
            case "INVALID_PASSWORD":
            case "INVALID_CREDENTIALS":
                alert( "Invalid username or password." );
                break;

            case "INVALID_LOGINS":
                alert( "Too many invalid logins have occurred. To reset your invalid login count, please reset your password." );
                break;

            default:
                alert( "An unexpected error occurred, please try again later." );
            }
        }
        else if ( json.results && (1 !== json.results.length) )
        {
            alert( "Session was not returned as expected, please try again later." );
        }
        else
        {
            var obj = json.results[0];

            if ( obj && obj.idtype )
            {
                var storage = DataStorage.Local;

                storage.SetItem( "sessionid", obj.sessionid  );

                Auth.SetCookie( "accessid", obj.accessid, 1 );

                var redirect_path = obj.redirect_path ? obj.redirect_path : "/";
                var redirect_url  = location.protocol + "//" + location.host + redirect_path;

                location.assign( redirect_url );
            }
        }
    }
}