public async Task <Unit> Handle(CreatePublicHiddenScriptCommand request, CancellationToken cancellationToken)
        {
            var exists = await _db.Scripts.FirstOrDefaultAsync(w => w.Name.ToLower() == request.Script.Name.ToLower() || w.Id == request.Script.Id,
                                                               cancellationToken);

            if (exists != null && request.Script.Id != exists.Id)
            {
                throw new Exception("A script by that name already exists.");
            }

            if (exists != null && exists.UserId != request.User.Id)
            {
                throw new Exception("A script by that name already exists.");
            }

            request.Script.Type        = ScriptType.HiddenPublic;
            request.Script.Price       = null;
            request.Script.Instances   = null;
            request.Script.Status      = ScriptStatus.Live;
            request.Script.ForumThread = "https://rspeer.org";
            request.Script.UserId      = request.User.Id;

            var bytes = request.File.OpenReadStream().ToByteArray();

            using (var transaction = await _db.Database.BeginTransactionAsync(cancellationToken))
            {
                if (exists != null)
                {
                    exists = TinyMapper.Map(request.Script, exists);
                    var content =
                        await _db.ScriptContents.FirstOrDefaultAsync(w => w.ScriptId == exists.Id, cancellationToken);

                    content.Content = bytes;
                    _db.ScriptContents.Update(content);
                    _db.Scripts.Update(exists);
                    await _db.SaveChangesAsync(cancellationToken);
                }
                else
                {
                    request.Script.Id = 0;
                    await _db.Scripts.AddAsync(request.Script, cancellationToken);

                    await _db.SaveChangesAsync(cancellationToken);

                    await _db.ScriptContents.AddAsync(new ScriptContent
                    {
                        ScriptId = request.Script.Id,
                        Content  = bytes
                    }, cancellationToken);

                    await _db.SaveChangesAsync(cancellationToken);
                }

                transaction.Commit();
            }

            return(Unit.Value);
        }
        public async Task <Unit> Handle(PaypalFinishOrderCommand request, CancellationToken cancellationToken)
        {
            if (request.Callback.ResourceType != "sale")
            {
                return(Unit.Value);
            }

            var orderId = request.Callback.Resource.ParentPayment;

            var order = await _db.Orders.FirstOrDefaultAsync(w =>
                                                             w.PaypalId == orderId, cancellationToken);

            if (order == null)
            {
                throw new NotFoundException("PaypalOrderCallback", orderId);
            }

            if (order.Status == OrderStatus.Completed || order.Status == OrderStatus.Processing)
            {
                throw new Exception("Order is already processing or completed.");
            }

            order.Status = OrderStatus.Processing;
            _db.Update(order);
            await _db.SaveChangesAsync(cancellationToken);

            await _mediator.Send(new ProcessPaypalOrderCommand { Order = order }, cancellationToken);

            return(Unit.Value);
        }
        public async Task <int> Handle(UserSignUpCommand request, CancellationToken cancellationToken)
        {
            request = CleanCommand(request);
            await AssertCanRegister(request);

            using (var transaction = await _db.Database.BeginTransactionAsync(cancellationToken))
            {
                var user = new User
                {
                    Username = request.Username,
                    Email    = request.Email,
                    LinkKey  = Guid.NewGuid()
                };

                await _db.Users.AddAsync(user, cancellationToken);

                await _db.SaveChangesAsync(cancellationToken);

                await _mediator.Send(new CognitoSignUpCommand
                {
                    Email    = request.Email,
                    Password = request.Password,
                    Username = request.Username
                }, cancellationToken);

                transaction.Commit();

                return(user.Id);
            }
        }
        public async Task <Unit> Handle(AddScripterInfoCommand request, CancellationToken cancellationToken)
        {
            var gitlabUser = await _gitlab.GetUserById(request.GitlabId);

            var user = await _mediator.Send(new GetUserByIdQuery { Id = request.UserId },
                                            cancellationToken);

            var group = await _gitlab.CreateScripterGroup(user, gitlabUser);

            var info = new ScripterInfo
            {
                DateAdded       = DateTime.UtcNow,
                GitlabGroupPath = $"https://gitlab.com/rspeer-public-sdn/{user.Username}/",
                GitlabUserId    = gitlabUser.Id,
                GitlabUsername  = gitlabUser.Username,
                UserId          = user.Id,
                GitlabGroupId   = group.Id
            };

            await _db.ScripterInfo.AddAsync(info, cancellationToken);

            await _db.SaveChangesAsync(cancellationToken);

            return(Unit.Value);
        }
        public async Task <Unit> Handle(SaveUserJsonDataCommand request, CancellationToken cancellationToken)
        {
            var exists =
                await _db.UserJsonData.FirstOrDefaultAsync(w => w.Key == request.Key && w.UserId == request.UserId,
                                                           cancellationToken);

            var value = JsonSerializer.Serialize(request.Value);

            if (exists != null)
            {
                exists.Value = value;
                _db.UserJsonData.Update(exists);
            }
            else
            {
                exists = new UserJsonData {
                    Key = request.Key, Value = value, UserId = request.UserId
                };
                await _db.UserJsonData.AddAsync(exists, cancellationToken);
            }

            await _db.SaveChangesAsync(cancellationToken);

            await _redis.GetDatabase().StringSetAsync($"user_json_data_{request.Key}_{request.UserId}",
                                                      JsonSerializer.Serialize(exists));

            return(Unit.Value);
        }
