diff --git a/LarpixServer/Account/Requests.cs b/LarpixServer/Account/Requests.cs index d1c09cb..1fa12e6 100644 --- a/LarpixServer/Account/Requests.cs +++ b/LarpixServer/Account/Requests.cs @@ -504,12 +504,17 @@ public class Requests return; } string id = idQuery.ToString().Split(":")[0]; - + string keysRaw = await Utils.GetUserKeys(id); + if (string.IsNullOrEmpty(keysRaw)) + { + await context.Response.WriteAsync(""); + return; + } Universal2String keys = JsonSerializer.Deserialize( - await Utils.GetUserKeys(id), + keysRaw, AppJsonSerializerContext.Default.Universal2String ); - await context.Response.WriteAsync(keys.string2); + await context.Response.WriteAsync(keys.string2 ?? ""); return; } @@ -631,6 +636,24 @@ public class Requests await Room.Requests.DmCreate(id, serializedBody.string2) , password)); break; + case "dm/key/get": + await context.Response.WriteAsync( + Encryption.Encryption.EncryptString( + await Room.Requests.GetDmKey(id, serializedBody.string2) + , password)); + break; + case "dm/key/update": + { + Universal2String dmKeyUpdate = JsonSerializer.Deserialize( + serializedBody.string2, + AppJsonSerializerContext.Default.Universal2String + ); + await context.Response.WriteAsync( + Encryption.Encryption.EncryptString( + await Room.Requests.UpdateDmKey(id, dmKeyUpdate.string1, dmKeyUpdate.string2) + , password)); + break; + } default: await context.Response.WriteAsync(Encryption.Encryption.EncryptString( $"error:unknown.request:{serializedBody.string1}" diff --git a/LarpixServer/Room/Requests.cs b/LarpixServer/Room/Requests.cs index 0f59eef..910b9c9 100644 --- a/LarpixServer/Room/Requests.cs +++ b/LarpixServer/Room/Requests.cs @@ -10,6 +10,59 @@ namespace LarpixServer.Room; public class Requests { public static SemaphoreSlim createLock = new SemaphoreSlim(1, 1); + private const int MAX_DM_KEY_SIZE = 8192; + + private static bool IsSafeDmId(string dmId) + { + if (string.IsNullOrEmpty(dmId)) return false; + //yk + if (dmId.Contains("..") || dmId.Contains("/") || dmId.Contains("\\")) + { + return false; + } + return true; + } + + private static async Task IsMemberOfDm(string id, string dmId) + { + if (!IsSafeDmId(dmId)) return false; + string memberPath = $"{ROOMS_DIR}/dms/{DOMAIN}/{dmId}/members/{id};{DOMAIN}"; + return Fs.Exists(memberPath); + } + + public static async Task GetDmKey(string id, string dmId) + { + if (!await IsMemberOfDm(id, dmId)) + { + return "error:forbidden"; + } + string path = $"{ROOMS_DIR}/dms/{DOMAIN}/{dmId}/keys/0/{id};{DOMAIN}"; + if (!Fs.Exists(path)) + { + return ""; + } + return Encoding.UTF8.GetString(await Fs.ReadFile(path)); + } + + public static async Task UpdateDmKey(string id, string dmId, string key) + { + if (!await IsMemberOfDm(id, dmId)) + { + return "error:forbidden"; + } + if (key == null || key.Length > MAX_DM_KEY_SIZE) + { + return "error:dm.key.too.large"; + } + string path = $"{ROOMS_DIR}/dms/{DOMAIN}/{dmId}/keys/0/{id};{DOMAIN}"; + if (!Fs.Exists(path)) + { + return "error:dm.key.not.found"; + } + await Fs.WriteFile(path, Encoding.UTF8.GetBytes(key)); + return "success:dm.key.updated"; + } + public static async Task DmInvite(string id, string targetId) { if (!Account.Utils.IsUserLocal(targetId, out string domain)) //federation @@ -166,8 +219,9 @@ public class Requests string dmId = $"{users[0]}_{users[1]}"; - await Fs.WriteFile($"{ROOMS_DIR}/dms/{DOMAIN}/{dmId}/members", - Encoding.UTF8.GetBytes($"{id}:{DOMAIN};{id2}:{domain}")); + Fs.CreateDirectory($"{ROOMS_DIR}/dms/{DOMAIN}/{dmId}/members"); + await Fs.WriteFile($"{ROOMS_DIR}/dms/{DOMAIN}/{dmId}/members/{id};{DOMAIN}", Array.Empty()); + await Fs.WriteFile($"{ROOMS_DIR}/dms/{DOMAIN}/{dmId}/members/{id2};{domain}", Array.Empty()); await Fs.WriteFile($"{ROOMS_DIR}/dms/{DOMAIN}/{dmId}/messages/last", Encoding.UTF8.GetBytes($"0"));