Skip to content

Commit

Permalink
feat: get user based on their token
Browse files Browse the repository at this point in the history
  • Loading branch information
hariscs committed Mar 2, 2024
1 parent 6e9d219 commit 4747cae
Show file tree
Hide file tree
Showing 7 changed files with 143 additions and 12 deletions.
2 changes: 2 additions & 0 deletions apps/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"@repo/logger": "*",
"bcrypt": "^5.1.1",
"body-parser": "^1.20.2",
"cookie-parser": "^1.4.6",
"cors": "^2.8.5",
"express": "^4.18.2",
"jsonwebtoken": "^9.0.2",
Expand All @@ -31,6 +32,7 @@
"@repo/typescript-config": "*",
"@types/bcrypt": "^5.0.2",
"@types/body-parser": "^1.19.5",
"@types/cookie-parser": "^1.4.7",
"@types/cors": "^2.8.17",
"@types/express": "^4.17.21",
"@types/jest": "^29.5.11",
Expand Down
24 changes: 22 additions & 2 deletions apps/api/src/controllers/user_controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@ import { isValidObjectId } from 'mongoose'
import { log } from 'console'
import { generate_token } from 'utils/generate_token'

//* @desc Post user
//* @desc Register user
//* route POST /api/user
//? @access Public
export async function create_user(req: Request, res: Response): Promise<void> {
export async function register_user(
req: Request,
res: Response
): Promise<void> {
try {
const user_data = req.body
// check if user email already exists
Expand Down Expand Up @@ -98,3 +101,20 @@ export async function update_user(req: Request, res: Response): Promise<void> {
res.status(500).json({ error: 'Internal server error' })
}
}

//* @desc Get User
//* route GET /api/user/profile
//! @access Private
export async function get_user(req: Request, res: Response): Promise<void> {
try {
const user = {
name: req.user?.name,
email: req.user?.email,
_id: req.user?._id,
}
res.status(200).json(user)
} catch (error) {
log('Error fetching user:', error)
res.status(500).json({ error: 'Internal server error' })
}
}
41 changes: 41 additions & 0 deletions apps/api/src/middleware/auth_middleware.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { Request as ExpressRequest, Response, NextFunction } from 'express'
import jwt, { JwtPayload } from 'jsonwebtoken'
import { USER_SCHEMA } from '@/models/user_model'
import { log } from 'console'

interface User {
name?: string
email: string
password: string
}

interface Request extends ExpressRequest {
user?: User
}

export async function protect_route(
req: Request,
res: Response,
next: NextFunction
) {
try {
const token = req.cookies.token
if (!token) {
res.status(401).json({ error: 'Unauthorized' })
return
}
const secret = process.env.JWT_SECRET
if (!secret) {
res.status(500).json({ error: 'JWT secret is undefined' })
return
}
const decoded = jwt.verify(token, secret) as JwtPayload
req.user = (await USER_SCHEMA.findById(decoded.user_id).select(
'-password'
)) as User

next()
} catch (error) {
res.status(500).json({ error: 'Internal server error' })
}
}
21 changes: 16 additions & 5 deletions apps/api/src/routes/user_route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,35 @@ import { USER_VALIDATION_SCHEMA } from '@/validations/user_validation'
import {
login_user,
logout_user,
create_user,
register_user,
update_user,
get_user,
} from '@/controllers/user_controller'
import { protect_route } from '@/middleware/auth_middleware'

//* @desc Post user
//* @desc Create user
//? @access Public
router.post('/', validate_schema(USER_VALIDATION_SCHEMA), create_user)
router.post('/', validate_schema(USER_VALIDATION_SCHEMA), register_user)

//* @desc Login user
//? @access Public
router.get('/', validate_schema(USER_VALIDATION_SCHEMA), login_user)
router.get('/login', validate_schema(USER_VALIDATION_SCHEMA), login_user)

//* @desc Logout user
//? @access Public
router.post('/logout', logout_user)

//* @desc Get User
//! @access Private
router.get('/profile', protect_route, get_user)

//* @desc Update user
//! @access Private
router.patch('/:id', validate_schema(USER_VALIDATION_SCHEMA), update_user)
router.patch(
'/:id',
protect_route,
validate_schema(USER_VALIDATION_SCHEMA),
update_user
)

export default router
2 changes: 2 additions & 0 deletions apps/api/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import express, { type Express } from 'express'
import morgan from 'morgan'
import cors from 'cors'
import { config } from 'dotenv'
import cookieParser from 'cookie-parser'

config()

Expand All @@ -14,6 +15,7 @@ export const createServer = (): Express => {
.use(urlencoded({ extended: true }))
.use(json())
.use(cors())
.use(cookieParser())
.get('/health', (_, res) => {
return res.json({ ok: true })
})
Expand Down
24 changes: 24 additions & 0 deletions apps/api/src/types/express/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
export {}

declare global {
namespace Express {
export interface Request {
job?: {
id: string
title: string
description: string
company: string
location: string
salary: number
created_at: string
updated_at: string
}
user?: {
_id?: string
name?: string
email: string
password: string
}
}
}
}
41 changes: 36 additions & 5 deletions package-lock.json

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

0 comments on commit 4747cae

Please sign in to comment.