Skip to content

Commit

Permalink
First commit
Browse files Browse the repository at this point in the history
  • Loading branch information
aurelien-oc-mentorship committed May 19, 2022
0 parents commit a0fabfc
Show file tree
Hide file tree
Showing 39 changed files with 6,872 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.idea
4 changes: 4 additions & 0 deletions Backend/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules
.env
images/*
!images/.gitkeep
21 changes: 21 additions & 0 deletions Backend/ReadMe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Backend API - Sophie Bluel

Ce repo contient le code backend de l'architecte Sophie Bluel.

## Lancement du backend

Après avoir récupéré le REPO executez la commande `npm install` pour installer les dépendances du projet

Une fois les dépendances installées lancez le projet avec la commande `npm start`

Compte de test pour Sophie Bluel

```
email: [email protected]
password: S0phie
```
Lien pour voir la
[documentation Swagger](http://localhost:5678/api-docs/)

Pour lire la documentation, utiliser Chrome ou Firefox
25 changes: 25 additions & 0 deletions Backend/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const express = require('express');
const path = require('path');
const cors = require('cors')
require('dotenv').config();
const helmet = require('helmet');
const swaggerUi = require('swagger-ui-express')
const yaml = require('yamljs')
const swaggerDocs = yaml.load('swagger.yaml')
const app = express()
app.use(cors())
app.use(express.json())
app.use(express.urlencoded({ extended: true }))
app.use(helmet());
app.use('/images', express.static(path.join(__dirname, 'images')))

const db = require("./models");
const userRoutes = require('./routes/user.routes');
const categoriesRoutes = require('./routes/categories.routes');
const worksRoutes = require('./routes/works.routes');
db.sequelize.sync().then(()=> console.log('db is ready'));
app.use('/api/users', userRoutes);
app.use('/api/categories', categoriesRoutes);
app.use('/api/works', worksRoutes);
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDocs))
module.exports = app;
4 changes: 4 additions & 0 deletions Backend/config/db.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = {
dialect: "sqlite",
storage: './database.sqlite'
};
20 changes: 20 additions & 0 deletions Backend/controllers/categories.controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const db = require('./../models');
const Categories = db.categories

exports.findAll = async (req, res) => {
try{
const works = await Categories.findAll();
return res.status(200).json(works);
}catch(err){
return res.status(500).json({ error: new Error('Something went wrong')})
}

}

exports.create = async (req, res) => {

const category = await Categories.create({
name : req.body.name
})
return res.status(201).json(category)
}
47 changes: 47 additions & 0 deletions Backend/controllers/users.controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
const db = require('./../models');
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');
const Users = db.users;

exports.signup = async (req, res) => {
if(!req.body.email || !req.body.password){
return res.status(400).send({
message: "Must have email and password"
});
}
try{
const hash = await bcrypt.hash(req.body.password, 10)
const user = {
email: req.body.email,
password: hash
}
await Users.create(user)
return res.status(201).json({message: 'User Created'})
}catch (err){
return res.status(500).send({
message: err.message
});
}

}

exports.login = async (req, res) => {
const user = await Users.findOne({where: {email: req.body.email}});
if(user === null){
return res.status(404).json({message: 'user not found'})
}else {
const valid = await bcrypt.compare(req.body.password, user.password)
if(!valid){
return res.status(401).json({ error: new Error('Not Authorized') })
}
return res.status(200).json({
userId: user.id,
token: jwt.sign(
{userId : user.id},
process.env.TOKEN_SECRET,
{ expiresIn: '24h' }
)
})

}
}
36 changes: 36 additions & 0 deletions Backend/controllers/works.controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
const db = require('./../models');
const Works = db.works

exports.findAll = async (req, res) => {
const works = await Works.findAll({include: 'category'});
return res.status(200).json(works);
}

exports.create = async (req, res) => {
const host = req.get('host');
const title = req.body.title;
const categoryId = req.body.category;
const userId = req.auth.userId;
const imageUrl = `${req.protocol}://${host}/images/${req.file.filename}`;
try{
const work = await Works.create({
title,
imageUrl,
categoryId,
userId
})
return res.status(201).json(work)
}catch (err) {
return res.status(500).json({ error: new Error('Something went wrong') })
}
}

exports.delete = async (req, res) => {
try{
await Works.destroy({where:{id: req.params.id}})
return res.status(204).json({message: 'Work Deleted Successfully'})
}catch(e){
return res.status(500).json({error: new Error('Something went wrong')})
}

}
Binary file added Backend/database.sqlite
Binary file not shown.
Empty file added Backend/images/.gitkeep
Empty file.
20 changes: 20 additions & 0 deletions Backend/middlewares/auth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const jwt = require('jsonwebtoken')

module.exports = (req, res, next) => {
try {
console.log(req.headers.authorization);
const token = req.headers.authorization.split(' ')[1]
const decodedToken = jwt.verify(token, process.env.TOKEN_SECRET)
const userId = decodedToken.userId
req.auth = { userId }
if (req.body.userId && req.body.userId !== userId) {
throw 'Invalid user ID'
} else {
next()
}
} catch {
res.status(401).json({
error: new Error('You are not authenticated')
})
}
}
25 changes: 25 additions & 0 deletions Backend/middlewares/checkWork.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module.exports = (req, res, next) => {
try{
const host = req.get('host');
const title = req.body.title.trim() ?? undefined;
const categoryId = parseInt(req.body.category) ?? undefined;
const userId = req.auth.userId ?? undefined;
const imageUrl = `${req.protocol}://${host}/images/${req.file.filename}` ?? undefined;
console.log(title,categoryId,userId,imageUrl)
if(title !== undefined &&
title.length > 0 &&
categoryId !== undefined &&
categoryId > 0 &&
userId !== undefined &&
userId > 0 &&
imageUrl !== undefined){
req.work = {title, categoryId, userId, imageUrl}
next()
}else{
return res.status(400).json({error: new Error("Bad Request")})
}
}catch(e){
return res.status(500).json({error: new Error("Something wrong occured")})
}

}
24 changes: 24 additions & 0 deletions Backend/middlewares/multer-config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
const multer = require('multer')

const MIME_TYPE = {
'image/jpg': 'jpg',
'image/jpeg': 'jpg',
'image/png': 'png',
'image/webp': 'webp',
}

const storage = multer.diskStorage({
destination: function (req, file, callback) {
callback(null, './images')
},
filename: (req, file, callback) => {
const filename = file.originalname.split(' ').join('_')
const filenameArray = filename.split('.')
filenameArray.pop()
const filenameWithoutExtention = filenameArray.join('.')
const extension = MIME_TYPE[file.mimetype]
callback(null, filenameWithoutExtention + Date.now() + '.' + extension)
}
})

module.exports = multer({storage}).single('image')
15 changes: 15 additions & 0 deletions Backend/models/categories.model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@

module.exports = (sequelize, DataTypes) => {
const Categories = sequelize.define(
"categories",
{
name: {
type: DataTypes.STRING,
allowNull: false,
unique: true,
},
},
{timestamps: false}
)
return Categories
}
30 changes: 30 additions & 0 deletions Backend/models/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const dbConfig = require("./../config/db.config.js");
const {Sequelize} = require("sequelize");
const config = require("../config/db.config");

const sequelize = new Sequelize('project6-db', 'user', 'pass', config)

const db = {}

db.Sequelize = Sequelize;
db.sequelize = sequelize;

db.users = require('./users.model.js')(sequelize, Sequelize);
db.works = require('./works.model.js')(sequelize, Sequelize);
db.categories = require('./categories.model.js')(sequelize, Sequelize);

// Works and Categories Relationships
db.categories.hasMany(db.works, {as: "works"})
db.works.belongsTo(db.categories, {
foreignKey: 'categoryId',
as: 'category'
});

// Works and Users Relationships
db.users.hasMany(db.works, {as: "works"})
db.works.belongsTo(db.users, {
foreignKey: 'userId',
as: 'user'
});

module.exports = db;
19 changes: 19 additions & 0 deletions Backend/models/users.model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@

module.exports = (sequelize, DataTypes) => {
const Users = sequelize.define(
"users",
{
email: {
type: DataTypes.STRING,
allowNull: false,
unique: true
},
password: {
type: DataTypes.STRING,
allowNull: false
}
},
{timestamps:false}
)
return Users
}
18 changes: 18 additions & 0 deletions Backend/models/works.model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@

module.exports = (sequelize, DataTypes) => {
const Works = sequelize.define(
"works",
{
title: {
type: DataTypes.STRING,
allowNull: false
},
imageUrl: {
type: DataTypes.STRING,
allowNull: false
}
},
{timestamps:false}
)
return Works
}
Loading

0 comments on commit a0fabfc

Please sign in to comment.