public async Task <ActionResult> SendVerifyEmail(string email)
        {
            if (string.IsNullOrEmpty(email))
            {
                return(RedirectToAction("send-verify-email", "ost-account", new { success = false, status = "Email cannot be set to null or empty." }));
            }

            var username = Membership.GetUserNameByEmail(email);

            if (string.IsNullOrWhiteSpace(username))
            {
                return(RedirectToAction("send-verify-email", "ost-account", new { success = false, status = $"Cannot find any user with email {email}" }));
            }

            var emailModel = new OstCreateEmailModel
            {
                UserEmail    = email,
                UserName     = username,
                EmailSubject = "Verify your email address",
                EmailBody    = $"To finish setting up this {ConfigurationManager.ApplicationFullName} account, we just need to make sure this email address is yours."
            };

            await SendVerificationEmail(emailModel);

            return(RedirectToAction("success", "ost-account", new { success = true, status = "OK", operation = "send-verify-email" }));
        }
        public async Task <ActionResult> ForgotPassword(string email)
        {
            if (string.IsNullOrEmpty(email))
            {
                return(RedirectToAction("forgot-password", "ost-account", new { success = false, status = "Email cannot be set to null or empty." }));
            }

            var username = Membership.GetUserNameByEmail(email);

            if (string.IsNullOrWhiteSpace(username))
            {
                return(RedirectToAction("forgot-password", "ost-account", new { success = false, status = $"Cannot find any user with email {email}" }));
            }

            var emailModel = new OstCreateEmailModel
            {
                UserEmail    = email,
                UserName     = username,
                EmailSubject = "Forgot your password",
                EmailBody    = $"You're receiving this e-mail because you requested a password reset for your user account at {ConfigurationManager.ApplicationFullName}.",
            };

            await SendForgotPasswordEmail(emailModel);

            return(RedirectToAction("success", "ost-account", new { success = true, status = "OK", operation = "forgot-password" }));
        }
        public async Task <ActionResult> RegisterEst(string email)
        {
            if (string.IsNullOrEmpty(email))
            {
                return(RedirectToAction("register-est", "ost-account", new { success = false, status = "Email cannot be set to null or empty." }));
            }

            //TODO: Check with SnB if email existed proceed to first time login
            //if (true)
            //{
            //    //return RedirectToAction("register-est", "ost-account", new { success = false, status = $"Your email address {email} already existed. You may proceed to first time login." });
            //}

            var emailModel = new OstCreateEmailModel
            {
                UserEmail    = email,
                UserName     = email,
                EmailSubject = "New Pos Laju Business Customer Registration",
                EmailBody    = $"You're only one step away from becoming a Pos Laju Business Customer user at {ConfigurationManager.ApplicationFullName}. Just click on the following link to complete our online registration form and you`re almost there!"
            };

            await SendEstRegistrationEmail(emailModel);

            return(RedirectToAction("success", "ost-account", new { success = true, status = "OK", operation = "register-est" }));
        }
        public async Task <ActionResult> Register(OstRegisterModel model)
        {
            if (string.IsNullOrEmpty(model.UserName))
            {
                return(RedirectToAction("register", "ost-account", new { success = false, status = "Username cannot be set to null or empty." }));
            }
            if (string.IsNullOrEmpty(model.Designation))
            {
                return(RedirectToAction("register", "ost-account", new { success = false, status = "Designation cannot be set to null or empty." }));
            }
            if (string.IsNullOrEmpty(model.Password))
            {
                return(RedirectToAction("register", "ost-account", new { success = false, status = "Password cannot be set to null or empty." }));
            }
            if (!model.Password.Equals(model.ConfirmPassword))
            {
                return(RedirectToAction("register", "ost-account", new { success = false, status = "Password and ConfirmPassword cannot be different." }));
            }
            if (string.IsNullOrEmpty(model.Email))
            {
                return(RedirectToAction("register", "ost-account", new { success = false, status = "Email cannot be set to null or empty." }));
            }

            model.FullName = model.UserName;
            var result = await CreateAccount(model);

            if (!result.Success)
            {
                return(RedirectToAction("register", "ost-account", new { success = result.Success, status = result.Status }));
            }

            var emailModel = new OstCreateEmailModel
            {
                UserEmail    = model.Email,
                UserName     = model.UserName,
                EmailSubject = "Verify your email address",
                EmailBody    = $"To finish setting up this {ConfigurationManager.ApplicationFullName} account, we just need to make sure this email address is yours."
            };

            await SendVerificationEmail(emailModel);

            return(RedirectToAction("success", "ost-account", new { success = true, status = "OK", operation = "register" }));
        }
        private static async Task SendForgotPasswordEmail(OstCreateEmailModel model)
        {
            var setting = new Setting
            {
                UserName = model.UserEmail,
                Key      = "ForgotPassword",
                Value    = DateTime.Now.ToString("s"),
                Id       = Strings.GenerateId()
            };

            await SaveSetting(setting, "ForgotPassword");

            var emailSubject = $"{ConfigurationManager.ApplicationFullName} - {model.EmailSubject}";
            var emailBody    = $@"Hello {model.UserName},

{model.EmailBody}
Please click the link below to proceed.
    {ConfigurationManager.BaseUrl}/ost-account/reset-password/{setting.Id}";

            await SendEmail(model.UserEmail, emailSubject, emailBody);
        }
        public async Task <ActionResult> SocialMediaHandle(OstSocialModel model)
        {
            if (string.IsNullOrEmpty(model.Email))
            {
                Response.StatusCode = (int)HttpStatusCode.Accepted;
                return(Json(new { success = false, status = "ERROR", message = "Email cannot be set to null or empty." }));
            }
            if (string.IsNullOrEmpty(model.Name))
            {
                Response.StatusCode = (int)HttpStatusCode.Accepted;
                return(Json(new { success = false, status = "ERROR", message = "Name cannot be set to null or empty." }));
            }
            if (string.IsNullOrEmpty(model.Id))
            {
                Response.StatusCode = (int)HttpStatusCode.Accepted;
                return(Json(new { success = false, status = "ERROR", message = "Id cannot be set to null or empty." }));
            }

            if (!string.IsNullOrEmpty(model.IdToken))
            {
                // TODO: Verify the integrity of the ID token
                // Phase 2
                if (model.Brand.Equals("facebook"))
                {
                }
                if (model.Brand.Equals("google"))
                {
                }
            }

            var username = Membership.GetUserNameByEmail(model.Email);

            if (null == username)
            {
                //register
                string strippedName = new string(model.Name.ToCharArray()
                                                 .Where(c => !char.IsWhiteSpace(c))
                                                 .ToArray()).ToLower();
                Random rnd         = new Random();
                int    rndTail     = rnd.Next(1000, 10000);
                var    newUserName = strippedName + rndTail.ToString();
                string password    = Membership.GeneratePassword(8, 1);

                var registerModel = new OstRegisterModel
                {
                    UserName        = newUserName,
                    FullName        = model.Name,
                    Email           = model.Email,
                    Password        = password,
                    ConfirmPassword = password,
                    Designation     = "No contract customer"
                };
                var result = await CreateAccount(registerModel);

                if (!result.Success)
                {
                    Response.StatusCode = (int)HttpStatusCode.Accepted;
                    return(Json(new { success = result.Success, status = "ERROR", message = result.Status }));
                }

                var emailModel = new OstCreateEmailModel
                {
                    UserEmail    = registerModel.Email,
                    UserName     = registerModel.UserName,
                    EmailSubject = "Verify your email address",
                    EmailBody    = $"To finish setting up this {ConfigurationManager.ApplicationFullName} account, we just need to make sure this email address is yours."
                };
                await SendVerificationEmail(emailModel);

                //create user details
                var context    = new SphDataContext();
                var userDetail = new Bespoke.Ost.UserDetails.Domain.UserDetail();
                var guid       = Guid.NewGuid().ToString();
                userDetail.Id     = guid;
                userDetail.UserId = registerModel.UserName;
                userDetail.Profile.ContactPerson            = registerModel.FullName;
                userDetail.ProfilePictureUrl                = model.PictureUrl;
                userDetail.Profile.ContactInformation.Email = registerModel.Email;
                userDetail.Profile.Address.Country          = "MY";
                using (var session = context.OpenSession())
                {
                    session.Attach(userDetail);
                    await session.SubmitChanges("Default");
                }

                Response.StatusCode = (int)HttpStatusCode.OK;
                return(Json(new { success = true, status = "OK", message = $"User {registerModel.UserName} with email {registerModel.Email} has been registered." }));
            }
            else
            {
                //login
                var logger   = ObjectBuilder.GetObject <ILogger>();
                var identity = new ClaimsIdentity(ConfigurationManager.ApplicationName + "Cookie");
                identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, username));
                identity.AddClaim(new Claim(ClaimTypes.Name, username));
                var roles = Roles.GetRolesForUser(username).Select(x => new Claim(ClaimTypes.Role, x));
                identity.AddClaims(roles);


                var context = new SphDataContext();
                var profile = await context.LoadOneAsync <UserProfile>(u => u.UserName == username);

                await logger.LogAsync(new LogEntry { Log = EventLog.Security });

                if (null != profile)
                {
                    // user email address verification pending
                    if (!profile.HasChangedDefaultPassword)
                    {
                        Response.StatusCode = (int)HttpStatusCode.Accepted;
                        return(Json(new { success = false, status = "ERROR", message = "Email verification pending. Please check your inbox for a verification email. You will be allowed to sign in after verification is complete." }));
                    }

                    var claims = profile.GetClaims();
                    identity.AddClaims(claims);

                    var designation = context.LoadOneFromSources <Designation>(x => x.Name == profile.Designation);
                    if (null != designation && designation.EnforceStartModule)
                    {
                        profile.StartModule = designation.StartModule;
                    }

                    HttpContext.GetOwinContext().Authentication.SignIn(identity);

                    Response.StatusCode = (int)HttpStatusCode.OK;
                    return(Json(new { success = true, status = "OK", message = $"User {profile.UserName} with email {profile.Email} has been authenticated." }));
                }
                HttpContext.GetOwinContext().Authentication.SignIn(identity);

                Response.StatusCode = (int)HttpStatusCode.OK;
                return(Json(new { success = true, status = "OK", message = $"User {profile.UserName} with email {profile.Email} has been authenticated." }));
            }
        }
        public async Task <ActionResult> FirstTimeLogin(int step, EstUserInputModel model)
        {
            var pointingUrl  = $"/api/est-registration/" + model.AccountNo;
            var outputString = await m_baseUrlClient.GetAsync(pointingUrl);

            var output       = string.Empty;
            var errorMessage = "Please go to the nearest Pusat Pos Laju (PPL) to reactivate your account.";

            if (outputString.IsSuccessStatusCode)
            {
                output = await outputString.Content.ReadAsStringAsync();

                var item         = JsonConvert.DeserializeObject <EstRegisterModel>(output);
                var encodedEmail = Convert.ToBase64String(Encoding.UTF8.GetBytes(item.EmailAddress));
                if (step == 1)
                {
                    if (model.AccountNo == item.AccountNo)
                    {
                        if (item.AccountStatus == 0)
                        {
                            if (item.EmailAddress != null)
                            {
                                if (IsValidEmail(item.EmailAddress))
                                {
                                    return(RedirectToAction("first-time-login/step/2", "ost-account", new { accNo = item.AccountNo, email = encodedEmail }));
                                }
                                else
                                {
                                    return(RedirectToAction("first-time-login/step/1", "ost-account", new { success = false, status = $"Your registered email address is invalid. {errorMessage}", accNo = item.AccountNo, email = encodedEmail }));
                                }
                            }
                            else
                            {
                                return(RedirectToAction("first-time-login/step/1", "ost-account", new { success = false, status = $"Your registered email address is invalid. {errorMessage}", accNo = item.AccountNo, email = encodedEmail }));
                            }
                        }
                        else if (item.AccountStatus == 1)
                        {
                            return(RedirectToAction("first-time-login/step/1", "ost-account", new { success = false, status = $"Your account has been blocked. {errorMessage}", accNo = item.AccountNo, email = encodedEmail }));
                        }
                        else
                        {
                            return(RedirectToAction("first-time-login/step/1", "ost-account", new { success = false, status = $"Your account has been terminated. {errorMessage}", accNo = item.AccountNo, email = encodedEmail }));
                        }
                    }
                    else
                    {
                        return(RedirectToAction("first-time-login/step/1", "ost-account", new { success = false, status = $"Your account number is invalid. {errorMessage}", accNo = item.AccountNo, email = encodedEmail }));
                    }
                }
                else if (step == 2)
                {
                    if (IsValidEmail(model.EmailAddress) && IsValidEmail(item.EmailAddress))
                    {
                        if ((model.EmailAddress != item.EmailAddress) ||
                            (model.AccountNo != item.AccountNo))
                        {
                            return(RedirectToAction("first-time-login/step/2", "ost-account", new { success = false, status = $"Your email address cannot be verified. {errorMessage}", accNo = item.AccountNo, email = encodedEmail }));
                        }
                    }
                    else
                    {
                        return(RedirectToAction("first-time-login/step/1", "ost-account", new { success = false, status = $"Your registered email address is invalid. {errorMessage}", accNo = item.AccountNo, email = encodedEmail }));
                    }

                    //register customer as Ezisend user; designation - "Contract customer"
                    string password      = Membership.GeneratePassword(8, 1);
                    var    registerModel = new OstRegisterModel
                    {
                        UserName        = model.AccountNo,
                        FullName        = item.CustomerName,
                        Password        = password,
                        ConfirmPassword = password,
                        Email           = model.EmailAddress,
                        Designation     = "Contract customer"
                    };
                    var result = await CreateAccount(registerModel);

                    if (!result.Success)
                    {
                        return(RedirectToAction("first-time-login/step/1", "ost-account", new { success = result.Success, status = result.Status, accNo = item.AccountNo, email = encodedEmail }));
                    }

                    var emailModel = new OstCreateEmailModel
                    {
                        UserEmail    = registerModel.Email,
                        UserName     = registerModel.UserName,
                        EmailSubject = "Create your password",
                        EmailBody    = $"Thank you for registering as a Pos Laju Business Customer user at {ConfigurationManager.ApplicationFullName}. To complete your account registration, you must create a new password.",
                    };
                    await SendForgotPasswordEmail(emailModel);

                    //create user details
                    var context    = new SphDataContext();
                    var userDetail = new Bespoke.Ost.UserDetails.Domain.UserDetail();
                    var guid       = Guid.NewGuid().ToString();
                    userDetail.Id     = guid;
                    userDetail.UserId = registerModel.UserName;
                    userDetail.Profile.CompanyName                                 = item.CompanyName;
                    userDetail.Profile.ContactPerson                               = item.CustomerName;
                    userDetail.ProfilePictureUrl                                   = "/assets/admin/pages/img/avatars/user_default.png";
                    userDetail.Profile.ContactInformation.Email                    = registerModel.Email;
                    userDetail.Profile.ContactInformation.ContactNumber            = item.ContactNo;
                    userDetail.Profile.ContactInformation.AlternativeContactNumber = item.AltContactNo;

                    userDetail.Profile.Address.Address1 = item.Address.Address1;
                    userDetail.Profile.Address.Address2 = item.Address.Address2;
                    userDetail.Profile.Address.Address3 = item.Address.Address3;
                    userDetail.Profile.Address.Address4 = $"{item.Address.Address4} {item.Address.Address5}";
                    userDetail.Profile.Address.City     = item.Address.City;
                    userDetail.Profile.Address.State    = item.Address.State;
                    userDetail.Profile.Address.Country  = "MY"; //item.Address.Country;
                    userDetail.Profile.Address.Postcode = item.Address.Postcode;

                    userDetail.PickupAddress.Address.Address1 = item.PickupAddress.Address1;
                    userDetail.PickupAddress.Address.Address2 = item.PickupAddress.Address2;
                    userDetail.PickupAddress.Address.Address3 = item.PickupAddress.Address3;
                    userDetail.PickupAddress.Address.Address4 = $"{item.PickupAddress.Address4} {item.PickupAddress.Address5}";
                    userDetail.PickupAddress.Address.City     = item.PickupAddress.City;
                    userDetail.PickupAddress.Address.State    = item.PickupAddress.State;
                    userDetail.PickupAddress.Address.Country  = "MY"; //item.PickupAddress.Country;
                    userDetail.PickupAddress.Address.Postcode = item.PickupAddress.Postcode;

                    userDetail.BillingAddress.Address.Address1 = item.BillingAddress.Address1;
                    userDetail.BillingAddress.Address.Address2 = item.BillingAddress.Address2;
                    userDetail.BillingAddress.Address.Address3 = item.BillingAddress.Address3;
                    userDetail.BillingAddress.Address.Address4 = $"{item.BillingAddress.Address4} {item.BillingAddress.Address5}";
                    userDetail.BillingAddress.Address.City     = item.BillingAddress.City;
                    userDetail.BillingAddress.Address.State    = item.BillingAddress.State;
                    userDetail.BillingAddress.Address.Country  = "MY"; //item.BillingAddress.Country;
                    userDetail.BillingAddress.Address.Postcode = item.BillingAddress.Postcode;

                    using (var session = context.OpenSession())
                    {
                        session.Attach(userDetail);
                        await session.SubmitChanges("Default");
                    }

                    return(RedirectToAction("success", "ost-account", new { success = true, status = "OK", operation = "register" }));
                }
            }
            else
            {
                return(RedirectToAction("first-time-login/step/1", "ost-account", new { success = false, status = $"Account number {model.AccountNo} is not exist. {errorMessage}" }));
            }
            return(RedirectToAction("first-time-login/step/1", "ost-account"));
        }