Building Safer Social Spaces in the MyZubster Metaverse
MyZubster is evolving from a digital plant-tracking platform into an experimental ecosystem connecting identity, communities, marketplaces, underground cultures, knowledge exchange, and virtual social spaces.
During the latest development cycle, we focused on one essential part of this vision: building a safer, privacy-conscious foundation for communication inside the MyZubster Metaverse.
This work does not yet represent a finished immersive 3D world. The current metaverse is an experimental, server-authoritative prototype designed to validate identity, rooms, sessions, permissions, social interactions, and moderation before connecting them to a complete realtime environment.
Explore the experimental metaverse:
https://www.myzubster.com/metaverse?utm_source=devto&utm_medium=article&utm_campaign=myzubster_metaverse_build
Verified character identity
The metaverse uses account-linked MyZubster characters.
Instead of creating a temporary identity every time a user enters a room, the platform loads the verified character associated with the authenticated account.
A character can include:
- A unique character ID
- A public character name
- An archetype
- An identity status
- A world assignment
- A connected GitHub profile This is how the character H4x0r can remain connected to the correct MyZubster account without exposing internal database identifiers to other participants. The public interface receives only the information necessary to represent the character safely. Server-authoritative virtual rooms Virtual rooms are not controlled only by frontend state. The server validates:
- Room creation
- Draft and published states
- Access policies
- Room capacity
- Session scheduling
- Session start and conclusion
- Participant membership
- Host permissions
- Private invitations
- Blocked accounts
- Stage access
- Chat access This prevents users from bypassing room rules by modifying browser state or manually sending unauthorized API requests. Room lifecycle Every room follows a controlled lifecycle: Draft ↓ Published ↓ Scheduled session ↓ Live session ↓ Ended Lifecycle transitions are checked by the backend and cannot move backward arbitrarily. Hosts can configure:
- Public access
- Authenticated-user access
- Private access
- Maximum capacity
- Stage policy
- Scheduled date and time Scheduled sessions can also be cancelled safely before they begin. Private invitations Private rooms support expiring, single-use invitation links. The implementation includes:
- Secure invitation generation
- Expiration checks
- Single-use redemption
- Invitation status
- Manual revocation
- Automatic invalidation of the previous invitation when a new one is created Invitation redemption is handled atomically to prevent the same invitation from being consumed concurrently by multiple accounts. Participant management Hosts can manage active room participants without exposing internal account IDs. The moderation interface works with privacy-safe references and public character information. Hosts can:
- View active participants
- Remove a participant
- Remove and block a participant
- Inspect the room blocklist
- Restore access to a blocked participant Blocked accounts are rejected by server-side authorization checks, including chat access. Moderated stage access Rooms can use different stage policies. The current implementation supports:
- Host-only stages
- Host-approved speaking requests
- Pending speaking requests
- Approval or rejection by the host
- Leaving the stage voluntarily
- Revocation of speaking access
- Privacy-safe speaker lists This creates a foundation for talks, workshops, community meetings, university support sessions, underground cultural events, and marketplace presentations. Persistent session synchronization Room state is synchronized through resilient polling instead of relying on fragile in-memory serverless connections. The client periodically refreshes:
- Session state
- Participant counts
- Stage requests
- Approved speakers
- Room messages
- Moderation reports This is still an experimental transport layer. A dedicated realtime system can be connected later without changing the authorization model already enforced by the server. Room-scoped chat Each live session now has its own chat. Chat messages are constrained by:
- Room ID
- Session ID
- Verified participant access
- Session state
- Maximum message length
- Sanitization
- Server-side rate limiting Messages automatically expire after 24 hours. The public message representation contains only: { id, characterName, text, createdAt, reportedByMe, authoredByMe } Private sender account IDs never appear in the public API response. Distributed chat rate limiting Chat rate limiting uses MongoDB-backed shared state. This means the restriction remains effective across multiple serverless instances and does not depend on the memory of a single process. Throttle keys are generated with SHA-256 and do not contain readable account IDs. Temporary throttle records are removed automatically through TTL indexes. Privacy-safe message reporting Participants can report chat messages using a small validated set of reasons: spam harassment unsafe other Every report is scoped to the exact:
- Room
- Session
- Message
- Authenticated reporter Reporter account IDs are stored privately and are never returned to the host interface. Reports are automatically deleted after seven days. Persistent personal report status After reporting a message, the participant immediately sees: Segnalato The button becomes disabled, preventing accidental duplicate submissions. This state is also reconstructed by the server after a page reload. The participant receives only the boolean reportedByMe, representing their own activity. Users cannot inspect whether other participants reported the same message. Preventing self-reports Users cannot report their own messages. This protection exists at two levels:
- The interface replaces the report button with “Il tuo messaggio.”
- The backend independently verifies ownership and rejects manipulated requests. The private senderUserId field remains on the server. The frontend receives only authoredByMe. Report abuse protection The reporting system has its own distributed rate limit. Each account can submit a maximum of 10 report attempts per minute for a specific room and session. The implementation uses:
- Atomic MongoDB counters
- SHA-256 throttle keys
- Fixed time windows
- TTL cleanup
- HTTP 429 responses When the limit is exceeded, the interface displays a clear message asking the participant to wait before trying again. Aggregated moderation queue Multiple participants may report the same message. Showing every report separately would create unnecessary duplication. The host moderation queue therefore groups reports by message and displays:
- Total number of reports
- Distinct report reasons
- Public message content
- Public character name
- Oldest report time Messages with the highest number of reports appear first. If two messages have the same number, the oldest case receives priority. No reporter identity is included in the aggregated result. Complete moderation workflow Hosts and administrators can choose between two actions: Archive the report group or: Remove the message and close the report group Message deletion and report resolution are performed inside a MongoDB transaction. This prevents partial moderation states where a message is deleted but its reports remain open, or reports are closed while the message remains visible. If the message has already expired, the reports can still be closed safely. Anonymous moderation history The host can review recent moderation outcomes. The history records only:
- Report reason
- Resolution type
- Resolution time Resolution types are intentionally limited: dismissed message_removed The history does not contain:
- Reporter identities
- Sender account IDs
- Message text
- Internal participant references Only the latest 20 results are displayed, and the underlying records expire automatically after seven days. Technical architecture The current system uses:
- React for the room interface
- Express routes for authenticated room operations
- MongoDB and Mongoose for persistent state
- TTL indexes for automatic retention enforcement
- MongoDB transactions for coordinated moderation
- SHA-256 hashes for privacy-safe throttle keys
- Server-side room, session, role, and membership checks
- Polling-based synchronization suitable for the current serverless architecture A simplified reporting flow looks like this: Participant selects a message ↓ Server verifies authentication ↓ Server verifies room membership ↓ Server verifies message ownership ↓ Server validates the report reason ↓ Distributed rate limit is checked ↓ Report is stored privately ↓ Host receives an aggregated moderation entry ↓ Host archives or removes the message ↓ Anonymous outcome enters the moderation history ↓ Data expires automatically What is already implemented The current MyZubster Metaverse foundation includes:
- Account-linked characters
- Verified identity status
- Room creation and discovery
- Server-controlled room lifecycle
- Configurable access policies
- Scheduled sessions
- Private invitations
- Invitation revocation
- Participant access controls
- Room blocklists
- Stage requests
- Speaker approval and revocation
- Session event history
- Room-scoped chat
- Automatic message expiration
- Distributed chat throttling
- Privacy-safe reporting
- Aggregated moderation queues
- Transactional moderation
- Anonymous moderation history
- Persistent personal report status
- Self-report prevention
- Distributed report throttling What still needs to be built The next development stages include:
- A dedicated realtime transport layer
- Presence synchronization
- Immersive scene rendering
- Spatial movement
- Voice communication
- Reactions and social interactions
- Stronger automated moderation signals
- Host moderation dashboards
- Accessibility improvements
- Mobile room controls
- Marketplace-to-metaverse experiences
- Community events connected to marketplace categories
- Kefir culture exchange spaces
- Underground subculture rooms
- University peer-support environments
- Plant identity and growth visualization The larger MyZubster cycle The goal is not to build an isolated virtual world. MyZubster is being designed as a cyclical ecosystem: Register and document a plant ↓ Share knowledge and progress ↓ Participate in communities ↓ Discover marketplace categories ↓ Exchange skills, cultures and resources ↓ Meet inside virtual rooms ↓ Create new knowledge and collaboration ↓ Return that value to the ecosystem The marketplace, plant records, kefir culture, underground communities, university support, and metaverse are intended to become connected parts of the same system. Explore the project Experimental MyZubster Metaverse: https://www.myzubster.com/metaverse?utm_source=devto&utm_medium=article&utm_campaign=myzubster_metaverse_build MyZubster Marketplace: https://www.myzubster.com/marketplace?utm_source=devto&utm_medium=article&utm_campaign=myzubster_metaverse_build How MyZubster works: https://www.myzubster.com/come-funziona?utm_source=devto&utm_medium=article&utm_campaign=myzubster_metaverse_build GitHub repository: https://github.com/MyZubster-Ecosystem/myzubster The metaverse remains experimental, but its security, privacy, identity, lifecycle, chat, and moderation foundations are now taking shape. We are building it incrementally, validating each layer before moving toward the complete immersive experience.
Top comments (0)