node-ejs-renderer/routes/api.js

159 lines
6.1 KiB
JavaScript
Raw Normal View History

2024-06-09 13:55:01 -04:00
const { authenticate, createSession, validateSession } = require('../acl');
const cookie = require('cookie');
const users = require('../users'); // Hardcoded users
const { User, Achievement } = require('../models'); // Sequelize models
const { getLearningContent } = require('../openai');
const bcrypt = require('bcrypt');
// Function to handle user login
const loginUser = async (req, res) => {
let body = '';
req.on('data', chunk => {
body += chunk.toString();
});
req.on('end', async () => {
try {
const { username, password } = JSON.parse(body);
let user = await User.findOne({ where: { username } });
if (!user && users[username]) {
user = { username, password: users[username].password, role: users[username].role };
}
if (user && bcrypt.compareSync(password, user.password)) {
const token = await createSession(username);
res.setHeader('Set-Cookie', cookie.serialize('token', token, {
httpOnly: true,
maxAge: 3600 // 1 hour
}));
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ message: 'Login successful', token }));
} else {
res.writeHead(401, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: 'Invalid username or password' }));
}
} catch (err) {
res.writeHead(400, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: 'Invalid request format - ' + err }));
}
});
};
// Function to handle user registration
const registerUser = async (req, res) => {
let body = '';
req.on('data', chunk => {
body += chunk.toString();
});
req.on('end', async () => {
try {
const { username, password, role } = JSON.parse(body);
if (!username || !password || !role) {
res.writeHead(400, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: 'Missing required fields' }));
return;
}
const existingUser = await User.findOne({ where: { username } });
if (existingUser || users[username]) {
res.writeHead(409, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: 'User already exists' }));
return;
}
// Save user to the database
await User.create({ username, password, role });
// Save user to the hardcoded users list
users[username] = { password, role };
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ message: 'User registered successfully' }));
} catch (err) {
res.writeHead(400, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: 'Invalid request format' }));
}
});
};
// Function to fetch user achievements
const fetchAchievements = async (req, res) => {
try {
const session = await validateSession(req.cookies.token);
if (session && session.data.user) {
const achievements = await Achievement.findAll({ where: { userId: session.data.user.id } });
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify(achievements));
} else {
res.writeHead(401, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: 'Unauthorized' }));
}
} catch (err) {
res.writeHead(500, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: 'Failed to fetch achievements' }));
}
};
// Function to fetch learning content from OpenAI
const fetchLearningContent = async (req, res) => {
let body = '';
req.on('data', chunk => {
body += chunk.toString();
});
req.on('end', async () => {
try {
const { prompt } = JSON.parse(body);
const content = await getLearningContent(prompt);
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ content }));
} catch (err) {
res.writeHead(500, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: 'Failed to fetch learning content' }));
}
});
};
// Function to handle adding achievements
const addAchievement = async (req, res) => {
let body = '';
req.on('data', chunk => {
body += chunk.toString();
});
req.on('end', async () => {
try {
const { userId, badge } = JSON.parse(body);
if (!userId || !badge) {
res.writeHead(400, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: 'Missing required fields' }));
return;
}
await Achievement.create({ userId, badge });
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ message: 'Achievement added successfully' }));
} catch (err) {
res.writeHead(500, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: 'Failed to add achievement' }));
}
});
};
// Export the API request handler
const handleApiRequest = (req, res) => {
if (req.url === '/api/login' && req.method === 'POST') {
loginUser(req, res);
} else if (req.url === '/api/register' && req.method === 'POST') {
registerUser(req, res);
} else if (req.url === '/api/achievements' && req.method === 'GET') {
fetchAchievements(req, res);
} else if (req.url === '/api/achievements' && req.method === 'POST') {
addAchievement(req, res);
} else if (req.url === '/api/learning-content' && req.method === 'POST') {
fetchLearningContent(req, res);
} else {
res.writeHead(404, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: 'Not Found' }));
}
};
module.exports = { handleApiRequest };