Protected User Management
This guide covers the complete lifecycle of protected user management in ChatMinder, including guardian relationships, protection levels, and administrative workflows.
Overview
Protected users are individuals who require supervision and approval workflows for their communications. This includes minors, individuals with special needs, or anyone requiring guided communication oversight.
Key Concepts
- Protected User: An individual whose communications require supervision
- Guardian: An authorized adult who manages and supervises protected users
- Owner: The primary guardian who created the protected user account (has full administrative rights)
- Shared Guardian: Additional guardians with approval permissions (no administrative rights)
- Protection Level: The supervision intensity applied to the protected user
Protection Levels
ChatMinder supports three distinct protection levels that determine the scope of supervision required.
GuardianFullyManaged
Most Restrictive: Complete guardian control over all communication activities.
Characteristics:
- ❌ Channel Creation: Protected user cannot create channels
- ❌ Channel Invitations: Protected user cannot invite others or accept invitations
- ❌ Direct Communication: All messages require guardian approval before delivery
- 🎯 Guardian Role: Creates channels and manages all communication on behalf of the protected user
Implementation:
// Guardian creates channel for protected user
const channel = await fetch('/api/guardian/channels/create-direct', {
method: 'POST',
headers: { 'Authorization': `Bearer ${guardianToken}` },
body: JSON.stringify({
fromUserId: protectedUserId,
targetUserId: contactUserId
})
});
// All messages require approval
const messageResponse = await fetch(`/api/messages/channel/${channelId}`, {
method: 'POST',
headers: { 'Authorization': `Bearer ${protectedUserToken}` },
body: JSON.stringify({ content: 'Hello!', messageType: 'text' })
});
// Response contains pendingMessageId for guardian approval
if (messageResponse.pendingMessageId) {
// Guardian must approve via:
await fetch(`/api/guardian/pending-messages/${messageResponse.pendingMessageId}/approve`, {
method: 'POST',
headers: { 'Authorization': `Bearer ${guardianToken}` }
});
}
GuardianFullyModerated
Collaborative Supervision: Shared control between guardian and protected user.
Characteristics:
- ✅ Channel Creation: Protected user can create channels (with guardian approval for invitations)
- ⚠️ Channel Invitations: Protected user can send invitations, but recipient's guardian must approve
- ❌ Direct Communication: All messages require guardian approval before delivery
- 🎯 Guardian Role: Approves communications but allows protected user initiative
Implementation:
// Protected user creates channel
const channel = await fetch('/api/channels/direct/${targetUserId}', {
method: 'POST',
headers: { 'Authorization': `Bearer ${protectedUserToken}` }
});
// Channel invitation requires guardian approval
if (channel.channelInvite) {
// Recipient's guardian approves invitation
await fetch(`/api/guardian/channels/invite/${channel.channelInvite.id}/approve`, {
method: 'POST',
headers: { 'Authorization': `Bearer ${recipientGuardianToken}` }
});
// Then recipient can accept
await fetch(`/api/channels/invite/${channel.channelInvite.id}/accept`, {
method: 'POST',
headers: { 'Authorization': `Bearer ${recipientToken}` }
});
}
Trusted
Minimal Supervision: Independent communication with monitoring.
Characteristics:
- ✅ Channel Creation: Protected user can create channels independently
- ✅ Channel Invitations: Protected user can invite others and accept invitations
- ✅ Direct Communication: Messages are delivered immediately
- 🎯 Guardian Role: Monitors communications but does not block them
Implementation:
// Trusted users operate like regular users
const channel = await fetch('/api/channels/direct/${targetUserId}', {
method: 'POST',
headers: { 'Authorization': `Bearer ${trustedUserToken}` }
});
// Messages are delivered immediately
const message = await fetch(`/api/messages/channel/${channelId}`, {
method: 'POST',
headers: { 'Authorization': `Bearer ${trustedUserToken}` },
body: JSON.stringify({ content: 'Hello!', messageType: 'text' })
});
// Guardian can monitor via dashboard but messages are not blocked
Guardian Management
Guardian Roles and Responsibilities
Owner Guardian:
- Creates and configures the protected user account
- Manages protection level settings
- Can share guardianship with other adults
- Can transfer ownership to another guardian
- Has full administrative control
Shared Guardian:
- Can approve/reject pending communications
- Can monitor protected user activities
- Cannot modify protection level or administrative settings
- Cannot delete or transfer the protected user
Protected User Lifecycle
1. Creation
Create a new protected user account under your guardianship:
POST /api/protected-user
Authorization: Bearer {guardian-token}
Content-Type: application/json
{
"name": "Emma Johnson",
"protectionLevel": "GuardianFullyManaged",
"dateOfBirth": "2010-05-15",
"notes": "Needs supervision for online safety"
}
Response:
{
"success": true,
"data": {
"userId": "user_abc123",
"name": "Emma Johnson",
"protectionLevel": "GuardianFullyManaged",
"dateOfBirth": "2010-05-15",
"createdAt": "2025-09-20T10:00:00Z",
"isOwner": true
}
}
2. Management
List Your Protected Users:
GET /api/protected-user
Authorization: Bearer {guardian-token}
Get Specific Protected User:
GET /api/protected-user/{userId}
Authorization: Bearer {guardian-token}
Update Protected User:
PUT /api/protected-user/{userId}
Authorization: Bearer {guardian-token}
Content-Type: application/json
{
"name": "Emma Johnson-Smith",
"protectionLevel": "GuardianFullyModerated",
"dateOfBirth": "2010-05-15",
"notes": "Upgraded to collaborative supervision"
}
3. Guardian Access Control
Authenticate as Protected User:
Guardians can sign in as their protected users to manage their communications:
POST /api/auth/login-protected-user/{protectedUserId}
Authorization: Bearer {guardian-token}
This switches the session to act as the protected user while maintaining guardian oversight.
Share Guardianship:
Allow another adult to become a guardian:
POST /api/protected-user/{userId}/share
Authorization: Bearer {owner-guardian-token}
Content-Type: application/json
{
"email": "co-guardian@example.com"
}
Transfer Ownership:
Transfer primary ownership to another guardian:
POST /api/protected-user/{userId}/transfer-ownership
Authorization: Bearer {owner-guardian-token}
Content-Type: application/json
{
"newOwnerId": "guardian_xyz789"
}
View Guardian Team:
GET /api/protected-user/{userId}/guardians
Authorization: Bearer {guardian-token}
4. Deletion and Data Management
Delete Protected User:
DELETE /api/protected-user/{userId}
Authorization: Bearer {owner-guardian-token}
Note: Deletion preserves chat history but anonymizes the user as "Deleted User" to maintain conversation context for other participants.
Communication Workflows
Guardian Approval Process
Pending Message Management
Get Overview of Pending Approvals:
GET /api/guardian/pending-messages
Authorization: Bearer {guardian-token}
Response:
{
"totalPendingMessages": 5,
"protectedUsers": [
{
"userId": "user_abc123",
"name": "Emma Johnson",
"pendingMessageCount": 3
}
],
"channelSummaries": [
{
"channelId": 42,
"channelName": "Emma & Sarah",
"pendingMessageCount": 2
}
]
}
Get Channel-Specific Pending Messages:
GET /api/guardian/pending-messages/{channelId}
Authorization: Bearer {guardian-token}
Approve Message:
POST /api/guardian/pending-messages/{pendingMessageId}/approve
Authorization: Bearer {guardian-token}
Reject Message:
POST /api/guardian/pending-messages/{pendingMessageId}/reject
Authorization: Bearer {guardian-token}
Content-Type: application/json
{
"reason": "Inappropriate language"
}
Channel Management for Protected Users
Create Channel on Behalf of Protected User:
POST /api/guardian/channels/create-direct
Authorization: Bearer {guardian-token}
Content-Type: application/json
{
"fromUserId": "protected_user_id",
"targetUserId": "contact_user_id"
}
Get Protected User's Channels:
GET /api/guardian/channels/protected-user/{protectedUserId}
Authorization: Bearer {guardian-token}
Get Pending Channel Invitations:
GET /api/guardian/channels/pending
Authorization: Bearer {guardian-token}
Approve Channel Invitation:
POST /api/guardian/channels/invite/{inviteId}/approve
Authorization: Bearer {guardian-token}
Cross-Guardian Coordination
When protected users with different guardians communicate, both guardians may need to approve various actions:
Scenario: GuardianFullyManaged ↔ GuardianFullyModerated
- Guardian A creates channel for Emma (GuardianFullyManaged)
- Guardian B approves channel invitation for Jake (GuardianFullyModerated)
- Jake accepts the invitation (user-level approval required)
- Guardian A approves Emma's messages
- Guardian B approves Jake's messages
// Complete cross-guardian workflow
async function crossGuardianCommunication() {
// Step 1: Guardian A creates channel
const channel = await fetch('/api/guardian/channels/create-direct', {
method: 'POST',
headers: { 'Authorization': `Bearer ${guardianAToken}` },
body: JSON.stringify({
fromUserId: 'emma_id',
targetUserId: 'jake_id'
})
});
// Step 2: Guardian B approves invitation
const pendingInvites = await fetch('/api/guardian/channels/pending', {
headers: { 'Authorization': `Bearer ${guardianBToken}` }
});
await fetch(`/api/guardian/channels/invite/${inviteId}/approve`, {
method: 'POST',
headers: { 'Authorization': `Bearer ${guardianBToken}` }
});
// Step 3: Jake accepts invitation
await fetch(`/api/channels/invite/${inviteId}/accept`, {
method: 'POST',
headers: { 'Authorization': `Bearer ${jakeToken}` }
});
// Step 4 & 5: Message approval workflow continues...
}
Best Practices
Security Considerations
- Guardian Verification: Always verify guardian authority before allowing protected user access
- Session Management: Properly handle session switching between guardian and protected user contexts
- Data Privacy: Limit data exposure to necessary guardian oversight functions
- Audit Trails: Maintain logs of guardian actions for accountability
User Experience Guidelines
- Clear Status Indicators: Show approval status prominently in guardian dashboards
- Bulk Operations: Provide bulk approval options for efficiency
- Real-time Updates: Use SignalR to notify guardians of pending approvals
- Mobile Optimization: Ensure guardian tools work well on mobile devices
Implementation Patterns
class ProtectedUserManager {
constructor(apiClient, authService) {
this.api = apiClient;
this.auth = authService;
}
async createProtectedUser(userData) {
try {
const response = await this.api.post('/api/protected-user', {
...userData,
headers: { 'Authorization': `Bearer ${this.auth.getGuardianToken()}` }
});
return {
success: true,
protectedUser: response.data
};
} catch (error) {
return this.handleProtectedUserError(error);
}
}
async switchToProtectedUser(protectedUserId) {
try {
const response = await this.api.post(`/api/auth/login-protected-user/${protectedUserId}`, {
headers: { 'Authorization': `Bearer ${this.auth.getGuardianToken()}` }
});
// Update session to protected user context
this.auth.setProtectedUserToken(response.token);
this.auth.setCurrentContext('protected-user', protectedUserId);
return { success: true };
} catch (error) {
if (error.status === 403) {
throw new Error('Guardian does not have access to this protected user');
}
throw error;
}
}
async approvePendingMessage(pendingMessageId) {
try {
await this.api.post(`/api/guardian/pending-messages/${pendingMessageId}/approve`, {
headers: { 'Authorization': `Bearer ${this.auth.getGuardianToken()}` }
});
// Emit event for real-time UI updates
this.eventBus.emit('message-approved', { pendingMessageId });
return { success: true };
} catch (error) {
return this.handleApprovalError(error);
}
}
handleProtectedUserError(error) {
switch (error.response?.data?.errorCode) {
case 'UNAUTHORIZED_GUARDIAN_ACTION':
return { success: false, message: 'You do not have permission to manage this user' };
case 'INVALID_PROTECTION_LEVEL':
return { success: false, message: 'Invalid protection level specified' };
default:
return { success: false, message: 'Failed to manage protected user' };
}
}
}
Performance Optimization
- Caching: Cache protection level information to reduce API calls
- Batch Processing: Group multiple approvals when possible
- Real-time Updates: Use SignalR for instant approval notifications
- Lazy Loading: Load protected user details on demand
Data Models
ProtectedUserDto
{
"userId": "string",
"name": "string",
"protectionLevel": "GuardianFullyManaged | GuardianFullyModerated | Trusted",
"dateOfBirth": "2010-05-15",
"notes": "string",
"createdAt": "2025-09-20T10:00:00Z",
"isOwner": true,
"guardianCount": 2
}
ProtectedUserGuardianDto
{
"guardianId": "string",
"guardianName": "string",
"guardianEmail": "string",
"isOwner": true,
"sharedAt": "2025-09-20T10:00:00Z",
"status": "Active | Pending | Expired"
}
GuardianPendingMessagesOverview
{
"totalPendingMessages": 5,
"protectedUsers": [
{
"userId": "string",
"name": "string",
"pendingMessageCount": 3
}
],
"channelSummaries": [
{
"channelId": 42,
"channelName": "string",
"pendingMessageCount": 2
}
]
}
Common Integration Scenarios
1. Guardian Dashboard
// Complete guardian dashboard data loading
async function loadGuardianDashboard() {
const [protectedUsers, pendingMessages, pendingChannels] = await Promise.all([
fetch('/api/protected-user'),
fetch('/api/guardian/pending-messages'),
fetch('/api/guardian/channels/pending')
]);
return {
protectedUsers: await protectedUsers.json(),
pendingApprovals: await pendingMessages.json(),
pendingChannelInvites: await pendingChannels.json()
};
}
2. Protected User Communication Interface
// Interface for protected user with approval indicators
class ProtectedUserChat {
async sendMessage(channelId, content) {
const response = await fetch(`/api/messages/channel/${channelId}`, {
method: 'POST',
body: JSON.stringify({ content, messageType: 'text' }),
headers: { 'Authorization': `Bearer ${this.protectedUserToken}` }
});
const result = await response.json();
if (result.pendingMessageId) {
this.showApprovalRequiredMessage('Your message is awaiting guardian approval');
this.notifyGuardian(result.pendingMessageId);
} else {
this.showMessageSent();
}
return result;
}
showApprovalRequiredMessage(message) {
// Show pending approval UI
this.ui.showStatus(message, 'pending');
}
notifyGuardian(pendingMessageId) {
// Send real-time notification to guardian
this.signalR.invoke('NotifyGuardianOfPendingMessage', pendingMessageId);
}
}
3. Multi-Guardian Coordination
// Coordinate approvals across multiple guardians
class CrossGuardianWorkflow {
async createCrossGuardianChannel(fromUserId, targetUserId) {
// Guardian A creates channel for their protected user
const channel = await this.createDelegatedChannel(fromUserId, targetUserId);
if (channel.channelInvite) {
// Guardian B needs to approve the invitation
await this.notifyTargetGuardian(channel.channelInvite);
// Wait for guardian approval via webhook or polling
return this.waitForChannelApproval(channel.channelInvite.id);
}
return channel;
}
async notifyTargetGuardian(channelInvite) {
// Real-time notification to target user's guardian
await this.signalR.invoke('NotifyGuardianOfChannelInvite', {
inviteId: channelInvite.id,
fromUserName: channelInvite.fromUserName,
targetUserId: channelInvite.targetUserId
});
}
}
Related Documentation
- Core Concepts: Understanding protection levels and user types
- Authentication: Guardian and protected user authentication flows
- Error Handling: Guardian authority errors and recovery patterns
- Walkthroughs: Complete scenarios with protection level workflows
- Real-time Features: SignalR events for guardian notifications