Spaces:
Runtime error
Runtime error
| import { supabase } from '../config/supabase'; | |
| export type LogAction = | |
| // User actions | |
| | 'USER_SIGNED_UP' | |
| | 'USER_SIGNED_IN' | |
| | 'PROFILE_UPDATED' | |
| | 'AVATAR_UPLOADED' | |
| | 'CHALLENGE_SUBMITTED' | |
| | 'CHALLENGE_COMPLETED' | |
| | 'DUEL_CREATED' | |
| | 'DUEL_SUBMIT' | |
| | 'EXAM_SUBMITTED' | |
| | 'EXAM_PASSED' | |
| | 'BADGE_EARNED' | |
| | 'TEAM_CREATED' | |
| | 'TEAM_JOINED' | |
| | 'TEAM_LEFT' | |
| | 'TEAM_INVITE_SENT' | |
| | 'TEAM_INVITE_ACCEPTED' | |
| | 'TEAM_INVITE_REJECTED' | |
| | 'TEAM_DELETED' | |
| | 'TEAM_IMAGE_UPLOADED' | |
| | 'NEWS_CREATED' | |
| | 'NEWS_UPDATED' | |
| | 'NEWS_DELETED' | |
| | 'PASSWORD_CHANGED' | |
| // Admin actions | |
| | 'USER_BANNED' | |
| | 'USER_UNBANNED' | |
| | 'USER_DELETED' | |
| | 'USER_ROLE_CHANGED' | |
| | 'COURSE_RELEASE_TOGGLED' | |
| // Security events | |
| | 'INVALID_TOKEN' | |
| | 'BANNED_ACCESS_ATTEMPT' | |
| | 'PRIVILEGE_ESCALATION' | |
| | 'RATE_LIMIT_HIT' | |
| | 'ROUTE_PROBING' | |
| | 'SUSPICIOUS_INPUT' | |
| | 'UNAUTHENTICATED_ACCESS' | |
| | 'TOKEN_REUSE_ATTEMPT'; | |
| interface LogEntry { | |
| user_id?: string; | |
| action: LogAction; | |
| details?: string; | |
| ip?: string; | |
| user_agent?: string; | |
| } | |
| export async function logActivity(entry: LogEntry): Promise<void> { | |
| try { | |
| const details = [ | |
| entry.details, | |
| entry.ip ? `IP:${entry.ip}` : null, | |
| entry.user_agent ? `UA:${entry.user_agent}` : null, | |
| ].filter(Boolean).join(' | '); | |
| await supabase | |
| .from('activity_logs') | |
| .insert({ | |
| user_id: entry.user_id || null, | |
| action: entry.action, | |
| details: details || null, | |
| }); | |
| } catch { | |
| // Silent fail — logging should never break the main flow | |
| } | |
| } | |