Skip to content
Open
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
36 changes: 21 additions & 15 deletions app.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,31 @@
const express = require('express')
const logger = require('morgan')
const cors = require('cors')
const express = require('express');
const logger = require('morgan');
const cors = require('cors');

const contactsRouter = require('./routes/api/contacts')
const authRouter = require('./routes/api/auth');
const usersRouter = require('./routes/api/users');
const contactsRouter = require('./routes/api/contacts');

const app = express()
const app = express();

const formatsLogger = app.get('env') === 'development' ? 'dev' : 'short'
const formatsLogger = app.get('env') === 'development' ? 'dev' : 'short';

app.use(logger(formatsLogger))
app.use(cors())
app.use(express.json())
app.use(logger(formatsLogger));
app.use(cors());
app.use(express.json());
app.use(express.static('public')); // Asigură-te că ai public pentru a servi fișiere statice

app.use('/api/contacts', contactsRouter)
app.use('/avatars', express.static('public/avatars'));
app.use('/api/auth', authRouter);
app.use('/api/users', usersRouter);
app.use('/api/contacts', contactsRouter);

app.use((req, res) => {
res.status(404).json({ message: 'Not found' })
})
res.status(404).json({ message: 'Not found' });
});

app.use((err, req, res, next) => {
res.status(500).json({ message: err.message })
})
res.status(500).json({ message: err.message });
});

module.exports = app
module.exports = app;
11 changes: 11 additions & 0 deletions config/db.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const mongoose = require('mongoose');
require('dotenv').config();

mongoose.connect(process.env.MONGODB_URI)
.then(() => console.log('Connected to MongoDB'))
.catch(err => {
console.error('MongoDB connection error:', err);
process.exit(1);
});

module.exports = mongoose;
47 changes: 47 additions & 0 deletions controllers/authController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
const User = require('../models/userModel');
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');

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

try {
const existingUser = await User.findOne({ email });
if (existingUser) {
return res.status(400).json({ message: 'User already exists' });
}

const hashedPassword = await bcrypt.hash(password, 10);
const newUser = new User({ email, password: hashedPassword });

await newUser.save();
res.status(201).json({ message: 'User registered successfully' });
} catch (error) {
console.error(error);
res.status(500).json({ message: 'Server error' });
}
};

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

try {
const user = await User.findOne({ email });
if (!user) {
return res.status(401).json({ message: 'Invalid email or password' });
}

const isMatch = await bcrypt.compare(password, user.password);
if (!isMatch) {
return res.status(401).json({ message: 'Invalid email or password' });
}

const token = jwt.sign({ id: user._id }, process.env.JWT_SECRET, { expiresIn: '1h' });
res.status(200).json({ token, userId: user._id });
} catch (error) {
console.error(error);
res.status(500).json({ message: 'Server error' });
}
};

module.exports = { register, login };
24 changes: 24 additions & 0 deletions controllers/contactController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@

const Contact = require('../models/contactModel');


const addContact = async (req, res) => {
try {
const newContact = new Contact(req.body);
await newContact.save();
res.status(201).json(newContact);
} catch (error) {
res.status(400).json({ message: 'Error creating contact', error });
}
};

const getContacts = async (req, res) => {
try {
const contacts = await Contact.find();
res.status(200).json(contacts);
} catch (error) {
res.status(500).json({ message: 'Error fetching contacts', error });
}
};

module.exports = { addContact, getContacts };
54 changes: 54 additions & 0 deletions controllers/userController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
const User = require('../models/userModel');
const gravatar = require('gravatar');
const fs = require('fs').promises;
const path = require('path');
const Jimp = require('jimp');
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');

const avatarsDir = path.join(__dirname, '../public/avatars');

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

const existingUser = await User.findOne({ email });
if (existingUser) {
return res.status(409).json({ message: 'User already exists' });
}

const avatarURL = gravatar.url(email, { s: '250' }, true);
const hashedPassword = await bcrypt.hash(password, 10);

const newUser = await User.create({ email, password: hashedPassword, avatarURL });
res.status(201).json({ email: newUser.email, avatarURL: newUser.avatarURL });
};

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

const user = await User.findOne({ email });
if (!user || !(await bcrypt.compare(password, user.password))) {
return res.status(401).json({ message: 'Invalid email or password' });
}

const token = jwt.sign({ id: user._id }, process.env.JWT_SECRET, { expiresIn: '1h' });
res.status(200).json({ token, avatarURL: user.avatarURL });
};

