forked from noxious/server
(WIP) Added pw reset token row, added checks to reset function
This commit is contained in:
parent
5a36d10f0e
commit
a4e96f9ede
11
package-lock.json
generated
11
package-lock.json
generated
@ -28,6 +28,7 @@
|
||||
"@types/express": "^4.17.21",
|
||||
"@types/jsonwebtoken": "^9.0.6",
|
||||
"@types/node": "^20.14.11",
|
||||
"@types/nodemailer": "^6.4.16",
|
||||
"nodemon": "^3.1.4",
|
||||
"prettier": "^3.3.3"
|
||||
}
|
||||
@ -728,6 +729,16 @@
|
||||
"undici-types": "~6.19.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/nodemailer": {
|
||||
"version": "6.4.16",
|
||||
"resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-6.4.16.tgz",
|
||||
"integrity": "sha512-uz6hN6Pp0upXMcilM61CoKyjT7sskBoOWpptkjjJp8jIMlTdc3xG01U7proKkXzruMS4hS0zqtHNkNPFB20rKQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/qs": {
|
||||
"version": "6.9.16",
|
||||
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.16.tgz",
|
||||
|
@ -29,6 +29,7 @@
|
||||
"@types/express": "^4.17.21",
|
||||
"@types/jsonwebtoken": "^9.0.6",
|
||||
"@types/node": "^20.14.11",
|
||||
"@types/nodemailer": "^6.4.16",
|
||||
"nodemon": "^3.1.4",
|
||||
"prettier": "^3.3.3"
|
||||
}
|
||||
|
@ -49,6 +49,17 @@ CREATE TABLE `User` (
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `PasswordResetToken` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`userId` INTEGER NOT NULL,
|
||||
`token` VARCHAR(191) NOT NULL,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
|
||||
UNIQUE INDEX `PasswordResetToken_token_key`(`token`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `CharacterType` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
@ -204,6 +215,9 @@ ALTER TABLE `Chat` ADD CONSTRAINT `Chat_zoneId_fkey` FOREIGN KEY (`zoneId`) REFE
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `SpriteAction` ADD CONSTRAINT `SpriteAction_spriteId_fkey` FOREIGN KEY (`spriteId`) REFERENCES `Sprite`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `PasswordResetToken` ADD CONSTRAINT `PasswordResetToken_userId_fkey` FOREIGN KEY (`userId`) REFERENCES `User`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `CharacterType` ADD CONSTRAINT `CharacterType_spriteId_fkey` FOREIGN KEY (`spriteId`) REFERENCES `Sprite`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
@ -1,10 +1,19 @@
|
||||
model User {
|
||||
id Int @id @default(autoincrement())
|
||||
username String @unique
|
||||
email String @unique
|
||||
password String
|
||||
online Boolean @default(false)
|
||||
characters Character[]
|
||||
id Int @id @default(autoincrement())
|
||||
username String @unique
|
||||
email String @unique
|
||||
password String
|
||||
online Boolean @default(false)
|
||||
characters Character[]
|
||||
passwordResetTokens PasswordResetToken[]
|
||||
}
|
||||
|
||||
model PasswordResetToken {
|
||||
id Int @id @default(autoincrement())
|
||||
userId Int
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
token String @unique
|
||||
createdAt DateTime @default(now())
|
||||
}
|
||||
|
||||
enum CharacterGender {
|
||||
@ -62,4 +71,4 @@ model CharacterItem {
|
||||
itemId String
|
||||
item Item @relation(fields: [itemId], references: [id], onDelete: Cascade)
|
||||
quantity Int
|
||||
}
|
||||
}
|
@ -1,8 +1,9 @@
|
||||
import bcrypt from 'bcryptjs'
|
||||
import UserRepository from '../repositories/userRepository'
|
||||
import prisma from '../utilities/prisma'
|
||||
import { User } from '@prisma/client'
|
||||
import { User, PasswordResetToken } from '@prisma/client'
|
||||
import config from '../utilities/config'
|
||||
import NodeMailer from 'nodemailer'
|
||||
|
||||
/**
|
||||
* User service
|
||||
@ -59,10 +60,27 @@ class UserService {
|
||||
* Reset password
|
||||
* @param email
|
||||
*/
|
||||
async resetPassword(email: string): Promise<boolean | User> {
|
||||
const nodemailer = require("nodemailer");
|
||||
async resetPassword(email: string): Promise<boolean | undefined> {
|
||||
|
||||
const transporter = nodemailer.createTransport({
|
||||
const user = await UserRepository.getByEmail(email)
|
||||
if ( !user ) return
|
||||
const token = await bcrypt.genSalt(10)
|
||||
|
||||
//Check if password reset has been requested recently
|
||||
if (await prisma.passwordResetToken.findFirst({
|
||||
where: {
|
||||
userId: user.id
|
||||
},
|
||||
})) return
|
||||
|
||||
prisma.passwordResetToken.create({
|
||||
data: {
|
||||
userId: user.id,
|
||||
token: token,
|
||||
}
|
||||
});
|
||||
|
||||
const transporter = NodeMailer.createTransport({
|
||||
host: config.SMTP_HOST,
|
||||
port: config.SMTP_PORT,
|
||||
secure: false,
|
||||
@ -76,12 +94,15 @@ class UserService {
|
||||
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
|
||||
text: "A password reset has been requested, reset your password here: " + config.CLIENT_URL + "/" + token, // Plain text body
|
||||
html: "<p>A password reset has been requested, reset your password here: " + config.CLIENT_URL + "/" + token + "</p>", // Html body
|
||||
});
|
||||
console.log("Message sent: %s", info.messageId);
|
||||
|
||||
return info.messageId
|
||||
|
||||
if (info) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@ class config {
|
||||
static REDIS_URL: string = process.env.REDIS_URL || 'redis://@127.0.0.1:6379/4'
|
||||
static HOST: string = process.env.HOST || '0.0.0.0'
|
||||
static PORT: number = process.env.PORT ? parseInt(process.env.PORT) : 6969
|
||||
static CLIENT_URL: string = process.env.CLIENT_URL ? process.env.CLIENT_URL : 'https://sylvan.quest/'
|
||||
static JWT_SECRET: string = process.env.JWT_SECRET || 'secret'
|
||||
|
||||
static ALLOW_DIAGONAL_MOVEMENT: boolean = process.env.ALLOW_DIAGONAL_MOVEMENT === 'true'
|
||||
|
@ -73,9 +73,9 @@ async function addHttpRoutes(app: Application) {
|
||||
}
|
||||
|
||||
const userService = new UserService()
|
||||
const user = await userService.resetPassword( email )
|
||||
const sentEmail = await userService.resetPassword( email )
|
||||
|
||||
if (user) {
|
||||
if (sentEmail) {
|
||||
return res.status(200).json({ message: 'Email has been sent' })
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user