NovelBin/server.js
2025-03-02 22:36:26 +01:00

145 lines
4.6 KiB
JavaScript

// server.js
const express = require('express');
const session = require('express-session');
const bodyParser = require('body-parser');
const path = require('path');
const fs = require('fs');
const cors = require('cors');
const app = express();
const port = 25570;
// Dynamic CORS configuration: allow requests with or without an Origin header
app.use(cors({
origin: function (origin, callback) {
// Allow requests with no origin (like extension or curl requests)
if (!origin) return callback(null, true);
callback(null, true);
},
credentials: true
}));
// Setup persistent sessions with a 1-week cookie lifetime
app.use(session({
secret: 'my-secret-key',
resave: false,
saveUninitialized: true,
cookie: { maxAge: 7 * 24 * 60 * 60 * 1000 } // 1 week
}));
// Parse incoming request bodies
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
// (Optional) Serve static files from "public" if needed
app.use(express.static(path.join(__dirname, 'public')));
// Default route for testing
app.get('/', (req, res) => {
res.send("Welcome to the NovelSaver server. Please use the POST /api/login endpoint to log in.");
});
// Demo credentials
const demoUsername = "demo";
const demoPassword = "demo";
// In-memory storage for auto update tasks (keyed by session ID)
const userAutoUpdateTasks = {};
// In-memory storage for update logs, now keyed by username (account)
const userUpdatesLog = {};
// Example chapters array (if used elsewhere)
const chapters = [];
// POST /api/login - JSON-based login endpoint (records logs by username)
app.post('/api/login', (req, res) => {
console.log("Login attempt:", req.body);
const { username, password } = req.body;
if (username === demoUsername && password === demoPassword) {
req.session.username = username;
// Initialize the user's update log if it doesn't exist.
if (!userUpdatesLog[username]) {
userUpdatesLog[username] = [];
}
console.log("Login successful for account:", username);
res.json({ success: true, message: "Logged in successfully" });
} else {
console.log("Invalid credentials:", req.body);
res.status(401).json({ success: false, message: "Invalid credentials" });
}
});
// GET /api/status - returns the login status
app.get('/api/status', (req, res) => {
if (req.session.username) {
res.json({ loggedIn: true, username: req.session.username });
} else {
res.json({ loggedIn: false });
}
});
// POST /record - record the current chapter URL sent by the extension (by account)
app.post('/record', (req, res) => {
if (!req.session.username) {
return res.status(401).json({ error: 'Unauthorized' });
}
const recordUrl = req.body.url;
if (!recordUrl) {
return res.status(400).json({ error: 'URL required' });
}
// Use the username as the key for the log
const user = req.session.username;
if (!userUpdatesLog[user]) {
userUpdatesLog[user] = [];
}
// Check if this URL has already been recorded for this account.
const accountLog = userUpdatesLog[user];
const alreadyRecorded = accountLog.some(record => record.url === recordUrl);
if (alreadyRecorded) {
console.log(`Account ${user}: URL already recorded: ${recordUrl}`);
return res.json({ success: true, message: 'URL already recorded, ignoring.' });
}
const updateRecord = {
account: user,
url: recordUrl,
timestamp: new Date().toISOString()
};
userUpdatesLog[user].push(updateRecord);
fs.appendFile('updates.log', JSON.stringify(updateRecord) + '\n', err => {
if (err) {
console.error("Error writing update log:", err);
return res.status(500).json({ error: 'Logging failed' });
}
console.log(`Account ${user} recorded URL: ${recordUrl}`);
res.json({ success: true, message: 'URL recorded' });
});
});
// GET /logs - retrieve the update logs for the logged-in account
app.get('/logs', (req, res) => {
if (!req.session.username) {
return res.status(401).json({ error: 'Unauthorized' });
}
const user = req.session.username;
res.json({ updates: userUpdatesLog[user] || [] });
});
// GET /logout - logout endpoint (logs persist)
app.get('/logout', (req, res) => {
if (userAutoUpdateTasks[req.sessionID]) {
clearInterval(userAutoUpdateTasks[req.sessionID]);
delete userAutoUpdateTasks[req.sessionID];
}
req.session.destroy();
res.json({ success: true, message: "Logged out" });
});
app.listen(port, () => {
console.log(`Server running at http://192.168.0.226:${port}`);
});