exports.updateUserAvatar = async (req, res) => {
if (!req.file) {
return res.status(400).json({ message: 'No file uploaded' });
}

const { path: tempPath, filename } = req.file;
const avatarPath = path.join(avatarsDir, filename);

const avatarImage = await Jimp.read(tempPath);
await avatarImage.resize(250, 250).writeAsync(avatarPath);
await fs.unlink(tempPath);

const avatarURL = `/avatars/${filename}`;
await User.findByIdAndUpdate(req.user._id, { avatar: avatarURL });

res.status(200).json({ avatarURL });
};
27 changes: 27 additions & 0 deletions middlewares/auth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
const jwt = require('jsonwebtoken');
const User = require('../models/userModel');

const auth = async (req, res, next) => {
const { authorization = '' } = req.headers;
const token = authorization.startsWith('Bearer ') ? authorization.slice(7) : null;

if (!token) {
return res.status(401).json({ message: 'Not authorized' });
}

try {
const { id } = jwt.verify(token, 'secret-key');
const user = await User.findById(id);

if (!user || user.token !== token) {
return res.status(401).json({ message: 'Not authorized' });
}

req.user = user;
next();
} catch {
res.status(401).json({ message: 'Not authorized' });
}
};

module.exports = auth;
34 changes: 34 additions & 0 deletions middlewares/authMiddleware.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
const jwt = require('jsonwebtoken');
const User = require('../models/userModel');

const auth = async (req, res, next) => {
console.log('Auth middleware called'); // Log pentru debugging

// Obține tokenul din header
const authHeader = req.headers.authorization;
const token = authHeader ? authHeader.split(' ')[1] : null;

if (!token) {
return res.status(401).json({ message: 'No token, authorization denied' });
}

try {
// Verifică și decodează tokenul
const decoded = jwt.verify(token, process.env.JWT_SECRET);

// Găsește utilizatorul în baza de date
req.user = await User.findById(decoded.id).select('-password'); // Exclude parola

if (!req.user) {
return res.status(401).json({ message: 'Not authorized' });
}

// Continuă spre următorul middleware/rută
next();
} catch (error) {
console.error('Error in auth middleware:', error);
res.status(401).json({ message: 'Token is not valid' });
}
};

module.exports = auth;
19 changes: 19 additions & 0 deletions middlewares/uploadConfig.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@

const multer = require('multer');
const path = require('path');


const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, path.join(__dirname, '../tmp/avatars'));
},
filename: (req, file, cb) => {
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
cb(null, uniqueSuffix + '-' + file.originalname);
}
});


const upload = multer({ storage });

module.exports = upload;
23 changes: 23 additions & 0 deletions middlewares/uploadMiddleware.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const multer = require('multer');
const path = require('path');

<<<<<<< Updated upstream
const tempDir = path.join(__dirname, '../tmp');
const storage = multer.diskStorage({
destination: tempDir,
filename: (req, file, cb) => cb(null, `${req.user._id}-${Date.now()}${path.extname(file.originalname)}`),
=======
const tmpDir = path.join(__dirname, '../tmp');

const storage = multer.diskStorage({
destination: tmpDir,
filename: (req, file, cb) => {
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9);
cb(null, uniqueSuffix + path.extname(file.originalname));
},
>>>>>>> Stashed changes
});

const upload = multer({ storage });

module.exports = upload;
39 changes: 23 additions & 16 deletions models/contacts.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,26 @@
// const fs = require('fs/promises')
const mongoose = require('mongoose');

const listContacts = async () => {}
const contactSchema = new mongoose.Schema({
name: {
type: String,
required: true,
},
email: {
type: String,
required: true,
unique: true,
match: /.+@.+\..+/
},
phone: {
type: String,
required: true,
},
favorite: {
type: Boolean,
default: false,
}
});

const getContactById = async (contactId) => {}
const Contact = mongoose.model('Contact', contactSchema);

const removeContact = async (contactId) => {}

const addContact = async (body) => {}

const updateContact = async (contactId, body) => {}

module.exports = {
listContacts,
getContactById,
removeContact,
addContact,
updateContact,
}
module.exports = Contact;
27 changes: 27 additions & 0 deletions models/userModel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
const mongoose = require('mongoose');
const bcrypt = require('bcrypt');

const userSchema = new mongoose.Schema({
email: {
type: String,
required: true,
unique: true,
},
password: {
type: String,
required: true,
},
avatarURL: String,
});

// Hash password before saving to the database
userSchema.pre('save', async function(next) {
if (this.isModified('password')) {
this.password = await bcrypt.hash(this.password, 10);
}
next();
});

const User = mongoose.models.User || mongoose.model('User', userSchema);

module.exports = User;
Loading