Page 1 of 1

Login in Popup

Posted: Mon Oct 18, 2010 1:07 pm
by dappy2
I know there are various modal popups in the forums using both a javascript framework (contact) and the modal popup (product send). Ablecommerce.com even uses the modal popup on their homepage for login.

I'm trying to have modal popups with Javascript (jquery/fancybox) specifically on the onepagecheckout. I don't want people leaving the page if they are required to login.

Has anyone successfully implemented something like that? I've got the login links on onepagecheckout loading the LoginDialog.ascx file through a LoginBox.aspx page and it works - sort of. I've attempted to put in some code to check if a property I created - isPopup == true to perform some code instead of the default Able redirects. This is where everything stops working. If I popup the login dialog, login with my admin username. It seems to work, then if I manually close the popup, the Checkout/Default.aspx reloads (as it should) and takes me to my basket saying it is empty and I'm also not logged in. The basket is migrated to the user (I checked in a different browser that was logged in) but the login doesn't seem to be preserved. The popup loads in an iframe.

Any thoughts? Is this just way beyond something I should be attempting?

Thanks - Dappy

This is the logindialog code behind:

Code: Select all

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Collections.Generic;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using CommerceBuilder.Common;
using CommerceBuilder.Users;
using CommerceBuilder.Utility;

public partial class ConLib_LoginDialog : System.Web.UI.UserControl
{
    private string _LastPasswordValue = string.Empty;

    private bool _isPopUp = false;
     public bool isPopUp
     {
          get { return _isPopUp; }
          set { _isPopUp = value;}
     }

    private bool _EnableAdminRememberMe = true;
    public bool EnableAdminRememberMe
    {
        get { return _EnableAdminRememberMe; }
        set { _EnableAdminRememberMe = value; }
    }

    protected void Page_Init(object sender, EventArgs e)
    {
        LoadCustomViewState();
    }

    private void LoadCustomViewState()
    {
        if (Page.IsPostBack)
        {
            string vsContent = Request.Form[VS.UniqueID];
            string decodedContent = EncryptionHelper.DecryptAES(vsContent);
            UrlEncodedDictionary customViewState = new UrlEncodedDictionary(decodedContent);
            _LastPasswordValue = customViewState.TryGetValue("P");
        }
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        InstructionText.Text = string.Format(InstructionText.Text, Token.Instance.Store.Name);
        if (!Page.IsPostBack)
        {
            HttpCookie usernameCookie = Request.Cookies["UserName"];
            if ((usernameCookie != null) && !string.IsNullOrEmpty(usernameCookie.Value))
            {
                UserName.Text = usernameCookie.Value;
                RememberUserName.Checked = true;
                Password.Focus();
            }
            else
            {
                UserName.Focus();
            }
            PasswordExpiredPanel.Visible = false;
            ForgotPasswordPanel.Visible = false;
            EmailSentPanel.Visible = false;
            CustomerPasswordPolicy policy = new CustomerPasswordPolicy();
            trCaptchaField.Visible = policy.ImageCaptcha;
            trCaptchaImage.Visible = policy.ImageCaptcha;
        }

        PageHelper.ConvertEnterToTab(UserName);
        // SET DEFALUT BUTTONS FOR INPUT FIELDS
        if (trCaptchaImage.Visible)
        {
            PageHelper.ConvertEnterToTab(Password);
            WebControl inputControl = CaptchaImage.FindControl("CaptchaInput") as WebControl;
            if (inputControl != null) PageHelper.SetDefaultButton(inputControl, LoginButton.ClientID);
        }
        else
        {
            PageHelper.SetDefaultButton(Password, LoginButton.ClientID);
        }
    }

