Skip to content
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
Binary file added .DS_Store
Binary file not shown.
2 changes: 2 additions & 0 deletions .replit
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
language = "nodejs"
run = "npm start"
8 changes: 4 additions & 4 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"editor.fontSize": 38,
"terminal.integrated.fontSize": 60
}
// {
// "editor.fontSize": 38,
// "terminal.integrated.fontSize": 60
// }
23 changes: 23 additions & 0 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Dependencies:
- mongoose, express, express-session, express-flash, passport, passport-local, bcrypt, ejs, nodemon, validator, multer

# Security:
- Using bcrypt.hash() with 10 rounds. NO SALT REQUIRED
- Using bcrypt.compare() to match passwords within passport config. No need for pre functions upon saving of mongoose model.

# Database Structuring:
- There are three collections.
1) Users - Stores user info (uniqueid, username, password, email)
2) Sessions - Stores cookie info
3) Posts - Stores post info (uniquepostid, creationDate, title, description, img, idOfPostOwner)

# Landing Page:
- Renders index.ejs upon get request. This is the home page.
Options to login/signup. New users will signup, get posted to the db, and get redirected to their dashboard immediately (immediate login). Existing users will login and get redirected to their dashboard. Session cookies are stored in db.

# Dashboard Page:
- Renders dashboard.ejs upon get request. An array with all 'post' objects from Posts.find() will be passed in to be rendered in the feed.
- Place special css classes upon posts with req.user.username matching to distinguish it from others' posts.

# PROPERTIES OF USERPOST
-
4 changes: 4 additions & 0 deletions DONT_TOUCH.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# if you have a poorly coded code snippet that could break with the addition of a single console.log, place em here:

