M5: moderation, permissions, channel CRUD, in-app account management

- Server-side moderation & permissions (kick/ban/move/server-mute, channel CRUD).

- Database schema v2: channels, bans; BLAKE2b channel passwords, Argon2id accounts.

- C ABI additions and client-side handling (vc_kick_user, vc_ban_user, vc_set_permission, vc_set_server_mute, vc_move_user, vc_create/edit/delete_channel, vc_create/reset/delete/list_account).

- vccli flags for all M5 operations plus --username/--password auth.

- Four new tests covering permissions, kick/ban/move/mute, admin accounts, channel CRUD.

- Docs: protocol.md envelope updates, security.md channel-password hashing, PROGRESS.md.
This commit is contained in:
2026-06-17 15:08:05 +02:00
parent a2f159e971
commit 3990f63f0f
23 changed files with 3281 additions and 97 deletions

View File

@@ -202,9 +202,75 @@ vc_result vc_confirm_server_identity(vc_client* c, int accept) {
}
vc_result vc_get_server_identity_display(vc_client* c, char* out_buf, size_t buf_cap,
size_t* out_len) {
size_t* out_len) {
if (c == nullptr) return VC_ERR_INVALID_ARG;
return c->get_server_identity_display(out_buf, buf_cap, out_len);
}
vc_result vc_kick_user(vc_client* c, uint32_t user_id, const char* reason) {
if (c == nullptr) return VC_ERR_INVALID_ARG;
return c->kick_user(user_id, reason);
}
vc_result vc_ban_user(vc_client* c, uint32_t user_id, const char* reason,
uint64_t expires_unix_ms) {
if (c == nullptr) return VC_ERR_INVALID_ARG;
return c->ban_user(user_id, reason, expires_unix_ms);
}
vc_result vc_set_permission(vc_client* c, uint32_t user_id, const vc_permissions* perms) {
if (c == nullptr || perms == nullptr) return VC_ERR_INVALID_ARG;
return c->set_permission(user_id, perms);
}
vc_result vc_set_server_mute(vc_client* c, uint32_t user_id, int muted, int deafened) {
if (c == nullptr) return VC_ERR_INVALID_ARG;
return c->set_server_mute(user_id, muted != 0, deafened != 0);
}
vc_result vc_move_user(vc_client* c, uint32_t user_id, uint32_t channel_id) {
if (c == nullptr) return VC_ERR_INVALID_ARG;
return c->move_user(user_id, channel_id);
}
vc_result vc_create_channel(vc_client* c, const vc_channel_info* info) {
if (c == nullptr || info == nullptr) return VC_ERR_INVALID_ARG;
return c->create_channel(info);
}
vc_result vc_edit_channel(vc_client* c, const vc_channel_info* info) {
if (c == nullptr || info == nullptr) return VC_ERR_INVALID_ARG;
return c->edit_channel(info);
}
vc_result vc_delete_channel(vc_client* c, uint32_t channel_id) {
if (c == nullptr) return VC_ERR_INVALID_ARG;
return c->delete_channel(channel_id);
}
vc_result vc_create_account(vc_client* c, const char* username, const char* password) {
if (c == nullptr || username == nullptr || password == nullptr) return VC_ERR_INVALID_ARG;
return c->create_account(username, password);
}
vc_result vc_reset_password(vc_client* c, const char* username, const char* new_password) {
if (c == nullptr || username == nullptr || new_password == nullptr) return VC_ERR_INVALID_ARG;
return c->reset_password(username, new_password);
}
vc_result vc_delete_account(vc_client* c, const char* username) {
if (c == nullptr || username == nullptr) return VC_ERR_INVALID_ARG;
return c->delete_account(username);
}
vc_result vc_list_accounts(vc_client* c) {
if (c == nullptr) return VC_ERR_INVALID_ARG;
return c->list_accounts();
}
vc_result vc_get_permissions(vc_client* c, vc_permissions* out) {
if (c == nullptr || out == nullptr) return VC_ERR_INVALID_ARG;
return c->get_permissions(out);
}
} // extern "C"