    protected void LoginButton_Click(object sender, EventArgs e)
    {
        _LastPasswordValue = Password.Text;
        User loginUser = UserDataSource.LoadForUserName(UserName.Text);
        if (loginUser != null)
        {
            bool stillNeedsCaptcha = false;
            if ((loginUser.IsAdmin) && (!trCaptchaField.Visible))
            {
                stillNeedsCaptcha = (new MerchantPasswordPolicy()).ImageCaptcha;
            }
            if (!stillNeedsCaptcha)
            {
                //EITHER THIS IS NOT AN ADMIN USER, OR THE CAPTCHA IS ALREADY VISIBLE
                if ((!trCaptchaField.Visible) || (CaptchaImage.Authenticate(CaptchaInput.Text)))
                {
                    //CAPTCHA IS HIDDEN OR VALIDATED, PROCEED WITH LOGIN ATTEMPT
                    if (User.Login(UserName.Text, Password.Text))
                    {
                        //LOGIN SUCCEEDED, MIGRATE USER IF NEEDED
                        int newUserId = loginUser.UserId;
                        int oldUserId = Token.Instance.UserId;
                        if ((oldUserId != newUserId) && (newUserId != 0))
                        {
                            User.Migrate(Token.Instance.User, UserDataSource.Load(newUserId));
                            Token.Instance.UserId = newUserId;
                        }
                        //HANDLE LOGIN PROCESSING
                        if (trRememberMe.Visible && RememberUserName.Checked)
                        {
                            HttpCookie cookie = new HttpCookie("UserName", UserName.Text);
                            cookie.Expires = DateTime.MaxValue;
                            Response.Cookies.Add(cookie);
                        }
                        else
                        {
                            Response.Cookies.Add(new HttpCookie("UserName", ""));
                        }
                        //CHECK FOR EXPIRED PASSWORDS
                        PasswordPolicy policy;
                        if (loginUser.IsAdmin) policy = new MerchantPasswordPolicy();
                        else policy = new CustomerPasswordPolicy();
                        if (policy.IsPasswordExpired(loginUser))
                        {
                            ShowPasswordExpired(policy, loginUser);
                        }
                        else
                        {
                            //REDIRECT TO THE STANDARD PAGE
                             if (_isPopUp == false) FormsAuthentication.RedirectFromLoginPage(UserName.Text, false);
                             // DAPPY MOD IF TRUE ADD JS TO CLOSE THE PAGE
                             if (_isPopUp == true)
                                  {
                                       string closeFancy = "function pageLoad() {$(document).ready(function(){$(\".iframe-close\").trigger('click');});};";
                                       ScriptManager.RegisterClientScriptBlock(base.Page, this.GetType(), "fancybox", closeFancy, true);
                                  }
                        }
                    }
                    else
                    {
                        if (loginUser != null)
                        {
                            if (!loginUser.IsApproved)
                            {
                                AccountDisabled.IsValid = false;
                            }
                            else
                            {
                                PasswordPolicy policy;
                                if (loginUser.IsAdmin) policy = new MerchantPasswordPolicy();
                                else policy = new CustomerPasswordPolicy();
                                int remainingTries = policy.MaxAttempts - loginUser.FailedPasswordAttemptCount;
                                if (!loginUser.IsLockedOut && remainingTries > 0)
                                {
                                    InvalidLogin.ErrorMessage += " You have {0} tries remaining.";
                                    InvalidLogin.ErrorMessage = String.Format(InvalidLogin.ErrorMessage, remainingTries);
                                    InvalidLogin.IsValid = false;
                                }
                                else
                                {
                                    AccountLocked.ErrorMessage = String.Format(AccountLocked.ErrorMessage, policy.LockoutPeriod);
                                    AccountLocked.IsValid = false;
                                }
                            }
                        }
                        else
                        {
                            InvalidLogin.IsValid = false;
                        }
                    }
                }
                else
                {
                    //CAPTCHA IS VISIBLE AND DID NOT AUTHENTICATE
                    CustomValidator invalidInput = new CustomValidator();
                    invalidInput.ValidationGroup = "Login";
                    invalidInput.Text = "Required";
                    invalidInput.CssClass = "validator";
                    invalidInput.ErrorMessage = "You did not input the verification number correctly.";
                    invalidInput.IsValid = false;
                    phCaptchaValidators.Controls.Add(invalidInput);
                    CaptchaInput.Text = "";
                    Password.Attributes.Add("value", string.Empty);
                    RefreshCaptcha();
                }
            }
            else
            {
                //THIS IS AN ADMIN USER AND CAPTCHA IS NOT DISPLAYED YET
                trCaptchaField.Visible = true;
                trCaptchaImage.Visible = true;
                trRememberMe.Visible = _EnableAdminRememberMe;
                CaptchaImage.ChallengeText = StringHelper.RandomNumber(6);
                CustomValidator needsCaptcha = new CustomValidator();
                needsCaptcha.ValidationGroup = "Login";
                needsCaptcha.Text = "Required";
                needsCaptcha.CssClass = "validator";
                needsCaptcha.ErrorMessage = "Please type the verification number to log in.";
                needsCaptcha.IsValid = false;
                phCaptchaValidators.Controls.Add(needsCaptcha);
                Password.Attributes.Add("value", Password.Text);
            }
        }
        else
        {
            //THIS IS AN INVALID USER NAME
            InvalidLogin.IsValid = false;
        }
    }

    private void ShowPasswordExpired(PasswordPolicy policy, User user)
    {
        LoginPanel.Visible = false;
        PasswordExpiredPanel.Visible = true;
        List<string> requirements = new List<string>();
        PasswordPolicyLength.Text = string.Format(PasswordPolicyLength.Text, policy.MinLength);
        ppHistoryCount.Visible = (policy.HistoryCount > 0);
        if (ppHistoryCount.Visible) PasswordPolicyHistoryCount.Text = string.Format(PasswordPolicyHistoryCount.Text, policy.HistoryCount);
        ppHistoryDays.Visible = (policy.HistoryDays > 0);
        if (ppHistoryDays.Visible) PasswordPolicyHistoryDays.Text = string.Format(PasswordPolicyHistoryDays.Text, policy.HistoryDays);
        if (policy.RequireUpper) requirements.Add("uppercase letter");
        if (policy.RequireLower) requirements.Add("lowercase letter");
        if (policy.RequireNumber) requirements.Add("number");
        if (policy.RequireSymbol) requirements.Add("symbol");
        if (!policy.RequireNumber && !policy.RequireSymbol && policy.RequireNonAlpha) requirements.Add("non-letter");
        
        ppPolicyRequired.Visible = (requirements.Count > 0);
        if (ppPolicyRequired.Visible)
        {
            if (requirements.Count > 1) requirements[requirements.Count - 1] = "and " + requirements[requirements.Count - 1];
            PasswordPolicyRequired.Text = string.Format(PasswordPolicyRequired.Text, string.Join(", ", requirements.ToArray()));
        }
    }

    protected void ForgotPasswordButton_Click(object sender, EventArgs e)
    {
        LoginPanel.Visible = false;
        ForgotPasswordPanel.Visible = true;
        ForgotPasswordUserName.Text = UserName.Text;
    }

    protected void ForgotPasswordCancelButton_Click(object sender, EventArgs e)
    {
        LoginPanel.Visible = true;
        ForgotPasswordPanel.Visible = false;
    }

    protected void ForgotPasswordNextButton_Click(object sender, EventArgs e)
    {
        if (Page.IsValid)
        {
            User user = null;
            UserCollection users = UserDataSource.LoadForEmail(ForgotPasswordUserName.Text);
            if (users.Count != 0) user = users[0];
            if (user != null && user.IsApproved)
            {
                user.GeneratePasswordRequest();
                ForgotPasswordPanel.Visible = false;
                EmailSentPanel.Visible = true;
                EmailSentHelpText.Text = string.Format(EmailSentHelpText.Text, user.Email);
            }
            else
            {
                if ((user != null) && (!user.IsApproved)) DisabledUsernameValidator.IsValid = false;
                else ForgotPasswordUserNameValidator.IsValid = false;
            }
        }
    }

    protected void KeepShoppingButton_Click(object sender, EventArgs e)
    {
         // DAPPY MOD
        if (_isPopUp == false) Response.Redirect(NavigationHelper.GetLastShoppingUrl());
        if (_isPopUp == true)
        {
             string closeFancy = "function pageLoad() {$(document).ready(function(){$(\".iframe-close\").trigger('click');});};";
             ScriptManager.RegisterClientScriptBlock(base.Page, this.GetType(), "fancybox", closeFancy, true);
        }
    }

