🌳
pt0/gamesapp/serverF/validateGameInputAI.mts
1import { inputLimits } from './gamesRlAI.mts'
4type GameActionParams = {
5 actionJSON: Record<string, unknown>
6 gameRoom: string
7}
9type ValidationResult = {
10 error?: string
11 actionJsonBytes: number
14/**
15 * Validate game action input sizes only (no rate limiting)
16 * Returns error message if validation fails, null if valid
17 * Used in test harness to verify limits don't break real games
18 */
19export const checkGameActionSizes = (params: GameActionParams): ValidationResult => {
20 const { actionJSON, gameRoom } = params
22 // Validate gameRoom length
23 if (gameRoom && gameRoom.length > inputLimits.gameRoomMaxChars) {
24 return { error: `gameRoom too long (max ${inputLimits.gameRoomMaxChars} chars)`, actionJsonBytes: 0 }
25 }
27 // Check total actionJSON size
28 const actionJsonStr = JSON.stringify(actionJSON)
29 const actionJsonBytes = actionJsonStr.length
31 if (actionJsonBytes > inputLimits.actionJsonMaxBytes) {
32 return { error: `Action payload too large (max ${Math.round(inputLimits.actionJsonMaxBytes / 1024)}KB)`, actionJsonBytes }
33 }
35 // Validate specific fields based on action type
36 const { playerAction, playerAlias, descriptionText, finishedTrails } = actionJSON as Record<string, unknown>
38 // playerAlias validation
39 if (playerAction === 'setPlayerAlias' && typeof playerAlias === 'string') {
40 if (playerAlias.length > inputLimits.playerAliasMaxChars) {
41 return { error: `Name too long (max ${inputLimits.playerAliasMaxChars} chars)`, actionJsonBytes }
42 }
43 }
45 // descriptionText validation
46 if (playerAction === 'submitDescription' && typeof descriptionText === 'string') {
47 if (descriptionText.length > inputLimits.descriptionTextMaxChars) {
48 return { error: `Description too long (max ${inputLimits.descriptionTextMaxChars} chars)`, actionJsonBytes }
49 }
50 }
52 // finishedTrails (drawing) validation
53 if (playerAction === 'submitDrawing' && finishedTrails) {
54 const trailsBytes = JSON.stringify(finishedTrails).length
55 if (trailsBytes > inputLimits.finishedTrailsMaxBytes) {
56 return { error: `Drawing too complex (max ${Math.round(inputLimits.finishedTrailsMaxBytes / 1024)}KB)`, actionJsonBytes }
57 }
58 }
60 return { actionJsonBytes }
63/**
64 * Validate game action input sizes (no rate limiting in stripped version)
65 * Call this at the start of the gameAction mutation
66 */
67export const validateGameActionInput = (params: GameActionParams) => {
68 const result = checkGameActionSizes(params)
69 if (result.error) silPubErr(result.error)