gbowne1 / RadioLogger

A Radio Logging application build with NodeJS and ExpressJS
GNU General Public License v3.0
6 stars 6 forks source link

Duplicate routes #32

Closed jzunigarce closed 1 year ago

jzunigarce commented 1 year ago

The dashboard and signin routes are defined in both the server.js file and the routes folder. I suggest removing the ones defined in the server.js file and moving the rest of the routes to the routes folder

gbowne1 commented 1 year ago

There is a get route which asks if the user is auth then displays the dashboard. I agree. Lets remove the duplication.

There are also common folders like

Views Layouts Pages Middleware Data

I mean in addidtion to what we already have for structure Which I think is more modularized.

jzunigarce commented 1 year ago

We can create a middleware for validate authentication on routes

gbowne1 commented 1 year ago

Yeah I was thinking about that during breakfast this morning. I like that. I have examples from the old project auth.{...}.js and also an auth.js Which would you like to see?

jzunigarce commented 1 year ago

Yes, please

gbowne1 commented 1 year ago

@jzunigarce

auth.js

const authenticate = async (req, res, next) => {
    let id, email, role;

    try {
      if (!req.headers.access_token) {
        throw {
          code: 401,
          message: 'Unauthorized, you must login first', from: 'auth.js'        };
      }

      ({ id, email, role } = verifyToken(req.headers.access_token));
    } catch (err) {
      return next(err);
    }

    try {
      const user = await User.findOne({ where: { email } });

      if (!user) {
        throw {
          code: 401,
          message: 'Unauthorized, only admin can perform this action', from: 'auth.js'
        };
      }

      req.currentUser = {
        id: user.id,
        email: user.email,
        role: user.role
      };

      return next();
    } catch (err) {
      return next({ code: 500, message: err.message, from: 'auth.js' });
    }
  };

user.controller.js

  const { user } = require("../models/user");
const bcrypt = require("bcrypt")
const jwt = require("jsonwebtoken")
module.exports.register = (req, res) => {
    const user = new user(req.body);
    user.save()
        .then(() => {
            res.json({ msg: "success!", user: user });
        })
        .catch(err => res.json(err));
};

module.exports.getAll = async (req, res) => {
    const getAll = await user.find({})
    res.json(getAll)
}
module.exports.logout = (req, res) => {
    try {
        res.clearCookie("userToken");
        res.json({ msg: "" });
    } catch (error) {
        res.status(400)
        res.json(error)
    }
}
module.exports.login = async (req, res) => {
    try {
        const { email, password } = req.body;
        const usuario = await user.findOne({ email: email })
        if (usuario === null) {
            return res.status(403).json({ msg: "" })
        }
        const isValid = await bcrypt.compare(password, usuario.password);
        if (isValid) {
            const secret = "clave sercret jwt"
            const newJWT = jwt.sign({
                _id: usuario._id,
                usuario: usuario.userName,
                acceso: usuario.permit
            }, secret)
            res.cookie("userToken", newJWT, {
                httpOnly: true
            })
            res.json({ msg: "Logueado Correctamente" })

        } else {
            return res.status(403).json({ msg: "Correo o contraseña Incorrecta" })
        }
    } catch (error) {
        res.status(400)
        res.json(error)
    }
}

module.exports.generator = async (req, res) => {
    const { guarda } = req.body
    try {
        const secret = "";
        const newTokenQR = jwt.sign({
            id: new Date(),
            guard: guard
        }, secret)
        res.json(newTokenQR);
    } catch (error) {
        return res.json({ msg: "" })
    }
}
module.exports.searchEmail = async (req, res) => {
    //console.log(req.body)
    const { email } = req.body
    const result = await user.findOne({ email: email })
    res.json(result)
}
module.exports.getUser = async (req, res) => {
    const { id } = req.body
    const result = await user.findOne({ _id: id })
    res.json(result)
}

const token = jwt.sign({ id: user._id }, 'your_jwt_secret', { expiresIn: 86400 });

  res.status(200).send({ id: user._id, username: user.username, accessToken: token });

