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
23 changes: 23 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Use Node.js LTS image
FROM node:16

# Set working directory
WORKDIR /usr/src/app

# Copy package files
COPY package*.json ./

# Install dependencies
RUN npm install

# Copy the application files
COPY . .

# Expose port 3000
EXPOSE 3000

# Set environment variables
ENV NODE_ENV=production

# Start the application
CMD ["node", "server.js"]
77 changes: 60 additions & 17 deletions app.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,68 @@
const express = require('express')
const logger = require('morgan')
const cors = require('cors')
import express from 'express';
import path from 'path';
import { fileURLToPath } from 'url';
import mongoose from 'mongoose';
import dotenv from 'dotenv';

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

const app = express()
dotenv.config(); // Load environment variables

const formatsLogger = app.get('env') === 'development' ? 'dev' : 'short'
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

app.use(logger(formatsLogger))
app.use(cors())
app.use(express.json())
// Database connection URI
const DB_URI = process.env.DB_URI;

app.use('/api/contacts', contactsRouter)
if (!DB_URI || (!DB_URI.startsWith('mongodb://') && !DB_URI.startsWith('mongodb+srv://'))) {
console.error('Invalid or missing DB_URI in environment variables.');
process.exit(1);
}

app.use((req, res) => {
res.status(404).json({ message: 'Not found' })
})
// Configure Mongoose settings
mongoose.set('bufferCommands', false); // Disable buffering to prevent unexpected behavior

app.use((err, req, res, next) => {
res.status(500).json({ message: err.message })
})
// MongoDB connection events
mongoose.connection.on('connecting', () => console.log('Connecting to MongoDB...'));
mongoose.connection.on('connected', () => console.log('Connected to MongoDB'));
mongoose.connection.on('error', (err) => console.error('Mongoose connection error:', err.message));
mongoose.connection.on('disconnected', () => console.log('Mongoose disconnected'));

module.exports = app
// Connect to the database
const connectDB = async () => {
try {
await mongoose.connect(DB_URI); // Remove deprecated options
console.log('MongoDB connected successfully');
} catch (err) {
console.error('Failed to connect to MongoDB:', err.message);
process.exit(1); // Exit the process if the connection fails
}
};

const app = express();
app.use(express.json());

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

// Log route registration for debugging
console.log('Registering routes...');
app.use('/api/contacts', contactsRouter);
console.log('Contacts route registered at /api/contacts');

app.use('/api/users', usersRouter);
console.log('Users route registered at /api/users');

app.use('/auth', authRouter);
console.log('Auth route registered at /auth');

// Middleware for handling 404 errors
app.use((req, res, next) => res.status(404).json({ message: 'Not Found' }));

// Connect to MongoDB
if (process.env.NODE_ENV !== 'test') {
connectDB();
}

export { app, connectDB };
16 changes: 16 additions & 0 deletions helpers/sendEmail.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import sgMail from '@sendgrid/mail';
import dotenv from 'dotenv';

dotenv.config(); // Load environment variables

const apiKey = process.env.SENDGRID_API_KEY;

if (!apiKey || !apiKey.startsWith('SG.')) {
console.error('Invalid SendGrid API key.');
process.exit(1); // Terminate the app if the API key is invalid
}

sgMail.setApiKey(apiKey);
console.log('SendGrid API key set successfully');

export default sgMail;
27 changes: 27 additions & 0 deletions middlewares/auth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import jwt from 'jsonwebtoken';
import User from '../models/user.js';

const authenticate = async (req, res, next) => {
const { authorization = '' } = req.headers;
const [bearer, token] = authorization.split(' ');

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

try {
const { id } = jwt.verify(token, process.env.JWT_SECRET);
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' });
}
};

export default authenticate;
38 changes: 22 additions & 16 deletions models/contacts.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,25 @@
// const fs = require('fs/promises')
import mongoose from 'mongoose';

const listContacts = async () => {}
const contactSchema = new mongoose.Schema({
name: {
type: String,
required: true,
},
email: {
type: String,
required: true,
},
phone: {
type: String,
required: true,
},
owner: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
required: true,
},
});

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,
}
export default Contact;
62 changes: 0 additions & 62 deletions models/contacts.json

This file was deleted.

29 changes: 29 additions & 0 deletions models/user.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import mongoose from 'mongoose';
import { nanoid } from 'nanoid';

const userSchema = new mongoose.Schema({
email: {
type: String,
required: true,
unique: true,
},
password: {
type: String,
required: true,
},
verify: {
type: Boolean,
default: false,
},
verificationToken: {
type: String,
default: null, // Allow null values
required: function () {
return !this.verify; // Required only if the user is not verified
},
},
});

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

export default User;
Loading