﻿var passwordRequirementTypes = { Moderate : 0, Strong : 1, Stronger : 2 }; //Javascript Enumeration of Password Strenght Types.

function testAlphaNumeric(password, enforceMixedCase)
{
    if(!enforceMixedCase)
    {
        if(!testLowerCase(password) && !testUpperCase(password))
            return false;
    }
    else
    {
        if(!testLowerCase(password) || !testUpperCase(password))
            return false;
    }
    if (enforceNumeric)
    {
        if(!testNumeric(password))
            return false;
    }
    return true;
}

function testAlphaNumeric(password, enforceMixedCase, enforceNumeric)
{
    if(!enforceMixedCase)
    {
        if(!testLowerCase(password) && !testUpperCase(password))
            return false;
    }
    else
    {
        if(!testLowerCase(password) || !testUpperCase(password))
            return false;
    }
    if (enforceNumeric)
    {
        if(!testNumeric(password))
            return false;
    }
    return true;
}

function testAlpha(password)
{
    if(testLowerCase(password) || testUpperCase(password))
    {
        return true;
    }
    else
    {
        return false;
    }
}
function testMixedCase(password)
{
    if(testLowerCase(password) && testUpperCase(password))
    {
        return true;
    }
    else
    {
        return false;
    }
}
function testUpperCase(password)
{
    return /(?=.*[A-Z]+?)/.test(password);
}

function testLowerCase(password)
{
    return /(?=.*[a-z]+?)/.test(password);
}

function testNumeric(password)
{
    return /(?=.*\d+?)/.test(password);
}

function testSpecialCharacters(password)
{
    return /(?=.*[ !~@#_\-\^\$\)\(\*\+\}\{\.\&‘,\/:;<=>\?\[\]`\|]+?)/.test(password);
}

function testLengthMinimum(password, minLength)
{
    if(password.length >= minLength)
        return true;
        
    return false;
}

function testLengthMaximum(password, maxLength)
{
    if(password.length <= maxLength)
        return true;
        
    return false;
}   

//Constructor
function PasswordTest(passwordRequirementType)
{
    this.SetStrength(passwordRequirementType);
}

PasswordTest.prototype.FailedMessage = "";
PasswordTest.prototype.Passed = true;
PasswordTest.prototype.MinLength = 6;
PasswordTest.prototype.MaxLength = 25;
PasswordTest.prototype.EnforceMixedCase = false;
PasswordTest.prototype.EnforceSpecialCharacters = false;
PasswordTest.prototype.EnforceNumeric = true;
PasswordTest.prototype.Test = testPass;
PasswordTest.prototype.SetStrength = setStrength;
PasswordTest.prototype.TestAlphaNumeric = testAlphaNumeric;
PasswordTest.prototype.TestNumeric = testNumeric;
PasswordTest.prototype.TestSpecialCharacters = testSpecialCharacters;
PasswordTest.prototype.TestLengthMinimum = testLengthMinimum;
PasswordTest.prototype.TestLengthMaximum = testLengthMaximum;
PasswordTest.prototype.TestAlpha = testAlpha;
PasswordTest.prototype.TestMixedCase = testMixedCase;


function setStrength(passwordRequirementType)
{
    switch(passwordRequirementType)
    {
        case passwordRequirementTypes.Moderate: //Moderate
            this.MinLength = 6;
            this.MaxLength = 25;
            this.EnforceMixedCase = false;
            this.EnforceSpecialCharacters = false;
            break;
        default:
            this.MinLength = 8;
            this.MaxLength = 25;
            this.EnforceMixedCase = false;
            this.EnforceSpecialCharacters = true;
            break;
        case passwordRequirementTypes.Stronger:
            this.MinLength = 8;
            this.MaxLength = 25;
            this.EnforceMixedCase = true;
            this.EnforceSpecialCharacters = true;
            break;
    }
}

function testPass(password)
{
    if(!testLengthMinimum(password, this.MinLength))
    {
        this.Passed = false;
        this.FailedMessage += "\tPassword must be at least " + this.MinLength + " characters long.\n";
    }
    
    if(!testLengthMaximum(password, this.MaxLength))
    {
        this.Passed = false;
        this.FailedMessage += "\tPassword must not be more than " + this.MinLength + " characters long.\n";
    }
    
    if(!this.EnforceMixedCase)
    {
        if(!testAlphaNumeric(password, false, this.EnforceNumeric))
        {
            this.Passed = false;
            this.FailedMessage += "\tPassword must contain at least one letter and one number.\n";
        }
    }
    else
    {
        if(!testAlphaNumeric(password, true, this.EnforceNumeric))
        {
            this.Passed = false;
            this.FailedMessage += "\tPassword must contain at least one lower case letter, one upper case letter, and one number.\n";
        }
    }
    
    if(this.EnforceSpecialCharacters)
    {
        if(!testSpecialCharacters(password))
        {
            this.Passed = false;
            this.FailedMessage += "\tPassword must contain at least one special character.\n";
        }
    }
	
	return this.Passed;
}

function checkPassword(min, max, enforceMixedCase, enforceSpecialChars, password)
{
    var passwordTest = new PasswordTest(1);
    passwordTest.MinLength = min;
    passwordTest.MaxLength = max;
    passwordTest.EnforceMixedCase = enforceMixedCase;
    passwordTest.EnforceSpecialCharacters = enforceSpecialChars;
    
    passwordTest.Test(password);
    if(!passwordTest.Passed)
        alert(passwordTest.FailedMessage);
        
    return passwordTest.Passed;
}

function checkPassword(min, max, enforceMixedCase, enforceSpecialChars, enforceNumeric, password)
{
    var passwordTest = new PasswordTest(1);
    passwordTest.MinLength = min;
    passwordTest.MaxLength = max;
    passwordTest.EnforceMixedCase = enforceMixedCase;
    passwordTest.EnforceSpecialCharacters = enforceSpecialChars;
    passwordTest.EnforceNumeric = enforceNumeric
    passwordTest.Test(password);
    if(!passwordTest.Passed)
        alert(passwordTest.FailedMessage);
        
    return passwordTest.Passed;
}
