File size: 4,473 Bytes
062c414
 
 
 
9953d0a
 
 
062c414
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10299c3
062c414
10299c3
 
 
 
 
062c414
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
import { NextResponse } from 'next/server'
import fs from 'fs'
import path from 'path'

// Use /tmp for temporary message storage
// Messages will reset on rebuilds, which is fine for a global chat
const dataFilePath = path.join('/tmp', 'messages.json')

// Simple bad word list (expand as needed)
const BAD_WORDS = [
    // English
    'badword', 'spam', 'toxic', 'hate', 'violence', 'kill', 'stupid', 'idiot',
    'fuck', 'fuxk', 'fck', 'shit', 'sh!t', 'bitch', 'asshole', 'damn', 'hell',
    'crap', 'piss', 'dick', 'cock', 'pussy', 'bastard', 'slut', 'whore',
    // Spanish
    'puto', 'mierda', 'coño', 'cabron', 'pendejo', 'joder',
    // French
    'merde', 'putain', 'connard', 'salope', 'encule',
    // German
    'scheisse', 'arschloch', 'schlampe', 'fotze',
    // Italian
    'cazzo', 'merda', 'vaffanculo', 'stronzo',
    // Portuguese
    'porra', 'caralho', 'merda', 'puta',
    // Russian (transliterated)
    'cyka', 'blyat', 'nahui', 'pizda',
    // Hindi (transliterated)
    'madarchod', 'bhenchod', 'chutiya', 'kutta', 'kamina'
]

interface Message {
    id: string
    text: string
    sender: string
    userId: string
    timestamp: number
}

const getMessages = (): Message[] => {
    try {
        if (!fs.existsSync(dataFilePath)) {
            fs.writeFileSync(dataFilePath, '[]', 'utf8')
            return []
        }
        const fileData = fs.readFileSync(dataFilePath, 'utf8')
        return JSON.parse(fileData)
    } catch (error) {
        console.error('Error reading messages:', error)
        return []
    }
}

const saveMessages = (messages: Message[]) => {
    try {
        fs.writeFileSync(dataFilePath, JSON.stringify(messages, null, 2), 'utf8')
    } catch (error) {
        console.error('Error saving messages:', error)
    }
}

export async function GET() {
    const messages = getMessages()
    return NextResponse.json(messages, {
        headers: { 'Content-Type': 'application/json; charset=utf-8' }
    })
}

export async function POST(request: Request) {
    try {
        const body = await request.json()
        const { text, sender, userId } = body

        // 1. Validation: Length
        if (!text || text.length > 200) {
            return NextResponse.json({ error: 'Message too long (max 200 chars)' }, { status: 400 })
        }

        if (!text.trim()) {
            return NextResponse.json({ error: 'Message cannot be empty' }, { status: 400 })
        }

        // 2. Validation: Toxicity (whole word matching only)
        const lowerText = text.toLowerCase()
        const containsBadWord = BAD_WORDS.some(word => {
            // Use word boundaries to match whole words only
            const regex = new RegExp(`\\b${word.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\b`, 'i')
            return regex.test(text)
        })
        if (containsBadWord) {
            return NextResponse.json({ error: 'Message contains inappropriate content' }, { status: 400 })
        }

        const messages = getMessages()
        const now = Date.now()

        // 3. Validation: Spam (Rate Limiting)
        // Check if this user sent a message in the last 2 seconds
        const lastMessageFromUser = messages
            .filter(m => m.userId === userId)
            .sort((a, b) => b.timestamp - a.timestamp)[0]

        if (lastMessageFromUser && (now - lastMessageFromUser.timestamp) < 2000) {
            return NextResponse.json({ error: 'You are sending messages too fast. Please wait.' }, { status: 429 })
        }

        // Check for duplicate message from same user
        if (lastMessageFromUser && lastMessageFromUser.text === text) {
            return NextResponse.json({ error: 'Do not send duplicate messages.' }, { status: 400 })
        }

        const newMessage: Message = {
            id: Math.random().toString(36).substring(2, 15),
            text: text.trim(),
            sender: sender || 'Anonymous',
            userId: userId,
            timestamp: now
        }

        // Keep only last 100 messages to prevent file from growing too large
        const updatedMessages = [...messages, newMessage].slice(-100)

        saveMessages(updatedMessages)

        return NextResponse.json(updatedMessages, {
            headers: { 'Content-Type': 'application/json; charset=utf-8' }
        })
    } catch (error) {
        console.error('Error processing message:', error)
        return NextResponse.json({ error: 'Internal Server Error' }, { status: 500 })
    }
}