feat(dashboard): reading whispers is its own permission

chat_dms (GM 8) reads whispers; chat_private is now team and guild chat only.
Adds chat_flag and chat_flag_review (GM 3). Both can be granted per account or
character with the permission grants.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Aaron Kimbrell
2026-09-29 18:22:32 -05:00
parent ffeb742c82
commit 8e440d4928
5 changed files with 11 additions and 1 deletions

View File

@@ -57,7 +57,10 @@ namespace {
{ "moderate_pet_names", "Moderation", "Moderate pet names", "Approve and reject pet names", 5 },
{ "guilds_manage", "Moderation", "Guilds", "See guilds, their members and history; approve, reject and change guild names, remove members and disband guilds", 5 },
{ "chat_view", "Moderation", "Read chat", "The chat log: what players said in zones, and what the chat filter stopped", 3 },
{ "chat_private", "Moderation", "Read private chat", "Whispers, team and guild chat in the chat log", 8 },
{ "chat_private", "Moderation", "Read team and guild chat", "Team and guild chat in the chat log, and the team and guild chat histories", 8 },
{ "chat_dms", "Moderation", "Read whispers", "Whispers between players: in the chat log and as conversations on a character (every conversation opened is audited)", 8 },
{ "chat_flag", "Moderation", "Flag chat", "Flag chat messages for review and see the Chat Flags queue (a flag only shows chat the viewer may read)", 3 },
{ "chat_flag_review", "Moderation", "Review chat flags", "Mark chat flags actioned or dismissed, and add notes to them", 3 },
{ "chat_filter_manage", "Moderation", "Chat filter", "See and change the words the chat filter allows and stops, and apply them in running worlds", 5 },
{ "player_reports_view", "Moderation", "View player reports", "Read what players reported from the game's Report Abuse window", 2 },
{ "player_reports_manage", "Moderation", "Handle player reports", "Act on or dismiss player reports (a strike also needs strikes_give)", 3 },

View File

@@ -130,6 +130,7 @@ namespace {
q.characterId = characterId;
q.accountId = accountId;
q.includePrivate = Can(context, "chat_private");
q.includeWhispers = Can(context, "chat_dms");
q.newestFirst = true;
q.limit = 100;
nlohmann::json rows = nlohmann::json::array();

View File

@@ -383,6 +383,7 @@ namespace {
IChatLog::ChatQuery query;
query.search = *word;
query.includePrivate = Can(context, "chat_private");
query.includeWhispers = Can(context, "chat_dms");
query.blockedOnly = allowed;
query.newestFirst = true;
query.limit = CHECK_MESSAGES;

View File

@@ -216,6 +216,8 @@ namespace {
query.characterId = character;
query.since = center - window;
query.includePrivate = Can(context, "chat_private");
query.includeWhispers = Can(context, "chat_dms");
query.includeWhispers = Can(context, "chat_dms");
query.limit = 200;
for (auto& m : Database::Get()->GetChatMessages(query)) {
if (m.time <= center + window) found[m.id] = std::move(m);
@@ -317,6 +319,7 @@ namespace {
query.afterId = id - 1;
query.limit = 1;
query.includePrivate = Can(context, "chat_private");
query.includeWhispers = Can(context, "chat_dms");
const auto found = Database::Get()->GetChatMessages(query);
if (found.empty() || found.front().id != id) return std::nullopt;
return found.front();
@@ -354,6 +357,7 @@ namespace {
IChatLog::ChatQuery query;
query.characterId = characterId;
query.includePrivate = Can(context, "chat_private");
query.includeWhispers = Can(context, "chat_dms");
query.newestFirst = true;
query.limit = MAX_CHAT_LINES;
auto messages = Database::Get()->GetChatMessages(query);

View File

@@ -157,6 +157,7 @@ namespace {
}
IChatLog::ChatQuery q;
q.includePrivate = true;
q.includeWhispers = true;
q.limit = CHAT_PAGE;
for (uint32_t page = 0; page < CHAT_PAGES && g_ChatSeen < newest; page++) {
q.afterId = g_ChatSeen;