Added email subjects, and favourites
This commit is contained in:
@@ -34,6 +34,8 @@ Emails are stored in the [`templates`](https://github.com/jslightham/kno-logic-a
|
||||
|
||||
Any portion of the message can be replaced when sending the email. The convention used in all default email templates is `%replace_string%`. The replace string does not matter since when calling the sendMail function, replacements is an array of data with the form `{from: "%replace_string%", to: "Username"}`.
|
||||
|
||||
Email subjects are the first line of the file, which are removed from the email body.
|
||||
|
||||
## Configuration
|
||||
Configuration for the application is done in the [`config.js`](https://github.com/jslightham/kno-logic-api/blob/main/config.js) file.
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ categoryRoutes.route('/create').post((req, res) => {
|
||||
res.json(c);
|
||||
})
|
||||
.catch((e) => {
|
||||
console.log(e);
|
||||
console.error(e);
|
||||
res.status(500).send("Error creating category");
|
||||
});
|
||||
} else {
|
||||
@@ -46,7 +46,7 @@ categoryRoutes.route('/create').post((req, res) => {
|
||||
categoryRoutes.route('/all').get((req, res) => {
|
||||
Category.find({}, (err, cArr) => {
|
||||
if (err) {
|
||||
console.log(err);
|
||||
console.error(err);
|
||||
res.status(500).send("Error getting categories");
|
||||
return;
|
||||
}
|
||||
@@ -62,7 +62,7 @@ categoryRoutes.route('/all').get((req, res) => {
|
||||
categoryRoutes.route('/posts').get((req, res) => {
|
||||
Post.find({}, (err, postArr) => {
|
||||
if (err) {
|
||||
console.log(err);
|
||||
console.error(err);
|
||||
res.status(500).send("Error getting posts");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3,11 +3,11 @@ var config = {};
|
||||
// Mailer settings
|
||||
config.mail = {};
|
||||
config.mail.host = "localhost";
|
||||
config.mail.port = "465";
|
||||
config.mail.port = "587";
|
||||
config.mail.secure = false;
|
||||
config.mail.user = "username";
|
||||
config.mail.pass = "pass";
|
||||
config.mail.from = "<noreply@knologic.com>"
|
||||
config.mail.user = "email";
|
||||
config.mail.pass = "password";
|
||||
config.mail.from = "name"
|
||||
|
||||
// Session purge settings
|
||||
config.maxSessionLength = 30;
|
||||
|
||||
4
index.js
4
index.js
@@ -10,6 +10,7 @@ const config = require('./DB.js');
|
||||
const userRoutes = require('./user.route');
|
||||
const postRoutes = require('./post.route');
|
||||
const categoryRoutes = require('./category.route');
|
||||
const mongoSanitize = require('express-mongo-sanitize');
|
||||
|
||||
console.log("Starting Kno-Logic Backend Server");
|
||||
|
||||
@@ -32,6 +33,9 @@ app.use(cors());
|
||||
app.use(express.urlencoded({ extended: true }))
|
||||
app.use(express.json());
|
||||
|
||||
// Sanitize data to prevent NoSQL injections
|
||||
app.use(mongoSanitize());
|
||||
|
||||
// Express routes
|
||||
app.use('/user', userRoutes);
|
||||
app.use('/post', postRoutes);
|
||||
|
||||
5
package-lock.json
generated
5
package-lock.json
generated
@@ -622,6 +622,11 @@
|
||||
"vary": "~1.1.2"
|
||||
}
|
||||
},
|
||||
"express-mongo-sanitize": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/express-mongo-sanitize/-/express-mongo-sanitize-2.1.0.tgz",
|
||||
"integrity": "sha512-ELGeH/Tx+kJGn3klCzSmOewfN1ezJQrkqzq83dl/K3xhd5PUbvLtiD5CiuYRmQfoZPL4rUEVjANf/YjE2BpTWQ=="
|
||||
},
|
||||
"fill-range": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
"cors": "^2.8.5",
|
||||
"cron": "^1.8.2",
|
||||
"express": "^4.17.1",
|
||||
"express-mongo-sanitize": "^2.1.0",
|
||||
"log-timestamp": "^0.3.0",
|
||||
"mongoose": "^5.12.7",
|
||||
"nodemailer": "^6.6.0"
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
Kno-Logic Password Reset
|
||||
Hello %name%,
|
||||
|
||||
Someone has requested a password reset for the account connected to your email.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
Welcome to Kno-Logic!
|
||||
Hello %name%,
|
||||
|
||||
Welcome to kno-logic!
|
||||
Welcome to the kno-logic app. Thank you for...
|
||||
@@ -14,6 +14,9 @@ let User = new Schema({
|
||||
},
|
||||
permission: {
|
||||
type: Number
|
||||
},
|
||||
favorites: {
|
||||
type: Array
|
||||
}
|
||||
}, {
|
||||
collection: 'users'
|
||||
|
||||
107
user.route.js
107
user.route.js
@@ -8,6 +8,7 @@ const sessionLength = 25;
|
||||
|
||||
let Session = require('./session.model');
|
||||
let User = require('./user.model');
|
||||
let Post = require('./post.model');
|
||||
|
||||
/*
|
||||
POST - /user/create
|
||||
@@ -26,19 +27,16 @@ userRoutes.route('/create').post((req, res) => {
|
||||
res.status(401).send("Empty fields");
|
||||
return;
|
||||
}
|
||||
console.log(req.body);
|
||||
let u = new User(req.body);
|
||||
// TODO: Look for a different encryption method that can scale more easily
|
||||
bcrypt.hash(u.password, saltRounds, (err, hash) => {
|
||||
if (err) {
|
||||
console.log(err);
|
||||
console.error(err);
|
||||
res.status(500).send("Error creating user");;
|
||||
} else {
|
||||
console.log(hash);
|
||||
u.password = hash;
|
||||
User.find({ email: u.email }, (err, arr) => {
|
||||
if (err) {
|
||||
console.log(err);
|
||||
console.error(err);
|
||||
res.status(500).send("Error creating user");
|
||||
}
|
||||
// Account already exists
|
||||
@@ -67,7 +65,6 @@ userRoutes.route('/create').post((req, res) => {
|
||||
401 - Incorrect
|
||||
*/
|
||||
userRoutes.route('/login').post((req, res) => {
|
||||
console.log(req.body);
|
||||
if (!req.body) {
|
||||
res.status(401).send("Missing body");
|
||||
return;
|
||||
@@ -80,7 +77,7 @@ userRoutes.route('/login').post((req, res) => {
|
||||
}
|
||||
User.findOne({ email: req.body.email }, (err, u) => {
|
||||
if (err) {
|
||||
console.log(err);
|
||||
console.error(err);
|
||||
res.status(500).send("Error logging in user");
|
||||
return;
|
||||
}
|
||||
@@ -92,7 +89,7 @@ userRoutes.route('/login').post((req, res) => {
|
||||
|
||||
bcrypt.compare(req.body.password, u.password, (err, result) => {
|
||||
if (err) {
|
||||
console.log(err);
|
||||
console.error(err);
|
||||
res.status(500).send("Error logging in user");
|
||||
return;
|
||||
}
|
||||
@@ -127,7 +124,7 @@ userRoutes.route('/login').post((req, res) => {
|
||||
userRoutes.route('/logout').post((req, res) => {
|
||||
Session.findOne({ sessionId: req.body.sessionId }, (err, sess) => {
|
||||
if (err) {
|
||||
console.log(err);
|
||||
console.error(err);
|
||||
res.status(500).send("Error logging out");
|
||||
return;
|
||||
}
|
||||
@@ -141,7 +138,8 @@ userRoutes.route('/logout').post((req, res) => {
|
||||
.then(() => {
|
||||
res.status(201).send("Success deleting session");
|
||||
})
|
||||
.catch(() => {
|
||||
.catch((e) => {
|
||||
console.error(e);
|
||||
res.status(500).send("Error logging out");
|
||||
});
|
||||
|
||||
@@ -150,6 +148,95 @@ userRoutes.route('/logout').post((req, res) => {
|
||||
|
||||
// TODO: Add forgotten password route
|
||||
|
||||
/*
|
||||
POST - /user/favorite/add
|
||||
Add a favorite article
|
||||
Response: 200 - OK
|
||||
401 - Unauthorized
|
||||
*/
|
||||
userRoutes.route('/favorite/add').post((req, res) => {
|
||||
utils.checkSession(req.body.userId, req.body.sessionId, valid => {
|
||||
if (valid) {
|
||||
User.findById(req.body.userId, (err, user) => {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
res.status(500).send("Error adding article");
|
||||
return;
|
||||
}
|
||||
user.favorites.push(req.body.postId);
|
||||
user.save()
|
||||
.then(() => {
|
||||
res.status(201).send("Success saving article");
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error(e);
|
||||
res.status(500).send("Error saving article");
|
||||
});
|
||||
})
|
||||
} else {
|
||||
res.status(401).send("Unauthorized");
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
/*
|
||||
POST - /user/favorite/remove
|
||||
Remove a favorite article
|
||||
Response: 200 - OK
|
||||
401 - Unauthorized
|
||||
*/
|
||||
userRoutes.route('/favorite/remove').post((req, res) => {
|
||||
utils.checkSession(req.body.userId, req.body.sessionId, valid => {
|
||||
if (valid) {
|
||||
User.findById(req.body.userId, (err, user) => {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
res.status(500).send("Error removing article");
|
||||
return;
|
||||
}
|
||||
user.favorites = utils.removeValue(user.favorites, req.body.articleId);
|
||||
user.save()
|
||||
.then(() => {
|
||||
res.status(201).send("Success removing article");
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error(e);
|
||||
res.status(500).send("Error removing article");
|
||||
});
|
||||
})
|
||||
} else {
|
||||
res.status(401).send("Unauthorized");
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
/*
|
||||
POST - /user/favorite/get
|
||||
Get all favorite articles
|
||||
Response: 200 - OK
|
||||
401 - Unauthorized
|
||||
*/
|
||||
userRoutes.route('/favorite/get').post((req, res) => {
|
||||
utils.checkSession(req.body.userId, req.body.sessionId, valid => {
|
||||
if (valid) {
|
||||
User.findById(req.body.userId, (err, user) => {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
res.status(500).send("Error removing article");
|
||||
return;
|
||||
}
|
||||
console.log(user.favorites);
|
||||
Post.find({ '_id': { $in: user.favorites } }, (err, postArray) => {
|
||||
res.json(postArray);
|
||||
})
|
||||
})
|
||||
} else {
|
||||
res.status(401).send("Unauthorized");
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
module.exports = userRoutes;
|
||||
|
||||
function generateSession() {
|
||||
|
||||
20
utils.js
20
utils.js
@@ -43,8 +43,8 @@ const loadDefaultTemplates = () => {
|
||||
} else {
|
||||
let newMsg = Message();
|
||||
newMsg.name = name;
|
||||
newMsg.subject = "Email From Kno-Logic" //TODO: Should load these from config.js
|
||||
newMsg.body = data;
|
||||
newMsg.subject = data.substring(0, data.indexOf("\n"));
|
||||
newMsg.body = data.substring(data.indexOf("\n") + 1);
|
||||
newMsg.save()
|
||||
.then(() => {
|
||||
console.log("Loaded " + name + " message");
|
||||
@@ -74,15 +74,17 @@ const sendMail = async (user, message, replacements) => {
|
||||
pass: config.mail.pass,
|
||||
},
|
||||
});
|
||||
|
||||
Message.findOne({ name: message }, (err, message) => {
|
||||
let msgBody = message.body;
|
||||
|
||||
for (let i = 0; i < replacements.length; i++) {
|
||||
msgBody = msgBody.replace(replacements[i].from, replacements[i].to);
|
||||
}
|
||||
|
||||
console.log(message);
|
||||
|
||||
try {
|
||||
await transporter.sendMail({
|
||||
transporter.sendMail({
|
||||
from: config.mail.from,
|
||||
to: user.email,
|
||||
subject: message.subject,
|
||||
@@ -93,6 +95,7 @@ const sendMail = async (user, message, replacements) => {
|
||||
console.log("Error sending mail: ")
|
||||
console.error(error);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -130,9 +133,18 @@ function dateToEpoch(d) {
|
||||
}
|
||||
}
|
||||
|
||||
// removeValue(array, item) remove item from the array
|
||||
function removeValue(array, item) {
|
||||
var index = array.indexOf(item);
|
||||
if (index !== -1) {
|
||||
array.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports.purgeSessions = purgeSessions;
|
||||
module.exports.loadDefaultTemplates = loadDefaultTemplates;
|
||||
module.exports.sendMail = sendMail;
|
||||
module.exports.checkSession = checkSession;
|
||||
module.exports.isAdmin = isAdmin;
|
||||
module.exports.dateToEpoch = dateToEpoch;
|
||||
module.exports.removeValue = removeValue;
|
||||
|
||||
Reference in New Issue
Block a user