Exemple #1
0
        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 }));
            }
        }
Exemple #2
0
        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);
        }
Exemple #4
0
        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;
                }
            }
        }
Exemple #5
0
 public UserInvitation(UserInvitationData data,
                       IUserInvitationDataSaver dataSaver,
                       IEmailAddressFactory emailAddressFactory)
 {
     _data                = data;
     _dataSaver           = dataSaver;
     _emailAddressFactory = emailAddressFactory;
 }
Exemple #6
0
 public UserInvitation(UserInvitationData data,
                       IUserInvitationDataSaver dataSaver,
                       IEmailAddressFactory emailAddressFactory,
                       IAccount account,
                       IEmailAddress emailAddress) : this(data, dataSaver, emailAddressFactory)
 {
     _account      = account;
     _emailAddress = emailAddress;
 }
Exemple #7
0
        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);
        }
Exemple #10
0
        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);
        }
Exemple #11
0
        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);