require('dotenv').config(); const express = require('express'); const mongoose = require('mongoose'); const session = require('express-session'); const path = require('path'); const fetch = require('node-fetch'); const cors = require('cors'); const logger = require('./logger'); const bcrypt = require('bcryptjs'); const User = require('./models/User'); // Assuming User model is defined for your MongoDB users const app = express(); const port = process.env.PORT || 3001; // MongoDB connection setup const mongoUri = process.env.MONGO_URI; mongoose.connect(mongoUri) .then(() => logger.info('Connected to MongoDB successfully')) .catch(err => logger.error('Failed to connect to MongoDB:', err)); // Configuration and constants setup const config = { SESSION_SECRET: process.env.SESSION_SECRET || "default-session-secret" }; const STREMIO_API = { BASE_URL: "https://api.strem.io/api", LOGIN: "/login", REGISTER: "/register", ADDON_COLLECTION_GET: "/addonCollectionGet", ADDON_COLLECTION_SET: "/addonCollectionSet", LOGOUT: "/logout" }; const corsOptions = { origin: "*", methods: ["GET", "POST", "DELETE", "PUT", "PATCH"], allowedHeaders: ["Content-Type", "Authorization"], credentials: true, maxAge: 86400 }; // Process error handlers process.on("uncaughtException", (error) => { logger.error("Uncaught Exception:", error); process.exit(1); }); process.on("unhandledRejection", (reason, promise) => { logger.error("Unhandled Rejection at:", promise, "reason:", reason); }); // Middleware setup app.use(cors(corsOptions)); app.options("*", cors(corsOptions)); app.use(express.json({ limit: "50mb" })); app.use(express.static("public")); app.use(session({ secret: config.SESSION_SECRET, resave: false, saveUninitialized: true, cookie: { secure: false, maxAge: 24 * 60 * 60 * 1000 } })); // POST login route app.post('/api/login', async (req, res) => { const { email, password } = req.body; try { logger.info('Attempting login for email:', email); const user = await User.findOne({ email }); if (!user) { logger.info('User not found'); return res.status(401).send('User not found'); } const isMatch = await bcrypt.compare(password, user.password); if (!isMatch) { logger.info('Invalid credentials'); return res.status(401).send('Invalid credentials'); } // Session handling req.session.user = user; // Save user to session res.status(200).send({ message: 'Login successful' }); } catch (error) { logger.error('Login error:', error); // Send generic error message if unexpected token error occurs if (error.message && error.message.startsWith('Unexpected token')) { return res.status(500).send('Internal server error: invalid response format'); } else { return res.status(500).send('Internal server error'); } } }); // Register route for user creation with bcrypt hashing app.post('/api/register', async (req, res) => { const { email, password } = req.body; try { const hashedPassword = await bcrypt.hash(password, 10); const newUser = new User({ email, password: hashedPassword }); await newUser.save(); res.status(201).send({ message: 'User registered successfully' }); } catch (error) { logger.error('Registration error:', error); res.status(500).send('Internal server error'); } }); // Hugging Face API Example Function (to demonstrate API interaction) async function fetchHuggingFaceData(apiUrl) { try { const response = await fetch(apiUrl); if (!response.ok) { throw new Error(`HTTP Error: ${response.status}`); } const data = await response.json(); logger.info('Hugging Face API response:', data); return data; } catch (error) { logger.error('Failed to fetch Hugging Face API:', error); throw error; } } // Server initialization async function startServer() { try { app.listen(port, () => { logger.info(`Server started on port ${port}`); }); } catch (error) { logger.error('Failed to initialize:', error); process.exit(1); } } startServer(); module.exports = app;