Skip to content

Commit

Permalink
Object endpoints (#33)
Browse files Browse the repository at this point in the history
* Add cross-env for seamless Windows support

* Initial object endpoints

* Add mongodb memory server for easier testing

* Rename Object to Offer

* Add flat package

* bug fixes, flatten body before updating, better error formatting

* surname -> lastName to pass tests

* update roleCheck for easier usage

* Add authorization

* Add @types/jest package for jest suggestions in vscode

* Improve error messages

* Add tests

* fix casing to pass github actions tests

* fix auth

* reenable tests

* cleanup

* apply suggestions
  • Loading branch information
krygacz authored Mar 7, 2022
1 parent e64ebee commit 7f683ec
Show file tree
Hide file tree
Showing 17 changed files with 527 additions and 66 deletions.
1 change: 0 additions & 1 deletion .env.template
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
MONGO_URL =
MONGO_TEST_URL =
PORT =
JWT_SECRET =
JWT_EXP =
81 changes: 65 additions & 16 deletions package-lock.json

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

7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
"type": "module",
"scripts": {
"start": "node .",
"dev": "NODE_ENV=development nodemon .",
"test": "NODE_ENV=test jest",
"dev": "cross-env NODE_ENV=development nodemon .",
"test": "cross-env NODE_ENV=test jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage",
"postinstall": "husky install",
Expand All @@ -28,9 +28,11 @@
"dependencies": {
"bcrypt": "^5.0.1",
"cors": "^2.8.5",
"cross-env": "^7.0.3",
"dotenv": "^16.0.0",
"express": "^4.17.3",
"express-validator": "^6.14.0",
"flat": "^5.0.2",
"jsonwebtoken": "^8.5.1",
"mongoose": "^6.2.3",
"morgan": "^1.10.0",
Expand All @@ -41,6 +43,7 @@
"@babel/core": "^7.17.5",
"@babel/eslint-parser": "^7.17.0",
"@babel/preset-env": "^7.16.11",
"@types/jest": "^27.4.1",
"eslint": "^8.9.0",
"eslint-config-prettier": "^8.4.0",
"eslint-plugin-jest": "^26.1.1",
Expand Down
4 changes: 3 additions & 1 deletion src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'dotenv/config';
import cors from 'cors';
import morgan from 'morgan';
import { StartRouter } from './routes/start.js';
import { OfferRouter } from './offer/offer.router.js';
import passport from 'passport';
import { AuthRouter } from './auth/auth.router.js';
import { JwtConfig } from './auth/passport.js';
Expand All @@ -10,12 +11,13 @@ import { UserRouter } from './user/user.router.js';
export const app = express();

app.use(passport.initialize());
JwtConfig(passport);
JwtConfig();
app.use(cors());
app.use(morgan('tiny'));
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

app.use('/', StartRouter);
app.use('/auth', AuthRouter);
app.use('/offer', OfferRouter);
app.use('/user', UserRouter);
8 changes: 2 additions & 6 deletions src/auth/auth.router.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,12 @@ import { Router } from 'express';
import { signin, signup, protectedController } from './auth.controller.js';
import { verifyFieldsErrors } from '../middlewares/validation.middleware.js';
import { registerValidator, loginValidator } from '../helpers/validators.js';
import passport from 'passport';
import { requireAuth } from './passport.js';

export const AuthRouter = Router();

AuthRouter.post('/register', [registerValidator, verifyFieldsErrors], signup);

AuthRouter.post('/login', [loginValidator, verifyFieldsErrors], signin);

AuthRouter.get(
'/protected',
passport.authenticate('jwt', { session: false }),
protectedController,
);
AuthRouter.get('/protected', requireAuth, protectedController);
6 changes: 3 additions & 3 deletions src/auth/auth.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import request from 'supertest';
import { app } from '../app.js';
import { connect, disconnect } from '../helpers/testDbConnection.js';
import dbConnection from '../helpers/dbConnection.js';

const userBody = {
email: `[email protected]`,
Expand All @@ -22,10 +22,10 @@ let token;

describe('auth endpoints', () => {
beforeAll(async () => {
await connect();
await dbConnection.connect();
});
afterAll(async () => {
await disconnect();
await dbConnection.disconnect();
});

it('should allow a POST to /auth/register with correct data', async () => {
Expand Down
16 changes: 14 additions & 2 deletions src/auth/passport.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { Strategy, ExtractJwt } from 'passport-jwt';
import passport from 'passport';
import { User } from '../user/user.model.js';

export const JwtConfig = (passport) => {
export const JwtConfig = () => {
const options = {
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: process.env.JWT_SECRET,
Expand All @@ -10,7 +11,7 @@ export const JwtConfig = (passport) => {
const JwtStrategy = () =>
new Strategy(options, async (payload, done) => {
try {
const user = await User.findOne({ id: payload.id });
const user = await User.findOne({ _id: payload.id });
if (user) {
return done(null, user);
} else {
Expand All @@ -23,3 +24,14 @@ export const JwtConfig = (passport) => {

passport.use(JwtStrategy());
};

export const requireAuth = (req, res, next) => {
passport.authenticate('jwt', { session: false }, function (err, user, info) {
if (err || !user?.role) {
return res.status(401).json({ message: 'Unauthorized', errors: [info] });
} else {
req.user = user;
return next();
}
})(req, res, next);
};
26 changes: 7 additions & 19 deletions src/helpers/dbConnection.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,9 @@
import mongoose from 'mongoose';
import * as productionDbConnection from './productionDbConnection.js';
import * as testDbConnection from './testDbConnection.js';

const dbUri =
process.env.NODE_ENV === 'test'
? process.env.MONGO_TEST_URL
: process.env.MONGO_URL;
const dbConnection =
process.env.NODE_ENV === 'production'
? productionDbConnection
: testDbConnection;

export const dbConnection = async () => {
try {
await mongoose.connect(dbUri, {
useNewUrlParser: true,
useUnifiedTopology: true,
});
} catch (error) {
console.log(error.message);
}
};

export const closeConnection = () => {
return mongoose.disconnect();
};
export default dbConnection;
16 changes: 16 additions & 0 deletions src/helpers/productionDbConnection.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import mongoose from 'mongoose';

export const connect = async () => {
try {
await mongoose.connect(process.env.MONGO_URL, {
useNewUrlParser: true,
useUnifiedTopology: true,
});
} catch (error) {
console.log(error.message);
}
};

export const disconnect = () => {
return mongoose.disconnect();
};
Loading

0 comments on commit 7f683ec

Please sign in to comment.