public static string GetLocationForGoogleMaps(LcRest.Address address) { return(ASP.LcHelpers.JoinNotEmptyStrings(", ", address.addressLine1, address.city, address.stateProvinceCode, address.countryCode)); }
public static string GetLocationGoogleMapsUrl(LcRest.Address address) { return("http://maps.google.com/?q=" + Uri.EscapeDataString(GetLocationForGoogleMaps(address))); }
/// <summary> /// Signup with fields: /// - email [required] /// - password [required when no facebookUserID is given] /// - facebookUserID [optional] /// - countryID [optional defaults to COUNTRY_CODE_USA] /// - profileType [optional defaults to client] /// - utm [optional, not a named form parameter but the whole query string] /// - firstName [optional for professionals, required for clients] /// - lastName [optional for professionals, required for clients] /// - postalCode [optional] /// - referralCode [optional] /// - device [optional] /// - phone [optional for professionals, required for clients] /// - returnProfile [optional defaults to false] Returns the user profile in a property of the result /// </summary> /// <param name="page"></param> /// <returns></returns> public static LoginResult Signup(WebPage page) { page.Validation.RequireField("email", "You must specify an email."); // Username is an email currently, so need to be restricted page.Validation.Add("email", Validator.Regex(LcValidators.EmailAddressRegexPattern, "The email is not valid.")); // First data var profileTypeStr = Request.Form["profileType"] ?? ""; var isServiceProfessional = SERVICE_PROFESSIONAL_TYPE == profileTypeStr.ToUpper(); var isClient = !isServiceProfessional; var facebookUserID = Request.Form["facebookUserID"].AsLong(0); var facebookAccessToken = Request.Form["facebookAccessToken"]; var email = Request.Form["email"]; // // Conditional validations // Facebook var useFacebookConnect = facebookUserID > 0 && !String.IsNullOrEmpty(facebookAccessToken); if (!useFacebookConnect) { page.Validation.RequireField("password", "You must specify a password."); // We manually validate if a password was given, in order to prevent // showing up the validation format message additionally to the 'required password' message if (!String.IsNullOrWhiteSpace(Request.Form["password"])) { page.Validation.Add("password", new PasswordValidator()); } } else { var prevFbUser = LcAuth.GetFacebookUser(facebookUserID); if (prevFbUser != null) { throw new HttpException(409, "Facebook account already connected. Sign in."); } } // Profile Type if (isClient) { page.Validation.RequireField("phone", "You must specify your mobile phone number."); page.Validation.RequireField("firstName", "You must specify your first name."); page.Validation.RequireField("lastName", "You must specify your last name."); } if (page.Validation.IsValid()) { var postalCode = Request.Form["postalCode"]; // TODO To use countryCode for a more 'open' public REST API, where 'code' is a well know ISO 2-letters CODE //var countryCode = Request.Form["countryCode"] ?? "US"; var countryID = Request.Form["countryID"].AsInt(COUNTRY_CODE_USA); // Postal code is Optional if (!String.IsNullOrEmpty(postalCode)) { // Validate postal code before continue var add = new LcRest.Address { postalCode = postalCode, //countryCode = countryCode countryID = countryID }; if (!LcRest.Address.AutosetByCountryPostalCode(add)) { // bad postal code page.ModelState.AddError("postalCode", "Invalid postal code"); throw new HttpException(400, LcRessources.ValidationSummaryTitle); } } // Autogenerated password (we need to save one) on facebook connect: var password = useFacebookConnect ? LcAuth.GeneratePassword() : Request.Form["password"]; var firstName = Request.Form["firstName"]; var lastName = Request.Form["lastName"]; var referralCode = Request.Form["referralCode"]; var device = Request.Form["device"]; var phone = Request.Form["phone"]; var returnProfile = Request.Form["returnProfile"].AsBool(); var utm = Request.Url.Query; LoginResult logged = null; // If the user exists, try to log-in with the given password, // becoming a provider if that was the requested profileType and follow as // a normal login. // If the password didn't match, throw a sign-up specific error (email in use) // Otherwise, just register the user. if (LcAuth.ExistsEmail(email)) { // If the email exists, we try to log-in using the provided password, to don't bother with "e-mail in use" error // if the user provides the correct credentials (maybe just don't remember he/she has already an account; make it easy for them // to return). // BUT we have a special situation that needs extra checks: // CLIENT--CONFIRMATION LOGIC // The email can exists because the user has an account created as client by a service professional: // - A: On that cases, we need to communicate that specific situation (error message), generate a confirmation code // for the existent user, send email to let him to confirm it owns the given e-mail. // - B: On returning here after point A, a confirmation code is provided and we must proceed // by checking the confirmation code and, on success, unlock and update the membership password and // continue updating any given data. var userID = WebSecurity.GetUserId(email); var user = LcRest.UserProfile.Get(userID); if (user.accountStatusID != (int)LcEnum.AccountStatus.serviceProfessionalClient) { // NOT a client, just standard sign-up that requires verify the email/password or fail // Try Login try { logged = Login(email, password, false, returnProfile, true); userID = logged.userID; // throw exception on error if (isServiceProfessional) { LcAuth.BecomeProvider(userID); } } catch (HttpException) { // Not valid log-in, throw a 'email exists' error with Conflict http code throw new HttpException(409, "E-mail address is already in use."); } } else { // CLIENT--CONFIRMATION LOGIC // The email can exists because the user has an account created as client by a service professional: // - A: On that cases, we need to communicate that specific situation (error message), generate a confirmation code // for the existent user, send email to let him to confirm it owns the given e-mail. // - B: On returning here after point A, a confirmation code is provided and we must proceed // by checking the confirmation code and, on success, unlock and update the membership password and // continue updating any given data. var confirmationCode = Request["confirmationCode"]; var errMsg = String.Format(@"We see one of our service professionals has already scheduled services for you in the past. We've just sent an invitation to create your account to {0}. Please follow its instructions. We can't wait to get you on board!", email ); if (String.IsNullOrEmpty(confirmationCode)) { // Point A: create confirmation code // generate a confirmation code (creates the Membership record, that does not exists still since is as just a client) // this needs a random password (we still didn't verified the user, so do NOT trust on the given password). // NOTE: since this can be attempted several time by the user, and next attempts will fail because the Membership // record will exists already, just double check and try creation only if record don't exists: if (!LcAuth.HasMembershipRecord(userID)) { WebSecurity.CreateAccount(email, LcAuth.GeneratePassword(), true); } // send email to let him to confirm it owns the given e-mail LcMessaging.SendWelcomeCustomer(userID, email); // Not valid after all, just communicate was was done and needs to do to active its account: throw new HttpException(409, errMsg); } else { // Point B: confirm confirmation code if (LcAuth.GetConfirmationToken(userID) == confirmationCode) { // We know is valid, we can update the accountStatus to not be any more a "service professional's client" // and that will allow to set the account as confirmed using (var db = new LcDatabase()) { db.Execute("UPDATE users SET accountStatusID = @1 WHERE UserID = @0", userID, LcEnum.AccountStatus.active); } // now we can confirm (we already know the code is valid, it will just double check and update database) LcAuth.ConfirmAccount(confirmationCode); // set the password provided by the user. Trick: we need to generate a reset token in order to set the password. var token = WebSecurity.GeneratePasswordResetToken(email); LcAuth.ResetPassword(token, password); // Left continue with profile data update.. } else { // RE-send email to let him to confirm it owns the given e-mail LcMessaging.SendWelcomeCustomer(userID, email); throw new HttpException(409, errMsg); } } // We need a logged object, and additionally a double check is performed (so we ensure setting the password process worked). logged = Login(email, password, false, returnProfile, false); } // Update account data with the extra information. using (var db = new LcDatabase()) { db.Execute(@" UPDATE users SET firstName = coalesce(@1, firstName), lastName = coalesce(@2, lastName), mobilePhone = coalesce(@3, mobilePhone), signupDevice = coalesce(@4, signupDevice) WHERE userID = @0 ", userID, firstName, lastName, phone, device); if (!String.IsNullOrEmpty(postalCode)) { var address = LcRest.Address.GetHomeAddress(userID); if (address.postalCode != postalCode) { address.postalCode = postalCode; //address.countryCode = countryCode; address.countryCode = LcRest.Locale.GetCountryCodeByID(countryID); address.countryID = countryID; LcRest.Address.SetAddress(address); } } } // SIGNUP LcMessaging.SendMail("*****@*****.**", "Sign-up", String.Format(@" <html><body><h3>Sign-up.</h3> <strong>This user was already in the database, is re-registering itself again!</strong><br/> <dl> <dt>Profile:</dt><dd>{0}</dd> <dt>First Name:</dt><dd>{1}</dd> <dt>Last Name:</dt><dd>{2}</dd> <dt>Postal code:</dt><dd>{3}</dd> <dt>Country:</dt><dd>{9}</dd> <dt>Referral code:</dt><dd>{4}</dd> <dt>Device:</dt><dd>{5}</dd> <dt>Phone:</dt><dd>{6}</dd> <dt>Email:</dt><dd>{7}</dd> <dt>UserID:</dt><dd>{8}</dd> </dl> </body></html> ", profileTypeStr, firstName, lastName, postalCode, referralCode, device, phone, email, logged.userID, countryID)); return(logged); } else { if (useFacebookConnect) { // Verify Facebook ID and accessToken contacting to Facebook Servers if (LcFacebook.GetUserFromAccessToken(facebookUserID.ToString(), facebookAccessToken) == null) { throw new HttpException(400, "Facebook account does not exists."); } } var registered = LcAuth.RegisterUser(email, firstName, lastName, password, isServiceProfessional, utm, -1, null, phone, device); if (!String.IsNullOrEmpty(postalCode)) { // Set address var address = LcRest.Address.GetHomeAddress(registered.UserID); address.postalCode = postalCode; //address.countryCode = countryCode; address.countryCode = LcRest.Locale.GetCountryCodeByID(countryID); address.countryID = countryID; LcRest.Address.SetAddress(address); } if (useFacebookConnect) { // Register connection between the new account and the Facebook account LcAuth.ConnectWithFacebookAccount(registered.UserID, facebookUserID); } // Welcome and confirmation e-mail LcAuth.SendRegisterUserEmail(registered); // SIGNUP LcMessaging.SendMail("*****@*****.**", "Sign-up", String.Format(@" <html><body><h3>Sign-up.</h3> <dl> <dt>Profile:</dt><dd>{0}</dd> <dt>First Name:</dt><dd>{1}</dd> <dt>Last Name:</dt><dd>{2}</dd> <dt>Postal code:</dt><dd>{3}</dd> <dt>Country:</dt><dd>{9}</dd> <dt>Referral code:</dt><dd>{4}</dd> <dt>Device:</dt><dd>{5}</dd> <dt>Phone:</dt><dd>{6}</dd> <dt>Email:</dt><dd>{7}</dd> <dt>UserID:</dt><dd>{8}</dd> </dl> </body></html> ", profileTypeStr, firstName, lastName, postalCode, referralCode, device, phone, email, registered.UserID, countryID)); // Auto login: return(Login(email, password, false, returnProfile, true)); } } else { // Bad request, input data incorrect because of validation rules throw new HttpException(400, LcRessources.ValidationSummaryTitle); } }