diff --git a/src/http_tests/authentication.test.ts b/src/http_tests/authentication.test.ts index 986a5fc..a0bbacd 100644 --- a/src/http_tests/authentication.test.ts +++ b/src/http_tests/authentication.test.ts @@ -46,4 +46,17 @@ describe('Authentication JWT', () => { expect(res.statusCode).toEqual(200); expect(userBody).toHaveProperty('email', testUser.email); }); + + it('should reject request with invalid token', async () => { + const invalidToken = 'this.is.an.invalid.token'; + + const res: Response = await request(app) + .get('/auth/me') + .set('Authorization', `Bearer ${invalidToken}`) + .expect(401); + + const body = res.body as AuthResponse; + expect(body).toHaveProperty('message'); + expect(typeof body.message).toBe('string'); + }); }); diff --git a/src/midleware/authMiddleware.ts b/src/midleware/authMiddleware.ts new file mode 100644 index 0000000..99386b4 --- /dev/null +++ b/src/midleware/authMiddleware.ts @@ -0,0 +1,31 @@ +import { NextFunction, Request, Response } from 'express'; +import jwt from 'jsonwebtoken'; + +const JWT_SECRET = process.env.JWT_SECRET; + +if (!JWT_SECRET) { + throw new Error('JWT_SECRET is not defined'); +} + +// Extend the Request interface to include the user payload from the token + +const authMiddleware = (req: Request, res: Response, next: NextFunction): void => { + const authHeader = req.headers.authorization; + const token = authHeader?.split(' ')[1]; + + if (!token) { + res.status(401).json({ message: 'No token provided' }); + return; + } + + jwt.verify(token, JWT_SECRET, err => { + if (err) { + res.status(401).json({ message: 'Invalid or expired token' }); + return; + } + + next(); + }); +}; + +export default authMiddleware; diff --git a/src/routes/authRoute.ts b/src/routes/authRoute.ts index 917e946..f006429 100644 --- a/src/routes/authRoute.ts +++ b/src/routes/authRoute.ts @@ -4,6 +4,7 @@ import jwt from 'jsonwebtoken'; import { ObjectId } from 'mongodb'; import { getDatabase } from '../database/mongo-common'; +import authMiddleware from '../midleware/authMiddleware'; const router: Router = Router(); const JWT_SECRET = process.env.JWT_SECRET; @@ -80,7 +81,7 @@ router.post('/login', async (req: Request, res: Response): Promise => { }); // responds with user data -router.get('/me', async (req: Request, res: Response): Promise => { +router.get('/me', authMiddleware, async (req: Request, res: Response): Promise => { const token = req.headers.authorization?.split(' ')[1]; if (!token) { diff --git a/src/utils/git-user-name.ts b/src/utils/git-user-name.ts index 85e7a7a..a9b9247 100644 --- a/src/utils/git-user-name.ts +++ b/src/utils/git-user-name.ts @@ -3,7 +3,7 @@ import { execSync } from 'child_process'; function getGitUserName(): string { if (process.env.GITHUB_ACTIONS === 'true') { const githubActor = process.env.GITHUB_ACTOR; - return githubActor || 'github-actions'; + return githubActor ?? 'github-actions'; } else { try { const name = execSync('git config --get user.name', { encoding: 'utf8' }).trim();