Team Ai
Apppublic

sanket3280/code-execution

sourceHugging Faceupdated 11mo agoView on Hugging Face
0likes
suspiciousActivity.service.js198 linesDownload Raw Back to services
1const SuspiciousActivity = require('../models/SuspiciousActivity');2const CodeHistory = require('../models/CodeHistory');3 4/**5 * Detect large paste operations6 */7function detectLargePaste(code, previousCode) {8  if (!previousCode) return false;9  10  const diff = code.length - previousCode.length;11  const linesDiff = code.split('\n').length - previousCode.split('\n').length;12  13  return linesDiff > 50 || diff > 1000;14}15 16/**17 * Detect rapid problem switching18 */19async function detectRapidSwitching(participantId, challengeId) {20  try {21    // Get recent code history22    const recentHistory = await CodeHistory.find({23      participantId,24      challengeId,25      timestamp: { $gte: new Date(Date.now() - 60000) } // Last minute26    }).lean();27 28    // Count unique problems29    const uniqueProblems = new Set(recentHistory.map(h => h.problemId.toString()));30    31    return uniqueProblems.size > 3;32  } catch (error) {33    console.error('Error detecting rapid switching:', error);34    return false;35  }36}37 38/**39 * Detect code similarity using simple comparison40 */41async function detectCodeSimilarity(participantId, code, challengeId, problemId) {42  try {43    // Get all participant codes for same problem44    const allCodes = await CodeHistory.find({45      challengeId,46      problemId,47      participantId: { $ne: participantId }48    }).sort({ timestamp: -1 }).limit(50).lean();49 50    // Simple similarity check51    for (const otherCode of allCodes) {52      const similarity = calculateSimilarity(code, otherCode.code);53      if (similarity > 0.8) {54        return {55          isSimilar: true,56          similarity,57          otherParticipantId: otherCode.participantId58        };59      }60    }61 62    return { isSimilar: false };63  } catch (error) {64    console.error('Error detecting code similarity:', error);65    return { isSimilar: false };66  }67}68 69/**70 * Calculate simple similarity ratio71 */72function calculateSimilarity(str1, str2) {73  // Normalize strings74  const normalize = (str) => str.replace(/\s+/g, ' ').trim().toLowerCase();75  const s1 = normalize(str1);76  const s2 = normalize(str2);77  78  if (s1 === s2) return 1.0;79  if (s1.length === 0 || s2.length === 0) return 0.0;80  81  // Simple character-based similarity82  const longer = s1.length > s2.length ? s1 : s2;83  const shorter = s1.length > s2.length ? s2 : s1;84  85  let matches = 0;86  for (let i = 0; i < shorter.length; i++) {87    if (longer[i] === shorter[i]) matches++;88  }89  90  return matches / longer.length;91}92 93/**94 * Flag suspicious activity95 */96async function flagActivity(challengeId, participantId, activityType, severity, details) {97  try {98    const flag = await SuspiciousActivity.create({99      challengeId,100      participantId,101      activityType,102      severity: severity || 'medium',103      details: details || {},104      detectedAt: new Date(),105      status: 'pending'106    });107 108    return { success: true, flagId: flag._id };109  } catch (error) {110    console.error('Error flagging activity:', error);111    return { success: false, error: error.message };112  }113}114 115/**116 * Check code for suspicious patterns117 */118async function checkCodeForSuspiciousPatterns(io, participantId, code, previousCode, challengeId, problemId) {119  try {120    const flags = [];121 122    // Check for large paste123    if (detectLargePaste(code, previousCode)) {124      const linesDiff = code.split('\n').length - (previousCode ? previousCode.split('\n').length : 0);125      await flagActivity(challengeId, participantId, 'large_paste', 'high', {126        linesPasted: linesDiff,127        charactersPasted: code.length - (previousCode ? previousCode.length : 0)128      });129      130      flags.push('large_paste');131      132      // Broadcast to spectators133      io.to(`challenge:${challengeId}:spectators`).emit('spectator:suspiciousActivity', {134        flagId: Date.now(),135        participantId,136        participantName: 'Participant',137        activityType: 'large_paste',138        severity: 'high',139        details: { linesPasted: linesDiff },140        timestamp: Date.now()141      });142    }143 144    // Check for rapid switching145    const isRapidSwitching = await detectRapidSwitching(participantId, challengeId);146    if (isRapidSwitching) {147      await flagActivity(challengeId, participantId, 'rapid_switching', 'medium', {148        switchCount: 4149      });150      151      flags.push('rapid_switching');152      153      io.to(`challenge:${challengeId}:spectators`).emit('spectator:suspiciousActivity', {154        flagId: Date.now(),155        participantId,156        activityType: 'rapid_switching',157        severity: 'medium',158        timestamp: Date.now()159      });160    }161 162    // Check for code similarity (expensive, run less frequently)163    if (Math.random() < 0.1) { // 10% of the time164      const similarity = await detectCodeSimilarity(participantId, code, challengeId, problemId);165      if (similarity.isSimilar) {166        await flagActivity(challengeId, participantId, 'code_similarity', 'high', {167          similarity: similarity.similarity,168          otherParticipantId: similarity.otherParticipantId169        });170        171        flags.push('code_similarity');172        173        io.to(`challenge:${challengeId}:spectators`).emit('spectator:suspiciousActivity', {174          flagId: Date.now(),175          participantId,176          activityType: 'code_similarity',177          severity: 'high',178          details: { similarity: similarity.similarity },179          timestamp: Date.now()180        });181      }182    }183 184    return { flags };185  } catch (error) {186    console.error('Error checking for suspicious patterns:', error);187    return { flags: [] };188  }189}190 191module.exports = {192  detectLargePaste,193  detectRapidSwitching,194  detectCodeSimilarity,195  flagActivity,196  checkCodeForSuspiciousPatterns197};198