server overhaul, new jwt strategy, some various patches
This commit is contained in:
@@ -20,12 +20,25 @@ export default class AuthService {
|
|||||||
// not allowed to use email address that already exists
|
// not allowed to use email address that already exists
|
||||||
const user = await UserInstance.getOneByEmail(data.email);
|
const user = await UserInstance.getOneByEmail(data.email);
|
||||||
|
|
||||||
if (user) throw createError('409', 'Email already in use');
|
if (user) {
|
||||||
|
return new ControllerResponse(StatusCode.Conflict, "Email already in use", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check that all required fields are populated
|
||||||
|
let missingFields = new Array<string>();
|
||||||
|
let requiredFields: Array<keyof IUser> = ['firstname', 'lastname', 'handle', 'email', 'isadmin', 'password'];
|
||||||
|
for (let field of requiredFields) {
|
||||||
|
if (!(field in data)) {
|
||||||
|
missingFields.push(field as string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (missingFields.length) {
|
||||||
|
return new ControllerResponse(StatusCode.BadRequest, `Missing fields in output: ${missingFields.join(", ")}`, false);
|
||||||
|
}
|
||||||
|
|
||||||
// hash password and create new user record
|
// hash password and create new user record
|
||||||
const salt = await bcrypt.genSalt(12);
|
const salt = await bcrypt.genSalt(12);
|
||||||
console.log(salt);
|
|
||||||
console.log(data.password);
|
|
||||||
|
|
||||||
bcrypt.hash(data.password!, salt, (err, hash) => {
|
bcrypt.hash(data.password!, salt, (err, hash) => {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
@@ -37,7 +50,7 @@ export default class AuthService {
|
|||||||
UserInstance.post(newData);
|
UserInstance.post(newData);
|
||||||
})
|
})
|
||||||
|
|
||||||
return true;
|
return new ControllerResponse(StatusCode.NewContent, "registered successfully", true);
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
throw new Error(e);
|
throw new Error(e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,23 @@
|
|||||||
import e, { NextFunction, Request, Response } from "express"
|
import { NextFunction, Request, Response } from "express"
|
||||||
import ControllerResponse from "../util/ControllerResponse";
|
import dotenv from "dotenv";
|
||||||
import { StatusCode } from "../util/types";
|
import { IUser } from "../schemas";
|
||||||
|
|
||||||
|
dotenv.config();
|
||||||
|
|
||||||
export function restrictAccess(req: Request, res: Response, next: NextFunction) {
|
export function restrictAccess(req: Request, res: Response, next: NextFunction) {
|
||||||
if (req.session.user == undefined) {
|
if (req.session.user == undefined) {
|
||||||
console.log("restricted")
|
res.send("content restricted");
|
||||||
res.send(undefined);
|
} else {
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function requireSessionSecret(req: Request, res: Response, next: NextFunction) {
|
||||||
|
const secret = process.env.SESSIONSECRET;
|
||||||
|
|
||||||
|
if (!secret) {
|
||||||
|
res.sendStatus(500);
|
||||||
|
throw new Error("Express secret is undefined");
|
||||||
} else {
|
} else {
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
@@ -20,5 +32,11 @@ export function checkFriendStatus(req: Request, res: Response, next: NextFunctio
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function checkIsAdmin(req: Request, res: Response, next: NextFunction) {
|
export function checkIsAdmin(req: Request, res: Response, next: NextFunction) {
|
||||||
|
const user: IUser | undefined = req.user as IUser;
|
||||||
|
|
||||||
|
if (user.isadmin) {
|
||||||
|
next();
|
||||||
|
} else {
|
||||||
|
res.status(403).send("Unauthorized");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,13 +1,11 @@
|
|||||||
import express from 'express';
|
import express from 'express';
|
||||||
import cors from 'cors';
|
|
||||||
import dotenv from 'dotenv';
|
import dotenv from 'dotenv';
|
||||||
import { loaders } from './loaders';
|
import { loaders } from './loaders';
|
||||||
|
|
||||||
dotenv.config();
|
dotenv.config();
|
||||||
|
|
||||||
const port = 8080;
|
const port = process.env.PORT || 8080;
|
||||||
const app = express();
|
const app = express();
|
||||||
app.use(cors());
|
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
await loaders(app);
|
await loaders(app);
|
||||||
|
|||||||
@@ -6,39 +6,31 @@ import cors from 'cors';
|
|||||||
import session from 'express-session';
|
import session from 'express-session';
|
||||||
import pgSessionStore from '../db/sessionStore';
|
import pgSessionStore from '../db/sessionStore';
|
||||||
import { IUser } from '../schemas';
|
import { IUser } from '../schemas';
|
||||||
|
import { requireSessionSecret } from '../auth/middlewares';
|
||||||
|
|
||||||
declare module "express-session" {
|
const origin = process.env.ORIGIN || 'http://localhost:5173';
|
||||||
|
const secret = process.env.SESSIONSECRET;
|
||||||
|
|
||||||
|
declare module 'express-session' {
|
||||||
interface SessionData {
|
interface SessionData {
|
||||||
user: IUser
|
user?: IUser
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const expressLoader = async (app: Express) => {
|
export const expressLoader = async (app: Express) => {
|
||||||
app.use(cors({
|
app.use(cors({ origin: origin }));
|
||||||
origin: process.env.ORIGIN || 'http://localhost:5173',
|
|
||||||
credentials: true
|
|
||||||
}));
|
|
||||||
|
|
||||||
app.use(bodyParser.json());
|
app.use(bodyParser.json());
|
||||||
app.use(bodyParser.urlencoded({ extended: true }));
|
app.use(bodyParser.urlencoded({ extended: true }));
|
||||||
app.use(cookieParser());
|
app.use(cookieParser());
|
||||||
|
|
||||||
// app.options("*", cors({ origin: 'http://localhost:5173', optionsSuccessStatus: 200 }));
|
|
||||||
// app.use(cors({ origin: "http://localhost:5173", optionsSuccessStatus: 200 }));
|
|
||||||
|
|
||||||
app.use(morgan('tiny'));
|
app.use(morgan('tiny'));
|
||||||
|
app.use(requireSessionSecret);
|
||||||
app.get('/', (req, res) => {
|
|
||||||
res.cookie('name', 'express').send('cookie set');
|
|
||||||
})
|
|
||||||
|
|
||||||
const secret = process.env.SESSIONSECRET as string;
|
|
||||||
|
|
||||||
app.use(session({
|
app.use(session({
|
||||||
secret: secret,
|
secret: secret as string,
|
||||||
cookie: {
|
cookie: {
|
||||||
maxAge: 8 * 60 * 60 * 1000,
|
maxAge: 8 * 60 * 60 * 1000,
|
||||||
secure: false
|
secure: false,
|
||||||
|
httpOnly: false
|
||||||
},
|
},
|
||||||
resave: false,
|
resave: false,
|
||||||
saveUninitialized: false,
|
saveUninitialized: false,
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { passportLoader } from './passport';
|
|||||||
|
|
||||||
export const loaders = async (app: Express) => {
|
export const loaders = async (app: Express) => {
|
||||||
const expressApp = await expressLoader(app);
|
const expressApp = await expressLoader(app);
|
||||||
const passportApp = await passportLoader(expressApp);
|
await passportLoader(expressApp);
|
||||||
await swaggerLoader(expressApp);
|
await swaggerLoader(expressApp);
|
||||||
await routes(expressApp, passportApp);
|
await routes(expressApp);
|
||||||
}
|
}
|
||||||
@@ -1,32 +1,35 @@
|
|||||||
import { Strategy as LocalStrategy } from "passport-local";
|
|
||||||
import passport from "passport";
|
import passport from "passport";
|
||||||
import { Express } from "express";
|
import { Express } from "express";
|
||||||
import AuthService from "../auth";
|
import { ExtractJwt, Strategy as JwtStrategy } from "passport-jwt";
|
||||||
import { IUserAuth } from "../schemas";
|
|
||||||
const AuthInstance = new AuthService();
|
|
||||||
|
|
||||||
export const passportLoader = async (app: Express) => {
|
export const passportLoader = async (app: Express) => {
|
||||||
app.use(passport.initialize());
|
app.use(passport.initialize());
|
||||||
app.use(passport.session());
|
app.use(passport.session());
|
||||||
|
|
||||||
passport.serializeUser((user, done) => {
|
passport.serializeUser((user: Express.User, done) => {
|
||||||
done(null, user);
|
process.nextTick(() => {
|
||||||
|
done(null, user);
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
passport.deserializeUser((user: IUserAuth, done) => {
|
passport.deserializeUser((user: Express.User, done) => {
|
||||||
done(null, user);
|
process.nextTick(() => {
|
||||||
|
done(null, user);
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
// sign in method with passport local strategy
|
// config for jwt strategy
|
||||||
passport.use(new LocalStrategy({
|
let opts = {
|
||||||
usernameField: 'email',
|
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
|
||||||
passwordField: 'password'
|
secretOrKey: 'secret'
|
||||||
}, async (email, password, done) => {
|
}
|
||||||
|
|
||||||
|
// jwt strategy
|
||||||
|
passport.use(new JwtStrategy(opts, async (token, done) => {
|
||||||
try {
|
try {
|
||||||
const response = await AuthInstance.login({ email, password });
|
return done(null, token.user);
|
||||||
return done(null, response);
|
} catch (error) {
|
||||||
} catch (e: any) {
|
done(error);
|
||||||
return done(e);
|
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "bash util/build.sh",
|
"build": "bash util/build.sh",
|
||||||
"seed": "npm run build && ts-node-dev db/seed.ts",
|
"seed": "npm run build && ts-node --files db/seed.ts",
|
||||||
"dev": "bash util/dev.sh",
|
"dev": "bash util/dev.sh",
|
||||||
"prod": "npm run build && node dist/index.js",
|
"prod": "npm run build && node dist/index.js",
|
||||||
"test": "jest --coverage",
|
"test": "jest --coverage",
|
||||||
@@ -15,7 +15,6 @@
|
|||||||
"author": "",
|
"author": "",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/cookie-parser": "^1.4.3",
|
|
||||||
"bcrypt": "^5.1.0",
|
"bcrypt": "^5.1.0",
|
||||||
"body-parser": "^1.20.1",
|
"body-parser": "^1.20.1",
|
||||||
"connect-pg-simple": "^8.0.0",
|
"connect-pg-simple": "^8.0.0",
|
||||||
@@ -28,8 +27,10 @@
|
|||||||
"helmet": "^6.0.0",
|
"helmet": "^6.0.0",
|
||||||
"http-errors": "^2.0.0",
|
"http-errors": "^2.0.0",
|
||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
|
"jsonwebtoken": "^9.0.0",
|
||||||
"morgan": "^1.10.0",
|
"morgan": "^1.10.0",
|
||||||
"passport": "^0.6.0",
|
"passport": "^0.6.0",
|
||||||
|
"passport-jwt": "^4.0.1",
|
||||||
"passport-local": "^1.0.0",
|
"passport-local": "^1.0.0",
|
||||||
"pg": "^8.8.0",
|
"pg": "^8.8.0",
|
||||||
"pg-promise": "^10.15.0",
|
"pg-promise": "^10.15.0",
|
||||||
@@ -38,16 +39,18 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/bcrypt": "^5.0.0",
|
"@types/bcrypt": "^5.0.0",
|
||||||
"@types/connect-pg-simple": "^7.0.0",
|
"@types/connect-pg-simple": "^7.0.0",
|
||||||
|
"@types/cookie-parser": "^1.4.3",
|
||||||
"@types/cors": "^2.8.12",
|
"@types/cors": "^2.8.12",
|
||||||
"@types/dotenv": "^8.2.0",
|
"@types/dotenv": "^8.2.0",
|
||||||
"@types/express": "^4.17.14",
|
"@types/express": "^4.17.14",
|
||||||
"@types/express-session": "^1.17.5",
|
"@types/express-session": "^1.17.6",
|
||||||
"@types/http-errors": "^2.0.1",
|
"@types/http-errors": "^2.0.1",
|
||||||
"@types/jest": "^29.2.4",
|
"@types/jest": "^29.2.4",
|
||||||
"@types/js-yaml": "^4.0.5",
|
"@types/js-yaml": "^4.0.5",
|
||||||
"@types/morgan": "^1.9.3",
|
"@types/morgan": "^1.9.3",
|
||||||
"@types/node": "^18.11.9",
|
"@types/node": "^18.11.9",
|
||||||
"@types/passport": "^1.0.11",
|
"@types/passport": "^1.0.11",
|
||||||
|
"@types/passport-jwt": "^3.0.8",
|
||||||
"@types/passport-local": "^1.0.34",
|
"@types/passport-local": "^1.0.34",
|
||||||
"@types/pg": "^8.6.5",
|
"@types/pg": "^8.6.5",
|
||||||
"@types/pg-promise": "^5.4.3",
|
"@types/pg-promise": "^5.4.3",
|
||||||
@@ -57,6 +60,7 @@
|
|||||||
"nodemon": "^2.0.20",
|
"nodemon": "^2.0.20",
|
||||||
"supertest": "^6.3.3",
|
"supertest": "^6.3.3",
|
||||||
"ts-jest": "^29.0.3",
|
"ts-jest": "^29.0.3",
|
||||||
|
"ts-node": "^10.9.1",
|
||||||
"ts-node-dev": "^2.0.0",
|
"ts-node-dev": "^2.0.0",
|
||||||
"tslint": "^6.1.3",
|
"tslint": "^6.1.3",
|
||||||
"typescript": "^4.9.3"
|
"typescript": "^4.9.3"
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { Express, Request, Router } from "express"
|
import { Express, Router } from "express"
|
||||||
import { PassportStatic } from "passport";
|
import { PassportStatic } from "passport";
|
||||||
|
import jwt from "jsonwebtoken";
|
||||||
import { IUser, IUserAuth } from "../schemas";
|
import { IUser, IUserAuth } from "../schemas";
|
||||||
import AuthService from "../auth";
|
import AuthService from "../auth";
|
||||||
import { UserCtl } from "../controllers";
|
import { UserCtl } from "../controllers";
|
||||||
@@ -12,18 +13,9 @@ const UserInstance = new UserCtl();
|
|||||||
|
|
||||||
const router = Router();
|
const router = Router();
|
||||||
|
|
||||||
export const authRoute = (app: Express, passport: PassportStatic) => {
|
export const authRoute = (app: Express) => {
|
||||||
app.use('/auth', router);
|
app.use('/auth', router);
|
||||||
|
|
||||||
// router.use((req, res, next) => {
|
|
||||||
// console.log(req.isAuthenticated());
|
|
||||||
// console.log(req.session.user);
|
|
||||||
// console.log(req.cookies);
|
|
||||||
// console.log();
|
|
||||||
|
|
||||||
// next();
|
|
||||||
// })
|
|
||||||
|
|
||||||
router.use((req, res, next) => {
|
router.use((req, res, next) => {
|
||||||
console.log(req.session);
|
console.log(req.session);
|
||||||
next();
|
next();
|
||||||
@@ -49,7 +41,7 @@ export const authRoute = (app: Express, passport: PassportStatic) => {
|
|||||||
res.status(200).send({ message: "Cool restricted content!" });
|
res.status(200).send({ message: "Cool restricted content!" });
|
||||||
})
|
})
|
||||||
|
|
||||||
router.post('/login', passport.authenticate('local'), async (req, res, next) => {
|
router.post('/login', async (req, res, next) => {
|
||||||
try {
|
try {
|
||||||
const data: IUserAuth = req.body;
|
const data: IUserAuth = req.body;
|
||||||
console.log(data);
|
console.log(data);
|
||||||
@@ -59,19 +51,27 @@ export const authRoute = (app: Express, passport: PassportStatic) => {
|
|||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
const user = response.data as IUser;
|
const user = response.data as IUser;
|
||||||
|
|
||||||
req.session.regenerate((err) => {
|
req.user = user;
|
||||||
if (err) next(err);
|
req.session.user = user;
|
||||||
req.session.user = user;
|
|
||||||
|
|
||||||
req.session.save((err) => {
|
const safeUserData = {
|
||||||
if (err) return next(err);
|
id: user.id,
|
||||||
})
|
handle: user.handle,
|
||||||
|
email: user.email,
|
||||||
|
datecreated: user.datecreated,
|
||||||
|
datemodified: user.datemodified
|
||||||
|
}
|
||||||
|
|
||||||
|
const token = jwt.sign({ user: safeUserData }, process.env.SESSIONSECRET as string);
|
||||||
|
|
||||||
|
req.session.save((err) => {
|
||||||
|
return next(err);
|
||||||
})
|
})
|
||||||
|
|
||||||
res.cookie('userid', user.id, { maxAge: 1000 * 60 * 60 * 24 });
|
console.log(req.session);
|
||||||
|
|
||||||
res.send(response);
|
res.cookie('token', token, { httpOnly: true });
|
||||||
res.end();
|
res.json({ token });
|
||||||
} else {
|
} else {
|
||||||
res.status(401).send({ message: "Login unsuccessful" });
|
res.status(401).send({ message: "Login unsuccessful" });
|
||||||
}
|
}
|
||||||
@@ -82,10 +82,11 @@ export const authRoute = (app: Express, passport: PassportStatic) => {
|
|||||||
|
|
||||||
router.post('/register', async (req, res, next) => {
|
router.post('/register', async (req, res, next) => {
|
||||||
try {
|
try {
|
||||||
const data = req.body;
|
const data: IUser = req.body;
|
||||||
const response = await AuthInstance.register(data);
|
const response = await AuthInstance.register(data);
|
||||||
if (!response) res.status(400).send({ ok: false });
|
response.represent();
|
||||||
res.status(200).send({ ok: true });
|
|
||||||
|
res.status(response.code).send({ ok: response.ok, message: response.data });
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
next(e);
|
next(e);
|
||||||
}
|
}
|
||||||
@@ -93,11 +94,9 @@ export const authRoute = (app: Express, passport: PassportStatic) => {
|
|||||||
|
|
||||||
router.delete('/logout', async (req, res, next) => {
|
router.delete('/logout', async (req, res, next) => {
|
||||||
try {
|
try {
|
||||||
req.session.destroy((err) => {
|
res.clearCookie('connect.sid').clearCookie('token');
|
||||||
if (err) throw err;
|
res.status(204).send("logout successful");
|
||||||
})
|
res.end();
|
||||||
res.clearCookie('userid');
|
|
||||||
res.status(204).send({ ok: true });
|
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
next(e);
|
next(e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
import { Express, Router } from "express";
|
import { Express, Router } from "express";
|
||||||
import { restrictAccess } from "../auth/middlewares";
|
import { checkIsAdmin, restrictAccess } from "../auth/middlewares";
|
||||||
import CollectionCtl from "../controllers/CollectionCtl";
|
import CollectionCtl from "../controllers/CollectionCtl";
|
||||||
const CollectionInstance = new CollectionCtl();
|
const CollectionInstance = new CollectionCtl();
|
||||||
|
|
||||||
const router = Router();
|
const router = Router();
|
||||||
|
|
||||||
export const collectionRoute = (app: Express) => {
|
export const collectionRoute = (app: Express) => {
|
||||||
app.use('/collection', router);
|
app.use('/app/collection', router);
|
||||||
|
|
||||||
router.get('/:id', restrictAccess, async (req, res, next) => {
|
router.get('/:id', async (req, res, next) => {
|
||||||
const { id } = req.params;
|
const { id } = req.params;
|
||||||
try {
|
try {
|
||||||
const { code, data } = await CollectionInstance.getOne(id);
|
const { code, data } = await CollectionInstance.getOne(id);
|
||||||
@@ -19,7 +19,7 @@ export const collectionRoute = (app: Express) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// implement is admin on this route
|
// implement is admin on this route
|
||||||
router.get('/', restrictAccess, async (req, res, next) => {
|
router.get('/', checkIsAdmin, async (req, res, next) => {
|
||||||
try {
|
try {
|
||||||
const { code, data } = await CollectionInstance.getAll();
|
const { code, data } = await CollectionInstance.getAll();
|
||||||
res.status(code).send(data);
|
res.status(code).send(data);
|
||||||
@@ -28,7 +28,7 @@ export const collectionRoute = (app: Express) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
router.post('/', restrictAccess, async (req, res, next) => {
|
router.post('/', async (req, res, next) => {
|
||||||
const data = req.body;
|
const data = req.body;
|
||||||
console.log(data);
|
console.log(data);
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ const CourseInstance = new CourseCtl();
|
|||||||
const router = Router();
|
const router = Router();
|
||||||
|
|
||||||
export const courseRouter = (app: Express) => {
|
export const courseRouter = (app: Express) => {
|
||||||
app.use('/course', router);
|
app.use('/app/course', router);
|
||||||
|
|
||||||
router.get('/', async (req, res, next) => {
|
router.get('/', async (req, res, next) => {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ const UserInstance = new UserCtl();
|
|||||||
const router = Router();
|
const router = Router();
|
||||||
|
|
||||||
export const friendRouter = (app: Express) => {
|
export const friendRouter = (app: Express) => {
|
||||||
app.use('/friend', router);
|
app.use('/app/friend', router);
|
||||||
|
|
||||||
router.use((req, res, next) => {
|
router.use((req, res, next) => {
|
||||||
let test = req.session.user;
|
let test = req.session.user;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ const groceryinstance = new GroceryListCtl();
|
|||||||
const router = Router();
|
const router = Router();
|
||||||
|
|
||||||
export const groceryListRoute = (app: Express) => {
|
export const groceryListRoute = (app: Express) => {
|
||||||
app.use('/grocery-list', router);
|
app.use('/app/grocery-list', router);
|
||||||
|
|
||||||
router.get('/', async (req, res, next) => {
|
router.get('/', async (req, res, next) => {
|
||||||
const userid = req.query.userid as string;
|
const userid = req.query.userid as string;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
|
import jwt from "jsonwebtoken";
|
||||||
|
import dotenv from 'dotenv';
|
||||||
import { Express } from "express"
|
import { Express } from "express"
|
||||||
import { PassportStatic } from "passport";
|
|
||||||
import { userRoute } from "./users";
|
import { userRoute } from "./users";
|
||||||
import { recipeRoute } from "./recipe";
|
import { recipeRoute } from "./recipe";
|
||||||
import { collectionRoute } from "./collection";
|
import { collectionRoute } from "./collection";
|
||||||
@@ -11,14 +12,38 @@ import { friendRouter } from "./friend";
|
|||||||
import { cuisineRouter } from "./cuisine";
|
import { cuisineRouter } from "./cuisine";
|
||||||
import { courseRouter } from "./course";
|
import { courseRouter } from "./course";
|
||||||
|
|
||||||
export const routes = async (app: Express, passport: PassportStatic) => {
|
dotenv.config();
|
||||||
|
|
||||||
|
export const routes = async (app: Express) => {
|
||||||
|
// unprotected routes
|
||||||
|
authRoute(app);
|
||||||
|
|
||||||
|
// middleware to check for auth on cookies on each request in protected routes
|
||||||
|
app.use('/app', async (req, res, next) => {
|
||||||
|
// pull jwt from request headers
|
||||||
|
const token = req.headers['authorization']?.split(" ")[1];
|
||||||
|
console.log(token);
|
||||||
|
|
||||||
|
if (!token) {
|
||||||
|
res.status(403).send("Unauthorized");
|
||||||
|
} else {
|
||||||
|
jwt.verify(token, process.env.SESSIONSECRET as string, (err, data) => {
|
||||||
|
if (err) {
|
||||||
|
res.status(403).send(err);
|
||||||
|
} else {
|
||||||
|
console.log(data);
|
||||||
|
req.user = data;
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// protected routes
|
||||||
userRoute(app);
|
userRoute(app);
|
||||||
friendRouter(app);
|
friendRouter(app);
|
||||||
recipeRoute(app);
|
recipeRoute(app);
|
||||||
ingredientRoute(app);
|
ingredientRoute(app);
|
||||||
|
|
||||||
// to do: refactor for ctlresponse
|
|
||||||
authRoute(app, passport);
|
|
||||||
collectionRoute(app);
|
collectionRoute(app);
|
||||||
subscriptionRoute(app);
|
subscriptionRoute(app);
|
||||||
groceryListRoute(app);
|
groceryListRoute(app);
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ const IngredientInstance = new IngredientCtl();
|
|||||||
const router = Router();
|
const router = Router();
|
||||||
|
|
||||||
export const ingredientRoute = (app: Express) => {
|
export const ingredientRoute = (app: Express) => {
|
||||||
app.use('/ingredient', router);
|
app.use('/app/ingredient', router);
|
||||||
|
|
||||||
router.get('/', async (req, res, next) => {
|
router.get('/', async (req, res, next) => {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ const recipectl = new RecipeCtl();
|
|||||||
const router = Router();
|
const router = Router();
|
||||||
|
|
||||||
export const recipeRoute = (app: Express) => {
|
export const recipeRoute = (app: Express) => {
|
||||||
app.use('/recipe', router);
|
app.use('/app/recipe', router);
|
||||||
|
|
||||||
router.get('/:id', async (req, res, next) => {
|
router.get('/:id', async (req, res, next) => {
|
||||||
const { id } = req.params;
|
const { id } = req.params;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ const CollectionInstance = new CollectionCtl();
|
|||||||
const router = Router();
|
const router = Router();
|
||||||
|
|
||||||
export const subscriptionRoute = (app: Express) => {
|
export const subscriptionRoute = (app: Express) => {
|
||||||
app.use('/subscription', router);
|
app.use('/app/subscription', router);
|
||||||
|
|
||||||
router.get('/', async (req, res, next) => {
|
router.get('/', async (req, res, next) => {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ const router = Router();
|
|||||||
const userCtl = new UserCtl();
|
const userCtl = new UserCtl();
|
||||||
|
|
||||||
export const userRoute = (app: Express) => {
|
export const userRoute = (app: Express) => {
|
||||||
app.use('/users', router);
|
app.use('/app/users', router);
|
||||||
|
|
||||||
// get all users
|
// get all users
|
||||||
router.get('/', async (req, res) => {
|
router.get('/', async (req, res) => {
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export interface IUser extends HasHistory, CanDeactivate {
|
|||||||
handle: string
|
handle: string
|
||||||
email: string
|
email: string
|
||||||
isadmin: boolean
|
isadmin: boolean
|
||||||
password?: string
|
password: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IUserAuth {
|
export interface IUserAuth {
|
||||||
|
|||||||
@@ -8,10 +8,14 @@ export default class ControllerResponse<T> implements CtlResponse<T> {
|
|||||||
constructor(code: StatusCode, data: T | string, ok?: boolean) {
|
constructor(code: StatusCode, data: T | string, ok?: boolean) {
|
||||||
this.code = code
|
this.code = code
|
||||||
this.data = data
|
this.data = data
|
||||||
this.ok = ok || (this.data !== null)
|
this.ok = ok ?? (this.data !== null)
|
||||||
}
|
}
|
||||||
|
|
||||||
send() {
|
send() {
|
||||||
return { ok: this.ok, code: this.code, data: this.data }
|
return { ok: this.ok, code: this.code, data: this.data }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
represent() {
|
||||||
|
console.log({ ok: this.ok, code: this.code, data: this.data });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
#! /bin/bash
|
#! /bin/bash
|
||||||
|
|
||||||
rm -rf dist && mkdir -p dist && cp ./swagger.yaml ./dist && ./node_modules/.bin/tsc --project ./tsconfig.json --watch & ts-node-dev index.ts
|
rm -rf dist && mkdir -p dist && cp ./swagger.yaml ./dist && ./node_modules/.bin/tsc --project ./tsconfig.json --watch & ts-node --files index.ts
|
||||||
|
|||||||
@@ -13,5 +13,6 @@ export enum StatusCode {
|
|||||||
Unauthorized = 401,
|
Unauthorized = 401,
|
||||||
Forbidden = 403,
|
Forbidden = 403,
|
||||||
NotFound = 404,
|
NotFound = 404,
|
||||||
|
Conflict = 409,
|
||||||
ServerError = 500
|
ServerError = 500
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user