Ejemplo n.º 6
0
        public async Task <Unit> Handle(UpdateInuvationUpdaterCommand request, CancellationToken cancellationToken)
        {
            var stream = request.File.OpenReadStream();

            var hash = stream.CalculateHash();

            var file = await _mediator.Send(new PutFileCommand
            {
                Name    = FileHelper.GetFileName(Game.Rs3Updater),
                Stream  = stream,
                Version = request.Version
            }, cancellationToken);

            await _db.Data.AddAsync(new Data
            {
                Key   = $"invuvation-updater:version:hash:{file.Version}",
                Value = hash
            }, cancellationToken);

            await _db.SaveChangesAsync(cancellationToken);

            await _redis.Set("latest_file_version_inuvation-updater.jar", request.Version);

            return(Unit.Value);
        }
        public async Task <Unit> Handle(GenerateDashboardKeyCommand request, CancellationToken cancellationToken)
        {
            var keys = await _db.UserJsonData.Where(w => w.Key == "dashboard_access_key" && w.UserId == request.UserId).ToListAsync(cancellationToken);

            _db.UserJsonData.RemoveRange(keys);
            await _db.SaveChangesAsync(cancellationToken);

            var expiration = DateTimeOffset.UtcNow.AddHours(8);
            var value      = StringExtensions.GetUniqueKey(50);

            var key = new JObject
            {
                { "value", value },
                { "expiration", expiration }
            };

            await _mediator.Send(new SaveUserJsonDataCommand { Key    = "dashboard_access_key",
                                                               UserId = request.UserId, Value = key }, cancellationToken);

            await _mediator.Send(new SendEmailCommand
            {
                FromEmail = "*****@*****.**",
                ToEmail   = request.Email,
                Subject   = "Dashboard Access Key",
                Body      = $"Your access key is {value}"
            }, cancellationToken);

            await _mediator.Send(new SendDiscordWebHookCommand
            {
                Message = "Successfully sent dashboard access key to " + request.Email, Type = DiscordWebHookType.Log
            }, cancellationToken);

            return(Unit.Value);
        }
        public async Task <Unit> Handle(UpdateInuvationCommand request, CancellationToken cancellationToken)
        {
            var enabled = bool.Parse(await _mediator.Send(new GetSiteConfigOrThrowCommand {
                Key = "bot:update:enabled"
            },
                                                          cancellationToken));

            if (!enabled)
            {
                throw new Exception("Bot update is disabled at this time.");
            }

            var stream = request.File.OpenReadStream();

            var hash = stream.CalculateHash();

            var file = await _mediator.Send(new PutFileCommand
            {
                Name    = "inuvation.jar",
                Stream  = stream,
                Version = request.Version
            }, cancellationToken);

            await _db.Data.AddAsync(new Data
            {
                Key   = $"invuvation:version:hash:{file.Version}",
                Value = hash
            }, cancellationToken);

            await _db.SaveChangesAsync(cancellationToken);

            await _redis.Set("latest_file_version_inuvation.jar", request.Version);

            return(Unit.Value);
        }
