fix(chat): preserve unedited GUI tags and read complete role histories
This commit is contained in:
1 parent
b7f799ebe5
commit
e3ea2ef78f
3 files changed
+25
-12
No files matched your search
+18
-3
@@ -690,7 +690,8 @@ struct chat_member_tags* chat_member_tags_load(struct UTUN_INSTANCE* inst, const
|
||||
const void *signature = sqlite3_column_blob(st, 1), *x = sqlite3_column_blob(st, 2), *ed = sqlite3_column_blob(st, 3);
|
||||
if ((type != SQLITE_NULL && type != SQLITE_TEXT) || (type == SQLITE_TEXT && (!text || strlen(text) != (size_t)bytes)) ||
|
||||
bytes > MS_ADM_TAGS_MAX || sqlite3_column_type(st, 2) != SQLITE_BLOB || sqlite3_column_bytes(st, 2) != 32 || !x ||
|
||||
sqlite3_column_type(st, 3) != SQLITE_BLOB || sqlite3_column_bytes(st, 3) != 32 || !ed || sqlite3_column_int(st, 4)) goto error;
|
||||
sqlite3_column_type(st, 3) != SQLITE_BLOB || sqlite3_column_bytes(st, 3) != 32 || !ed ||
|
||||
sqlite3_column_type(st, 4) != SQLITE_INTEGER || sqlite3_column_int(st, 4)) goto error;
|
||||
if (bytes) memcpy(t->baseline, text, (size_t)bytes + 1);
|
||||
if (sig_type != SQLITE_NULL) {
|
||||
if (sig_type != SQLITE_BLOB || sqlite3_column_bytes(st, 1) != 64 || !signature) goto error;
|
||||
@@ -767,7 +768,7 @@ int chat_member_tags_replace(struct chat_member_tags* t, const char* json) {
|
||||
if (!requested && parsed.key_count == CHAT_MEMBER_TAGS_MAX_KEYS) rc = -1;
|
||||
if (rc != 0) {
|
||||
for (int i = 0; i < parsed.key_count; i++) { u_free(parsed.keys[i].raw); u_free(parsed.keys[i].val); }
|
||||
DEBUG_WARN(DEBUG_CATEGORY_CHAT_SYNC, "%s: tags_replace — invalid JSON", CC_ID); return -1;
|
||||
DEBUG_WARN(DEBUG_CATEGORY_CHAT_SYNC, "tags: replace rejected JSON/version/key limit"); return -1;
|
||||
}
|
||||
for (int i = 0; i < t->key_count; i++) { u_free(t->keys[i].raw); u_free(t->keys[i].val); }
|
||||
t->key_count = parsed.key_count; memcpy(t->keys, parsed.keys, sizeof(t->keys));
|
||||
@@ -902,7 +903,21 @@ void chat_member_tags_commit_trampoline(void* arg) {
|
||||
}
|
||||
struct chat_member_tags* t = chat_member_tags_load(req->inst, req->ch_id, req->node_id);
|
||||
if (!t) { u_free(arg); return; }
|
||||
if (!req->json[0] || !chat_member_tags_replace(t, req->json)) chat_member_tags_commit(req->inst, t);
|
||||
int rc = 0;
|
||||
if (req->json[0]) {
|
||||
struct chat_member_tags* patch = u_calloc(1, sizeof(*patch));
|
||||
if (!patch) { DEBUG_ERROR(DEBUG_CATEGORY_CHAT_SYNC, "tags: patch allocation failed"); rc = -1; }
|
||||
else {
|
||||
patch->db = t->db; patch->version = t->version;
|
||||
rc = chat_member_tags_replace(patch, req->json);
|
||||
for (int i = 0; !rc && i < patch->key_count; i++) {
|
||||
struct chat_member_tags_key* key = &patch->keys[i];
|
||||
if (strcmp(key->key, "ver")) rc = chat_member_tags_set(t, key->key, key->val);
|
||||
}
|
||||
chat_member_tags_free(patch);
|
||||
}
|
||||
}
|
||||
if (!rc) chat_member_tags_commit(req->inst, t);
|
||||
chat_member_tags_free(t);
|
||||
u_free(arg);
|
||||
}
|
||||
@@ -64,7 +64,7 @@ static uint8_t parse_adm_tags_flags(const char* adm_tags) {
|
||||
uint8_t flags = 0;
|
||||
|
||||
/* supernode */
|
||||
char buf[256];
|
||||
char buf[MS_ADM_TAGS_MAX + 1];
|
||||
if (json_flat_get(adm_tags, "supernode", buf, sizeof(buf)) == 0
|
||||
&& strcmp(buf, "yes") == 0) flags |= CHAT_MEMBER_FLAG_SUPERNODE;
|
||||
|
||||
|
||||
@@ -797,7 +797,7 @@ char* utun_bridge_get_channel_members_json(const char* channel_id) {
|
||||
int is_admin = 0, is_super = 0, is_moder = 0, is_verified = 0, is_deleted = sqlite3_column_int(st, 10);
|
||||
int storage_role = 0;
|
||||
if (adm_tags) {
|
||||
char buf[256];
|
||||
char buf[MS_ADM_TAGS_MAX + 1];
|
||||
if (json_flat_get(adm_tags, "supernode", buf, sizeof(buf)) == 0 && strcmp(buf, "yes") == 0) is_super = 1;
|
||||
if (json_flat_get(adm_tags, "admin", buf, sizeof(buf)) == 0) {
|
||||
const char* last = buf; for (const char* p = buf; *p; p++) if (*p == 'e' || *p == 'd') last = p;
|
||||
@@ -1030,13 +1030,11 @@ static void member_tags_edit_trampoline(void* arg) {
|
||||
u_free(arg);
|
||||
return;
|
||||
}
|
||||
chat_member_tags_set(t, "admin", req->admin ? "yes" : "no");
|
||||
chat_member_tags_set(t, "moder", req->moder ? "yes" : "no");
|
||||
chat_member_tags_set(t, "supernode", req->supernode ? "yes" : "no");
|
||||
chat_member_tags_set(t, "storage", req->storage ? "yes" : "no");
|
||||
chat_member_tags_set(t, "verified", req->verified ? "yes" : "no");
|
||||
chat_member_tags_set(t, "deleted", req->deleted ? "yes" : "no");
|
||||
int rc = chat_member_tags_commit(req->inst, t);
|
||||
const char* keys[] = {"admin", "moder", "supernode", "storage", "verified", "deleted"};
|
||||
int values[] = {req->admin, req->moder, req->supernode, req->storage, req->verified, req->deleted};
|
||||
int rc = 0;
|
||||
for (size_t i = 0; !rc && i < sizeof(values) / sizeof(values[0]); i++) rc = chat_member_tags_set(t, keys[i], values[i] ? "yes" : "no");
|
||||
if (!rc) rc = chat_member_tags_commit(req->inst, t);
|
||||
bridge_log(rc == 0 ? BLEV_INFO : BLEV_ERROR,
|
||||
"set_member_flags ch=%s nid=0x%016llx admin=%d super=%d moder=%d storage=%d verified=%d deleted=%d rc=%d",
|
||||
req->ch_id, (unsigned long long)req->node_id, req->admin, req->supernode,
|
||||
|
||||
Reference in new issue
Block a user