Skip to content

Commit 89a7a62

Browse files
BIG commit. The web is now almost ready for realease. v0.9.7 No known bugs for now. (/profile/edit can edit everything with many possible cases and a flash for every case + backend validation in every section)
1 parent af9376d commit 89a7a62

File tree

15 files changed

+221
-75
lines changed

15 files changed

+221
-75
lines changed

src/app.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@ app.use((req, res, next) => {
6969
app.locals.userLoggedIn = req.flash('userLoggedIn');
7070
app.locals.userNotLoggedIn = req.flash('userNotLoggedIn');
7171
app.locals.usedEmail = req.flash('usedEmail');
72+
app.locals.bothUpdated = req.flash('bothUpdated');
73+
app.locals.onlyFullnameUpdated = req.flash('onlyFullnameUpdated');
74+
app.locals.onlyPasswordUpdated = req.flash('onlyPasswordUpdated');
75+
app.locals.nothingUpdated = req.flash('nothingUpdated');
76+
app.locals.moreThanOneUser = req.flash('moreThanOneUser');
7277
app.locals.user = req.user;
7378
next();
7479
});

src/database.js

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,23 @@ const { database } = require('./keys');
1212
const pool = mysql.createPool(database);
1313

1414
pool.getConnection((err, connection) => {
15-
/* Treat the different error codes. */
16-
if (err) {
17-
if (err.code === 'PROTOCOL_CONNECTION_LOST') {
18-
console.error('DATABASE CONNECTION WAS CLOSED.');
19-
}
20-
if (err.code === 'ER_CON_COUNT_ERROR') {
21-
console.error('DATABASE HAS TOO MANY CONNECTIONS.');
22-
}
23-
if (err.code === 'ECONNREFUSED') {
24-
console.error('DATABASE CONNECTION WAS REFUSED. THIS MIGHT HAPPEN DUE TO INCORRECT LOGIN INFORMATION');
25-
}
26-
}
15+
/* Treat the different error codes. */
16+
if (err) {
17+
if (err.code === 'PROTOCOL_CONNECTION_LOST') {
18+
console.error('DATABASE CONNECTION WAS CLOSED.');
19+
}
20+
if (err.code === 'ER_CON_COUNT_ERROR') {
21+
console.error('DATABASE HAS TOO MANY CONNECTIONS.');
22+
}
23+
if (err.code === 'ECONNREFUSED') {
24+
console.error('DATABASE CONNECTION WAS REFUSED. THIS MIGHT HAPPEN DUE TO INCORRECT LOGIN INFORMATION');
25+
}
26+
}
2727

28-
/* Release the connection to the database when connected. */
29-
if (connection) connection.release();
30-
console.log('DB is connected;');
31-
return;
28+
/* Release the connection to the database when connected. */
29+
if (connection) connection.release();
30+
console.log('DB is connected;');
31+
return;
3232
});
3333

3434
//Change callbacks to promises with promisify.

src/lib/passport.js

