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.

281 lines
7.9 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='" +
  79. result_category[0].category_id +
  80. "' and url='" + splitURL[2] + "'";
  81. fetch(q2).then(function (result_posts)
  82. {
  83. if(result_posts != 0)
  84. {
  85. resolve(result_posts[0]);
  86. }
  87. else
  88. {
  89. resolve(0);
  90. }
  91. });
  92. }
  93. else
  94. {
  95. resolve(0);
  96. }
  97. });
  98. });
  99. },
  100. /**
  101. * Function used to retrieve all categories when making the sidebar
  102. *
  103. * @return {Promise<Response> | * | Array}
  104. */
  105. getCategories : function()
  106. {
  107. var q = "select * from categories";
  108. return fetch(q);
  109. },
  110. /**
  111. * Function which currently returns all posts of a particular
  112. * category from the database
  113. * @param requestURL
  114. * @return {*|Promise}
  115. */
  116. getPostsFromCategory: function(requestURL)
  117. {
  118. return new Promise(function(resolve, reject)
  119. {
  120. var q = "select * from categories where url ='" + requestURL + "'";
  121. fetch(q).then(function(categories)
  122. {
  123. if(categories.length != 0)
  124. {
  125. var qPosts = "select * from posts where category_id='" +
  126. categories[0].category_id + "' order by published desc";
  127. resolve(fetch(qPosts));
  128. }
  129. else
  130. {
  131. resolve([]);
  132. }
  133. });
  134. });
  135. },
  136. /**
  137. * Helper method which returns a list of objects which contains the url
  138. * and name of thee ten most recent posts
  139. *
  140. * {[name: , url: ],[name: , url: ],[name: , url: ],...}
  141. *
  142. * @return {*|Promise}
  143. */
  144. getRecentPosts: function()
  145. {
  146. return new Promise(function(resolve, reject)
  147. {
  148. var q = "select name,url, category_id from posts order " +
  149. "by post_id desc limit 10";
  150. fetch(q).then(function(sqlPosts)
  151. {
  152. var promises = [];
  153. sqlPosts.forEach(function(post)
  154. {
  155. promises.push(new Promise(function(res, rej)
  156. {
  157. var getCategory = "select url from categories where " +
  158. "category_id='" + post.category_id + "'";
  159. fetch(getCategory).then(function(urls)
  160. {
  161. var obj = new Object();
  162. obj.name = post.name;
  163. obj.url = post.url;
  164. obj.category = urls[0].url;
  165. res(obj);
  166. });
  167. }));
  168. });
  169. Promise.all(promises).then(function(goodies)
  170. {
  171. resolve(goodies);
  172. });
  173. });
  174. });
  175. },
  176. getPopularPosts: function()
  177. {
  178. return new Promise(function(resolve, reject)
  179. {
  180. var q = "select * from popular_posts";
  181. fetch(q).then(function(sqlPosts)
  182. {
  183. });
  184. });
  185. },
  186. /**
  187. * Function which checks to see if a user successfully logged in based on
  188. * the post data which they sent
  189. *
  190. * @param postData the post data
  191. * @return {*|Promise} a json object with {pass: , user: }
  192. * the pass is whether or not they logged in successfully and the user is
  193. * the username they successfully logged in with
  194. */
  195. checkLogin: function(postData)
  196. {
  197. var post = qs.parse(postData);
  198. return new Promise(function(resolve, reject)
  199. {
  200. var result = Object();
  201. result.pass = false;
  202. if(post.username && post.password)
  203. {
  204. var cleanName = sanitizer.sanitize(post.username);
  205. var cleanPassword = sanitizer.sanitize(post.password);
  206. var getSalt = "select * from users where user_name='" +
  207. cleanName + "'";
  208. fetch(getSalt).then(function(saltResult)
  209. {
  210. if(saltResult.length == 1)
  211. {
  212. var hashedPassword = crypto.createHash('sha256')
  213. .update(cleanPassword + saltResult[0].salt)
  214. .digest('hex');
  215. if(saltResult[0].password === hashedPassword)
  216. {
  217. result.pass = true;
  218. result.user = cleanName;
  219. resolve(result);
  220. }
  221. else
  222. {
  223. resolve(result)
  224. }
  225. }
  226. else
  227. {
  228. //incorrect username
  229. resolve(result);
  230. }
  231. })
  232. }
  233. else
  234. {
  235. //no login attempts were made
  236. resolve(result);
  237. }
  238. });
  239. },
  240. getCategory: function(categoryId)
  241. {
  242. return fetch("select * from categories where category_id='"
  243. + categoryId + "'");
  244. },
  245. getDownload: function(downloadURL)
  246. {
  247. var cleanD = sanitizer.sanitize(downloadURL);
  248. var q = "select * from downloads where url='" + cleanD + "' limit 1";
  249. return fetch(q);
  250. },
  251. getSiteMap: function()
  252. {
  253. return new Promise(function(resolve, reject)
  254. {
  255. });
  256. }
  257. };