From 7da97dbeb6e376b598d83427cc4469e11511e854 Mon Sep 17 00:00:00 2001 From: olcxja Date: Sun, 10 May 2026 20:55:24 +0200 Subject: [PATCH] Fix user locks & change return strings to blah.blah.blah --- LarpixServer/Account/Requests.cs | 29 +++++++++++-------- LarpixServer/Account/Utils.cs | 20 +++++++------- LarpixServer/Federation/Receiver.cs | 10 +++---- LarpixServer/Program.cs | 1 + LarpixServer/Room/Requests.cs | 43 +++++++++++++++-------------- LarpixServer/Utils/Utils.cs | 2 +- 6 files changed, 56 insertions(+), 49 deletions(-) diff --git a/LarpixServer/Account/Requests.cs b/LarpixServer/Account/Requests.cs index 568e953..b38d7fb 100644 --- a/LarpixServer/Account/Requests.cs +++ b/LarpixServer/Account/Requests.cs @@ -118,7 +118,7 @@ public class Requests ); if (!createHolder.TryGetValue(serializedBody.idKey, out CreateHolder entry)) { - await context.Response.WriteAsync("Account request expired"); + await context.Response.WriteAsync("error:account.creation.request.expired"); return; } @@ -133,13 +133,13 @@ public class Requests if (!Utils.IsValidUsername(entry.name, out string message)) { - await context.Response.WriteAsync("Username: " + message); + await context.Response.WriteAsync($"error:invalid.username.{{{message}}}"); return; } if (!Utils.IsValidPassword(entry.pass, out message)) { - await context.Response.WriteAsync("Password: " + message); + await context.Response.WriteAsync($"error:invalid.password.{{{message}}}"); return; } @@ -162,14 +162,14 @@ public class Requests ); if (!createHolder.TryGetValue(serialized.idKey, out var entry)) { - await context.Response.WriteAsync("Account request expired"); + await context.Response.WriteAsync("error:account.creation.request.expired"); return; } if (entry.captcha.ToLower() != serialized.captcha.ToLower()) { createHolder.TryRemove(serialized.idKey, out _); - await context.Response.WriteAsync("Incorrect captcha. Please try again"); + await context.Response.WriteAsync("error:incorrect.captcha"); return; } @@ -177,7 +177,7 @@ public class Requests if (Fs.Exists($"{ACCOUNTS_NAME_DIR}/{lowerName}")) { - await context.Response.WriteAsync("This username is already taken"); + await context.Response.WriteAsync("error:username.taken"); return; } @@ -185,7 +185,7 @@ public class Requests Encoding.UTF8.GetString(await Fs.ReadFile($"{ACCOUNTS_DIR}/registration")); if (registrationString.StartsWith("0;")) { - await context.Response.WriteAsync("Account creation is currently disabled. Try again later"); + await context.Response.WriteAsync("error:registration.disabled"); return; } @@ -217,7 +217,7 @@ public class Requests if (!valid) { await context.Response.WriteAsync( - "Account creation is currently disabled. Try again later"); + "error:registration.disabled"); return; } } @@ -240,7 +240,7 @@ public class Requests if (id == ulong.MaxValue) { await context.Response.WriteAsync( - "Server is full, cannot create new accounts. Try again later."); + "error:accounts.slots.full"); return; } @@ -264,7 +264,7 @@ public class Requests userLock.Release(); } - await context.Response.WriteAsync("Account created"); + await context.Response.WriteAsync("success:account.created"); return; } } @@ -389,7 +389,7 @@ public class Requests userLock.Release(); } - await context.Response.WriteAsync("Password changed successfully"); + await context.Response.WriteAsync("success:password.changed"); return; } @@ -444,7 +444,7 @@ public class Requests //string publicKey = serializedBody.string1; //string privateEncryptedKey = serializedBody.string2; await Utils.UpdateUserKeys(id, body); - return "Keys updated successfully"; + return "success:keys.updated"; } public static async Task GetUserPublicKey(HttpContext context, Func next, IQueryCollection query, StreamReader bodyReader) @@ -565,6 +565,11 @@ public class Requests await Room.Requests.DmCreate(id, serializedBody.string2) , password)); break; + default: + await context.Response.WriteAsync(Encryption.Encryption.EncryptString( + $"error:unknown.request.{{{serializedBody.string1}}}" + , password)); + break; } } finally diff --git a/LarpixServer/Account/Utils.cs b/LarpixServer/Account/Utils.cs index b62fa43..a418190 100644 --- a/LarpixServer/Account/Utils.cs +++ b/LarpixServer/Account/Utils.cs @@ -13,7 +13,7 @@ public class Utils { private static readonly Regex USERNAME_REGEX = new Regex(@"^[a-zA-Z0-9_]+$"); - public static string LOGIN_SUCCESS = "Login successful"; + public static string LOGIN_SUCCESS = "success:login.successful"; public static ConcurrentDictionary userLocks = new(); public static ConcurrentQueue keyQueue = new(); @@ -58,16 +58,16 @@ public class Utils public static bool IsValidUsername(string username, out string message) { - message = "Username must be 3-18 characters long"; + message = "error:username.length.{3-18}"; if (string.IsNullOrWhiteSpace(username)) return false; if (username.Length is < 3 or > 18) return false; - message = "Only letters, numbers, and underscores allowed"; + message = "error:username.conditions.allowed.{letters,numbers,underscores}"; return USERNAME_REGEX.IsMatch(username); } public static bool IsValidPassword(string password, out string message) { - message = "Password is not hashed properly"; + message = "error:password.not.hashed.properly"; if (password.Length != 128) { return false; @@ -126,11 +126,11 @@ public class Utils { if (!Fs.Exists($"{ACCOUNTS_DATA_DIR}/{id}")) { - return "Invalid username or password"; + return "error:invalid.username.or.password"; } if (password != password2) { - return "Invalid password"; + return "error:invalid.password"; } await UpdateLastLogin(id); @@ -141,7 +141,7 @@ public class Utils { if (!Requests.nonceHolder.TryGetValue(username, out (string, DateTimeOffset) nonce)) { - return "Invalid nonce"; + return "error:invalid.nonce"; } string decBody = Encryption.Encryption.PacketDecPass(body, password, nonce.Item1); if (delEntry) @@ -275,7 +275,7 @@ public class Utils { if (!Fs.Exists($"{ACCOUNTS_DATA_DIR}/{id}/secret")) { - return "Account does not exist"; + return "error:account.not.exist"; } if (!IsValidUsername(newName, out string message)) @@ -290,13 +290,13 @@ public class Utils { if (Fs.Exists($"{ACCOUNTS_NAME_DIR}/{lowerNewName}")) { - return "This username is already taken"; + return "error:username.taken"; } Fs.MoveFile($"{ACCOUNTS_NAME_DIR}/{lowerOldName}", $"{ACCOUNTS_NAME_DIR}/{lowerNewName}"); } await Fs.WriteFile($"{ACCOUNTS_DATA_DIR}/{id}/username", Encoding.UTF8.GetBytes(newName)); - return "Username changed successfully"; + return "success:username.changed"; } } \ No newline at end of file diff --git a/LarpixServer/Federation/Receiver.cs b/LarpixServer/Federation/Receiver.cs index fc036b9..f555baf 100644 --- a/LarpixServer/Federation/Receiver.cs +++ b/LarpixServer/Federation/Receiver.cs @@ -32,7 +32,7 @@ public class Receiver if (!await Sender.HasSentDmInvite(ids[1], domain, ids[0])) { - await context.Response.WriteAsync( "Bad request" ); + await context.Response.WriteAsync( "error:bad.request" ); return; } @@ -43,7 +43,7 @@ public class Receiver string inviteFile = ACCOUNTS_DATA_DIR + $"/{ids[0]}/dminvites/recv/{ids[1]};{domain}"; if (Fs.Exists(inviteFile)) { - await context.Response.WriteAsync("User already invited"); + await context.Response.WriteAsync("info:user.already.invited"); return; } await Fs.WriteFile(inviteFile, Encoding.UTF8.GetBytes("0")); @@ -54,7 +54,7 @@ public class Receiver userLock.Release(); } - await context.Response.WriteAsync("User invited"); + await context.Response.WriteAsync("success:user.invited"); return; case "dm/invite/hassent": @@ -77,7 +77,7 @@ public class Receiver inviteSentFile = ACCOUNTS_DATA_DIR + $"/{ids[0]}/dminvites/sent/{ids[1]};{domain}"; if (!Fs.Exists(inviteSentFile)) { - await context.Response.WriteAsync( "Failed to add. No invite found" ); + await context.Response.WriteAsync( "error:no.invite.found" ); return; } Fs.DeleteFile(inviteSentFile); @@ -99,7 +99,7 @@ public class Receiver DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString()); - await context.Response.WriteAsync("DM accepted"); + await context.Response.WriteAsync("success:dm.accepted"); return; } diff --git a/LarpixServer/Program.cs b/LarpixServer/Program.cs index 7bc9d38..31f4a05 100644 --- a/LarpixServer/Program.cs +++ b/LarpixServer/Program.cs @@ -184,6 +184,7 @@ public class Program } catch (Exception ex) { + await context.Response.WriteAsync($"error:unknown.error"); Console.WriteLine(ex); } diff --git a/LarpixServer/Room/Requests.cs b/LarpixServer/Room/Requests.cs index 18b2c31..372dc0b 100644 --- a/LarpixServer/Room/Requests.cs +++ b/LarpixServer/Room/Requests.cs @@ -14,23 +14,24 @@ public class Requests { if (!Account.Utils.IsUserLocal(username2, out string domain)) //federation { - SemaphoreSlim userLock = Account.Utils.GetUserLock(id); - await userLock.WaitAsync(); - try - { - username2 = username2.Split(":")[0]; - string remoteId2 = await Federation.Sender.GetUserId(username2, domain); - await Fs.WriteFile(ACCOUNTS_DATA_DIR + $"/{id}/dminvites/sent/{remoteId2};{domain}", []); //only save sent while federating - return await Federation.Sender.DmInvite(id, domain, remoteId2); - } - finally - { - userLock.Release(); - } + + username2 = username2.Split(":")[0]; + string remoteId2 = await Federation.Sender.GetUserId(username2, domain); + await Fs.WriteFile(ACCOUNTS_DATA_DIR + $"/{id}/dminvites/sent/{remoteId2};{domain}", []); //only save sent while federating + return await Federation.Sender.DmInvite(id, domain, remoteId2); + } username2 = username2.Split(":")[0]; string id2 = await Account.Utils.IdFromName(username2); - + if (id2 == "0") + { + return "error:user.not.found"; + } + + if (id2 == id) + { + return "error:cant.invite.urself"; + } SemaphoreSlim userLock2 = Account.Utils.GetUserLock(id2); await userLock2.WaitAsync(); @@ -39,7 +40,7 @@ public class Requests string inviteFile = ACCOUNTS_DATA_DIR + $"/{id2}/dminvites/recv/{id};{DOMAIN}"; if (Fs.Exists(inviteFile)) { - return "User already invited"; + return "info:user.already.invited"; } await Fs.WriteFile(inviteFile, Encoding.UTF8.GetBytes("0")); @@ -52,7 +53,7 @@ public class Requests userLock2.Release(); } - return "User invited"; + return "success:user.invited"; } public static async Task DmCreate(string id, string body) @@ -93,7 +94,7 @@ public class Requests { if (!await Federation.Sender.HasSentDmInvite(id2, domain, id)) { - return "You can't create a DM without an invitation"; + return "error:cant.create.dm.without.invitation"; } } @@ -123,7 +124,7 @@ public class Requests startingMessage.timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString(); startingMessage.type = "larp.info"; startingMessage.content = - "At the beginning of a DM, you should always verify that the person you're talking to is the intended recipient"; + "dm.begin.notice"; startingMessage.key = ""; //no key == NOT encrypted startingMessage.pervious = ""; @@ -169,10 +170,10 @@ public class Requests catch (Exception e) { - return "Failed to accept DM. Ask for another invite"; + return "error:failed.accept.dm"; } - return "DM accepted"; + return "success:dm.accepted"; } @@ -181,6 +182,6 @@ public class Requests { createLock.Release(); } - return "You can't create a DM without an invitation"; + return "error:cant.create.dm.without.invitation"; } } \ No newline at end of file diff --git a/LarpixServer/Utils/Utils.cs b/LarpixServer/Utils/Utils.cs index e1a68b5..38929b0 100644 --- a/LarpixServer/Utils/Utils.cs +++ b/LarpixServer/Utils/Utils.cs @@ -109,7 +109,7 @@ public class Utils totalRead += read; if (totalRead > MAX_BODY_SIZE) - throw new Exception("Body too large"); + throw new Exception("error:body.too.large"); bodyBuilder.Append(buffer, 0, read); }