Personal blog written from scratch using Node.js, Bootstrap, and MySQL. https://jrtechs.net
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

260 lines
7.5 KiB

  1. const mysql = require('mysql');
  2. const sanitizer = require('sanitizer');
  3. const Promise = require('promise');
  4. const crypto = require('crypto');
  5. const qs = require('querystring');
  6. const utils = require('../utils/utils.js');
  7. var con = mysql.createConnection({
  8. host: "localhost",
  9. user: "blog_user",
  10. password: utils.getFileLine('../sql_secret'),
  11. database: "jrtechs_blog"
  12. });
  13. con.connect(function(err) {
  14. if (err) throw err;
  15. });
  16. /**
  17. * Function used to query the database for records
  18. *
  19. * @param sqlStatement
  20. * @returns {Array}
  21. */
  22. var fetch = function(sqlStatement)
  23. {
  24. return new Promise(function(resolve, reject)
  25. {
  26. con.query(sqlStatement, function (err, result)
  27. {
  28. if(err)
  29. {
  30. reject();
  31. }
  32. resolve(result);
  33. });
  34. });
  35. };
  36. module.exports=
  37. {
  38. /**
  39. * Function used to use insert statements into the database
  40. *
  41. * Don't worry, the input gets sanitized
  42. *
  43. * @param sqlStatement
  44. * @return the id of the new record - if there is one
  45. */
  46. insert : function(sqlStatement)
  47. {
  48. return new Promise(function(resolve, reject)
  49. {
  50. con.query(sanitizer.sanitize(sqlStatement), function (err, result)
  51. {
  52. if (err)
  53. {
  54. console.log(err);
  55. resolve(0);
  56. }
  57. resolve(result.insertId);
  58. });
  59. })
  60. },
  61. /**
  62. * Not to be mistaken for getPostData() in @file utils/utils.js,
  63. * this function extracts a post entry from the sql server
  64. *
  65. * @param requestURL url user used to request blog post
  66. * @return {*} the entry found in the data base -- if any
  67. */
  68. getPost : function(requestURL)
  69. {
  70. return new Promise(function(resolve, reject)
  71. {
  72. var splitURL = requestURL.split("/")
  73. var q = "select * from categories where url='" + splitURL[1] + "'";
  74. fetch(q).then(function (result_category)
  75. {
  76. if(result_category.length != 0)
  77. {
  78. var q2 = "select * from posts where category_id='" + result_category[0].category_id +
  79. "' and url='" + splitURL[2] + "'";
  80. fetch(q2).then(function (result_posts)
  81. {
  82. if(result_posts != 0)
  83. {
  84. resolve(result_posts[0]);
  85. }
  86. else
  87. {
  88. resolve(0);
  89. }
  90. });
  91. }
  92. else
  93. {
  94. resolve(0);
  95. }
  96. });
  97. });
  98. },
  99. /**
  100. * Function used to retrieve all categories when making the sidebar
  101. *
  102. * @return {Promise<Response> | * | Array}
  103. */
  104. getCategories : function()
  105. {
  106. var q = "select * from categories";
  107. return fetch(q);
  108. },
  109. /**
  110. * Function which currently returns all posts of a particular category from the database
  111. * @param requestURL
  112. * @return {*|Promise}
  113. */
  114. getPostsFromCategory: function(requestURL)
  115. {
  116. return new Promise(function(resolve, reject)
  117. {
  118. var q = "select * from categories where name ='" + requestURL + "' limit 1";
  119. fetch(q).then(function(categories)
  120. {
  121. if(categories.length != 0)
  122. {
  123. var qPosts = "select * from posts where category_id='" + categories[0].category_id + "'";
  124. resolve(fetch(qPosts));
  125. }
  126. else
  127. {
  128. resolve([]);
  129. }
  130. });
  131. });
  132. },
  133. /**
  134. * Helper method which returns a list of objects which contains the url and name of thee ten most recent posts
  135. *
  136. * {[name: , url: ],[name: , url: ],[name: , url: ],...}
  137. *
  138. * @return {*|Promise}
  139. */
  140. getRecentPosts: function()
  141. {
  142. return new Promise(function(resolve, reject)
  143. {
  144. var q = "select name,url, category_id from posts order by post_id desc limit 10";
  145. fetch(q).then(function(sqlPosts)
  146. {
  147. var promises = [];
  148. sqlPosts.forEach(function(post)
  149. {
  150. promises.push(new Promise(function(res, rej)
  151. {
  152. var getCategory = "select url from categories where category_id='" + post.category_id + "'";
  153. fetch(getCategory).then(function(urls)
  154. {
  155. var obj = new Object();
  156. obj.name = post.name;
  157. obj.url = post.url;
  158. obj.category = urls[0].url;
  159. res(obj);
  160. });
  161. }));
  162. });
  163. Promise.all(promises).then(function(goodies)
  164. {
  165. resolve(goodies);
  166. });
  167. });
  168. });
  169. },
  170. getPopularPosts: function()
  171. {
  172. return new Promise(function(resolve, reject)
  173. {
  174. var q = "select * from popular_posts";
  175. fetch(q).then(function(sqlPosts)
  176. {
  177. });
  178. });
  179. },
  180. /**
  181. * Function which checks to see if a user successfully logged in based on
  182. * the post data which they sent
  183. *
  184. * @param postData the post data
  185. * @return {*|Promise} a json object with {pass: , user: }
  186. * the pass is whether or not they logged in successfully and the user is
  187. * the username they successfully logged in with
  188. */
  189. checkLogin: function(postData)
  190. {
  191. var post = qs.parse(postData);
  192. return new Promise(function(resolve, reject)
  193. {
  194. var result = Object();
  195. result.pass = false;
  196. if(post.username && post.password)
  197. {
  198. var cleanName = sanitizer.sanitize(post.username);
  199. var cleanPassword = sanitizer.sanitize(post.password);
  200. var getSalt = "select * from users where user_name='" + cleanName + "'";
  201. fetch(getSalt).then(function(saltResult)
  202. {
  203. if(saltResult.length == 1)
  204. {
  205. var hashedPassword = crypto.createHash('sha256')
  206. .update(cleanPassword + saltResult[0].salt)
  207. .digest('hex');
  208. if(saltResult[0].password === hashedPassword)
  209. {
  210. //yay!
  211. result.pass = true;
  212. result.user = cleanName;
  213. resolve(result);
  214. }
  215. else
  216. {
  217. //wrong password
  218. resolve(result)
  219. }
  220. }
  221. else
  222. {
  223. //incorrect username
  224. resolve(result);
  225. }
  226. })
  227. }
  228. else
  229. {
  230. //no login attempts were made
  231. resolve(result);
  232. }
  233. });
  234. },
  235. getCategory: function(categoryId)
  236. {
  237. return fetch("select * from categories where category_id='" + categoryId + "'");
  238. }
  239. };