Skip to content

Commit b31e485

Browse files
committed
feat: login working and cookie being set
1 parent b4b900b commit b31e485

File tree

7 files changed

+233
-30
lines changed

7 files changed

+233
-30
lines changed

.github/workflows/ci.yml

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
name: CI Monorepo
2+
3+
on:
4+
push:
5+
branches: [develop, master]
6+
pull_request:
7+
branches: [develop, master]
8+
9+
jobs:
10+
test-client:
11+
name: Test Client
12+
runs-on: ubuntu-latest
13+
defaults:
14+
run:
15+
working-directory: ./client
16+
17+
steps:
18+
- name: Checkout repository
19+
uses: actions/checkout@v3
20+
21+
- name: Setup Node.js
22+
uses: actions/setup-node@v3
23+
with:
24+
node-version: 18
25+
26+
- name: Install dependencies
27+
run: npm install
28+
29+
- name: Run client tests
30+
run: npm test
31+
32+
test-server:
33+
name: Test Server
34+
runs-on: ubuntu-latest
35+
defaults:
36+
run:
37+
working-directory: ./server
38+
39+
steps:
40+
- name: Checkout repository
41+
uses: actions/checkout@v3
42+
43+
- name: Setup Node.js
44+
uses: actions/setup-node@v3
45+
with:
46+
node-version: 18
47+
48+
- name: Install dependencies
49+
run: npm install
50+
51+
- name: Run server tests
52+
run: npm test

package-lock.json

Lines changed: 130 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

server/package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,16 @@
1414
"bcrypt": "^6.0.0",
1515
"cors": "^2.8.5",
1616
"express": "^5.1.0",
17+
"jsonwebtoken": "^9.0.2",
18+
"memory-cache": "^0.2.0",
1719
"zod": "^4.0.13"
1820
},
1921
"devDependencies": {
2022
"@types/bcrypt": "^6.0.0",
2123
"@types/cors": "^2.8.19",
2224
"@types/express": "^5.0.3",
25+
"@types/jsonwebtoken": "^9.0.10",
26+
"@types/memory-cache": "^0.2.6",
2327
"@types/node": "^24.1.0",
2428
"jest": "^30.0.5",
2529
"prisma": "^6.12.0",

server/src/repositories/UserRepository.ts

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
11
import prisma from "../db/connect";
2-
import bcrypt from "bcrypt"
32
import { CreateUserDTO, LoginUser, PublicUserDTO } from "../db/models/UsersModel";
43

54
export class UserRepository {
65
async create(user: Omit<CreateUserDTO, "idUser">): Promise<PublicUserDTO> {
7-
const createdUser = await prisma.users.create({
6+
return this.toPublicDTO(await prisma.users.create({
87
data: user
9-
});
10-
return this.toPublicDTO(createdUser)
11-
8+
}));
129
}
1310

1411
async findByEmail(email: string): Promise<PublicUserDTO | null> {
@@ -17,17 +14,10 @@ export class UserRepository {
1714
})
1815
}
1916

20-
async loginUser(email: string, password: string): Promise<LoginUser | null> {
21-
const user = await prisma.users.findUnique({
17+
async loginUser(email: string,): Promise<CreateUserDTO | null> {
18+
return await prisma.users.findUnique({
2219
where: { email: email }
2320
})
24-
25-
if (user) {
26-
if (await bcrypt.compare(password, user.password)) {
27-
return { name: user.name, email: user.email }
28-
}
29-
}
30-
return null
3121
}
3222

3323
private toPublicDTO(user: CreateUserDTO): PublicUserDTO {

server/src/routes/UserRoutes.ts

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@ import express, { Request, Response } from "express"
22
import { UserService } from "../services/UserService"
33
import { UserRepository } from "../repositories/UserRepository"
44
import { validateLogin, validateUser } from "../../utils/validateUser"
5-
import { CustomError, InvalidRequest } from "../errors/HttpError"
5+
import { InvalidRequest } from "../errors/HttpError"
6+
import { JWTClass } from "../../utils/jwt"
67

78
const router = express.Router()
8-
const service = new UserService(new UserRepository())
9+
const service = new UserService(new UserRepository(), new JWTClass(process.env.JWT_TOKEN!))
910

1011
router.post("/user", async (req: Request, res: Response) => {
1112
const { email, name, password } = req.body
@@ -35,20 +36,24 @@ router.post('/auth/login', async (req: Request, res: Response) => {
3536
const validLogin = validateLogin({ email, password })
3637

3738
if (validLogin.error) {
38-
return new InvalidRequest("Invalid login.", 400, "INVALID_LOGIN", validLogin.error.issues.map(err => ({
39+
throw new InvalidRequest("Invalid login.", 400, "INVALID_LOGIN", validLogin.error.issues.map(err => ({
3940
fields: err.path.join('.'),
4041
message: err.message
4142
})))
4243
}
43-
const login = await service.loginUser(email, password)
44-
45-
if (login) {
46-
return res.status(200).json({
44+
const token = await service.loginUser(email, password)
45+
46+
return res.
47+
cookie('token', token, {
48+
httpOnly: true,
49+
sameSite: "strict",
50+
path: "/",
51+
secure: true
52+
}).status(200).json({
4753
message: "User logged in successfully.",
48-
token: "TOKEN"
54+
code: "USER_LOGGED"
4955
})
50-
}
51-
throw new CustomError("Incorrect email or password.", 401, "INCORRECT_LOGIN")
56+
5257
})
5358

5459
export default router

server/src/services/UserService.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,21 @@ import { CreateUserDTO } from "../db/models/UsersModel";
22
import { CustomError } from "../errors/HttpError";
33
import { UserRepository } from "../repositories/UserRepository";
44
import hashPassword from "../../utils/hashPassword"
5+
import bcrypt from "bcrypt"
6+
import { JWTClass } from "../../utils/jwt"
57

68

79
export class UserService {
8-
constructor(private repository: UserRepository) { }
10+
constructor(
11+
private repository: UserRepository,
12+
private jwtHandler: JWTClass
13+
) { }
914

1015
async createUser(user: Omit<CreateUserDTO, "idUser">) {
1116
const existing = await this.repository.findByEmail(user.email)
1217

1318
if (existing) {
14-
return new CustomError("Email already used.", 400, "REPEATED_EMAIL")
19+
throw new CustomError("Email already used.", 400, "REPEATED_EMAIL")
1520
}
1621

1722
const newUser = await this.repository.create({
@@ -24,10 +29,11 @@ export class UserService {
2429
}
2530

2631
async loginUser(email: string, password: string) {
27-
const login = await this.repository.loginUser(email, password)
32+
const user = await this.repository.loginUser(email)
2833

29-
if (login) return login
30-
31-
return null
34+
if (!user || !(await bcrypt.compare(password, user.password))) {
35+
throw new CustomError("Incorrect email or password.", 401, "INCORRECT_LOGIN")
36+
}
37+
return this.jwtHandler.generateJWT({ email: user.email })
3238
}
3339
}

0 commit comments

Comments
 (0)