Major refactor: security, performance, and code organization

Security:
- DeepSeek API moved to server-side proxy with rate limiting (20 req/min)
- Whitelist validation for all POST/PUT routes
- Cookie security (secure, sameSite, httpOnly in production)
- Input validation for messages, tokens, temperature
- Sanitized hasOwnProperty to prevent prototype pollution

Performance:
- Lazy loading for chat messages (sliding window of 20)
- Streaming response throttling (50ms batches)
- Scroll optimization (only scroll on new messages)
- AbortController fix for stop button

Code organization:
- GamePage refactored from ~1170 to ~750 lines
- New hooks: useGameSession, useStreamingResponse, useCharacterDetection, useLazyMessages
- New components: MessageList, ChatInput, SessionSelector, CharacterPanel
- Fixed ESLint errors

Features:
- OOC mode button for direct AI instructions
- Message versions (aiResponse) now persist to DB
- playerId saved in sessions
This commit is contained in:
Alexej Wolff
2026-05-05 23:41:52 +02:00
parent bbefa114f8
commit 68c2b129fa
23 changed files with 1817 additions and 553 deletions
+64
View File
@@ -289,6 +289,28 @@
box-sizing: border-box;
}
.load-more-messages-btn {
align-self: center;
padding: 0.5rem 1rem;
margin-bottom: 0.5rem;
background: rgba(255, 255, 255, 0.08);
border: 1px solid rgba(255, 255, 255, 0.15);
border-radius: 20px;
color: rgba(255, 255, 255, 0.7);
font-size: 0.85rem;
cursor: pointer;
transition: all 0.2s ease;
}
.load-more-messages-btn:hover {
background: rgba(255, 255, 255, 0.12);
color: rgba(255, 255, 255, 0.9);
}
.load-more-messages-btn:active {
transform: scale(0.98);
}
.message {
max-width: 88%;
animation: fadeIn 0.25s ease;
@@ -710,6 +732,48 @@
background: #b91c1c;
}
/* OOC Mode Button */
.ooc-btn {
padding: 0.4rem 0.6rem;
background: transparent;
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 12px;
color: #888;
font-size: 0.7rem;
font-weight: 600;
cursor: pointer;
transition: all 0.2s;
flex-shrink: 0;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.ooc-btn:hover {
background: rgba(255, 255, 255, 0.1);
color: #aaa;
}
.ooc-btn.active {
background: #f59e0b;
border-color: #f59e0b;
color: #000;
}
.ooc-btn.active:hover {
background: #d97706;
border-color: #d97706;
}
/* OOC Mode Input Container */
.input-container.ooc-mode {
border-color: #f59e0b;
background: rgba(245, 158, 11, 0.1);
}
.input-container.ooc-mode textarea::placeholder {
color: #f59e0b;
}
/* Streaming message animation */
.message.streaming .message-text {
position: relative;