Skip to content

Commit 8d599b5

Browse files
batalabsrui-typelets
authored andcommitted
feat(code): add secure API proxy for code execution
- Add API endpoints with authentication and rate limiting - Implement secure error handling to prevent information disclosure
1 parent 93140e6 commit 8d599b5

File tree

3 files changed

+47
-0
lines changed

3 files changed

+47
-0
lines changed

.env.example

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,18 @@ MAX_FILE_SIZE_MB=50 # Maximum size per file (default: 50MB)
8585
# Documents: PDF, Plain Text, Markdown, JSON, CSV
8686
# Add new types in: src/lib/validation.ts
8787

88+
# ================================================================
89+
# CODE EXECUTION CONFIGURATION (Judge0 API)
90+
# ================================================================
91+
92+
# Judge0 API Configuration (OPTIONAL - for code execution features)
93+
# Get your API key from: https://rapidapi.com/judge0-official/api/judge0-ce
94+
# JUDGE0_API_KEY=your_judge0_rapidapi_key_here
95+
96+
# Code execution rate limits
97+
# Adjust based on your Judge0 plan limits (defaults: development=200, production=50)
98+
# CODE_EXEC_RATE_LIMIT_MAX=50 # Max code executions per 15 minutes per user
99+
88100
# ================================================================
89101
# BILLING & LIMITS CONFIGURATION
90102
# ================================================================
@@ -147,6 +159,13 @@ FREE_TIER_NOTE_LIMIT=100 # Note count limit for free users (default
147159
# API Keys: Use your service provider's dashboard
148160
# Database passwords: Use password managers
149161

162+
# Judge0 API Key Setup:
163+
# 1. Go to https://rapidapi.com/judge0-official/api/judge0-ce
164+
# 2. Sign up/login to RapidAPI
165+
# 3. Subscribe to Judge0 CE (free tier available)
166+
# 4. Copy your API key and uncomment JUDGE0_API_KEY above
167+
# 5. Code execution endpoints will be available: /api/code/*
168+
150169
# ================================================================
151170
# PRODUCTION DEPLOYMENT NOTES
152171
# ================================================================

README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ The backend API for the [Typelets Application](https://github.com/typelets/typel
2121
- 🔄 **Real-time Sync** via WebSockets for multi-device support
2222
-**Fast & Type-Safe** with TypeScript and Hono
2323
- 🐘 **PostgreSQL** with Drizzle ORM
24+
- 💻 **Code Execution** via secure Judge0 API proxy
2425

2526
## Tech Stack
2627

@@ -37,6 +38,7 @@ The backend API for the [Typelets Application](https://github.com/typelets/typel
3738
- pnpm 9.15.0+
3839
- PostgreSQL database (local installation or Docker)
3940
- Clerk account for authentication ([sign up here](https://dashboard.clerk.com))
41+
- Judge0 API key for code execution (optional - [get from RapidAPI](https://rapidapi.com/judge0-official/api/judge0-ce))
4042

4143
## Local Development Setup
4244

@@ -71,11 +73,14 @@ cp .env.example .env
7173
4. **Configure environment variables:**
7274
- Create a free account at [Clerk Dashboard](https://dashboard.clerk.com)
7375
- Create a new application
76+
- (Optional) Get Judge0 API key from [RapidAPI](https://rapidapi.com/judge0-official/api/judge0-ce)
7477
- Update `.env` with your settings:
7578

7679
```env
7780
CLERK_SECRET_KEY=sk_test_your_actual_clerk_secret_key_from_dashboard
7881
CORS_ORIGINS=http://localhost:5173,http://localhost:3000
82+
# Optional: For code execution features
83+
JUDGE0_API_KEY=your_judge0_rapidapi_key_here
7984
```
8085

8186
5. **Set up database schema:**
@@ -199,6 +204,13 @@ All `/api/*` endpoints require authentication via Bearer token in the Authorizat
199204
- `GET /api/files/:id` - Get file details
200205
- `DELETE /api/files/:id` - Delete file attachment
201206

207+
### Code Execution (requires Judge0 API key)
208+
209+
- `POST /api/code/execute` - Submit code for execution
210+
- `GET /api/code/status/:token` - Get execution status and results
211+
- `GET /api/code/languages` - Get supported programming languages
212+
- `GET /api/code/health` - Check Judge0 service connectivity
213+
202214
### WebSocket Real-time Sync
203215

204216
The API provides real-time synchronization via WebSocket connection at `ws://localhost:3000` (or your configured port).
@@ -261,6 +273,9 @@ The application uses the following main tables:
261273
| `WS_RATE_LIMIT_MAX_MESSAGES` | Max WebSocket messages per window | No | 300 |
262274
| `WS_MAX_CONNECTIONS_PER_USER`| Max WebSocket connections per user | No | 20 |
263275
| `WS_AUTH_TIMEOUT_MS` | WebSocket authentication timeout in milliseconds | No | 30000 (30 sec) |
276+
| `JUDGE0_API_KEY` | Judge0 API key for code execution | No* | - |
277+
278+
*Required only for code execution features
264279

265280
## Development
266281

@@ -278,6 +293,7 @@ src/
278293
│ ├── rate-limit.ts # Rate limiting middleware
279294
│ └── security.ts # Security headers middleware
280295
├── routes/
296+
│ ├── code.ts # Code execution routes (Judge0 proxy)
281297
│ ├── files.ts # File attachment routes
282298
│ ├── folders.ts # Folder management routes
283299
│ ├── notes.ts # Note management routes

src/server.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import foldersRouter from "./routes/folders";
1414
import notesRouter from "./routes/notes";
1515
import usersRouter from "./routes/users";
1616
import filesRouter from "./routes/files";
17+
import codeRouter from "./routes/code";
1718
import { VERSION } from "./version";
1819

1920
const maxFileSize = process.env.MAX_FILE_SIZE_MB
@@ -44,6 +45,16 @@ app.use(
4445
})
4546
);
4647

48+
// Rate limiting for code execution (higher limits in development)
49+
const codeRateLimit = process.env.NODE_ENV === 'development' ? 200 : 50;
50+
app.use(
51+
"/api/code/*",
52+
rateLimit({
53+
windowMs: 15 * 60 * 1000, // 15 minutes
54+
max: codeRateLimit, // Configurable based on environment
55+
})
56+
);
57+
4758
app.use(
4859
"*",
4960
bodyLimit({
@@ -124,6 +135,7 @@ app.use("*", authMiddleware);
124135
app.route("/api/users", usersRouter);
125136
app.route("/api/folders", foldersRouter);
126137
app.route("/api/notes", notesRouter);
138+
app.route("/api/code", codeRouter);
127139
app.route("/api", filesRouter);
128140

129141
app.onError((err, c) => {

0 commit comments

Comments
 (0)