Ejemplo n.º 9
0
        public async Task <ApiClient> Handle(CreateApiClientCommand request, CancellationToken cancellationToken)
        {
            var exists = await _db.ApiClients.FirstOrDefaultAsync(w => w.UserId == request.User.Id, cancellationToken);

            if (exists != null)
            {
                throw new Exception("You already have an api client.");
            }

            var key = await GenerateKey();

            var client = new ApiClient
            {
                Key       = key,
                UserId    = request.User.Id,
                Timestamp = DateTimeOffset.UtcNow
            };
            await _db.ApiClients.AddAsync(client, cancellationToken);

            await _db.SaveChangesAsync(cancellationToken);

            await _redis.SetJson($"{request.User.Id}_api_client", client);

            await _redis.SetJson($"{key}_api_client_by_key", client);

            return(client);
        }
        public async Task <Unit> Handle(ProcessTokenPurchaseCommand request, CancellationToken cancellationToken)
        {
            var order = await _mediator.Send(new GetOrderByIdQuery { OrderId = request.Order.Id, IsAdmin = true }, cancellationToken);

            if (order == null || order.Status == OrderStatus.Completed)
            {
                throw new NotFoundException("ProcessTokenPurchase_OrderNotFound", request.Order.Id);
            }

            using (var transaction = await _db.Database.BeginTransactionAsync(cancellationToken))
            {
                order.Status = OrderStatus.Completed;
                _db.Orders.Update(order);
                await _db.SaveChangesAsync(cancellationToken);

                await _mediator.Send(
                    new UserUpdateBalanceCommand
                {
                    Amount  = request.Order.Quantity,
                    UserId  = order.UserId,
                    OrderId = order.Id,
                    Type    = AddRemove.Add
                }, cancellationToken);

                transaction.Commit();
                return(Unit.Value);
            }
        }
Ejemplo n.º 11
0
        public override async Task <Unit> Handle(PaypalExecuteOrderCommand request, CancellationToken cancellationToken)
        {
            var order = await _db.Orders.FirstOrDefaultAsync(w => w.PaypalId == request.PaymentId, cancellationToken);

            if (order == null)
            {
                throw new NotFoundException("Paypal Order", request.PaymentId);
            }
            if (order.Status != OrderStatus.Created)
            {
                throw new Exception("Order is already processing or completed.");
            }
            var url  = $"payments/payment/{order.PaypalId}/execute";
            var body = new Dictionary <string, string>
            {
                { "payer_id", request.PayerId }
            };

            await using (var transaction = await _db.Database.BeginTransactionAsync(cancellationToken))
            {
                order.Status = OrderStatus.Processing;
                _db.Orders.Update(order);
                await _db.SaveChangesAsync(cancellationToken);
                await MakeAuthorizedPost(_baseUrl, url, body);

                transaction.Commit();
            }
            return(Unit.Value);
        }
        public async Task <Unit> Handle(UpdateItemDetailsCommand request, CancellationToken cancellationToken)
        {
            var item = await _db.Items.FirstOrDefaultAsync(w => w.Id == request.ItemId, cancellationToken);

            if (item == null)
            {
                throw new NotFoundException("Item", request.ItemId);
            }

            if (!string.IsNullOrEmpty(request.Name))
            {
                item.Name = request.Name;
            }
            if (!string.IsNullOrEmpty(request.Description))
            {
                item.Description = request.Description;
            }
            if (request.Price != default(decimal))
            {
                item.Price = request.Price;
            }

            _db.Items.Update(item);
            await _db.SaveChangesAsync(cancellationToken);

            return(Unit.Value);
        }
        public async Task <Unit> Handle(SetSiteConfigCommand request, CancellationToken cancellationToken)
        {
            var exists = await _db.SiteConfig.FirstOrDefaultAsync(w => w.Key == request.Key, cancellationToken : cancellationToken);

            if (exists != null)
            {
                exists.Value = request.Value;
                _db.SiteConfig.Update(exists);
            }
            else
            {
                var config = new Domain.Entities.SiteConfig
                {
                    Key   = request.Key,
                    Value = request.Value
                };
                await _db.SiteConfig.AddAsync(config, cancellationToken);
            }

            await _db.SaveChangesAsync(cancellationToken);

            await _redis.SetJson($"site_config_{request.Key}", request.Value);

            return(Unit.Value);
        }
        public async Task <Unit> Handle(DeleteScriptCommand request, CancellationToken cancellationToken)
        {
            var script = await _db.Scripts.FirstOrDefaultAsync(w => w.Id == request.ScriptId, cancellationToken);

            if (script == null)
            {
                throw new NotFoundException("Script", request.ScriptId);
            }

            if (script.Status == ScriptStatus.Live)
            {
                await _mediator.Send(new RemovePendingRequestsCommand { ScriptId = script.Id }, cancellationToken);
            }

            _db.Remove(script);

            await _db.Data.AddAsync(new Data
            {
                Key   = $"script:delete:{script.Id}:{script.Name}:by",
                Value = request.Admin.Id.ToString()
            }, cancellationToken);

            await _db.SaveChangesAsync(cancellationToken);

            return(Unit.Value);
        }
