Skip to content

Commit

Permalink
Adding basic securitization
Browse files Browse the repository at this point in the history
  • Loading branch information
basshamut committed Jun 27, 2024
1 parent 097b8d4 commit c26df52
Show file tree
Hide file tree
Showing 17 changed files with 105 additions and 26 deletions.
1 change: 1 addition & 0 deletions backend/config/database/database.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const {Sequelize} = require('sequelize');

const connection = 'postgresql://test_db_owner:Lqn84hbsNPvG@ep-purple-voice-a5bgc10s.us-east-2.aws.neon.tech/test_db?sslmode=require'
// const connection = process.env.DATABASE_URL

const sequelize = new Sequelize(connection, {
dialect: 'postgres',
Expand Down
3 changes: 2 additions & 1 deletion backend/controller/StripeController.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ const router = express.Router()
const stripe = require('stripe')('sk_test_51PSHknKnVUk9u0R7NE00UeVyiOzpnfGxGYnLG6ViHxy2eOpDXfYCQTU28Xnfuh9MPvg7qwi5hQp4ArEBjJhjv73z005BOmZJSK')

// const domain = "http://localhost:5173"
const domain = "http://86.38.204.61"
// const domain = "http://86.38.204.61"
const domain = process.env.FRONTEND_URL

router.post('/create-checkout-session', async (req, res) => {
//TODO encriptar y parsear a bse64 datos del retorno de la respuesta
Expand Down
4 changes: 3 additions & 1 deletion backend/controller/UserController.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ router.post('/register', async (req, res) => {
})

router.post('/login', async (req, res) => {
const { user, password } = req.body
const user = req.body.user
const password = atob(req.body.password)

const errors = {}

Expand All @@ -78,6 +79,7 @@ router.post('/login', async (req, res) => {
return res.status(404).json({ message: 'Usuario o contraseña incorrectos' })
}

userFound.password = undefined
res.status(200).json(userFound)
})

Expand Down
8 changes: 5 additions & 3 deletions backend/index.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
require('dotenv').config()
require('dotenv').config();
const express = require('express');
const app = express();

const express = require("express")
const cors = require('cors')

const meetController = require('./controller/MeetController')
const stripeController = require('./controller/StripeController')
const userController = require('./controller/UserController')
const purchaseController = require('./controller/PurchaseController')
const authenticateInterceptorMiddleware = require('./interceptor/AuthenticateInterceptorMiddleware');

const app = express()
const port = process.env.PORT ? process.env.PORT : 5000

const corsOptions = {
Expand All @@ -19,6 +20,7 @@ const corsOptions = {

app.use(cors(corsOptions))
app.use(express.json())
app.use(authenticateInterceptorMiddleware)

app.use('/api/meets', meetController)
app.use('/api/users', userController)
Expand Down
41 changes: 41 additions & 0 deletions backend/interceptor/AuthenticateInterceptorMiddleware.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
const userService = require("../service/UserService");

async function interceptorMiddleware(req, res, next) {
const path = req.path.toLowerCase();

const excludedPaths = [
'/api/users/login',
'/api/users/register'
];

if (!excludedPaths.includes(path)) {
const authHeader = req.headers.authorization;
if (!authHeader || !authHeader.startsWith('Basic ')) {
return res.status(401).json({ message: 'Unauthorized' });
}

try {
const authHeaderReplaced = authHeader.replace('Basic ', '');
const authDecode = Buffer.from(authHeaderReplaced, 'base64').toString('utf-8');
const [user, password] = authDecode.split(':');

// Validar usuario y contraseña
const userFound = await userService.login(user, atob(password));

if (!userFound) {
return res.status(401).json({ message: 'Unauthorized' });
}

// Agregar el usuario encontrado al objeto req para su uso posterior si es necesario
req.user = userFound;

} catch (error) {
console.error('Error en middleware de autenticación:', error);
return res.status(500).json({ message: 'Internal Server Error' });
}
}

next();
}

module.exports = interceptorMiddleware;
2 changes: 1 addition & 1 deletion backend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"dependencies": {
"bcrypt": "^5.1.0",
"cors": "^2.8.5",
"dotenv": "^16.0.3",
"dotenv": "^16.4.5",
"express": "^4.19.2",
"express-validator": "^6.14.2",
"jsonwebtoken": "^9.0.0",
Expand All @@ -22,10 +22,10 @@
"pg-hstore": "^2.3.4",
"sequelize": "^6.37.3",
"sqlite3": "^5.1.7",
"stripe": "^15.12.0",
"swagger-jsdoc": "^6.2.8",
"swagger-ui-express": "^4.6.2",
"uuid": "^9.0.0",
"stripe": "^15.12.0"
"uuid": "^9.0.0"
},
"devDependencies": {
"eslint": "^9.5.0",
Expand Down
2 changes: 1 addition & 1 deletion frontend/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module.exports = {
root: true,
env: { browser: true, es2020: true },
env: { browser: true, es2020: true, node: true},
extends: [
'eslint:recommended',
'plugin:react/recommended',
Expand Down
12 changes: 12 additions & 0 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"@stripe/react-stripe-js": "^2.7.1",
"bcrypt": "^5.1.1",
"date-fns": "^3.6.0",
"dotenv": "^16.4.5",
"express": "^4.19.2",
"primeflex": "^3.3.1",
"primeicons": "^7.0.0",
Expand Down
9 changes: 6 additions & 3 deletions frontend/src/components/forms/login/Login.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ export default function Login() {
const navigate = useNavigate()
const [user, setUser] = useState("")
const [password, setPassword] = useState("")
// const domain = 'http://localhost:5000'
const domain = "http://86.38.204.61"
const domain = import.meta.env.VITE_API_URL

function validateEmail(email) {
const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
Expand All @@ -27,7 +26,10 @@ export default function Login() {
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({user, password})
body: JSON.stringify({
user: user,
password: btoa(password)
})
})
.then(async response => {
if (!response.ok) {
Expand All @@ -36,6 +38,7 @@ export default function Login() {
return response.json()
})
.then(data => {
data.password = btoa(password)
startSession(data)
navigate("/virtual-dojo/frontend/dashboard")
})
Expand Down
8 changes: 5 additions & 3 deletions frontend/src/components/forms/meet/MeetRegisterForm.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Button } from "primereact/button";
import { useState } from "react";
import { Calendar } from "primereact/calendar";
import styled from 'styled-components';
import {getBase64CredentialsFromSession} from "../../../utils/session";

const RegisterContainer = styled.div`
background-image: radial-gradient(circle at left top, var(--primary-400), var(--primary-700));
Expand Down Expand Up @@ -56,14 +57,15 @@ export default function MeetRegisterForm() {
const [date, setDate] = useState(today);
const [url, setUrl] = useState('');
const [price, setPrice] = useState(0);
// const domain = "http://localhost:5000"
const domain = "http://86.38.204.61";
const domain = import.meta.env.VITE_API_URL
const base64Credentials = getBase64CredentialsFromSession()

function saveMeet() {
fetch(domain + '/api/meets', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
'Content-Type': 'application/json',
'Authorization': `Basic ${base64Credentials}`
},
body: JSON.stringify({ meetUrl: url, meetDate: date, price: price })
})
Expand Down
3 changes: 1 addition & 2 deletions frontend/src/components/forms/register/Register.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ export default function Register() {
const [confirmPassword, setConfirmPassword] = useState("")
const [errors, setErrors] = useState({})
const navigate = useNavigate()
// const domain = 'http://localhost:5000'
const domain = "http://86.38.204.61"
const domain = import.meta.env.VITE_API_URL

const today = new Date()
const majorityAgeDate = new Date(today.getFullYear() - 18, 0, 1)
Expand Down
7 changes: 4 additions & 3 deletions frontend/src/components/payment/CheckoutForm.jsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import {useCallback} from "react"
import {loadStripe} from '@stripe/stripe-js'
import {format} from "date-fns"
import {getSession} from "../../utils/session.jsx";
import {getBase64CredentialsFromSession, getSession} from "../../utils/session.jsx";

// eslint-disable-next-line react/prop-types
export default function CheckoutForm({meet}) {
// const domain = "http://localhost:5000"
const domain = "http://86.38.204.61"
const domain = import.meta.env.VITE_API_URL

const stripePromise = loadStripe("pk_test_51PSHknKnVUk9u0R7xWznb2PU2LeYeOgFXDVB14wP4BvJQBJ3RdH0ZLF801Ka7oLlNd7pFV7VZndQa2soCDluMFf200UugFXgnD")
const user = getSession()
const base64Credentials = getBase64CredentialsFromSession()

const fetchSessionId = useCallback(() => {
return fetch(domain + "/api/stripe/create-checkout-session", {
Expand All @@ -21,6 +21,7 @@ export default function CheckoutForm({meet}) {
}),
headers: {
"Content-Type": "application/json",
'Authorization': `Basic ${base64Credentials}`
},
})
.then((res) => {
Expand Down
11 changes: 8 additions & 3 deletions frontend/src/hooks/useFetchMeets.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
import {useEffect, useState} from 'react';
import {getBase64CredentialsFromSession} from "../utils/session";

function useFetchMeets(isUser, hasSession) {
const [meets, setMeets] = useState([]);
const [error, setError] = useState(null);
// const domain = 'http://localhost:5000'
const domain = 'http://86.38.204.61'
const domain = import.meta.env.VITE_API_URL
const base64Credentials = getBase64CredentialsFromSession()

useEffect(() => {
async function fetchMeets() {
try {
const response = await fetch(domain + '/api/meets/all');
const response = await fetch(domain + '/api/meets/all', {
headers: {
'Authorization': `Basic ${base64Credentials}`
}
});

if (!response.ok) {
console.error('Network response was not ok', error);
Expand Down
8 changes: 6 additions & 2 deletions frontend/src/hooks/useSavePurchase.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
import {useEffect, useState} from "react"
import {getBase64CredentialsFromSession} from "../utils/session";

function useSavePurchase(isSuccess, meetId, userId) {
const [response, setResponse] = useState({})
const [error, setError] = useState(null);
// const domain = 'http://localhost:5000'
const domain = 'http://86.38.204.61'
const domain = import.meta.env.VITE_API_URL
const base64Credentials = getBase64CredentialsFromSession()

useEffect(() => {
async function savePurchase() {
try {
const response = await fetch(domain + '/api/purchases', {

method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Basic ${base64Credentials}`
},
body: JSON.stringify({ meetId, userId}),
})
Expand Down
5 changes: 5 additions & 0 deletions frontend/src/utils/session.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,8 @@ export const isAdmin = () => {
const sessionData = getSession()
return sessionData && sessionData.role && sessionData.role === 'ADMIN'
}

export const getBase64CredentialsFromSession = () => {
const sessionData = getSession()
return btoa(sessionData.email + ':' + sessionData.password)
}

0 comments on commit c26df52

Please sign in to comment.