Merge pull request #2 from Braeden57/editor

Add Editor page to edit accounts (currently Student only)
This commit is contained in:
Braeden Sowinski authored and GitHub committed 2020-12-04 10:12:38 -08:00
commit a117e7e082
11 files changed
+339 -31

No files matched your search

+6 -7
View File
@@ -1,13 +1,12 @@
// Import required libraries
const express = require('express'); const express = require('express');
const expressLayouts = require('express-ejs-layouts'); const expressLayouts = require('express-ejs-layouts');
const mongoose = require('mongoose'); const mongoose = require('mongoose');
const passport = require('passport'); const passport = require('passport');
const flash = require('connect-flash'); const flash = require('connect-flash');
const session = require('express-session'); const session = require('express-session');
const fs = require('fs');
const bodyParser = require('body-parser'); const bodyParser = require('body-parser');
const path = require('path'); var path = require('path');
var fs = require('fs');
require('dotenv/config'); require('dotenv/config');
const app = express(); const app = express();
@@ -19,9 +18,10 @@ require('./config/passport')(passport);
const db = require('./config/keys').mongoURI; const db = require('./config/keys').mongoURI;
// Connect to MongoDB // Connect to MongoDB
mongoose.connect( mongoose
.connect(
db, db,
{ useNewUrlParser: true ,useUnifiedTopology: true} { useNewUrlParser: true, useUnifiedTopology: true}
) )
.then(() => console.log('MongoDB Connected')) .then(() => console.log('MongoDB Connected'))
.catch(err => console.log(err)); .catch(err => console.log(err));
@@ -30,7 +30,7 @@ mongoose.connect(
app.use(expressLayouts); app.use(expressLayouts);
app.set('view engine', 'ejs'); app.set('view engine', 'ejs');
// Body parser // Body Parser
app.use(bodyParser.urlencoded({ extended: false })) app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json()) app.use(bodyParser.json())
@@ -64,5 +64,4 @@ app.use('/users', require('./routes/users.js'));
const PORT = process.env.PORT || 5000; const PORT = process.env.PORT || 5000;
// Start Server
app.listen(PORT, console.log(`Server started on port ${PORT}`)); app.listen(PORT, console.log(`Server started on port ${PORT}`));
+11
View File
@@ -0,0 +1,11 @@
const fs = require('fs');
const path = require('../routes/users.js').path;
let image = {
data: fs.readFileSync(path),
contentType: "image/png"
}
module.exports = {
defaultImage: image
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

+246 -7
View File
@@ -3,15 +3,19 @@ const express = require('express');
const router = express.Router(); const router = express.Router();
const bcrypt = require('bcryptjs'); const bcrypt = require('bcryptjs');
const passport = require('passport'); const passport = require('passport');
const ObjectID = require('mongodb').ObjectID; const MongoClient = require('mongodb').MongoClient;
const ObjectId = require('mongodb').ObjectId;
// Load User model // Load User model
const User = require('../models/User'); const User = require('../models/User');
const { forwardAuthenticated } = require('../config/auth'); const { forwardAuthenticated } = require('../config/auth');
// DB Config
const db = require('../config/keys').mongoURI;
// Loads libraries for uploading img functions // Loads libraries for uploading img functions
const fs = require('fs'); let fs = require('fs');
const path = require('path'); let path = require('path');
const multer = require('multer'); let multer = require('multer');
let storage = multer.diskStorage({ let storage = multer.diskStorage({
destination: (req, file, cb) => { destination: (req, file, cb) => {
@@ -30,8 +34,211 @@ router.get('/login', forwardAuthenticated, (req, res) => res.render('login'));
// Register Page // Register Page
router.get('/register', forwardAuthenticated, (req, res) => res.render('register')); router.get('/register', forwardAuthenticated, (req, res) => res.render('register'));
// Edit page
router.get('/edit', (req, res) => res.render('edit'));
// Edit
router.post('/edit', upload.single('image'), (req, res, next) => {
// Passes image path to defaultImage Model
imagePath = __dirname + '/uploads/image-1606947471396';
module.exports = {
path: imagePath
}
// Gets inputs
const { _id, name, newPassword, newPassword2 } = req.body;
let errors = [];
let useName = true;
let useNewPassword = true;
if (!name) {
useName = false;
}
if (!newPassword) {
if (newPassword2.length > 0) {
errors.push({ msg: 'You need to enter your new password' })
}
if (!newPassword2) {
useNewPassword = false;
}
}
if (newPassword.length > 0) {
if (!newPassword2) {
errors.push({ msg: 'Confirm new Password' })
}
// Checks if new password & new password confirm match
if (newPassword != newPassword2) {
errors.push({ msg: 'New Passwords do not match' });
}
// Validates new password is required lenght
if (newPassword.length < 6) {
errors.push({ msg: 'Password must be at least 6 characters' });
}
}
// Error Handling
if (errors.length > 0) {
// Redirects to edit page with errors
res.render('edit', {
errors,
name,
currPassword,
newPassword,
newPassword2
});
} else {
let hashPass;
let updated;
let defaultImage = require('../models/defaultImage').defaultImage;
try {
if (useName && useNewPassword) {
// Encrypts password
bcrypt.genSalt(10, (err, salt) => {
bcrypt.hash(newPassword, salt, (err, hash) => {
if (err) throw err;
hashPass = hash;
});
});
console.log(newPassword);
console.log(hashPass);
//creates updated image object
updated = {
name: name,
image: {
data: fs.readFileSync(path.join(__dirname + '/uploads/' + req.file.filename)),
contentType: 'image/png'
},
password: hashPass
}
}
if (useName) {
//creates updated image object
updated = {
name: name,
image: {
data: fs.readFileSync(path.join(__dirname + '/uploads/' + req.file.filename)),
contentType: 'image/png'
}
}
}
if (useNewPassword) {
//creates updated image object
updated = {
image: {
data: fs.readFileSync(path.join(__dirname + '/uploads/' + req.file.filename)),
contentType: 'image/png'
},
password: hashPass
}
}
if (!useName && !useNewPassword) {
//creates updated image object
updated = {
image: {
data: fs.readFileSync(path.join(__dirname + '/uploads/' + req.file.filename)),
contentType: 'image/png'
}
}
}
//Updates user and redirects to dashboard
MongoClient.connect(db, {
useUnifiedTopology: true,
useNewUrlParser: true}, function(err, db) {
if (err) throw err;
let dbo = db.db("XPmockDB");
dbo.collection('users').updateOne({ _id: ObjectId(_id) }, { $set: updated }, { upsert: true }, function(err, res) {
if (err) throw err;
console.log('1 Document Updated');
console.log('With customImage');
db.close()
});
res.redirect('/users/login');
}
);
}
catch(err) {
console.log(err);
if (useName && useNewPassword) {
// Encrypts password
bcrypt.genSalt(10, (err, salt) => {
bcrypt.hash(newPassword, salt, (err, hash) => {
if (err) throw err;
hashPass = hash;
});
});
console.log(newPassword);
console.log(hashPass);
//creates updated image object
updated = {
name: name,
image: defaultImage,
password: hashPass
}
}
if (useName) {
//creates updated image object
updated = {
name: name,
image: defaultImage
}
}
if (useNewPassword) {
//creates updated image object
updated = {
image: defaultImage,
password: hashPass
}
}
if (!useName && !useNewPassword) {
//creates updated image object
updated = {
image: defaultImage
}
}
//Updates user and redirects to dashboard
MongoClient.connect(db, {
useUnifiedTopology: true,
useNewUrlParser: true}, function(err, db) {
if (err) throw err;
let dbo = db.db("XPmockDB");
dbo.collection('users').updateOne({ _id: ObjectId(_id) }, { $set: updated }, { upsert: true }, function(err, res) {
if (err) throw err;
console.log('1 Document Updated');
console.log('With defaultImage');
db.close()
});
res.flash('Success')
res.redirect('/users/login');
}
);
}
}
});
// Register // Register
router.post('/register', upload.single('image'), (req, res, next) => { router.post('/register', upload.single('image'), (req, res, next) => {
// Passes image path to defaultImage Model
path = __dirname + '/uploads/image-1606947471396';
module.exports = {
path: path
}
// Collects input // Collects input
const { name, email, password, password2 } = req.body; const { name, email, password, password2 } = req.body;
let errors = []; let errors = [];
@@ -75,15 +282,17 @@ router.post('/register', upload.single('image'), (req, res, next) => {
password2 password2
}); });
} else { } else {
try {
// Creates new User Object // Creates new User Object
const newUser = new User({ const newUser = new User({
name, name,
email,
password,
image: { image: {
data: fs.readFileSync(path.join(__dirname + '/uploads/' + req.file.filename)), data: fs.readFileSync(path.join(__dirname + '/uploads/' + req.file.filename)),
contentType: 'image/png' contentType: 'image/png'
}, }
email,
password,
}); });
// Encrypts password // Encrypts password
@@ -105,6 +314,36 @@ router.post('/register', upload.single('image'), (req, res, next) => {
}); });
}); });
} }
catch(err) {
const defaultImage = require('../models/defaultImage').defaultImage;
// Creates new User Object
const newUser = new User({
name,
email,
password,
image: defaultImage
});
// Encrypts password
bcrypt.genSalt(10, (err, salt) => {
bcrypt.hash(newUser.password, salt, (err, hash) => {
if (err) throw err;
newUser.password = hash;
newUser
.save()
.then(user => {
req.flash(
'success_msg',
'You are now registered and can log in'
);
// Takes to login page on success
res.redirect('/users/login');
})
.catch(err => console.log(err));
});
});
}
}
}); });
} }
}); });
+67
View File
@@ -0,0 +1,67 @@
<div class="row mt-5">
<div class="col-md-6 m-auto">
<div class="card card-body">
<h1 class="text-center mb-3">
<i class="fas fa-user-plus"></i> Edit Account
</h1>
<% include ./partials/messages %>
<form action="/users/edit" method="POST" enctype="multipart/form-data">
<!-- Catching _id -->
<script>
window.onload = function () {
var url = document.location.href,
params = url.split('?')[1].split('&'),
data = {}, tmp;
for (var i = 0, l = params.length; i < l; i++) {
tmp = params[i].split('=');
data[tmp[0]] = tmp[1];
}
document.getElementById('_id').value = data.name;
}
</script>
<input id='_id' type='text' name='_id' value='' style='display: none'></input>
<div class="form-group">
<label for="name">Name</label>
<input
type="name"
id="name"
name="name"
class="form-control"
placeholder="Enter Name"
value="<%= typeof name != 'undefined' ? name : '' %>"
/>
</div>
<div class='form-group'>
<label for='image'>Upload Profile Picture</label>
<input class='form-control' type="file" id="image" name="image" value="">
</div>
<div class="form-group">
<label for="password2">New Password</label>
<input
type="password"
id="newPassword"
name="newPassword"
class="form-control"
placeholder="New Password"
value="<%= typeof password2 != 'undefined' ? password2 : '' %>"
/>
</div>
<div class="form-group">
<label for="password2">Confirm New Password</label>
<input
type="password"
id="newPassword2"
name="newPassword2"
class="form-control"
placeholder="Confirm New Password"
value="<%= typeof password2 != 'undefined' ? password2 : '' %>"
/>
</div>
<button type="submit" class="btn btn-primary btn-block">
Save Changes
</button>
</form>
</div>
</div>
</div>
+4
View File
@@ -21,6 +21,10 @@
<label for='image'>Upload Profile Picture</label> <label for='image'>Upload Profile Picture</label>
<input class='form-control' type="file" id="image" name="image" value="" required> <input class='form-control' type="file" id="image" name="image" value="" required>
</div> </div>
<div class="form-group">
<label for='image'>Upload Profile Picture</label>
<input class="form-control-file" type="file" id="image" name="image" value="">
</div>
<div class="form-group"> <div class="form-group">
<label for="email">Email</label> <label for="email">Email</label>
<input <input
+4 -3
View File
@@ -20,9 +20,9 @@
#pro-pic { #pro-pic {
position: absolute; position: absolute;
top: 24px; margin: 27px;
left: 24px; width: 90px;
width: 100px; height: 90px;
display: block; display: block;
border-radius: 50px; border-radius: 50px;
} }
@@ -52,6 +52,7 @@
<!-- Action Buttons --> <!-- Action Buttons -->
<a href="/users/logout" class="btn btn-secondary">Logout</a> <a href="/users/logout" class="btn btn-secondary">Logout</a>
<button onClick='passData()' class='btn btn-secondary'>Edit</button>
<!-- Passing user _id to edit page script --> <!-- Passing user _id to edit page script -->
<script> <script>
+1 -14
View File
@@ -4,15 +4,12 @@
width: 230px; width: 230px;
display: inline-block; display: inline-block;
} }
.head { .head {
margin-bottom: 100px; margin-bottom: 100px;
} }
#teacher-container { #teacher-container {
position: relative; position: relative;
} }
#pro-pic { #pro-pic {
position: absolute; position: absolute;
top: 0px; top: 0px;
@@ -23,18 +20,17 @@
border: 1px solid black; border: 1px solid black;
margin:5px; margin:5px;
} }
#user-pro-pic { #user-pro-pic {
position: absolute; position: absolute;
top: 0px; top: 0px;
left: 150px; left: 150px;
width: 50px; width: 50px;
height: 50px;
display: block; display: block;
border-radius: 50px; border-radius: 50px;
border: 1px solid black; border: 1px solid black;
margin:5px; margin:5px;
} }
#logout-btn { #logout-btn {
position: absolute; position: absolute;
top: 0px; top: 0px;
@@ -45,41 +41,34 @@
left: 115px; left: 115px;
top: 60px; top: 60px;
} }
h2 { h2 {
font: 350 35px/1.5 Helvetica, Verdana, sans-serif; font: 350 35px/1.5 Helvetica, Verdana, sans-serif;
margin: 0; margin: 0;
padding: 0; padding: 0;
} }
ul { ul {
list-style-type: none; list-style-type: none;
margin: 0; margin: 0;
padding: 0; padding: 0;
} }
li { li {
font: 200 20px/1.5 Helvetica, Verdana, sans-serif; font: 200 20px/1.5 Helvetica, Verdana, sans-serif;
border-bottom: 1px solid #ccc; border-bottom: 1px solid #ccc;
} }
li:last-child { li:last-child {
border: none; border: none;
} }
li a { li a {
text-decoration: none; text-decoration: none;
color: #000; color: #000;
display: block; display: block;
width: 200px; width: 200px;
-webkit-transition: font-size 0.3s ease, background-color 0.3s ease; -webkit-transition: font-size 0.3s ease, background-color 0.3s ease;
-moz-transition: font-size 0.3s ease, background-color 0.3s ease; -moz-transition: font-size 0.3s ease, background-color 0.3s ease;
-o-transition: font-size 0.3s ease, background-color 0.3s ease; -o-transition: font-size 0.3s ease, background-color 0.3s ease;
-ms-transition: font-size 0.3s ease, background-color 0.3s ease; -ms-transition: font-size 0.3s ease, background-color 0.3s ease;
transition: font-size 0.3s ease, background-color 0.3s ease; transition: font-size 0.3s ease, background-color 0.3s ease;
} }
li a:hover { li a:hover {
font-size: 30px; font-size: 30px;
background: #f6f6f6; background: #f6f6f6;
@@ -156,7 +145,6 @@
<!-- Calculates user specific Rank --> <!-- Calculates user specific Rank -->
<script> <script>
xp = <%= member.xp %>; xp = <%= member.xp %>;
// Get current rank // Get current rank
if (xp == 0) { if (xp == 0) {
currRank = 'Digital Noob'; currRank = 'Digital Noob';
@@ -181,7 +169,6 @@
// Display Rank // Display Rank
document.getElementById('userRank-<%= member.id %>').innerHTML = currRank; document.getElementById('userRank-<%= member.id %>').innerHTML = currRank;
</script> </script>
</div> </div>
<% } %> <% } %>