add rate limits
All checks were successful
Server Build / publish (push) Successful in 29s
Voice Build / publish (push) Successful in 25s

This commit is contained in:
olcxja 2026-07-04 17:03:56 +02:00
commit c523d40342
4 changed files with 71 additions and 6 deletions

View file

@ -14,6 +14,27 @@ public class Requests
{
public static ConcurrentDictionary<string, CreateHolder> createHolder = new();
public static ConcurrentDictionary<string, (string, DateTimeOffset)> nonceHolder = new();
public static ConcurrentDictionary<string, (int count, DateTime resetTime)> actionRateLimits = new();
public static bool IsActionRateLimited(string id)
{
if (ACTION_RATE_LIMIT <= 0) return false;
var now = DateTime.UtcNow;
actionRateLimits.AddOrUpdate(id,
_ => (1, now.AddMinutes(1)),
(_, old) => {
if (now > old.resetTime) return (1, now.AddMinutes(1));
return (old.count + 1, old.resetTime);
}
);
if (actionRateLimits.TryGetValue(id, out var record) && record.count > ACTION_RATE_LIMIT)
{
return true;
}
return false;
}
public static SemaphoreSlim createLock = new SemaphoreSlim(1, 1);
@ -625,6 +646,20 @@ public static async Task Auth(HttpContext context, Func<Task> next, IQueryCollec
return;
}
string[] actionRequests = {
"user/dm/invite", "user/dm/invite/revoke", "user/dm/invite/decline", "user/dm/create",
"dm/message/send", "dm/message/delete", "dm/message/react", "dm/key/update",
"user/storage/public/update", "user/storage/private/update", "dm/read"
};
if (System.Array.IndexOf(actionRequests, serializedBody.string1) >= 0)
{
if (IsActionRateLimited(id))
{
await context.Response.WriteAsync(Encryption.Encryption.EncryptString("error:rate.limit", password));
return;
}
}
SemaphoreSlim userLock = Utils.GetUserLock(id);
await userLock.WaitAsync();
try
@ -733,6 +768,16 @@ public static async Task Auth(HttpContext context, Func<Task> next, IQueryCollec
await context.Response.WriteAsync(Encryption.Encryption.EncryptString(await Room.Requests.GetDmMessages(id, msgGet.string1, msgGet.string3, msgGet.string2), password));
break;
}
case "dm/read":
{
Universal2String readGet = JsonSerializer.Deserialize(
serializedBody.string2,
AppJsonSerializerContext.Default.Universal2String
);
await Account.Utils.UpdateUserDm(id, readGet.string1, "true", "");
await context.Response.WriteAsync(Encryption.Encryption.EncryptString("success:dm.read", password));
break;
}
case "dm/key/get":
await context.Response.WriteAsync(
Encryption.Encryption.EncryptString(
@ -789,6 +834,12 @@ public static async Task Auth(HttpContext context, Func<Task> next, IQueryCollec
return;
}
if (IsActionRateLimited(id))
{
await context.Response.WriteAsync(Encryption.Encryption.EncryptString("error:rate.limit", password));
return;
}
byte[] bodyBytes = await LarpixServer.Utils.Utils.LoadBodyBytes(context.Request.Body, LarpixServer.Utils.Utils.PUBLIC_STORAGE_LIMIT);
byte[] fileBytes = await Utils.NonceDecryptBytes(id, password, bodyBytes, true);