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
4 changes: 4 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules
npm-debug.log
.env
tmp
5 changes: 5 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
DB_USERNAME=your_username
DB_PASSWORD=your_password
DB_HOST=mongodb+srv://username:password@cluster0.oc5wu.mongodb.net/db-contacts?retryWrites=true&w=majority
SECRET_KEY=your_secret_key
SENDGRID_API_KEY=your_sendgrid_api_key
7 changes: 7 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
FROM node:16
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "start"]
41 changes: 26 additions & 15 deletions app.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,36 @@
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 usersRouter = require("./routes/api/users");
const auth = require("./middlewares/auth"); // middleware pt autentificare
const path = require("path");

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'
// middlewareuri globale
app.use(logger(formatsLogger));
app.use(cors());
app.use(express.json());

app.use(logger(formatsLogger))
app.use(cors())
app.use(express.json())
// rute publice (fara autentificare)
app.use("/api/users", usersRouter);

app.use('/api/contacts', contactsRouter)
// rute protejate (autentificare necesara)
app.use("/api/contacts", auth, contactsRouter); // adauga autentificarea pt rutele de contacte

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

// middleware global pentru gestionarea erorilor
app.use((err, req, res, next) => {
res.status(500).json({ message: err.message })
})
res.status(500).json({ message: err.message });
});

module.exports = app
app.use("/avatars", express.static(path.join(__dirname, "public/avatars"))); // ruta pt fisierele de avatar

module.exports = app;
14 changes: 14 additions & 0 deletions helpers/sendEmail.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const sgMail = require("@sendgrid/mail");
require("dotenv").config();

const { SENDGRID_API_KEY } = process.env;

sgMail.setApiKey(SENDGRID_API_KEY);

const sendEmail = async (data) => {
const email = { ...data, from: "miro_stefan@outlook.com" };
await sgMail.send(email);
return true;
};

module.exports = sendEmail;
33 changes: 33 additions & 0 deletions middlewares/auth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
const jwt = require("jsonwebtoken");
const User = require("../models/user");
require("dotenv").config();

const { SECRET_KEY } = process.env;

const auth = async (req, res, next) => {
const { authorization = "" } = req.headers; // extrage antetul Authorization
const [bearer, token] = authorization.split(" ");

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

try {
// decodifica token
const { id } = jwt.verify(token, SECRET_KEY);

// gaseste utilizatorul in baza de date
const user = await User.findById(id);
if (!user || !user.token) {
return res.status(401).json({ message: "Not authorized" });
}

// adauga utilizatorul în req pentru a fi utilizat în rutele protejate
req.user = user;
next(); // Permite accesul la ruta
} catch (error) {
res.status(401).json({ message: "Not authorized" });
}
};

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

// set director pt salvare fisiere
const tempDir = path.join(__dirname, "../tmp");

const multerConfig = multer.diskStorage({
destination: tempDir,
filename: (req, file, cb) => {
const uniqueName = `${Date.now()}-${file.originalname}`;
cb(null, uniqueName);
},
});

const upload = multer({
storage: multerConfig,
limits: {
fileSize: 5 * 1024 * 1024,
},
});

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 { Schema, model } = require("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 la utilizator
ref: "User", // numele modelului de utilizatori
},
});

const getContactById = async (contactId) => {}
const Contact = 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;
40 changes: 40 additions & 0 deletions models/user.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
const mongoose = require("mongoose");
const { Schema, model } = mongoose;

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

const User = model("User", userSchema);

module.exports = User;
Loading