|
74 | 74 | return; |
75 | 75 | } |
76 | 76 |
|
77 | | - // Initialize session tracking for candidates only (IP, device, duplicate login check) |
| 77 | + // Initialize session tracking for candidates (make it async/non-blocking) |
78 | 78 | if (window.SessionTracking) { |
79 | | - candidateJoinBtn.textContent = 'Checking security...'; |
80 | | - const canProceed = await window.SessionTracking.initialize(sessionCode, 'candidate', name); |
81 | | - if (!canProceed) { |
82 | | - candidateJoinBtn.disabled = false; |
83 | | - candidateJoinBtn.textContent = 'Join Session'; |
84 | | - return; |
85 | | - } |
| 79 | + // Don't await - let tracking happen in background |
| 80 | + window.SessionTracking.initialize(sessionCode, 'candidate', name); |
| 81 | + // Remove the security check message - just proceed |
86 | 82 | } |
87 | 83 |
|
88 | 84 | Auth.joinAsCandidate(name); |
|
738 | 734 | ${users.length === 0 ? '<div style="color: #666;">No participants</div>' : ''} |
739 | 735 | `; |
740 | 736 |
|
| 737 | + // Check for fraud indicators from security warnings |
| 738 | + let fraudBadge = ''; |
| 739 | + if (fullSession && fullSession.security_warnings) { |
| 740 | + const warnings = Object.values(fullSession.security_warnings || {}); |
| 741 | + const candidateWarnings = warnings.filter(w => w.userType === 'candidate'); |
| 742 | + |
| 743 | + if (candidateWarnings.length > 0) { |
| 744 | + const hasVPN = candidateWarnings.some(w => w.type === 'vpn_detected'); |
| 745 | + const hasMultipleLogin = candidateWarnings.some(w => w.type === 'multiple_login'); |
| 746 | + |
| 747 | + if (hasMultipleLogin) { |
| 748 | + fraudBadge = '<span class="fraud-badge" style="background: #ff0000; color: white; padding: 2px 6px; border-radius: 3px; font-size: 10px; margin-left: 4px;">🚨 FRAUD</span>'; |
| 749 | + } else if (hasVPN) { |
| 750 | + fraudBadge = '<span class="fraud-badge" style="background: #ff9800; color: white; padding: 2px 6px; border-radius: 3px; font-size: 10px; margin-left: 4px;">⚠️ VPN</span>'; |
| 751 | + } |
| 752 | + } |
| 753 | + } |
| 754 | + |
741 | 755 | // Determine session status - Simple progression: Active -> In Progress -> Ended |
742 | 756 | let status = 'active'; |
743 | 757 | let statusBadge = ''; |
744 | 758 |
|
745 | 759 | if (session.isTerminated) { |
746 | 760 | // Session has ended |
747 | 761 | status = 'ended'; |
748 | | - statusBadge = '<span class="status-badge status-ended" style="background-color: #666;">Ended</span>'; |
| 762 | + statusBadge = '<span class="status-badge status-ended" style="background-color: #666;">Ended</span>' + fraudBadge; |
749 | 763 | } else if (candidates.length > 0 && interviewers.length > 0) { |
750 | 764 | // Both candidate and interviewer present - interview in progress |
751 | 765 | status = 'in-progress'; |
752 | | - statusBadge = '<span class="status-badge status-in-progress" style="background-color: #2196f3;">In Progress</span>'; |
| 766 | + statusBadge = '<span class="status-badge status-in-progress" style="background-color: #2196f3;">In Progress</span>' + fraudBadge; |
753 | 767 | } else { |
754 | 768 | // Session created but interview not started yet |
755 | 769 | status = 'active'; |
756 | | - statusBadge = '<span class="status-badge status-active" style="background-color: #4caf50;">Active</span>'; |
| 770 | + statusBadge = '<span class="status-badge status-active" style="background-color: #4caf50;">Active</span>' + fraudBadge; |
757 | 771 | } |
758 | 772 |
|
759 | 773 | // Format time |
|
0 commit comments