Skip to content
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

Hw06 email #5484

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
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
Binary file added .DS_Store
Binary file not shown.
46 changes: 31 additions & 15 deletions app.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,41 @@
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 path = require('path');
require('dotenv').config();
const connectDB = require('./models/db');

const contactsRouter = require('./routes/api/contacts')
connectDB();

const app = express()
const authRouter = require('./routes/api/auth');
const contactsRouter = require('./routes/api/contacts');

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

app.use(logger(formatsLogger))
app.use(cors())
app.use(express.json())
app.use('/avatars', express.static(path.join(__dirname, 'public/avatars')));

app.use('/api/contacts', contactsRouter)
const formatsLogger = app.get('env') === 'development' ? 'dev' : 'short';

app.use(logger(formatsLogger));
app.use(cors());
app.use(express.json());

app.use('/api/users', authRouter);
app.use('/api/contacts', contactsRouter);

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

const PORT = process.env.PORT || 3000;

app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
});

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

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

const registerSchema = Joi.object({
email: Joi.string().email().required(),
password: Joi.string().min(6).required(),
});

const loginSchema = Joi.object({
email: Joi.string().email().required(),
password: Joi.string().min(6).required(),
});

const register = async (req, res) => {
const { error } = registerSchema.validate(req.body);
if (error) {
return res.status(400).json({ message: error.details[0].message });
}

const { email, password } = req.body;
const userExists = await User.findOne({ email });

if (userExists) {
return res.status(409).json({ message: 'Email in use' });
}

const newUser = new User({ email, password });
await newUser.save();

return res.status(201).json({
user: {
email: newUser.email,
subscription: newUser.subscription,
},
});
};

const login = async (req, res) => {
const { error } = loginSchema.validate(req.body);
if (error) {
return res.status(400).json({ message: error.details[0].message });
}

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: 'Email or password is wrong' });
}

const token = jwt.sign({ id: user._id }, process.env.JWT_SECRET, {
expiresIn: '1h',
});
user.token = token;
await user.save();

return res.status(200).json({
token,
user: {
email: user.email,
subscription: user.subscription,
},
});
};

module.exports = { register, login };
28 changes: 28 additions & 0 deletions middlewares/auth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
const jwt = require('jsonwebtoken');
const User = require('../models/user');

const auth = async (req, res, next) => {
try {
const authHeader = req.headers.authorization;

if (!authHeader || !authHeader.startsWith('Bearer ')) {
return res.status(401).json({ message: 'Not authorized' });
}

const token = authHeader.split(' ')[1];
const decoded = jwt.verify(token, process.env.JWT_SECRET);

const user = await User.findById(decoded.id);

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

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

module.exports = auth;
67 changes: 59 additions & 8 deletions models/contacts.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,70 @@
// const fs = require('fs/promises')
const mongoose = require('mongoose');
const { Schema, model } = mongoose;

const listContacts = async () => {}
const contactSchema = new Schema({
name: {
type: String,
required: [true, 'Set name for contact'],
},
email: {
type: String,
},
phone: {
type: String,
},
favorite: {
type: Boolean,
default: false,
},
owner: {
type: Schema.Types.ObjectId,
ref: 'user',
required: true,
},
});

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

const removeContact = async (contactId) => {}
const listContacts = async () => {
return await Contact.find({});
};

const addContact = async (body) => {}
const getContactById = async contactId => {
return await Contact.findById(contactId);
};

const updateContact = async (contactId, body) => {}
const addContact = async ({ name, email, phone }) => {
const newContact = new Contact({ name, email, phone });
return await newContact.save();
};

const removeContact = async contactId => {
try {
const result = await Contact.findByIdAndDelete(contactId);
return result;
} catch (error) {
console.error('Error removing contact:', error);
throw error;
}
};

const updateContact = async (contactId, updates) => {
return await Contact.findByIdAndUpdate(contactId, updates, { new: true });
};

const updateStatusContact = async (contactId, { favorite }) => {
return await Contact.findByIdAndUpdate(
contactId,
{ favorite },
{ new: true }
);
};

module.exports = {
listContacts,
getContactById,
removeContact,
addContact,
removeContact,
updateContact,
}
updateStatusContact,
};
62 changes: 0 additions & 62 deletions models/contacts.json

This file was deleted.

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

const { DB_HOST: urlDb } = process.env;

const connectDB = async () => {
try {
await mongoose.connect(urlDb, {
dbName: 'db-contacts',
});
console.log('Database connection successful');
} catch (error) {
console.error(`Error: ${error.message}`);
process.exit(1);
}
};

module.exports = connectDB;
38 changes: 38 additions & 0 deletions models/user.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
const { Schema, model } = require('mongoose');
const gravatar = require('gravatar');

const userSchema = new Schema({
email: {
type: String,
required: [true, 'Email is required'],
unique: true,
},
password: {
type: String,
required: [true, 'Password is required'],
},
subscription: {
type: String,
enum: ['starter', 'pro', 'business'],
default: 'starter',
},
avatarURL: {
type: String,
},
token: {
type: String,
default: null,
},
verify: {
type: Boolean,
default: false,
},
verificationToken: {
type: String,
required: null,
},
});

const User = model('user', userSchema);

module.exports = User;
Loading