Advertisement
Guest User

Untitled

a guest
May 17th, 2018
188
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.71 KB | None | 0 0
  1. import express from 'express';
  2. import sqlite from 'sqlite';
  3.  
  4. import { asyncMiddleware } from './utils/asyncMiddleware';
  5. import { generateRandomness, HMAC, KDF, checkPassword } from './utils/crypto';
  6.  
  7. const router = express.Router();
  8. const dbPromise = sqlite.open('./db/database.sqlite', { cached: true });
  9. const key = generateRandomness();
  10. const token_key = generateRandomness();
  11.  
  12. async function logDatabaseState() {
  13. const db = await dbPromise;
  14. const query = `SELECT * FROM Users`;
  15. const result = await db.all(query);
  16. console.log(result);
  17. }
  18.  
  19.  
  20. function render(req, res, next, page, title, errorMsg = false, result = null) {
  21. // logDatabaseState();
  22. res.render(
  23. 'layout/template', {
  24. page,
  25. title,
  26. loggedIn: req.session.loggedIn,
  27. account: req.session.account,
  28. errorMsg,
  29. result,
  30. }
  31. );
  32. }
  33.  
  34.  
  35. router.get('/', (req, res, next) => {
  36. if (req.session.signature !== '' && req.session.signature != null) {
  37. if(!checkSignature(req)) {
  38. render(req, res, next, 'login/form', 'Login', 'Invalid Session.');
  39. return;
  40. };
  41. }
  42.  
  43. render(req, res, next, 'index', 'Bitbar Home');
  44. });
  45.  
  46.  
  47. router.post('/set_profile', asyncMiddleware(async (req, res, next) => {
  48. if(!checkSignature(req)) {
  49. render(req, res, next, 'login/form', 'Login', 'Invalid Session.');
  50. return;
  51. };
  52. req.session.account.profile = req.body.new_profile;
  53. req.session.account.profile = cleanInput(req.session.account.profile,['<script','</script>','<img','</img>','<iframe','</iframe>','<input','</input>','<audio','</audio>','<embed','</embed>','<source','</source>','<track','</track>','<video','</video>']);
  54. req.session.signature = HMAC(key, JSON.stringify(req.session.account));
  55. console.log('Updated HMAC in set_profile');
  56. const db = await dbPromise;
  57. const query = `UPDATE Users SET profile = ? WHERE username = ?;`;
  58. const result = await db.run(query, req.body.new_profile, req.session.account.username);
  59. render(req, res, next, 'index', 'Bitbar Home');
  60. }));
  61.  
  62.  
  63. function cleanInput(input,whitelist){
  64. for (var i = 0; i <whitelist.length; i++){
  65. var scrub = whitelist[i];
  66. var start = input.search(scrub);
  67. while(start !== -1){
  68. input = input.slice(0,start) + input.slice(start+scrub.length);
  69. start = input.search(scrub);
  70. }
  71. }
  72. return input;
  73. }
  74.  
  75.  
  76. function alphaNumericOnly(username){
  77. var re = /\w/;
  78. var cleanedUsername = '';
  79. for (var i = 0; i < username.length; i++){
  80. var char = username.charAt(i);
  81. if (re.test(char) === true){
  82. cleanedUsername += char;
  83. }
  84. }
  85. return cleanedUsername;
  86. }
  87.  
  88.  
  89. router.get('/login', (req, res, next) => {
  90. render(req, res, next, 'login/form', 'Login');
  91. });
  92.  
  93.  
  94. router.post('/post_login', asyncMiddleware(async (req, res, next) => {
  95. const db = await dbPromise;
  96. var oldUserName = req.body.username;
  97. req.body.username = alphaNumericOnly(req.body.username);
  98. if (req.body.username !== oldUserName){
  99. render(req, res, next, 'login/form', 'Login', 'Alphanumeric Characters Only (a-z,A-Z,0-9 And No Whitespaces)');
  100. return;
  101. }
  102.  
  103. const query = `SELECT * FROM Users WHERE username == ?;`;
  104. const result = await db.get(query, req.body.username);
  105. if(result) { // if this username actually exists
  106. if(checkPassword(req.body.password, result)) { // if password is valid
  107. req.session.loggedIn = true;
  108. req.session.account = result;
  109. req.session.signature = HMAC(key, JSON.stringify(req.session.account));
  110. console.log('Updated HMAC in post_login');
  111. render(req, res, next, 'login/success', 'Bitbar Home');
  112. return;
  113. }
  114. }
  115. render(req, res, next, 'login/form', 'Login', 'This username and password combination does not exist!');
  116. }));
  117.  
  118.  
  119. router.get('/register', (req, res, next) => {
  120. render(req, res, next, 'register/form', 'Register');
  121. });
  122.  
  123.  
  124. router.post('/post_register', asyncMiddleware(async (req, res, next) => {
  125. const db = await dbPromise;
  126. var oldUserName = req.body.username;
  127. req.body.username = alphaNumericOnly(req.body.username);
  128. if (req.body.username !== oldUserName){
  129. render(req, res, next, 'register/form', 'Register', 'Alphanumeric Characters Only (a-z,A-Z,0-9 And No Whitespaces)');
  130. return;
  131. }
  132.  
  133. let query = `SELECT * FROM Users WHERE username == ?;`;
  134. let result = await db.get(query, req.body.username);
  135. if(result) { // query returns results
  136. if(result.username === req.body.username) { // if username exists
  137. render(req, res, next, 'register/form', 'Register', 'This username already exists!');
  138. return;
  139. }
  140. }
  141.  
  142. const salt = generateRandomness();
  143. const hashedPassword = KDF(req.body.password, salt);
  144. query = `INSERT INTO Users(username, hashedPassword, salt, profile, bitbars) VALUES(?, ?, ?, ?, ?)`;
  145. await db.run(query, [req.body.username, hashedPassword, salt, '', 100]);
  146. req.session.loggedIn = true;
  147. req.session.account = {
  148. username: req.body.username,
  149. hashedPassword,
  150. salt,
  151. profile: '',
  152. bitbars: 100,
  153. };
  154. req.session.signature = HMAC(key, JSON.stringify(req.session.account));
  155. console.log('Updated HMAC in post_register');
  156. render(req, res, next,'register/success', 'Bitbar Home');
  157. }));
  158.  
  159.  
  160. router.get('/close', asyncMiddleware(async (req, res, next) => {
  161. if(req.session.loggedIn == false) {
  162. render(req, res, next, 'login/form', 'Login', 'You must be logged in to use this feature!');
  163. return;
  164. };
  165. const db = await dbPromise;
  166. const query = `DELETE FROM Users WHERE username == ?;`;
  167. await db.get(query, req.session.account.username);
  168. req.session.loggedIn = false;
  169. req.session.account = {};
  170. req.session.signature = '';
  171. render(req, res, next, 'index', 'Bitbar Home', 'Deleted account successfully!');
  172. }));
  173.  
  174.  
  175. router.get('/logout', (req, res, next) => {
  176. req.session.loggedIn = false;
  177. req.session.account = {};
  178. req.session.signature = '';
  179. render(req, res, next, 'index', 'Bitbar Home', 'Logged out successfully!');
  180. });
  181.  
  182.  
  183. function checkSignature(req){
  184. return req.session.signature === HMAC(key, JSON.stringify(req.session.account));
  185. }
  186.  
  187.  
  188. router.get('/profile', asyncMiddleware(async (req, res, next) => {
  189. if(req.session.loggedIn == false) {
  190. render(req, res, next, 'login/form', 'Login', 'You must be logged in to use this feature!');
  191. return;
  192. };
  193.  
  194. if(!checkSignature(req)) {
  195. render(req, res, next, 'login/form', 'Login', 'Invalid Session.');
  196. return;
  197. };
  198.  
  199. if(req.query.username != null) { // if visitor makes a search query
  200. const db = await dbPromise;
  201.  
  202. var oldUserName = req.query.username;
  203. req.query.username = alphaNumericOnly(req.query.username);
  204. if (req.query.username !== oldUserName){
  205. render(req, res, next, 'profile/view', 'View Profile', 'Alphanumeric Characters Only (a-z,A-Z,0-9 And No Whitespaces)', req.session.account);
  206. return;
  207. }
  208.  
  209. const query = `SELECT * FROM Users WHERE username == ?;`;
  210. let result;
  211. try {
  212. result = await db.get(query, req.query.username);
  213. } catch(err) {
  214. result = false;
  215. }
  216. if(result) { // if user exists
  217. render(req, res, next, 'profile/view', 'View Profile', false, result);
  218. }
  219. else { // user does not exist
  220. render(req, res, next, 'profile/view', 'View Profile', `${req.query.username} does not exist!`, req.session.account);
  221. }
  222. } else { // visitor did not make query, show them their own profile
  223. render(req, res, next, 'profile/view', 'View Profile', false, req.session.account);
  224. }
  225. }));
  226.  
  227. function generateToken(req){
  228. return HMAC(token_key, req.session.signature);
  229. }
  230.  
  231. function checkToken(token, req){
  232. return token === generateToken(req);
  233. }
  234.  
  235. router.get('/transfer', (req, res, next) => {
  236. if(req.session.loggedIn == false) {
  237. render(req, res, next, 'login/form', 'Login', 'You must be logged in to use this feature!');
  238. return;
  239. };
  240.  
  241. if(!checkSignature(req)) {
  242. render(req, res, next, 'login/form', 'Login', 'Invalid Session.');
  243. return;
  244. };
  245.  
  246. var secretToken = generateToken(req);
  247. render(req, res, next, 'transfer/form', 'Transfer Bitbars', false, {receiver:null, amount:null, secretToken});
  248. });
  249.  
  250.  
  251. router.post('/post_transfer', asyncMiddleware(async(req, res, next) => {
  252. if(req.session.loggedIn == false) {
  253. render(req, res, next, 'login/form', 'Login', 'You must be logged in to use this feature!');
  254. return;
  255. };
  256.  
  257. if(!checkSignature(req)) {
  258. render(req, res, next, 'login/form', 'Login', 'Invalid Session.');
  259. return;
  260. };
  261.  
  262. if(req.body.destination_username === req.session.account.username) {
  263. render(req, res, next, 'transfer/form', 'Transfer Bitbars', 'You cannot send money to yourself!', {receiver:null, amount:null});
  264. return;
  265. }
  266.  
  267. var oldUserName = req.body.destination_username;
  268. req.body.destination_username = alphaNumericOnly(req.body.destination_username);
  269. if (req.body.destination_username !== oldUserName){
  270. render(req, res, next, 'transfer/form', 'Transfer Bitbars', 'Alphanumeric Characters Only (a-z,A-Z,0-9 And No Whitespaces)', {receiver:null, amount:null});
  271. return;
  272. }
  273.  
  274. if(!checkToken(req.body.secretToken, req)) {
  275. console.log('Secret token validation failed');
  276. render(req, res, next, 'transfer/form', 'Transfer Bitbars', 'Invalid Token.', {receiver:null, amount:null});
  277. return;
  278. };
  279.  
  280. const db = await dbPromise;
  281. let query = `SELECT * FROM Users WHERE username == ?;`;
  282. const receiver = await db.get(query, req.body.destination_username);
  283. if(receiver) { // if user exists
  284. const amount = parseInt(req.body.quantity);
  285. if(Number.isNaN(amount) || amount > req.session.account.bitbars || amount < 1) {
  286. render(req, res, next, 'transfer/form', 'Transfer Bitbars', 'Invalid transfer amount!', {receiver:null, amount:null});
  287. return;
  288. }
  289.  
  290. req.session.account.bitbars -= amount;
  291. req.session.signature = HMAC(key, JSON.stringify(req.session.account));
  292. query = `UPDATE Users SET bitbars = "${req.session.account.bitbars}" WHERE username == "${req.session.account.username}";`;
  293. await db.exec(query);
  294. const receiverNewBal = receiver.bitbars + amount;
  295. query = `UPDATE Users SET bitbars = "${receiverNewBal}" WHERE username == "${receiver.username}";`;
  296. await db.exec(query);
  297. render(req, res, next, 'transfer/success', 'Transfer Complete', false, {receiver, amount});
  298. } else { // user does not exist
  299. render(req, res, next, 'transfer/form', 'Transfer Bitbars', 'This user does not exist!', {receiver:null, amount:null});
  300. }
  301. }));
  302.  
  303.  
  304. router.get('/steal_cookie', (req, res, next) => {
  305. let stolenCookie = req.query.cookie;
  306. console.log('\n\n' + stolenCookie + '\n\n');
  307. render(req, res, next, 'theft/view_stolen_cookie', 'Cookie Stolen!', false, stolenCookie);
  308. });
  309.  
  310.  
  311. module.exports = router;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement