Skip to content

Commit

Permalink
feat: generate token and send it in a cookie
Browse files Browse the repository at this point in the history
  • Loading branch information
hariscs committed Feb 25, 2024
1 parent 3c9cbb0 commit ca247d0
Show file tree
Hide file tree
Showing 7 changed files with 517 additions and 25 deletions.
3 changes: 2 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
NODE_ENV=development
PORT=5000
MONGO_URI=YOUR_MONGO_URI
MONGO_URI=YOUR_MONGO_URI
JWT_SECRET=YOUR_JWT_SECRET
4 changes: 4 additions & 0 deletions apps/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@
},
"dependencies": {
"@repo/logger": "*",
"bcrypt": "^5.1.1",
"body-parser": "^1.20.2",
"cors": "^2.8.5",
"express": "^4.18.2",
"jsonwebtoken": "^9.0.2",
"mongoose": "^8.1.1",
"morgan": "^1.10.0",
"zod": "^3.22.4"
Expand All @@ -27,10 +29,12 @@
"@repo/eslint-config": "*",
"@repo/jest-presets": "*",
"@repo/typescript-config": "*",
"@types/bcrypt": "^5.0.2",
"@types/body-parser": "^1.19.5",
"@types/cors": "^2.8.17",
"@types/express": "^4.17.21",
"@types/jest": "^29.5.11",
"@types/jsonwebtoken": "^9.0.5",
"@types/morgan": "^1.9.9",
"@types/node": "^20.10.6",
"@types/supertest": "^6.0.2",
Expand Down
12 changes: 7 additions & 5 deletions apps/api/src/controllers/user_controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Request, Response } from 'express'
import { USER_SCHEMA } from '@/models/user_model'
import { isValidObjectId } from 'mongoose'
import { log } from 'console'
import { generate_token } from 'utils/generate_token'

//* @desc Post user
//* route POST /api/user
Expand All @@ -19,6 +20,7 @@ export async function post_user(req: Request, res: Response): Promise<void> {

//* post user
const user = await USER_SCHEMA.create(user_data)
generate_token(res, user._id.toString())
res.status(201).json(user)
} catch (error) {
log('Error posting user:', error)
Expand All @@ -28,19 +30,19 @@ export async function post_user(req: Request, res: Response): Promise<void> {

//* @desc Get user
//* route GET /api/user
//! @access Private
//! @access Public
export async function get_user(req: Request, res: Response): Promise<void> {
try {
//* get user by email and password
const { email, password } = req.body
const user = await USER_SCHEMA.findOne({ email, password })
const user = await USER_SCHEMA.findOne({ email })

//* check if user email or password is incorrect
if (!user || user.email !== email || user.password !== password) {
// check if user exists and password is correct
if (!user || !(await user.match_password(password))) {
res.status(401).json({ error: 'Incorrect email or password' })
return
}

generate_token(res, user._id.toString())
res.status(200).json(user)
} catch (error) {
log('Error fetching user:', error)
Expand Down
27 changes: 25 additions & 2 deletions apps/api/src/models/user_model.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
import mongoose, { Schema } from 'mongoose'
import mongoose, { Document, Schema } from 'mongoose'
import bcrypt from 'bcrypt'

interface IUserSchema extends Document {
email: string
password: string
name?: string
match_password: (password: string) => Promise<boolean>
}

const user_schema = new Schema(
{
Expand All @@ -11,4 +19,19 @@ const user_schema = new Schema(
}
)

export const USER_SCHEMA = mongoose.model('User', user_schema)
user_schema.pre('save', async function (next) {
const user = this
if (!user.isModified('password')) {
next()
return
}
const salt = await bcrypt.genSalt(10)
this.password = await bcrypt.hash(this.password, salt)
next()
})

user_schema.methods.match_password = async function (entered_password: string) {
return await bcrypt.compare(entered_password, this.password)
}

export const USER_SCHEMA = mongoose.model<IUserSchema>('User', user_schema)
2 changes: 1 addition & 1 deletion apps/api/src/routes/user_route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
router.post('/', validate_schema(USER_VALIDATION_SCHEMA), post_user)

//* @desc Get user
//! @access Private
//? @access Public
router.get('/', validate_schema(USER_VALIDATION_SCHEMA), get_user)

//* @desc Delete user
Expand Down
21 changes: 21 additions & 0 deletions apps/api/utils/generate_token.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import jwt from 'jsonwebtoken'
import { Response } from 'express'
import { log } from 'console'

export function generate_token(res: Response, user_id: string) {
const secret = process.env.JWT_SECRET

if (!secret) {
log('JWT_SECRET is not defined')
return
}
const token = jwt.sign({ user_id }, secret, {
expiresIn: '30m',
})
res.cookie('token', token, {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
sameSite: 'strict',
maxAge: 30 * 60 * 1000,
})
}
Loading

0 comments on commit ca247d0

Please sign in to comment.