-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.js
More file actions
155 lines (133 loc) · 3.88 KB
/
server.js
File metadata and controls
155 lines (133 loc) · 3.88 KB
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
import "dotenv/config";
import express from 'express';
import cors from "cors";
import { GoogleGenAI } from "@google/genai";
import rateLimit from "express-rate-limit";
import cookieParser from "cookie-parser";
import path from "path";
import { fileURLToPath } from "url";
import connectDB from "./config/database.js";
import authRoutes from "./routes/auth.js";
import roadmapRoutes from "./routes/roadmap.js";
await connectDB();
const app = express();
app.set('trust proxy', 1);
const allowedOrigins = [
"http://127.0.0.1:5500",
"http://localhost:5500",
"http://localhost:3000",
"https://path4developers.vercel.app",
"https://path4developers.vercel.app/"
];
if (process.env.VERCEL_URL) {
allowedOrigins.push(`https://${process.env.VERCEL_URL}`);
}
if (process.env.CLIENT_URL && !allowedOrigins.includes(process.env.CLIENT_URL)) {
allowedOrigins.push(process.env.CLIENT_URL);
}
app.use(
cors({
origin: (origin, callback) => {
if (!origin || allowedOrigins.includes(origin)) {
callback(null, true);
} else {
callback(new Error("Not allowed by CORS"));
}
},
credentials: true,
})
);
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const requiredEnvVars = [
"GEMINI_API_KEY",
"MONGODB_URI",
"JWT_SECRET",
"SESSION_SECRET",
];
const missingEnvVars = requiredEnvVars.filter(
(varName) => !process.env[varName]
);
if (missingEnvVars.length > 0) {
console.error(
"ERRO: As seguintes variáveis de ambiente estão faltando:",
missingEnvVars.join(", ")
);
process.exit(1);
}
const port = process.env.PORT || 3000;
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cookieParser());
app.use(express.static(__dirname));
const apiLimiter = rateLimit({
windowMs: 1 * 60 * 1000, // 1 minute
max: 10,
message:
"Muitas requisições foram enviadas. Aguarde um minuto e tente novamente.",
standardHeaders: true,
legacyHeaders: false,
});
const authLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 5,
message: "Muitas tentativas de login. Tente novamente em 15 minutos.",
skipSuccessfulRequests: true,
});
const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
app.use("/api/auth", authLimiter, authRoutes);
app.use("/api/roadmap", roadmapRoutes);
app.post("/api/gemini", apiLimiter, async (req, res) => {
try {
const { prompt } = req.body;
if (!prompt) {
return res.status(400).json({ error: "O prompt é obrigatório" });
}
const response = await ai.models.generateContent({
model: "gemini-2.0-flash",
contents: prompt,
});
const text = response.text;
res.json({ text });
} catch (error) {
console.error("Erro ao chamar a API do Gemini:", error);
const status = error.status || 500;
res.status(status).json({
error: "Falha ao chamar a API do Gemini",
details: error.message
});
}
});
app.get("/api/health", (req, res) => {
res.json({
success: true,
message: "Servidor funcionando!",
timestamp: new Date().toISOString(),
});
});
// Fallback route to serve index.html for non-API routes
app.get(/^(?!\/api).*/, (req, res) => {
res.sendFile(path.resolve(__dirname, "index.html"));
});
app.use((err, req, res, next) => {
console.error("Erro não tratado:", err);
res.status(500).json({
success: false,
message:
"Um erro inesperado ocorreu. Por favor, tente novamente mais tarde.",
error: process.env.NODE_ENV === "development" ? err.message : undefined,
});
});
app.use((req, res) => {
res.status(404).json({
success: false,
message: "Rota não encontrada",
});
});
if (process.env.NODE_ENV !== "production") {
app.listen(port, () => {
console.log(`\nServidor rodando em http://localhost:${port}`);
console.log(`Acesse http://localhost:${port}/index.html no navegador\n`);
});
}
export default app;