Skip to content

update all controllers with using to avoid using try catch everything #29

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 39 additions & 47 deletions controllers/authController.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require('express-async-errors');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const pool = require('../config/db');
Expand All @@ -6,62 +7,53 @@ const register = async (req, res, next) => {
const { name, email, password } = req.body;
const hashedPassword = await bcrypt.hash(password, 10);

try {
const result = await pool.query(
'INSERT INTO users (name, email, password) VALUES ($1, $2, $3) RETURNING id',
[name, email, hashedPassword]
);
res.status(201).json({ message: 'User registered', userId: result.rows[0].id });
} catch (error) {
next(error);
}
const result = await pool.query(
'INSERT INTO users (name, email, password) VALUES ($1, $2, $3) RETURNING id',
[name, email, hashedPassword]
);
res.status(201).json({ message: 'User registered', userId: result.rows[0].id });
};

const login = async (req, res) => {
const { email, password } = req.body;

try {
// Input validation
if (!email || !password) {
return res.status(400).json({ message: 'Email and password are required' });
}

// Check if the user exists
const result = await pool.query('SELECT * FROM users WHERE email = $1', [email]);
const user = result.rows[0];

if (!user) {
return res.status(401).json({ message: 'Invalid email or password' });
}
// Input validation
if (!email || !password) {
return res.status(400).json({ message: 'Email and password are required' });
}

// Compare password with hashed password in database
const passwordMatch = await bcrypt.compare(password, user.password);
if (!passwordMatch) {
return res.status(401).json({ message: 'Invalid email or password' });
}
// Check if the user exists
const result = await pool.query('SELECT * FROM users WHERE email = $1', [email]);
const user = result.rows[0];

// Generate a JWT token including user role
const token = jwt.sign(
{ userId: user.id, email: user.email, role: user.role }, // Include role in payload
process.env.JWT_SECRET,
{ expiresIn: '1h' } // Token expiration
);
if (!user) {
return res.status(401).json({ message: 'Invalid email or password' });
}

// Response with token and user details
res.status(200).json({
message: 'Login successful',
token,
user: {
id: user.id,
name: user.name,
email: user.email,
role: user.role,
},
});
} catch (error) {
console.error('Login error:', error);
res.status(500).json({ message: 'Server error during login' });
// Compare password with hashed password in database
const passwordMatch = await bcrypt.compare(password, user.password);
if (!passwordMatch) {
return res.status(401).json({ message: 'Invalid email or password' });
}

// Generate a JWT token including user role
const token = jwt.sign(
{ userId: user.id, email: user.email, role: user.role }, // Include role in payload
process.env.JWT_SECRET,
{ expiresIn: '1h' } // Token expiration
);

// Response with token and user details
res.status(200).json({
message: 'Login successful',
token,
user: {
id: user.id,
name: user.name,
email: user.email,
role: user.role,
},
});
};

module.exports = { register, login };
83 changes: 32 additions & 51 deletions controllers/metricsController.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require('express-async-errors');
const Metrics = require('../models/metrics');
const client = require('prom-client');
const jwt = require('jsonwebtoken');
Expand Down Expand Up @@ -34,40 +35,36 @@ const getMetrics = async (req, res) => {
};
*/

// Metrics endpoint handler
const getMetrics = async (req, res) => {
try {
// Get the Authorization header
const authHeader = req.headers['authorization'];
if (!authHeader || !authHeader.startsWith('Bearer ')) {
return res.status(401).json({ error: 'Unauthorized: No token provided' });
}
// Get the Authorization header
const authHeader = req.headers['authorization'];
if (!authHeader || !authHeader.startsWith('Bearer ')) {
return res.status(401).json({ error: 'Unauthorized: No token provided' });
}

// Extract the token
const token = authHeader.split(' ')[1];
// Extract the token
const token = authHeader.split(' ')[1];

// Verify and decode the token
const decoded = jwt.verify(token, process.env.JWT_SECRET);
const userId = decoded.userId; // Ensure your JWT payload contains a `userId`
// Verify and decode the token
const decoded = jwt.verify(token, process.env.JWT_SECRET);
const userId = decoded.userId; // Ensure your JWT payload contains a `userId`

if (!userId) {
return res.status(400).json({ error: 'Invalid token: userId missing' });
}
if (!userId) {
return res.status(400).json({ error: 'Invalid token: userId missing' });
}

// Set content type and retrieve metrics
res.set('Content-Type', register.contentType);
const metricsText = await register.metrics();
const metrics = parseMetrics(metricsText); // Helper function to parse metrics.
// Set content type and retrieve metrics
res.set('Content-Type', register.contentType);
const metricsText = await register.metrics();
const metrics = parseMetrics(metricsText); // Helper function to parse metrics.

// Save metrics to the database
await Metrics.saveMetricsToDatabase(userId, metrics);
// Save metrics to the database
await Metrics.saveMetricsToDatabase(userId, metrics);

// Send the metrics as a response
res.set('Content-Type', register.contentType);
res.send(metricsText);
} catch (error) {
console.error("Error in getMetrics:", error);
res.status(500).send({ error: "Failed to process metrics" });
}
// Send the metrics as a response
res.set('Content-Type', register.contentType);
res.send(metricsText);
};

function parseMetrics(metricsText) {
Expand All @@ -90,43 +87,27 @@ function parseMetrics(metricsText) {

const createMetric = async (req, res) => {
const { userId, metricName, metricValue } = req.body;
try {
const metric = await Metrics.create({ userId, metricName, metricValue });
res.status(201).json(metric);
} catch (error) {
res.status(500).json({ error: 'Failed to create metric' });
}
const metric = await Metrics.create({ userId, metricName, metricValue });
res.status(201).json(metric);
};

const getMetricsByUser = async (req, res) => {
const { userId } = req.params;
try {
const metrics = await Metrics.findByUserId(userId);
res.status(200).json(metrics);
} catch (error) {
res.status(500).json({ error: 'Failed to fetch metrics' });
}
const metrics = await Metrics.findByUserId(userId);
res.status(200).json(metrics);
};

const updateMetric = async (req, res) => {
const { id } = req.params;
const { metricName, metricValue } = req.body;
try {
const metric = await Metrics.update(id, { metricName, metricValue });
res.status(200).json(metric);
} catch (error) {
res.status(500).json({ error: 'Failed to update metric' });
}
const metric = await Metrics.update(id, { metricName, metricValue });
res.status(200).json(metric);
};

const deleteMetric = async (req, res) => {
const { id } = req.params;
try {
await Metrics.delete(id);
res.status(200).json({ message: 'Metric deleted successfully' });
} catch (error) {
res.status(500).json({ error: 'Failed to delete metric' });
}
await Metrics.delete(id);
res.status(200).json({ message: 'Metric deleted successfully' });
};

module.exports = {
Expand Down
101 changes: 41 additions & 60 deletions controllers/userController.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require('express-async-errors');
const User = require('../models/user');
const Joi = require('joi');
const logger = require('../utils/logger');
Expand All @@ -9,94 +10,74 @@ const userSchema = Joi.object({
password: Joi.string().min(8).required(),
});

const getUsers = async (req, res, next) => {
try {
const users = await User.getAll(req.query);
res.status(200).json(users);
} catch (error) {
next(error);
}
const getUsers = async (req, res) => {
const users = await User.getAll(req.query);
res.status(200).json(users);
};

const getUserById = async (req, res, next) => {
try {
const userId = parseInt(req.params.id, 10); // Ensure userId is a number
if (isNaN(userId)) {
return res.status(400).json({ error: 'Invalid user ID' });
}
const user = await User.getById(userId);
if (!user) return res.status(404).json({ message: 'User not found' });
res.status(200).json(user);
} catch (error) {
next(error);
const getUserById = async (req, res) => {
const userId = parseInt(req.params.id, 10); // Ensure userId is a number
if (isNaN(userId)) {
return res.status(400).json({ error: 'Invalid user ID' });
}
const user = await User.getById(userId);
if (!user) return res.status(404).json({ message: 'User not found' });
res.status(200).json(user);
};

const createUser = async (req, res, next) => {
try {
const { error, value } = userSchema.validate(req.body);
if (error) {
return res.status(400).json({ error: error.details[0].message });
}
if (!req.file) {
return res.status(400).json({ error: "Profile picture is required" });
}
value.picture = req.file.filename; // Add uploaded filename to user data
const userId = await User.create(value);
res.status(201).json({ message: "User added", userId });
} catch (error) {
next(error);
const createUser = async (req, res) => {
const { error, value } = userSchema.validate(req.body);
if (error) {
return res.status(400).json({ error: error.details[0].message });
}
if (!req.file) {
return res.status(400).json({ error: "Profile picture is required" });
}
value.picture = req.file.filename; // Add uploaded filename to user data
const userId = await User.create(value);
res.status(201).json({ message: "User added", userId });
};

const updateUser = async (req, res, next) => {
const updateUser = async (req, res) => {
const { id } = req.params;
const { name, email, password } = req.body;

if (!email || !email.match(/^[\w-]+(\.[\w-]+)*@([\w-]+\.)+[a-zA-Z]{2,7}$/)) {
return res.status(400).json({ error: 'Invalid email format' });
}

try {
const user = await User.getById(id);
if (!user) {
return res.status(404).json({ error: 'User not found' });
}
const user = await User.getById(id);
if (!user) {
return res.status(404).json({ error: 'User not found' });
}

// Assuming `User.update` returns the updated user
await User.update(id, { name, email, password });
// Assuming `User.update` returns the updated user
await User.update(id, { name, email, password });

// If `User.update` doesn't return the full user object, fetch it again
const updatedUserDetails = await User.getById(id);
// If `User.update` doesn't return the full user object, fetch it again
const updatedUserDetails = await User.getById(id);

return res.status(200).json({
message: `User modified with ID: ${id}`,
user: updatedUserDetails, // return the updated user object
});
} catch (error) {
next(error);
}
return res.status(200).json({
message: `User modified with ID: ${id}`,
user: updatedUserDetails, // return the updated user object
});
};

const deleteUser = async (req, res, next) => {
const deleteUser = async (req, res) => {
const { id } = req.params;

// Ensure that the ID is a valid integer
if (!Number.isInteger(Number(id))) {
return res.status(400).json({ error: 'Invalid user ID format' });
}

try {
const user = await User.getById(id); // Check if the user exists
if (!user) {
return res.status(404).json({ error: 'User not found' });
}

await User.delete(id); // Proceed with the deletion
res.status(200).json({ message: `User soft deleted with ID: ${id}` });
} catch (error) {
next(error);
const user = await User.getById(id); // Check if the user exists
if (!user) {
return res.status(404).json({ error: 'User not found' });
}

await User.delete(id); // Proceed with the deletion
res.status(200).json({ message: `User soft deleted with ID: ${id}` });
};

module.exports = {
Expand Down
10 changes: 10 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"cors": "^2.8.5",
"dotenv": "^16.4.5",
"express": "^4.19.2",
"express-async-errors": "^3.1.1",
"express-rate-limit": "^7.4.1",
"express-rate-limit-redis": "^0.0.4",
"helmet": "^8.0.0",
Expand Down