Admin User Management
Overviewβ
The admin user management endpoints provide comprehensive CRUD operations for user accounts, role management, and verification status. These endpoints are restricted to users with admin privileges and provide full control over the platform's user base.
Authenticationβ
Required: Admin role
Endpoints: /api/admin/users/*
Rate Limit: 300 requests per minute for admins
Endpointsβ
Get User Detailsβ
GET /api/admin/users/[id]
Headers:
Authorization: Bearer <admin-session-token>
Accept: application/json
Path Parameters:
Parameter | Type | Required | Description |
---|---|---|---|
id | string | Yes | User ID |
Response (200):
{
"id": "user_123",
"email": "john.doe@example.com",
"name": "John Doe",
"firstName": "John",
"lastName": "Doe",
"avatar": "https://storage.ring.ck.ua/avatars/user_123.jpg",
"role": "member",
"isVerified": true,
"isActive": true,
"bio": "Software engineer passionate about Web3",
"location": "Kyiv, Ukraine",
"company": "Tech Innovations Ltd",
"position": "Senior Developer",
"walletAddress": "0x742d35Cc6634C0532925a3b8D4C2C4e0C8A8C8C8",
"authProviders": ["google", "metamask"],
"loginHistory": [
{
"timestamp": "2024-12-14T15:45:00Z",
"ip": "192.168.1.100",
"userAgent": "Mozilla/5.0...",
"provider": "google"
}
],
"statistics": {
"entitiesCreated": 3,
"opportunitiesCreated": 7,
"notificationsSent": 45,
"lastActivity": "2024-12-14T15:45:00Z"
},
"preferences": {
"language": "en",
"theme": "dark",
"notifications": {
"email": true,
"push": true,
"sms": false
}
},
"createdAt": "2024-01-15T10:30:00Z",
"updatedAt": "2024-12-14T15:45:00Z",
"lastLoginAt": "2024-12-14T15:45:00Z"
}
Update User Roleβ
PUT /api/admin/users/[id]/role
Headers:
Authorization: Bearer <admin-session-token>
Content-Type: application/json
Path Parameters:
Parameter | Type | Required | Description |
---|---|---|---|
id | string | Yes | User ID |
Request Body:
{
"role": "confidential",
"reason": "User verified as industry professional"
}
Available Roles:
visitor
- Basic accesssubscriber
- Newsletter and updatesmember
- Full platform accessconfidential
- Premium features and exclusive contentadmin
- Administrative privileges
Response (200):
{
"success": true,
"message": "User role updated successfully",
"data": {
"userId": "user_123",
"previousRole": "member",
"newRole": "confidential",
"updatedBy": "admin_456",
"updatedAt": "2024-12-14T16:00:00Z",
"reason": "User verified as industry professional"
}
}
Update Verification Statusβ
PUT /api/admin/users/[id]/verification
Headers:
Authorization: Bearer <admin-session-token>
Content-Type: application/json
Request Body:
{
"isVerified": true,
"verificationType": "manual",
"notes": "Verified through LinkedIn profile and company email"
}
Response (200):
{
"success": true,
"message": "User verification status updated",
"data": {
"userId": "user_123",
"isVerified": true,
"verificationType": "manual",
"verifiedBy": "admin_456",
"verifiedAt": "2024-12-14T16:00:00Z",
"notes": "Verified through LinkedIn profile and company email"
}
}
Delete User Accountβ
DELETE /api/admin/users/[id]
Headers:
Authorization: Bearer <admin-session-token>
Content-Type: application/json
Request Body:
{
"reason": "Account violation - spam content",
"deleteData": true,
"notifyUser": false
}
Response (200):
{
"success": true,
"message": "User account deleted successfully",
"data": {
"userId": "user_123",
"deletedBy": "admin_456",
"deletedAt": "2024-12-14T16:00:00Z",
"reason": "Account violation - spam content",
"dataDeleted": true
}
}
Code Examplesβ
JavaScript/TypeScriptβ
// Admin user management service
class AdminUserService {
private baseUrl = '/api/admin/users'
async getUserDetails(userId: string) {
try {
const response = await fetch(`${this.baseUrl}/${userId}`, {
headers: {
'Authorization': `Bearer ${this.getAdminToken()}`,
'Accept': 'application/json'
}
})
if (!response.ok) {
throw new Error('Failed to fetch user details')
}
return await response.json()
} catch (error) {
console.error('Error fetching user details:', error)
throw error
}
}
async updateUserRole(userId: string, role: string, reason?: string) {
try {
const response = await fetch(`${this.baseUrl}/${userId}/role`, {
method: 'PUT',
headers: {
'Authorization': `Bearer ${this.getAdminToken()}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ role, reason })
})
if (!response.ok) {
throw new Error('Failed to update user role')
}
return await response.json()
} catch (error) {
console.error('Error updating user role:', error)
throw error
}
}
async updateVerificationStatus(
userId: string,
isVerified: boolean,
notes?: string
) {
try {
const response = await fetch(`${this.baseUrl}/${userId}/verification`, {
method: 'PUT',
headers: {
'Authorization': `Bearer ${this.getAdminToken()}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
isVerified,
verificationType: 'manual',
notes
})
})
if (!response.ok) {
throw new Error('Failed to update verification status')
}
return await response.json()
} catch (error) {
console.error('Error updating verification:', error)
throw error
}
}
async deleteUser(userId: string, reason: string, deleteData = true) {
try {
const response = await fetch(`${this.baseUrl}/${userId}`, {
method: 'DELETE',
headers: {
'Authorization': `Bearer ${this.getAdminToken()}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
reason,
deleteData,
notifyUser: false
})
})
if (!response.ok) {
throw new Error('Failed to delete user')
}
return await response.json()
} catch (error) {
console.error('Error deleting user:', error)
throw error
}
}
private getAdminToken(): string {
// Implementation to get admin session token
return localStorage.getItem('adminToken') || ''
}
}
React Admin Componentβ
import { useState, useEffect } from 'react'
import { useSession } from 'next-auth/react'
interface User {
id: string
email: string
name: string
role: string
isVerified: boolean
isActive: boolean
createdAt: string
lastLoginAt: string
}
export function UserManagement({ userId }: { userId: string }) {
const { data: session } = useSession()
const [user, setUser] = useState<User | null>(null)
const [loading, setLoading] = useState(true)
const [updating, setUpdating] = useState(false)
useEffect(() => {
if (session?.user?.role === 'admin') {
fetchUserDetails()
}
}, [userId, session])
const fetchUserDetails = async () => {
try {
setLoading(true)
const response = await fetch(`/api/admin/users/${userId}`)
if (!response.ok) {
throw new Error('Failed to fetch user')
}
const userData = await response.json()
setUser(userData)
} catch (error) {
console.error('Error:', error)
} finally {
setLoading(false)
}
}
const handleRoleChange = async (newRole: string) => {
try {
setUpdating(true)
const response = await fetch(`/api/admin/users/${userId}/role`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
role: newRole,
reason: `Role updated by admin`
})
})
if (!response.ok) {
throw new Error('Failed to update role')
}
await fetchUserDetails() // Refresh data
} catch (error) {
console.error('Error updating role:', error)
} finally {
setUpdating(false)
}
}
const handleVerificationToggle = async () => {
try {
setUpdating(true)
const response = await fetch(`/api/admin/users/${userId}/verification`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
isVerified: !user?.isVerified,
notes: `Verification ${!user?.isVerified ? 'approved' : 'revoked'} by admin`
})
})
if (!response.ok) {
throw new Error('Failed to update verification')
}
await fetchUserDetails() // Refresh data
} catch (error) {
console.error('Error updating verification:', error)
} finally {
setUpdating(false)
}
}
if (session?.user?.role !== 'admin') {
return <div>Access denied. Admin privileges required.</div>
}
if (loading) return <div>Loading user details...</div>
if (!user) return <div>User not found</div>
return (
<div className="user-management">
<h2>User Management: {user.name}</h2>
<div className="user-info">
<p><strong>Email:</strong> {user.email}</p>
<p><strong>Role:</strong> {user.role}</p>
<p><strong>Verified:</strong> {user.isVerified ? 'β
' : 'β'}</p>
<p><strong>Active:</strong> {user.isActive ? 'β
' : 'β'}</p>
<p><strong>Created:</strong> {new Date(user.createdAt).toLocaleDateString()}</p>
<p><strong>Last Login:</strong> {new Date(user.lastLoginAt).toLocaleDateString()}</p>
</div>
<div className="actions">
<div className="role-management">
<label>Role:</label>
<select
value={user.role}
onChange={(e) => handleRoleChange(e.target.value)}
disabled={updating}
>
<option value="visitor">Visitor</option>
<option value="subscriber">Subscriber</option>
<option value="member">Member</option>
<option value="confidential">Confidential</option>
<option value="admin">Admin</option>
</select>
</div>
<button
onClick={handleVerificationToggle}
disabled={updating}
className={user.isVerified ? 'revoke' : 'approve'}
>
{user.isVerified ? 'Revoke Verification' : 'Approve Verification'}
</button>
</div>
</div>
)
}
cURL Examplesβ
# Get user details
curl -X GET "https://ring.ck.ua/api/admin/users/user_123" \
-H "Authorization: Bearer admin-session-token" \
-H "Accept: application/json"
# Update user role
curl -X PUT "https://ring.ck.ua/api/admin/users/user_123/role" \
-H "Authorization: Bearer admin-session-token" \
-H "Content-Type: application/json" \
-d '{
"role": "confidential",
"reason": "User verified as industry professional"
}'
# Update verification status
curl -X PUT "https://ring.ck.ua/api/admin/users/user_123/verification" \
-H "Authorization: Bearer admin-session-token" \
-H "Content-Type: application/json" \
-d '{
"isVerified": true,
"notes": "Verified through LinkedIn profile"
}'
# Delete user account
curl -X DELETE "https://ring.ck.ua/api/admin/users/user_123" \
-H "Authorization: Bearer admin-session-token" \
-H "Content-Type: application/json" \
-d '{
"reason": "Account violation",
"deleteData": true,
"notifyUser": false
}'
Error Handlingβ
Unauthorized Access (403)β
{
"error": "FORBIDDEN",
"message": "Admin privileges required",
"code": 403
}
User Not Found (404)β
{
"error": "USER_NOT_FOUND",
"message": "User with specified ID does not exist",
"code": 404
}
Invalid Role (400)β
{
"error": "INVALID_ROLE",
"message": "Invalid role specified",
"code": 400,
"validRoles": ["visitor", "subscriber", "member", "confidential", "admin"]
}
Cannot Delete Admin (400)β
{
"error": "CANNOT_DELETE_ADMIN",
"message": "Cannot delete admin user account",
"code": 400
}
Audit Loggingβ
Admin Action Loggingβ
All admin actions are automatically logged for audit purposes:
interface AdminAuditLog {
id: string
adminId: string
adminEmail: string
action: 'USER_ROLE_UPDATE' | 'USER_VERIFICATION' | 'USER_DELETE' | 'USER_VIEW'
targetUserId: string
targetUserEmail: string
details: {
previousValue?: any
newValue?: any
reason?: string
}
timestamp: string
ipAddress: string
userAgent: string
}
Audit Log Exampleβ
{
"id": "audit_789",
"adminId": "admin_456",
"adminEmail": "admin@ring.ck.ua",
"action": "USER_ROLE_UPDATE",
"targetUserId": "user_123",
"targetUserEmail": "john.doe@example.com",
"details": {
"previousValue": "member",
"newValue": "confidential",
"reason": "User verified as industry professional"
},
"timestamp": "2024-12-14T16:00:00Z",
"ipAddress": "192.168.1.100",
"userAgent": "Mozilla/5.0..."
}
Security Featuresβ
Access Controlβ
- Role Verification: Admin role required for all operations
- Session Validation: Valid admin session token required
- IP Logging: All admin actions logged with IP address
- Rate Limiting: 300 requests per minute for admin users
Data Protectionβ
- Sensitive Data: Password hashes and tokens not exposed
- Audit Trail: Complete history of admin actions
- Soft Delete: User data can be recovered if needed
- GDPR Compliance: Data deletion follows privacy regulations
Admin Restrictionsβ
- Self-Modification: Admins cannot modify their own role
- Admin Deletion: Cannot delete other admin accounts
- Reason Required: All significant actions require reason
- Confirmation: Destructive actions require confirmation
Bulk Operationsβ
Bulk Role Updateβ
POST /api/admin/users/bulk/role
Request Body:
{
"userIds": ["user_123", "user_456", "user_789"],
"role": "member",
"reason": "Bulk promotion to member status"
}
Bulk Verificationβ
POST /api/admin/users/bulk/verification
Request Body:
{
"userIds": ["user_123", "user_456"],
"isVerified": true,
"notes": "Bulk verification after document review"
}
Related Endpointsβ
/api/auth/[...nextauth]
- Authentication/api/profile
- User profile management/api/set-user-role
- Role assignment/api/info
- Platform statistics
Testingβ
Unit Testsβ
describe('Admin User Management', () => {
test('should get user details for admin', async () => {
const response = await request(app)
.get('/api/admin/users/user_123')
.set('Authorization', `Bearer ${adminToken}`)
.expect(200)
expect(response.body).toHaveProperty('id', 'user_123')
expect(response.body).toHaveProperty('email')
expect(response.body).toHaveProperty('role')
})
test('should update user role', async () => {
const response = await request(app)
.put('/api/admin/users/user_123/role')
.set('Authorization', `Bearer ${adminToken}`)
.send({
role: 'confidential',
reason: 'Test role update'
})
.expect(200)
expect(response.body.success).toBe(true)
expect(response.body.data.newRole).toBe('confidential')
})
test('should reject non-admin access', async () => {
await request(app)
.get('/api/admin/users/user_123')
.set('Authorization', `Bearer ${memberToken}`)
.expect(403)
})
})
Troubleshootingβ
Common Issuesβ
Issue: "Admin privileges required" Solution: Ensure user has admin role and valid session
Issue: "User not found" Solution: Verify user ID exists in the system
Issue: "Cannot modify admin user" Solution: Admin users have special restrictions for security
Issue: "Rate limit exceeded" Solution: Admin rate limit is 300/minute, reduce request frequency