1
0
forked from noxious/server

Added reset password function + basic mail layout

This commit is contained in:
Colin Kallemein 2024-10-27 21:30:33 +01:00
parent 8f8f019ab7
commit 5a36d10f0e
7 changed files with 86 additions and 2 deletions

View File

@ -12,3 +12,9 @@ ALLOW_DIAGONAL_MOVEMENT=false
DEFAULT_CHARACTER_ZONE="0" DEFAULT_CHARACTER_ZONE="0"
DEFAULT_CHARACTER_POS_X="0" DEFAULT_CHARACTER_POS_X="0"
DEFAULT_CHARACTER_POS_Y="0" DEFAULT_CHARACTER_POS_Y="0"
# SMTP configuration
SMTP_HOST="my.directonline.io"
SMTP_PORT="587"
SMTP_USER="no-reply@sylvan.quest"
SMTP_PASSWORD="Z%kI*1xe67WuGg"

10
package-lock.json generated
View File

@ -14,6 +14,7 @@
"express": "^4.19.2", "express": "^4.19.2",
"ioredis": "^5.4.1", "ioredis": "^5.4.1",
"jsonwebtoken": "^9.0.2", "jsonwebtoken": "^9.0.2",
"nodemailer": "^6.9.15",
"pino": "^9.3.2", "pino": "^9.3.2",
"prisma": "^5.17.0", "prisma": "^5.17.0",
"sharp": "^0.33.4", "sharp": "^0.33.4",
@ -1955,6 +1956,15 @@
"node-gyp-build-optional-packages-test": "build-test.js" "node-gyp-build-optional-packages-test": "build-test.js"
} }
}, },
"node_modules/nodemailer": {
"version": "6.9.15",
"resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.15.tgz",
"integrity": "sha512-AHf04ySLC6CIfuRtRiEYtGEXgRfa6INgWGluDhnxTZhHSKvrBu7lc1VVchQ0d8nPc4cFaZoPq8vkyNoZr0TpGQ==",
"license": "MIT-0",
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/nodemon": { "node_modules/nodemon": {
"version": "3.1.7", "version": "3.1.7",
"resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.7.tgz", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.7.tgz",

View File

@ -15,6 +15,7 @@
"express": "^4.19.2", "express": "^4.19.2",
"ioredis": "^5.4.1", "ioredis": "^5.4.1",
"jsonwebtoken": "^9.0.2", "jsonwebtoken": "^9.0.2",
"nodemailer": "^6.9.15",
"pino": "^9.3.2", "pino": "^9.3.2",
"prisma": "^5.17.0", "prisma": "^5.17.0",
"sharp": "^0.33.4", "sharp": "^0.33.4",

View File

@ -2,6 +2,7 @@ import bcrypt from 'bcryptjs'
import UserRepository from '../repositories/userRepository' import UserRepository from '../repositories/userRepository'
import prisma from '../utilities/prisma' import prisma from '../utilities/prisma'
import { User } from '@prisma/client' import { User } from '@prisma/client'
import config from '../utilities/config'
/** /**
* User service * User service
@ -53,6 +54,35 @@ class UserService {
} }
}) })
} }
/**
* Reset password
* @param email
*/
async resetPassword(email: string): Promise<boolean | User> {
const nodemailer = require("nodemailer");
const transporter = nodemailer.createTransport({
host: config.SMTP_HOST,
port: config.SMTP_PORT,
secure: false,
auth: {
user: config.SMTP_USER,
pass: config.SMTP_PASSWORD,
},
});
const info = await transporter.sendMail({
from: config.SMTP_USER,
to: email,
subject: "Reset your password",
text: "A password reset has been requested, reset your password here: ", // Plain text body
html: "<p>A password reset has been requested, reset your password here: </p>", // Html body
});
console.log("Message sent: %s", info.messageId);
return info.messageId
}
} }
export default UserService export default UserService

View File

@ -14,6 +14,11 @@ class config {
static DEFAULT_CHARACTER_ZONE: number = parseInt(process.env.DEFAULT_CHARACTER_ZONE || '1') static DEFAULT_CHARACTER_ZONE: number = parseInt(process.env.DEFAULT_CHARACTER_ZONE || '1')
static DEFAULT_CHARACTER_X: number = parseInt(process.env.DEFAULT_CHARACTER_POS_X || '0') static DEFAULT_CHARACTER_X: number = parseInt(process.env.DEFAULT_CHARACTER_POS_X || '0')
static DEFAULT_CHARACTER_Y: number = parseInt(process.env.DEFAULT_CHARACTER_POS_Y || '0') static DEFAULT_CHARACTER_Y: number = parseInt(process.env.DEFAULT_CHARACTER_POS_Y || '0')
static SMTP_HOST: string = process.env.SMTP_HOST || 'my.directonline.io'
static SMTP_PORT: number = process.env.SMTP_PORT ? parseInt(process.env.SMTP_PORT) : 587
static SMTP_USER: string = process.env.SMTP_USER || 'no-reply@sylvan.quest'
static SMTP_PASSWORD: string = process.env.SMTP_PASSWORD || 'password'
} }
export default config export default config

View File

@ -2,7 +2,7 @@ import { Application, Request, Response } from 'express'
import UserService from '../services/userService' import UserService from '../services/userService'
import jwt from 'jsonwebtoken' import jwt from 'jsonwebtoken'
import config from './config' import config from './config'
import { loginAccountSchema, registerAccountSchema } from './zodTypes' import { loginAccountSchema, registerAccountSchema, resetPasswordSchema } from './zodTypes'
import fs from 'fs' import fs from 'fs'
import { httpLogger } from './logger' import { httpLogger } from './logger'
import { getPublicPath } from './storage' import { getPublicPath } from './storage'
@ -58,6 +58,30 @@ async function addHttpRoutes(app: Application) {
return res.status(400).json({ message: 'Failed to register user' }) return res.status(400).json({ message: 'Failed to register user' })
}) })
/**
* Register
* @param req
* @param res
*/
app.post('/reset-password', async (req: Request, res: Response) => {
const { email } = req.body
try {
resetPasswordSchema.parse({ email })
} catch (error: any) {
return res.status(400).json({ message: error.errors[0]?.message })
}
const userService = new UserService()
const user = await userService.resetPassword( email )
if (user) {
return res.status(200).json({ message: 'Email has been sent' })
}
return res.status(400).json({ message: 'Failed to send password reset request' })
})
/** /**
* Get all tiles from a zone as an array of ids * Get all tiles from a zone as an array of ids
* @param req * @param req

View File

@ -33,6 +33,14 @@ export const registerAccountSchema = z.object({
.max(255) .max(255)
}) })
export const resetPasswordSchema = z.object({
email: z
.string()
.min(3, { message: 'Email must be at least 3 characters long' })
.max(255, { message: 'Email must be at most 255 characters long' })
.regex(/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/, { message: 'Email must be valid' })
})
export const ZCharacterCreate = z.object({ export const ZCharacterCreate = z.object({
name: z name: z
.string() .string()