Exemplo n.º 1
0
        public async Task <SendMessagePayload> SendMessageAsync(
            SendMessageInput input,
            FieldNode field,
            [GlobalState] string currentUserEmail,
            PersonByEmailDataLoader personByEmail,
            [Service] IMessageRepository messageRepository,
            [Service] IEventDispatcher eventDispatcher,
            CancellationToken cancellationToken)
        {
            IReadOnlyList <Person> participants =
                await personByEmail.LoadAsync(
                    cancellationToken, currentUserEmail, input.RecipientEmail)
                .ConfigureAwait(false);

            if (participants[1] is null)
            {
                throw new QueryException(
                          ErrorBuilder.New()
                          .SetCode("UNKNOWN_RECIPIENT")
                          .SetMessage("The given recipient id is invalid.")
                          .AddLocation(field.Arguments[0])
                          .Build());
            }

            Person sender    = participants[0];
            Person recipient = participants[1];

            var message = new Message(
                sender.Id,
                recipient.Id,
                input.Text);

            await messageRepository.AddMessageAsync(
                message, cancellationToken)
            .ConfigureAwait(false);

            await eventDispatcher.SendAsync(
                recipient.Email, message, cancellationToken)
            .ConfigureAwait(false);

            return(new SendMessagePayload(
                       sender,
                       recipient,
                       message,
                       input.ClientMutationId));
        }
Exemplo n.º 2
0
        public async Task <SendMessagePayload> SendMessageAsync(
            SendMessageInput input,
            FieldNode field,
            [GlobalState] string currentUserEmail,
            PersonByEmailDataLoader personByEmail,
            [Service] ChatDbContext dbContext,
            [Service] ITopicEventSender eventSender,
            CancellationToken cancellationToken)
        {
            IReadOnlyList <Person> participants =
                await personByEmail.LoadAsync(
                    cancellationToken, currentUserEmail, input.RecipientEmail);

            if (participants[1] is null)
            {
                throw new QueryException(
                          ErrorBuilder.New()
                          .SetCode("UNKNOWN_RECIPIENT")
                          .SetMessage("The given recipient id is invalid.")
                          .AddLocation(field.Arguments[0])
                          .Build());
            }

            Person sender    = participants[0];
            Person recipient = participants[1];

            var message = new Message
            {
                SenderId    = sender.Id,
                RecipientId = recipient.Id,
                Text        = input.Text,
                Sent        = DateTime.UtcNow
            };

            dbContext.Messages.Add(message);
            await dbContext.SaveChangesAsync(cancellationToken);

            await eventSender.SendAsync(recipient.Email, message, cancellationToken);

            return(new SendMessagePayload(
                       sender,
                       recipient,
                       message,
                       input.ClientMutationId));
        }
        public async Task <Direction> GetDirectionAsync(
            [GlobalState] string currentUserEmail,
            PersonByEmailDataLoader personByEmail,
            [Parent] Message message,
            CancellationToken cancellationToken)
        {
            Person sender = await personByEmail.LoadAsync(currentUserEmail, cancellationToken);

            if (message.RecipientId == message.SenderId &&
                message.SenderId == sender.Id)
            {
                return(Direction.Incoming);
            }

            if (message.SenderId == sender.Id)
            {
                return(Direction.Outgoing);
            }

            return(Direction.Incoming);
        }
        public async Task <LoginPayload> LoginAsync(
            LoginInput input,
            [Service] ChatDbContext dbContext,
            [Service] PersonByEmailDataLoader personByEmail,
            [Service] ITopicEventSender eventSender,
            CancellationToken cancellationToken)
        {
            if (string.IsNullOrEmpty(input.Email))
            {
                throw new QueryException(
                          ErrorBuilder.New()
                          .SetMessage("The email mustn't be empty.")
                          .SetCode("EMAIL_EMPTY")
                          .Build());
            }

            if (string.IsNullOrEmpty(input.Password))
            {
                throw new QueryException(
                          ErrorBuilder.New()
                          .SetMessage("The password mustn't be empty.")
                          .SetCode("PASSWORD_EMPTY")
                          .Build());
            }

            User?user = await dbContext.Users.FirstOrDefaultAsync(t => t.Email == input.Email);

            if (user is null)
            {
                throw new QueryException(
                          ErrorBuilder.New()
                          .SetMessage("The specified username or password are invalid.")
                          .SetCode("INVALID_CREDENTIALS")
                          .Build());
            }

            using var sha = SHA512.Create();
            byte[] hash = sha.ComputeHash(Encoding.UTF8.GetBytes(input.Password + user.Salt));

            if (!Convert.ToBase64String(hash).Equals(user.PasswordHash, StringComparison.Ordinal))
            {
                throw new QueryException(
                          ErrorBuilder.New()
                          .SetMessage("The specified username or password are invalid.")
                          .SetCode("INVALID_CREDENTIALS")
                          .Build());
            }

            Person me = await personByEmail.LoadAsync(input.Email, cancellationToken);

            var identity = new ClaimsIdentity(new Claim[]
            {
                new Claim(ClaimTypes.Name, user.Email),
                new Claim(ClaimTypes.Email, user.Email),
                new Claim(WellKnownClaimTypes.UserId, me.Id.ToString()),
            });

            var tokenHandler = new JwtSecurityTokenHandler();

            var tokenDescriptor = new SecurityTokenDescriptor
            {
                Subject            = identity,
                Expires            = DateTime.UtcNow.AddHours(12),
                SigningCredentials = new SigningCredentials(
                    new SymmetricSecurityKey(Startup.SharedSecret),
                    SecurityAlgorithms.HmacSha256Signature)
            };

            SecurityToken token       = tokenHandler.CreateToken(tokenDescriptor);
            string        tokenString = tokenHandler.WriteToken(token);

            await eventSender.SendAsync <string, Person>("online", me);

            return(new LoginPayload(me, tokenString, "bearer", input.ClientMutationId));
        }