Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
joaquincorimayo committed Nov 13, 2023
0 parents commit 744e215
Show file tree
Hide file tree
Showing 34 changed files with 5,290 additions and 0 deletions.
11 changes: 11 additions & 0 deletions .env.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
AUTH_MAIL_USER=<>
AUTH_MAIL_PASSWORD=<>

MERCADO_PAGO_ACCESS_TOKEN_TEST=<>
MERCADO_PAGO_ACCESS_TOKEN_PROD=<>

HOST=<>
PORT=<>
DATABASE=<>
USERNAME=<>
PASSWORD=<>
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules
.idea
.env
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2023 JFECM

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
77 changes: 77 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Backend-Gym

This is a project that uses the Express.js framework and MongoDB to create a REST-Ful API. It allows managing operations of a gym.

## General Description

The application manages resources and provides basic CRUD (Create, Read, Update, Delete) operations for users, equipment and plans.

## Project Structure

The project is organized as follows:
- `index.js`: Application entry point.
- `package.json`: Dependency management files.
- `controllers/`: All controllers
- `middleware/`: Custom middleware.
- `models/`: Data model definitions.
- `routes/`: Application routes definitions.
- `.env`: Env file `(you need create this file)`
- `.env.sample`: Configuration file sample with environment variables for .env file.

## Requirements

- Make sure you have Node installed and the dependencies defined in the `package.json` file.
- Make sure you have MongoDB installed and check MongoDB connection configuration.

## Use (local)

1. Clone this repository or download the source code.
2. Make sure all dependencies are installed.
3. Start the application using `npm run dev`.
4. The API will be available at `http://localhost:3000`.

## API Routes
### Authentication

- `POST /api/v2/auth/sign-in`: Sign in
- `POST /api/v2/auth/sign-up`: Sign up

### Admin

- `POST /api/v2/admin/create-admin`: Create Admin.
- `POST /api/v2/admin/create-coach`: Create Coach.
- `POST /api/v2/admin/create-member/plan/:id`: Create Member.
- `GET /api/v2/admin/users`: Get All Users.
- `POST /api/v2/admin/create-admin`: Create Admin.
- `POST /api/v2/admin/create-coach`: Create Coach.
- `POST /api/v2/admin/create-member/plan/:id`: Create Member.
- `GET /api/v2/admin/users`: Get All Users.
- `GET /api/v2/admin/users/:id`: Get User by ID.
- `POST /api/v2/admin/create-payment`: Create Payment.
- `POST /api/v2/admin/create-equipment`: Create Equipment.
- `POST /api/v2/admin/create-plan`: Create Plan.
- `GET /api/v2/admin/plans`: Get All Plans.
- `GET /api/v2/admin/sales-report`: Get Sales Report.
- `GET /api/v2/admin/users/:id/generate-access-credentials`: Generate Access Credentials for a User.
- `DELETE /api/v2/admin/users/:id`: Delete User by ID.
- `PUT /api/v2/admin/users/:id`: Update User by ID.
- `PUT /api/v2/admin/users/:id/change-password`: Update User Password by ID.
- `PUT /api/v2/admin/memberships`: Associate User with Plan.

## Contribution

If you would like to contribute to this project, feel free to do so.

You can open an issue, submit a pull request, or work on improvements or new features.

All contributions are welcome!

## License

This project is licensed under the MIT License. You can find more details in the [LICENSE](LICENSE) file.

## Contact

If you have any questions or comments, feel free to contact me via my email address or the GitHub repository.

Thank you for your interest in this project!
125 changes: 125 additions & 0 deletions controllers/auth.controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
const jwt = require('jsonwebtoken');
const authCtrl = {};
const User = require("../models/user");
const bcrypt = require("bcrypt");

authCtrl.verifyToken = async (req, res, next) => {
if (!req.headers.authorization) {
return res.status(401).json({
success: false,
message: "Authorization header is missing.",
});
}

const split = req.headers.authorization.split(' ');
let token;

if (split.length >= 2) {
token = split[1];
} else {
return res.status(401).json({
success: false,
message: "Invalid authorization format.",
});
}

if (!token) {
return res.status(401).json({
success: false,
message: "Token is missing in authorization header.",
});
}

try {
const payload = jwt.verify(token, "secretkey");
req.userId = payload._id;
req.userRol = payload.rol;
req.user = payload;
next();
} catch (error) {
return res.status(401).json({
success: false,
message: "Invalid or expired token.",
});
}
};