api.js

import express from 'express';
import cors from 'cors';
import axios from 'axios';

export const API = '';
export const ENDPOINT = '/api/v1';

export default {
  API_ENDPOINT: API,
  ENDPOINT
};

the original server.js

const express = require('express');
const session = require('express-session');
const app = express();
const router = express.Router()
const http = require('http');
const hostname = '127.0.0.1';
const path = require('path');
const mongoose = require('mongoose');
const cors = require('cors');
const bodyParser = require('body-parser'); // Middleware
const cookieParser = require('cookie-parser')
const componentsDirUrl = './src/client/src/components';

async function main() {
  mongoose.set('strictQuery', true)
  await mongoose.connect('mongodb://localhost:27017/test')
  .then(()=> console.log("Connected to MongoDB"))
  .catch(err => console.log("Unable to connect ", err.message))

  // use `await mongoose.connect('mongodb://user:password@localhost:27017/test');` if your database has auth enabled
}
main()

app.use(express.json());

app.set('view engine', 'html');

/*app.use(express.static(config.set('/components')));*/

app.all('/*', function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "X-Requested-With");
  next();
});

app.use(session({
    secret: 'secret',
    resave: true,
    saveUninitialized: true
}));

app.use(cors({credentials: true, origin: true}));

app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(express.urlencoded({ extended: true }));
app.set('port', (process.env.PORT || 3000));

app.use(cookieParser());

app.use(express.static(path.join(__dirname, '/public')));
app.use(express.static(path.join(__dirname, '/src/client/src/components')));

// for including all css & image file in server
app.use(express.static(__dirname + "/public"));

app.use(express.static(__dirname +"/src/client/src/components"));

app.get('/', (req, res) => {
  res.sendFile(__dirname + '/index.html')
});

app.get('/api/v1/users/:id', (req, res) => {
    const id = parseInt(req.params.id)
    const users = {name: 'someuser', id: 1}
    res.send(users)
    console.log(users)
});

app.get('/dashboard', (req, res) => {
  res.header('Content-type', 'text/html');
  res.sendFile(componentsDirUrl + '/dashboard.html', { root: __dirname });
});

app.get('/contestlog', (req, res) => {
  res.header('Content-type', 'text/html');
  res.sendFile(componentsDirUrl + '/contestlog.html', { root: __dirname });
});

app.get('/scanlog', (req, res) => {
  res.header('Content-type', 'text/html');
  res.sendFile(componentsDirUrl + '/scanlog.html', { root: __dirname });
});

app.get('/swllog', (req, res) => {
  res.header('Content-type', 'text/html');
  res.sendFile(componentsDirUrl + '/swllog.html', { root: __dirname });
});

app.get('/signin', function (req, res) {
  res.header('Content-type', 'text/html');
  res.sendFile(componentsDirUrl + '/signin.html', { root: __dirname });
});

app.get('/hamlog', function (req, res) {
  res.header('Content-type', 'text/html');
  res.sendFile(componentsDirUrl + '/hamlog.html', { root: __dirname });
});

app.get('/signup', function (req, res) {
  res.header('Content-type', 'text/html');
  res.sendFile(componentsDirUrl + '/signup.html', { root: __dirname });
});

app.get('/mwlog', function (req, res) {
  res.header('Content-type', 'text/html');
  res.sendFile(componentsDirUrl + '/mwlog.html', { root: __dirname });
});

app.get('/vhflog', function (req, res) {
  res.header('Content-type', 'text/html');
  res.sendFile(componentsDirUrl + '/vhflog.html', { root: __dirname });
});

app.post('/signin', (req, res) => {
  res.header('Content-type', 'text/html');
  // Insert Login Code Here
  let username = req.body.username;
  let password = req.body.password;
  res.send(`Username: ${username} Password: ${password}`);
});

// Route to Login Page
app.get('/login', (req, res) => {
  res.header('Content-type', 'text/html');
  res.sendFile(__dirname + '/signin.html');
});

