[FIX/WIP] Fix replies and try fixing a bug with MUCs

This commit is contained in:
lda 2025-02-15 08:44:25 +00:00
commit e2b014d000
11 changed files with 142 additions and 20 deletions

View file

@ -25,11 +25,13 @@ ASInvite(const ParseeConfig *conf, char *id, char *invited)
"@", conf->sender_localpart, "@", conf->sender_localpart,
":", conf->server_base ":", conf->server_base
); );
id = HttpUrlEncode(id);
path = StrConcat(5, path = StrConcat(5,
"/_matrix/client/v3/rooms/", id, "/invite", "/_matrix/client/v3/rooms/", id, "/invite",
"?user_id=", bridge "?user_id=", bridge
); );
Free(bridge); Free(bridge);
Free(id);
ctx = ParseeCreateRequest( ctx = ParseeCreateRequest(
conf, conf,
@ -60,11 +62,13 @@ ASBan(const ParseeConfig *conf, char *id, char *banned)
"@", conf->sender_localpart, "@", conf->sender_localpart,
":", conf->server_base ":", conf->server_base
); );
id = HttpUrlEncode(id);
path = StrConcat(5, path = StrConcat(5,
"/_matrix/client/v3/rooms/", id, "/ban", "/_matrix/client/v3/rooms/", id, "/ban",
"?user_id=", bridge "?user_id=", bridge
); );
Free(bridge); Free(bridge);
Free(id);
ctx = ParseeCreateRequest( ctx = ParseeCreateRequest(
conf, conf,
@ -95,11 +99,13 @@ ASKick(const ParseeConfig *conf, char *id, char *banned)
"@", conf->sender_localpart, "@", conf->sender_localpart,
":", conf->server_base ":", conf->server_base
); );
id = HttpUrlEncode(id);
path = StrConcat(5, path = StrConcat(5,
"/_matrix/client/v3/rooms/", id, "/kick", "/_matrix/client/v3/rooms/", id, "/kick",
"?user_id=", bridge "?user_id=", bridge
); );
Free(bridge); Free(bridge);
Free(id);
ctx = ParseeCreateRequest( ctx = ParseeCreateRequest(
conf, conf,
@ -120,7 +126,8 @@ ASJoin(const ParseeConfig *conf, char *id, char *masquerade)
{ {
HttpClientContext *ctx = NULL; HttpClientContext *ctx = NULL;
HashMap *json = NULL; HashMap *json = NULL;
char *path, *ret; char *path, *ret, *serv;
int status;
if (!conf || !id) if (!conf || !id)
{ {
return NULL; return NULL;
@ -139,6 +146,11 @@ ASJoin(const ParseeConfig *conf, char *id, char *masquerade)
{ {
masquerade = HttpUrlEncode(masquerade); masquerade = HttpUrlEncode(masquerade);
} }
serv = strchr(id, ':');
if (serv)
{
serv = serv + 1;
}
id = HttpUrlEncode(id); id = HttpUrlEncode(id);
path = StrConcat(5, path = StrConcat(5,
"/_matrix/client/v3/join/", id, "?", "/_matrix/client/v3/join/", id, "?",
@ -152,7 +164,7 @@ ASJoin(const ParseeConfig *conf, char *id, char *masquerade)
Free(path); Free(path);
json = HashMapCreate(); json = HashMapCreate();
ASAuthenticateRequest(conf, ctx); ASAuthenticateRequest(conf, ctx);
ParseeSetRequestJSON(ctx, json); status = ParseeSetRequestJSON(ctx, json);
JsonFree(json); JsonFree(json);
json = JsonDecode(HttpClientStream(ctx)); json = JsonDecode(HttpClientStream(ctx));
@ -163,6 +175,8 @@ ASJoin(const ParseeConfig *conf, char *id, char *masquerade)
Free(masquerade); Free(masquerade);
Free(id); Free(id);
(void) serv; // TODO
return ret; return ret;
} }
void void

View file

@ -298,6 +298,7 @@ Main(Array *args, HashMap *env)
"7e228734ec8e792960bb5633e43f0cb845f709f61825130490034651136" "7e228734ec8e792960bb5633e43f0cb845f709f61825130490034651136"
); );
ASSetName(parsee_conf, parsee, "Parsee bridge"); ASSetName(parsee_conf, parsee, "Parsee bridge");
Free(parsee); Free(parsee);
} }

View file

@ -100,7 +100,7 @@ ParseeMemberHandler(ParseeData *data, HashMap *event)
char *jid = ParseeEncodeMXID(state_key); char *jid = ParseeEncodeMXID(state_key);
char *sha = NULL, *mime = NULL; char *sha = NULL, *mime = NULL;
char *avatar = ASGetAvatar(data->config, NULL, state_key); char *avatar = ASGetAvatar(data->config, NULL, state_key);
char *url = ParseeToUnauth(data, avatar); char *url = ParseeToUnauth(data, avatar, NULL);
chat_id = ParseeGetFromRoomID(data, room_id); chat_id = ParseeGetFromRoomID(data, room_id);
ASGetMIMESHA(data->config, avatar, &mime, &sha); ASGetMIMESHA(data->config, avatar, &mime, &sha);
@ -417,7 +417,7 @@ ParseeMessageHandler(ParseeData *data, HashMap *event)
type = direct ? "chat" : "groupchat"; type = direct ? "chat" : "groupchat";
user = GrabString(json, 1, "xmpp_user"); user = GrabString(json, 1, "xmpp_user");
unauth = ParseeToUnauth(data, url); unauth = ParseeToUnauth(data, url, GrabString(event, 2, "content", "filename"));
encoded_from = ParseeEncodeMXID(m_sender); encoded_from = ParseeEncodeMXID(m_sender);
xmppified_user = StrConcat(3, xmppified_user = StrConcat(3,

View file

@ -687,12 +687,13 @@ end:
#include <Cytoplasm/Uri.h> #include <Cytoplasm/Uri.h>
char * char *
ParseeToUnauth(ParseeData *data, char *mxc) ParseeToUnauth(ParseeData *data, char *mxc, char *filename)
{ {
Uri *url = NULL; Uri *url = NULL;
char *ret; char *ret;
char *key, *hmac; char *key, *hmac;
#define PAT "%s/media/%s%s?hmac=%s" #define PAT "%s/media/%s%s?hmac=%s"
#define PATF "%s/media/%s%s/%s?hmac=%s"
size_t l; size_t l;
if (!data || !mxc) if (!data || !mxc)
{ {
@ -713,19 +714,43 @@ ParseeToUnauth(ParseeData *data, char *mxc)
hmac = ParseeHMACS(data->id, key); hmac = ParseeHMACS(data->id, key);
Free(key); Free(key);
if (!filename)
{
l = snprintf(NULL, 0, l = snprintf(NULL, 0,
PAT, PAT,
data->config->media_base, data->config->media_base,
url->host, url->path, url->host, url->path,
hmac hmac
); );
}
else
{
l = snprintf(NULL, 0,
PATF,
data->config->media_base,
url->host, url->path, filename,
hmac
);
}
ret = Malloc(l + 3); ret = Malloc(l + 3);
if (!filename)
{
snprintf(ret, l + 1, snprintf(ret, l + 1,
PAT, PAT,
data->config->media_base, data->config->media_base,
url->host, url->path, url->host, url->path,
hmac hmac
); );
}
else
{
snprintf(ret, l + 1,
PATF,
data->config->media_base,
url->host, url->path, filename,
hmac
);
}
UriFree(url); UriFree(url);
Free(hmac); Free(hmac);
return ret; return ret;

View file

@ -277,3 +277,38 @@ UnistrGetOffset(Unistr *str, uint32_t sep)
} }
return 0; return 0;
} }
size_t
UnistrGetUTFOffset(char *cstr, size_t unicode)
{
Unistr *tmp;
size_t ret = 0;
if (!cstr)
{
return 0;
}
tmp = UnistrCreate(cstr);
for (size_t i = 0; i < unicode && i < tmp->length; i++)
{
uint32_t codepoint = tmp->codepoints[i];
if (codepoint >= 0x0000 && codepoint <= 0x007F)
{
ret += 1;
}
else if (codepoint >= 0x0080 && codepoint <= 0x07FF)
{
ret += 2;
}
else if (codepoint >= 0x0800 && codepoint <= 0xFFFF)
{
ret += 3;
}
else if (codepoint >= 0x010000 && codepoint <= 0x10FFFF)
{
ret += 4;
}
}
end:
Free(tmp);
return ret;
}

View file

@ -159,6 +159,31 @@ XMPPGetReply(XMLElement *elem)
return HashMapGet(rep->attrs, "id"); return HashMapGet(rep->attrs, "id");
} }
ssize_t
XMPPGetReplyOffset(XMLElement *elem)
{
if (!elem)
{
return -1;
}
for (size_t i = 0; i < ArraySize(elem->children); i++)
{
XMLElement *child = ArrayGet(elem->children, i);
char *xmlns = HashMapGet(child->attrs, "xmlns");
char *xfor = HashMapGet(child->attrs, "for");
if (StrEquals(child->name, "fallback") &&
StrEquals(xmlns, "urn:xmpp:feature-fallback:0") &&
StrEquals(xfor, "urn:xmpp:reply:0"))
{
XMLElement *body = XMLookForUnique(child, "body");
if (body && HashMapGet(body->attrs, "end"))
{
return strtol(HashMapGet(body->attrs, "end"), NULL, 10);
}
}
}
return -1;
}
char * char *
XMPPGetModeration(XMLElement *stanza) XMPPGetModeration(XMLElement *stanza)
{ {

View file

@ -5,6 +5,7 @@
#include <Cytoplasm/Str.h> #include <Cytoplasm/Str.h>
#include <Cytoplasm/Log.h> #include <Cytoplasm/Log.h>
#include <Unistring.h>
#include <Matrix.h> #include <Matrix.h>
#include <AS.h> #include <AS.h>
@ -324,8 +325,9 @@ end_error:
{ {
Log(LOG_DEBUG, "Fetching bridge: %fs", Elapsed(rectime)); Log(LOG_DEBUG, "Fetching bridge: %fs", Elapsed(rectime));
} }
char *trim = ParseeTrimJID(from);
if (!mroom_id && !room && !XMPPIsParseeStanza(stanza) && if (!mroom_id && !room && !XMPPIsParseeStanza(stanza) &&
to && *to == '@') to && *to == '@' && !XMPPQueryMUC(jabber, trim, NULL))
{ {
DbRef *room_ref; DbRef *room_ref;
HashMap *room_json; HashMap *room_json;
@ -344,6 +346,7 @@ end_error:
ParseePushDMRoom(args, to, from, room); ParseePushDMRoom(args, to, from, room);
} }
} }
Free(trim);
/* TODO: THIS IS A HACK. THIS CODE IGNORES ALL MUC MESSAGES EVER /* TODO: THIS IS A HACK. THIS CODE IGNORES ALL MUC MESSAGES EVER
* SENT TO NON-PARSEE PUPPETS, AS A "FIX" TO THE MULTITHREADED * SENT TO NON-PARSEE PUPPETS, AS A "FIX" TO THE MULTITHREADED
@ -518,6 +521,15 @@ end_error:
* too. Go figure. */ * too. Go figure. */
size_t off = size_t off =
reply_to ? ParseeFindDatastart(data->data) : 0; reply_to ? ParseeFindDatastart(data->data) : 0;
size_t stanzaoff = XMPPGetReplyOffset(stanza);
if (reply_to && stanzaoff != -1)
{
off = UnistrGetUTFOffset(data->data, stanzaoff);
}
if (data->data && off >= strlen(data->data))
{
off = 0;
}
HashMap *ev = MatrixCreateMessage(data->data + off); HashMap *ev = MatrixCreateMessage(data->data + off);
if (reply_to) if (reply_to)
{ {

View file

@ -368,7 +368,7 @@ extern char * ParseeDMEventFromID(ParseeData *d, char *r_id, char *ori_id);
extern char * ParseeDMEventFromSID(ParseeData *d, char *r_id, char *ori_id); extern char * ParseeDMEventFromSID(ParseeData *d, char *r_id, char *ori_id);
/* Gets a Parsee "shim" link to an MXC, usable as unauth for a limited time */ /* Gets a Parsee "shim" link to an MXC, usable as unauth for a limited time */
extern char * ParseeToUnauth(ParseeData *data, char *mxc); extern char * ParseeToUnauth(ParseeData *data, char *mxc, char *filename);
extern void ParseeInitialiseOIDTable(void); extern void ParseeInitialiseOIDTable(void);
extern void ParseePushOIDTable(char *muc, char *occupant); extern void ParseePushOIDTable(char *muc, char *occupant);

View file

@ -79,7 +79,8 @@ typedef struct ParseeCmdArg {
X_ROUTE("/_matrix/app/v1/users/(.*)", RouteUserAck) \ X_ROUTE("/_matrix/app/v1/users/(.*)", RouteUserAck) \
X_ROUTE("/_matrix/app/v1/rooms/(.*)", RouteRoomAck) \ X_ROUTE("/_matrix/app/v1/rooms/(.*)", RouteRoomAck) \
X_ROUTE("/_matrix/app/v1/ping", RoutePing) \ X_ROUTE("/_matrix/app/v1/ping", RoutePing) \
X_ROUTE("/media/(.*)/(.*)", RouteMedia) X_ROUTE("/media/(.*)/(.*)", RouteMedia) \
X_ROUTE("/media/(.*)/(.*)/(.*)", RouteMedia)
#define X_ROUTE(path, name) extern void * name(Array *, void *); #define X_ROUTE(path, name) extern void * name(Array *, void *);
ROUTES ROUTES

View file

@ -82,4 +82,10 @@ extern Unistr * UnistrFilter(Unistr *str, UnistrFilterFunc filter);
* -------- * --------
* Returns: an offset of the first line to not start by {c} | 0 */ * Returns: an offset of the first line to not start by {c} | 0 */
extern size_t UnistrGetOffset(Unistr *str, uint32_t sep); extern size_t UnistrGetOffset(Unistr *str, uint32_t sep);
/** Locates the new index within a regular UTF-8 sequence from an index
* within all codepoints.
* -----------------------------------
* Returns: an offset */
extern size_t UnistrGetUTFOffset(char *cstr, size_t unicode);
#endif #endif

View file

@ -90,6 +90,9 @@ extern char * XMPPGetRetractedID(XMLElement *);
/* Get the replied-to stanza ID, if existent. */ /* Get the replied-to stanza ID, if existent. */
extern char * XMPPGetReply(XMLElement *elem); extern char * XMPPGetReply(XMLElement *elem);
/* Get the replied-to stanza offset, if existent. */
extern ssize_t XMPPGetReplyOffset(XMLElement *elem);
/** Get the moderated message ID(as a stanza ID/plain ID) from a moderation /** Get the moderated message ID(as a stanza ID/plain ID) from a moderation
* stanza, that lives *alongside* the stanza itself. * stanza, that lives *alongside* the stanza itself.
* ---------------------------------------------------------------------- * ----------------------------------------------------------------------