authCtrl.signIn = async (req, res) => {
const {username, password} = req.body;

try {
const user = await User.findOne({username});

if (!user) {
return res.status(401).json({
success: false,
message: "Authentication failed. User not found.",
});
}

const isPasswordValid = await bcrypt.compare(password, user.password);

if (!isPasswordValid) {
return res.status(401).json({
success: false,
message: "Authentication failed. Incorrect password.",
});
}

const token = jwt.sign({id: user._id, rol: user.rol}, "secretkey");

res.json({
success: true,
message: "Authentication successful.",
user: user, token: token
});

} catch (error) {
res.status(500).json({
success: false,
message: "Internal server error.",
error: error.message,
});
}

}

authCtrl.signUp = async (req, res) => {
const {username, password, rol} = req.body;

try {
const existingUser = await User.findOne({username});

if (existingUser) {
return res.status(400).json({
success: false,
message: "Username already exists. Please choose a different username.",
});
}

const hashedPassword = await bcrypt.hash(password, 10);

const user = new User({
username,
password: hashedPassword,
rol: rol || 'user',
});

await user.save();

res.json({
success: true,
message: "User registered successfully.",
user: user,
});

} catch (error) {
res.status(500).json({
success: false,
message: "Internal server error.",
error: error.message,
});
}
}

module.exports = authCtrl;
146 changes: 146 additions & 0 deletions controllers/equipment.controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
const equipmentCtrl = {};
const Equipment = require('../models/equipment');
const Plan = require("../models/plan");

equipmentCtrl.create = async (req, res) => {
try {
const {name, total, image} = req.body;

const existingNameEquipment = await Equipment.findOne({ name });
if (existingNameEquipment) {
return res.status(400).json({
success: false,
message: "Name equipment already exists. Please choose a different name.",
});
}

const newEquipment = new Equipment({
name,
total,
status: 'active',
image,
});

await newEquipment.save();

res.json({
success: true,
message: 'Equipment created successfully.',
equipment: newEquipment,
});
} catch (error) {
res.status(500).json({
success: false, message: 'Internal server error.', error: error.message,
});
}
};

equipmentCtrl.get = async (req, res) => {
try {
const { id } = req.params;
const equipment = await Equipment.findById(id);

if (!equipment) {
return res.status(404).json({
success: false,
message: 'Equipment not found.',
});
}

res.json({
success: true,
equipment: equipment,
});
} catch (error) {
res.status(500).json({
success: false,
message: 'Internal server error.',
error: error.message,
});
}
};

equipmentCtrl.getAll = async (req, res) => {
try {
const equipmentList = await Equipment.find();

res.json({
success: true,
equipment: equipmentList,
});
} catch (error) {
res.status(500).json({
success: false,
message: 'Internal server error.',
error: error.message,
});
}
};

equipmentCtrl.update = async (req, res) => {
try {
const { id } = req.params;
const { name, total, image } = req.body;

const existingNameEquipment = await Equipment.findOne({ name });
if (existingNameEquipment) {
return res.status(400).json({
success: false,
message: "Name equipment already exists. Please choose a different name.",
});
}

const updatedEquipment = await Equipment.findByIdAndUpdate(
id,
{ name, total, image },
{ new: true }
);

if (!updatedEquipment) {
return res.status(404).json({
success: false,
message: 'Equipment not found.',
});
}

res.json({
success: true,
message: 'Equipment updated successfully.',
equipment: updatedEquipment,
});
} catch (error) {
res.status(500).json({
success: false,
message: 'Internal server error.',
error: error.message,
});
}
};

equipmentCtrl.delete = async (req, res) => {
try {
const { id } = req.params;
const deletedEquipment = await Equipment.findByIdAndDelete(id);

if (!deletedEquipment) {
return res.status(404).json({
success: false,
message: 'Equipment not found.',
});
}

res.json({
success: true,
message: 'Equipment deleted successfully.',
equipment: deletedEquipment,
});
} catch (error) {
res.status(500).json({
success: false,
message: 'Internal server error.',
error: error.message,
});
}
};

module.exports = equipmentCtrl;
Loading

0 comments on commit 744e215

Please sign in to comment.