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

Version 1.2.4: News of Project routes, email format validation and new structure to README.md (Dev to Main) #70

Merged
merged 47 commits into from
Sep 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
1597f10
feat: modifies the verifyEmail() function for custom email verification
matheusvictoor Sep 12, 2023
66ffbcc
docs: README.md updated
ManoMax Sep 14, 2023
9bb18b3
Merge pull request #60 from codexjr-dev/iss#59
ManoMax Sep 14, 2023
f72317b
Update README.md
ManoMax Sep 14, 2023
b9d223a
docs: creates new folder and files for model News
Anaritamed Sep 17, 2023
dff42ed
refactor: creates NewsSchema structure and organization
Anaritamed Sep 17, 2023
17f8b00
refactor: creates functions on newsService.js
Anaritamed Sep 17, 2023
4b31eb8
Merge pull request #58 from codexjr-dev/iss#55
ManoMax Sep 18, 2023
6406380
refactor: change details in News attributes
Anaritamed Sep 18, 2023
0e920c6
feat: middleware for 'news' has been modified
maahog Sep 19, 2023
0ac3c15
feat: routes for 'news' has been added
maahog Sep 19, 2023
416ddda
refactor: change type of attribute
Anaritamed Sep 21, 2023
6f2e84a
feat: create save and remove functions on NewsController
Anaritamed Sep 21, 2023
fdf5e80
feat: middleware and routes modefield
maahog Sep 21, 2023
1b9482c
feat: middlewares and routes has been modifield again
maahog Sep 21, 2023
ab7e32e
feat: update function has been added in NewsService
maahog Sep 21, 2023
a8935c0
feat: update function has been added in NewsController
maahog Sep 21, 2023
fa54fae
refactor: message for update was modifield
maahog Sep 21, 2023
32977da
Refactor: adds new member attribute referring to who made the update
Anaritamed Sep 21, 2023
f2ffb3f
refactor: add news list to Project Model attributes
Anaritamed Sep 21, 2023
5c0f2db
refactor: changes POST and DELETE routes
Anaritamed Sep 21, 2023
a78ac78
refactor: changes save function on NewsService
Anaritamed Sep 21, 2023
9921be2
refactor: changes routes GET, PATCH and DELETE
Anaritamed Sep 21, 2023
f1f5d33
refact: findByProject has been added in NewsController
maahog Sep 21, 2023
ce41093
refactor: adds findByProject function on News Service
Anaritamed Sep 21, 2023
a90d43d
refactor: exports findByProject function
Anaritamed Sep 21, 2023
e521193
feat: isOwnerOfNews function created
maahog Sep 21, 2023
1ee0e7c
refactor: news of project removed in remove function
maahog Sep 21, 2023
5053134
refactor: variables renamed
maahog Sep 21, 2023
03bc901
refactor: middleware added and environment changed
maahog Sep 21, 2023
512fd03
refactor: string value to ref of news in Project Model
ManoMax Sep 22, 2023
e30140a
refactor: string value to ref of project in News Model and updateLink…
ManoMax Sep 22, 2023
9873122
feat/refactor: CRUD of News updated and added
ManoMax Sep 22, 2023
3b794f3
refactor: params and some environments changed
ManoMax Sep 22, 2023
cff2b62
refactor: params changed
ManoMax Sep 22, 2023
80ff19d
feat: News Routes added to API
ManoMax Sep 22, 2023
f368ab8
feat: @news added to moduleAlieases
ManoMax Sep 22, 2023
920da54
refactor: returns and queries changed in findByProject, update and re…
ManoMax Sep 27, 2023
73c17a6
refactor: variable name and return format changed
ManoMax Sep 27, 2023
758e4cf
feat: news added to getDTOproject
ManoMax Sep 27, 2023
c1c6292
refactor: functions use and functions names changed
ManoMax Sep 27, 2023
38ce605
fix: return of all news in remove function fixed
ManoMax Sep 27, 2023
b96bed3
fix: isOwnerOfNews fixed
ManoMax Sep 27, 2023
3766252
refactor/fix: router of PATCH news fixed and updated
ManoMax Sep 27, 2023
04fc33e
refactor: auth functions names updated
ManoMax Sep 29, 2023
2a0d433
refactor: News schema import removed from Project model
ManoMax Sep 29, 2023
f5fa0e6
Merge pull request #62 from codexjr-dev/iss#40
ManoMax Sep 29, 2023
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
210 changes: 209 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,209 @@
# tcc-backend
<img src="https://imgur.com/58aRLCO.png" width="100%"></img>

# 🖥️ Projexa

Dashboard to organize and manage the team and the projects of our enterprise.

With the aim of creating **efficient management** and **centralized data collection**, access to **leaders and** other **members** of the junior company, **Projexa** offers an environment for the construction and continuous evolution of a web system, open-source and, mainly, promoted by developers **CodeX Jr.** internals.
The application has a register of members, projects and links, available for viewing by the entire company, as well as management over each one, according to the authorization level of each user.

Read [endpoints.md.](https://github.com/codexjr-dev/dashboard-codex-api/blob/main/ENDPOINTS.md) for more API information.

## 🚀 Starting

These instructions will allow you to get a copy of the project running on your local machine for development and testing purposes.

### 📋 Prerequisites

To run the Backend system, you will need to have Node JS installed.

You can do this accessing this **[link](https://nodejs.org/en/download)**.

### 🔧 Installation

To install, you will need to clone the project, install the dependencies, create a .env file in the project root and add the necessary variables.

First, to clone the project, run:

```shell
git clone https://github.com/codexjr-dev/dashboard-codex-api.git
```

At the project root, install the dependencies by running:

```shell
npm install
```

Also in the project root, add a ".env" file and insert the following variables:

```.env
BD_PROD=<developer database link (MongoDB Atlas)>
BD_DEV=<production database link (MongoDB Atlas)>

PORT=<port on which you want to run the API. Ex: 4444>

SALT_ROUNDS=<integer of your choice>

JWT_SECRET=<jwt password>
```

Perhaps dependencies such as **cors**, **dotenv**, **express**, **jsonwebtoken** and/or **mongoose** inform you that they need to be installed globally (on your machine).

To do so, just listen to the following commands:

```shell
node i -g <dependence>
```

## ⚙️ Configuring Scripts

Before running, you may need to configure the scripts according to your Operating System.

Change the package.json according to your need:

**Linux**

```json
"scripts": {
"start": "NODE_ENV=prod node src/server.js",
"test": "NODE_ENV=test mocha ./test/integration/*.test.js --timeout 10000 --exit",
"dev": "NODE_ENV=dev nodemon src/server.js",
"debug": "NODE_ENV=dev nodemon --inspect src/server.js"
}
```

**Windows**

```json
"scripts": {
"start": "set NODE_ENV=prod node && src/server.js",
"test": "set NODE_ENV=test && mocha ./test/integration/*.test.js --timeout 10000 --exit",
"dev": "set NODE_ENV=dev && nodemon src/server.js",
"debug": "set NODE_ENV=dev nodemon && --inspect src/server.js"
}
```

---

## ✅ Running the System

Execute in production environment:

```shell
npm start
```

Execute in developer environment:

```shell
npm run dev
```

Execute tests, creating a temporary Data Base:

```shell
npm run test
```

## 🛠️ Construído com

The main technologies used were:

- [express](https://expressjs.com/) - The API used
- [npm](https://docs.npmjs.com/) - Dependency Manager
- [mongoose](https://mongoosejs.com/) - Mongodb object modeling

## 🖇️ Collaboration

Please, read a **[COLLAB.md](https://github.com/codexjr-dev/dashboard-codex-api/blob/main/COLLAB.md)** for details about our code of conduct and the process for submitting requests to us.

## 📌 Versions

- [1.0.0](https://github.com/lucasanthony/tcc-backend) - [Completion of Course Work - Lucas Anthony](http://dspace.sti.ufcg.edu.br:8080/xmlui/bitstream/handle/riufcg/29267/LUCAS%20ANTHONY%20FERREIRA%20DE%20OLIVEIRA%20-%20TCC%20ARTIGO%20CI%C3%8ANCIA%20DA%20COMPUTA%C3%87%C3%83O%20CEEI%202022.pdf?sequence=1&isAllowed=y).
- [1.2.1](https://github.com/codexjr-dev/dashboard-codex-api/tree/6300cc4e1b9cf42b05ccc3ead418e30dae10e218) - [User Model Updates and role of user format changed](https://github.com/codexjr-dev/dashboard-codex-api/pull/17).
- [1.2.2](https://github.com/codexjr-dev/dashboard-codex-api/tree/821a75765695012046d16f6540d6c177e31674ce) - [nodeenv configs, member access, role and email verifications and new roles](https://github.com/codexjr-dev/dashboard-codex-api/pull/27).
- [1.2.3](https://github.com/codexjr-dev/dashboard-codex-api/tree/b8a880204d038336145321c9e7436bc1a847a22e) - [Bug Fixes and System Improvements](https://github.com/codexjr-dev/dashboard-codex-api/pull/57).

## ✒️ Authors

<table>
<tr>
<td align="center" width="190px" height="160px">
<img src="https://avatars.githubusercontent.com/u/25506401?v=4" alt="Lucas Anthony Profile Image" width="50"></img>
</br>
<a href="https://github.com/lucasanthony">@lucasanthony</a>
</br>
<span>Initial Work</span>
</td>
<td align="center" width="190px" height="160px">
<img src="https://avatars.githubusercontent.com/u/34282197?v=4" alt="Gabriel Max Profile Image" width="50"></img>
</br>
<a href="https://github.com/ManoMax">@ManoMax</a>
</br>
<span>Continuation of Work</span>
</td>
</tr>
</table>

- **Lucas Anthony** - _Initial Work_ - [@lucasanthony](https://github.com/lucasanthony)
- **Gabriel Max** - _Subsequent Project Leader_ - [@ManoMax](https://github.com/ManoMax)

You can also see the list of all contributors who participated in this project.

<table>
<tr>
<td align="center" width="190px" height="160px">
<img src="https://avatars.githubusercontent.com/u/100716949?v=4" alt="Ana Rita Profile Image" width="50"></img>
</br>
<a href="https://github.com/Anaritamed">@anaritamed</a>
</br>
<span>Developer</span>
</td>
<td align="center" width="190px" height="160px">
<img src="https://avatars.githubusercontent.com/u/64997111?v=4" alt="Filipe Luiz Profile Image" width="50"></img>
</br>
<a href="https://github.com/FLuiz22">@FLuiz22</a>
</br>
<span>Developer</span>
</td>
<td align="center" width="190px" height="160px">
<img src="https://avatars.githubusercontent.com/u/117235880?v=4" alt="Maria Clara Profile Image" width="50"></img>
</br>
<a href="https://github.com/maahog">@maahog</a>
</br>
<span>Developer</span>
</td>
<td align="center" width="190px" height="160px">
<img src="https://avatars.githubusercontent.com/u/92826048?v=4" alt="Matheus Victor Profile Image" width="50"></img>
</br>
<a href="https://github.com/matheusvictoor">@matheusvictoor</a>
</br>
<span>Developer</span>
</td>
</tr>
<tr>
<td align="center" width="190px" height="160px">
<img src="https://avatars.githubusercontent.com/u/62821027?v=4" alt="Daniele Oliveira Profile Image" width="50"></img>
</br>
<a href="https://github.com/danieleolivs">@danieleolivs</a>
</br>
<span>UI Design</span>
</td>
<td align="center" width="190px" height="160px">
<img src="https://avatars.githubusercontent.com/u/96065590?v=4" alt="Carlos Lucena Profile Image" width="50"></img>
</br>
<a href="https://github.com/carlos-lucenag">@carlos-lucenag</a>
</br>
<span>UI Design</span>
</td>
</tr>
</table>

## 📄 Licença

This project is under license **GNU General Public License v3.0 (GNU GPLv3)** - see the file [LICENSE.md](https://github.com/usuario/projeto/licenca) for details.

---

⌨️ with ❤️ by [CodeX Jr.](https://codexjr.com.br/) 😊
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"@project": "src/modules/Project",
"@link": "src/modules/Link",
"@member": "src/modules/Member",
"@news": "src/modules/News",
"@config": "src/config"
}
}
40 changes: 32 additions & 8 deletions src/middlewares/auth.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,27 @@
const jwt = require("jsonwebtoken");
const Member = require("@member/Member");
const Project = require("@project/Project");
const News = require("../modules/News/News");

module.exports = {
validatedUser(req, res, next) {
authorize(req, res, next, "valid");
existentUser(req, res, next) {
authorize(req, res, next, "existent");
},

authorizedUser(req, res, next) {
authorize(req, res, next, "user");
authorize(req, res, next, "authorized");
},

authorizedLeadership(req, res, next) {
isLeadership(req, res, next) {
authorize(req, res, next, "leadership");
},

authorizePresident(req, res, next) {
next();
isMemberOnProject(req, res, next){
authorize(req, res, next, "team");
},

haveRightsToTheNews(req, res, next){
authorize(req, res, next, "newsOwner");
},
};

Expand All @@ -38,12 +44,12 @@ const authorize = (req, res, next, type) => {
const member = await Member.findOne({ _id: decoded.sub });

switch (type) {
case "valid":
case "existent":
if (!member)
return res.status(404).send({ error: "Usuário não existe." });
break;

case "user":
case "authorized":
if (!isLeadership(member) && member._id.toString() !== req.body._id)
return res.status(403).send({ error: "Usuário sem permissão." });
break;
Expand All @@ -52,6 +58,18 @@ const authorize = (req, res, next, type) => {
if (!isLeadership(member))
return res.status(403).send({ error: "Usuário sem permissão." });
break;

case "team":
const project = await Project.findOne({ _id: req.params.projectId });
if(!isLeadership(member) && !isMemberProject(project, member))
return res.status(403).send({ error: "Usuário sem permissão." });
break;

case "newsOwner":
const news = await News.findOne({_id: req.body.newsId});
if(!isLeadership(member) && !isNewsOwner(news, member))
return res.status(403).send({ error: "Usuário sem permissão." });
break;
}

req.ejId = member.ej;
Expand All @@ -62,3 +80,9 @@ const authorize = (req, res, next, type) => {

const isLeadership = (member) =>
member && ["Presidente", "Diretor(a)"].includes(`${member.role}`);

const isMemberProject = (project, member) =>
project && project.team.includes(member._id);

const isNewsOwner = (news, member) =>
news.member.toString() === member._id.toString();
10 changes: 5 additions & 5 deletions src/modules/Link/LinkRoutes.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
const router = require("express").Router();
const { save, findByEj, update, remove } = require("./LinkController");
const {
validatedUser,
existentUser,
authorizedUser,
authorizedLeadership,
isLeadership,
} = require("@middlewares/auth");

router.post("/link", authorizedLeadership, save);
router.get("/link", validatedUser, findByEj);
router.post("/link", isLeadership, save);
router.get("/link", existentUser, findByEj);
router.patch("/link/:id", authorizedUser, update);
router.delete("/link/:id", authorizedLeadership, remove);
router.delete("/link/:id", isLeadership, remove);

module.exports = router;
10 changes: 5 additions & 5 deletions src/modules/Member/MemberRoutes.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
const router = require("express").Router();
const { save, findByEj, update, remove } = require("./MemberController");
const {
validatedUser,
existentUser,
authorizedUser,
authorizedLeadership,
isLeadership,
} = require("@middlewares/auth");

router.post("/member", authorizedLeadership, save);
router.get("/member", validatedUser, findByEj);
router.post("/member", isLeadership, save);
router.get("/member", existentUser, findByEj);
router.patch("/member/:id", authorizedUser, update);
router.delete("/member/:id", authorizedLeadership, remove);
router.delete("/member/:id", isLeadership, remove);

module.exports = router;
15 changes: 12 additions & 3 deletions src/modules/Member/MemberService.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,19 @@ module.exports = {
},
};

async function verifyEmail(memberEmail) {
const emailInUse = await Member.findOne({ email: memberEmail });
async function verifyEmail(email) {
if (!email) {
throw new Error('EMPTY_EMAIL');
}

const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!regex.test(email)) {
throw new Error('INVALID_EMAIL_FORMAT');
}

const emailInUse = await Member.findOne({ email: email });
if (emailInUse) {
throw new Error('Já existe um membro cadastrado para esse email!');
throw new Error('EMAIL_ALREADY_IN_USE');
}
}

Expand Down
32 changes: 32 additions & 0 deletions src/modules/News/News.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
const { Schema, model } = require("mongoose");
const Member = require("@member/Member")

const NewsSchema = new Schema({
member: {
type: Schema.Types.ObjectId,
ref: Member,
required: true
},
project: {
type: Schema.Types.ObjectId,
ref: 'Project',
required: true
},
description: {
type: String,
required: true
},
image: {
type: Buffer,
required: false
},
updateLink: {
type: String,
required: false
}
},
{
timestamps: true,
});

module.exports = model("News", NewsSchema);
Loading