diff --git a/apps/backend/bun.lock b/apps/backend/bun.lock index 167e10a..9773556 100644 --- a/apps/backend/bun.lock +++ b/apps/backend/bun.lock @@ -21,7 +21,7 @@ "eslint-config-prettier": "^10.1.8", "prettier": "^3.6.2", "ts-node": "^10.9.2", - "typescript": "5.8.3", + "typescript": "^5.9.2", "typescript-eslint": "^8.30.0", }, "peerDependencies": { diff --git a/apps/backend/index.ts b/apps/backend/index.ts new file mode 100644 index 0000000..f67b2c6 --- /dev/null +++ b/apps/backend/index.ts @@ -0,0 +1 @@ +console.log("Hello via Bun!"); \ No newline at end of file diff --git a/apps/backend/package.json b/apps/backend/package.json index 609b209..b7186e0 100644 --- a/apps/backend/package.json +++ b/apps/backend/package.json @@ -1,4 +1,5 @@ { + "name": "backend", "module": "index.ts", "dependencies": { @@ -22,7 +23,7 @@ "eslint-config-prettier": "^10.1.8", "prettier": "^3.6.2", "ts-node": "^10.9.2", - "typescript": "5.8.3", + "typescript": "^5.8.3", "typescript-eslint": "^8.30.0" }, "private": true, @@ -30,7 +31,9 @@ "dev": "bun run --watch src/index.ts", "build": "bun build src/index.ts --outdir ./dist --target node", "lint": "bun eslint src/**/*.ts", - "format": "bun prettier --write 'src/**/*.ts'" + "format": "bun prettier --write 'src/**/*.ts'", + "setup": "bun run scripts/setup.ts", + "clean": "bun run scripts/clean.ts" }, "type": "module" } diff --git a/apps/backend/scripts/clean.ts b/apps/backend/scripts/clean.ts new file mode 100644 index 0000000..7e8a815 --- /dev/null +++ b/apps/backend/scripts/clean.ts @@ -0,0 +1,15 @@ +import { fileManager } from '../src/utils/fileManager'; + +async function main() { + const customPath = process.argv[2]; + + try { + await fileManager.cleanupProject(customPath); + console.log(' Cleanup completed successfully'); + } catch (error) { + console.error(' Cleanup failed:', error instanceof Error ? error.message : error); + process.exit(1); + } +} + +await main(); \ No newline at end of file diff --git a/apps/backend/scripts/setup.ts b/apps/backend/scripts/setup.ts new file mode 100644 index 0000000..ed6b364 --- /dev/null +++ b/apps/backend/scripts/setup.ts @@ -0,0 +1,17 @@ +import { fileManager } from '../src/utils/fileManager'; + +async function main() { + try { + const projectPath = await fileManager.setupProject(); + console.log('Project created at:', projectPath); + console.log('\nTo clean up later, run:'); + console.log('bun run clean'); + console.log('or to clean a specific path:'); + console.log('bun run clean -- /path/to/project'); + } catch (error) { + console.error('Setup failed:', error instanceof Error ? error.message : error); + process.exit(1); + } +} + +await main(); \ No newline at end of file diff --git a/apps/backend/src/index.ts b/apps/backend/src/index.ts index 663963d..6ad80b8 100644 --- a/apps/backend/src/index.ts +++ b/apps/backend/src/index.ts @@ -1,9 +1,46 @@ import express from 'express'; +import helmet from 'helmet'; +import cors from 'cors'; import { setupProject, getSanitizedDirName, createRustProject } from './utils/fileManager'; const app = express(); + +// Security middleware +app.use( + helmet({ + contentSecurityPolicy: { + directives: { + defaultSrc: ["'self'"], + styleSrc: ["'self'", "'unsafe-inline'"], + scriptSrc: ["'self'"], + imgSrc: ["'self'", 'data:', 'https:'], + }, + }, + crossOriginEmbedderPolicy: false, + hsts: { + maxAge: 31536000, + includeSubDomains: true, + preload: true, + }, + }) +); + +// CORS configuration +app.use( + cors({ + origin: 'http://localhost:4200', + credentials: true, + methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'], + allowedHeaders: ['Content-Type', 'Authorization', 'Accept'], + optionsSuccessStatus: 200, + }) +); + +// Body parsing middleware app.use(express.json()); +app.use(express.urlencoded({ extended: true })); +// Routes app.get('/', (_, res) => res.send('Hello from Backend!' + '
' + 'The best online soroban compiler is coming...') ); @@ -45,4 +82,24 @@ app.post('/api/test-filemanager', async (req, res) => { } }); -app.listen(3000, () => console.log('Server on http://localhost:3000')); +// Error handling middleware +app.use((err: Error, req: express.Request, res: express.Response, next: express.NextFunction) => { + res.status(500).json({ + error: 'Internal Server Error', + message: process.env.NODE_ENV === 'development' ? err.message : 'Something went wrong', + }); +}); + +// 404 handler +app.use((req, res) => { + res.status(404).json({ + error: 'Not Found', + message: `Route ${req.originalUrl} not found`, + }); +}); + +// Start server +app.listen(3000, () => { + console.log('Server on http://localhost:3000'); + console.log('CORS restricted to http://localhost:4200'); +});