Nextuschat / src /index.js
quan3s's picture
Upload index.js
37f201b verified
Raw
History Blame Contribute Delete
2.02 kB
import "dotenv/config";
import { createServer } from "http";
import app from "./app.js";
import { setupWS } from "./chat/ws.js";
import { logger } from "./lib/logger.js";
import { initDb, getUser, saveUser } from "./db/index.js";
import { connectRedis } from "./lib/redis.js";
import bcrypt from "bcryptjs";
const port = Number(process.env.PORT ?? 3000);
if (Number.isNaN(port) || port <= 0) throw new Error(`Invalid PORT: "${process.env.PORT}"`);
const httpServer = createServer(app);
function startListening(retriesLeft) {
httpServer.listen(port, async () => {
logger.info({ port }, "Nexus Chat server listening");
await seedAdmin();
});
httpServer.once("error", (err) => {
if (err.code === "EADDRINUSE" && retriesLeft > 0) {
logger.warn({ port, retriesLeft }, "Port in use, retrying in 3s…");
setTimeout(() => {
httpServer.removeAllListeners("error");
httpServer.close(() => startListening(retriesLeft - 1));
// Force-close if close hangs
setTimeout(() => startListening(retriesLeft - 1), 500);
}, 3000);
} else {
logger.error({ err }, "Server error");
process.exit(1);
}
});
}
async function main() {
await initDb();
logger.info("PostgreSQL ready");
await connectRedis();
setupWS(httpServer);
startListening(10);
}
main().catch((err) => {
logger.error({ err }, "Fatal startup error");
process.exit(1);
});
async function seedAdmin() {
const admins = [
{ email: "admin@nexus.vn", displayName: "quan5s" },
{ email: "quantri@nexus.vn", displayName: "quan5s" },
];
for (const { email, displayName } of admins) {
const existing = await getUser(email);
if (!existing) {
const passwordHash = await bcrypt.hash(process.env.SEED_ADMIN_PASSWORD ?? "11082012", 10);
await saveUser({
email, displayName, passwordHash, role: "admin",
avatar: null, nameTagColor: "red", createdAt: Date.now()
});
logger.info({ email }, "Admin seeded");
}
}
}