mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-05-13 19:05:04 +00:00
Add dashboard audit log and configuration management
- Implemented dashboard audit logging with InsertAuditLog, GetRecentAuditLogs, GetAuditLogsByIP, and CleanupOldAuditLogs methods. - Created dashboard configuration management with GetDashboardConfig and SetDashboardConfig methods. - Added new tables for dashboard_audit_log and dashboard_config in both MySQL and SQLite migrations. - Updated CMakeLists to include Crow and ASIO for dashboard server functionality. - Enhanced existing database classes to support new dashboard features, including character, play key, and property management. - Added new methods for retrieving and managing play keys, properties, and pet names. - Updated TestSQLDatabase to include stubs for new dashboard-related methods. - Modified shared and dashboard configuration files for new settings.
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
enum class eGameMasterLevel : uint8_t;
|
||||
|
||||
@@ -38,7 +39,62 @@ public:
|
||||
// Update the GameMaster level of an account.
|
||||
virtual void UpdateAccountGmLevel(const uint32_t accountId, const eGameMasterLevel gmLevel) = 0;
|
||||
|
||||
// Set the play_key_id for an account (used during registration)
|
||||
virtual void UpdateAccountPlayKey(const uint32_t accountId, const uint32_t playKeyId) = 0;
|
||||
|
||||
// Get counts for dashboard/stats
|
||||
virtual uint32_t GetBannedAccountCount() = 0;
|
||||
virtual uint32_t GetLockedAccountCount() = 0;
|
||||
|
||||
virtual uint32_t GetAccountCount() = 0;
|
||||
|
||||
struct ListInfo {
|
||||
uint32_t id{};
|
||||
std::string name;
|
||||
eGameMasterLevel gm_level{};
|
||||
bool banned{};
|
||||
bool locked{};
|
||||
uint64_t mute_expire{};
|
||||
uint32_t play_key_id{};
|
||||
};
|
||||
|
||||
struct DetailedInfo {
|
||||
uint32_t id{};
|
||||
std::string name;
|
||||
std::string email;
|
||||
eGameMasterLevel gm_level{};
|
||||
bool banned{};
|
||||
bool locked{};
|
||||
uint64_t mute_expire{};
|
||||
uint32_t play_key_id{};
|
||||
uint64_t created_at{};
|
||||
};
|
||||
|
||||
struct SessionInfo {
|
||||
uint64_t sessionId{};
|
||||
std::string ipAddress;
|
||||
uint64_t loginTime{};
|
||||
uint64_t logoutTime{};
|
||||
bool active{};
|
||||
};
|
||||
|
||||
// Return all accounts for dashboard listing
|
||||
virtual std::vector<ListInfo> GetAllAccounts() = 0;
|
||||
|
||||
// Update an account's locked status
|
||||
virtual void UpdateAccountLock(const uint32_t accountId, const bool locked) = 0;
|
||||
|
||||
// Get detailed account info by ID (for dashboard viewing)
|
||||
virtual std::optional<DetailedInfo> GetAccountById(const uint32_t accountId) = 0;
|
||||
|
||||
// Update account email (for dashboard)
|
||||
virtual void UpdateAccountEmail(const uint32_t accountId, const std::string_view email) = 0;
|
||||
|
||||
// Delete account and all associated data
|
||||
virtual void DeleteAccount(const uint32_t accountId) = 0;
|
||||
|
||||
// Get account session history
|
||||
virtual std::vector<SessionInfo> GetAccountSessions(const uint32_t accountId, uint32_t limit = 50) = 0;
|
||||
};
|
||||
|
||||
#endif //!__IACCOUNTS__H__
|
||||
|
||||
@@ -15,6 +15,27 @@ class IActivityLog {
|
||||
public:
|
||||
// Update the activity log for the given account.
|
||||
virtual void UpdateActivityLog(const LWOOBJID characterId, const eActivityType activityType, const LWOMAPID mapId) = 0;
|
||||
|
||||
struct Entry {
|
||||
LWOOBJID characterId{};
|
||||
eActivityType activity{};
|
||||
uint32_t timestamp{};
|
||||
LWOMAPID mapId{};
|
||||
};
|
||||
|
||||
// Retrieve recent activity entries ordered by time desc.
|
||||
virtual std::vector<Entry> GetRecentActivity(const uint32_t limit) = 0;
|
||||
|
||||
// Get total count of activity log entries
|
||||
virtual uint32_t GetActivityLogCount() = 0;
|
||||
|
||||
// Get paginated activity log entries with ordering
|
||||
virtual std::vector<Entry> GetActivityLogPaginated(
|
||||
uint32_t offset,
|
||||
uint32_t limit,
|
||||
const std::string& orderColumn = "time",
|
||||
const std::string& orderDir = "DESC"
|
||||
) = 0;
|
||||
};
|
||||
|
||||
#endif //!__IACTIVITYLOG__H__
|
||||
|
||||
@@ -2,7 +2,10 @@
|
||||
#define __IBUGREPORTS__H__
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
#include <optional>
|
||||
|
||||
class IBugReports {
|
||||
public:
|
||||
@@ -14,7 +17,29 @@ public:
|
||||
LWOOBJID characterId{};
|
||||
};
|
||||
|
||||
struct DetailedInfo {
|
||||
uint64_t id{};
|
||||
std::string body;
|
||||
std::string clientVersion;
|
||||
std::string otherPlayer;
|
||||
std::string selection;
|
||||
LWOOBJID characterId{};
|
||||
uint64_t submitted{};
|
||||
uint64_t resolved_time{};
|
||||
uint32_t resolved_by_id{};
|
||||
std::string resolution;
|
||||
};
|
||||
|
||||
// Add a new bug report to the database.
|
||||
virtual void InsertNewBugReport(const Info& info) = 0;
|
||||
|
||||
// Dashboard methods
|
||||
virtual std::vector<DetailedInfo> GetAllBugReports() = 0;
|
||||
virtual std::vector<DetailedInfo> GetUnresolvedBugReports() = 0;
|
||||
virtual std::vector<DetailedInfo> GetResolvedBugReports() = 0;
|
||||
virtual std::optional<DetailedInfo> GetBugReportById(const uint64_t reportId) = 0;
|
||||
virtual void ResolveBugReport(const uint64_t reportId, const uint32_t resolvedById, const std::string_view resolution) = 0;
|
||||
virtual uint32_t GetBugReportCount() = 0;
|
||||
virtual uint32_t GetUnresolvedBugReportCount() = 0;
|
||||
};
|
||||
#endif //!__IBUGREPORTS__H__
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
|
||||
#include "ePermissionMap.h"
|
||||
|
||||
// Forward declare eActivityType for Activity struct
|
||||
enum class eActivityType : uint32_t;
|
||||
|
||||
class ICharInfo {
|
||||
public:
|
||||
struct Info {
|
||||
@@ -19,6 +22,35 @@ public:
|
||||
bool needsRename{};
|
||||
LWOCLONEID cloneId{};
|
||||
ePermissionMap permissionMap{};
|
||||
// Extended fields for dashboard
|
||||
uint32_t level{};
|
||||
uint64_t uscore{};
|
||||
uint32_t zoneId{};
|
||||
uint64_t lastLogin{};
|
||||
uint64_t createdOn{};
|
||||
};
|
||||
|
||||
struct Stats {
|
||||
uint64_t totalCurrencyCollected{};
|
||||
uint64_t totalBricksCollected{};
|
||||
uint64_t totalSmashables{};
|
||||
uint64_t totalQuickbuildsCompleted{};
|
||||
uint64_t totalEnemiesSmashed{};
|
||||
uint64_t totalRocketsUsed{};
|
||||
uint64_t totalMissionsCompleted{};
|
||||
uint64_t totalPetsTamed{};
|
||||
};
|
||||
|
||||
struct InventoryItem {
|
||||
LWOOBJID itemId{};
|
||||
uint32_t count{};
|
||||
int32_t slot{};
|
||||
};
|
||||
|
||||
struct Activity {
|
||||
uint64_t timestamp{};
|
||||
eActivityType activity{};
|
||||
uint32_t mapId{};
|
||||
};
|
||||
|
||||
// Get the approved names of all characters.
|
||||
@@ -46,6 +78,41 @@ public:
|
||||
virtual void UpdateLastLoggedInCharacter(const LWOOBJID characterId) = 0;
|
||||
|
||||
virtual bool IsNameInUse(const std::string_view name) = 0;
|
||||
|
||||
// Get total count of characters
|
||||
virtual uint32_t GetCharacterCount() = 0;
|
||||
|
||||
// Get paginated list of all characters
|
||||
virtual std::vector<Info> GetAllCharactersPaginated(
|
||||
uint32_t offset,
|
||||
uint32_t limit,
|
||||
const std::string& orderColumn = "id",
|
||||
const std::string& orderDir = "DESC"
|
||||
) = 0;
|
||||
|
||||
// Get characters with pending names (for moderation)
|
||||
virtual std::vector<Info> GetCharactersWithPendingNames() = 0;
|
||||
|
||||
// Update character permission map (for restrictions)
|
||||
virtual void UpdateCharacterPermissions(const LWOOBJID characterId, ePermissionMap permissions) = 0;
|
||||
|
||||
// Set needs rename flag
|
||||
virtual void SetCharacterNeedsRename(const LWOOBJID characterId, bool needsRename) = 0;
|
||||
|
||||
// Get character statistics
|
||||
virtual std::optional<Stats> GetCharacterStats(const LWOOBJID characterId) = 0;
|
||||
|
||||
// Get character inventory
|
||||
virtual std::vector<InventoryItem> GetCharacterInventory(const LWOOBJID characterId) = 0;
|
||||
|
||||
// Get character activity history
|
||||
virtual std::vector<Activity> GetCharacterActivity(const LWOOBJID characterId, uint32_t limit = 50) = 0;
|
||||
|
||||
// Rescue character to a safe zone
|
||||
virtual void RescueCharacter(const LWOOBJID characterId, uint32_t zoneId) = 0;
|
||||
|
||||
// Delete character and all associated data
|
||||
virtual void DeleteCharacter(const LWOOBJID characterId) = 0;
|
||||
};
|
||||
|
||||
#endif //!__ICHARINFO__H__
|
||||
|
||||
@@ -2,13 +2,24 @@
|
||||
#define __ICOMMANDLOG__H__
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
class ICommandLog {
|
||||
public:
|
||||
public:
|
||||
struct Entry {
|
||||
uint64_t timestamp{};
|
||||
LWOOBJID characterId{};
|
||||
std::string command;
|
||||
std::string arguments;
|
||||
};
|
||||
|
||||
// Insert a new slash command log entry.
|
||||
virtual void InsertSlashCommandUsage(const LWOOBJID characterId, const std::string_view command) = 0;
|
||||
|
||||
// Get recent command log entries
|
||||
virtual std::vector<Entry> GetCommandLogs(uint32_t limit = 100) = 0;
|
||||
};
|
||||
|
||||
#endif //!__ICOMMANDLOG__H__
|
||||
|
||||
58
dDatabase/GameDatabase/ITables/IDashboardAuditLog.h
Normal file
58
dDatabase/GameDatabase/ITables/IDashboardAuditLog.h
Normal file
@@ -0,0 +1,58 @@
|
||||
#ifndef __IDASHBOARDAUDITLOG__H__
|
||||
#define __IDASHBOARDAUDITLOG__H__
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* Interface for Dashboard audit log table.
|
||||
* Records all API requests, security events, and administrative actions.
|
||||
*/
|
||||
class IDashboardAuditLog {
|
||||
public:
|
||||
|
||||
struct AuditLogEntry {
|
||||
uint64_t id;
|
||||
uint64_t timestamp;
|
||||
std::string ip_address;
|
||||
std::string endpoint;
|
||||
std::string method;
|
||||
std::string user_agent;
|
||||
int32_t response_code;
|
||||
};
|
||||
|
||||
struct AdminActionLog {
|
||||
uint64_t timestamp;
|
||||
uint32_t adminAccountId;
|
||||
std::string action;
|
||||
std::string targetType;
|
||||
uint64_t targetId;
|
||||
std::string details;
|
||||
};
|
||||
|
||||
// Insert a new audit log entry for API requests
|
||||
virtual void InsertAuditLog(const std::string_view ip, const std::string_view endpoint,
|
||||
const std::string_view method, const std::string_view user_agent,
|
||||
int32_t response_code) = 0;
|
||||
|
||||
// Insert a new admin action log entry
|
||||
virtual void InsertAdminActionLog(uint32_t adminAccountId, const std::string_view action,
|
||||
const std::string_view targetType, uint64_t targetId,
|
||||
const std::string_view details) = 0;
|
||||
|
||||
// Get recent audit log entries (limit = number of entries)
|
||||
virtual std::vector<AuditLogEntry> GetRecentAuditLogs(uint32_t limit = 100) = 0;
|
||||
|
||||
// Get recent admin action logs
|
||||
virtual std::vector<AdminActionLog> GetAuditLogs(uint32_t limit = 100) = 0;
|
||||
|
||||
// Get audit logs for a specific IP address
|
||||
virtual std::vector<AuditLogEntry> GetAuditLogsByIP(const std::string_view ip, uint32_t limit = 100) = 0;
|
||||
|
||||
// Clear old audit logs (older than days_to_keep)
|
||||
virtual void CleanupOldAuditLogs(uint32_t days_to_keep = 30) = 0;
|
||||
};
|
||||
|
||||
#endif //!__IDASHBOARDAUDITLOG__H__
|
||||
27
dDatabase/GameDatabase/ITables/IDashboardConfig.h
Normal file
27
dDatabase/GameDatabase/ITables/IDashboardConfig.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef __IDASHBOARDCONFIG__H__
|
||||
#define __IDASHBOARDCONFIG__H__
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
/**
|
||||
* Interface for Dashboard configuration table.
|
||||
* Stores key-value configuration settings for the Dashboard server.
|
||||
*/
|
||||
class IDashboardConfig {
|
||||
public:
|
||||
|
||||
struct DashboardConfig {
|
||||
std::string key;
|
||||
std::string value;
|
||||
};
|
||||
|
||||
// Get a configuration value
|
||||
virtual std::optional<std::string> GetDashboardConfig(const std::string_view key) = 0;
|
||||
|
||||
// Set a configuration value
|
||||
virtual void SetDashboardConfig(const std::string_view key, const std::string_view value) = 0;
|
||||
};
|
||||
|
||||
#endif //!__IDASHBOARDCONFIG__H__
|
||||
@@ -3,6 +3,8 @@
|
||||
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class IPetNames {
|
||||
public:
|
||||
@@ -11,11 +13,24 @@ public:
|
||||
int32_t approvalStatus{};
|
||||
};
|
||||
|
||||
struct DetailedInfo {
|
||||
LWOOBJID id{};
|
||||
std::string petName;
|
||||
int32_t approvalStatus{};
|
||||
LWOOBJID ownerId{};
|
||||
};
|
||||
|
||||
// Set the pet name moderation status for the given pet id.
|
||||
virtual void SetPetNameModerationStatus(const LWOOBJID& petId, const IPetNames::Info& info) = 0;
|
||||
|
||||
// Get pet info for the given pet id.
|
||||
virtual std::optional<IPetNames::Info> GetPetNameInfo(const LWOOBJID& petId) = 0;
|
||||
|
||||
// Dashboard methods
|
||||
virtual std::vector<DetailedInfo> GetAllPetNames() = 0;
|
||||
virtual std::vector<DetailedInfo> GetPetNamesByStatus(int32_t status) = 0;
|
||||
virtual void SetPetApprovalStatus(const LWOOBJID& petId, int32_t status) = 0;
|
||||
virtual uint32_t GetPendingPetNamesCount() = 0;
|
||||
};
|
||||
|
||||
#endif //!__IPETNAMES__H__
|
||||
|
||||
@@ -3,13 +3,38 @@
|
||||
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
class IPlayKeys {
|
||||
public:
|
||||
struct Info {
|
||||
uint32_t id{};
|
||||
std::string key_string;
|
||||
uint32_t key_uses{};
|
||||
uint32_t times_used{};
|
||||
bool active{};
|
||||
std::string notes;
|
||||
uint64_t created_at{};
|
||||
};
|
||||
|
||||
// Get the playkey id for the given playkey.
|
||||
// Optional of bool may seem pointless, however the optional indicates if the playkey exists
|
||||
// and the bool indicates if the playkey is active.
|
||||
virtual std::optional<bool> IsPlaykeyActive(const int32_t playkeyId) = 0;
|
||||
|
||||
// Dashboard methods
|
||||
virtual std::vector<Info> GetAllPlayKeys() = 0;
|
||||
virtual std::optional<Info> GetPlayKeyById(const uint32_t playkeyId) = 0;
|
||||
// Find a playkey by its string value (e.g. "ABCD-EFGH-...."). Returns Info if found.
|
||||
virtual std::optional<Info> GetPlayKeyByString(const std::string_view key_string) = 0;
|
||||
// Consume one usage of the given playkey id. Returns true if consumed, false if no uses left or not active.
|
||||
virtual bool ConsumePlayKeyUsage(const uint32_t playkeyId) = 0;
|
||||
virtual void CreatePlayKey(const std::string_view key_string, uint32_t uses, const std::string_view notes) = 0;
|
||||
virtual void UpdatePlayKey(const uint32_t playkeyId, uint32_t uses, bool active, const std::string_view notes) = 0;
|
||||
virtual void DeletePlayKey(const uint32_t playkeyId) = 0;
|
||||
virtual uint32_t GetPlayKeyCount() = 0;
|
||||
};
|
||||
|
||||
#endif //!__IPLAYKEYS__H__
|
||||
|
||||
@@ -61,8 +61,14 @@ public:
|
||||
|
||||
// Update the property performance cost for the given property id.
|
||||
virtual void UpdatePerformanceCost(const LWOZONEID& zoneId, const float performanceCost) = 0;
|
||||
|
||||
|
||||
// Insert a new property into the database.
|
||||
virtual void InsertNewProperty(const IProperty::Info& info, const uint32_t templateId, const LWOZONEID& zoneId) = 0;
|
||||
|
||||
// Dashboard methods
|
||||
virtual std::vector<Info> GetAllProperties() = 0;
|
||||
virtual std::vector<Info> GetPropertiesByApprovalStatus(uint32_t approved) = 0;
|
||||
virtual uint32_t GetPropertyCount() = 0;
|
||||
virtual uint32_t GetUnapprovedPropertyCount() = 0;
|
||||
};
|
||||
#endif //!__IPROPERTY__H__
|
||||
|
||||
Reference in New Issue
Block a user