    protected void ChangePasswordButton_Click(object sender, EventArgs e)
    {
        if (Page.IsValid)
        {
            //VERIFY THE GIVEN USERNAME IS VALID
            User user = UserDataSource.LoadForUserName(UserName.Text);
            if ((user != null) && !string.IsNullOrEmpty(UserName.Text) && !string.IsNullOrEmpty(_LastPasswordValue))
            {
                //VERIFY CURRENT PASSWORD IS CORRECT
                if (User.Login(UserName.Text, _LastPasswordValue))
                {
                    //VERIFY THE NEW PASSWORD MEETS POLICY
                    PasswordPolicy policy;
                    if (user.IsAdmin) policy = new MerchantPasswordPolicy();
                    else policy = new CustomerPasswordPolicy();
                    PasswordTestResult result = policy.TestPasswordWithFeedback(user, NewPassword.Text);
                    if ((result & PasswordTestResult.Success) == PasswordTestResult.Success && !NewPassword.Text.Equals(_LastPasswordValue))
                    {
                        user.SetPassword(NewPassword.Text);
                        //LOGIN SUCCEEDED, REDIRECT
                        // DAPPY MODE
                        if (_isPopUp == false) FormsAuthentication.RedirectFromLoginPage(UserName.Text, false);
                        if (_isPopUp == true)
                        {
                             string closeFancy = "function pageLoad() {$(document).ready(function(){$(\".iframe-close\").trigger('click');});};";
                             // Response.Redirect("~/Login.aspx?ReturnUrl=" + Server.UrlEncode(Request.Url.AbsolutePath));
                             ScriptManager.RegisterClientScriptBlock(base.Page, this.GetType(), "fancybox", closeFancy, true);
                        }
                    }
                    else
                    {
                        //REDISPLAY THE PASSWORD REQUIREMENST
                        ShowPasswordExpired(policy, user);

                        //"Your new password did not meet the following minimum requirements:<br>";
                        if ((result & PasswordTestResult.PasswordTooShort) == PasswordTestResult.PasswordTooShort) AddPasswordExpiredValidator(string.Format(PasswordPolicyLength.Text, policy.MinLength));
                        if ((result & PasswordTestResult.RequireLower) == PasswordTestResult.RequireLower) AddPasswordExpiredValidator("New password must contain at least one lowercase letter.<br>");
                        if ((result & PasswordTestResult.RequireUpper) == PasswordTestResult.RequireUpper) AddPasswordExpiredValidator("New password must contain at least one uppercase letter.<br> ");
                        if ((result & PasswordTestResult.RequireNonAlpha) == PasswordTestResult.RequireNonAlpha) AddPasswordExpiredValidator("New password must contain at least one non-letter.<br> ");
                        if ((result & PasswordTestResult.RequireNumber) == PasswordTestResult.RequireNumber) AddPasswordExpiredValidator("New password must contain at least one number.<br> ");
                        if ((result & PasswordTestResult.RequireSymbol) == PasswordTestResult.RequireSymbol) AddPasswordExpiredValidator("New password must contain at least one symbol.<br> ");

                        if ((result & PasswordTestResult.PasswordHistoryLimitation) == PasswordTestResult.PasswordHistoryLimitation)
                        {
                            AddPasswordExpiredValidator("You have recently used this password.<br/>");
                        }
                        if (NewPassword.Text.Equals(_LastPasswordValue))
                        {
                            AddPasswordExpiredValidator("You new password must be different from your current password.<br/>");
                        }
                    }
                }
            }
        }
    }

    private void AddPasswordExpiredValidator(String message)
    {
        CustomValidator validator = new CustomValidator();
        validator.ValidationGroup = "PasswordExpired";
        validator.ErrorMessage = message;
        validator.Text = "*";
        validator.IsValid = false;
        phNewPasswordValidators.Controls.Add(validator);
    }

    private void RefreshCaptcha()
    {
        CaptchaImage.ChallengeText = StringHelper.RandomNumber(6);
    }

