Skip to content

Commit

Permalink
PT-13765: registration from Checkout (#61)
Browse files Browse the repository at this point in the history
  • Loading branch information
ksavosteev authored Oct 12, 2023
1 parent 5fb732a commit 248bd96
Show file tree
Hide file tree
Showing 12 changed files with 67 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -167,10 +167,17 @@ protected override async Task HandleRequirementAsync(AuthorizationHandlerContext
updatePersonalDataCommand.UserId = currentUserId;
result = true;
}
else if (context.Resource is InviteUserCommand inviteUserCommand && currentContact != null)
else if (context.Resource is InviteUserCommand inviteUserCommand)
{
var currentUser = await userManager.FindByIdAsync(currentUserId);
result = currentContact.Organizations.Contains(inviteUserCommand.OrganizationId) && currentUser.StoreId.EqualsInvariant(inviteUserCommand.StoreId);
if (!string.IsNullOrEmpty(inviteUserCommand.OrganizationId) && currentContact != null)
{
var currentUser = await userManager.FindByIdAsync(currentUserId);
result = currentContact.Organizations.Contains(inviteUserCommand.OrganizationId) && currentUser.StoreId.EqualsInvariant(inviteUserCommand.StoreId);
}
else
{
result = true;
}
}
else if (context.Resource is LockOrganizationContactCommand lockOrganizationContact)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,7 @@ public class InviteUserCommand : ICommand<IdentityResultResponse>
public string Message { get; set; }

public string[] RoleIds { get; set; }

public string CustomerOrderId { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,14 @@ public virtual async Task<IdentityResultResponse> Handle(InviteUserCommand reque
FirstName = string.Empty,
LastName = string.Empty,
FullName = string.Empty,
Organizations = new List<string> { request.OrganizationId },
Emails = new List<string> { email }
};

if (!string.IsNullOrEmpty(request.OrganizationId))
{
contact.Organizations = new List<string> { request.OrganizationId };
}

await _memberService.SaveChangesAsync(new Member[] { contact });

var user = new ApplicationUser { UserName = email, Email = email, MemberId = contact.Id, StoreId = request.StoreId };
Expand Down Expand Up @@ -153,8 +158,18 @@ protected virtual async Task SendNotificationAsync(InviteUserCommand request, St
var user = await userManager.FindByEmailAsync(email);
var token = await userManager.GeneratePasswordResetTokenAsync(user);

var notification = await _notificationSearchService.GetNotificationAsync<RegistrationInvitationEmailNotification>(new TenantIdentity(store.Id, nameof(Store)));
// take notification
RegistrationInvitationNotificationBase notification = !string.IsNullOrEmpty(request.OrganizationId)
? await _notificationSearchService.GetNotificationAsync<RegistrationInvitationEmailNotification>(new TenantIdentity(store.Id, nameof(Store)))
: await _notificationSearchService.GetNotificationAsync<RegistrationInvitationCustomerEmailNotification>(new TenantIdentity(store.Id, nameof(Store)));

notification.InviteUrl = $"{store.Url.TrimLastSlash()}{request.UrlSuffix.NormalizeUrlSuffix()}?userId={user.Id}&email={HttpUtility.UrlEncode(user.Email)}&token={Uri.EscapeDataString(token)}";

if (!string.IsNullOrEmpty(request.CustomerOrderId))
{
notification.InviteUrl = $"{notification.InviteUrl}&customerOrderId={request.CustomerOrderId}";
}

notification.Message = request.Message;
notification.To = user.Email;
notification.From = store.Email;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,7 @@ public class RegisterByInvitationCommand : ICommand<IdentityResultResponse>
public string Username { get; set; }

public string Password { get; set; }

public string CustomerOrderId { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using Microsoft.Extensions.Hosting;
using VirtoCommerce.CustomerModule.Core.Model;
using VirtoCommerce.CustomerModule.Core.Services;
using VirtoCommerce.ExperienceApiModule.XOrder.Commands;
using VirtoCommerce.Platform.Core.Common;
using VirtoCommerce.Platform.Core.Security;
using VirtoCommerce.ProfileExperienceApiModule.Data.Extensions;
Expand Down Expand Up @@ -88,7 +89,13 @@ public virtual async Task<IdentityResultResponse> Handle(RegisterByInvitationCom

await _memberService.SaveChangesAsync(new Member[] { contact });

await SendRegistrationNotification(user, contact, cancellationToken);
// associate order
if (!string.IsNullOrEmpty(request.CustomerOrderId))
{
await TransferOrderAsync(request.CustomerOrderId, user.Id, contact.FullName, cancellationToken);
}

await SendRegistrationNotificationAsync(user, contact, cancellationToken);
}

return SetResponse(identityResult);
Expand All @@ -100,7 +107,7 @@ public virtual async Task<IdentityResultResponse> Handle(RegisterByInvitationCom
Succeeded = identityResult.Succeeded,
};

private async Task SendRegistrationNotification(ApplicationUser user, Contact contact, CancellationToken cancellationToken)
private async Task SendRegistrationNotificationAsync(ApplicationUser user, Contact contact, CancellationToken cancellationToken)
{
var store = await _storeService.GetByIdAsync(user.StoreId);
if (store == null)
Expand All @@ -119,5 +126,17 @@ private async Task SendRegistrationNotification(ApplicationUser user, Contact co
await _mediator.Send(registrationNotificationRequest, cancellationTokenSource.Token);
}

private async Task TransferOrderAsync(string customerOrderId, string userId, string userName, CancellationToken cancellationToken)
{
var transferOrderCommand = new TransferOrderCommand
{
CustomerOrderId = customerOrderId,
ToUserId = userId,
UserName = userName,
};

var cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
await _mediator.Send(transferOrderCommand, cancellationTokenSource.Token);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -124,11 +124,9 @@ protected virtual async Task BeforeProcessRequestAsync(RegisterRequestCommand re
EmailVerificationFlow = CurrentStore.GetEmailVerificationFlow();

// Read Settings
DefaultContactStatus = CurrentStore.Settings
.GetSettingValue<string>(CustomerSettings.ContactDefaultStatus.Name, null);
DefaultContactStatus = CurrentStore.Settings.GetValue<string>(CustomerSettings.ContactDefaultStatus);

DefaultOrganizationStatus = CurrentStore.Settings
.GetSettingValue<string>(CustomerSettings.OrganizationDefaultStatus.Name, null);
DefaultOrganizationStatus = CurrentStore.Settings.GetValue<string>(CustomerSettings.OrganizationDefaultStatus);

MaintainerRole = await GetMaintainerRole(result, tokenSource);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public virtual async Task<bool> Handle(SendVerifyEmailCommand request, Cancellat
return true;
}

if (store.Settings.GetSettingValue(StoreSettings.EmailVerificationEnabled.Name, (bool)StoreSettings.EmailVerificationEnabled.DefaultValue))
if (store.Settings.GetValue<bool>(StoreSettings.EmailVerificationEnabled))
{
await SendConfirmationEmailNotificationAsync(store, user, request.LanguageCode);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ public static class StoreExtensions
{
public static string GetEmailVerificationFlow(this Store store)
{
var emailVerificationEnabled = store.Settings.GetSettingValue(StoreSettings.EmailVerificationEnabled.Name, (bool)StoreSettings.EmailVerificationEnabled.DefaultValue);
var emailVerificationRequired = store.Settings.GetSettingValue(StoreSettings.EmailVerificationRequired.Name, (bool)StoreSettings.EmailVerificationRequired.DefaultValue);
var emailVerificationEnabled = store.Settings.GetValue<bool>(StoreSettings.EmailVerificationEnabled);
var emailVerificationRequired = store.Settings.GetValue<bool>(StoreSettings.EmailVerificationRequired);

if (!emailVerificationEnabled)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ public class InputInviteUserType : InputObjectGraphType
public InputInviteUserType()
{
Field<NonNullGraphType<StringGraphType>>(nameof(InviteUserCommand.StoreId), "ID of store which will send invites");
Field<NonNullGraphType<StringGraphType>>(nameof(InviteUserCommand.OrganizationId), "ID of organization where contact will be added for user");
Field<StringGraphType>(nameof(InviteUserCommand.OrganizationId), "ID of organization where contact will be added for user");
Field<StringGraphType>(nameof(InviteUserCommand.UrlSuffix), "Optional URL suffix: you may provide here relative URL to your page which handle registration by invite");
Field<NonNullGraphType<ListGraphType<NonNullGraphType<StringGraphType>>>>(nameof(InviteUserCommand.Emails), "Emails which will receive invites");
Field<StringGraphType>(nameof(InviteUserCommand.Message), "Optional message to include into email with instructions which invites persons will see");
Field<ListGraphType<NonNullGraphType<StringGraphType>>>(nameof(InviteUserCommand.RoleIds), "Role IDs or names to be assigned to the invited user");
Field<StringGraphType>(nameof(InviteUserCommand.CustomerOrderId), "Customer order Id to be associated with this user.");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public InputRegisterByInvitationType()
Field<StringGraphType>(nameof(RegisterByInvitationCommand.Phone), "Phone");
Field<NonNullGraphType<StringGraphType>>(nameof(RegisterByInvitationCommand.Username), "Username");
Field<NonNullGraphType<StringGraphType>>(nameof(RegisterByInvitationCommand.Password), "Password");
Field<StringGraphType>(nameof(RegisterByInvitationCommand.CustomerOrderId), "Customer order Id to be associated with this user.");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
<PackageReference Include="VirtoCommerce.CoreModule.Core" Version="3.400.0" />
<PackageReference Include="VirtoCommerce.CustomerModule.Core" Version="3.400.0" />
<PackageReference Include="VirtoCommerce.ExperienceApiModule.Core" Version="3.411.0" />
<PackageReference Include="VirtoCommerce.ExperienceApiModule.Core" Version="3.422.0" />
<PackageReference Include="VirtoCommerce.ExperienceApiModule.XOrder" Version="3.422.0" />
<PackageReference Include="VirtoCommerce.MarketingModule.Core" Version="3.400.0" />
<PackageReference Include="VirtoCommerce.NotificationsModule.Core" Version="3.400.0" />
<PackageReference Include="VirtoCommerce.Platform.Security" Version="3.400.0" />
<PackageReference Include="VirtoCommerce.NotificationsModule.Core" Version="3.403.0" />
<PackageReference Include="VirtoCommerce.Platform.Security" Version="3.413.0" />
<PackageReference Include="VirtoCommerce.PricingModule.Core" Version="3.400.0" />
<PackageReference Include="VirtoCommerce.StoreModule.Core" Version="3.401.0" />
<PackageReference Include="VirtoCommerce.TaxModule.Core" Version="3.400.0" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
<id>VirtoCommerce.ProfileExperienceApiModule</id>
<version>3.410.0</version>
<version-tag />
<platformVersion>3.400.0</platformVersion>
<platformVersion>3.413.0</platformVersion>
<dependencies>
<dependency id="VirtoCommerce.Core" version="3.400.0" />
<dependency id="VirtoCommerce.Customer" version="3.400.0" />
<dependency id="VirtoCommerce.ExperienceApi" version="3.411.0" />
<dependency id="VirtoCommerce.ExperienceApi" version="3.422.0" />
<dependency id="VirtoCommerce.Marketing" version="3.400.0" />
<dependency id="VirtoCommerce.Notifications" version="3.400.0" />
<dependency id="VirtoCommerce.Notifications" version="3.403.0" />
<dependency id="VirtoCommerce.Pricing" version="3.400.0" />
<dependency id="VirtoCommerce.Store" version="3.401.0" />
<dependency id="VirtoCommerce.Tax" version="3.400.0" />
Expand Down

0 comments on commit 248bd96

Please sign in to comment.