New DM creation concept, hope it works
This commit is contained in:
parent
8de0e0cacb
commit
c58d3dbcdf
5 changed files with 292 additions and 171 deletions
|
|
@ -1,6 +1,124 @@
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.Json;
|
||||||
|
using LarpixServer.Filesystem;
|
||||||
|
using LarpixServer.Utils.Jsons;
|
||||||
|
|
||||||
|
using static LarpixServer.Utils.Utils;
|
||||||
|
|
||||||
namespace LarpixServer.Federation;
|
namespace LarpixServer.Federation;
|
||||||
|
|
||||||
public class Receiver
|
public class Receiver
|
||||||
{
|
{
|
||||||
|
public static async Task FederationRequest(HttpContext context, Func<Task> next, IQueryCollection query, StreamReader bodyReader)
|
||||||
|
{
|
||||||
|
if (!query.TryGetValue("d", out var domain))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string body = await LoadBody(bodyReader);
|
||||||
|
Universal2String serializedBody = JsonSerializer.Deserialize(
|
||||||
|
body,
|
||||||
|
AppJsonSerializerContext.Default.Universal2String
|
||||||
|
);
|
||||||
|
|
||||||
|
switch (serializedBody.string1)
|
||||||
|
{
|
||||||
|
case "user/id/get":
|
||||||
|
await context.Response.WriteAsync( await Account.Utils.IdFromName(serializedBody.string2) );
|
||||||
|
return;
|
||||||
|
case "dm/invite/send":
|
||||||
|
string[] ids = serializedBody.string2.Split(','); //0=receiver, 1=sender
|
||||||
|
|
||||||
|
if (!await Sender.HasSentDmInvite(ids[1], domain, ids[0]))
|
||||||
|
{
|
||||||
|
await context.Response.WriteAsync( "Bad request" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SemaphoreSlim userLock = Account.Utils.GetUserLock(ids[0]);
|
||||||
|
await userLock.WaitAsync();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string inviteFile = ACCOUNTS_DATA_DIR + $"/{ids[0]}/dminvites/recv/{ids[1]};{domain}";
|
||||||
|
if (Fs.Exists(inviteFile))
|
||||||
|
{
|
||||||
|
await context.Response.WriteAsync("User already invited");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await Fs.WriteFile(inviteFile, Encoding.UTF8.GetBytes("0"));
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
|
||||||
|
userLock.Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
await context.Response.WriteAsync("User invited");
|
||||||
|
|
||||||
|
return;
|
||||||
|
case "dm/invite/hassent":
|
||||||
|
ids = serializedBody.string2.Split(','); //0=sender, 1=receiver
|
||||||
|
|
||||||
|
string inviteSentFile = ACCOUNTS_DATA_DIR + $"/{ids[0]}/dminvites/sent/{ids[1]};{domain}";
|
||||||
|
if (!Fs.Exists(inviteSentFile))
|
||||||
|
{
|
||||||
|
await context.Response.WriteAsync( "false" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await context.Response.WriteAsync( "true" );
|
||||||
|
return;
|
||||||
|
case "dm/add":
|
||||||
|
ids = serializedBody.string2.Split(','); //0=creator (inv receiver), 1=inviter
|
||||||
|
|
||||||
|
|
||||||
|
//did i really sent an invite to this user???? idkkk maybeeeee yeahhh i did this
|
||||||
|
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" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Fs.DeleteFile(inviteSentFile);
|
||||||
|
//now full invite is deleted :333333333333333333333333333
|
||||||
|
//we need to add to dm :33333333333333333333
|
||||||
|
|
||||||
|
|
||||||
|
userLock = Account.Utils.GetUserLock(ids[0]);
|
||||||
|
await userLock.WaitAsync();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//best dmId creation ever
|
||||||
|
List<string> users = new List<string>(){$"{ids[0]};{DOMAIN}", $"{ids[1]};{domain}"};
|
||||||
|
users.Sort();
|
||||||
|
string dmId = $"{users[0]}_{users[1]}";
|
||||||
|
|
||||||
|
string dms2path = $"{ACCOUNTS_DATA_DIR}/{ids[0]}/dms";
|
||||||
|
string dms2;
|
||||||
|
if (await Account.Utils.NameFromId(ids[0]) == "") //if user account just got deleted
|
||||||
|
{
|
||||||
|
await context.Response.WriteAsync("DM accepted");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!Fs.Exists(dms2path))
|
||||||
|
{
|
||||||
|
dms2 = "";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dms2 = Encoding.UTF8.GetString(await Fs.ReadFile(dms2path));
|
||||||
|
}
|
||||||
|
|
||||||
|
await Fs.WriteFile(dms2path, Encoding.UTF8.GetBytes($"{dmId};{dms2}"));
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
userLock.Release();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,24 +1,52 @@
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.Json;
|
||||||
|
using LarpixServer.Utils.Jsons;
|
||||||
|
|
||||||
|
using static LarpixServer.Utils.Utils;
|
||||||
|
|
||||||
namespace LarpixServer.Federation;
|
namespace LarpixServer.Federation;
|
||||||
|
|
||||||
public class Sender
|
public class Sender
|
||||||
{
|
{
|
||||||
|
public static async Task<string> FederationRequest(string endpoint, string value, string domain)
|
||||||
|
{
|
||||||
|
HttpClient client = new HttpClient();
|
||||||
|
|
||||||
|
Universal2String universal = new Universal2String();
|
||||||
|
universal.string1 = endpoint;
|
||||||
|
universal.string2 = value;
|
||||||
|
|
||||||
|
string body = JsonSerializer.Serialize(
|
||||||
|
universal,
|
||||||
|
AppJsonSerializerContext.Default.Universal2String
|
||||||
|
);
|
||||||
|
|
||||||
|
var content = new StringContent(body, Encoding.UTF8, "text/plain");
|
||||||
|
|
||||||
|
return (await client.PostAsync($"http://{domain}/_larpix/federation?d={DOMAIN}", content)).Content.ReadAsStringAsync().Result;
|
||||||
|
}
|
||||||
|
|
||||||
public static async Task<string> GetUserId(string username, string domain)
|
public static async Task<string> GetUserId(string username, string domain)
|
||||||
{
|
{
|
||||||
return "?";
|
return await FederationRequest("user/id/get", username, domain);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<bool> HasSentDmInvite(string senderId, string domain, string receiverId) //receiver is always from local domain
|
public static async Task<bool> HasSentDmInvite(string senderId, string domain, string receiverId) //receiver is always from local domain
|
||||||
{
|
{
|
||||||
return true;
|
if (await FederationRequest("dm/invite/hassent", $"{senderId},{receiverId}", domain) == "true")
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task CreateDm(string id, string domain, string dmId)
|
public static async Task<string> AddToDm(string receiverId, string domain, string senderId) //receiver is always from local domain
|
||||||
{
|
{
|
||||||
|
return await FederationRequest("dm/add", $"{receiverId},{senderId}", domain);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<string> DmInvite(string senderId, string domain, string receiverId) //sender is always from local domain
|
public static async Task<string> DmInvite(string senderId, string domain, string receiverId) //sender is always from local domain
|
||||||
{
|
{
|
||||||
return "User invited";
|
return await FederationRequest("dm/invite/send", $"{receiverId},{senderId}", domain);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -82,7 +82,7 @@ public class Program
|
||||||
|
|
||||||
switch (path)
|
switch (path)
|
||||||
{
|
{
|
||||||
case "/restart":
|
case "/_larpix/restart":
|
||||||
if (!query.TryGetValue("skey", out var skey))
|
if (!query.TryGetValue("skey", out var skey))
|
||||||
{
|
{
|
||||||
context.Response.ContentType = mimeTypes["html"];
|
context.Response.ContentType = mimeTypes["html"];
|
||||||
|
|
@ -113,7 +113,7 @@ public class Program
|
||||||
var lifetime = context.RequestServices.GetRequiredService<IHostApplicationLifetime>();
|
var lifetime = context.RequestServices.GetRequiredService<IHostApplicationLifetime>();
|
||||||
lifetime.StopApplication();
|
lifetime.StopApplication();
|
||||||
return;
|
return;
|
||||||
case "/clearcache": //kiedys bedzie endpoint cache
|
case "/_larpix/clearcache": //kiedys bedzie endpoint cache
|
||||||
if (!query.TryGetValue("skey", out skey))
|
if (!query.TryGetValue("skey", out skey))
|
||||||
{
|
{
|
||||||
context.Response.ContentType = mimeTypes["html"];
|
context.Response.ContentType = mimeTypes["html"];
|
||||||
|
|
@ -135,34 +135,37 @@ public class Program
|
||||||
ulong removed = Fs.ClearCache(p);
|
ulong removed = Fs.ClearCache(p);
|
||||||
await context.Response.WriteAsync($"Cache cleared with pattern: {p}. {removed} elements removed");
|
await context.Response.WriteAsync($"Cache cleared with pattern: {p}. {removed} elements removed");
|
||||||
return;
|
return;
|
||||||
case "/createaccount":
|
case "/_larpix/createaccount":
|
||||||
await Account.Requests.Create(context, next, query, reader);
|
await Account.Requests.Create(context, next, query, reader);
|
||||||
return;
|
return;
|
||||||
case "/deleteaccount":
|
case "/_larpix/deleteaccount":
|
||||||
await Account.Requests.Delete(context, next, query, reader);
|
await Account.Requests.Delete(context, next, query, reader);
|
||||||
return;
|
return;
|
||||||
case "/auth":
|
case "/_larpix/auth":
|
||||||
await Account.Requests.Auth(context, next, query, reader);
|
await Account.Requests.Auth(context, next, query, reader);
|
||||||
return;
|
return;
|
||||||
case "/chpass":
|
case "/_larpix/chpass":
|
||||||
await Account.Requests.ChangePassword(context, next, query, reader);
|
await Account.Requests.ChangePassword(context, next, query, reader);
|
||||||
return;
|
return;
|
||||||
case "/chname":
|
case "/_larpix/chname":
|
||||||
await Account.Requests.ChangeUsername(context, next, query, reader);
|
await Account.Requests.ChangeUsername(context, next, query, reader);
|
||||||
return;
|
return;
|
||||||
case "/correctedname":
|
case "/_larpix/correctedname":
|
||||||
await Account.Requests.CorrectedName(context, next, query);
|
await Account.Requests.CorrectedName(context, next, query);
|
||||||
return;
|
return;
|
||||||
case "/nextnonce":
|
case "/_larpix/nextnonce":
|
||||||
await Account.Requests.NextNonce(context, next, query);
|
await Account.Requests.NextNonce(context, next, query);
|
||||||
return;
|
return;
|
||||||
case "/encryptedrequest":
|
case "/_larpix/encryptedrequest":
|
||||||
await Account.Requests.EncryptedRequest(context, next, query, reader);
|
await Account.Requests.EncryptedRequest(context, next, query, reader);
|
||||||
return;
|
return;
|
||||||
case "/user/key/getpublic":
|
case "/_larpix/federation":
|
||||||
|
await Federation.Receiver.FederationRequest(context, next, query, reader);
|
||||||
|
return;
|
||||||
|
case "/_larpix/user/key/getpublic":
|
||||||
await Account.Requests.GetUserPublicKey(context, next, query, reader);
|
await Account.Requests.GetUserPublicKey(context, next, query, reader);
|
||||||
return;
|
return;
|
||||||
case "/user/storage/public/getentry":
|
case "/_larpix/user/storage/public/getentry":
|
||||||
await Account.Requests.GetUserPublicStorageEntry(context, next, query, reader);
|
await Account.Requests.GetUserPublicStorageEntry(context, next, query, reader);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,43 +14,42 @@ public class Requests
|
||||||
{
|
{
|
||||||
if (!Account.Utils.IsUserLocal(username2, out string domain)) //federation
|
if (!Account.Utils.IsUserLocal(username2, out string domain)) //federation
|
||||||
{
|
{
|
||||||
username2 = username2.Split(":")[0];
|
SemaphoreSlim userLock = Account.Utils.GetUserLock(id);
|
||||||
string remoteId2 = await Federation.Sender.GetUserId(username2, domain);
|
await userLock.WaitAsync();
|
||||||
await Fs.WriteFile(ACCOUNTS_DATA_DIR + $"/{id}/dminvites/sent/{remoteId2};{domain}", []);
|
try
|
||||||
return await Federation.Sender.DmInvite(id, domain, remoteId2);
|
{
|
||||||
|
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];
|
username2 = username2.Split(":")[0];
|
||||||
string id2 = await Account.Utils.IdFromName(username2);
|
string id2 = await Account.Utils.IdFromName(username2);
|
||||||
|
|
||||||
SemaphoreSlim userLock2 = Account.Utils.GetUserLock(id2);
|
SemaphoreSlim userLock2 = Account.Utils.GetUserLock(id2);
|
||||||
await userLock2.WaitAsync();
|
await userLock2.WaitAsync();
|
||||||
SemaphoreSlim userLock = Account.Utils.GetUserLock(id);
|
|
||||||
await userLock.WaitAsync();
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string inviteSentFile = ACCOUNTS_DATA_DIR + $"/{id}/dminvites/sent/{id2};{domain}";
|
|
||||||
string inviteFile = ACCOUNTS_DATA_DIR + $"/{id2}/dminvites/recv/{id};{DOMAIN}";
|
string inviteFile = ACCOUNTS_DATA_DIR + $"/{id2}/dminvites/recv/{id};{DOMAIN}";
|
||||||
if (Fs.Exists(inviteFile))
|
if (Fs.Exists(inviteFile))
|
||||||
{
|
{
|
||||||
string inviteState = Encoding.UTF8.GetString(await Fs.ReadFile(inviteFile));
|
return "User already invited";
|
||||||
switch (inviteState)
|
|
||||||
{
|
|
||||||
case "0": //invited
|
|
||||||
await Fs.WriteFile(inviteSentFile, []); //just in case
|
|
||||||
return "User already invited";
|
|
||||||
case "1": //accepted
|
|
||||||
return "You already have a DM with this user";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await Fs.WriteFile(inviteFile, Encoding.UTF8.GetBytes("0"));
|
await Fs.WriteFile(inviteFile, Encoding.UTF8.GetBytes("0"));
|
||||||
await Fs.WriteFile(inviteSentFile, []); //we should also save that this user invited someone, because this will act as dm accept verification while federating
|
|
||||||
|
//im not saving this like ts is litterally local scenario
|
||||||
|
//await Fs.WriteFile(inviteSentFile, []); //we should also save that this user invited someone, because this will act as dm accept verification while federating
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
userLock2.Release();
|
userLock2.Release();
|
||||||
userLock.Release();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return "User invited";
|
return "User invited";
|
||||||
|
|
@ -81,14 +80,16 @@ public class Requests
|
||||||
|
|
||||||
if (isUserLocal)
|
if (isUserLocal)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
string inviteSentFile = ACCOUNTS_DATA_DIR + $"/{id2}/dminvites/sent/{id};{DOMAIN}";
|
string inviteSentFile = ACCOUNTS_DATA_DIR + $"/{id2}/dminvites/sent/{id};{DOMAIN}";
|
||||||
if (!Fs.Exists(inviteSentFile))
|
if (!Fs.Exists(inviteSentFile))
|
||||||
{
|
{
|
||||||
return "You can't create a DM without an invitation";
|
return "You can't create a DM without an invitation";
|
||||||
}
|
}
|
||||||
Fs.DeleteFile(inviteSentFile);
|
Fs.DeleteFile(inviteSentFile);
|
||||||
|
*/ // local scenario, there is no need to check sent
|
||||||
}
|
}
|
||||||
else //also check this on federated server
|
else //check sent on federated server
|
||||||
{
|
{
|
||||||
if (!await Federation.Sender.HasSentDmInvite(id2, domain, id))
|
if (!await Federation.Sender.HasSentDmInvite(id2, domain, id))
|
||||||
{
|
{
|
||||||
|
|
@ -99,144 +100,123 @@ public class Requests
|
||||||
string inviteFile = ACCOUNTS_DATA_DIR + $"/{id}/dminvites/recv/{id2};{domain}";
|
string inviteFile = ACCOUNTS_DATA_DIR + $"/{id}/dminvites/recv/{id2};{domain}";
|
||||||
if (Fs.Exists(inviteFile))
|
if (Fs.Exists(inviteFile))
|
||||||
{
|
{
|
||||||
string inviteState = Encoding.UTF8.GetString(await Fs.ReadFile(inviteFile));
|
|
||||||
switch (inviteState)
|
List<(string file, string todo, string content)> restoreList = new();
|
||||||
|
|
||||||
|
try //try because federation is involved, if it fails we should just clean all written files
|
||||||
{
|
{
|
||||||
case "0": //invited
|
Fs.DeleteFile(inviteFile); //remove invite bc now its accepted (error = no invite & no dm)
|
||||||
|
|
||||||
|
|
||||||
|
//best dmId creation ever
|
||||||
|
List<string> users = new List<string>(){$"{id};{DOMAIN}", $"{id2};{domain}"};
|
||||||
|
users.Sort();
|
||||||
|
string dmId = $"{users[0]}_{users[1]}";
|
||||||
|
|
||||||
|
|
||||||
List<(string file, string todo, string content)> restoreList = new();
|
await Fs.WriteFile($"{ROOMS_DIR}/dms/{DOMAIN}/{dmId}/members",
|
||||||
try //try because federation is involved, if it fails we should just clean all written files
|
Encoding.UTF8.GetBytes($"{id}:{DOMAIN};{id2}:{domain}"));
|
||||||
|
await Fs.WriteFile($"{ROOMS_DIR}/dms/{DOMAIN}/{dmId}/messages/last", Encoding.UTF8.GetBytes($"0"));
|
||||||
|
|
||||||
|
|
||||||
|
Message startingMessage = new();
|
||||||
|
startingMessage.attachment = "";
|
||||||
|
startingMessage.author = "0";
|
||||||
|
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";
|
||||||
|
startingMessage.key = ""; //no key == NOT encrypted
|
||||||
|
startingMessage.pervious = "";
|
||||||
|
|
||||||
|
await Fs.WriteFile($"{ROOMS_DIR}/dms/{DOMAIN}/{dmId}/keys/0/{id};{DOMAIN}", //klucz dla uzytkownika tworzącego jest juz gotowy i ma zwykly zapis
|
||||||
|
Encoding.UTF8.GetBytes(serializedBody.string2));
|
||||||
|
|
||||||
|
|
||||||
|
Universal2String keys = JsonSerializer.Deserialize(
|
||||||
|
await Account.Utils.GetUserKeys(id),
|
||||||
|
AppJsonSerializerContext.Default.Universal2String
|
||||||
|
);
|
||||||
|
await Fs.WriteFile($"{ROOMS_DIR}/dms/{DOMAIN}/{dmId}/keys/0/{id2};{domain}",
|
||||||
|
Encoding.UTF8.GetBytes($"SETUP:{keys.string2};{serializedBody.string3}")); //jezeli mamy setup to [1] to jest publiczny klucz drugiej osoby,
|
||||||
|
//a string 3 to zaszyfrowany klucz pokoju ktory musi odszyfrowac za pomoca swoich kluczy i tego publicznego
|
||||||
|
|
||||||
|
await Fs.WriteFile($"{ROOMS_DIR}/dms/{DOMAIN}/{dmId}/messages/0", Encoding.UTF8.GetBytes(
|
||||||
|
JsonSerializer.Serialize(startingMessage, AppJsonSerializerContext.Default.Message)
|
||||||
|
));
|
||||||
|
|
||||||
|
restoreList.Add(($"{ROOMS_DIR}/dms/{DOMAIN}/{dmId}", "deletef", ""));
|
||||||
|
|
||||||
|
string dmspath = $"{ACCOUNTS_DATA_DIR}/{id}/dms";
|
||||||
|
string dms;
|
||||||
|
if (!Fs.Exists(dmspath))
|
||||||
|
{
|
||||||
|
dms = "";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dms = Encoding.UTF8.GetString(await Fs.ReadFile(dmspath));
|
||||||
|
}
|
||||||
|
restoreList.Add((dmspath, "write", dms));
|
||||||
|
await Fs.WriteFile(dmspath, Encoding.UTF8.GetBytes($"{dmId};{dms}"));
|
||||||
|
|
||||||
|
if (isUserLocal)
|
||||||
|
{
|
||||||
|
SemaphoreSlim userLock = Account.Utils.GetUserLock(id2);
|
||||||
|
await userLock.WaitAsync();
|
||||||
|
try
|
||||||
{
|
{
|
||||||
restoreList.Add((inviteFile, "delete", ""));
|
string dms2path = $"{ACCOUNTS_DATA_DIR}/{id2}/dms";
|
||||||
await Fs.WriteFile(inviteFile, Encoding.UTF8.GetBytes("1")); //we are setting this to 1,
|
string dms2;
|
||||||
//so now we should have an option to delete id from dmslist and still search it
|
if (await Account.Utils.NameFromId(id2) == "") //if user2 account just got deleted
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BigInteger dmId =
|
|
||||||
BigInteger.Parse(Encoding.UTF8.GetString(await Fs.ReadFile($"{ROOMS_DIR}/lastdm")));
|
|
||||||
dmId++;
|
|
||||||
var freeid =
|
|
||||||
Path.GetFileName(Directory.EnumerateFiles(ROOMS_DIR + "/freedms").FirstOrDefault());
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (freeid != null)
|
|
||||||
{
|
{
|
||||||
dmId = BigInteger.Parse(freeid);
|
return "DM accepted";
|
||||||
Fs.DeleteFile($"{ROOMS_DIR}/freedms/{freeid}");
|
}
|
||||||
restoreList.Add(($"{ROOMS_DIR}/freedms/{freeid}", "write", ""));
|
if (!Fs.Exists(dms2path))
|
||||||
|
{
|
||||||
|
dms2 = "";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
restoreList.Add(($"{ROOMS_DIR}/lastdm", "write", Encoding.UTF8.GetString(await Fs.ReadFile($"{ROOMS_DIR}/lastdm"))));
|
dms2 = Encoding.UTF8.GetString(await Fs.ReadFile(dms2path));
|
||||||
await Fs.WriteFile($"{ROOMS_DIR}/lastdm", Encoding.UTF8.GetBytes(dmId.ToString()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await Fs.WriteFile($"{ROOMS_DIR}/dms/{DOMAIN}/{dmId}/members",
|
await Fs.WriteFile(dms2path, Encoding.UTF8.GetBytes($"{dmId};{dms2}"));
|
||||||
Encoding.UTF8.GetBytes($"{id}:{DOMAIN};{id2}:{domain}"));
|
|
||||||
await Fs.WriteFile($"{ROOMS_DIR}/dms/{DOMAIN}/{dmId}/messages/last", Encoding.UTF8.GetBytes($"0"));
|
|
||||||
|
|
||||||
|
|
||||||
Message startingMessage = new();
|
|
||||||
startingMessage.attachment = "";
|
|
||||||
startingMessage.author = "0";
|
|
||||||
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";
|
|
||||||
startingMessage.key = ""; //no key == NOT encrypted
|
|
||||||
startingMessage.pervious = "";
|
|
||||||
|
|
||||||
await Fs.WriteFile($"{ROOMS_DIR}/dms/{DOMAIN}/{dmId}/keys/0/{id};{DOMAIN}", //klucz dla uzytkownika tworzącego jest juz gotowy i ma zwykly zapis
|
|
||||||
Encoding.UTF8.GetBytes(serializedBody.string2));
|
|
||||||
|
|
||||||
|
|
||||||
Universal2String keys = JsonSerializer.Deserialize(
|
|
||||||
await Account.Utils.GetUserKeys(id),
|
|
||||||
AppJsonSerializerContext.Default.Universal2String
|
|
||||||
);
|
|
||||||
await Fs.WriteFile($"{ROOMS_DIR}/dms/{DOMAIN}/{dmId}/keys/0/{id2};{domain}",
|
|
||||||
Encoding.UTF8.GetBytes($"SETUP:{keys.string2};{serializedBody.string3}")); //jezeli mamy setup to [1] to jest publiczny klucz drugiej osoby,
|
|
||||||
//a string 3 to zaszyfrowany klucz pokoju ktory musi odszyfrowac za pomoca swoich kluczy i tego publicznego
|
|
||||||
|
|
||||||
await Fs.WriteFile($"{ROOMS_DIR}/dms/{DOMAIN}/{dmId}/messages/0", Encoding.UTF8.GetBytes(
|
|
||||||
JsonSerializer.Serialize(startingMessage, AppJsonSerializerContext.Default.Message)
|
|
||||||
));
|
|
||||||
|
|
||||||
restoreList.Add(($"{ROOMS_DIR}/dms/{DOMAIN}/{dmId}", "deletef", ""));
|
|
||||||
|
|
||||||
string dmspath = $"{ACCOUNTS_DATA_DIR}/{id}/dms";
|
|
||||||
string dms;
|
|
||||||
if (!Fs.Exists(dmspath))
|
|
||||||
{
|
|
||||||
dms = "";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dms = Encoding.UTF8.GetString(await Fs.ReadFile(dmspath));
|
|
||||||
}
|
|
||||||
restoreList.Add((dmspath, "write", dms));
|
|
||||||
await Fs.WriteFile(dmspath, Encoding.UTF8.GetBytes($"{dmId};{dms}"));
|
|
||||||
|
|
||||||
if (isUserLocal)
|
|
||||||
{
|
|
||||||
SemaphoreSlim userLock = Account.Utils.GetUserLock(id2);
|
|
||||||
await userLock.WaitAsync();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
string dms2path = $"{ACCOUNTS_DATA_DIR}/{id2}/dms";
|
|
||||||
string dms2;
|
|
||||||
if (await Account.Utils.NameFromId(id2) == "") //if user2 account just got deleted
|
|
||||||
{
|
|
||||||
return "DM accepted";
|
|
||||||
}
|
|
||||||
if (!Fs.Exists(dms2path))
|
|
||||||
{
|
|
||||||
dms2 = "";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dms2 = Encoding.UTF8.GetString(await Fs.ReadFile(dms2path));
|
|
||||||
}
|
|
||||||
|
|
||||||
await Fs.WriteFile(dms2path, Encoding.UTF8.GetBytes($"{dmId};{dms2}"));
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
userLock.Release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else //federacja
|
|
||||||
{
|
|
||||||
await Federation.Sender.CreateDm(id2, domain, dmId.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
finally
|
||||||
{
|
{
|
||||||
foreach (var entry in restoreList)
|
userLock.Release();
|
||||||
{
|
|
||||||
if (entry.todo == "delete")
|
|
||||||
{
|
|
||||||
Fs.DeleteFile(entry.file);
|
|
||||||
}
|
|
||||||
if (entry.todo == "deletef")
|
|
||||||
{
|
|
||||||
Fs.DeleteDirectory(entry.file);
|
|
||||||
}
|
|
||||||
if (entry.todo == "write")
|
|
||||||
{
|
|
||||||
await Fs.WriteFile(entry.file, Encoding.UTF8.GetBytes(entry.content));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "Failed to accept DM. Ask for another invite";
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return "DM accepted";
|
else //federacja
|
||||||
case "1": //accepted
|
{
|
||||||
return "You already have a DM with this user";
|
await Federation.Sender.AddToDm(id, domain, id2);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
foreach (var entry in restoreList)
|
||||||
|
{
|
||||||
|
if (entry.todo == "delete")
|
||||||
|
{
|
||||||
|
Fs.DeleteFile(entry.file);
|
||||||
|
}
|
||||||
|
if (entry.todo == "deletef")
|
||||||
|
{
|
||||||
|
Fs.DeleteDirectory(entry.file);
|
||||||
|
}
|
||||||
|
if (entry.todo == "write")
|
||||||
|
{
|
||||||
|
await Fs.WriteFile(entry.file, Encoding.UTF8.GetBytes(entry.content));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "Failed to accept DM. Ask for another invite";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "DM accepted";
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ public class Utils
|
||||||
public static int DIR_CACHE_SIZE = 800000;
|
public static int DIR_CACHE_SIZE = 800000;
|
||||||
public static int LOCK_SIZE = 1000000;
|
public static int LOCK_SIZE = 1000000;
|
||||||
|
|
||||||
public static int MAX_BODY_SIZE = 65536;
|
public static int MAX_BODY_SIZE = 524288; //0.5mb
|
||||||
|
|
||||||
public static int PRIVATE_STORAGE_LIMIT = 5242880;
|
public static int PRIVATE_STORAGE_LIMIT = 5242880;
|
||||||
public static int PUBLIC_STORAGE_LIMIT = 10485760;
|
public static int PUBLIC_STORAGE_LIMIT = 10485760;
|
||||||
|
|
@ -205,10 +205,6 @@ public class Utils
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(ROOMS_DIR + "/spaces");
|
Directory.CreateDirectory(ROOMS_DIR + "/spaces");
|
||||||
}
|
}
|
||||||
if (!Directory.Exists(ROOMS_DIR + "/freedms"))
|
|
||||||
{
|
|
||||||
Directory.CreateDirectory(ROOMS_DIR + "/freedms");
|
|
||||||
}
|
|
||||||
if (!Directory.Exists(ROOMS_DIR + "/freegroups"))
|
if (!Directory.Exists(ROOMS_DIR + "/freegroups"))
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(ROOMS_DIR + "/freegroups");
|
Directory.CreateDirectory(ROOMS_DIR + "/freegroups");
|
||||||
|
|
@ -217,10 +213,6 @@ public class Utils
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(ROOMS_DIR + "/freespaces");
|
Directory.CreateDirectory(ROOMS_DIR + "/freespaces");
|
||||||
}
|
}
|
||||||
if (!File.Exists(ROOMS_DIR + "/lastdm"))
|
|
||||||
{
|
|
||||||
await File.WriteAllTextAsync(ROOMS_DIR + "/lastdm", "0");
|
|
||||||
}
|
|
||||||
if (!File.Exists(ROOMS_DIR + "/lastgroup"))
|
if (!File.Exists(ROOMS_DIR + "/lastgroup"))
|
||||||
{
|
{
|
||||||
await File.WriteAllTextAsync(ROOMS_DIR + "/lastgroup", "0");
|
await File.WriteAllTextAsync(ROOMS_DIR + "/lastgroup", "0");
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue