Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Workshop: node-express-reddit-clone [Tetyana] #20

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions controllers/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,19 @@ module.exports = function(myReddit) {
var authController = express.Router();

authController.get('/login', function(request, response) {
response.send("TO BE IMPLEMENTED");
response.render('login-form');
});

authController.post('/login', function(request, response) {
response.send("TO BE IMPLEMENTED");
response.render('login-form');
});

authController.get('/signup', function(request, response) {
response.send("TO BE IMPLEMENTED");
response.render('signup-form');
});

authController.post('/signup', function(request, response) {
response.send("TO BE IMPLEMENTED");
response.render('signup-form');
});

return authController;
Expand Down
194 changes: 194 additions & 0 deletions reddit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
'use strict'

var bcrypt = require('bcrypt-as-promised');
var HASH_ROUNDS = 10;

class RedditAPI {
constructor(conn) {
this.conn = conn;
}

createUser(user) {
/*
first we have to hash the password. we will learn about hashing next week.
the goal of hashing is to store a digested version of the password from which
it is infeasible to recover the original password, but which can still be used
to assess with great confidence whether a provided password is the correct one or not
*/
return bcrypt.hash(user.password, HASH_ROUNDS)
.then(hashedPassword => {
return this.conn.query(`INSERT INTO users (username,password, createdAt, updatedAt)
VALUES (?, ?, NOW(), NOW())`, [user.username, hashedPassword]);
})
.then(result => {
return result.insertId;
})
.catch(error => {
// Special error handling for duplicate entry
if (error.code === 'ER_DUP_ENTRY') {
throw new Error('A user with this username already exists');
}
else {
throw error;
}
});
}

createPost(post) {
if (post.subredditId === undefined) {
throw new Error('SubredditId is missing');
}
else {
return this.conn.query(
`
INSERT INTO posts (subredditId, userId, title, url, createdAt, updatedAt)
VALUES (?, ?, ?, ?, NOW(), NOW())
`,
[post.subredditId, post.userId, post.title, post.url]
)
.then(result => {
return result.insertId;
});
}
}

// Create Subreddit
createSubreddit(subreddit) {
return this.conn.query(
`
INSERT INTO subreddits(name, description, createdAt, updatedAt)
VALUES (?, ?, NOW(), NOW())
ON DUPLICATE KEY UPDATE name=?, updatedAt=NOW()`,

[subreddit.name, subreddit.description, subreddit.name]
)
.then(result => {
return result.insertId;
})
.catch(error => {
if (error.code === 'ER_DUP_ENTRY') {
throw new Error('A subreddit with this name already exists');
}
else {
throw error;
}
});
};

createVote(vote) {
switch (vote.voteDirection) {
case -1:
case 0:
case 1:
return this.conn.query(
`
INSERT INTO votes (userId, postId, voteDirection, createdAt, updatedAt)
VALUES (?, ?, ?, NOW(), NOW())
ON DUPLICATE KEY UPDATE voteDirection=?, updatedAt=NOW()
`,
[vote.userId, vote.postId, vote.voteDirection, vote.voteDirection]
);
default:
throw Error('Vote direction should be one of the following values (-1,0,1)');
}
};

getAllPosts() {
/*
strings delimited with ` are an ES2015 feature called "template strings".
they are more powerful than what we are using them for here. one feature of
template strings is that you can write them on multiple lines. if you try to
skip a line in a single- or double-quoted string, you would get a syntax error.

therefore template strings make it very easy to write SQL queries that span multiple
lines without having to manually split the string line by line.
*/
return this.conn.query(
`
SELECT p.id
, p.title
, p.url
, p.userId
, p.createdAt
, p.updatedAt
, p.subredditId
, u.username as userName
, u.createdAt as uCreatedAt
, u.updatedAt as uUpdatedAt
, s.name AS subredditName
, s.description AS subredditDescription
, s.createdAt AS subredditCreatedAt
, s.updatedAt AS subredditUpdatedAt
, SUM(v.voteDirection) AS voteScore
FROM posts p
JOIN users u ON u.id = p.userId
LEFT JOIN subreddits s ON p.subredditId = s.id
LEFT JOIN votes v ON p.id = v.postId
GROUP BY
p.id
, p.title
, p.url
, p.createdAt
, p.updatedAt
, p.subredditId
, p.userId
, s.name
, s.description
, s.createdAt
, s.updatedAt
ORDER BY SUM(v.voteDirection) DESC
LIMIT 25`
)
.then(result => {
return result.map(function(post) {
return {
id: post.id,
title: post.title,
url: post.url,
voteScore: post.voteScore,
createdAt: post.createdAt,
updatedAt: post.updatedAt,
subreddit: {
id: post.subredditId,
name: post.subredditName,
description: post.subredditDescription,
createdAt: post.subredditCreatedAt,
updatedAt: post.subredditUpdatedAt
},
user: {
id: post.userId,
name: post.userName,
createdAd: post.uCreatedAt,
updatedAt: post.uUpdatedAt
}
}
});
});
}

getAllSubreddits() {
return this.conn.query (
`SELECT id
, name
, description
, createdAt
, updatedAt
FROM subreddits
ORDER BY createdAt DESC`
)
.then(result => {
return result.map(function(subreddit) {
return {
id: subreddit.id,
name: subreddit.name,
description: subreddit.description,
createdAt: subreddit.createdAt,
updatedAt: subreddit.updatedAt
}
})
})
}

}

module.exports = RedditAPI;
2 changes: 1 addition & 1 deletion views/layout.pug
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ html
a(href="/auth/login") Login
main
block content
footer © 2017 blah
footer © 2017 project - cohort 9
11 changes: 11 additions & 0 deletions views/login-form.pug
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
extends layout.pug

block content
h1 Login
form(action="/auth/login" method="POST")
p Username:
input(type='text' name='username' placeholder='username')
p Password:
input(type='password' name='password' placeholder='password')
p
button(type='submit') Login!
11 changes: 11 additions & 0 deletions views/signup-form.pug
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
extends layout.pug

block content
h1 Signup
form(action="/auth/signup" method="POST")
p Username:
input(type='text' name='username' placeholder='username')
p Password:
input(type='password' name='password' placeholder='password')
p
button(type='submit') Signup!