Download src/app/api/codes/validate/route.ts from HonzaH/Letschat: direct link, hf CLI and curl.
- Browser
- Download file 4.14 kB
-
https://huggingface.co/spaces/HonzaH/Letschat/resolve/main/src/app/api/codes/validate/route.ts
- Command line
-
hf download hf://spaces/HonzaH/Letschat/src/app/api/codes/validate/route.ts
-
curl -L -o route.ts https://huggingface.co/spaces/HonzaH/Letschat/resolve/main/src/app/api/codes/validate/route.ts
4.14 kB
| import { NextRequest, NextResponse } from 'next/server' | |
| import { codeEntrySchema } from 'lib/validations/code' | |
| import { getAnonymousSession, setAnonymousSession } from 'lib/session' | |
| import { generateSessionHash } from 'lib/codes' | |
| import { getCodeByCode, updateCode } from 'lib/persistence' | |
| import { assertNotBlocked, noteFailure, resetFailures } from 'lib/rateLimiter' | |
| import { logEvent } from 'lib/logger' | |
| export async function POST(request: NextRequest) { | |
| try { | |
| const body = await request.json() | |
| const validation = codeEntrySchema.safeParse(body) | |
| if (!validation.success) { | |
| return NextResponse.json( | |
| { error: 'Neplatnì form t k¢du' }, | |
| { status: 400 } | |
| ) | |
| } | |
| const { code } = validation.data | |
| const headers = (request as any).headers | |
| const ip = headers?.get?.('x-forwarded-for') || 'unknown' | |
| const ua = headers?.get?.('user-agent') || 'unknown' | |
| const deviceKey = `${ip}:${ua}` | |
| try { | |
| assertNotBlocked(ip) | |
| assertNotBlocked(deviceKey) | |
| } catch (_e) { | |
| return NextResponse.json({ error: 'Pý¡liç mnoho pokus… – zkuste to pozdØji' }, { status: 429 }) | |
| } | |
| // Check if code exists via persistence (local-first) | |
| const codeData = await getCodeByCode(code) | |
| if (!codeData) { | |
| noteFailure(ip, { limit: 3, windowMs: 5 * 60 * 1000, blockMs: 5 * 60 * 1000, escalateAfterBlocks: 3, escalateBlockMs: 24 * 60 * 60 * 1000 }) | |
| noteFailure(deviceKey, { limit: 3, windowMs: 5 * 60 * 1000, blockMs: 5 * 60 * 1000, escalateAfterBlocks: 3, escalateBlockMs: 24 * 60 * 60 * 1000 }) | |
| return NextResponse.json( | |
| { error: 'K¢d nenalezen' }, | |
| { status: 404 } | |
| ) | |
| } | |
| // Code is not used yet - first time | |
| if (codeData.used !== 1) { | |
| await logEvent({ | |
| module: 'codes', | |
| operation: 'validate_unused', | |
| data: { codeId: codeData.id }, | |
| ip, | |
| userAgent: ua | |
| }) | |
| return NextResponse.json({ | |
| redirect: `/setup?code=${code.toUpperCase()}`, | |
| needsSetup: true | |
| }) | |
| } | |
| // Code is used - check access method | |
| if (codeData.pin_hash) { | |
| // Protected by PIN | |
| const session = await getAnonymousSession() | |
| if (session && session.codeId === codeData.id) { | |
| // User has valid session | |
| return NextResponse.json({ | |
| redirect: `/room/${codeData.room_id}?code=${code.toUpperCase()}`, | |
| roomId: codeData.room_id | |
| }) | |
| } else { | |
| // Needs PIN | |
| return NextResponse.json({ | |
| redirect: `/enter-pin?code=${code.toUpperCase()}`, | |
| needsPin: true | |
| }) | |
| } | |
| } else { | |
| // No PIN protection - ensure session exists and room is set | |
| if (!codeData.room_id) { | |
| return NextResponse.json( | |
| { error: 'M¡stnost pro tento k¢d nen¡ dostupn ' }, | |
| { status: 500 } | |
| ) | |
| } | |
| const session = await getAnonymousSession() | |
| const hasValidSession = session && session.codeId === codeData.id && session.sessionHash === codeData.session_hash | |
| if (!hasValidSession) { | |
| const userAgent = request.headers.get('user-agent') || '' | |
| const sessionHash = codeData.session_hash || generateSessionHash(code, userAgent) | |
| await setAnonymousSession({ | |
| codeId: codeData.id, | |
| sessionHash, | |
| roomId: codeData.room_id, | |
| expiresAt: Date.now() + (10 * 365 * 24 * 60 * 60 * 1000) // 10 let stejne jako flow bez PIN | |
| }) | |
| await updateCode(codeData.id, { session_hash: sessionHash }) | |
| } | |
| await logEvent({ | |
| module: 'codes', | |
| operation: 'validate_success', | |
| data: { codeId: codeData.id, roomId: codeData.room_id }, | |
| ip, | |
| userAgent: ua | |
| }) | |
| resetFailures(ip) | |
| resetFailures(deviceKey) | |
| return NextResponse.json({ | |
| redirect: `/room/${codeData.room_id}?code=${code.toUpperCase()}`, | |
| roomId: codeData.room_id | |
| }) | |
| } | |
| } catch (error) { | |
| console.error('Code validation error:', error) | |
| return NextResponse.json( | |
| { error: 'Vnitýn¡ chyba serveru' }, | |
| { status: 500 } | |
| ) | |
| } | |
| } | |