public Task <Result <string> > Send(UserInvitationData prefilledData, int inviterUserId) { return(Result.Success() .Ensure(AllProvidedRolesExist, "All admin roles should exist") .Bind(CreateInvitation) .Check(SendInvitationMail)); async Task <bool> AllProvidedRolesExist() { var allRoles = await _context.AdministratorRoles.Select(x => x.Id).ToListAsync(); return(prefilledData.RoleIds.All(allRoles.Contains)); } Task <Result <string> > CreateInvitation() => Create(prefilledData, inviterUserId); async Task <Result> SendInvitationMail(string invitationCode) { var registrationInfo = prefilledData.UserRegistrationInfo; var messagePayload = new InvitationData { InvitationCode = invitationCode, UserEmailAddress = registrationInfo.Email, UserName = $"{registrationInfo.FirstName} {registrationInfo.LastName}", FrontendBaseUrl = _options.FrontendBaseUrl }; return(await _notificationService.Send(messageData : messagePayload, notificationType : NotificationTypes.AdministratorInvitation, emails : new() { registrationInfo.Email })); } }
public async Task <Result> Accept(string invitationCode, UserInvitationData filledData, string identity, string email) { return(await GetActiveInvitation() .Bind(Validate) .BindWithTransaction(_context, values => Result.Success(values) .Tap(SaveAccepted) .Bind(CreateAgent) .Bind(GetOrCreateAgency) .Tap(AddAgentAgencyRelation)) .Tap(LogSuccess) .Tap(SendRegistrationMailToMaster) .OnFailure(LogFailed)); async Task <Result <AcceptPipeValues> > GetActiveInvitation() { var(_, isFailure, invitation, error) = await _invitationRecordService.GetActiveInvitationByCode(invitationCode); if (isFailure) { return(Result.Failure <AcceptPipeValues>(error)); } var originalInvitationData = _invitationRecordService.GetInvitationData(invitation); return(new AcceptPipeValues { Invitation = invitation, InvitationData = filledData.Equals(default) ? originalInvitationData : filledData,
public Task <Result <string> > Send(UserInvitationData prefilledData, UserInvitationTypes invitationType, int inviterUserId, int?inviterAgencyId = null) { return(Validate() .Bind(CreateInvitation) .Check(SendInvitationMailPipe)); Task <Result> SendInvitationMailPipe(string invitationCode) => SendInvitationMail(invitationCode, prefilledData, invitationType, inviterAgencyId); Result Validate() => GenericValidator <UserInvitationData> .Validate(v => { v.RuleFor(x => x.UserRegistrationInfo.FirstName).NotEmpty() .WithMessage("FirstName is required"); v.RuleFor(x => x.UserRegistrationInfo.LastName).NotEmpty() .WithMessage("LastName is required"); v.RuleFor(x => x.UserRegistrationInfo.Title).NotEmpty() .WithMessage("Title is required"); v.RuleFor(e => e.UserRegistrationInfo.Email).NotEmpty().EmailAddress() .WithMessage("Valid email is required"); }, prefilledData); Task <Result <string> > CreateInvitation() => Create(prefilledData, invitationType, inviterUserId, inviterAgencyId); }
public async Task Create(ISqlTransactionHandler transactionHandler, UserInvitationData userInvitationData) { if (userInvitationData.Manager.GetState(userInvitationData) == DataState.New) { await _providerFactory.EstablishTransaction(transactionHandler, userInvitationData); using (DbCommand command = transactionHandler.Connection.CreateCommand()) { command.CommandText = "[bla].[CreateUserInvitation]"; command.CommandType = CommandType.StoredProcedure; command.Transaction = transactionHandler.Transaction.InnerTransaction; IDataParameter guid = DataUtil.CreateParameter(_providerFactory, "id", DbType.Guid); guid.Direction = ParameterDirection.Output; command.Parameters.Add(guid); IDataParameter timestamp = DataUtil.CreateParameter(_providerFactory, "timestamp", DbType.DateTime2); timestamp.Direction = ParameterDirection.Output; command.Parameters.Add(timestamp); DataUtil.AddParameter(_providerFactory, command.Parameters, "accountGuid", DbType.Guid, userInvitationData.AccountId); DataUtil.AddParameter(_providerFactory, command.Parameters, "emailAddressGuid", DbType.Guid, userInvitationData.EmailAddressId); DataUtil.AddParameter(_providerFactory, command.Parameters, "status", DbType.Int16, userInvitationData.Status); DataUtil.AddParameter(_providerFactory, command.Parameters, "expirationTimestamp", DbType.DateTime2, userInvitationData.ExpirationTimestamp); await command.ExecuteNonQueryAsync(); userInvitationData.UserInvitationId = (Guid)guid.Value; userInvitationData.CreateTimestamp = (DateTime)timestamp.Value; userInvitationData.UpdateTimestamp = (DateTime)timestamp.Value; } } }
public UserInvitation(UserInvitationData data, IUserInvitationDataSaver dataSaver, IEmailAddressFactory emailAddressFactory) { _data = data; _dataSaver = dataSaver; _emailAddressFactory = emailAddressFactory; }
public UserInvitation(UserInvitationData data, IUserInvitationDataSaver dataSaver, IEmailAddressFactory emailAddressFactory, IAccount account, IEmailAddress emailAddress) : this(data, dataSaver, emailAddressFactory) { _account = account; _emailAddress = emailAddress; }
public async Task SendUserInvitationEmailAsync(UserInvitationData data) { if (string.IsNullOrWhiteSpace(data.ReceiverAddress)) { throw new ArgumentException("Cannot send to empty email address."); } var body = ConstructUserInvitationEmailBody(data); await SendEmailAsync(data.ReceiverAddress, "Join iChat", body); }
public Task <Result <string> > Create(UserInvitationData prefilledData, UserInvitationTypes invitationType, int inviterUserId, int?inviterAgencyId = null) { var invitationCode = GenerateRandomCode(); var now = _dateTimeProvider.UtcNow(); return(Result.Success() .Ensure(AllProvidedRolesExist, "All roles should exist") .Bind(SaveInvitation) .Tap(LogInvitationCreated) .Map(_ => invitationCode)); string GenerateRandomCode() { using var provider = new RNGCryptoServiceProvider(); var byteArray = new byte[64]; provider.GetBytes(byteArray); return(Base64UrlEncoder.Encode(byteArray)); } async Task <bool> AllProvidedRolesExist() { var allRoleIds = await _context.AgentRoles.Select(r => r.Id).ToListAsync(); return(prefilledData.RoleIds.All(x => allRoleIds.Contains(x))); } async Task <Result <UserInvitation> > SaveInvitation() { var newInvitation = new UserInvitation { CodeHash = HashGenerator.ComputeSha256(invitationCode), Email = prefilledData.UserRegistrationInfo.Email, Created = now, InviterUserId = inviterUserId, InviterAgencyId = inviterAgencyId, InvitationType = invitationType, InvitationStatus = UserInvitationStatuses.Active, Data = JsonConvert.SerializeObject(prefilledData) }; _context.UserInvitations.Add(newInvitation); await _context.SaveChangesAsync(); return(newInvitation); } void LogInvitationCreated() => _logger.LogInvitationCreated(invitationType, prefilledData.UserRegistrationInfo.Email); }
public async Task <IUserInvitation> Get(ISettings settings, Guid id) { UserInvitation result = null; UserInvitationData data = await _dataFactory.Get(_settingsFactory.CreateData(settings), id); if (data != null) { result = Create(data); } return(result); }
public Task <Result <string> > Create(UserInvitationData prefilledData, int inviterUserId) { if (prefilledData.RoleIds is null || !prefilledData.RoleIds.Any()) { return(Task.FromResult(Result.Failure <string>("Invitation should have role ids"))); } var invitationCode = GenerateRandomCode(); var now = _dateTimeProvider.UtcNow(); var registrationInfo = prefilledData.UserRegistrationInfo; return(SaveInvitation() .Tap(LogInvitationCreated) .Map(_ => invitationCode)); string GenerateRandomCode() { using var provider = new RNGCryptoServiceProvider(); var byteArray = new byte[64]; provider.GetBytes(byteArray); return(Base64UrlEncoder.Encode(byteArray)); } async Task <Result <UserInvitation> > SaveInvitation() { var newInvitation = new UserInvitation { CodeHash = HashGenerator.ComputeSha256(invitationCode), Email = registrationInfo.Email, Created = now, InviterUserId = inviterUserId, InvitationType = UserInvitationTypes.Administrator, InvitationStatus = UserInvitationStatuses.Active, Data = JsonConvert.SerializeObject(prefilledData) }; _context.UserInvitations.Add(newInvitation); await _context.SaveChangesAsync(); return(newInvitation); } void LogInvitationCreated() => _logger.LogInvitationCreated(UserInvitationTypes.Administrator, registrationInfo.Email); }
private string ConstructUserInvitationEmailBody(UserInvitationData data) { var emailTemplatePath = Path.Combine(iChatConstants.EmailTemplatePath, "UserInvitationEmail.htm"); var joinUrl = $"{_appSettings.FrontEndUrl}/user/acceptinvitation" + $"?email={data.ReceiverAddress}&code={data.InvitationCode}" + $"&workspaceName={data.WorkspaceName}"; var body = string.Empty; if (!string.IsNullOrEmpty(emailTemplatePath)) { using (StreamReader reader = new StreamReader(emailTemplatePath)) { body = reader.ReadToEnd(); } } body = body.Replace("{WorkspaceName}", HttpUtility.HtmlEncode(data.WorkspaceName)); body = body.Replace("{InviterName}", HttpUtility.HtmlEncode(data.InviterName)); body = body.Replace("{InviterEmail}", HttpUtility.HtmlEncode(data.InviterEmail)); body = body.Replace("{JoinUrl}", joinUrl); return(body); }
private async Task <Result> SendInvitationMail(string invitationCode, UserInvitationData prefilledData, UserInvitationTypes invitationType, int?inviterAgencyId) { string agencyName = null; if (inviterAgencyId.HasValue) { var getAgencyResult = await _agencyManagementService.Get(inviterAgencyId.Value); if (getAgencyResult.IsFailure) { return(Result.Failure("Could not find inviter agency")); } agencyName = getAgencyResult.Value.Name; } var messagePayload = new InvitationData { AgencyName = agencyName, InvitationCode = invitationCode, UserEmailAddress = prefilledData.UserRegistrationInfo.Email, UserName = $"{prefilledData.UserRegistrationInfo.FirstName} {prefilledData.UserRegistrationInfo.LastName}" }; var notificationType = invitationType switch { UserInvitationTypes.Agent => NotificationTypes.AgentInvitation, UserInvitationTypes.ChildAgency => NotificationTypes.ChildAgencyInvitation, _ => NotificationTypes.None }; return(await _notificationService.Send(messageData : messagePayload, notificationType : notificationType, email : prefilledData.UserRegistrationInfo.Email)); }
private UserInvitation Create(UserInvitationData data, IAccount account, IEmailAddress emailAddress) => new UserInvitation(data, _dataSaver, _emailAddressFactory, account, emailAddress);
private UserInvitation Create(UserInvitationData data) => new UserInvitation(data, _dataSaver, _emailAddressFactory);