Ejemplo n.º 15
0
        public async Task <Unit> Handle(UserUpdateGroupsCommand request, CancellationToken cancellationToken)
        {
            var user = await _db.Users.Where(w => w.Id == request.UserId).Include(w => w.UserGroups)
                       .FirstOrDefaultAsync(cancellationToken);

            if (user == null)
            {
                throw new UserNotFoundException(request.UserId);
            }

            switch (request.Type)
            {
            case AddRemove.Add when user.UserGroups.FirstOrDefault(w => w.GroupId == request.GroupId) != null:
                return(Unit.Value);

            case AddRemove.Remove:
                user.UserGroups.Remove(user.UserGroups.FirstOrDefault(w => w.GroupId == request.GroupId));
                break;

            default:
                user.UserGroups.Add(new UserGroup {
                    GroupId = request.GroupId, UserId = request.UserId
                });
                break;
            }

            await _db.SaveChangesAsync(cancellationToken);

            return(Unit.Value);
        }
Ejemplo n.º 16
0
        public async Task <PurchaseItemResult> Handle(ProcessInstancePurchaseCommand request, CancellationToken cancellationToken)
        {
            var instances = await _mediator.Send(new GetItemBySkuQuery { Sku = "instances" }, cancellationToken);

            if (request.Item.Sku == "unlimitedInstances")
            {
                request.Order.Quantity = 1000000;
                request.Order.ItemId   = instances.Id;
                request.Order.Item     = instances;
            }
            request.Order.Status = OrderStatus.Completed;
            _db.Orders.Update(request.Order);
            await _db.SaveChangesAsync(cancellationToken);

            await _redis.Remove($"{request.Order.UserId}_instances_allowed");

            await _redis.Remove($"{request.Order.UserId}_instances_allowed_no_free");

            await _redis.Remove($"user_{request.Order.UserId}");

            return(new PurchaseItemResult
            {
                IsCreator = false,
                PaymentMethod = PaymentMethod.Tokens,
                Sku = request.Item.Sku,
                Status = OrderStatus.Completed,
                Total = request.Order.Total
            });
        }
Ejemplo n.º 17
0
        public async Task <Unit> Handle(CompleteScripterPayoutCommand request, CancellationToken cancellationToken)
        {
            var orderIds = request.Payout.Orders.Select(w => w.Id).ToList();
            var orders   = await _db.Orders.Where(w => orderIds.Contains(w.Id)).ToListAsync(cancellationToken);

            foreach (var order in orders)
            {
                order.IsPaidOut  = true;
                order.PayoutDate = DateTimeOffset.UtcNow;
                _db.Orders.Update(order);
            }

            await _mediator.Send(new UserUpdateBalanceCommand
            {
                AdminUserId = request.Admin.Id,
                Amount      = request.Payout.TokensToRemove,
                Reason      = "scripter:payout",
                Type        = AddRemove.Remove,
                UserId      = request.Payout.Scripter.Id
            }, cancellationToken);

            await _db.SaveChangesAsync(cancellationToken);

            return(Unit.Value);
        }
