Skip to content

Commit 6b15895

Browse files
committed
v0.2
1 parent 67c025b commit 6b15895

File tree

2 files changed

+169
-0
lines changed

2 files changed

+169
-0
lines changed

app/analytics/page.tsx

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,25 @@ export default function AnalyticsPage() {
4545
}
4646
}, [timeRange]);
4747

48+
const generateTestEvents = async () => {
49+
try {
50+
const eventTypes = ['AUTH_FAILURE', 'INVALID_TOKEN', 'SUSPICIOUS_ACTIVITY', 'RATE_LIMIT_EXCEEDED'];
51+
52+
for (const eventType of eventTypes) {
53+
await fetch('/api/test/security-events', {
54+
method: 'POST',
55+
headers: { 'Content-Type': 'application/json' },
56+
body: JSON.stringify({ eventType, count: 2 })
57+
});
58+
}
59+
60+
alert('Test security events generated! Refresh data in 30 seconds to see them.');
61+
} catch (error) {
62+
console.error('Failed to generate test events:', error);
63+
alert('Failed to generate test events');
64+
}
65+
};
66+
4867
useEffect(() => {
4968
fetchAnalytics();
5069
}, [timeRange, fetchAnalytics]);
@@ -107,6 +126,9 @@ export default function AnalyticsPage() {
107126
<button onClick={fetchAnalytics} className="button">
108127
Refresh Data
109128
</button>
129+
<button onClick={generateTestEvents} className="button test-button">
130+
Generate Test Events
131+
</button>
110132
</div>
111133
<p>Last updated: {data.lastUpdated ? new Date(data.lastUpdated).toLocaleString() : 'Never'} | Time Range: {data.timeRange}</p>
112134
</div>
@@ -365,6 +387,14 @@ export default function AnalyticsPage() {
365387
background: #0056b3;
366388
}
367389
390+
.test-button {
391+
background: #dc3545;
392+
}
393+
394+
.test-button:hover {
395+
background: #c82333;
396+
}
397+
368398
.analytics-grid {
369399
display: grid;
370400
gap: 2rem;
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
import { NextRequest, NextResponse } from 'next/server';
2+
import { securityMonitor } from '@/lib/security-monitor';
3+
4+
export async function POST(request: NextRequest) {
5+
try {
6+
const { eventType, count = 1 } = await request.json();
7+
8+
const validEventTypes = [
9+
'AUTH_FAILURE',
10+
'INVALID_TOKEN',
11+
'SUSPICIOUS_ACTIVITY',
12+
'RATE_LIMIT_EXCEEDED',
13+
'UNAUTHORIZED_ACCESS',
14+
'TOKEN_REUSE',
15+
'UNUSUAL_LOCATION',
16+
'PRIVILEGE_ESCALATION',
17+
'MALFORMED_REQUEST',
18+
'BRUTE_FORCE_ATTEMPT'
19+
];
20+
21+
if (!validEventTypes.includes(eventType)) {
22+
return NextResponse.json({
23+
error: 'Invalid event type',
24+
validTypes: validEventTypes
25+
}, { status: 400 });
26+
}
27+
28+
const mockContext = {
29+
userId: 'test-user-123',
30+
clientId: 'test-client-456',
31+
ipAddress: request.headers.get('x-forwarded-for') || '127.0.0.1',
32+
userAgent: request.headers.get('user-agent') || 'Test Agent',
33+
endpoint: '/test/security-events',
34+
organization: 'Test Organization',
35+
ssoProvider: 'google',
36+
mcpServerId: 'test-mcp-server'
37+
};
38+
39+
const events = [];
40+
for (let i = 0; i < count; i++) {
41+
const mockEvent = {
42+
eventType: eventType as 'AUTH_FAILURE' | 'INVALID_TOKEN' | 'SUSPICIOUS_ACTIVITY' | 'RATE_LIMIT_EXCEEDED' | 'UNAUTHORIZED_ACCESS' | 'TOKEN_REUSE' | 'UNUSUAL_LOCATION' | 'PRIVILEGE_ESCALATION' | 'MALFORMED_REQUEST' | 'BRUTE_FORCE_ATTEMPT',
43+
severity: getSeverityForEventType(eventType),
44+
details: {
45+
test: true,
46+
eventNumber: i + 1,
47+
timestamp: new Date(),
48+
description: getDescriptionForEventType(eventType)
49+
},
50+
riskScore: getRiskScoreForEventType(eventType)
51+
};
52+
events.push(mockEvent);
53+
}
54+
55+
await securityMonitor.logSecurityEvents(events, mockContext);
56+
57+
return NextResponse.json({
58+
success: true,
59+
message: `Generated ${count} ${eventType} event(s)`,
60+
events: events.length
61+
});
62+
63+
} catch (error) {
64+
console.error('Test security event generation error:', error);
65+
return NextResponse.json({
66+
error: 'Failed to generate security events',
67+
details: error instanceof Error ? error.message : 'Unknown error'
68+
}, { status: 500 });
69+
}
70+
}
71+
72+
function getSeverityForEventType(eventType: string): 'low' | 'medium' | 'high' | 'critical' {
73+
switch (eventType) {
74+
case 'PRIVILEGE_ESCALATION':
75+
case 'BRUTE_FORCE_ATTEMPT':
76+
return 'critical';
77+
case 'TOKEN_REUSE':
78+
case 'UNUSUAL_LOCATION':
79+
case 'UNAUTHORIZED_ACCESS':
80+
return 'high';
81+
case 'RATE_LIMIT_EXCEEDED':
82+
case 'INVALID_TOKEN':
83+
case 'AUTH_FAILURE':
84+
return 'medium';
85+
default:
86+
return 'low';
87+
}
88+
}
89+
90+
function getRiskScoreForEventType(eventType: string): number {
91+
switch (eventType) {
92+
case 'PRIVILEGE_ESCALATION': return 95;
93+
case 'BRUTE_FORCE_ATTEMPT': return 90;
94+
case 'TOKEN_REUSE': return 85;
95+
case 'UNUSUAL_LOCATION': return 70;
96+
case 'UNAUTHORIZED_ACCESS': return 75;
97+
case 'RATE_LIMIT_EXCEEDED': return 60;
98+
case 'INVALID_TOKEN': return 50;
99+
case 'AUTH_FAILURE': return 45;
100+
case 'SUSPICIOUS_ACTIVITY': return 40;
101+
case 'MALFORMED_REQUEST': return 30;
102+
default: return 25;
103+
}
104+
}
105+
106+
function getDescriptionForEventType(eventType: string): string {
107+
switch (eventType) {
108+
case 'AUTH_FAILURE': return 'Test authentication failure event';
109+
case 'INVALID_TOKEN': return 'Test invalid token usage';
110+
case 'SUSPICIOUS_ACTIVITY': return 'Test suspicious activity detection';
111+
case 'RATE_LIMIT_EXCEEDED': return 'Test rate limiting trigger';
112+
case 'UNAUTHORIZED_ACCESS': return 'Test unauthorized access attempt';
113+
case 'TOKEN_REUSE': return 'Test token reuse from different IP';
114+
case 'UNUSUAL_LOCATION': return 'Test unusual geographic location';
115+
case 'PRIVILEGE_ESCALATION': return 'Test privilege escalation attempt';
116+
case 'MALFORMED_REQUEST': return 'Test malformed request detection';
117+
case 'BRUTE_FORCE_ATTEMPT': return 'Test brute force attack simulation';
118+
default: return 'Test security event';
119+
}
120+
}
121+
122+
export async function GET() {
123+
return NextResponse.json({
124+
message: 'Security Event Generator API',
125+
usage: 'POST with { "eventType": "AUTH_FAILURE", "count": 5 }',
126+
availableEventTypes: [
127+
'AUTH_FAILURE',
128+
'INVALID_TOKEN',
129+
'SUSPICIOUS_ACTIVITY',
130+
'RATE_LIMIT_EXCEEDED',
131+
'UNAUTHORIZED_ACCESS',
132+
'TOKEN_REUSE',
133+
'UNUSUAL_LOCATION',
134+
'PRIVILEGE_ESCALATION',
135+
'MALFORMED_REQUEST',
136+
'BRUTE_FORCE_ATTEMPT'
137+
]
138+
});
139+
}

0 commit comments

Comments
 (0)