Skip to content

Commit 593765b

Browse files
committed
login and register basics done
1 parent ad20d7c commit 593765b

16 files changed

Lines changed: 305 additions & 147 deletions

File tree

.eslintrc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"extends": [
3+
"prettier"
4+
],
5+
"rules": {
6+
"indent": "error"
7+
}
8+
}
Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,39 @@
1-
const {makeUser} = require("../../../enterprise-business-rules/entities");
1+
const { makeUser } = require("../../../enterprise-business-rules/entities");
22
const { UniqueConstraintError, InvalidPropertyError } = require("../../../interface-adapters/config/validators-errors/errors");
33
const { makeHttpError } = require("../../../interface-adapters/config/validators-errors/http-error");
4+
const jwt = require("jsonwebtoken");
45

56
module.exports = {
67

7-
addUserUseCase: ({dbUserHandler}) => {
8-
return async function addUser (userData){
8+
registerUserUseCase: ({ dbUserHandler }) => {
9+
return async function registerUserUserCaseHandler(userData) {
910

11+
try {
1012

11-
try {
12-
//validate the user data after sanitizing it.
13-
const validatedUser =await makeUser(userData);
13+
//validate the user data after sanitizing it.
14+
const validatedUser = await makeUser(userData);
1415

15-
/// check the existance of this user in DB
16-
const existingUser = await dbUserHandler.findUserByEmail(validatedUser);
17-
if(existingUser){
18-
console.log("user already exists: ", existingUser);
19-
existingUser;
20-
}
21-
22-
return await dbUserHandler.registerUser(validatedUser);
23-
} catch (error) {
24-
console.log(error);
25-
return makeHttpError({
26-
errorMessage: error.message,
27-
statusCode: 400
28-
})
29-
}
30-
31-
32-
33-
16+
// check the existance of this user in DB
17+
let existingUser = await dbUserHandler.findUserByEmail(validatedUser)
3418

19+
// check if the result come from my DB controller
20+
if (Array.isArray(existingUser) && existingUser.length > 0) {
21+
return makeHttpError({
22+
errorMessage: "user already exists",
23+
statusCode: 409
24+
})
3525
}
26+
27+
return await dbUserHandler.registerUser(validatedUser);
28+
} catch (error) {
29+
console.log(error);
30+
return makeHttpError({
31+
errorMessage: error.message,
32+
statusCode: 400
33+
})
34+
}
3635
}
37-
}
36+
},
37+
3838

39+
}
Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
const {addUserUseCase} = require("./add-user");
1+
const {registerUserUseCase} = require("./add-user");
22
const dbUserHandler = require("../../../framework-and-drivers/database-access/")
3+
const {loginUserUseCase} = require("./login-user");
34

5+
const registerUserUserCaseHandler = registerUserUseCase({dbUserHandler});
6+
const loginUserUseCaseHandler = loginUserUseCase({dbUserHandler});
47

5-
const addUser = addUserUseCase({dbUserHandler})
6-
7-
module.exports = {addUser}
8+
module.exports = {registerUserUserCaseHandler, loginUserUseCaseHandler}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
const jwt = require("jsonwebtoken");
2+
const bcrypt = require("bcrypt");
3+
4+
module.exports = {
5+
6+
loginUserUseCase: ({dbUserHandler}) => {
7+
8+
return async function loginUserUseCaseHandler(userData) {
9+
10+
const { email, password } = userData;
11+
12+
console.log("email", email, "password", password);
13+
//basic verification
14+
if (!email || !password) {
15+
throw new RequiredParameterError("email or password")
16+
}
17+
18+
try {
19+
//check the existance of this user in DB
20+
let existingUser = await dbUserHandler.findUserByEmailForLogin({email});
21+
22+
if (!existingUser[0].id) {
23+
throw new NotFoundError("user not found");
24+
}
25+
26+
//check the password
27+
const matchPasswd = await bcrypt.compare(password, existingUser[0].password);
28+
if (!matchPasswd) {
29+
throw new InvalidPropertyError("password");
30+
}
31+
32+
//create the JWT
33+
const accessToken = jwt.sign({ email }, process.env.JWT_SECRET, {
34+
expiresIn: process.env.JWT_EXPIRES_IN
35+
});
36+
37+
//create refresh token
38+
const refreshToken = jwt.sign({ email }, process.env.JWT_REFRESH_SECRET, {
39+
expiresIn: process.env.JWT_REFRESH_EXPIRES_IN
40+
});
41+
42+
// return tokens: access and refresh to renew the accesstoken when expires
43+
return {accessToken, refreshToken};
44+
} catch (error) {
45+
console.log("login error", error);
46+
throw new Error(" failed to login: ", error.stack);
47+
}
48+
49+
}
50+
},
51+
52+
}

enterprise-business-rules/validate-models/validation-functions.js

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11

22
const { InvalidPropertyError } = require("../../interface-adapters/config/validators-errors/errors");
33
const bcrypt = require("bcrypt");
4+
const { makeHttpError } = require("../../interface-adapters/config/validators-errors/http-error");
45

56

67

@@ -26,7 +27,7 @@ function validateEmail(email) {
2627
* @throws {InvalidPropertyError} If the name is less than 2 characters long.
2728
* @return {string} The validated name with '<' characters replaced, or 'No Name' if the name is falsy.
2829
*/
29-
function validateName(name) {
30+
function validateName(name = "") {
3031
if (name.length < 2) {
3132
throw new InvalidPropertyError(
3233
`A user's name must be at least 2 characters long.`
@@ -98,32 +99,23 @@ async function validatePassword(password) {
9899
* - mobile: The result of validating the mobile number.
99100
* - password: The result of validating the password.
100101
*/
101-
async function validateUserData({
102-
firstName,
103-
lastName,
104-
email,
105-
mobile,
106-
password
107-
}) {
108-
109-
if (!firstName && !lastName) {
110-
return res.status(400).json({ msg: 'user must have at least one name.' })
111-
}
102+
async function validateUserData({firstName, lastName, email, mobile, password}) {
103+
const errors = [];
112104

113-
if (!email) {
114-
return res.status(400).json({ msg: 'user must have an email.' })
115-
}
105+
if (!firstName && !lastName) errors.push('user must have a first name or last name.');
106+
if (!email) errors.push('user must have an email.');
107+
if (!password) errors.push('user must have a password.');
116108

117-
if (!password) {
118-
return res.status(400).json({ msg: 'user must have a password.' })
109+
if (errors.length) {
110+
throw new InvalidPropertyError(errors.join(', '));
119111
}
120112

121113
return {
122114
email: validateEmail(email),
123-
mobile: validatePhone(mobile),
115+
mobile: mobile ? validatePhone(mobile) : "",
124116
password: await validatePassword(password),
125-
firstName: validateName(firstName),
126-
lastName: validateName(lastName),
117+
firstName: firstName ? validateName(firstName) : "",
118+
lastName: lastName ? validateName(lastName) : "",
127119
};
128120
}
129121

framework-and-drivers/database-access/store-user.js

Lines changed: 71 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,45 @@
1-
const { ReturnDocument } = require("mongodb");
1+
22

33
async function findUserByEmail(email, dbconnection) {
44

55
const db = await dbconnection()
66
try {
77
const result = await db.collection('users').find({ email })
8-
// const found = await result.toArray()
9-
// console.log(" result from DB checking", result)
10-
return (await result.toArray()).map(({ _id: id, ...found }) => ({
11-
id,
12-
...found
13-
}))
8+
const res = (await result.toArray()).map(({ _id: id, ...found }) => ({
9+
id: id.toString(),
10+
email: found.email,
11+
firstName: found.firstName,
12+
lastName: found.lastName,
13+
mobile: found.mobile
14+
}));
15+
16+
console.log("result from store find register", res);
17+
return res;
18+
} catch (error) {
19+
console.log("error checking for thexistence of user in DB", error);
20+
return null;
21+
}
22+
}
23+
24+
async function findUserByEmailForLogin(email, dbconnection) {
25+
26+
const db = await dbconnection()
27+
try {
28+
// const result = await db.collection('users').find({ email })
29+
30+
// const res = (await result.toArray()).map(({ _id: id, ...found }) => ({
31+
// id: id.toString(),
32+
// password: found.password,
33+
// }));
34+
console.log("email from store", email);
35+
const result = await db.collection('users').find({ email })
36+
const res = (await result.toArray()).map(({ _id: id, ...found }) => ({
37+
id: id.toString(),
38+
...found,
39+
}));
40+
41+
console.log("result from store for login", res);
42+
return res;
1443
} catch (error) {
1544
console.log("error checking for thexistence of user in DB", error);
1645
return null;
@@ -21,54 +50,61 @@ async function registerUser(userData, dbconnection) {
2150

2251
const db = await dbconnection()
2352
try {
53+
//check if the user already exist
54+
const existingUser = await findUserByEmail(userData.email, dbconnection);
55+
if (existingUser) {
56+
console.log("user already exists: ", existingUser);
57+
existingUser;
58+
}
2459
//insert document and return the inserted document
2560
const result = await db
26-
.collection('users')
27-
.insertOne({...userData });
61+
.collection('users')
62+
.insertOne({ ...userData });
2863
return result
29-
64+
3065
} catch (error) {
31-
66+
3267
console.log("error registering the user to DB: ", error);
3368
if (error.code === 11000) {
3469
throw new UniqueConstraintError(error.message)
35-
}
70+
}
3671
return null;
3772
}
38-
73+
3974
}
4075

41-
// async function findAllUsers() {
42-
// const db = await dbconnection()
43-
// const result = await db.collection('users').find({})
44-
// return (await result.toArray()).map(({ _id: id, ...found }) => ({
45-
// id,
46-
// ...found
47-
// }))
48-
// }
76+
// async function findAllUsers() {
77+
// const db = await dbconnection()
78+
// const result = await db.collection('users').find({})
79+
// return (await result.toArray()).map(({ _id: id, ...found }) => ({
80+
// id,
81+
// ...found
82+
// }))
83+
// }
4984

5085

51-
// async function updateUser({ id: _id, userData }) {
52-
// const db = await dbconnection()
53-
// const result = await db
54-
// .collection('users')
55-
// .updateOne({ _id }, { $set: { ...userData } })
56-
// return result.modifiedCount > 0 ? { id: _id, ...userData } : null
57-
// }
86+
// async function updateUser({ id: _id, userData }) {
87+
// const db = await dbconnection()
88+
// const result = await db
89+
// .collection('users')
90+
// .updateOne({ _id }, { $set: { ...userData } })
91+
// return result.modifiedCount > 0 ? { id: _id, ...userData } : null
92+
// }
5893

59-
// async function deleteUser({ id: _id }) {
60-
// const db = await dbconnection()
61-
// const result = await db.collection('users').deleteOne({ _id })
62-
// return result.deletedCount
63-
// }
94+
// async function deleteUser({ id: _id }) {
95+
// const db = await dbconnection()
96+
// const result = await db.collection('users').deleteOne({ _id })
97+
// return result.deletedCount
98+
// }
6499

65100

66101
module.exports = function makeUserdb({ dbconnection }) {
67102

68103
return Object.freeze({
69104
// findAllUsers,
70-
findUserByEmail: async({ email }) => findUserByEmail(email, dbconnection),
71-
registerUser: async(userData) => registerUser(userData, dbconnection),
105+
findUserByEmail: async ({ email }) => findUserByEmail(email, dbconnection),
106+
registerUser: async (userData) => registerUser(userData, dbconnection),
107+
findUserByEmailForLogin: async ({ email }) => findUserByEmailForLogin(email, dbconnection),
72108
// updateUser,
73109
// deleteUser
74110
})

index.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const path = require('path');
55
const { dbconnection } = require('./framework-and-drivers/database-access/db-connection.js');
66
const errorHandler = require('./interface-adapters/middlewares/loggers/errorHandler.js');
77
const router = require('./routes/auth-user.router.js');
8+
const { NotFound, ErrorHandlerMiddleware } = require('./interface-adapters/config/validators-errors/errors.js');
89

910

1011
const app = express();
@@ -48,9 +49,11 @@ app.use((req, res, next) => {
4849

4950

5051
app.use(errorHandler);
52+
app.use(NotFound);
53+
app.use(ErrorHandlerMiddleware);
5154

5255
// databae connetion call function
5356
dbconnection().then((db) => {
5457
console.log("database connected: ", db.databaseName);
55-
})
58+
});
5659
app.listen(PORT, () => console.log(`Server started on port http://localhost:${PORT}`));

interface-adapters/adapter/index.js

Lines changed: 0 additions & 6 deletions
This file was deleted.

interface-adapters/adapter/request-adapter.js

Lines changed: 0 additions & 19 deletions
This file was deleted.

0 commit comments

Comments
 (0)