Ejemplo n.º 18
0
        public async Task <int> Handle(AddItemCommand request, CancellationToken cancellationToken)
        {
            var exists = await _db.Items.Where(w => w.Sku == request.Sku).FirstOrDefaultAsync(cancellationToken);

            if (exists != null && !request.Upsert)
            {
                throw new Exception("Item by Sku: " + request.Sku + " already exists.");
            }

            var item = new Item
            {
                Description   = request.Description,
                Name          = request.Name,
                Sku           = request.Sku,
                FeesPercent   = request.FeesPercent,
                PaymentMethod = request.PaymentMethod,
                Price         = request.Price
            };

            if (exists != null)
            {
                exists = TinyMapper.Map(item, exists);
                _db.Items.Update(exists);
            }
            else
            {
                await _db.Items.AddAsync(item, cancellationToken);
            }

            await _db.SaveChangesAsync(cancellationToken);

            return(item.Id);
        }
        public async Task Execute()
        {
            var enabled = await _mediator.Send(new IsReadOnlyModeQuery());

            if (enabled)
            {
                return;
            }

            var date    = DateTimeOffset.UtcNow;
            var scripts = await _db.Scripts.ToListAsync();

            foreach (var s in scripts)
            {
                var query = _db.ScriptAccess.Where(w => w.ScriptId == s.Id);
                if (s.Type == ScriptType.Premium)
                {
                    query = query.Where(w => w.Expiration.HasValue && w.Expiration.Value > date);
                }
                var count = await query.CountAsync();

                s.TotalUsers = count;
                _db.Scripts.Update(s);
            }
            await _db.SaveChangesAsync();
        }
        public async Task Execute()
        {
            var expiration = DateTimeOffset.UtcNow.AddMinutes(-5);

            _db.Messages.RemoveRange(_db.Messages.Where(w => w.Timestamp < expiration));
            _db.Launchers.RemoveRange(_db.Launchers.Where(w => w.LastUpdate < expiration));
            await _db.SaveChangesAsync();
        }
        public async Task <Unit> Handle(RemovePendingRequestsCommand request, CancellationToken cancellationToken)
        {
            var pending = await _db.PendingScripts.Where(w => w.LiveScriptId == request.ScriptId)
                          .Select(w => w.PendingScriptId).ToListAsync(cancellationToken: cancellationToken);

            _db.Scripts.RemoveRange(_db.Scripts.Where(w => pending.Contains(w.Id)));
            _db.RemoveRange(_db.PendingScripts.Where(w => pending.Contains(w.PendingScriptId)));
            await _db.SaveChangesAsync(cancellationToken);

            return(Unit.Value);
        }
