reject posts route if token is invalid and send one on login
This commit is contained in:
parent
ece8da877a
commit
3261158588
|
|
@ -5,7 +5,7 @@ generator client {
|
|||
|
||||
datasource db {
|
||||
provider = "mysql"
|
||||
url = env("DATABASE_URL")
|
||||
url = env("DB_URL")
|
||||
referentialIntegrity = "prisma"
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { getUser } from '@/controller/UserController';
|
||||
import UserLoginModel from '@/models/UserLoginModel';
|
||||
import { comparePassword } from '@/controller/AuthController';
|
||||
import { comparePassword, genToken } from '@/controller/AuthController';
|
||||
import { Request, Response } from 'express';
|
||||
import { User } from '@prisma/client';
|
||||
|
||||
|
|
@ -15,7 +15,8 @@ const login = async (req: Request, res: Response) => {
|
|||
if (!isValid) {
|
||||
return res.status(401).send({ error: 'Invalid password' });
|
||||
}
|
||||
return res.status(200).send(user);
|
||||
const token = genToken(user.id);
|
||||
return res.status(200).send({ token, userId: user.id });
|
||||
} catch (error) {
|
||||
return res.status(500).send(error);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,37 @@
|
|||
import { Router } from 'express';
|
||||
import { NextFunction, Request, Response, Router } from 'express';
|
||||
import getPosts from './getPosts';
|
||||
import postPost from './newPost';
|
||||
import putPost from './editPost';
|
||||
import deletePost from './deletePost';
|
||||
import likePost from './likePost';
|
||||
import unlikePost from './unlikePost';
|
||||
import { verifyToken } from '@/controller/AuthController';
|
||||
import { Token } from '@/models/TokenModel';
|
||||
|
||||
const posts = Router();
|
||||
|
||||
const getToken = (req: Request): string | undefined => {
|
||||
const token: string | undefined = req.headers.authorization?.substring(7); // remove 'Bearer ' from token
|
||||
return token;
|
||||
};
|
||||
|
||||
const checkAuth = (req: Request, res: Response, next: NextFunction) => {
|
||||
const token = getToken(req);
|
||||
if (token === undefined) {
|
||||
return res.status(401).send('No token provided');
|
||||
}
|
||||
return verifyToken(token)
|
||||
.then((decodedToken: Token) => {
|
||||
req.userId = decodedToken.id;
|
||||
next();
|
||||
})
|
||||
.catch(() => {
|
||||
return res.status(401).send('Invalid token');
|
||||
});
|
||||
};
|
||||
|
||||
posts.use(checkAuth);
|
||||
|
||||
posts.get('/', getPosts);
|
||||
posts.post('/new', postPost);
|
||||
posts.put('/edit/:id', putPost);
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
import * as jwt from 'jsonwebtoken';
|
||||
import * as bcrypt from 'bcrypt';
|
||||
import * as dotenv from 'dotenv';
|
||||
import { promisify } from 'util';
|
||||
|
||||
dotenv.config();
|
||||
import { config } from '..';
|
||||
import { Token } from '@/models/TokenModel';
|
||||
|
||||
const saltRounds = 10;
|
||||
const hashPromise = promisify(bcrypt.hash);
|
||||
|
|
@ -16,4 +15,25 @@ const comparePassword = (password: string, hash: string) => {
|
|||
return bcrypt.compare(password, hash);
|
||||
};
|
||||
|
||||
export { hashPassword, comparePassword };
|
||||
const genToken = (id: number) => {
|
||||
return jwt.sign({ id }, config.JWT_SECRET, {
|
||||
expiresIn: config.JWT_EXPIRES_IN,
|
||||
});
|
||||
};
|
||||
|
||||
const verifyToken = (token: string): Promise<Token> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
jwt.verify(token, config.JWT_SECRET, (err?, decoded?: jwt.JwtPayload | string) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else if (decoded === undefined || typeof decoded === 'string' || decoded.id === undefined) {
|
||||
reject('Invalid token');
|
||||
} else {
|
||||
const decodedToken: Token = { id: decoded.id };
|
||||
resolve(decodedToken);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export { hashPassword, comparePassword, genToken, verifyToken };
|
||||
|
|
|
|||
13
src/index.ts
13
src/index.ts
|
|
@ -1,9 +1,15 @@
|
|||
import express, { urlencoded, json } from 'express';
|
||||
import cors from 'cors';
|
||||
import api from '@/api';
|
||||
import { config } from 'dotenv';
|
||||
import { config as envConfig } from 'dotenv';
|
||||
|
||||
config();
|
||||
envConfig();
|
||||
|
||||
interface Config {
|
||||
[key: string]: string;
|
||||
}
|
||||
|
||||
let config: Config = {};
|
||||
|
||||
const checkEnvVars = () => {
|
||||
const requiredEnvVars = ['PORT', 'DB_URL', 'JWT_SECRET', 'JWT_EXPIRES_IN'];
|
||||
|
|
@ -12,6 +18,8 @@ const checkEnvVars = () => {
|
|||
if (process.env[envVar] === undefined) {
|
||||
error = true;
|
||||
console.log(`${envVar} is undefined`);
|
||||
} else {
|
||||
config[envVar] = process.env[envVar] as string;
|
||||
}
|
||||
});
|
||||
if (error) {
|
||||
|
|
@ -20,6 +28,7 @@ const checkEnvVars = () => {
|
|||
};
|
||||
|
||||
checkEnvVars();
|
||||
export { config };
|
||||
|
||||
const port = process.env.PORT || 5000;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
type Token = {
|
||||
id: number;
|
||||
};
|
||||
|
||||
export { Token };
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
export {};
|
||||
|
||||
declare global {
|
||||
namespace Express {
|
||||
export interface Request {
|
||||
userId?: number;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,6 @@
|
|||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"target": "es2017",
|
||||
"module": "CommonJS",
|
||||
"lib": [
|
||||
"esnext"
|
||||
],
|
||||
|
|
@ -23,7 +22,10 @@
|
|||
"@@/*": [
|
||||
"./*"
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeRoots": [
|
||||
"src/types"
|
||||
],
|
||||
},
|
||||
"ts-node": {
|
||||
"require": [
|
||||
|
|
|
|||
Loading…
Reference in New Issue