forked from b00tc4mp/isdi-parttime-202309
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add authenticate logic, handler and tests; update index with that cha…
…nges b00tc4mp#407
- Loading branch information
berlem
authored and
berlem
committed
Feb 22, 2024
1 parent
ef6a196
commit a308169
Showing
8 changed files
with
254 additions
and
3 deletions.
There are no files selected for viewing
37 changes: 37 additions & 0 deletions
37
staff/belen-ivars/project/api/handlers/authenticateUserHandler.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import jwt from 'jsonwebtoken' | ||
import logic from '../logic/index.js' | ||
import { errors } from 'com' | ||
|
||
const { ContentError, TokenError, CredentialsError, NotFoundError } = errors | ||
|
||
export default (req, res) => { | ||
const { email, password } = req.body | ||
|
||
try { | ||
logic.authenticateUser(email, password) | ||
|
||
.then(userId => { | ||
const token = jwt.sign({ sub: userId }, process.env.JWT_SECRET, { expiresIn: process.env.JWT_EXP }) | ||
|
||
res.json(token) | ||
}) | ||
.catch(error => { | ||
|
||
let status = 500 | ||
if (error instanceof NotFoundError) | ||
status = 404 | ||
|
||
else if (error instanceof CredentialsError) | ||
status = 401 | ||
|
||
res.status(status).json({ error: error.constructor.name, message: error.message }) | ||
}) | ||
|
||
} catch (error) { | ||
let status = 500 | ||
if (error instanceof ContentError || error instanceof TypeError) | ||
|
||
status = 406 | ||
res.status(status).json({ error: error.constructor.name, message: error.message }) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,7 @@ | ||
import registerUserHandler from './registerUserHandler.js' | ||
import authenticateUserHandler from './authenticateUserHandler.js' | ||
|
||
export { | ||
registerUserHandler | ||
registerUserHandler, | ||
authenticateUserHandler | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import bcrypt from 'bcryptjs' | ||
import { validate, errors } from 'com' | ||
import { User } from '../data/models.js' | ||
|
||
const { SystemError, CredentialsError, NotFoundError } = errors | ||
|
||
function authenticateUser(email, password) { | ||
validate.email(email, 'email') | ||
validate.password(password, 'password') | ||
|
||
return (async () => { | ||
|
||
let user | ||
try { | ||
user = await User.findOne({ email }) | ||
} catch (error) { | ||
|
||
throw new SystemError(error.message) | ||
} | ||
|
||
if (!user) | ||
throw new NotFoundError('user not found') | ||
|
||
let match | ||
try { | ||
match = await bcrypt.compare(password, user.password) | ||
} catch (error) { | ||
throw new SystemError(error.message) | ||
} | ||
|
||
if (!match) | ||
throw new CredentialsError('wrong password') | ||
|
||
return user.id | ||
|
||
})() | ||
} | ||
|
||
export default authenticateUser |
66 changes: 66 additions & 0 deletions
66
staff/belen-ivars/project/api/logic/authenticateUser.spec.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import dotenv from 'dotenv' | ||
dotenv.config() | ||
|
||
import mongoose, { mongo } from 'mongoose' | ||
|
||
import { expect } from 'chai' | ||
import bcrypt from 'bcryptjs' | ||
import random from './helpers/random.js' | ||
import authenticateUser from './authenticateUser.js' | ||
import { errors } from 'com' | ||
import { User } from '../data/models.js' | ||
|
||
const { NotFoundError, CredentialsError } = errors | ||
|
||
describe('authenticateUser', () => { | ||
before(async () => await mongoose.connect(process.env.TEST_MONGODB_URL)) | ||
beforeEach(async () => await User.deleteMany()) | ||
|
||
it('succeds on correct credentials', async () => { | ||
const name = random.name() | ||
const email = random.email() | ||
const password = random.password() | ||
|
||
const hash = await bcrypt.hash(password, 8) | ||
const user = await User.create({ name, email, password: hash }) | ||
|
||
const userId = await authenticateUser(email, password) | ||
|
||
|
||
expect(userId).to.be.a('string') | ||
expect(userId).to.have.lengthOf(24) | ||
expect(userId).to.equal(user.id) | ||
|
||
}) | ||
|
||
it('fails on wrong email', async () => { | ||
const email = random.email() | ||
const password = random.password() | ||
|
||
try { | ||
await authenticateUser(email, password) | ||
throw new Error('should not reach this point') | ||
} catch (error) { | ||
expect(error).to.be.instanceOf(NotFoundError) | ||
expect(error.message).to.equal('user not found') | ||
} | ||
}) | ||
|
||
it('fails on wrong password', async () => { | ||
const name = random.name() | ||
const email = random.email() | ||
const password = random.password() | ||
|
||
const user = await User.create({ name, email, password }) | ||
|
||
try { | ||
await authenticateUser(email, password + 'wrong') | ||
throw new Error('should not reach this point') | ||
} catch (error) { | ||
expect(error).to.be.instanceOf(CredentialsError) | ||
expect(error.message).to.equal('wrong password') | ||
} | ||
}) | ||
|
||
after(async () => await mongoose.disconnect()) | ||
}) |
15 changes: 15 additions & 0 deletions
15
staff/belen-ivars/project/api/logic/authenticateUser.test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import dotenv from 'dotenv' | ||
dotenv.config() | ||
import mongoose from 'mongoose' | ||
|
||
import authenticateUser from './authenticateUser.js' | ||
|
||
(async () => { | ||
await mongoose.connect(process.env.MONGODB_URL) | ||
try { | ||
await authenticateUser('[email protected]', '123123123') | ||
console.log('user authenticated') | ||
} catch (error) { | ||
console.log(error) | ||
} | ||
})() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,9 @@ | ||
import registerUser from './registerUser.js' | ||
import authenticateUser from './authenticateUser.js' | ||
|
||
const logic = { | ||
registerUser | ||
registerUser, | ||
authenticateUser | ||
} | ||
|
||
export default logic |
86 changes: 86 additions & 0 deletions
86
staff/belen-ivars/project/api/test/authenticate-user.test.sh
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
source pepetest.sh | ||
|
||
TEST 'authenticate-user' | ||
|
||
CASE 'success on correct credentials' | ||
|
||
curl 'http://localhost:9000/users/auth' \ | ||
-H 'Content-Type: application/json' \ | ||
-d '{"email": "[email protected]", "password": "123123123"}' \ | ||
-v | ||
|
||
# > POST /users/auth HTTP/1.1 | ||
# > Host: localhost:9000 | ||
# > User-Agent: curl/8.4.0 | ||
# > Accept: */* | ||
# > Content-Type: application/json | ||
# > Content-Length: 51 | ||
# > | ||
# < HTTP/1.1 200 OK | ||
# < X-Powered-By: Express | ||
# < Access-Control-Allow-Origin: * | ||
# < Content-Type: application/json; charset=utf-8 | ||
# < Content-Length: 174 | ||
# < ETag: W/"ae-xoMjJkMAcoU50Y0NdIBS6tqorMI" | ||
# < Date: Thu, 22 Feb 2024 17:37:25 GMT | ||
# < Connection: keep-alive | ||
# < Keep-Alive: timeout=5 | ||
# < | ||
# * Connection #0 to host localhost left intact | ||
# "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI2NWQ2NTZlYWE5MmU4NWM5ZjlmYTZkNzEiLCJpYXQiOjE3MDg2MjM0NDUsImV4cCI6MTcwODYyNzA0NX0.k6C_Yv259KFl4Mx0QyPcuuW3FfwrM6scbbJ_VxLk65s" | ||
|
||
CASE "fail on wrong email" | ||
|
||
curl 'http://localhost:9000/users/auth' \ | ||
-H 'Content-Type: application/json' \ | ||
-d '{ "email": "[email protected]", "password": "123123123" | ||
}' \ | ||
-v | ||
|
||
# > POST /users/auth HTTP/1.1 | ||
# > Host: localhost:9000 | ||
# > User-Agent: curl/8.4.0 | ||
# > Accept: */* | ||
# > Content-Type: application/json | ||
# > Content-Length: 77 | ||
# > | ||
# < HTTP/1.1 404 Not Found | ||
# < X-Powered-By: Express | ||
# < Access-Control-Allow-Origin: * | ||
# < Content-Type: application/json; charset=utf-8 | ||
# < Content-Length: 52 | ||
# < ETag: W/"34-Cs2INrsYwSHLSHCKVUFPEWh9NjI" | ||
# < Date: Thu, 22 Feb 2024 17:37:25 GMT | ||
# < Connection: keep-alive | ||
# < Keep-Alive: timeout=5 | ||
# < | ||
# * Connection #0 to host localhost left intact | ||
# {"error":"NotFoundError","message":"user not found"} | ||
|
||
CASE "fail on wrong password" | ||
|
||
curl 'http://localhost:9000/users/auth' \ | ||
-H 'Content-Type: application/json' \ | ||
-d '{ "email": "[email protected]", "password": "123123124" | ||
}' \ | ||
-v | ||
|
||
# > POST /users/auth HTTP/1.1 | ||
# > Host: localhost:9000 | ||
# > User-Agent: curl/8.4.0 | ||
# > Accept: */* | ||
# > Content-Type: application/json | ||
# > Content-Length: 54 | ||
# > | ||
# < HTTP/1.1 401 Unauthorized | ||
# < X-Powered-By: Express | ||
# < Access-Control-Allow-Origin: * | ||
# < Content-Type: application/json; charset=utf-8 | ||
# < Content-Length: 55 | ||
# < ETag: W/"37-3mBc0WtcQO2Ze4UXSt4AJH7BRe8" | ||
# < Date: Thu, 22 Feb 2024 17:49:59 GMT | ||
# < Connection: keep-alive | ||
# < Keep-Alive: timeout=5 | ||
# < | ||
# * Connection #0 to host localhost left intact | ||
# {"error":"CredentialsError","message":"wrong password"}% |