app.post('/login', (req, res) => {
  // Insert Login Code Here
  let username = req.body.username;
  let password = req.body.password;
  res.send(`Username: ${username} Password: ${password}`);
});

app.post('/auth', function(request, response) {
    // Capture the input fields
    let username = request.body.username;
    let password = request.body.password;
    // Ensure the input fields exists and are not empty
    if (username && password) {
        // Execute SQL query that'll select the account from the database based on the specified username and password
        connection.query('SELECT * FROM accounts WHERE username = ? AND password = ?', [username, password], function(error, results, fields) {
            // If there is an issue with the query, output the error
            if (error) throw error;
            // If the account exists
            if (results.length > 0) {
                // Authenticate the user
                request.session.loggedin = true;
                request.session.username = username;
                // Redirect to home page
                response.redirect('/home');
            } else {
                response.send('Incorrect Username and/or Password!');
            }
            response.end();
        });
    } else {
        response.send('Please enter Username and Password!');
        response.end();
    }
});

app.get('/logout', function (req, res) {
  req.session.destroy();
  res.send("logout success!");
});

app.post('/signup', function(req, res){
  if(!req.body.id || !req.body.password){
     res.status("400");
     res.send("Invalid details!");
  } else {
     Users.filter(function(user){
        if(user.id === req.body.id){
           res.render('signup', {
              message: "User Already Exists! Login or choose another user id"});
        }
     });
     var newUser = {id: req.body.id, password: req.body.password};
     Users.push(newUser);
     req.session.user = newUser;
     res.redirect('/protected_page');
  }
});

/* app.use((req, res) =>
  res.status(404).render('404', { title: '404' });
});
*/

app.get('*', (req, res) => {
   res.status(404).sendFile(componentsDirUrl + '/404.html', { root: __dirname });
});

var allowCrossDomain = function (req, res, next) {
  res.header("Access-Control-Allow-Credentials", true);
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
  res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');

  next();
}

/*
app.configure(function() {
  app.use(express.bodyParser());
  app.use(express.cookieParser());
  app.use(express.session({ secret: 'cool beans' }));
  app.use(express.methodOverride());
  app.use(allowCrossDomain);
});
*/

app.use((req, res, next) => {
    res.status(404).send("Sorry, that route doesn't exist. Have a nice day :)");
});

const port = process.env.PORT || 3001
app.listen(port, console.log(`Up and Running on port ${port}`))
gbowne1 commented 1 year ago

the original auth.routes.js

const express = require('express');
const { user } = require('../controllers/auth.controller');

const router = express.Router();

router.post('/user', user.signup);
router.get('/user', user.index);
router.post('/user', user.create);
router.delete('/user/:id', user.delete);
router.patch('/user/:id', user.update);
module.exports = router;

the original user.routes.js

const express = require('express');
const api = express.Router();
const userController = require('./user.controller');
const { ensureAuth, isAdmin } = require('../services/authenticated');

//test rutes
api.get('/test', [ensureAuth, isAdmin], userController.test);
api.post('/register', userController.register);
api.post('/save', [ensureAuth, isAdmin], userController.save);
api.post('/login', userController.login);
api.put('/update/:id', ensureAuth, userController.update);
api.delete('/delete/:id', ensureAuth, userController.delete);
module.exports = api;
jzunigarce commented 1 year ago

I like to make a proposal of the structure of the routes and logic in the server, can you help me define the routes that you have contemplated using, both for the pages and if you are going to use endpoint for apis?

gbowne1 commented 1 year ago

We have pretty much all of the routes for the pages already.

We will have both internal API's (I think it would be nice to provide users with some API's) as well as consume external API's from a website or websites, like api.radioreference.com as mentioned in another issue (has the actual link.

I am still missing /profile and /settings that is for the user profile and the settings, accessible from the User Icon.

Go ahead and make your proposal, we can decide with some followup conversation.

jzunigarce commented 1 year ago

What path will be used to sign in, signin or auth?

gbowne1 commented 1 year ago

/login or /signin, either is fine.

gbowne1 commented 1 year ago

Closed as largely fixed by recent merge