Skip to content

Commit

Permalink
Merge pull request #14 from jfabellera/react-frontend
Browse files Browse the repository at this point in the history
React Front End
  • Loading branch information
jfabellera authored Jan 4, 2021
2 parents bff0f28 + 32c0036 commit c44f04e
Show file tree
Hide file tree
Showing 66 changed files with 21,834 additions and 2,050 deletions.
47 changes: 47 additions & 0 deletions .vscode/docs.code-snippets
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
// Place your billy workspace snippets here. Each snippet is defined under a snippet name and has a scope, prefix, body and
// description. Add comma separated ids of the languages where the snippet is applicable in the scope field. If scope
// is left empty or omitted, the snippet gets applied to all languages. The prefix is what is
// used to trigger the snippet and the body will be expanded and inserted. Possible variables are:
// $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders.
// Placeholders with the same ids are connected.
// Example:
// "Print to console": {
// "scope": "javascript,typescript",
// "prefix": "log",
// "body": [
// "console.log('$1');",
// "$2"
// ],
// "description": "Log output to console"
// }

"API request documentation": {
"scope": "markdown",
"prefix": "apidoc",
"body": [
"---",
"",
"## $1",
"",
"$2",
"",
"```",
"$3",
"```",
"",
"| Parameter | Type | In | Description |",
"| --------- | ---- | -- | ----------- |",
"| $4 | $5 | $6 | $7 |"
],
"description": "Template for API request documentation"
},
"API parameter row": {
"scope": "markdown",
"prefix": "apirow",
"body": [
"| $1 | $2 | $3 | $4 |"
],
"description": "Template for API documentation parameter row"
}
}
82 changes: 19 additions & 63 deletions app.js
Original file line number Diff line number Diff line change
@@ -1,79 +1,35 @@
var createError = require("http-errors");
var express = require("express");
var path = require("path");
var cookieParser = require("cookie-parser");
var logger = require("morgan");
var session = require("express-session");
var methodOverride = require("method-override");
const mongoose = require("mongoose");
var dotenv = require("dotenv");
dotenv.config();
const express = require('express');
const logger = require('morgan');
const cors = require('cors');
const mongoose = require('mongoose');
const config = require('./config');

const uri = process.env.mongodb_uri;
mongoose.connect(uri, {
mongoose.connect(config.mongodb_uri, {
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true,
useFindAndModify: false,
});

mongoose.connection.on("connected", () => {
console.log("MongoDB connection established");
mongoose.connection.on('connected', () => {
console.log('MongoDB connection established');
});

mongoose.connection.on("error", (err) => {
mongoose.connection.on('error', (err) => {
console.log(err);
});

var indexRouter = require("./routes/index");
var usersRouter = require("./routes/users");
var expensesRouter = require("./routes/expenses");
const usersRouter = require('./routes/users');
const expensesRouter = require('./routes/expenses');

var app = express();
let app = express();

// view engine setup
app.set("views", path.join(__dirname, "views"));
app.set("view engine", "ejs");

app.use(logger("dev"));
app.use(cors());
app.use(logger('dev'));
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.use(
express.urlencoded({
extended: false,
})
);
app.use(cookieParser());
app.use(express.static(path.join(__dirname, "public")));
app.use(
session({
secret: "sampleSecret",
resave: false,
saveUninitialized: true,
})
);

app.use(methodOverride("_method"));

app.use("/", indexRouter);
app.use("/users", usersRouter);
app.use("/expenses", expensesRouter);

// catch 404 and forward to error handler
app.use(function (req, res, next) {
next(createError(404));
});

// error handler
app.use(function (err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get("env") === "development" ? err : {};

// render the error page
res.status(err.status || 500);
res.render("error", {
session: req.session,
error: res.locals.error,
});
});
app.use('/users', usersRouter);
app.use('/expenses', expensesRouter.router);

module.exports = app;
app.listen(5000);
113 changes: 113 additions & 0 deletions authServer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
const express = require('express');
const logger = require('morgan');
const cors = require('cors');
const bcrypt = require('bcrypt');
const app = express();
const jwt = require('jsonwebtoken');
const config = require('./config');
const { check, validationResult } = require('express-validator');
const mongoose = require('mongoose');

mongoose.connect(config.mongodb_uri, {
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true,
useFindAndModify: false,
});

mongoose.connection.on('connected', () => {
console.log('MongoDB connection established');
});

mongoose.connection.on('error', (err) => {
console.log(err);
});

app.use(cors());
app.use(logger('dev'));
app.use(express.urlencoded({ extended: true }));
app.use(express.json());

const Token = require('./models/tokenModel');
const User = require('./models/userModel');

app.post('/refresh', (req, res) => {
const refreshToken = req.body.token;
if (refreshToken == null) return res.sendStatus(401);
Token.findOne({ refresh_token: refreshToken }, (err, token) => {
if (err) throw err;
if (!token) return res.sendStatus(401);
jwt.verify(refreshToken, config.jwt_refresh_secret, (err, decoded) => {
if (err) return res.sendStatus(401);
const accessToken = generateAccessToken(decoded.user);
res.json({ accessToken: accessToken });
});
});
});

app.delete('/logout', (req, res) => {
// delete refresh token from database
Token.findOneAndDelete({ refresh_token: req.body.token }, (err, token) => {
if (err) throw err;
});

res.sendStatus(204);
});

app.post('/login', [check(['username', 'password']).exists()], (req, res) => {
let err = validationResult(req);
if (!err.isEmpty()) {
res.status(400).json(err.errors);
} else {
User.findOne(
{ username: req.body.username.toLowerCase() },
async (err, user) => {
if (err) throw err;
try {
if (
user != null &&
!user.disabled &&
(await bcrypt.compare(req.body.password, user.password_hash))
) {
// authorized
let userInfo = {};
userInfo.username = user.username;
userInfo.name = user.name;
userInfo.account_type = user.account_type;

const accessToken = generateAccessToken(userInfo);
const refreshToken = jwt.sign(
{ user: userInfo },
config.jwt_refresh_secret
);

// add refresh token to database
Token.create(
{
refresh_token: refreshToken,
user_id: user._id,
},
(err, token) => {
if (err) throw err;
}
);

res.json({ accessToken: accessToken, refreshToken: refreshToken });
} else {
// unauthorized
res.status(401).json({ message: 'Authentication failed' });
}
} catch {
// error
res.status(500).send();
}
}
);
}
});

function generateAccessToken(user) {
return jwt.sign({ user }, config.jwt_access_secret, { expiresIn: '15m' });
}

app.listen(5001);
90 changes: 0 additions & 90 deletions bin/www

This file was deleted.

11 changes: 11 additions & 0 deletions config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
require('dotenv').config();

const JWT_ACCESS_SECRET = process.env.JWT_ACCESS_SECRET;
const JWT_REFRESH_SECRET = process.env.JWT_REFRESH_SECRET;
const MONGODB_URI = process.env.MONGODB_URI;

module.exports = {
jwt_access_secret: JWT_ACCESS_SECRET,
jwt_refresh_secret: JWT_REFRESH_SECRET,
mongodb_uri: MONGODB_URI,
};
23 changes: 23 additions & 0 deletions frontend/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# production
/build

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*
Loading

0 comments on commit c44f04e

Please sign in to comment.