organized files better
This commit is contained in:
		
							parent
							
								
									ccdd7ad589
								
							
						
					
					
						commit
						74f3706852
					
				
							
								
								
									
										96
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										96
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @ -1974,31 +1974,12 @@ | ||||
|       "dev": true | ||||
|     }, | ||||
|     "bcrypt": { | ||||
|       "version": "4.0.1", | ||||
|       "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-4.0.1.tgz", | ||||
|       "integrity": "sha512-hSIZHkUxIDS5zA2o00Kf2O5RfVbQ888n54xQoF/eIaquU4uaLxK8vhhBdktd0B3n2MjkcAWzv4mnhogykBKOUQ==", | ||||
|       "version": "5.0.0", | ||||
|       "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.0.0.tgz", | ||||
|       "integrity": "sha512-jB0yCBl4W/kVHM2whjfyqnxTmOHkCX4kHEa5nYKSoGeYe8YrjTYTc87/6bwt1g8cmV0QrbhKriETg9jWtcREhg==", | ||||
|       "requires": { | ||||
|         "node-addon-api": "^2.0.0", | ||||
|         "node-pre-gyp": "0.14.0" | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "node-pre-gyp": { | ||||
|           "version": "0.14.0", | ||||
|           "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.14.0.tgz", | ||||
|           "integrity": "sha512-+CvDC7ZttU/sSt9rFjix/P05iS43qHCOOGzcr3Ry99bXG7VX953+vFyEuph/tfqoYu8dttBkE86JSKBO2OzcxA==", | ||||
|           "requires": { | ||||
|             "detect-libc": "^1.0.2", | ||||
|             "mkdirp": "^0.5.1", | ||||
|             "needle": "^2.2.1", | ||||
|             "nopt": "^4.0.1", | ||||
|             "npm-packlist": "^1.1.6", | ||||
|             "npmlog": "^4.0.2", | ||||
|             "rc": "^1.2.7", | ||||
|             "rimraf": "^2.6.1", | ||||
|             "semver": "^5.3.0", | ||||
|             "tar": "^4.4.2" | ||||
|           } | ||||
|         } | ||||
|         "node-addon-api": "^3.0.0", | ||||
|         "node-pre-gyp": "0.15.0" | ||||
|       } | ||||
|     }, | ||||
|     "big.js": { | ||||
| @ -4767,9 +4748,9 @@ | ||||
|       } | ||||
|     }, | ||||
|     "needle": { | ||||
|       "version": "2.5.0", | ||||
|       "resolved": "https://registry.npmjs.org/needle/-/needle-2.5.0.tgz", | ||||
|       "integrity": "sha512-o/qITSDR0JCyCKEQ1/1bnUXMmznxabbwi/Y4WwJElf+evwJNFNwIDMCCt5IigFVxgeGBJESLohGtIS9gEzo1fA==", | ||||
|       "version": "2.5.2", | ||||
|       "resolved": "https://registry.npmjs.org/needle/-/needle-2.5.2.tgz", | ||||
|       "integrity": "sha512-LbRIwS9BfkPvNwNHlsA41Q29kL2L/6VaOJ0qisM5lLWsTV3nP15abO5ITL6L81zqFhzjRKDAYjpcBcwM0AVvLQ==", | ||||
|       "requires": { | ||||
|         "debug": "^3.2.6", | ||||
|         "iconv-lite": "^0.4.4", | ||||
| @ -4823,9 +4804,9 @@ | ||||
|       "integrity": "sha512-0L9FvHG3nfnnmaEQPjT9xhfN4ISk0A8/2j4M37Np4mcDesJjHgEUfgPhdCyZuFI954tjokaIj/A3NdpFNdEh4Q==" | ||||
|     }, | ||||
|     "node-addon-api": { | ||||
|       "version": "2.0.1", | ||||
|       "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.1.tgz", | ||||
|       "integrity": "sha512-2WVfwRfIr1AVn3dRq4yRc2Hn35ND+mPJH6inC6bjpYCZVrpXPB4j3T6i//OGVfqVsR1t/X/axRulDsheq4F0LQ==" | ||||
|       "version": "3.0.0", | ||||
|       "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.0.0.tgz", | ||||
|       "integrity": "sha512-sSHCgWfJ+Lui/u+0msF3oyCgvdkhxDbkCS6Q8uiJquzOimkJBvX6hl5aSSA7DR1XbMpdM8r7phjcF63sF4rkKg==" | ||||
|     }, | ||||
|     "node-libs-browser": { | ||||
|       "version": "2.2.1", | ||||
| @ -4866,6 +4847,23 @@ | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "node-pre-gyp": { | ||||
|       "version": "0.15.0", | ||||
|       "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.15.0.tgz", | ||||
|       "integrity": "sha512-7QcZa8/fpaU/BKenjcaeFF9hLz2+7S9AqyXFhlH/rilsQ/hPZKK32RtR5EQHJElgu+q5RfbJ34KriI79UWaorA==", | ||||
|       "requires": { | ||||
|         "detect-libc": "^1.0.2", | ||||
|         "mkdirp": "^0.5.3", | ||||
|         "needle": "^2.5.0", | ||||
|         "nopt": "^4.0.1", | ||||
|         "npm-packlist": "^1.1.6", | ||||
|         "npmlog": "^4.0.2", | ||||
|         "rc": "^1.2.7", | ||||
|         "rimraf": "^2.6.1", | ||||
|         "semver": "^5.3.0", | ||||
|         "tar": "^4.4.2" | ||||
|       } | ||||
|     }, | ||||
|     "node-releases": { | ||||
|       "version": "1.1.60", | ||||
|       "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.60.tgz", | ||||
| @ -5385,6 +5383,11 @@ | ||||
|       "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "pseudomap": { | ||||
|       "version": "1.0.2", | ||||
|       "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", | ||||
|       "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" | ||||
|     }, | ||||
|     "public-encrypt": { | ||||
|       "version": "4.0.3", | ||||
|       "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", | ||||
| @ -6522,6 +6525,14 @@ | ||||
|         "setimmediate": "^1.0.4" | ||||
|       } | ||||
|     }, | ||||
|     "tmp": { | ||||
|       "version": "0.0.33", | ||||
|       "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", | ||||
|       "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", | ||||
|       "requires": { | ||||
|         "os-tmpdir": "~1.0.2" | ||||
|       } | ||||
|     }, | ||||
|     "to-arraybuffer": { | ||||
|       "version": "1.0.1", | ||||
|       "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", | ||||
| @ -6787,6 +6798,31 @@ | ||||
|       "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "useragent": { | ||||
|       "version": "2.3.0", | ||||
|       "resolved": "https://registry.npmjs.org/useragent/-/useragent-2.3.0.tgz", | ||||
|       "integrity": "sha512-4AoH4pxuSvHCjqLO04sU6U/uE65BYza8l/KKBS0b0hnUPWi+cQ2BpeTEwejCSx9SPV5/U03nniDTrWx5NrmKdw==", | ||||
|       "requires": { | ||||
|         "lru-cache": "4.1.x", | ||||
|         "tmp": "0.0.x" | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "lru-cache": { | ||||
|           "version": "4.1.5", | ||||
|           "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", | ||||
|           "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", | ||||
|           "requires": { | ||||
|             "pseudomap": "^1.0.2", | ||||
|             "yallist": "^2.1.2" | ||||
|           } | ||||
|         }, | ||||
|         "yallist": { | ||||
|           "version": "2.1.2", | ||||
|           "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", | ||||
|           "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "util": { | ||||
|       "version": "0.11.1", | ||||
|       "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", | ||||
|  | ||||
| @ -12,7 +12,7 @@ | ||||
|     "test": "run-p --race dev cy:run" | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "bcrypt": "^4.0.1", | ||||
|     "bcrypt": "^5.0.0", | ||||
|     "body-parser": "^1.19.0", | ||||
|     "cl-editor": "^2.1.0", | ||||
|     "compression": "^1.7.1", | ||||
| @ -28,7 +28,8 @@ | ||||
|     "passport": "^0.4.1", | ||||
|     "passport-local": "^1.0.0", | ||||
|     "rate-limiter-flexible": "^2.1.10", | ||||
|     "session-file-store": "^1.4.0" | ||||
|     "session-file-store": "^1.4.0", | ||||
|     "useragent": "^2.3.0" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "@babel/core": "^7.11.4", | ||||
|  | ||||
							
								
								
									
										93
									
								
								src/routes/cms/register.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								src/routes/cms/register.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,93 @@ | ||||
| import User from '../../models/user.js'; | ||||
| 
 | ||||
| export async function post(req, res) | ||||
| { | ||||
| 	if (req.user) { | ||||
| 		res.writeHead(401, { | ||||
| 			'Content-Type': 'application/json' | ||||
| 		}); | ||||
| 		res.end(JSON.stringify({ | ||||
| 			message: `You are already logged in` | ||||
| 		})); | ||||
| 		return false; | ||||
| 	} | ||||
| 	let { username, password, password_confirm, realname } = req.body; | ||||
| 	if (!username || !password || !password_confirm || !realname) { | ||||
| 		res.writeHead(422, { | ||||
| 			'Content-Type': 'application/json' | ||||
| 		}); | ||||
| 		res.end(JSON.stringify({ | ||||
| 			message: `You need to supply a username, real name, password, and password confirmation.` | ||||
| 		})); | ||||
| 		return false; | ||||
| 	} | ||||
| 	if (password.length < 8) { | ||||
| 		res.writeHead(422, { | ||||
| 			'Content-Type': 'application/json' | ||||
| 		}); | ||||
| 		res.end(JSON.stringify({ | ||||
| 			message: `The password must be at least 8 characters long.` | ||||
| 		})); | ||||
| 		return false; | ||||
| 	} | ||||
| 	if (password !== password_confirm) { | ||||
| 		res.writeHead(422, { | ||||
| 			'Content-Type': 'application/json' | ||||
| 		}); | ||||
| 		res.end(JSON.stringify({ | ||||
| 			message: `The password does not match the confirmation.` | ||||
| 		})); | ||||
| 		return false; | ||||
| 	} | ||||
| 	if (!/^[a-z0-9.]+$/i.test(username)) { | ||||
| 		res.writeHead(422, { | ||||
| 			'Content-Type': 'application/json' | ||||
| 		}); | ||||
| 		res.end(JSON.stringify({ | ||||
| 			message: `The username can only contain letters, numbers, and periods.` | ||||
| 		})); | ||||
| 		return false; | ||||
| 	} | ||||
| 	/* | ||||
| 	try { | ||||
| 		await registerRateLimiter.consume(); | ||||
| 	} catch (err) { | ||||
| 		res.writeHead(429, { | ||||
| 			'Content-Type': 'application/json' | ||||
| 		}); | ||||
| 		res.end(JSON.stringify({ | ||||
| 			message: `Too Many Requests` | ||||
| 		})); | ||||
| 		return false; | ||||
| 	} | ||||
| 	*/ | ||||
| 	try { | ||||
| 		const user = await User.findOne({ username: req.body.username }); | ||||
| 		if (user) { | ||||
| 			res.writeHead(401, { | ||||
| 				'Content-Type': 'application/json' | ||||
| 			}); | ||||
| 			res.end(JSON.stringify({ | ||||
| 				message: `This username is taken.` | ||||
| 			})); | ||||
| 			return false; | ||||
| 		} | ||||
| 		// password gets automatically hashed
 | ||||
| 		const newUser = await new User({ username, realname, password }); | ||||
| 		await newUser.save(); | ||||
| 
 | ||||
| 		req.login(newUser, err => { | ||||
| 			if (err) throw err; | ||||
| 			return res.redirect('/cms'); | ||||
| 		}); | ||||
| 	} catch (err) { | ||||
| 		console.error(err); | ||||
| 		res.writeHead(500, { | ||||
| 			'Content-Type': 'application/json' | ||||
| 		}); | ||||
| 		res.end(JSON.stringify({ | ||||
| 			message: `Internal server error` | ||||
| 		})); | ||||
| 		return false; | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										26
									
								
								src/routes/me/avatar.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								src/routes/me/avatar.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,26 @@ | ||||
| import fs from 'fs'; | ||||
| import User from '../../models/user.js'; | ||||
| 
 | ||||
| export async function del(req, res) | ||||
| { | ||||
| 	if (!req.user) { | ||||
| 		res.writeHead(401, { | ||||
| 			'Content-Type': 'application/json' | ||||
| 		}); | ||||
| 		res.end(JSON.stringify({ | ||||
| 			message: `You must be logged in to set an avatar.` | ||||
| 		})); | ||||
| 		return false; | ||||
| 	} | ||||
| 	const user = await User.findById(req.user._id); | ||||
| 	const filename = 'default.jpg'; | ||||
| 	if (user.avatar !== filename) { | ||||
| 		fs.unlinkSync(`./static/u/${user.avatar}`); | ||||
| 	} | ||||
| 	req.user.avatar = user.avatar = filename; | ||||
| 	await user.save(); | ||||
| 	res.writeHead(200, { | ||||
| 		'Content-Type': 'application/json' | ||||
| 	}); | ||||
| 	res.end(JSON.stringify({ filename })); | ||||
| } | ||||
							
								
								
									
										16
									
								
								src/routes/me/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/routes/me/index.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,16 @@ | ||||
| export function get(req, res, next) | ||||
| { | ||||
| 	if (req.user) { | ||||
| 		res.writeHead(200, { | ||||
| 			'Content-Type': 'application/json' | ||||
| 		}); | ||||
| 		res.end(JSON.stringify(req.user)); | ||||
| 	} else { | ||||
| 		res.writeHead(401, { | ||||
| 			'Content-Type': 'application/json' | ||||
| 		}); | ||||
| 		res.end(JSON.stringify({ | ||||
| 			message: `You are not logged in` | ||||
| 		})); | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										141
									
								
								src/server.js
									
									
									
									
									
								
							
							
						
						
									
										141
									
								
								src/server.js
									
									
									
									
									
								
							| @ -12,6 +12,7 @@ import fileUpload from 'express-fileupload'; | ||||
| import fs from 'fs'; | ||||
| import cors from 'cors'; | ||||
| import helmet from 'helmet'; | ||||
| import useragent from 'useragent'; | ||||
| import crypto from 'crypto'; | ||||
| import Article from './models/article.js'; | ||||
| import Category from './models/category.js'; | ||||
| @ -130,101 +131,6 @@ express() | ||||
|     .use(passport.initialize()) | ||||
|     .use(passport.session()) | ||||
| 
 | ||||
|     .post('/cms/register', | ||||
|         function(req, res, next) { | ||||
|             if (!req.user) { | ||||
|                 next(); | ||||
|             } else { | ||||
|                 res.writeHead(401, { | ||||
|                     'Content-Type': 'application/json' | ||||
|                 }); | ||||
|                 res.end(JSON.stringify({ | ||||
|                     message: `You are already logged in` | ||||
|                 })); | ||||
|             } | ||||
|         }, async (req, res) => { | ||||
|             let { username, password, password_confirm, realname } = req.body; | ||||
|             if (!username || !password || !password_confirm || !realname) { | ||||
|                 res.writeHead(422, { | ||||
|                     'Content-Type': 'application/json' | ||||
|                 }); | ||||
|                 res.end(JSON.stringify({ | ||||
|                     message: `You need to supply a username, real name, password, and password confirmation.` | ||||
|                 })); | ||||
|                 return false; | ||||
|             } | ||||
|             if (password.length < 8) { | ||||
|                 res.writeHead(422, { | ||||
|                     'Content-Type': 'application/json' | ||||
|                 }); | ||||
|                 res.end(JSON.stringify({ | ||||
|                     message: `The password must be at least 8 characters long.` | ||||
|                 })); | ||||
|                 return false; | ||||
|             } | ||||
|             if (password !== password_confirm) { | ||||
|                 res.writeHead(422, { | ||||
|                     'Content-Type': 'application/json' | ||||
|                 }); | ||||
|                 res.end(JSON.stringify({ | ||||
|                     message: `The password does not match the confirmation.` | ||||
|                 })); | ||||
|                 return false; | ||||
|             } | ||||
|             if (!/^[a-z0-9.]+$/i.test(username)) { | ||||
|                 res.writeHead(422, { | ||||
|                     'Content-Type': 'application/json' | ||||
|                 }); | ||||
|                 res.end(JSON.stringify({ | ||||
|                     message: `The username can only contain letters, numbers, and periods.` | ||||
|                 })); | ||||
|                 return false; | ||||
|             } | ||||
|             /* | ||||
|             try { | ||||
|                 await registerRateLimiter.consume(); | ||||
|             } catch (err) { | ||||
|                 res.writeHead(429, { | ||||
|                     'Content-Type': 'application/json' | ||||
|                 }); | ||||
|                 res.end(JSON.stringify({ | ||||
|                     message: `Too Many Requests` | ||||
|                 })); | ||||
|                 return false; | ||||
|             } | ||||
|             */ | ||||
|             try { | ||||
|                 const user = await User.findOne({ username: req.body.username }); | ||||
|                 if (user) { | ||||
|                     res.writeHead(401, { | ||||
|                         'Content-Type': 'application/json' | ||||
|                     }); | ||||
|                     res.end(JSON.stringify({ | ||||
|                         message: `This username is taken.` | ||||
|                     })); | ||||
|                     return false; | ||||
|                 } | ||||
|                 // password gets automatically hashed
 | ||||
|                 const newUser = await new User({ username, realname, password }); | ||||
|                 await newUser.save(); | ||||
| 
 | ||||
|                 req.login(newUser, err => { | ||||
|                     if (err) throw err; | ||||
|                     return res.redirect('/cms'); | ||||
|                 }); | ||||
|             } catch (err) { | ||||
|                 console.error(err); | ||||
|                 res.writeHead(500, { | ||||
|                     'Content-Type': 'application/json' | ||||
|                 }); | ||||
|                 res.end(JSON.stringify({ | ||||
|                     message: `Internal server error` | ||||
|                 })); | ||||
|                 return false; | ||||
|             } | ||||
|         } | ||||
|     ) | ||||
| 
 | ||||
|     .post('/cms/login', | ||||
|         // rateLimiterMiddleware(loginAttemptRateLimiter),
 | ||||
|         passport.authenticate('local', { failWithError: true }), | ||||
| @ -433,22 +339,6 @@ express() | ||||
|         } | ||||
|     ) | ||||
| 
 | ||||
|     .get('/me', function(req, res, next) { | ||||
|         if (req.user) { | ||||
|             res.writeHead(200, { | ||||
|                 'Content-Type': 'application/json' | ||||
|             }); | ||||
|             res.end(JSON.stringify(req.user)); | ||||
|         } else { | ||||
|             res.writeHead(401, { | ||||
|                 'Content-Type': 'application/json' | ||||
|             }); | ||||
|             res.end(JSON.stringify({ | ||||
|                 message: `You are not logged in` | ||||
|             })); | ||||
|         } | ||||
|     }) | ||||
| 
 | ||||
|     .post('/me/avatar', | ||||
|         async function(req, res, next) { | ||||
|             if (!req.user) { | ||||
| @ -511,33 +401,12 @@ express() | ||||
|         } | ||||
|     ) | ||||
| 
 | ||||
|     .delete('/me/avatar', | ||||
|         async function(req, res, next) { | ||||
|             if (!req.user) { | ||||
|                 res.writeHead(401, { | ||||
|                     'Content-Type': 'application/json' | ||||
|                 }); | ||||
|                 res.end(JSON.stringify({ | ||||
|                     message: `You must be logged in to set an avatar.` | ||||
|                 })); | ||||
|                 return false; | ||||
|             } | ||||
|             const user = await User.findById(req.user._id); | ||||
|             const filename = 'default.jpg'; | ||||
|             if (user.avatar !== filename) { | ||||
|                 fs.unlinkSync(`./static/u/${user.avatar}`); | ||||
|             } | ||||
|             req.user.avatar = user.avatar = filename; | ||||
|             await user.save(); | ||||
|             res.writeHead(200, { | ||||
|                 'Content-Type': 'application/json' | ||||
|             }); | ||||
|             res.end(JSON.stringify({ filename })); | ||||
|         } | ||||
|     ) | ||||
| 
 | ||||
|     .use(compression({ threshold: 0 })) | ||||
|     .use(express.static('./static')) | ||||
| 	.use(async function (req, res, next) { | ||||
| 		if (req.useragent.browser) { | ||||
| 		} | ||||
| 	}) | ||||
|     .use(sapper.middleware({ | ||||
|         session: req => ({ | ||||
|             user: req.session.passport ? req.session.passport.user : null | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user