# Week 7 Harry Potter
# KGBJ
---
# Process
<font size=4.5>
- Decided on new process for the project
- Created new tables for each house so that you could see fellow housemates
- Added the point system to accumulate for each house
- xml with promises
- Focussed on actual authentication
- Mobbing of client side validation
- Hashing of passwords
- Cookies
- Fixed the authentication to ensure passwords matched the database
- Fixed general issues
- Got the create user button to forward to the school roster and create a cookie
</font>
---
# Requirements
<font size=5>
- [x] Login form with 2 fields - username and password
- [x] Users only have to log in once (i.e. implement a cookie-based session on login)
- [ ] Username is visible on each page of the site after logging in
- [x] Any user-submitted content should be labelled with the authors username
- [x] There should be protected routes and unprotected routes that depend on the user having a cookie or not (or what level of access they have).
- [x] Website content should be stored in a database
- [ ] Include thorough tests on the back-end, testing pure functions and testing routes using Supertest. If you make external API calls, use Nock to mock the response for your tests.
- [ ] Test front-end logic, we don't expect tests on the DOM.
</font>
---
# Problems
We had a massive issue trying to insert the hashed password into the database! Our postData function was running before we had hashed our password and so the password was being posted to our database as 'undefined'. We eventually managed to solve it in two different ways...
---
Using callbacks

---
Using promises...

---
...then finally got it working **BUT** having inserted a lot of function promises as passwords along the way!

---
### Promises


---
```javascript=
// hashPassword.js
const bcrypt = require("bcryptjs");
const generateSalt = password => {
return new Promise((resolve, reject) => {
bcrypt.genSalt(12, (err, salt) => {
if (err) {
reject(new Error(err));
return;
} else {
const passSalt = [password, salt];
resolve(passSalt);
}
});
});
};
const hashIt = (password, salt) => {
return new Promise((resolve, reject) => {
bcrypt.hash(password, salt, (err, hash) => {
if (err) {
reject(new Error(err));
return;
} else {
resolve(hash);
}
});
});
};
const hashPassword = password => {
return new Promise((resolve, reject) => {
generateSalt(password)
.then(passSalt => hashIt(passSalt[0], passSalt[1]))
.then(hashedPassword => resolve(hashedPassword))
.catch(console.error);
});
};
```
---
```javascript=
// in our handlers.js
const handleCreateNewUser = (url, request, response) => {
let data = "";
request.on("data", chunk => {
data += chunk;
});
request.on("end", () => {
const results = queryString.parse(data);
let answers = Object.values(results);
let name = answers[0];
let password = answers[1][0];
let house = sortingHat(answers);
let points = Math.ceil(Math.random() * 100);
hash.hashPassword(password).then(hashedPassword => {
postData(name, house, points, hashedPassword, (err, res) => { ...
```
---
40 minutes of debugging and......:

---
# Cookies
```
req.on("end", () => {
const loginInfo = queryString.parse(data2);
let userDetails = {
user: `${loginInfo.name}`,
pass: `${loginInfo.password}`
};
const cookie = sign(userDetails, SECRET);
res.writeHead(302, {
Location: "/trivia",
"Set-Cookie": `jwt=${cookie}; HttpOnly; Max-Age=9000`
});
return res.end();
});
};
```
---
```
let userDetails = {
user: name,
pass: hashedPassword
};
const cookie = sign(userDetails, SECRET);
response.writeHead(302, {
Location: "/trivia",
"Set-Cookie": `Login=${cookie}; HttpOnly; Max-Age=9000`
});
return response.end();
}
```
---
```
else if (endpoint === "/trivia") {
serveTrivia(response);
} else if (endpoint === "/houses") {
handleGettingUsers(response);
} else if (endpoint === "/create-user") {
handleCreateNewUser(endpoint, request, response);
} else if (endpoint.startsWith("/public")) {
handlePublic(response, endpoint);
} else if (endpoint.startsWith("/login")){
handleLogin(request, response, endpoint)
} else {
handle404(response);
```
---
# Enhancements
Username appearing on each page
Better error messages for bad login
Add trivia quiz for gamification and point earning
Add logout button to houses page which returns to index and deletes cookie.
{"metaMigratedAt":"2023-06-15T02:31:18.642Z","metaMigratedFrom":"Content","title":"Week 7 Harry Potter","breaks":true,"contributors":"[{\"id\":\"5c8d1f73-6329-4c8b-88d4-bfb2f8bc28c4\",\"add\":1328,\"del\":13},{\"id\":\"09c2cb97-7340-43ab-a79b-d087b968c372\",\"add\":715,\"del\":1549},{\"id\":\"7a8e5efa-23d6-4b8f-8e21-d8d2bcafea85\",\"add\":4768,\"del\":169}]"}