first batch of requested changes
This commit is contained in:
		
							parent
							
								
									ed38d74b3e
								
							
						
					
					
						commit
						91e9d60040
					
				| @ -10,7 +10,6 @@ import { | ||||
| } from "@fosscord/util"; | ||||
| import bcrypt from "bcrypt"; | ||||
| import { Request, Response, Router } from "express"; | ||||
| import { HTTPError } from "lambert-server"; | ||||
| 
 | ||||
| const router = Router(); | ||||
| 
 | ||||
| @ -20,37 +19,37 @@ router.post( | ||||
| 	async (req: Request, res: Response) => { | ||||
| 		const { password, token } = req.body as PasswordResetSchema; | ||||
| 
 | ||||
| 		const { jwtSecret } = Config.get().security; | ||||
| 
 | ||||
| 		let user; | ||||
| 		try { | ||||
| 			const { jwtSecret } = Config.get().security; | ||||
| 			const { user } = await checkToken(token, jwtSecret, true); | ||||
| 
 | ||||
| 			// the salt is saved in the password refer to bcrypt docs
 | ||||
| 			const hash = await bcrypt.hash(password, 12); | ||||
| 
 | ||||
| 			const data = { | ||||
| 				data: { | ||||
| 					hash, | ||||
| 					valid_tokens_since: new Date(), | ||||
| 			const userTokenData = await checkToken(token, jwtSecret, true); | ||||
| 			user = userTokenData.user; | ||||
| 		} catch { | ||||
| 			throw FieldErrors({ | ||||
| 				password: { | ||||
| 					message: req.t("auth:password_reset.INVALID_TOKEN"), | ||||
| 					code: "INVALID_TOKEN", | ||||
| 				}, | ||||
| 			}; | ||||
| 			await User.update({ id: user.id }, data); | ||||
| 
 | ||||
| 			// come on, the user has to have an email to reset their password in the first place
 | ||||
| 			// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
 | ||||
| 			await Email.sendPasswordChanged(user, user.email!); | ||||
| 
 | ||||
| 			res.json({ token: await generateToken(user.id) }); | ||||
| 		} catch (e) { | ||||
| 			if ((e as Error).toString() === "Invalid Token") | ||||
| 				throw FieldErrors({ | ||||
| 					password: { | ||||
| 						message: req.t("auth:password_reset.INVALID_TOKEN"), | ||||
| 						code: "INVALID_TOKEN", | ||||
| 					}, | ||||
| 				}); | ||||
| 
 | ||||
| 			throw new HTTPError((e as Error).toString(), 400); | ||||
| 			}); | ||||
| 		} | ||||
| 
 | ||||
| 		// the salt is saved in the password refer to bcrypt docs
 | ||||
| 		const hash = await bcrypt.hash(password, 12); | ||||
| 
 | ||||
| 		const data = { | ||||
| 			data: { | ||||
| 				hash, | ||||
| 				valid_tokens_since: new Date(), | ||||
| 			}, | ||||
| 		}; | ||||
| 		await User.update({ id: user.id }, data); | ||||
| 
 | ||||
| 		// come on, the user has to have an email to reset their password in the first place
 | ||||
| 		// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
 | ||||
| 		await Email.sendPasswordChanged(user, user.email!); | ||||
| 
 | ||||
| 		res.json({ token: await generateToken(user.id) }); | ||||
| 	}, | ||||
| ); | ||||
| 
 | ||||
|  | ||||
| @ -16,10 +16,15 @@ | ||||
| 	along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | ||||
| */ | ||||
| 
 | ||||
| import { route, verifyCaptcha } from "@fosscord/api"; | ||||
| import { checkToken, Config, generateToken, User } from "@fosscord/util"; | ||||
| import { getIpAdress, route, verifyCaptcha } from "@fosscord/api"; | ||||
| import { | ||||
| 	checkToken, | ||||
| 	Config, | ||||
| 	FieldErrors, | ||||
| 	generateToken, | ||||
| 	User, | ||||
| } from "@fosscord/util"; | ||||
| import { Request, Response, Router } from "express"; | ||||
| import { HTTPError } from "lambert-server"; | ||||
| const router = Router(); | ||||
| 
 | ||||
| async function getToken(user: User) { | ||||
| @ -38,9 +43,21 @@ router.post( | ||||
| 	async (req: Request, res: Response) => { | ||||
| 		const { captcha_key, token } = req.body; | ||||
| 
 | ||||
| 		if (captcha_key) { | ||||
| 			const { sitekey, service } = Config.get().security.captcha; | ||||
| 			const verify = await verifyCaptcha(captcha_key); | ||||
| 		const config = Config.get(); | ||||
| 
 | ||||
| 		if (config.register.requireCaptcha) { | ||||
| 			const { sitekey, service } = config.security.captcha; | ||||
| 
 | ||||
| 			if (!captcha_key) { | ||||
| 				return res.status(400).json({ | ||||
| 					captcha_key: ["captcha-required"], | ||||
| 					captcha_sitekey: sitekey, | ||||
| 					captcha_service: service, | ||||
| 				}); | ||||
| 			} | ||||
| 
 | ||||
| 			const ip = getIpAdress(req); | ||||
| 			const verify = await verifyCaptcha(captcha_key, ip); | ||||
| 			if (!verify.success) { | ||||
| 				return res.status(400).json({ | ||||
| 					captcha_key: verify["error-codes"], | ||||
| @ -50,19 +67,26 @@ router.post( | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		const { jwtSecret } = Config.get().security; | ||||
| 		let user; | ||||
| 
 | ||||
| 		try { | ||||
| 			const { jwtSecret } = Config.get().security; | ||||
| 
 | ||||
| 			const { user } = await checkToken(token, jwtSecret, true); | ||||
| 
 | ||||
| 			if (user.verified) return res.json(await getToken(user)); | ||||
| 
 | ||||
| 			await User.update({ id: user.id }, { verified: true }); | ||||
| 
 | ||||
| 			return res.json(await getToken(user)); | ||||
| 		} catch (error) { | ||||
| 			throw new HTTPError((error as Error).toString(), 400); | ||||
| 			const userTokenData = await checkToken(token, jwtSecret, true); | ||||
| 			user = userTokenData.user; | ||||
| 		} catch { | ||||
| 			throw FieldErrors({ | ||||
| 				password: { | ||||
| 					message: req.t("auth:password_reset.INVALID_TOKEN"), | ||||
| 					code: "INVALID_TOKEN", | ||||
| 				}, | ||||
| 			}); | ||||
| 		} | ||||
| 
 | ||||
| 		if (user.verified) return res.json(await getToken(user)); | ||||
| 
 | ||||
| 		await User.update({ id: user.id }, { verified: true }); | ||||
| 
 | ||||
| 		return res.json(await getToken(user)); | ||||
| 	}, | ||||
| ); | ||||
| 
 | ||||
|  | ||||
| @ -52,7 +52,9 @@ export function adjustEmail(email?: string): string | undefined { | ||||
| 	// return email;
 | ||||
| } | ||||
| 
 | ||||
| const transporters = { | ||||
| const transporters: { | ||||
| 	[key: string]: () => Promise<nodemailer.Transporter<unknown> | void>; | ||||
| } = { | ||||
| 	smtp: async function () { | ||||
| 		// get configuration
 | ||||
| 		const { host, port, secure, username, password } = | ||||
| @ -223,8 +225,7 @@ export const Email: { | ||||
| 		const { provider } = Config.get().email; | ||||
| 		if (!provider) return; | ||||
| 
 | ||||
| 		const transporterFn = | ||||
| 			transporters[provider as keyof typeof transporters]; | ||||
| 		const transporterFn = transporters[provider]; | ||||
| 		if (!transporterFn) | ||||
| 			return console.error(`[Email] Invalid provider: ${provider}`); | ||||
| 		console.log(`[Email] Initializing ${provider} transport...`); | ||||
| @ -346,7 +347,7 @@ export const Email: { | ||||
| 		const link = await this.generateLink("reset", user.id, email); | ||||
| 
 | ||||
| 		// load the email template
 | ||||
| 		const rawTemplate = fs.readFileSync( | ||||
| 		const rawTemplate = await fs.promises.readFile( | ||||
| 			path.join( | ||||
| 				ASSET_FOLDER_PATH, | ||||
| 				"email_templates", | ||||
| @ -380,7 +381,7 @@ export const Email: { | ||||
| 		if (!this.transporter) return; | ||||
| 
 | ||||
| 		// load the email template
 | ||||
| 		const rawTemplate = fs.readFileSync( | ||||
| 		const rawTemplate = await fs.promises.readFile( | ||||
| 			path.join( | ||||
| 				ASSET_FOLDER_PATH, | ||||
| 				"email_templates", | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Puyodead1
						Puyodead1