Lines changed: 99 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ const LocalStrategy = require('passport-local').Strategy;
44
const pool = require('../database');
55
const helpers = require('./helpers');
66
const time = require('./timeago');
7+
/* REGEX for validations. */
8+
const fullPasswordPattern = /^(?=.*?[A-Z])(?=.*?[a-z])(?=.{1,}?[0-9])(?=.*?[#?!@$%&*\-+.,]).{8,30}$/g;
9+
const fullnamePattern = /^(([A-Za-z]+[\-\']?)*([A-Za-z]+)?\s)+([A-Za-z]+[\-\']?)*([A-Za-z]+)?$/i;
710

811
/* Login validation. */
912
passport.use(
@@ -65,10 +68,14 @@ passport.use(
6568
It DOESN'T store anything in the DB */
6669
return done(null, false, req.flash('usedEmail', 'The email you introduced is already stored in our DB. Please, use a NEW email.'));
6770
}
71+
if (password.match(fullPasswordPattern)) {
72+
const result = await pool.query('INSERT INTO users set ?', [newUser]);
73+
newUser.id = result.insertId;
74+
return done(null, newUser, req.flash('successSignup', newUser.email));
75+
} else {
76+
throw new Error(`The password isn't valid.`);
77+
}
6878
}
69-
const result = await pool.query('INSERT INTO users set ?', [newUser]);
70-
newUser.id = result.insertId;
71-
return done(null, newUser, req.flash('successSignup', newUser.email));
7279
} catch (err) {
7380
console.error(err);
7481
console.error('There has been an error inserting the data in the DB.');
@@ -77,6 +84,95 @@ passport.use(
7784
),
7885
);
7986

87+
/* Edit profile with password encryption. */
88+
passport.use(
89+
'local.profileEdit',
90+
new LocalStrategy(
91+
{
92+
usernameField: 'fullnameInput',
93+
passwordField: 'newPasswordInput',
94+
passReqToCallback: true,
95+
},
96+
async (req, fullname, newPassword, done) => {
97+
/* Make constants to use later in the function. */
98+
const currentPassword = req.body.currentPasswordInput;
99+
const userID = req.user.id;
100+
// SELECT the user that is currently logged in.
101+
const entry = await pool.query('SELECT * FROM users WHERE id = ?', [userID]);
102+
/* If the query found the user (it should do) it will execute this if: */
103+
if (entry.length > 0) {
104+
// We store the first entry retrieved from the DB to use it as "user".
105+
const user = entry[0];
106+
/* If the user introduced some valid data in the fullname OR password/s field/s it will execute this if: */
107+
if ((fullname.length > 0 && fullname.match(fullnamePattern)) || (newPassword.length > 0 && currentPassword.length > 0 && newPassword.match(fullPasswordPattern) && currentPassword.match(fullPasswordPattern))) {
108+
/* Creation of global variables to detect if the fullname and password has been saved. */
109+
var fullnameOK = true;
110+
var passwordOK = true;
111+
/* If the user introduced a fullname and it matches the fullname REGEX: */
112+
if (fullname.length > 0 && fullname.match(fullnamePattern)) {
113+
try {
114+
//Update the fullname in the DB
115+
const updateFullnameQuery = await pool.query(`UPDATE users SET fullname='${fullname}' WHERE id='${userID}'`);
116+
//Update the fullname of the logged user.
117+
req.user.fullname = fullname;
118+
//Maintain the var with a true value, to let the program know the fullname has been updated.
119+
fullnameOK = true;
120+
} catch (err) {
121+
//Set the var to false to let the program know
122+
fullnameOK = false;
123+
/* Display the error to the user */
124+
console.error(err);
125+
console.error('There has been an error updating your fullname in the DB. Please, try it again.');
126+
}
127+
} else if (!(fullname.length > 0 && fullname.match(fullnamePattern))) {
128+
/* In case the user doesn't introduce nothing in the fullname field (or the data introduced is not valid) it will let him and the program know the fullname hasn't been updated. */
129+
fullnameOK = false;
130+
console.log(`The fullname doesn't contain anything or the data inside the input has invalid characters.`);
131+
}
132+
/* If the user introduced both passwords and both match the REGEX: */
133+
if (newPassword.length > 0 && newPassword.match(fullPasswordPattern) && currentPassword.length > 0 && currentPassword.match(fullPasswordPattern)) {
134+
try {
135+
//Compare the password introduced by the user to the one in the DB.
136+
const passwordComparison = await helpers.comparePassword(currentPassword, user.password);
137+
/* If the comparison returns a true value: */
138+
if (passwordComparison) {
139+
/* Encrypt the new password, introduce it in the DB and set the var to true to let the program know the password has been updated. */
140+
const newHashedPassword = await helpers.encryptPassword(newPassword);
141+
const updatePasswordQuery = await pool.query(`UPDATE users SET password='${newHashedPassword}' WHERE id='${userID}'`);
142+
req.user.password = newHashedPassword;
143+
passwordOK = true;
144+
} else {
145+
//If the password comparison returns a false value it will throw a Error so we can't update the password.
146+
throw new Error('The "current password" you introduced is not the same as the one stored in the DB.');
147+
}
148+
} catch (err) {
149+
/* In case there is an error during the comparison/encryption or update of the password it will show a general error. */
150+
passwordOK = false;
151+
console.error(err);
152+
console.error('There has been an error updating your password in the DB. Please, try it again.');
153+
}
154+
} else if (!(newPassword.length > 0 && newPassword.match(fullPasswordPattern) && currentPassword.length > 0 && currentPassword.match(fullPasswordPattern))) {
155+
/* In case the user doesn't introduce nothing in the passwords fields (or the data introduced is not valid) it will let him and the program know the password hasn't been updated. */
156+
passwordOK = false;
157+
console.log(`The password doesn't contain anything or the data inside the input has invalid characters.`);
158+
}
159+
}
160+
if (fullnameOK && passwordOK) {
161+
return done(null, req.user, req.flash('bothUpdated', 'Both fullname and password has been updated.'));
162+
} else if (fullnameOK) {
163+
return done(null, req.user, req.flash('onlyFullnameUpdated', 'Only your fullname has been updated.'));
164+
} else if (passwordOK) {
165+
return done(null, req.user, req.flash('onlyPasswordUpdated', 'Only your password has been updated.'));
166+
} else {
167+
return done(null, false, req.flash('nothingUpdated', 'We could not update anything in the DB. Check both inputs.'));
168+
}
169+
} else {
170+
return done(null, false, req.flash('moreThanOneUser', 'There are more than 2 users with that ID. That is not supposed to happen. Please contact any administrator so he can delete one of the accounts.'));
171+
}
172+
},
173+
),
174+
);
175+
80176
/* Serializing the user to maintain the session. */
81177
passport.serializeUser((user, done) => {
82178
done(null, user.id);

0 commit comments

Comments
 (0)