Security & Access Control
Comprehensive security measures, access control, and audit logging for admin dashboard operations.
Preview
Security dashboard with access control, audit logging, and real-time security monitoring.
Overview
The security system provides multi-layered protection for admin operations with role-based access control, audit logging, and real-time security monitoring.
Access Control System
Admin Role Verification
typescript
// Environment-based admin configuration
const getAdminEmails = () => {
const emails = process.env.ADMIN_EMAILS || 'admin@example.com'
return emails.split(',').map(email => email.trim())
}
const getSuperAdminEmails = () => {
const emails = process.env.SUPER_ADMIN_EMAILS || ''
return emails.split(',').map(email => email.trim()).filter(Boolean)
}
// Role-based permissions
const userRole = computed(() => {
const user = useSupabaseUser()
if (!user.value) return 'guest'
const adminEmails = getAdminEmails()
const superAdminEmails = getSuperAdminEmails()
if (superAdminEmails.includes(user.value.email)) return 'super_admin'
if (adminEmails.includes(user.value.email)) return 'admin'
return 'user'
})Middleware Protection
typescript
// Admin middleware
export default defineNuxtRouteMiddleware((to) => {
const user = useSupabaseUser()
const adminEmails = getAdminEmails()
if (!user.value || !adminEmails.includes(user.value.email)) {
throw createError({
statusCode: 403,
statusMessage: 'Access denied. Admin privileges required.'
})
}
})
// Super admin middleware
export default defineNuxtRouteMiddleware((to) => {
const user = useSupabaseUser()
const superAdminEmails = getSuperAdminEmails()
if (!user.value || !superAdminEmails.includes(user.value.email)) {
throw createError({
statusCode: 403,
statusMessage: 'Super admin access required.'
})
}
})Permission System
typescript
const permissions = {
admin: [
'view_dashboard',
'view_users',
'view_subscriptions',
'view_analytics',
'edit_user_profile',
'cancel_subscription',
'export_data'
],
super_admin: [
'all_admin_permissions',
'delete_user',
'bulk_operations',
'system_settings',
'security_logs',
'manage_admins'
]
}
const hasPermission = (action) => {
const role = userRole.value
if (role === 'super_admin') return true
if (role === 'admin') return permissions.admin.includes(action)
return false
}
// Permission guard composable
export const usePermission = () => {
const checkPermission = (action, throwError = true) => {
const allowed = hasPermission(action)
if (!allowed && throwError) {
throw createError({
statusCode: 403,
statusMessage: `Permission denied: ${action}`
})
}
return allowed
}
return { hasPermission, checkPermission }
}Audit Logging System
Activity Logging
typescript
// Log all admin actions
const logAdminAction = async (action, details = {}) => {
const user = useSupabaseUser()
const { $ip } = useNuxtApp()
await $fetch('/api/admin/audit-log', {
method: 'POST',
body: {
admin_id: user.value.id,
admin_email: user.value.email,
action,
details,
ip_address: $ip,
user_agent: navigator.userAgent,
timestamp: new Date().toISOString()
}
})
}
// Usage example
const deleteUser = async (userId) => {
try {
await $fetch(`/api/admin/users/${userId}`, { method: 'DELETE' })
await logAdminAction('user_deleted', {
target_user_id: userId,
reason: 'Admin action'
})
toast.success('User deleted successfully')
} catch (error) {
await logAdminAction('user_delete_failed', {
target_user_id: userId,
error: error.message
})
throw error
}
}Audit Log Viewer
typescript
const { data: auditLogs, refresh: refreshAuditLogs } = await useFetch('/api/admin/audit-logs', {
query: {
page: currentPage.value,
limit: itemsPerPage.value,
action: selectedAction.value,
admin: selectedAdmin.value,
dateRange: dateRange.value
}
})
const auditLogActions = [
'user_created', 'user_updated', 'user_deleted',
'subscription_canceled', 'subscription_resumed',
'bulk_operation', 'data_export', 'settings_changed'
]
const formatAuditLog = (log) => ({
id: log.id,
timestamp: new Date(log.created_at).toLocaleString(),
admin: log.admin_email,
action: log.action.replace('_', ' ').toUpperCase(),
details: log.details,
ipAddress: log.ip_address,
userAgent: log.user_agent,
severity: getSeverityLevel(log.action)
})Security Monitoring
Failed Login Attempts
typescript
const securityAlerts = ref([])
const monitorFailedLogins = () => {
const { $socket } = useNuxtApp()
$socket.on('security:failed_login', (data) => {
securityAlerts.value.unshift({
type: 'failed_login',
message: `Failed login attempt for ${data.email}`,
ip: data.ip_address,
timestamp: new Date(),
severity: 'warning'
})
// Check for brute force attempts
if (data.attempt_count > 5) {
securityAlerts.value.unshift({
type: 'brute_force',
message: `Potential brute force attack detected for ${data.email}`,
ip: data.ip_address,
timestamp: new Date(),
severity: 'critical'
})
}
})
}Suspicious Activity Detection
typescript
const detectSuspiciousActivity = () => {
const { $socket } = useNuxtApp()
$socket.on('security:suspicious_activity', (data) => {
const alert = {
type: data.type,
message: data.message,
details: data.details,
timestamp: new Date(),
severity: data.severity
}
securityAlerts.value.unshift(alert)
// Auto-notify for critical alerts
if (data.severity === 'critical') {
notifySecurityTeam(alert)
}
})
}
const suspiciousPatterns = [
'multiple_admin_access_different_ips',
'bulk_operations_unusual_time',
'rapid_user_deletions',
'mass_data_export',
'settings_changes_after_hours'
]IP Whitelisting
IP Access Control
typescript
const allowedIPs = ref([])
const ipWhitelistEnabled = ref(false)
const { data: ipSettings } = await useFetch('/api/admin/security/ip-settings')
const checkIPAccess = (clientIP) => {
if (!ipWhitelistEnabled.value) return true
return allowedIPs.value.some(allowedIP => {
if (allowedIP.includes('/')) {
// CIDR notation support
return isIPInCIDR(clientIP, allowedIP)
}
return clientIP === allowedIP
})
}
const updateIPWhitelist = async (newIPs) => {
await $fetch('/api/admin/security/ip-whitelist', {
method: 'PUT',
body: {
enabled: ipWhitelistEnabled.value,
allowed_ips: newIPs
}
})
await logAdminAction('ip_whitelist_updated', {
previous_ips: allowedIPs.value,
new_ips: newIPs
})
allowedIPs.value = newIPs
toast.success('IP whitelist updated successfully')
}Two-Factor Authentication
2FA Enforcement for Admins
typescript
const enforce2FA = ref(false)
const admin2FAStatus = ref({})
const check2FAStatus = async () => {
const { data } = await $fetch('/api/admin/security/2fa-status')
admin2FAStatus.value = data
}
const require2FAForAdmin = async (adminEmail) => {
await $fetch('/api/admin/security/require-2fa', {
method: 'POST',
body: { admin_email: adminEmail }
})
await logAdminAction('2fa_required', {
target_admin: adminEmail
})
toast.success('2FA requirement set for admin')
}Session Management
Admin Session Control
typescript
const activeSessions = ref([])
const getActiveSessions = async () => {
const { data } = await $fetch('/api/admin/security/active-sessions')
activeSessions.value = data.sessions
}
const terminateSession = async (sessionId) => {
await $fetch('/api/admin/security/terminate-session', {
method: 'POST',
body: { session_id: sessionId }
})
await logAdminAction('session_terminated', {
session_id: sessionId
})
getActiveSessions()
toast.success('Session terminated successfully')
}
// Auto-logout after inactivity
const sessionTimeout = ref(30 * 60 * 1000) // 30 minutes
let inactivityTimer = null
const resetInactivityTimer = () => {
clearTimeout(inactivityTimer)
inactivityTimer = setTimeout(() => {
logAdminAction('session_timeout')
navigateTo('/auth/login')
}, sessionTimeout.value)
}Data Protection
Sensitive Data Masking
typescript
const maskSensitiveData = (data, field) => {
const sensitiveFields = ['email', 'phone', 'address', 'payment_method']
if (sensitiveFields.includes(field)) {
if (field === 'email') {
const [username, domain] = data.split('@')
return `${username.substring(0, 2)}***@${domain}`
}
if (field === 'phone') {
return data.replace(/(\d{3})\d{4}(\d{3})/, '$1****$2')
}
// Generic masking
return data.substring(0, 2) + '*'.repeat(data.length - 4) + data.substring(data.length - 2)
}
return data
}
// Apply masking based on admin role
const shouldMaskField = (field) => {
const role = userRole.value
if (role === 'super_admin') return false
if (role === 'admin') return ['payment_method', 'full_address'].includes(field)
return true
}Encryption for Sensitive Operations
typescript
const encryptSensitiveData = async (data) => {
const { data: encrypted } = await $fetch('/api/admin/security/encrypt', {
method: 'POST',
body: { data }
})
return encrypted
}
const decryptSensitiveData = async (encryptedData) => {
const { data: decrypted } = await $fetch('/api/admin/security/decrypt', {
method: 'POST',
body: { encrypted_data: encryptedData }
})
return decrypted
}Security Settings
Configuration Management
typescript
const securitySettings = ref({
passwordPolicy: {
minLength: 8,
requireUppercase: true,
requireNumbers: true,
requireSpecialChars: true
},
sessionTimeout: 30,
maxFailedLogins: 5,
lockoutDuration: 15,
ipWhitelistEnabled: false,
enforce2FA: false,
auditLogRetention: 90
})
const updateSecuritySettings = async (newSettings) => {
await $fetch('/api/admin/security/settings', {
method: 'PUT',
body: newSettings
})
await logAdminAction('security_settings_updated', {
previous_settings: securitySettings.value,
new_settings: newSettings
})
securitySettings.value = newSettings
toast.success('Security settings updated')
}Emergency Procedures
Emergency Access
typescript
const emergencyAccess = {
enabled: false,
code: '',
expiresAt: null
}
const generateEmergencyAccess = async () => {
const { data } = await $fetch('/api/admin/security/emergency-access', {
method: 'POST'
})
emergencyAccess.enabled = true
emergencyAccess.code = data.code
emergencyAccess.expiresAt = data.expires_at
await logAdminAction('emergency_access_generated', {
expires_at: data.expires_at
})
toast.warning('Emergency access code generated. Valid for 1 hour.')
}
const revokeEmergencyAccess = async () => {
await $fetch('/api/admin/security/emergency-access', {
method: 'DELETE'
})
emergencyAccess.enabled = false
emergencyAccess.code = ''
await logAdminAction('emergency_access_revoked')
toast.success('Emergency access revoked')
}Security Reporting
Security Dashboard
typescript
const securityMetrics = computed(() => ({
totalAdmins: Object.keys(admin2FAStatus.value).length,
adminsWithout2FA: Object.values(admin2FAStatus.value).filter(status => !status.enabled).length,
failedLoginsToday: securityAlerts.value.filter(alert =>
alert.type === 'failed_login' &&
isToday(alert.timestamp)
).length,
suspiciousActivitiesWeek: securityAlerts.value.filter(alert =>
alert.severity === 'critical' &&
isThisWeek(alert.timestamp)
).length,
activeSessionsCount: activeSessions.value.length
}))Compliance Reporting
typescript
const generateComplianceReport = async (type = 'gdpr') => {
const reportData = {
type,
period: {
start: getReportPeriodStart(),
end: getReportPeriodEnd()
},
include: [
'audit_logs',
'access_logs',
'data_exports',
'user_deletions',
'security_incidents'
]
}
const { data } = await $fetch('/api/admin/security/compliance-report', {
method: 'POST',
body: reportData
})
downloadFile(data, `compliance-report-${type}-${new Date().toISOString().split('T')[0]}.pdf`)
await logAdminAction('compliance_report_generated', { type })
}API Endpoints
Security APIs
GET /api/admin/security/audit-logs # Audit log entries
POST /api/admin/audit-log # Create audit log entry
GET /api/admin/security/active-sessions # Active admin sessions
POST /api/admin/security/terminate-session # Terminate session
GET /api/admin/security/ip-settings # IP whitelist settings
PUT /api/admin/security/ip-whitelist # Update IP whitelist
GET /api/admin/security/2fa-status # 2FA status for admins
POST /api/admin/security/require-2fa # Require 2FA for admin
PUT /api/admin/security/settings # Update security settings
POST /api/admin/security/emergency-access # Generate emergency access
DELETE /api/admin/security/emergency-access # Revoke emergency access
POST /api/admin/security/compliance-report # Generate compliance reportBest Practices
Security Checklist
- [ ] All admin emails configured in environment variables
- [ ] 2FA enabled for all admin accounts
- [ ] IP whitelist configured for production
- [ ] Audit logging enabled and monitored
- [ ] Session timeouts properly configured
- [ ] Failed login monitoring active
- [ ] Regular security setting reviews
- [ ] Emergency access procedures documented
- [ ] Compliance reporting automated
- [ ] Security alerts properly routed
Monitoring Recommendations
- Set up alerts for critical security events
- Review audit logs regularly for suspicious patterns
- Monitor failed logins and implement rate limiting
- Regular security assessments of admin access
- Keep emergency procedures updated and tested
The security system provides comprehensive protection for admin operations while maintaining usability and compliance with security best practices.