    protected void ChangeImageLink_Click(object sender, EventArgs e)
    {
        RefreshCaptcha();
        Password.Attributes.Add("value", Password.Text);
    }

    protected void Page_PreRender(object sender, EventArgs e)
    {
        SaveCustomViewState();
    }

    private void SaveCustomViewState()
    {
        UrlEncodedDictionary customViewState = new UrlEncodedDictionary();
        customViewState["P"] = _LastPasswordValue;
        VS.Value = EncryptionHelper.EncryptAES(customViewState.ToString());
    }
}

Re: Login in Popup

Posted: Mon Oct 18, 2010 4:41 pm
by jmestep
A page like the one page checkout is hard to put jquery or javascript on because of the post backs that make it lose it's value. We have had to write it from the code behind, like Able does in places. If you search the pages for "RegisterStartupScript", you can find some examples . I can't remember OTMH where it is used.

Re: Login in Popup

Posted: Tue Oct 19, 2010 2:44 am
by plugables
We have written an Ajax PopUp Login Control that works on the OnePageCheckout. See it in action on our site http://www.plugables.com

Re: Login in Popup

Posted: Tue Oct 19, 2010 4:50 am
by mazhar
If you want to keep the things simple see following thread viewtopic.php?f=47&t=9983
Here I mentioned how to use greybox for popup. You can simply create a separate page having login control only and then open it in greybox popup on checkout page.

Re: Login in Popup

Posted: Tue Oct 19, 2010 8:13 am
by dappy2
jmestep wrote: If you search the pages for "RegisterStartupScript", you can find some examples . I can't remember OTMH where it is used.
I was using that but for some reason I don't know - I wasn't using startupscript - I was using RegisterClientScriptBlock. StartupScript fixed one issue - after a successful login, the modal popup will close.
mazhar wrote:If you want to keep the things simple see following thread viewtopic.php?f=47&t=9983
Here I mentioned how to use greybox for popup. You can simply create a separate page having login control only and then open it in greybox popup on checkout page.
This is exactly what I started from and exactly how I built the the page - LoginBox.aspx. I just modified it to use the jquery fancybox instead - I also have a contact form that loads the same way and works great.

The problem I'm having is - when the checkout page reloads the user still isn't logged in even though the basket is migrated to the logged user. I'm calling window.location.reload() in javascript when the modal popup closes. I'm guessing something with the cookies or viewstate isn't updated - any thoughts?

Re: Login in Popup

Posted: Wed Oct 20, 2010 3:45 am
by jmestep
You might have to play with a setting like this- I remember I've had to do it at times.
//LOGIN SUCCEEDED, REDIRECT
FormsAuthentication.RedirectFromLoginPage(UserName.Text, false);

Here is what a sample of what Able does on the Admin/users/Default page. You could also look at the add user popup in the admin.
You might need to reload the new user also.

Code: Select all

   protected void UserGrid_RowCommand(object sender, GridViewCommandEventArgs e)
    {
        if (e.CommandName == "Login")
        {
            int newUserId = AlwaysConvert.ToInt(e.CommandArgument);
            User user = UserDataSource.Load(newUserId);
            if ((user != null) && (user.UserId != Token.Instance.UserId) && (!user.IsAdmin))
            {
                //LOGIN AS USER AND SEND TO THE STORE HOME PAGE
                FormsAuthentication.SetAuthCookie(user.UserName, false);
                Response.Redirect(NavigationHelper.GetHomeUrl());
            }
        }
    }

Re: Login in Popup

Posted: Wed Oct 20, 2010 7:51 am
by dappy2
jmestep wrote:You might have to play with a setting like this- I remember I've had to do it at times.
FormsAuthentication.SetAuthCookie(user.UserName, false);
Response.Redirect(NavigationHelper.GetHomeUrl());

Thank you!! That's what the issue was. I wasn't authorizing the user after login when it was in a popup. I also switched my Javascript to go to the checkout URL instead of just reloading the page since that's what Able was doing with the Response.Redirect - it seemed to help with the checkout process.

Thanks again!!

Dappy