- loginCont.js - brownfox
- signCont.js - brownfox
1 change: 1 addition & 0 deletions Procfile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"web: node server.js"
5 changes: 4 additions & 1 deletion config/.env
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
PORT = 2121
DB_STRING = mongodb+srv://demo:[email protected]/todolist?retryWrites=true&w=majority
DB_STRING = mongodb+srv://sid:[email protected]/myFirstDatabase?retryWrites=true&w=majority
CLOUD_NAME = dcb0elhsr
API_KEY = 173911944542314
API_SECRET = pbe1zFsen23ZJp2VIRKG0rHvJfI
8 changes: 4 additions & 4 deletions config/config.js
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
exports.creds = {
identityMetadata: 'https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration',

clientID: '<add your own>',
clientID: '0bd0f608-3470-493a-8dc8-d7682aefed92',

clientSecret: '<add your own>',
clientSecret: 'PxS_-fjKMW1i-Wy_6T4WK7s7mE.4P7HevC',

responseType: 'code id_token',

responseMode: 'form_post',

redirectUrl: 'http://localhost:2121/auth/openid/return',
redirectUrl: 'https://bubsocialnetwork.egodeath.repl.co/auth/openid/return',

allowHttpForRedirectUrl: true,

Expand Down Expand Up @@ -37,7 +37,7 @@ exports.creds = {
clockSkew: null,
};

exports.destroySessionUrl = 'http://localhost:2121';
exports.destroySessionUrl = 'https://bubsocialnetwork.egodeath.repl.co';

exports.useMongoDBSessionStore = false;

Expand Down
4 changes: 2 additions & 2 deletions config/database.js
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
const mongoose = require('mongoose')
const mongoose = require('mongoose') //setting up our db

const connectDB = async () => {
try {
const conn = await mongoose.connect(process.env.DB_STRING, {
const conn = await mongoose.connect(process.env.DB_STRING, {
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: false,
Expand Down
80 changes: 29 additions & 51 deletions config/passport.js
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,58 +1,36 @@
const OIDCStrategy = require('passport-azure-ad').OIDCStrategy
const mongoose = require('mongoose')
const config = require('../config/config')
const User = require('../models/User')
const lstrat = require('passport-local').Strategy;
const mongoose = require('mongoose');
const User = require('../models/User');
const bcrypt = require('bcrypt');

module.exports = function (passport) {
passport.use(
new OIDCStrategy({
identityMetadata: config.creds.identityMetadata,
clientID: config.creds.clientID,
responseType: config.creds.responseType,
responseMode: config.creds.responseMode,
redirectUrl: config.creds.redirectUrl,
allowHttpForRedirectUrl: config.creds.allowHttpForRedirectUrl,
clientSecret: config.creds.clientSecret,
validateIssuer: config.creds.validateIssuer,
isB2C: config.creds.isB2C,
issuer: config.creds.issuer,
passReqToCallback: config.creds.passReqToCallback,
scope: config.creds.scope,
loggingLevel: config.creds.loggingLevel,
nonceLifetime: config.creds.nonceLifetime,
nonceMaxAmount: config.creds.nonceMaxAmount,
useCookieInsteadOfSession: config.creds.useCookieInsteadOfSession,
cookieEncryptionKeys: config.creds.cookieEncryptionKeys,
clockSkew: config.creds.clockSkew,
},
async (accessToken, refreshToken, profile, done) => {
console.log('auth: ', profile)
const newUser = {
microsoftId: profile.oid,
displayName: profile.displayName,
}

try {
let user = await User.findOne({ microsoftId: profile.oid })

if (user) {
done(null, user)
} else {
user = await User.create(newUser)
done(null, user)
}
} catch (err) {
console.error(err)
}
}
)
)

passport.serializeUser((user, done) => {
//export to server.js
module.exports = function(passport) {
passport.use(new lstrat({
usernameField: 'email' //set up usernameField to be email field in inputs
}, async (email, password, done) => {
User.findOne({email: email.toLowerCase()}, async (err, user) => {
if(err) {return done(err);} //return callback with error only
if(!user) {
return done(null, false, {msg: 'user does not exist'});
//return callback with null error, !user, and error message
}
try {
if(await bcrypt.compare(password, user.password)) {
return done(null, user);
}
else {
return done(null, false, {msg: 'invalid password'})
}
} catch(e) {
return done(e);
}
})
}))
passport.serializeUser((user, done) => {
done(null, user.id)
})

passport.deserializeUser((id, done) => {
User.findById(id, (err, user) => done(err, user))
})
}
}
41 changes: 40 additions & 1 deletion controllers/home.js
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,5 +1,44 @@
const userPostsdb = require('../models/UserPost')

module.exports = {
getIndex: (req,res)=>{
res.render('index.ejs')
res.render('index.ejs')
},
getDashboard: async (req,res) => {
try{
let allPosts = await userPostsdb.find();
allPosts = allPosts.reverse();
res.render('dashboard.ejs', {userPosts: allPosts})
}catch(err){
console.log(err)
}
},
getProfile: async (req, res) => {
try {
const userPosts = await userPostsdb.find({username:req.user.username});
//.filter(el => el.username == req.user.username);
// console.log(userPosts)
res.render('profile', {
userPosts,
username: req.user.username,
other: false
})
} catch(err) {
console.log(err)
}
},
getOtherProfile: async (req, res) => {
try {
const userPosts = await userPostsdb.find({username:req.params.username});
//.filter(el => el.username == req.user.username);
// console.log(userPosts)
res.render('profile', {
userPosts,
username: req.params.username,
other: true
})
} catch(err) {
console.error(err);
}
}
}
31 changes: 31 additions & 0 deletions controllers/loginCont.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const validator = require('validator');
const passport = require('passport');
const User = require('../models/User');

module.exports = {
getPage: async (req, res) => {
res.render('login', {msg: 'none'});
},
postLogin: async (req, res, next) => {
const errors = [];
if(!validator.isEmail(req.body.email)) errors.push({msg: 'email is invalid'});
if(validator.isEmpty(req.body.password)) errors.push({msg: 'password field cant be blank'});

if(errors.length) {
req.flash('errors', errors);
return res.redirect('/login');
}
req.body.email = validator.normalizeEmail(req.body.email, { gmail_remove_dots: false });
passport.authenticate('local', (err, user, info) => {
if(err) return next(err);
if(!user) {
req.flash('errors', info);
return res.redirect('/login');
}
req.logIn(user, (err) => {
if(err) return next(err);
res.redirect(req.session.returnTo || '/dashboard')
})
})(req, res, next)
}
}
61 changes: 61 additions & 0 deletions controllers/signCont.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
const passport = require('passport');
const User = require('../models/User');
const validator = require('validator');
const bcrypt = require('bcrypt');

module.exports = {
getPage: async (req, res) => {
res.render('signup', {msg: 'none'});
},
postUser: async (req, res, next) => {
const errors = [];
if(!validator.isEmail(req.body.email)) {
errors.push({msg: 'not a valid email for reg'});
}
if(!validator.isLength(req.body.password, {min: 0})) {
errors.push({msg: 'password must be at least 8 chars long'});
}
if(req.body.password !== req.body.confirmPassword) {
errors.push({msg: 'passwords do not match'});
}
if(errors.length) {
req.flash('errors', errors);
return res.redirect('../signup');
}
req.body.email = validator.normalizeEmail(req.body.email, {gmail_remove_dots: false});
const hashPass = await bcrypt.hash(req.body.password, 10);
const user = new User({
username: req.body.username,
email: req.body.email,
password: hashPass
}
)
User.findOne({$or: [
{username: req.body.username},
{email: req.body.email}
]}, (err, doc) => {
if(err) return next(err);
if(doc) {
req.flash('errors', {msg: 'an account with that email/username already exists'});
return res.redirect('../signup')
}
user.save((err) => {
if (err) { return next(err) }
req.logIn(user, (err) => {
if (err) {
return next(err)
}
res.redirect('/dashboard')
})
})
})
},
logout:(req, res) => {
req.logout()
req.session.destroy((err) => {
if (err) console.log('Error : Failed to destroy the session during logout.', err)
req.user = null
res.redirect('/')
})
}
}
57 changes: 0 additions & 57 deletions controllers/todos.js

This file was deleted.

Loading