Ejemplo n.º 22
0
        public async Task <Unit> Handle(RemoveAllScriptAccessCommand request, CancellationToken cancellationToken)
        {
            var script = await _mediator.Send(new GetFullScriptByIdQuery { ScriptId = request.ScriptId }, cancellationToken);

            _db.ScriptAccess.RemoveRange(_db.ScriptAccess.Where(w => w.ScriptId == request.ScriptId));
            script.TotalUsers = 0;
            _db.Scripts.Update(script);
            await _db.SaveChangesAsync(cancellationToken);

            return(Unit.Value);
        }
        public async Task Execute()
        {
            var purchases = _mongo.Database.GetCollection <MongoScriptPurchase>("ScriptPurchases");

            using (var cursor = purchases.AsQueryable().Where(w => true).ToCursor())
            {
                while (await cursor.MoveNextAsync())
                {
                    using (var transaction = await _db.Database.BeginTransactionAsync())
                    {
                        var documents = cursor.Current;
                        await OnBatch(documents.ToList());

                        await _db.SaveChangesAsync();

                        transaction.Commit();
                    }
                }
            }
            await _db.SaveChangesAsync();
        }
        private async Task AssertHasBalance(ProcessTokenOrderCommand request)
        {
            var user = await _db.Users.FirstOrDefaultAsync(w => w.Id == request.User.Id);

            if (user.Balance < request.Order.Total)
            {
                _db.Orders.Remove(request.Order);
                await _db.SaveChangesAsync();

                throw new Exception("Insufficient funds.");
            }
        }
        public async Task <PurchaseItemResult> Handle(ProcessScriptPurchaseCommand request,
                                                      CancellationToken cancellationToken)
        {
            var scriptId = int.Parse(request.Item.Sku.Replace("premium-script-", ""));
            var script   = await _mediator.Send(new GetScriptByIdQuery { ScriptId = scriptId }, cancellationToken);

            var isBuyingOwnScript = request.Order.UserId == script.AuthorId;

            if (!request.Item.FeesPercent.HasValue)
            {
                throw new Exception("Item does not have a fees percent but requires fees.");
            }

            if (script.Disabled)
            {
                throw new Exception("This script is disabled and may not be purchased.");
            }

            if (!isBuyingOwnScript)
            {
                var taken  = request.Order.Total * request.Item.FeesPercent.Value;
                var payout = request.Order.Total - taken;
                await _mediator.Send(new UserUpdateBalanceCommand
                                     { UserId = script.AuthorId, Amount = (int)payout, Type = AddRemove.Add, OrderId = request.Order.Id },
                                     cancellationToken);
            }

            await _db.ScriptAccess.AddAsync(new ScriptAccess
            {
                Expiration = DateTimeOffset.UtcNow.AddDays(30),
                Instances  = script.Instances *request.Order.Quantity,
                OrderId    = request.Order.Id,
                UserId     = request.Order.UserId,
                Timestamp  = DateTimeOffset.UtcNow,
                ScriptId   = script.Id,
                Recurring  = request.Order.Recurring
            }, cancellationToken);

            request.Order.Status = OrderStatus.Completed;
            _db.Orders.Update(request.Order);

            await _db.SaveChangesAsync(cancellationToken);

            return(new PurchaseItemResult
            {
                Status = OrderStatus.Completed,
                PaymentMethod = PaymentMethod.Tokens,
                Sku = request.Item.Sku,
                Total = request.Order.Total,
                IsCreator = isBuyingOwnScript
            });
        }
        public async Task <Unit> Handle(ConfirmScriptCommand request, CancellationToken cancellationToken)
        {
            var pendingScript =
                await _db.Scripts.FirstOrDefaultAsync(s =>
                                                      s.Id == request.ScriptId && s.Status == ScriptStatus.Pending, cancellationToken);

            if (pendingScript == null)
            {
                throw new NotFoundException("PendingScript", request.ScriptId);
            }

            var map = await _db.PendingScripts.FirstOrDefaultAsync(w => w.PendingScriptId == pendingScript.Id,
                                                                   cancellationToken);

            var script =
                await _mediator.Send(new GetScriptByIdQuery { ScriptId = map.LiveScriptId }, cancellationToken);

            TinyMapper.Map(pendingScript, script);

            script.Status = ScriptStatus.Live;

            var oldContent =
                await _db.ScriptContents.FirstOrDefaultAsync(w => w.ScriptId == script.Id, cancellationToken);

            var newContent =
                await _db.ScriptContents.FirstOrDefaultAsync(w => w.ScriptId == pendingScript.Id, cancellationToken);

            newContent.ScriptId = script.Id;

            _db.Scripts.Remove(pendingScript);
            _db.Scripts.Update(script);
            _db.ScriptContents.Update(newContent);
            _db.ScriptContents.Remove(oldContent);
            _db.PendingScripts.Remove(map);

            if (script.Price.HasValue && script.Type == ScriptType.Premium)
            {
                await _mediator.Send(new AddItemCommand
                {
                    Upsert        = true,
                    Description   = script.Description,
                    Name          = script.Name,
                    PaymentMethod = PaymentMethod.Tokens,
                    Price         = script.Price.Value,
                    Sku           = $"premium-script-{script.Id}"
                }, cancellationToken);
            }

            await _db.SaveChangesAsync(cancellationToken);

            return(Unit.Value);
        }
        public async Task <int> Handle(AddGroupCommand request, CancellationToken cancellationToken)
        {
            var group = new Group
            {
                Name        = request.Name,
                Description = request.Description
            };

            _db.Groups.Add(group);
            await _db.SaveChangesAsync(cancellationToken);

            return(group.Id);
        }
Ejemplo n.º 28
0
        public async Task Execute()
        {
            var orders = _mongo.Database.GetCollection <PaypalFinishedOrder>("PaypalFinishedOrders");

            using (var cursor = orders.AsQueryable().Where(w => w.UserId != null).ToCursor())
            {
                while (await cursor.MoveNextAsync())
                {
                    var documents = cursor.Current;
                    await OnBatch(documents);
                }
            }

            await _db.SaveChangesAsync();
        }
        public async Task <Unit> Handle(UserLogCommand request, CancellationToken cancellationToken)
        {
            var log = new UserLog
            {
                Message   = request.Message,
                Timestamp = DateTimeOffset.Now,
                UserId    = request.UserId,
                Type      = request.Type
            };
            await _db.UserLogs.AddAsync(log, cancellationToken);

            await _db.SaveChangesAsync(cancellationToken);

            return(Unit.Value);
        }
        public async Task <Unit> Handle(DeleteApiClientCommand request, CancellationToken cancellationToken)
        {
            var exists = await _db.ApiClients.FirstOrDefaultAsync(w => w.UserId == request.User.Id, cancellationToken);

            if (exists == null)
            {
                return(Unit.Value);
            }
            _db.ApiClients.Remove(exists);
            await _db.SaveChangesAsync(cancellationToken);

            await _redis.Remove($"{request.User.Id}_api_client");

            return(Unit.Value);
        }