diff --git a/.gitignore b/.gitignore index 7b7b4a8..4324f10 100644 --- a/.gitignore +++ b/.gitignore @@ -113,4 +113,9 @@ ehthumbs.db Thumbs.db # bundle.js file -bundle.js \ No newline at end of file +bundle.js + +#vscode setting +.vscode +# keys.js file +keys.js diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..ac694bf --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,12 @@ +{ + "workbench.colorCustomizations": { + "statusBar.background": "#2980b9", + "statusBar.foreground": "#e7e7e7", + "statusBarItem.hoverBackground": "#409ad5", + "titleBar.activeBackground": "#2980b9", + "titleBar.activeForeground": "#e7e7e7", + "titleBar.inactiveBackground": "#2980b999", + "titleBar.inactiveForeground": "#e7e7e799" + }, + "peacock.color": "#2980B9" +} \ No newline at end of file diff --git a/config/keys.js b/config/keys.js new file mode 100644 index 0000000..446ef2a --- /dev/null +++ b/config/keys.js @@ -0,0 +1,24 @@ +//add this file to gitignore + +module.exports = { + google: { + // this clientID and clientSecret are given to us from google + clientID: + '979104596982-qkkdoare2fms3gaqne9v3pkbfs6bnppt.apps.googleusercontent.com', + clientSecret: '2h4K44PG0SUQzPq6eU1abQs7', + }, + postgres: { + // here is our postgres URL + PG_URI: + 'postgres://fojeewoc:yKLXZvm6DqRW840uEqmWDnT3OdGmYW_n@suleiman.db.elephantsql.com:5432/fojeewoc', + }, + session: { + // this cookieKey is going to encrypt our cookie so that folks can't just see our cookie + cookieKey: 'dfkjghsjdhasdakjsdan', + }, + + facebook: { + clientID: '383299809591566', + AppSecret: 'cd417d5c4a4272542fe535826b91e7c1', + }, +}; diff --git a/config/passport-setup.js b/config/passport-setup.js new file mode 100644 index 0000000..b360e35 --- /dev/null +++ b/config/passport-setup.js @@ -0,0 +1,110 @@ +const passport = require('passport'); +const GoogleStrategy = require('passport-google-oauth20'); +const keys = require('./keys'); +const db = require('../models/closetModels'); +const FacebookStrategy = require('passport-facebook').Strategy; + +//serialize user's oauth_id for our cookie +passport.serializeUser((user, done) => { + done(null, user.rows[0]._id); +}); + +passport.deserializeUser(async (id, done) => { + // we need to pass in the user we're making the cookie for in done, so we will grab that user (again) via their oath_id in our query string + const userQuery = 'SELECT * FROM users WHERE oauth_id = $1'; + const queryParam = [id]; + //query db to find user based on their oath_id + const user = await db.query(userQuery, queryParam); + //pass user into done + done(null, user); +}); + +passport.use( + new GoogleStrategy( + { + //options for the strategy + //need to add a redirectURL, found in our google developer console + callbackURL: '/auth/google/redirect', + //need a client ID and a client secret + clientID: keys.google.clientID, + clientSecret: keys.google.clientSecret, + }, + async (req, accessToken, refreshToken, profile, done) => { + //passport callback function + // check if user exists in our db first + try { + const findUserStr = `SELECT EXISTS (SELECT * FROM USERS WHERE oauth_id=$1)`; + //finduser params + const authID = profile.id; + const query2 = [authID]; + + //insert string params + const { givenName, familyName } = profile.name; + const emails = profile.emails[0].value; + const profileImage = profile.photos[0].value; + const insertUser = `INSERT INTO USERS (first_name1, last_name1, username, email, profile_Image, display_name_1, oauth_id) VALUES + ($1, $2, $3, $4, $5, $6, $7)`; + const findUserQuery = [ + givenName, + familyName, + emails, + emails, + profileImage, + givenName, + authID, + ]; + //check if user exists in db + const response = await db.query(findUserStr, query2); + //if user does not exists, quuery the db again to add the user + if (!response.rows[0].exists) await db.query(insertUser, findUserQuery); + //otherwise query the database to find the ID of the newly added user on line 37 + const userQuery = 'SELECT * FROM USERS WHERE oauth_id = $1'; + //assign a var the value of findind the newly added or already added user in table and assign it as second arg in done() + const user = await db.query(userQuery, query2); + done(null, user); + } catch (error) { + console.log('we got here somehow'); + } + } + ) +); +passport.use( + new FacebookStrategy( + { + clientID: keys.facebook.clientID, + clientSecret: keys.facebook.AppSecret, + callbackURL: 'http://localhost:3000/auth/facebook/callback', + }, + async (accessToken, refreshToken, profile, done) => { + console.log(profile); + try { + const findUserStr = `SELECT EXISTS (SELECT * FROM USERS WHERE oauth_id=$1)`; + //finduser params + const authID = profile.id; + const query2 = [authID]; + + //insert string params + const displayName = profile.displayName; + let first_Name = displayName.split(' ')[0]; + let last_Name = displayName.split(' ')[1]; + + // const profileImage = profile.photos[0].value; + const insertUser = `INSERT INTO USERS (first_name1, last_name1, username, email, profile_Image, display_name_1, oauth_id) VALUES + ($1, $2, $3, 'N/A', 'N/A', $3, $4)`; + + const findUserQuery = [first_Name, last_Name, displayName, authID]; + //check if user exists in db + const response = await db.query(findUserStr, query2); + //if user does not exists, quuery the db again to add the user + if (!response.rows[0].exists) await db.query(insertUser, findUserQuery); + //otherwise query the database to find the ID of the newly added user on line 37 + const userQuery = 'SELECT * FROM USERS WHERE oauth_id = $1'; + //assign a var the value of findind the newly added or already added user in table and assign it as second arg in done() + const user = await db.query(userQuery, query2); + done(null, user); + } catch (error) { + console.log('we got here somehow'); + } + } + ) +); diff --git a/controllers/closetController.js b/controllers/closetController.js new file mode 100644 index 0000000..557ac1d --- /dev/null +++ b/controllers/closetController.js @@ -0,0 +1,167 @@ +const db = require('../models/closetModels'); + +const closetController = {}; + +// adds a new item to a user's closet +closetController.newClothingItem = async (req, res, next) => { + const { + itemName, + itemClothingType, + itemColor, + itemImage, + user_id, + season, + size, + availability, + } = req.body; + + const queryStr = + 'INSERT INTO Closet (itemName, itemClothingType, itemColor, itemImage, user_id, season, size, availability) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)'; + const queryParams = [ + itemName, + itemClothingType, + itemColor, + itemImage, + user_id, + season, + size, + availability, + ]; + + try { + await db.query(queryStr, queryParams); + return next(); + } catch (error) { + return next({ + log: `Database error`, + status: 502, + message: { err: `${error.stack}` }, + }); + } +}; + +// retrieves all clothes from Clothes table +closetController.getClothes = async (req, res, next) => { + // would this be req.params?? + const userId = req.params.id; + const queryStr = + 'SELECT u._id, c.* FROM Users u LEFT OUTER JOIN Closet c ON c.user_id = $1'; + // const queryStr = 'SELECT * FROM Closet ORDER BY _id ASC'; + try { + const data = await db.query(queryStr, [userId]); + res.locals.clothes = data.rows; + return next(); + } catch (error) { + return next(error); + } +}; + +// updates how many times an item has been worn and date of last wear +// id of item is passed through as key/value on request body +closetController.updateClosetItem = async (req, res, next) => { + const worn = req.body.worn; + const { id, itemname, itemclothingtype, itemcolor } = req.body; + console.log(id); + console.log(worn); + const firstQuery = 'SELECT times_worn FROM Closet WHERE _id = $1'; + + if (worn) { + try { + const data = await db.query(firstQuery, [id]); + let { times_worn } = data.rows[0]; + console.log(times_worn); + times_worn += 1; + const todaysDate = new Date(); + + const queryStr = + 'UPDATE Closet SET itemname = $1, itemclothingtype = $2, itemcolor = $3, last_worn = $4, times_worn = $5 WHERE _id= $6'; + const queryParams = [ + itemname, + itemclothingtype, + itemcolor, + todaysDate, + times_worn, + id, + ]; + await db.query(queryStr, queryParams); + return next(); + } catch (error) { + return next({ + log: `Database error`, + status: 502, + message: { err: `${error.stack}` }, + }); + } + } +}; + +// removes a piece of clothing from the Closet table +// request body includes key/value of clothing item id +closetController.deleteClothingItem = async (req, res, next) => { + const id = req.params.id; + + // query string is to delete item from closet table where id matches passed in id + const queryStr = 'DELETE FROM Closet WHERE _id = $1'; + const queryParams = [id]; + + try { + await db.query(queryStr, queryParams); + return next(); + } catch (error) { + return next({ + log: `Database error`, + status: 502, + message: { err: `${error.stack}` }, + }); + } +}; + +// update donation status in closet table +// select donation_status matching clothing item _id +closetController.donationStatusUpdate = async (req, res, next) => { + const id = req.body.id; + console.log(id); + const firstQuery = 'SELECT donation_status FROM Closet WHERE _id = $1'; + + try { + const data = await db.query(firstQuery, [id]); + let { donation_status } = data.rows[0]; + console.log(donation_status); + // swap donation_status based on current value + donation_status = donation_status === 'Inactive' ? 'Active' : 'Inactive'; + + const queryStr = 'UPDATE Closet SET donation_status = $1 WHERE _id= $2'; + const queryParams = [donation_status, id]; + + await db.query(queryStr, queryParams); + return next(); + } catch (error) { + return next({ + log: `Database error`, + status: 502, + message: { err: `${error.stack}` }, + }); + } +}; + +// query to find donation items for marketplace +// pulls everything matching donation status of 'Active' +closetController.getMarketplaceItems = async (req, res, next) => { + console.log('inside marketplace middleware!'); + const queryStr = 'SELECT * FROM Closet WHERE donation_status = $1'; + queryParams = ['Active']; + + try { + const data = await db.query(queryStr, queryParams); + res.locals.clothes = data.rows; + return next(); + } catch (error) { + return next({ + log: `Database error`, + status: 502, + message: { err: `${error.stack}` }, + }); + } +}; + +module.exports = closetController; diff --git a/controllers/userController.js b/controllers/userController.js new file mode 100644 index 0000000..0ec3687 --- /dev/null +++ b/controllers/userController.js @@ -0,0 +1,96 @@ +const db = require('../models/closetModels'); + +const userController = {}; + +// adds a user to the db +userController.addUser = async (req, res, next) => { + const { + first_name, + last_name, + username, + password, + email, + zip_code, + profile_image, + city, + state, + display_name_1, + oauth_id, + } = req.body; + + const queryStr = + 'INSERT INTO Users (_id, first_name, last_name, username, password, email, zip_code, profile_image, city, state, display_name_1, oauth_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)'; + const queryParams = [ + DEFAULT, + first_name, + last_name, + username, + password, + email, + zip_code, + profile_image, + city, + state, + display_name_1, + oauth_id, + ]; + // need to check first if a user with username/password already exists...? + + try { + await db.query(queryStr, queryParams); + return next(); + } catch (error) { + return next({ + log: `Database error`, + status: 502, + message: { err: `${error.stack}` }, + }); + } +}; + +userController.userLogin = async (req, res, next) => { + const { username, password } = req.body; + + const firstQuery = + 'SELECT EXISTS (SELECT 1 FROM Users WHERE username = $1 AND password = $2)'; + const queryParams = [username, password]; + + try { + const validUser = await db.query(firstQuery, queryParams); + // if validUser is true: + // query db for id belonging to username and password and return to client? + if (validUser) { + const queryString = + 'SELECT _id FROM Users WHERE username = $1 AND password = $2'; + const data = await db.query(queryString, queryParams); + res.locals._id = data.rows[0]; + return next(); + } + res.send('Invalid username or password'); + } catch (error) { + return next({ + log: `Database error`, + status: 502, + message: { err: `${error.stack}` }, + }); + } +}; + +userController.getUser = async (req, res, next) => { + const userId = req.params.id; + const queryStr = 'SELECT * FROM Users WHERE _id = $1'; + + try { + const data = await db.query(queryStr, [userId]); + res.locals.user = data.rows; + return next(); + } catch (error) { + return next({ + log: `Database error`, + status: 502, + message: { err: `${error.stack}` }, + }); + } +}; + +module.exports = userController; diff --git a/fileController.js b/fileController.js deleted file mode 100644 index 37f7af6..0000000 --- a/fileController.js +++ /dev/null @@ -1,73 +0,0 @@ -const db = require('./models/closetModels') - -const fileController = {}; - -fileController.getClothes = async (req, res, next) => { - const queryStr = 'SELECT * FROM Closet ORDER BY _id ASC'; - try { - const data = await db.query(queryStr); - res.locals.clothes = data.rows; - return next(); - } catch (error) { - return next(error); - } -}; - -fileController.newClothingItem = async (req, res, next) => { - const { itemName, itemClothingType, itemColor, itemImage } = req.body - - const queryStr = 'INSERT INTO Closet (itemName, itemClothingType, itemColor, itemImage) VALUES ($1, $2, $3, $4)'; - const queryParams = [itemName, itemClothingType, itemColor, itemImage]; - - try { - await db.query(queryStr, queryParams); - return next(); - } catch (error) { - return next({ - log: `Database error`, - status: 502, - message: { err: `${error.stack}` }, - }); - } -}; - -fileController.updateClosetItem = async (req, res, next) => { - const id = req.body._id; - const firstQuery = 'SELECT times_worn FROM Closet WHERE _id = $1'; - - try { - const data = await db.query(firstQuery, [id]); - let { times_worn } = data.rows[0]; - times_worn += 1; - const todaysDate = new Date(); - - const queryStr = 'UPDATE Closet SET last_worn = $1, times_worn = $2 WHERE _id= $3'; - const queryParams = [todaysDate, times_worn, id]; - await db.query(queryStr, queryParams); - return next(); - } catch (error) { - return next({ - log: `Database error`, - status: 502, - message: { err: `${error.stack}` }, - }); - } -} - -fileController.deleteClothingItem = async (req, res, next) => { - const id = req.body._id - const queryStr = 'DELETE FROM Closet WHERE _id = $1'; - const queryParams = [id]; - - try { - await db.query(queryStr, queryParams); - return next(); - } catch (error) { - return next({ - log: `Database error`, - status: 502, - message: { err: `${error.stack}` }, - }); - } -} -module.exports = fileController; diff --git a/index.html b/index.html index 7a8b372..b279d69 100644 --- a/index.html +++ b/index.html @@ -1,15 +1,35 @@
- - - - + + + +